/* ===================================================================
   ПРОТОТИП А — per-scene re-skin overrides.
   Loaded AFTER theme.css; assembled from per-scene blocks. Each block
   re-skins one non-battlefield scene onto the design system (ink/red
   canvas, cm-header, cm-pill, tokens). Never targets battlefield
   selectors (game/hud/board/hand). Assembled by the redesign workflow.
   =================================================================== */

/* ======================= SCENE: equip ======================= */
/* ===================================================================
   EQUIP — LOADOUT / pre-battle (Прототип А re-skin)
   Scoped to .equip-screen (cm-screen--ink) and the arcana-detail modal.
   All selectors meet/exceed the originals in theme.css; loads later → wins.
   =================================================================== */

/* ---- root canvas + hero-accent radial wash ---- */
.cm-screen.equip-screen {
  --equip-accent: var(--cm-red);
}
.cm-screen.equip-screen::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    120% 55% at 50% 0%,
    color-mix(in srgb, var(--equip-accent) 26%, transparent),
    transparent 58%
  );
}

/* override the legacy fixed/overflow .equip-wrap — it is now the cm-stack */
.cm-stack.equip-wrap {
  position: relative;
  inset: auto;
  z-index: 1;
  flex: 1;
  min-height: 0;
  background: transparent;
  padding: calc(env(safe-area-inset-top) + 6px) 18px calc(env(safe-area-inset-bottom) + 14px);
  gap: clamp(8px, 1.6vh, 14px);
  overflow: hidden;
}
@media (max-width: 340px) {
  .cm-stack.equip-wrap.corev2-equip-wrap {
    padding-inline: 8px;
  }
}

/* ---- header: suit mark in the right slot ---- */
.equip-header {
  flex: 0 0 auto;
}
.equip-suit-mark {
  width: 38px;
  flex: 0 0 38px;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 22px;
  line-height: 1;
  color: var(--equip-accent);
  text-shadow: 0 0 14px color-mix(in srgb, var(--equip-accent) 60%, transparent);
}

.equip-screen .equip-subtitle {
  flex: 0 0 auto;
  padding: 0 2px;
  margin-top: -2px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cm-fg-mute);
}

/* ---- slot rail — 5 equipped-arcana card slots ---- */
.equip-screen .equip-rail {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  padding: 2px 0 2px;
  flex: 0 0 auto;
}
.equip-screen .equip-slot {
  position: relative;
  aspect-ratio: 3 / 4;
  /* Let the 5 grid columns shrink below their content's intrinsic width.
     Without this, a filled slot's name (e.g. "WHETSTONE") sets a min-content
     floor that overflowed the rail on narrow phones (iPhone SE, Galaxy Fold) —
     the 5th slot got pushed off-screen. min-width:0 lets 1fr win and the name
     truncates instead. */
  min-width: 0;
  border-radius: var(--cm-r-chip);
  border: 1px dashed var(--cm-hair-22);
  background: var(--cm-surface-1);
  color: #fff;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 6px 4px;
  font-family: var(--font-mono);
  transition:
    transform 0.12s var(--cm-ease),
    border-color 0.12s,
    background 0.12s;
}
.equip-screen .equip-slot:active {
  transform: scale(0.95);
}
.equip-screen .equip-slot.empty {
  color: var(--cm-fg-dim);
}
.equip-screen .equip-slot.locked {
  opacity: 0.32;
  pointer-events: none;
  filter: grayscale(1);
  border-style: solid;
  border-color: var(--cm-hair-12);
}
.equip-screen .equip-slot.filled {
  border-style: solid;
  border-color: var(--equip-accent);
  background: color-mix(in srgb, var(--equip-accent) 12%, var(--cm-surface-1));
  box-shadow: var(--cm-shadow-card);
}
/* gold corner dot on filled slots */
.equip-screen .equip-slot.filled::after {
  content: '';
  position: absolute;
  top: 6px;
  right: 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cm-gold);
  box-shadow: 0 0 6px color-mix(in srgb, var(--cm-gold) 70%, transparent);
}
.equip-screen .equip-slot-glyph {
  font-size: clamp(18px, 4svh, 26px);
  line-height: 1;
}
.equip-screen .equip-slot.empty .equip-slot-glyph {
  color: var(--cm-fg-dim);
}
.equip-screen .equip-slot.filled .equip-slot-glyph {
  color: #fff;
}
.equip-screen .equip-slot-name {
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.15;
  color: var(--cm-fg-mute);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Cap to the slot width and let long single words break, so a name can never
     widen the slot and overflow the rail on narrow screens. */
  max-width: 100%;
  overflow-wrap: anywhere;
}

/* ---- set-bonus strip ----
   2×2 grid instead of a 4-wide row: four school chips with their glyph +
   label + count don't fit a phone's width on one line (the labels are
   nowrap), so a single row overflowed off-screen. A 2×2 block keeps every
   chip fully visible without a horizontal scroller. */
.equip-screen .equip-sets {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  padding: 0;
  flex: 0 0 auto;
}
.equip-screen .equip-set-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  gap: 5px;
  padding: 7px 4px;
  border-radius: var(--cm-r-pill);
  border: 1px solid var(--cm-hair-12);
  background: var(--cm-hair-08);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
  transition:
    color 0.14s,
    border-color 0.14s,
    background 0.14s;
}
.equip-screen .equip-set-chip.active-2 {
  color: #fff;
  border-color: var(--cm-hair-30);
  background: var(--cm-hair-10);
}
.equip-screen .equip-set-chip.active-3 {
  color: #fff;
  border-color: var(--cm-red);
  background: color-mix(in srgb, var(--cm-red) 18%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--cm-red) 30%, transparent) inset;
}
.equip-screen .equip-set-glyph {
  font-size: 12px;
  line-height: 1;
}
.equip-screen .equip-set-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.equip-screen .equip-set-count {
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
}

/* ---- catalog list ---- */
/* Single scroll region between the pinned header + footer: the whole loadout
   (chrome + rail + arcana catalog) scrolls together, so the catalog gets full
   height instead of a cramped strip. */
.equip-screen .equip-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.6vh, 14px);
  padding-bottom: 6px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
}
.equip-screen .equip-scroll::-webkit-scrollbar {
  width: 8px;
}
.equip-screen .equip-scroll::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.22);
  border-radius: 4px;
}
.equip-screen .equip-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  padding: 2px 0 4px;
  /* natural height — the .equip-scroll parent handles scrolling */
  flex: none;
}
@media (min-width: 520px) {
  .equip-screen .equip-list {
    grid-template-columns: 1fr 1fr;
  }
}
.equip-screen .equip-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--cm-r-banner);
  border: 1px solid var(--cm-hair-10);
  background: var(--cm-surface-1);
  color: #fff;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-mono);
  position: relative;
  transition:
    transform 0.12s var(--cm-ease),
    border-color 0.12s,
    background 0.12s;
}
.equip-screen .equip-card:active {
  transform: scale(0.985);
}
.equip-screen .equip-card.selected {
  border-color: var(--equip-accent);
  background: color-mix(in srgb, var(--equip-accent) 12%, var(--cm-surface-1));
}
.equip-screen .equip-card.locked {
  opacity: 0.5;
}
.equip-screen .equip-card.locked::before {
  content: '🔒';
  position: absolute;
  right: 10px;
  top: 8px;
  font-size: 12px;
  opacity: 0.75;
}
.equip-screen .equip-card.selected::after {
  content: '✓';
  position: absolute;
  right: 10px;
  top: 8px;
  color: var(--equip-accent);
  font-size: 14px;
}
.equip-screen .equip-card-glyph {
  font-size: 18px;
  line-height: 1;
  flex: 0 0 auto;
  color: var(--cm-fg-mute);
}
.equip-screen .equip-card-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}
.equip-screen .equip-card-name {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
}
.equip-screen .equip-card-meta {
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--cm-fg-dim);
  text-transform: uppercase;
}

/* rarity left-border ramp — preserved, raised specificity to win */
.equip-screen .equip-card.equip-rarity-common {
  border-left: 3px solid #707070;
}
.equip-screen .equip-card.equip-rarity-uncommon {
  border-left: 3px solid #4ec76b;
}
.equip-screen .equip-card.equip-rarity-rare {
  border-left: 3px solid #4488ff;
}
.equip-screen .equip-card.equip-rarity-epic {
  border-left: 3px solid #b264e0;
}
.equip-screen .equip-card.equip-rarity-legendary {
  border-left: 3px solid var(--cm-gold);
}

/* ---- footer: ghost SKIP + red double-glow READY ---- */
.equip-screen .equip-footer {
  display: flex;
  align-items: stretch;
  gap: 10px;
  padding: 8px 0 calc(env(safe-area-inset-bottom) + 2px);
  flex: 0 0 auto;
  border-top: 1px solid var(--cm-hair-10);
  background: transparent;
  margin-top: auto;
}
.equip-screen .equip-footer .equip-skip {
  flex: 0 0 auto;
  align-self: stretch;
  height: 60px;
  padding: 0 20px;
  border-radius: var(--cm-r-tile);
}
.equip-screen .equip-footer .equip-ready {
  flex: 1 1 auto;
}

/* ===================================================================
   Arcana detail modal — ink popup card (scoped via the panel class so the
   shared .modal-backdrop / other scenes are untouched).
   =================================================================== */
.modal-backdrop:has(.arcana-detail-panel) {
  align-items: flex-end;
  padding: env(safe-area-inset-top) 14px calc(env(safe-area-inset-bottom) + 14px);
}
@media (min-width: 560px) {
  .modal-backdrop:has(.arcana-detail-panel) {
    align-items: center;
  }
}
.arcana-detail-panel {
  background: var(--cm-surface-1);
  color: #fff;
  border: 1px solid var(--cm-hair-12);
  border-radius: var(--cm-r-screen);
  width: min(440px, calc(100vw - 28px));
  max-height: calc(100svh - 80px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--font-mono);
  box-shadow: var(--cm-shadow-popup);
  animation: cm-pop 0.26s var(--cm-ease) both;
}
/* keep the rarity left-border on the panel too */
.arcana-detail-panel.equip-rarity-common {
  border-left: 3px solid #707070;
}
.arcana-detail-panel.equip-rarity-uncommon {
  border-left: 3px solid #4ec76b;
}
.arcana-detail-panel.equip-rarity-rare {
  border-left: 3px solid #4488ff;
}
.arcana-detail-panel.equip-rarity-epic {
  border-left: 3px solid #b264e0;
}
.arcana-detail-panel.equip-rarity-legendary {
  border-left: 3px solid var(--cm-gold);
}
.arcana-detail-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--cm-hair-10);
}
.arcana-detail-glyph {
  font-size: 28px;
  line-height: 1;
  flex: 0 0 auto;
  color: var(--cm-fg-mute);
}
.arcana-detail-title-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.arcana-detail-name {
  font-family: var(--font-mono);
  font-size: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #fff;
}
.arcana-detail-meta {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
}
.arcana-detail-desc {
  padding: 14px 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--cm-fg-mute);
  overflow-y: auto;
}
.arcana-detail-trigger,
.arcana-detail-tax {
  display: flex;
  gap: 8px;
  padding: 4px 18px;
  font-size: 11px;
  letter-spacing: 0.06em;
}
.arcana-detail-trigger-label {
  color: var(--cm-fg-dim);
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.16em;
  min-width: 44px;
}
.arcana-detail-trigger-text {
  color: #fff;
}
.arcana-detail-tax-text {
  color: var(--cm-red);
}
.arcana-detail-set {
  /* margin: top sides bottom — the bottom value is the gap between this box and
     the CLOSE/ACQUIRE buttons below it (was 0). Everything else is original. */
  margin: 12px 18px 18px;
  padding: 11px 12px;
  background: var(--cm-hair-08);
  border: 1px solid var(--cm-hair-10);
  border-radius: var(--cm-r-banner);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.arcana-detail-set-title {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cm-gold);
}
.arcana-detail-set-line {
  font-size: 11px;
  color: var(--cm-fg-dim);
}
.arcana-detail-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 14px 18px calc(env(safe-area-inset-bottom) + 14px);
  margin-top: auto;
  border-top: 1px solid var(--cm-hair-10);
}
.arcana-detail-cancel {
  flex: 0 0 auto;
  padding: 11px 18px;
  border-radius: var(--cm-r-pill);
  border: 1px solid var(--cm-hair-18);
  background: var(--cm-hair-08);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background 0.12s,
    transform 0.08s ease;
}
.arcana-detail-cancel:active {
  transform: translateY(1px);
}
.arcana-detail-equip {
  flex: 1 1 auto;
  padding: 13px 18px;
  border-radius: var(--cm-r-pill);
  border: 0;
  background: var(--cm-red);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--cm-glow-red);
  transition:
    background 0.12s,
    transform 0.08s ease;
}
.arcana-detail-equip:hover {
  background: var(--cm-red-pill-hover);
}
.arcana-detail-equip:active {
  transform: translateY(1px);
  background: var(--cm-red-deep);
}
.arcana-detail-equip.is-unequip {
  background: var(--cm-hair-10);
  color: #fff;
  border: 1px solid var(--cm-hair-18);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .arcana-detail-panel {
    animation: none !important;
  }
  .equip-screen .equip-slot,
  .equip-screen .equip-card,
  .equip-screen .equip-set-chip {
    transition: none !important;
  }
}

/* ======================= SCENE: matchmaking ======================= */
/* =========================== MATCHMAKING (Прототип А #9) ===========================
   Black "search dial" waiting canvas. All sizing here was promoted out of the
   scene's inline style.cssText into classes. Selectors are scoped under
   .mm-screen (specificity >= the single-class .matchmaking-root / utilities in
   theme.css) and this file loads after theme.css, so these win. */

.cm-screen.mm-screen {
  /* dimmed-arena vignette over the black canvas, like the prototype gradient */
  background: #000;
}
.cm-screen.mm-screen::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 70% at 50% 18%, rgba(215, 25, 33, 0.16), transparent 62%),
    linear-gradient(180deg, rgba(8, 4, 5, 0.55), rgba(8, 4, 5, 0.92));
}

/* the safe-area column: center the waiting content vertically */
.mm-screen .mm-stack {
  justify-content: center;
  gap: clamp(12px, 2.4vh, 22px);
}

/* root holder — override legacy .matchmaking-root width/centering */
.mm-screen .matchmaking-root.mm-root {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 100%;
  gap: 0;
  animation: cm-slide 0.4s var(--cm-ease) both;
}

/* eyebrow — "RANKED ARENA"-style mode label */
.mm-screen .mm-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-align: center;
  color: var(--cm-fg-dim);
  margin-bottom: 10px;
}

/* title — replaces the old inline 16px/0.2em/700 */
.mm-screen .mm-title {
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  color: #fff;
  margin: 0 0 4px;
  transition: color 0.2s var(--cm-ease);
}

/* search dial — frames the KEPT inline loader video as a glowing ring */
.mm-screen .mm-dial {
  position: relative;
  width: 132px;
  height: 132px;
  margin: 22px auto 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid var(--cm-hair-16);
  box-shadow:
    var(--cm-glow-red),
    inset 0 0 24px rgba(0, 0, 0, 0.5);
}
.mm-screen .mm-dial::before {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid var(--cm-hair-10);
  pointer-events: none;
}
/* The pulsing ping lives on its own layer so the hairline above stays static;
   the ring itself is a static box-shadow — only transform/opacity animate. */
.mm-screen .mm-dial::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(215, 25, 33, 0.45);
  animation: cm-pulse-ring 2s var(--cm-ease) infinite;
  pointer-events: none;
}

/* keep the loader video centered; override legacy .matchmaking-spinner margin */
.mm-screen .mm-dial .matchmaking-spinner {
  margin: 0;
  position: relative;
  z-index: 1;
}

/* status line — live queue state (replaces inline 10px) */
.mm-screen .mm-status {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  color: #fff;
  margin: 6px 0 0;
  min-height: 17px;
}

/* loadout summary line — hero · board · mode (replaces inline 11px) */
.mm-screen .mm-info {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.3;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: center;
  color: var(--cm-fg-dim);
  margin: 8px 0 0;
}

/* CANCEL — ghost pill, full-width, sits below with breathing room */
.mm-screen .mm-cancel.cm-pill {
  margin-top: 28px;
  max-width: 320px;
}

/* ======================= SCENE: profile ======================= */
/* ===================================================================
   PROFILE (C.6) — Прототип А ink re-skin. Scoped under .profile-screen
   so these win over the single-class .profile-* rules in theme.css
   (proto-overrides.css also loads after theme.css).
   =================================================================== */
.profile-screen {
  /* canvas provided by .cm-screen--ink; nothing extra needed here */
}
/* the .cm-stack becomes the scroll container (the IntersectionObserver
   root is this element). Override the flow-scene gap + center cap width. */
.profile-screen .profile-root.cm-stack {
  flex: 1;
  min-height: 0;
  gap: 14px;
  max-width: 1040px;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

/* ---- header row: logout icon button in the right slot ---- */
.profile-screen .cm-header {
  padding-top: 0;
}
.profile-screen .cm-header-right {
  width: auto;
  flex: 0 0 auto;
}
.profile-screen .profile-logout {
  position: relative;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--cm-hair-10);
  color: var(--cm-red);
  cursor: pointer;
  transition:
    background 0.12s ease,
    color 0.12s ease,
    transform 0.12s var(--cm-ease);
}
/* 38px visual, 48px hit area — keep the small circle, pad the tappable zone. */
.profile-screen .profile-logout::after {
  content: '';
  position: absolute;
  inset: -5px;
  border-radius: 50%;
}
.profile-screen .profile-logout svg {
  display: block;
}
.profile-screen .profile-logout:hover {
  background: var(--cm-r-pill);
  background: color-mix(in oklch, var(--cm-red) 22%, var(--cm-hair-10));
  color: #fff;
}
.profile-screen .profile-logout:active {
  transform: scale(0.92);
}
.profile-screen .profile-logout:disabled,
.profile-screen .profile-logout.is-loading {
  cursor: wait;
  opacity: 0.5;
  pointer-events: none;
}

/* ---- identity card: centered avatar + name + status ---- */
.profile-screen .profile-header-slot {
  width: 100%;
}
.profile-screen .profile-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 22px 18px 18px;
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-08);
  border-radius: var(--cm-r-tray);
  box-shadow: var(--cm-shadow-card);
}
/* enlarge the shared avatar disc for the header hero treatment */
.profile-screen .profile-header .cm-avatar {
  width: 64px;
  height: 64px;
  flex: 0 0 64px;
  font-size: 26px;
  border-color: var(--cm-hair-30);
  background: var(--cm-shell);
}
.profile-screen .profile-header .cm-avatar-badge {
  font-size: 9px;
  padding: 2px 6px;
  border-color: color-mix(in oklch, var(--cm-red) 55%, var(--cm-hair-30));
}
.profile-screen .profile-identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2px;
}
.profile-screen .profile-kicker {
  color: var(--cm-fg-dim);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.profile-screen .profile-name {
  color: #fff;
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.1em;
  line-height: 1.06;
  text-transform: uppercase;
  overflow-wrap: anywhere;
  margin: 0;
}
.profile-screen .profile-subline {
  color: var(--cm-fg-mute);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-top: 8px;
}
.profile-screen .profile-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 6px 14px;
  border: 1px solid var(--cm-hair-16);
  border-radius: var(--cm-r-pill);
  background: var(--cm-hair-08);
  color: var(--cm-fg-mute);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.profile-screen .profile-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cm-mana);
  box-shadow: 0 0 10px color-mix(in oklch, var(--cm-mana) 70%, transparent);
}

/* ---- stat rail: 2-col --cm-surface-1 cards with hairline ---- */
.profile-screen .profile-stats-slot {
  width: 100%;
}
.profile-screen .profile-stat-rail {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  background: transparent;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.profile-screen .profile-stat-cell {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 14px 12px;
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-08);
  border-radius: var(--cm-r-banner);
}
.profile-screen .profile-stat-cell + .profile-stat-cell {
  box-shadow: none;
}
/* last odd cell (Rating) spans full width when 5 cells wrap 2-up */
.profile-screen .profile-stat-cell:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}
.profile-screen .profile-stat-label {
  color: var(--cm-fg-dim);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.profile-screen .profile-stat-value {
  color: #fff;
  font-family: var(--font-mono);
  font-size: 20px;
  letter-spacing: 0.06em;
  line-height: 1;
}

/* ---- body: stack the two sections (single column) ---- */
.profile-screen .profile-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
  padding-bottom: 4px;
}
.profile-screen .profile-section {
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-08);
  border-radius: var(--cm-r-tray);
  box-shadow: var(--cm-shadow-card);
  overflow: hidden;
}
.profile-screen .profile-section-heading {
  min-height: 44px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 16px 11px;
  border-bottom: 1px solid var(--cm-hair-10);
}
.profile-screen .profile-section-heading h2 {
  margin: 0;
  color: #fff;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.profile-screen .profile-section-heading span {
  color: var(--cm-fg-dim);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.profile-screen .profile-history-list,
.profile-screen .profile-ranking-list {
  display: flex;
  flex-direction: column;
}

/* ---- history rows ---- (always phone-width: badge + main, detail below) */
.profile-screen .profile-history-row {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  min-height: 68px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--cm-hair-08);
  background: transparent;
  transition: background 0.16s var(--cm-ease);
}
.profile-screen .profile-history-row:last-child {
  border-bottom: 0;
}
.profile-screen .profile-history-row:hover {
  background: var(--cm-hair-08);
}
.profile-screen .profile-result-badge {
  min-height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  border: 1px solid var(--cm-hair-16);
  border-radius: var(--cm-r-pill);
  background: var(--cm-hair-08);
  color: var(--cm-fg-mute);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.profile-screen .result-win .profile-result-badge {
  color: var(--cm-mana);
  border-color: color-mix(in oklch, var(--cm-mana) 50%, var(--cm-hair-16));
  background: color-mix(in oklch, var(--cm-mana) 14%, transparent);
}
.profile-screen .result-loss .profile-result-badge {
  color: var(--cm-red);
  border-color: color-mix(in oklch, var(--cm-red) 52%, var(--cm-hair-16));
  background: color-mix(in oklch, var(--cm-red) 16%, transparent);
}
.profile-screen .result-draw .profile-result-badge,
.profile-screen .result-abandoned .profile-result-badge {
  color: var(--cm-gold);
  border-color: color-mix(in oklch, var(--cm-gold) 44%, var(--cm-hair-16));
  background: color-mix(in oklch, var(--cm-gold) 12%, transparent);
}
.profile-screen .result-active .profile-result-badge {
  color: var(--cm-blue);
  border-color: color-mix(in oklch, var(--cm-blue) 48%, var(--cm-hair-16));
  background: color-mix(in oklch, var(--cm-blue) 14%, transparent);
}
.profile-screen .profile-history-main {
  min-width: 0;
}
.profile-screen .profile-history-title {
  color: #fff;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.06em;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-screen .profile-history-meta {
  color: var(--cm-fg-dim);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 6px;
  overflow-wrap: anywhere;
}
.profile-screen .profile-history-detail {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 5px;
  padding-left: 86px;
  color: var(--cm-fg-mute);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.profile-screen .profile-history-detail span {
  border: 1px solid var(--cm-hair-12);
  border-radius: var(--cm-r-pill);
  background: var(--cm-hair-08);
  padding: 4px 8px;
  white-space: nowrap;
}

/* ---- load-more sentinels (history + ranking) ---- */
.profile-screen .profile-history-sentinel {
  width: calc(100% - 32px);
  margin: 12px 16px;
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--cm-hair-16);
  border-radius: var(--cm-r-pill);
  background: var(--cm-hair-08);
  color: var(--cm-fg-mute);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 7px 14px;
  transition:
    background 0.16s var(--cm-ease),
    color 0.16s var(--cm-ease),
    border-color 0.16s var(--cm-ease);
}
.profile-screen .profile-history-sentinel:hover {
  color: #fff;
  border-color: var(--cm-hair-22);
  background: var(--cm-hair-10);
}
.profile-screen .profile-history-sentinel:disabled {
  cursor: wait;
  opacity: 0.6;
}
.profile-screen .profile-history-sentinel[hidden] {
  display: none;
}

/* ---- empty / error states ---- */
.profile-screen .profile-empty {
  min-height: 124px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 9px;
  padding: 24px 18px;
  color: var(--cm-fg-mute);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
}
.profile-screen .profile-empty strong {
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.profile-screen .profile-empty-compact {
  min-height: 78px;
}

/* ---- ranking rows ---- */
.profile-screen .profile-ranking-row {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) 54px 70px;
  gap: 8px;
  align-items: center;
  min-height: 46px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--cm-hair-08);
}
.profile-screen .profile-ranking-row:last-child {
  border-bottom: 0;
}
.profile-screen .profile-ranking-row.is-current {
  background: color-mix(in oklch, var(--cm-blue) 12%, transparent);
  box-shadow: inset 2px 0 0 var(--cm-blue);
}
.profile-screen .profile-ranking-place {
  color: var(--cm-fg-dim);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
}
.profile-screen .profile-ranking-name {
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.profile-screen .profile-ranking-games,
.profile-screen .profile-ranking-record {
  color: var(--cm-fg-mute);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-align: right;
}

/* ---- skeletons ---- */
.profile-screen .profile-skeleton {
  position: relative;
  height: 10px;
  border-radius: var(--cm-r-pill);
  overflow: hidden;
  background: var(--cm-hair-10);
}
.profile-screen .profile-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--cm-hair-16), transparent);
  transform: translateX(-100%);
  animation: profile-skeleton-sweep 1.4s ease-out infinite;
}
.profile-screen .profile-skeleton-badge {
  width: 64px;
  height: 28px;
  border-radius: var(--cm-r-pill);
}
.profile-screen .profile-skeleton-line {
  width: min(220px, 100%);
  margin-bottom: 8px;
}
.profile-screen .profile-skeleton-stat {
  /* Mirror the real .profile-history-detail: span the full row and indent to
     86px so the skeleton lines up with loaded rows instead of wrapping into
     (and overflowing) the 76px badge column. */
  grid-column: 1 / -1;
  width: 112px;
  margin-left: 86px;
}

/* ---- footer SIGN OUT text link ---- */
.profile-screen .profile-footer {
  display: flex;
  justify-content: center;
  padding: 6px 0 2px;
  margin-top: 2px;
}
.profile-screen .profile-signout {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--cm-red);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 10px 14px;
  border-bottom: 1px solid color-mix(in oklch, var(--cm-red) 45%, transparent);
  transition:
    color 0.16s var(--cm-ease),
    border-color 0.16s var(--cm-ease);
}
.profile-screen .profile-signout:hover {
  color: var(--cm-red-pill-hover);
  border-bottom-color: var(--cm-red-pill-hover);
}
.profile-screen .profile-signout:disabled {
  cursor: wait;
  opacity: 0.6;
}

/* The profile is always rendered in the phone-width frame (.cm-screen caps at
   480px), so history + ranking ALWAYS stack in a single column — no viewport
   2-column rule (it used to fire on wide viewports and crush the framed
   history column to ~180px, wrapping the meta one char per line). */
.profile-screen .profile-stat-rail {
  grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
}

/* opening animation — staggered slide-up of the profile blocks on mount,
   over the screen-level cm-fade (matches the prototype's entrance feel). */
.profile-screen .profile-header-slot,
.profile-screen .profile-progress-slot,
.profile-screen .profile-stats-slot,
.profile-screen .profile-history-section,
.profile-screen .profile-ranking-section {
  animation: cm-slide 0.44s var(--cm-ease) both;
}
.profile-screen .profile-progress-slot {
  animation-delay: 0.06s;
}
.profile-screen .profile-stats-slot {
  animation-delay: 0.12s;
}
.profile-screen .profile-history-section {
  animation-delay: 0.18s;
}
.profile-screen .profile-ranking-section {
  animation-delay: 0.24s;
}
@media (prefers-reduced-motion: reduce) {
  .profile-screen .profile-header-slot,
  .profile-screen .profile-progress-slot,
  .profile-screen .profile-stats-slot,
  .profile-screen .profile-history-section,
  .profile-screen .profile-ranking-section {
    animation: none;
  }
}

/* ======================= SCENE: marketplace ======================= */
/* ===================================================================
   SCENE: marketplace (Store) — Прототип А re-skin overrides.
   Root is now .cm-screen--ink > .cm-stack.mp-wrap. Selectors are scoped
   under .cm-screen--ink (or carry the .mp- prefix) at specificity >= the
   originals in theme.css so these (loaded later) win. Felt-grain cards +
   buy modal are preserved and re-tinted to --cm-* tokens.
   =================================================================== */

/* --- Canvas column: the old .mp-wrap owned the whole scrollable screen
   (100svh, own bg, own padding). Now .cm-stack owns the safe-area column;
   here we only keep the bits the layout needs: a fresh stacking context for
   the sticky tab bar, clipped overflow, and the inter-block gap. ---------- */
.cm-screen--ink .mp-wrap {
  width: 100%;
  max-width: 480px;
  height: auto;
  max-height: none;
  flex: 1;
  min-height: 0;
  gap: 14px;
  background: transparent;
  overflow: hidden;
  isolation: isolate;
  color: #fff;
}

/* --- Header row: widen the right slot so two currency pills fit; the
   primitive's .cm-header-right is a fixed 38px (one trailing control). ---- */
.cm-screen--ink .mp-topbar {
  flex: 0 0 auto;
  margin-bottom: 2px;
}
.cm-screen--ink .mp-topbar .cm-header-right {
  width: auto;
  flex: 0 1 auto;
  gap: 6px;
}
.cm-screen--ink .mp-topbar .mp-wallet {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* tighten the in-store wallet pills (no trailing "+" to balance) */
.cm-screen--ink .mp-topbar .cm-currency {
  padding: 5px 9px;
}

/* --- Tabs: keep the segmented bar, restyle to an ink card; selected reads
   white-on-ink like the rest of the system. ------------------------------ */
.cm-screen--ink .mp-tabs {
  border: 1px solid var(--cm-hair-10);
  border-radius: var(--cm-r-banner);
  background: var(--cm-surface-1);
  box-shadow: var(--cm-shadow-card);
}
.cm-screen--ink .mp-tab {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-tab + .mp-tab {
  box-shadow: -1px 0 0 var(--cm-hair-10);
}
.cm-screen--ink .mp-tab:hover {
  color: #fff;
}
.cm-screen--ink .mp-tab.selected {
  background: #fff;
  color: var(--cm-ink);
}
.cm-screen--ink .mp-tab.selected .mp-tab-count {
  color: rgba(20, 10, 11, 0.6);
}
.cm-screen--ink .mp-tab-label {
  letter-spacing: 0.16em;
}

/* --- Empty / retry states on ink. ------------------------------------- */
.cm-screen--ink .mp-empty {
  color: var(--cm-fg-mute);
}
.cm-screen--ink .mp-empty::before {
  color: var(--cm-fg-dim);
  opacity: 0.5;
}
.cm-screen--ink .mp-empty-detail {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-retry-btn {
  border: 1px solid var(--cm-hair-18);
  color: #fff;
  border-radius: var(--cm-r-pill);
}
.cm-screen--ink .mp-retry-btn:hover {
  border-color: var(--cm-red);
  color: var(--cm-red);
}

/* --- Shop cards: keep the felt grain, re-base onto ink surfaces + tokens. */
.cm-screen--ink .mp-card {
  background-color: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-08);
  border-radius: var(--cm-r-tile);
  box-shadow: var(--cm-shadow-card);
}
.cm-screen--ink .mp-card:hover {
  background-color: var(--cm-surface-2b);
}
.cm-screen--ink .mp-card-watermark {
  color: #fff;
}
.cm-screen--ink .mp-card-type {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-card-name {
  color: #fff;
}
.cm-screen--ink .mp-card-desc {
  color: var(--cm-fg-mute);
}
/* price chip → glass token pill */
.cm-screen--ink .mp-card-price {
  color: #fff;
  border: 1px solid var(--cm-hair-12);
  background: var(--cm-glass);
  border-radius: var(--cm-r-chip);
}
.cm-screen--ink .mp-card-price-currency {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-card-footer {
  border-top: 1px dashed var(--cm-hair-12);
}
/* BUY → white capsule (cm-pill--white vocabulary) */
.cm-screen--ink .mp-card-buy {
  background: #fff;
  color: var(--cm-ink);
  border: 1px solid #fff;
  border-radius: var(--cm-r-pill);
  letter-spacing: 0.18em;
  box-shadow: var(--cm-shadow-pill);
}
.cm-screen--ink .mp-card-buy:hover {
  background: var(--cm-red);
  border-color: var(--cm-red);
  color: #fff;
  box-shadow: var(--cm-glow-red);
}
.cm-screen--ink .mp-card-buy[disabled] {
  background: var(--cm-hair-08);
  border-color: var(--cm-hair-12);
  color: var(--cm-fg-dim);
  box-shadow: none;
}
.cm-screen--ink .mp-card-owned-stamp {
  background: var(--cm-mana);
  color: var(--cm-ink);
}

/* --- Owned tab tiles on ink. ------------------------------------------ */
.cm-screen--ink .mp-owned-tile {
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-08);
  border-radius: var(--cm-r-tile);
}
.cm-screen--ink .mp-owned-name {
  color: #fff;
}
.cm-screen--ink .mp-owned-meta {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-owned-open {
  font-family: var(--font-mono);
  margin-top: 6px;
  align-self: flex-start;
  background: #fff;
  color: var(--cm-ink);
  border: 0;
  border-radius: var(--cm-r-pill);
  padding: 6px 14px;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--cm-shadow-pill);
  transition:
    background 0.12s,
    color 0.12s,
    transform 0.08s ease;
}
.cm-screen--ink .mp-owned-open:hover {
  background: var(--cm-red);
  color: #fff;
}
.cm-screen--ink .mp-owned-open:active {
  transform: translateY(1px);
}
.cm-screen--ink .mp-owned-open[disabled] {
  opacity: 0.5;
  pointer-events: none;
}

/* --- Orders ledger on ink. -------------------------------------------- */
.cm-screen--ink .mp-order-row {
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-08);
  border-radius: var(--cm-r-tile);
}
.cm-screen--ink .mp-order-name {
  color: #fff;
}
.cm-screen--ink .mp-order-detail {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-order-detail-money {
  color: var(--cm-fg-mute);
}
.cm-screen--ink .mp-order-detail-refund {
  color: var(--cm-blue);
}
/* status LED pills keep the dot vocabulary, re-based on ink + tokens */
.cm-screen--ink .mp-status {
  color: var(--cm-fg-mute);
  border: 1px solid var(--cm-hair-12);
  background: var(--cm-glass);
}
.cm-screen--ink .mp-status-success {
  color: var(--cm-mana);
  border-color: rgba(123, 211, 137, 0.35);
}
.cm-screen--ink .mp-status-success::before {
  background: var(--cm-mana);
  box-shadow: 0 0 6px var(--cm-mana);
}
.cm-screen--ink .mp-status-failed {
  color: var(--cm-red);
  border-color: rgba(215, 25, 33, 0.35);
}
.cm-screen--ink .mp-status-failed::before {
  background: var(--cm-red);
  box-shadow: 0 0 6px var(--cm-red);
}
.cm-screen--ink .mp-status-pending {
  color: var(--cm-gold);
  border-color: rgba(232, 195, 107, 0.35);
}
.cm-screen--ink .mp-status-pending::before {
  background: var(--cm-gold);
  box-shadow: 0 0 6px var(--cm-gold);
}
.cm-screen--ink .mp-status-refunded {
  color: var(--cm-blue);
  border-color: rgba(111, 168, 255, 0.35);
}
.cm-screen--ink .mp-status-refunded::before {
  background: var(--cm-blue);
  box-shadow: 0 0 6px var(--cm-blue);
}
.cm-screen--ink .mp-status-disputed {
  color: var(--cm-gold);
  border-color: rgba(232, 195, 107, 0.45);
}
.cm-screen--ink .mp-status-disputed::before {
  background: var(--cm-gold);
  box-shadow: 0 0 6px var(--cm-gold);
}
/* dev test panel band */
.cm-screen--ink .mp-test-panel {
  border-top: 1px dashed var(--cm-hair-12);
}
.cm-screen--ink .mp-test-label {
  color: var(--cm-fg-dim);
}
.cm-screen--ink .mp-test-btn {
  border: 1px solid var(--cm-hair-16);
  color: var(--cm-fg-mute);
  border-radius: var(--cm-r-pill);
}
.cm-screen--ink .mp-test-btn:hover:not([disabled]) {
  color: #fff;
  border-color: var(--cm-hair-30);
}

/* --- Buy modal: kept via installModalShell; re-trim to ink + token red. -- */
.mp-buy-panel {
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-10);
  border-radius: var(--cm-r-tray);
  box-shadow:
    0 0 0 1px rgba(215, 25, 33, 0.14),
    var(--cm-shadow-popup);
}
.mp-buy-model {
  width: 112px;
  height: 112px;
  margin: -4px auto 8px;
}
.mp-buy-panel .mp-buy-eyebrow {
  color: var(--cm-fg-dim);
}
.mp-buy-panel .mp-buy-title {
  color: #fff;
}
.mp-buy-panel .mp-buy-price {
  color: #fff;
}
.mp-buy-panel .mp-buy-price-currency {
  color: var(--cm-fg-dim);
}
.mp-buy-panel .mp-card-watermark {
  color: #fff;
}
.mp-buy-panel .mp-card-hint {
  background: var(--cm-glass);
  border: 1px dashed var(--cm-hair-16);
  border-radius: var(--cm-r-chip);
}
.mp-buy-panel .mp-card-hint-row {
  color: var(--cm-fg-mute);
}
.mp-buy-panel .mp-card-hint-row:hover {
  border-color: var(--cm-hair-16);
  color: #fff;
}
.mp-buy-panel .mp-card-hint-row.outcome-succeed .mp-card-hint-mark {
  color: var(--cm-mana);
}
.mp-buy-panel .mp-card-hint-row.outcome-decline .mp-card-hint-mark {
  color: var(--cm-red);
}
.mp-buy-panel .mp-card-hint-row.outcome-dispute .mp-card-hint-mark {
  color: var(--cm-gold);
}
.mp-buy-panel .mp-label {
  color: var(--cm-fg-dim);
}
.mp-buy-panel .mp-input {
  background: var(--cm-glass);
  border: 1px solid var(--cm-hair-12);
  border-radius: var(--cm-r-chip);
  color: #fff;
}
.mp-buy-panel .mp-input:focus {
  border-color: var(--cm-red);
  box-shadow: 0 0 0 3px rgba(215, 25, 33, 0.2);
}
.mp-buy-panel .mp-input::placeholder {
  color: var(--cm-fg-dim);
}
.mp-buy-panel .mp-buy-status {
  color: var(--cm-fg-mute);
}
.mp-buy-panel .mp-buy-status.is-error {
  color: var(--cm-red);
}
.mp-buy-panel .mp-buy-status.is-success {
  color: var(--cm-mana);
}
.mp-buy-panel .mp-buy-cancel {
  border: 1px solid var(--cm-hair-16);
  color: var(--cm-fg-mute);
  border-radius: var(--cm-r-pill);
}
.mp-buy-panel .mp-buy-cancel:hover {
  color: #fff;
  border-color: var(--cm-hair-30);
}
/* PAY → token-red capsule with the system glow */
.mp-buy-panel .mp-buy-pay {
  background: var(--cm-red);
  border: 1px solid var(--cm-red);
  color: #fff;
  border-radius: var(--cm-r-pill);
  box-shadow: var(--cm-shadow-pill);
}
.mp-buy-panel .mp-buy-pay:hover {
  background: var(--cm-red-pill-hover);
  box-shadow: var(--cm-glow-red);
}
.mp-buy-panel .mp-buy-pay[disabled] {
  opacity: 0.5;
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .cm-screen--ink .mp-card-buy,
  .cm-screen--ink .mp-owned-open,
  .mp-buy-panel .mp-buy-pay {
    transition: none !important;
  }
}

/* ======================= SCENE: auth ======================= */
/* ===================================================================
   AUTH (C.8) — auth-scene.ts re-skin onto the ink dot-matrix system.
   Root: .cm-screen--ink > .auth-root.cm-stack (column). .auth-root is
   kept so #scene:has(.auth-root){padding:0} and .auth-input autofill/
   focus masks in theme.css keep matching. The Google button stays light
   (Google brand) and is intentionally NOT restyled here.
   =================================================================== */

/* Fill the canvas; the inner .auth-root scrolls. */
.cm-screen.auth-screen {
  background: var(--cm-ink);
}

/* Inner content column. .auth-root keeps cm-stack safe-area padding but
   overrides the legacy max-width:380 / gap so it reads as the proto column. */
.cm-screen--ink .auth-root.cm-stack {
  max-width: 420px;
  gap: 12px;
  /* Top-anchored, NOT vertically centered: switching login↔register adds the
     confirm-password field, and a centered column re-centers everything (brand
     + tabs visibly jump). Anchoring to the top keeps the brand/tabs fixed and
     lets the extra field grow downward. Overrides the responsive
     `.auth-root { justify-content: center }` (theme.css media query). */
  justify-content: flex-start;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

/* Top bar — element is now a .cm-header; neutralize the old .auth-topbar
   flex/min-height so the header primitive governs layout. */
.cm-screen--ink .auth-topbar {
  justify-content: flex-start;
  min-height: 46px;
  margin-bottom: 2px;
}

/* ---------------- Brand ---------------- */
.cm-screen--ink .auth-brand {
  text-align: center;
  margin-top: clamp(10px, 4vh, 34px);
}
.cm-screen--ink .auth-logo {
  font-family: var(--font-mono);
  /* Sized so the full "CARDOMANCER" wordmark (0.24em tracking) fits the column
     at every width — from a 320px phone (~259px text in a 284px column) up to
     the 480px max-width column. The old clamp(30px,9vw,46px) overflowed both
     ends and clipped the trailing R. */
  font-size: clamp(26px, 7.5vw, 42px);
  font-weight: 700;
  letter-spacing: 0.24em;
  line-height: 1;
  white-space: nowrap;
  color: #fff;
  text-shadow: 0 0 26px rgba(215, 25, 33, 0.45);
}
.cm-screen--ink .auth-tagline {
  font-family: var(--font-mono);
  font-size: clamp(9px, 2.4vw, 11px);
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
  margin-top: 9px;
}

/* ---------------- Per-step title ---------------- */
.cm-screen--ink .auth-step-title {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cm-fg-mute);
  text-align: center;
  margin-top: 8px;
}

/* ---------------- Login / Register segmented toggle ---------------- */
.cm-screen--ink .auth-tabs {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--cm-hair-12);
  border-radius: var(--cm-r-pill);
  background: var(--cm-hair-08);
  margin-top: 6px;
}
/* The white block: a single pill that slides between the two tabs instead of
   the highlight jumping. Width = one tab (50% of the box minus half the 4px
   padding pair and the 4px gap → 50% - 6px); slides by its width + the gap. */
.cm-screen--ink .auth-tab-indicator {
  position: absolute;
  top: 4px;
  bottom: 4px;
  /* inset-inline-start so the rest position sits under the first (login) tab in
     both LTR and RTL — the grid's first column follows the inline direction. */
  inset-inline-start: 4px;
  width: calc(50% - 6px);
  border-radius: var(--cm-r-pill);
  background: #fff;
  box-shadow: var(--cm-shadow-pill);
  transform: translateX(0);
  transition: transform 0.3s var(--cm-ease);
  z-index: 0;
  pointer-events: none;
}
.cm-screen--ink .auth-tabs[data-active='register'] .auth-tab-indicator {
  transform: translateX(calc(100% + 4px));
}
/* RTL: the register tab is on the inline-end (left), so slide the other way. */
[dir='rtl'] .cm-screen--ink .auth-tabs[data-active='register'] .auth-tab-indicator {
  transform: translateX(calc(-100% - 4px));
}
@media (prefers-reduced-motion: reduce) {
  .cm-screen--ink .auth-tab-indicator {
    transition: none;
  }
}
.cm-screen--ink .auth-tab {
  position: relative;
  z-index: 1;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cm-fg-mute);
  padding: 10px 6px;
  min-height: 40px;
  border-radius: var(--cm-r-pill);
  transition: color 0.2s var(--cm-ease);
}
.cm-screen--ink .auth-tab:hover {
  color: #fff;
}
/* Selected tab: text reads dark over the white sliding pill; the pill itself
   is the .auth-tab-indicator, not the button background. */
.cm-screen--ink .auth-tab.selected {
  background: transparent;
  box-shadow: none;
  color: var(--cm-ink);
}

/* ---------------- Feedback line ---------------- */
.cm-screen--ink .auth-feedback {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-align: center;
  min-height: 14px;
  color: var(--cm-rose);
}

/* ---------------- Google button — KEEP LIGHT (Google brand) ----------------
   Re-assert the light spec so the ink-canvas/.cm-* cascade can never recolor it. */
.cm-screen--ink .auth-google {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0;
  min-height: 46px;
  border-radius: 8px;
  background: #fff;
  border: 1px solid #dadce0;
  box-shadow: var(--cm-shadow-pill);
  cursor: pointer;
  transition:
    background 0.12s,
    box-shadow 0.12s;
  margin-top: 2px;
}
.cm-screen--ink .auth-google:hover {
  background: #f7f8f8;
}
.cm-screen--ink .auth-google:active {
  background: #eee;
}
.cm-screen--ink .auth-google-text {
  font-family: 'Roboto', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #3c4043;
  letter-spacing: 0.01em;
}

/* ---------------- Apple button — KEEP BLACK (Apple HIG) ----------------
   The Apple button shares .auth-google for geometry, so the light re-assert
   above also bleached it (white logo on white = invisible). Re-assert the
   HIG black variant at the same specificity, after the Google block. */
.cm-screen--ink .auth-apple {
  background: #000;
  border-color: #000;
  margin-top: 8px;
}
.cm-screen--ink .auth-apple:hover {
  background: #111;
}
.cm-screen--ink .auth-apple:active {
  background: #222;
}
.cm-screen--ink .auth-apple .auth-google-text {
  color: #fff;
}

/* ---------------- OR divider ---------------- */
.cm-screen--ink .auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 4px 0;
}
.cm-screen--ink .auth-divider-line {
  flex: 1;
  height: 1px;
  background: var(--cm-hair-12);
}
.cm-screen--ink .auth-divider-text {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
}

/* ---------------- Form + inputs ---------------- */
.cm-screen--ink .auth-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cm-screen--ink .auth-input {
  width: 100%;
  box-sizing: border-box;
  padding: 13px 15px;
  border: 1px solid var(--cm-hair-16);
  border-radius: var(--cm-r-chip);
  background: var(--cm-hair-08);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.04em;
  outline: none;
  transition:
    border-color 0.15s var(--cm-ease),
    background 0.15s var(--cm-ease),
    box-shadow 0.15s var(--cm-ease);
}
.cm-screen--ink .auth-input::placeholder {
  color: var(--cm-fg-dim);
  letter-spacing: 0.08em;
}
.cm-screen--ink .auth-input:focus {
  border-color: var(--cm-red);
  background: var(--cm-surface-1);
  box-shadow: 0 0 0 3px rgba(215, 25, 33, 0.18);
}
/* iOS WebKit yellow-autofill mask, re-asserted for the ink surface. */
.cm-screen--ink .auth-input:-webkit-autofill,
.cm-screen--ink .auth-input:-webkit-autofill:hover,
.cm-screen--ink .auth-input:-webkit-autofill:focus,
.cm-screen--ink .auth-input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--cm-surface-1) inset;
  -webkit-text-fill-color: #fff;
  caret-color: #fff;
  transition: background-color 9999s ease-out 0s;
}
.cm-screen--ink .auth-input:-webkit-autofill:focus {
  -webkit-box-shadow:
    0 0 0 1000px var(--cm-surface-1) inset,
    0 0 0 3px rgba(215, 25, 33, 0.18);
}
.cm-screen--ink .auth-input-otp {
  text-align: center;
  letter-spacing: 0.45em;
  font-size: 18px;
  font-weight: 700;
}

/* ---------------- Submit — white block CTA (cm-pill--white --block) ----------------
   Override the legacy .auth-submit radius/glow so the proto pill look wins. */
.cm-screen--ink .auth-submit {
  margin-top: 6px;
  width: 100%;
  border-radius: var(--cm-r-tile);
  letter-spacing: 0.18em;
  transition:
    transform 0.08s ease,
    box-shadow 0.2s ease,
    background 0.12s ease;
}
.cm-screen--ink .auth-submit:hover {
  box-shadow:
    var(--cm-shadow-pill),
    0 0 22px rgba(255, 255, 255, 0.18);
}
.cm-screen--ink .auth-submit:active {
  transform: translateY(1px);
}
.cm-screen--ink .auth-submit:disabled,
.cm-screen--ink .auth-submit[disabled] {
  opacity: 0.45;
  pointer-events: none;
}

/* ---------------- Secondary links ---------------- */
.cm-screen--ink .auth-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  justify-content: center;
  margin-top: 2px;
}
.cm-screen--ink .auth-link {
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cm-fg-mute);
  padding: 8px 4px;
  min-height: 34px;
  transition: color 0.12s var(--cm-ease);
}
.cm-screen--ink .auth-link:hover {
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .cm-screen--ink .auth-input,
  .cm-screen--ink .auth-tab,
  .cm-screen--ink .auth-submit,
  .cm-screen--ink .auth-link {
    transition: none !important;
  }
}

/* ======================= SCENE: chest ======================= */
/* ===================================================================
   chest-scene (plan C.9) — light re-skin only.
   KEEP intact: holographic foil/pack/cloth animation, rarity radial
   bloom (--spades/--diamonds/--clubs/--yellow), particles, sfx,
   .chest-stage canvas + .chest-hint. Restyle ONLY the close button
   (-> .cm-header-back look) and the pack-grant banner (token red trim).
   This block loads after theme.css so single-class selectors win by
   order; specificity matches the originals.
   =================================================================== */

/* Close button -> design-system header-back look: round, hairline fill,
   white outline glyph. Positioning/z-index preserved from the original. */
.chest-close.cm-header-back,
.chest-close {
  position: fixed;
  top: 14px;
  right: 14px;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--cm-hair-10);
  color: #fff;
  cursor: pointer;
  z-index: 52;
  -webkit-appearance: none;
  appearance: none;
  transition:
    background 0.12s,
    transform 0.12s var(--cm-ease);
}
.chest-close.cm-header-back svg,
.chest-close svg {
  display: block;
  width: 20px;
  height: 20px;
}
.chest-close.cm-header-back:hover,
.chest-close:hover {
  background: var(--cm-hair-18);
  color: #fff;
  border-color: transparent;
}
.chest-close.cm-header-back:active,
.chest-close:active {
  transform: scale(0.92);
}

/* Pack-grant banner -> ink card with token red trim. */
.pack-grant-banner {
  background: var(--cm-surface-1);
  border: 1px solid var(--cm-hair-12);
  border-top: 2px solid var(--cm-red);
  border-radius: var(--cm-r-banner);
  box-shadow:
    var(--cm-shadow-popup),
    inset 0 1px 0 var(--cm-hair-08);
  color: var(--cm-fg-mute);
}
.pack-grant-title {
  color: var(--cm-red);
}
.pack-grant-glyph {
  color: var(--cm-red);
}
.pack-grant-name {
  color: #fff;
}
.pack-grant-meta {
  color: var(--cm-fg-dim);
}

/* ======================= SCENE: language-selector ======================= */
/* ===================================================================
   C.11 — language-selector MODAL (ink card on Прототип А)
   Companion .cm-lang-* classes sit alongside the original .lang-*
   classes (same or higher specificity, loaded after theme.css → win).
   Modal behaviour, lazy ensureLoaded, full 30-locale list and the
   onChange callback are all untouched in the .ts.
   =================================================================== */

/* Backdrop — darker scrim + soft blur to seat the ink card. */
.modal-backdrop.cm-lang-backdrop {
  background: var(--cm-glass, rgba(0, 0, 0, 0.5));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Panel — ink card: surface-1 fill, screen radius, popup shadow. */
.lang-panel.cm-lang-panel {
  background: var(--cm-surface-1);
  color: #fff;
  border: 1px solid var(--cm-hair-12);
  border-radius: var(--cm-r-screen);
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100svh - 80px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--cm-shadow-popup);
  font-family: var(--font-mono);
  animation: cm-pop 0.28s var(--cm-ease) both;
}
@media (prefers-reduced-motion: reduce) {
  .lang-panel.cm-lang-panel {
    animation: none;
  }
}

/* Header — title + round close button, divided by a hairline rule. */
.lang-header.cm-lang-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--cm-hair-10);
  flex: 0 0 auto;
}
.lang-title.cm-lang-title {
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
}

/* Close — matches .cm-header-back: round hairline disc, outline glyph. */
.lang-close.cm-lang-close {
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--cm-hair-10);
  color: var(--cm-fg-mute);
  cursor: pointer;
  padding: 0;
  transition:
    background 0.12s,
    color 0.12s,
    transform 0.12s var(--cm-ease);
}
.lang-close.cm-lang-close svg {
  display: block;
}
.lang-close.cm-lang-close:hover {
  background: var(--cm-hair-18);
  color: #fff;
}
.lang-close.cm-lang-close:active {
  transform: scale(0.92);
}
.lang-close.cm-lang-close:focus-visible {
  outline: 2px solid var(--cm-gold);
  outline-offset: 2px;
}

/* List — scroll region with a thin gold-on-ink scrollbar. */
.lang-list.cm-lang-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 8px 0 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--cm-hair-22) transparent;
}
.lang-list.cm-lang-list::-webkit-scrollbar {
  width: 8px;
}
.lang-list.cm-lang-list::-webkit-scrollbar-thumb {
  background: var(--cm-hair-22);
  border-radius: 99px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.lang-list.cm-lang-list::-webkit-scrollbar-track {
  background: transparent;
}

/* Row — full-width tap target; native name left, english micro-caps right. */
.lang-item.cm-lang-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 18px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: #fff;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-mono);
  transition:
    background 0.12s var(--cm-ease),
    border-color 0.12s var(--cm-ease);
}
.lang-item.cm-lang-item:hover {
  background: var(--cm-hair-08);
}
.lang-item.cm-lang-item:active {
  background: var(--cm-hair-12);
}
.lang-item.cm-lang-item:focus-visible {
  outline: 0;
  background: var(--cm-hair-12);
  border-left-color: var(--cm-gold);
}

/* Active locale — gold rail + faint red wash, check rendered in gold. */
.lang-item.cm-lang-item.selected {
  background: rgba(215, 25, 33, 0.1);
  border-left-color: var(--cm-gold);
}
.lang-item.cm-lang-item.selected:hover {
  background: rgba(215, 25, 33, 0.14);
}

/* Loading — dim the row + spin a gold ring where the check sits. */
.lang-item.cm-lang-item.loading {
  opacity: 0.55;
  pointer-events: none;
}
.lang-item.cm-lang-item.loading .lang-check,
.lang-item.cm-lang-item.loading .lang-check-spacer {
  position: relative;
}
.lang-item.cm-lang-item.loading .lang-check svg {
  display: none;
}
.lang-item.cm-lang-item.loading .lang-check::after,
.lang-item.cm-lang-item.loading .lang-check-spacer::after {
  content: '';
  position: absolute;
  top: 50%;
  right: 0;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border-radius: 50%;
  border: 2px solid var(--cm-hair-22);
  border-top-color: var(--cm-gold);
  animation: cm-spin 0.7s linear infinite;
}

/* Native name — reads in the row's own script (lang attr on the button). */
.lang-native.cm-lang-native {
  flex: 1 1 auto;
  font-size: 15px;
  line-height: 1.2;
  color: #fff;
}

/* English/Latin name — dim mono micro-caps. */
.lang-english.cm-lang-english {
  flex: 0 0 auto;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
}

/* Check column — outline glyph tinted gold; spacer keeps rows aligned. */
.lang-check.cm-lang-check {
  flex: 0 0 18px;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  color: var(--cm-gold);
}
.lang-check.cm-lang-check svg {
  display: block;
}
.lang-check-spacer.cm-lang-check-spacer {
  flex: 0 0 18px;
}

/* RTL rows mirror so the check sits on the leading edge. */
[dir='rtl'] .lang-item.cm-lang-item {
  text-align: right;
  border-left: 0;
  border-right: 2px solid transparent;
}
[dir='rtl'] .lang-item.cm-lang-item.selected,
[dir='rtl'] .lang-item.cm-lang-item:focus-visible {
  border-right-color: var(--cm-gold);
}
[dir='rtl'] .lang-check.cm-lang-check {
  justify-content: flex-start;
}
[dir='rtl'] .lang-item.cm-lang-item.loading .lang-check::after,
[dir='rtl'] .lang-item.cm-lang-item.loading .lang-check-spacer::after {
  right: auto;
  left: 0;
}

/* ======================= profile progress bars (added) ======================= */
.profile-progress {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 4px 0 2px;
}
.profile-wr {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.profile-wr-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.profile-wr-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cm-fg-mute);
}
.profile-wr-pct {
  font-family: var(--font-mono);
  font-size: 20px;
  letter-spacing: 0.04em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.profile-wr-sub {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
}
.profile-bars {
  padding: 14px 14px 16px;
}
.profile-bars-title {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cm-fg-dim);
  margin-bottom: 4px;
}
.profile-barline {
  margin-top: 11px;
}
.profile-barline-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 5px;
}
.profile-barline-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cm-fg-mute);
}
.profile-barline-val {
  font-family: var(--font-mono);
  font-size: 11px;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* =========================================================================
   SHOP — foil card-tile catalog (ported 1:1 from "Shop Card Tiles.html").
   Live product models sit on the holographic foil backing.
   Prices are coins/gems only; real money lives in the separate Currency Store.
   Animates transform/opacity only (Android WebView compositing rule).
   ========================================================================= */

.sh-wrap {
  display: flex;
  flex-direction: column;
  /* height (not min-height) bounds the column to the fixed screen so .sh-scroll
     scrolls INTERNALLY instead of the whole page growing. */
  height: 100%;
  /* Keep the store in a centered phone-width column so it reads the same on
     desktop as on device (matches .cm-stack). */
  width: 100%;
  max-width: 480px;
  margin-inline: auto;
}

/* ── Top bar: back · STORE · currency purse ─────────────────────────── */
.sh-top {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: max(8px, env(safe-area-inset-top)) 16px 8px;
}
.sh-back {
  width: 38px;
  height: 38px;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sh-back:active {
  transform: scale(0.92);
}
.sh-title {
  font-family: var(--font-mono);
  font-size: 17px;
  letter-spacing: 0.16em;
}
.sh-top-spacer {
  flex: 1;
}
.sh-purse {
  display: flex;
  align-items: center;
  gap: 7px;
}
.sh-coin {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 5px 0 10px;
  border-radius: 15px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.03em;
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sh-coin:active {
  transform: scale(0.95);
}
/* Signed-out corner: no balance to show, so the chip carries the invitation to
   make one. Padded evenly since it holds only a word — the coin chip's lopsided
   padding exists to seat the round + button. */
.sh-coin--signin {
  padding: 0 12px;
  text-transform: uppercase;
}
.sh-coin img {
  width: 15px;
  height: 15px;
  display: block;
  object-fit: contain;
}
.sh-coin-plus {
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--cm-red);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
}

/* ── Scroll body ────────────────────────────────────────────────────── */
.sh-scroll {
  flex: 1;
  /* A flex child must allow itself to shrink below content height to become a
     scroll container inside the column. */
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 0 16px calc(28px + env(safe-area-inset-bottom));
  /* Always-visible slim scrollbar (desktop) — the default overlay bar was
     invisible until hover, so long catalogs looked stuck. */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
}
.sh-scroll::-webkit-scrollbar {
  width: 8px;
}
.sh-scroll::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.22);
  border-radius: 4px;
}
.sh-scroll::-webkit-scrollbar-track {
  background: transparent;
}

/* ── Featured banner ────────────────────────────────────────────────── */
.sh-banner {
  position: relative;
  height: 138px;
  margin: 6px 0 2px;
  border-radius: 14px;
  overflow: hidden;
  background: radial-gradient(110% 150% at 84% 50%, #4a1016, #140709 72%);
  border: 1px solid rgba(215, 25, 33, 0.42);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 16px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sh-banner:active {
  transform: scale(0.99);
}
.sh-banner-art {
  position: absolute;
  right: -6px;
  top: 50%;
  transform: translateY(-50%);
  width: 150px;
  height: 150px;
  object-fit: contain;
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.5));
  pointer-events: none;
}
.sh-banner-art--model .item-3d,
.sh-banner-art--model .item-3d-canvas {
  width: 100%;
  height: 100%;
}
.sh-banner-tag {
  position: relative;
  font-family: var(--font-mono);
  font-size: 7.5px;
  letter-spacing: 0.22em;
  color: #ffb3b8;
}
.sh-banner-name {
  position: relative;
  font-family: var(--font-mono);
  font-size: 21px;
  letter-spacing: 0.02em;
  margin: 7px 0 11px;
  max-width: 58%;
  line-height: 1.04;
}
.sh-banner-buy {
  position: relative;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 14px;
  border-radius: 16px;
  background: #fff;
  color: #15101a;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}
.sh-banner-buy img {
  width: 14px;
  height: 14px;
  display: block;
}
.sh-banner-buy .sh-was {
  font-size: 9px;
  color: rgba(21, 16, 26, 0.45);
  text-decoration: line-through;
}

/* ── Category tabs (segmented) ──────────────────────────────────────── */
.sh-tabs {
  display: flex;
  gap: 6px;
  padding: 12px 0 2px;
  position: sticky;
  top: 0;
  z-index: 6;
  background: linear-gradient(180deg, #0a0709 72%, rgba(10, 7, 9, 0));
}
.sh-tab {
  flex: 1;
  height: 32px;
  border: 0;
  cursor: pointer;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.55);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  -webkit-tap-highlight-color: transparent;
  transition:
    background 0.2s var(--cm-ease, ease),
    color 0.2s,
    transform 0.16s var(--cm-ease, ease);
}
.sh-tab.is-on {
  background: var(--cm-red);
  color: #fff;
}
.sh-tab:active {
  transform: scale(0.94);
}
.sh-tab.is-pop {
  animation: shTabPop 0.34s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}
@keyframes shTabPop {
  0% {
    transform: scale(0.86);
  }
  55% {
    transform: scale(1.08);
  }
  100% {
    transform: scale(1);
  }
}

/* ── Section header ─────────────────────────────────────────────────── */
.sh-sec {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 18px 2px 9px;
}
.sh-sec-name {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  color: #fff;
}
.sh-sec-sub {
  font-style: normal;
  font-size: 8px;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.4);
}

/* ── Grid + entrance stagger ────────────────────────────────────────── */
.sh-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 11px;
}
/* Category tabs have no section header, so the grid would butt against the
   sticky tab bar — give the first grid breathing room. */
.sh-content > .sh-grid:first-child {
  margin-top: 14px;
}
.sh-anim .sh-sec {
  animation: shSecIn 0.32s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1)) both;
}
.sh-anim .sh-tile {
  animation: shRowIn 0.42s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1)) both;
}
@keyframes shRowIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes shSecIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sh-anim .sh-sec,
  .sh-anim .sh-tile {
    animation: none;
  }
}

/* ── Foil card tile ─────────────────────────────────────────────────── */
.sh-tile {
  position: relative;
  border-radius: 13px;
  overflow: hidden;
  background: #0b0a0d;
  aspect-ratio: 3 / 3.95;
  cursor: pointer;
  color: #fff;
  -webkit-tap-highlight-color: transparent;
  box-shadow:
    0 10px 24px rgba(0, 0, 0, 0.5),
    0 2px 6px rgba(0, 0, 0, 0.4);
  transition: transform 0.12s var(--cm-ease, ease);
}
.sh-tile:active {
  transform: translateY(1px) scale(0.992);
}
/* Holo foil backing — the collectible-card texture, dimmed so art reads. */
.sh-foil {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background-image: url('/src/assets/shop/holo.png');
  background-size: cover;
  background-position: center;
  opacity: 0.55;
}
/* Holographic sheen — a soft light band that tracks device tilt ONLY (no
   time-based loop). --mx/--my (-1..1) are set on the shop scene root by
   attachTilt (gyro) and inherit down here; at rest the band sits mid-card and
   only sweeps when the phone is physically tilted. Transform-only
   (compositor-safe on Android WebView); no blend-mode / paint-property anim. */
.sh-foil::after {
  content: '';
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: -60%;
  width: 60%;
  background: linear-gradient(
    115deg,
    transparent 38%,
    rgba(255, 255, 255, 0.22) 50%,
    transparent 62%
  );
  transform: translate3d(calc(150% + var(--mx, 0) * 150%), calc(var(--my, 0) * 24%), 0);
  transition: transform 0.12s linear;
  will-change: transform;
  pointer-events: none;
}
/* Reduced motion: pin the sheen to its resting position; ignore tilt. */
@media (prefers-reduced-motion: reduce) {
  .sh-foil::after {
    transform: translate3d(150%, 0, 0);
    transition: none;
  }
}

/* No-foil tiles (packs) — the product's own full-art background fills the tile;
   no holo backing, art covers, and a heavier veil keeps the text readable. */
.sh-tile--nofoil {
  background: #17151b;
}
.sh-tile--nofoil .sh-art {
  inset: 0;
  top: 0;
  height: 100%;
}
.sh-tile--nofoil .sh-art img {
  max-width: 100%;
  max-height: 100%;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sh-tile--nofoil .sh-veil {
  background:
    radial-gradient(120% 80% at 50% 20%, rgba(8, 6, 9, 0.05) 30%, rgba(8, 6, 9, 0.5) 100%),
    linear-gradient(
      180deg,
      rgba(8, 6, 9, 0.2) 0%,
      rgba(8, 6, 9, 0) 34%,
      rgba(10, 7, 9, 0.9) 66%,
      #0a0709 100%
    );
}
.sh-glow {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(
    70% 52% at 50% 40%,
    color-mix(in oklab, var(--sh-g, var(--cm-red)) 40%, transparent) 0%,
    transparent 70%
  );
}
.sh-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    radial-gradient(125% 80% at 50% 22%, rgba(8, 6, 9, 0.12) 30%, rgba(8, 6, 9, 0.55) 100%),
    linear-gradient(
      180deg,
      rgba(8, 6, 9, 0.1) 0%,
      rgba(8, 6, 9, 0) 28%,
      rgba(10, 7, 9, 0.82) 62%,
      #0a0709 100%
    );
}
.sh-art {
  position: absolute;
  left: 0;
  right: 0;
  top: 7%;
  height: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.sh-art img {
  max-width: 66%;
  max-height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.55));
}
.sh-art-glyph {
  font-family: var(--font-mono);
  font-size: 52px;
  line-height: 1;
  opacity: 0.9;
  filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.55));
}
.sh-frame {
  position: absolute;
  inset: 6px;
  border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  z-index: 3;
  pointer-events: none;
}
.sh-badge {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 5;
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.1em;
  line-height: 1;
  padding: 4px 7px;
  text-transform: uppercase;
  border-radius: 7px;
}
.sh-badge.is-legendary {
  background: var(--cm-gold);
  color: #0c0c0e;
}
.sh-badge.is-epic {
  background: #8e5cff;
  color: #fff;
}
.sh-badge.is-rare {
  background: #8fb9e0;
  color: #0c0c0e;
}
.sh-badge.is-uncommon,
.sh-badge.is-common {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
}
.sh-tag {
  position: absolute;
  top: 9px;
  right: 9px;
  z-index: 5;
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.1em;
  padding: 3px 6px;
  border-radius: 5px;
  background: var(--cm-red);
  color: #fff;
}
.sh-tag.is-owned {
  background: rgba(123, 211, 137, 0.16);
  border: 1px solid rgba(123, 211, 137, 0.4);
  color: #9ee6ad;
}
.sh-tag.is-core {
  background: rgba(143, 185, 224, 0.14);
  border: 1px solid rgba(143, 185, 224, 0.35);
  color: #b8d8f3;
}
.sh-plate {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  padding: 0 11px 11px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sh-nm {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.03em;
  line-height: 1.05;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.7);
}
.sh-sub {
  font-size: 8.5px;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.62);
  line-height: 1.28;
  min-height: 10px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sh-anchor {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
}
.sh-was {
  font-size: 9px;
  color: rgba(255, 255, 255, 0.42);
  text-decoration: line-through;
}
.sh-disc {
  font-family: var(--font-mono);
  font-size: 8px;
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--cm-red);
  color: #fff;
}
.sh-buy {
  margin-top: 5px;
  height: 27px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  background: rgba(0, 0, 0, 0.42);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.22);
}
.sh-buy.is-owned {
  background: rgba(123, 211, 137, 0.14);
  border-color: rgba(123, 211, 137, 0.4);
  color: #9ee6ad;
  font-size: 9px;
  letter-spacing: 0.12em;
}
.sh-buy img {
  width: 14px;
  height: 14px;
  display: block;
}

/* ── Currency Store + confirm sheets (reuse the modal shell) ────────── */
.sh-sheet {
  width: min(94vw, 420px);
  max-height: 86vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: #0d0b10;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 22px;
  padding: 20px 18px calc(18px + env(safe-area-inset-bottom));
}
.sh-sheet-head {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 16px;
}
.sh-sheet-title {
  font-family: var(--font-mono);
  font-size: 18px;
  letter-spacing: 0.08em;
}
.sh-sheet-note {
  font-size: 9px;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.44);
  line-height: 1.5;
}
.sh-store-group {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.4);
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 14px 2px 9px;
}
.sh-store-group img {
  width: 15px;
  height: 15px;
}
.sh-store-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.sh-pack {
  position: relative;
  border-radius: 14px;
  background: #17151b;
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: 18px 12px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s var(--cm-ease, ease);
}
.sh-pack:active {
  transform: scale(0.97);
}
.sh-pack.is-best {
  border-color: rgba(232, 195, 107, 0.55);
}
.sh-pack-icon {
  width: 40px;
  height: 40px;
  object-fit: contain;
}
.sh-pack-model {
  width: 72px;
  height: 72px;
  margin: -8px 0 -2px;
}
.sh-pack-amt {
  font-family: var(--font-mono);
  font-size: 16px;
}
.sh-pack-bonus {
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.06em;
  color: #7bd389;
}
.sh-pack-price {
  margin-top: 4px;
  height: 28px;
  min-width: 74px;
  padding: 0 12px;
  border-radius: 125px;
  background: var(--cm-red);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sh-pack-badge {
  position: absolute;
  top: -7px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 7px;
  letter-spacing: 0.12em;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--cm-gold);
  color: #0c0c0e;
  white-space: nowrap;
}

/* Currency purchase confirm */
.sh-confirm {
  width: min(90vw, 340px);
  background: #0d0b10;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 22px;
  padding: 22px 20px calc(20px + env(safe-area-inset-bottom));
  text-align: center;
}
.sh-confirm-art {
  width: 96px;
  height: 96px;
  margin: 0 auto 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* The live model gets enough room for its rotation to read. */
.sh-confirm-art.has-model {
  width: 156px;
  height: 156px;
}
.item-3d {
  position: relative;
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
}
.item-3d-status {
  position: absolute;
  inset: 18%;
  z-index: 0;
  display: grid;
  place-items: center;
  border: 1px solid rgba(190, 196, 215, 0.22);
  border-radius: 18%;
  background: radial-gradient(circle at 50% 34%, rgba(117, 126, 153, 0.16), rgba(9, 9, 13, 0.24));
  color: rgba(220, 224, 236, 0.48);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  opacity: 1;
  transition: opacity 0.2s cubic-bezier(0.25, 1, 0.5, 1);
  pointer-events: none;
}
.item-3d.is-model-failed .item-3d-status {
  border-style: dashed;
  color: rgba(220, 224, 236, 0.34);
}
.item-3d-canvas {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity 0.24s ease;
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.5));
}
.item-3d-canvas.is-ready {
  opacity: 1;
}
.item-3d.is-model-ready .item-3d-status {
  opacity: 0;
}
.sh-confirm-name {
  font-family: var(--font-mono);
  font-size: 17px;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}
.sh-confirm-sub {
  font-size: 10px;
  letter-spacing: 0.03em;
  color: rgba(255, 255, 255, 0.55);
  line-height: 1.5;
  margin-bottom: 16px;
}
.sh-confirm-price {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 22px;
  margin-bottom: 18px;
}
.sh-confirm-price img {
  width: 22px;
  height: 22px;
}
.sh-confirm-msg {
  min-height: 14px;
  font-size: 10px;
  letter-spacing: 0.03em;
  margin-bottom: 12px;
  color: rgba(255, 255, 255, 0.55);
}
.sh-confirm-msg.is-error {
  color: #ff6b74;
}
.sh-confirm-msg.is-ok {
  color: #9ee6ad;
}
.sh-confirm-actions {
  display: flex;
  gap: 10px;
}

/* =========================================================================
   SHOP v2 — pixel port of the "Cardomancer-Canvas Shop" prototype.
   Hub: blurred battle backdrop + veil, pill tabs, featured banner, 2-col
   consumable tiles with live models. Detail: 252×348 holo-foil card
   (scrubbed foil canvas + live model), rarity bars, stat tiles, EFFECT/LORE,
   ACQUIRE bar. Animates transform/opacity only; the blur layer is STATIC.
   ========================================================================= */

.sh2-screen {
  position: relative;
  overflow: hidden;
}
/* Static blurred backdrop (§3). scale(1.25) bleeds the blur edges off-screen.
   Never animate anything over or under this layer. */
.sh2-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url('/src/assets/shop2/battle-bg.jpg') center / cover no-repeat;
  filter: blur(26px) brightness(0.3) saturate(0.7);
  transform: scale(1.25);
  pointer-events: none;
}
.sh2-veil {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(120% 70% at 50% 16%, rgba(215, 25, 33, 0.15), transparent 60%),
    linear-gradient(
      180deg,
      rgba(0, 0, 0, 0.55) 0%,
      rgba(0, 0, 0, 0.25) 30%,
      rgba(0, 0, 0, 0.8) 80%,
      #000 100%
    );
  pointer-events: none;
}
.sh-wrap.sh2 {
  position: relative;
  z-index: 1;
}

/* ── Hub column — cross-slides out when the detail opens ─────────────── */
.sh2-hub {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  transition:
    opacity 0.25s ease,
    transform 0.3s var(--cm-ease, ease);
}
.sh2-hub.is-hide {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-12px);
}

/* ── Header (§3.1): 36px round back · SHOP .32em · wallet chips ──────── */
.sh2 .sh-top {
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
  padding-bottom: 10px;
}
.sh2 .sh-back {
  width: 36px;
  height: 36px;
}
.sh2 .sh-title {
  font-size: 17px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
}

/* ── Tabs (§3.2): capsule pills, active white, horizontal scroll ─────── */
.sh2 .sh-tabs {
  position: static;
  display: flex;
  gap: 8px;
  padding: 13px 16px 3px;
  background: transparent;
  overflow-x: auto;
  scrollbar-width: none;
  flex: none;
}
.sh2 .sh-tabs::-webkit-scrollbar {
  display: none;
}
.sh2 .sh-tab {
  flex: 0 0 auto;
  height: 30px;
  padding: 0 14px;
  border-radius: var(--cm-r-pill, 125px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: transparent;
  color: rgba(255, 255, 255, 0.6);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition:
    background 0.28s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1)),
    color 0.28s,
    border-color 0.28s,
    transform 0.18s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}
.sh2 .sh-tab.is-on {
  background: #fff;
  color: #111;
  border-color: #fff;
}
.sh2 .sh-tab:active {
  transform: scale(0.92);
}

/* ── Scroll area (§3.3) ──────────────────────────────────────────────── */
.sh2 .sh-scroll {
  padding: 14px 16px calc(130px + env(safe-area-inset-bottom));
}

/* ── Featured banner (§3.4) ──────────────────────────────────────────── */
.sh2-banner {
  position: relative;
  height: 150px;
  border-radius: 18px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  background: radial-gradient(95% 150% at 84% 50%, #4a1016, #140709 72%);
  border: 1px solid rgba(215, 25, 33, 0.4);
  padding: 0 16px;
  margin-bottom: 20px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sh2-banner:active {
  transform: scale(0.99);
}
.sh2-banner-tag {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.2em;
  color: #ff8e96;
}
.sh2-banner-nm {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: 21px;
  letter-spacing: 0.03em;
  line-height: 1.05;
  margin: 6px 0 8px;
  max-width: 58%;
}
.sh2-banner-prices {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 11px;
}
.sh2-old {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
  text-decoration: line-through;
}
.sh2-old img {
  width: 12px;
  height: 12px;
  opacity: 0.6;
}
.sh2-new {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-mono);
  font-size: 15px;
  color: #fff;
}
.sh2-new img {
  width: 15px;
  height: 15px;
}
.sh2-off {
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.1em;
  font-weight: 700;
  background: var(--cm-red);
  color: #fff;
  padding: 2px 7px;
  border-radius: 7px;
}
.sh2-banner-buy {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 16px;
  border-radius: var(--cm-r-pill, 125px);
  background: #fff;
  color: #15101a;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.sh2-banner-buy img {
  width: 13px;
  height: 13px;
}
.sh2-banner-model {
  position: absolute;
  right: -14px;
  bottom: -10px;
  width: 160px;
  height: 160px;
  z-index: 0;
  pointer-events: none;
}
.sh2-banner-model .item-3d,
.sh2-banner-model .item-3d-canvas {
  width: 100%;
  height: 100%;
}
.sh2-banner-model .item-3d-canvas {
  filter: drop-shadow(0 12px 18px rgba(0, 0, 0, 0.5));
}

/* ── Section headers + tiles (§3.5) ──────────────────────────────────── */
.sh2-sech {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.26em;
  color: rgba(255, 255, 255, 0.42);
  text-transform: uppercase;
  margin: 20px 2px 8px;
}
.sh2-banner-slot + .sh-content .sh2-sech:first-child,
.sh-content > .sh2-sech:first-child {
  margin-top: 2px;
}
.sh2-grid {
  gap: 12px;
  padding: 2px 0 6px;
}
.sh2-tile {
  position: relative;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  overflow: hidden;
  background: radial-gradient(120% 80% at 50% 0%, #16151a, #0e0e11 74%);
  display: flex;
  flex-direction: column;
  cursor: pointer;
  color: #fff;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform 0.14s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1)),
    border-color 0.2s;
}
.sh2-tile:active {
  transform: scale(0.96);
}
.sh2-art {
  width: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.sh2-art img {
  max-width: 76%;
  max-height: 84%;
  object-fit: contain;
  filter: drop-shadow(0 10px 16px rgba(0, 0, 0, 0.55));
}
.sh2-art--model .item-3d,
.sh2-art--model .item-3d-canvas {
  width: 86%;
  height: 86%;
}
.sh2-art--model .item-3d-canvas {
  object-fit: contain;
}
.sh2-art .sh-art-glyph {
  font-size: 52px;
}
.sh2-rp {
  position: absolute;
  top: 9px;
  left: 9px;
  z-index: 2;
  height: 15px;
  display: inline-flex;
  align-items: center;
  padding: 0 7px;
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 7px;
  letter-spacing: 0.12em;
  font-weight: 700;
  color: #0c0c0e;
  text-transform: uppercase;
}
.sh2-body {
  padding: 0 12px 13px;
  margin-top: -2px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.sh2-tnm {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.04em;
  line-height: 1.05;
}
.sh2-tprice {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: 0.04em;
}
.sh2-tprice img {
  width: 13px;
  height: 13px;
}
.sh2-tprice.is-sale {
  gap: 8px;
}
.sh2-tprice-o {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  color: rgba(255, 255, 255, 0.4);
  text-decoration: line-through;
}
.sh2-tprice-o img {
  width: 9px;
  height: 9px;
  opacity: 0.6;
}
.sh2-tprice-n {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--cm-red-hot, #ff4b54);
}
.sh2-tprice-n img {
  width: 13px;
  height: 13px;
}
.sh2-tprice.is-owned {
  font-size: 9px;
  letter-spacing: 0.12em;
  color: #9ee6ad;
}

/* ── Entrance stagger (§3.6) — translate-only, re-triggered per tab ──── */
@keyframes sh2RowIn {
  from {
    transform: translateY(14px);
  }
  to {
    transform: none;
  }
}
@keyframes sh2SechIn {
  from {
    transform: translateY(8px);
  }
  to {
    transform: none;
  }
}
.sh-anim .sh2-tile,
.sh-anim .sh2-banner {
  animation: sh2RowIn 0.42s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1)) both;
}
.sh-anim .sh2-sech {
  animation: sh2SechIn 0.32s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1)) both;
}

/* ── Detail view (§4) — cross-slides over the hub ────────────────────── */
.sh2-detail {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transform: translateX(16px);
  transition:
    opacity 0.25s ease,
    transform 0.3s var(--cm-ease, ease);
}
.sh2-detail.is-show {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}
.sh2-dtitle {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.sh2-dscroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 6px 22px calc(150px + env(safe-area-inset-bottom));
  scrollbar-width: none;
}
.sh2-dscroll::-webkit-scrollbar {
  display: none;
}

/* The card (§4.1). */
.sh2-cardwrap {
  position: relative;
  display: flex;
  justify-content: center;
  padding: 10px 0 4px;
  perspective: 800px;
  /* Horizontal finger-drags over the card drive the light rig (pointermove)
     even without motion permission; vertical still scrolls the sheet. */
  touch-action: pan-y;
}
.sh2-card {
  position: relative;
  width: 252px;
  height: 348px;
  border-radius: 16px;
  background: #0b0a0d;
  overflow: hidden;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.35);
  transition: transform 160ms ease;
  will-change: transform;
}
/* Live light-rig mode: the JS spring drives rotation every frame — the CSS
   transition would double-smooth it into mush. Static/reduced keeps it. */
.sh2-card--live {
  transition: none;
}
/* Foil backing — a paused all-intra video scrubbed by tilt/cursor, over a
   static holo still that doubles as decode poster + failure fallback. */
.sh2-foil {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* Self-clip for the same reason as .sh2-plate — never lean on the card's
     rounded overflow when the card is a composited 3D layer. */
  border-radius: 16px;
  overflow: hidden;
}
.sh2-foilimg,
.sh2-foilvid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Native builds scrub pre-captured frames on a canvas instead (foil-frames.ts
   — mobile WebViews are too slow at per-frame video seeks). */
.sh2-foilcv {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.sh2-foilvid {
  opacity: 0;
  transition: opacity 0.35s ease;
}
.sh2-foil.is-live .sh2-foilvid {
  opacity: 1;
}
.sh2-dart {
  position: absolute;
  left: 0;
  right: 0;
  top: 6px;
  height: 236px;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  will-change: transform;
  pointer-events: none;
}
.sh2-dart .item-3d,
.sh2-dart .item-3d-canvas {
  width: 212px;
  height: 212px;
}
.sh2-dart .item-3d-canvas {
  object-fit: contain;
  filter: drop-shadow(0 12px 20px rgba(0, 0, 0, 0.55));
}
.sh2-dframe {
  position: absolute;
  inset: 9px;
  z-index: 3;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  pointer-events: none;
}
/* The plate paints an OPAQUE gradient all the way to the card's bottom edge, so
   it needs its own bottom radius. It used to rely purely on .sh2-card's
   `border-radius + overflow:hidden`, but the card is a 3D-transformed,
   will-change:transform composited layer, and Chromium drops the rounded clip
   for a plain rect clip on such subtrees — which showed up on Android as square
   bottom corners while the top two looked fine (nothing opaque paints there;
   the foil canvas rounds itself). */
.sh2-plate {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  height: 104px;
  padding: 18px 16px 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
  background: linear-gradient(180deg, rgba(11, 10, 13, 0), rgba(15, 9, 10, 0.84) 32%, #120a0b 62%);
  border-bottom-left-radius: 16px;
  border-bottom-right-radius: 16px;
  pointer-events: none;
}
.sh2-pnm {
  font-family: var(--font-mono);
  font-size: 22px;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}
.sh2-psub {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.24em;
}
.sh2-porigin {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.6);
}
/* ── Light rig (§5) — one virtual light drives every layer below. All layers
   are card-sized (clipped by .sh2-card's overflow:hidden), pre-painted ONCE,
   and animated ONLY via transform/opacity — zero per-frame paint work. The
   card-sized mix-blend-mode layers follow the old .sh2-gloss precedent; never
   grow them to full-screen. ────────────────────────────────────────────── */

/* Specular hotspot — replaces the repainted --gx/--gy gradient: the gradient
   is painted once on an oversized layer and TRANSLATED under the light. */
.sh2-spec {
  position: absolute;
  left: -40%;
  top: -40%;
  width: 180%;
  height: 180%;
  z-index: 4;
  opacity: 0;
  background: radial-gradient(
    circle 170px at 50% 50%,
    rgba(255, 255, 255, 0.55),
    rgba(255, 255, 255, 0) 70%
  );
  mix-blend-mode: screen;
  will-change: transform, opacity;
  pointer-events: none;
}
/* Environment reflection — diagonal streaks counter-sliding across the foil
   like a window reflection on a real holo card. */
.sh2-env {
  position: absolute;
  top: -5%;
  left: -60%;
  width: 220%;
  height: 110%;
  z-index: 1;
  opacity: 0.14;
  background: repeating-linear-gradient(
    105deg,
    rgba(255, 255, 255, 0) 0 40px,
    rgba(255, 255, 255, 0.05) 40px 70px,
    rgba(190, 160, 255, 0.09) 70px 86px,
    rgba(255, 255, 255, 0) 86px 150px
  );
  mix-blend-mode: screen;
  will-change: transform, opacity;
  pointer-events: none;
}
/* Edge rim lights — static box-shadow paints, opacity-only crossfades as the
   light passes each edge (the light "catching" the card). */
.sh2-rim {
  position: absolute;
  inset: 6px;
  z-index: 5;
  border-radius: 12px;
  opacity: 0;
  will-change: opacity;
  pointer-events: none;
}
.sh2-rim--l {
  box-shadow: inset 3px 0 12px -4px rgba(185, 225, 255, 0.7);
}
.sh2-rim--r {
  box-shadow: inset -3px 0 12px -4px rgba(255, 205, 170, 0.7);
}
.sh2-rim--t {
  box-shadow: inset 0 3px 12px -4px rgba(255, 255, 255, 0.55);
}
.sh2-rim--b {
  box-shadow: inset 0 -3px 12px -4px rgba(200, 160, 255, 0.5);
}
/* Contact shadow on the stage floor — slides opposite the light, grounding
   the card in space (the depth cue the flat drop-shadow never gave). */
.sh2-stage-shadow {
  position: absolute;
  left: 50%;
  bottom: -4px;
  width: 210px;
  height: 38px;
  margin-left: -105px;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0) 70%);
  opacity: 0.45;
  will-change: transform, opacity;
  pointer-events: none;
}
/* Energy surge — one-shot ring pop when shake energy crosses the high tier. */
.sh2-surge {
  position: absolute;
  inset: 0;
  z-index: 6;
  opacity: 0;
  background: radial-gradient(
    circle at 50% 45%,
    rgba(255, 255, 255, 0.32),
    rgba(140, 210, 255, 0.14) 40%,
    rgba(255, 255, 255, 0) 72%
  );
  pointer-events: none;
}
.sh2-surge.is-surge {
  animation: sh2-surge-pop 0.6s ease-out both;
}
@keyframes sh2-surge-pop {
  0% {
    opacity: 0;
    transform: scale(0.6);
  }
  30% {
    opacity: 0.85;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1.18);
  }
}

/* Rarity row (§4.2). */
.sh2-rarity {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 18px 0 4px;
}
.sh2-rlab {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.5);
  text-transform: uppercase;
}
.sh2-rbars {
  display: flex;
  gap: 4px;
}
.sh2-rbar {
  width: 18px;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.16);
}
.sh2-rbar.is-on {
  background: var(--cm-red);
}

/* Stats grid (§4.3). Solid-ish backgrounds instead of backdrop-filter — the
   panel slides during the cross-fade and per-frame backdrop re-blur is a
   WebView compositing no-go. */
.sh2-stats {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 9px;
  margin-top: 18px;
}
.sh2-stat {
  background: rgba(20, 20, 22, 0.8);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 14px;
  padding: 13px 8px 11px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}
.sh2-sglyph {
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sh2-sglyph img {
  height: 18px;
  width: auto;
  display: block;
}
.sh2-sval {
  font-family: var(--font-mono);
  font-size: 17px;
}
.sh2-slab {
  font-family: var(--font-mono);
  font-size: 7.5px;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.45);
  text-transform: uppercase;
}

/* Info blocks (§4.4). */
.sh2-block {
  margin-top: 14px;
  background: rgba(18, 18, 20, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  padding: 15px 16px;
}
.sh2-bh {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.24em;
  color: var(--cm-red);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.sh2-btxt {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  color: #fff;
}
.sh2-btxt--lore {
  font-size: 13.5px;
  line-height: 1.66;
  color: rgba(255, 255, 255, 0.82);
}
.sh2-kv {
  display: flex;
  gap: 16px;
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.sh2-kv-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sh2-k {
  font-family: var(--font-mono);
  font-size: 7.5px;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.4);
  text-transform: uppercase;
}
.sh2-v {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  color: #fff;
}

/* CTA (§4.5). */
.sh2-cta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  display: flex;
  padding: 14px 22px calc(28px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.82) 36%, #000);
  pointer-events: none;
}
.sh2-acquire {
  pointer-events: auto;
  flex: 1;
  height: 54px;
  border: 0;
  border-radius: var(--cm-r-pill, 125px);
  background: var(--cm-red);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 8px 24px rgba(215, 25, 33, 0.4);
  transition:
    transform 80ms ease,
    background 120ms ease;
}
.sh2-acquire:active {
  background: var(--cm-red-deep);
  transform: translateY(1px);
}
.sh2-acquire img {
  width: 16px;
  height: 16px;
  display: block;
}

/* Reduced motion: no entrance animation, no cross-slide travel, flat card
   (JS already skips tilt/pointer/scrub input). */
@media (prefers-reduced-motion: reduce) {
  .sh-anim .sh2-tile,
  .sh-anim .sh2-banner,
  .sh-anim .sh2-sech {
    animation: none;
  }
  .sh2-hub,
  .sh2-detail,
  .sh2-card {
    transition: none;
  }
  .sh2-hub.is-hide {
    transform: none;
  }
  .sh2-detail {
    transform: none;
  }
  /* Light-rig layers stay dark and the surge never plays — the JS loop is
     also skipped, so the card is a flat still exactly as before. */
  .sh2-spec,
  .sh2-env,
  .sh2-rim,
  .sh2-stage-shadow,
  .sh2-surge {
    opacity: 0 !important;
    animation: none !important;
  }
}

/* =========================================================================
   Reduced-motion — in-app switch (gameplay-prefs) that mirrors the OS setting.
   ========================================================================= */
.cm-reduce-motion *,
.cm-reduce-motion *::before,
.cm-reduce-motion *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

/* =========================================================================
   SETTINGS — profile card + grouped red-chip rows (ported from Settings.html).
   ========================================================================= */
.st-wrap {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  max-width: 480px;
  margin-inline: auto;
  /* Reinstate the safe-area insets that #app zeroes for .cm-screen scenes —
     .st-wrap is NOT a .cm-stack, so without this the SETTINGS header sits under
     the status bar / camera cutout and flush to the screen edge on notched
     phones. Horizontal inset lives here (not on .st-body) so the header and the
     scrolling rows share the same 16px gutter. */
  padding: calc(env(safe-area-inset-top) + 6px) max(16px, env(safe-area-inset-right)) 0
    max(16px, env(safe-area-inset-left));
}
.st-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* Horizontal gutter now comes from .st-wrap; keep only vertical padding here. */
  padding: 4px 0 calc(30px + env(safe-area-inset-bottom));
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
}
.st-body::-webkit-scrollbar {
  width: 8px;
}
.st-body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.22);
  border-radius: 4px;
}
.st-body::-webkit-scrollbar-track {
  background: transparent;
}

/* Profile card */
.st-prof {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 20px;
  padding: 16px;
  margin: 6px 0 4px;
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background:
    radial-gradient(120% 120% at 20% -10%, rgba(215, 25, 33, 0.28), transparent 60%),
    rgba(255, 255, 255, 0.03);
  transition: transform 0.12s var(--cm-ease, ease);
}
.st-prof:active {
  transform: scale(0.99);
}
.st-prof-av {
  position: relative;
  width: 54px;
  height: 54px;
  flex: none;
  border-radius: 15px;
  overflow: hidden;
  background: rgba(215, 25, 33, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 24px;
  color: #fff;
}
.st-prof-av-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.st-prof-info {
  flex: 1;
  min-width: 0;
}
.st-prof-name {
  font-family: var(--font-mono);
  font-size: 16px;
  letter-spacing: 0.04em;
  line-height: 1.1;
}
.st-prof-meta {
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 5px;
}
.st-prof-chev {
  flex: none;
  color: rgba(255, 255, 255, 0.4);
  display: flex;
}
.st-prof-bar {
  flex-basis: 100%;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
  margin-top: 4px;
}
.st-prof-bar-fill {
  display: block;
  height: 100%;
  /* Full width, revealed via scaleX — compositor-only, no per-frame relayout
     (the old `transition: width` animated a layout property). */
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  border-radius: 3px;
  background: #fff;
  transition: transform 0.5s var(--cm-ease, ease);
}

/* Section header */
.st-sec {
  margin-top: 8px;
}
.st-sech {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.24em;
  color: rgba(255, 255, 255, 0.42);
  margin: 20px 2px 8px;
}
.st-sech::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(255, 255, 255, 0.1);
}
.st-sech--danger {
  color: rgba(255, 90, 98, 0.7);
}
.st-sech--danger::after {
  background: rgba(215, 25, 33, 0.28);
}

/* Row */
.st-row {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 58px;
  width: 100%;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.09);
  padding: 8px 14px;
  margin-bottom: 10px;
  color: #fff;
  text-align: left;
}
.st-row--btn {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s var(--cm-ease, ease);
}
.st-row--btn:active {
  transform: scale(0.985);
}
.st-chip {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 13px;
  background: rgba(215, 25, 33, 0.16);
  border: 1px solid rgba(215, 25, 33, 0.34);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.st-row-txt {
  flex: 1;
  min-width: 0;
}
.st-row-title {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.1;
}
.st-row-sub {
  font-size: 9.5px;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 4px;
}
.st-row-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}
.st-row-val {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.7);
}
.st-row-chev {
  color: rgba(255, 255, 255, 0.4);
  display: flex;
}

/* Pill toggle */
.st-tog {
  position: relative;
  width: 46px;
  height: 25px;
  flex: none;
  border: 0;
  border-radius: 125px;
  background: rgba(255, 255, 255, 0.16);
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.22s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}
/* The 46x25 pill is well under the 44pt/48dp touch minimum and the row itself
   isn't tappable — extend the hit area without moving the visual. The row is
   ≥58px tall so -12px stays inside it. */
.st-tog::after {
  content: '';
  position: absolute;
  inset: -12px -8px;
}
.st-tog.is-on {
  background: var(--cm-red);
}
.st-tog-knob {
  display: block;
  width: 19px;
  height: 19px;
  margin: 3px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.22s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}
.st-tog.is-on .st-tog-knob {
  transform: translateX(21px);
}

/* Segmented picker (board slot shape) */
.st-row--seg {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}
.st-seg-head {
  display: flex;
  align-items: center;
  gap: 14px;
}
.st-seg {
  display: flex;
  gap: 8px;
}
.st-seg-btn {
  flex: 1;
  /* 48dp Android / 44pt iOS minimum — the glyph is small, the target is not. */
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 4px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.04);
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform 0.12s var(--cm-ease, ease),
    background 0.18s var(--cm-ease, ease),
    color 0.18s var(--cm-ease, ease);
}
.st-seg-btn:active {
  transform: scale(0.97);
}
.st-seg-btn.is-on {
  background: rgba(215, 25, 33, 0.16);
  border-color: rgba(215, 25, 33, 0.5);
  color: #fff;
}
/* The glyph IS the slot: same aspect and same corner treatment the board uses,
   so the row previews the setting instead of describing it. */
.st-seg-glyph {
  display: block;
  width: 15px;
  height: 21px;
  border-radius: 3px;
  background: currentColor;
  opacity: 0.9;
}
.st-seg-glyph--v1,
.st-seg-glyph--v2 {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  background: transparent;
  border: 1.5px solid currentColor;
  opacity: 0.95;
  position: relative;
}
.st-seg-glyph--v1::after {
  content: '';
  position: absolute;
  inset: 4px;
  background: currentColor;
  opacity: 0.35;
}
.st-seg-glyph--v2 {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  background: currentColor;
}
.st-seg-lbl {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
}

/* Dot slider */
.st-row--slider .st-row-txt {
  flex: 0 0 auto;
  max-width: 40%;
}
.st-dots-wrap {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  justify-content: flex-end;
}
.st-dots {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  touch-action: none;
  /* 15px bars + 8px pad = 31px, under the 44pt minimum for the sole volume
     control. 15px pad brings the drag strip to ~45px; bars are unchanged. */
  padding: 15px 0;
}
.st-dots:focus-visible {
  outline: 2px solid var(--cm-red);
  outline-offset: 4px;
  border-radius: 4px;
}
.st-dots i {
  width: 7px;
  height: 15px;
  border-radius: 1.5px;
  background: rgba(255, 255, 255, 0.18);
  transition: background 0.12s ease;
}
.st-dots i.is-on {
  background: #fff;
}
.st-dots-val {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255, 255, 255, 0.7);
  min-width: 2ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Danger zone */
.st-logout {
  width: 100%;
  height: 46px;
  border-radius: 14px;
  background: transparent;
  border: 1px solid rgba(215, 25, 33, 0.5);
  color: #ff5a62;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s var(--cm-ease, ease);
}
.st-logout:active {
  transform: scale(0.985);
}
.st-foot {
  text-align: center;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.25);
  margin-top: 22px;
}

/* Sign-out confirm dialog (destructive-action gate) */
.st-confirm {
  width: min(340px, calc(100vw - 48px));
  padding: 22px 20px 18px;
  border-radius: 18px;
  background: #16090b;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
}
.st-confirm-title {
  font-family: var(--font-mono);
  font-size: 16px;
  letter-spacing: 0.06em;
  color: #fff;
  margin-bottom: 8px;
}
.st-confirm-body {
  font-size: 13px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.62);
  margin-bottom: 20px;
}
.st-confirm-actions {
  display: flex;
  gap: 10px;
}
.st-confirm-btn {
  flex: 1;
  min-height: 46px;
  border-radius: 13px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s var(--cm-ease, ease);
}
.st-confirm-btn:active {
  transform: scale(0.97);
}
.st-confirm-cancel {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: #fff;
}
.st-confirm-danger {
  background: var(--cm-red);
  border: 1px solid var(--cm-red);
  color: #fff;
}
.st-confirm-danger[disabled] {
  opacity: 0.6;
}

/* =========================================================================
   PROFILE — hero card + CAREER KPI tiles (ported from Profile.html). All values
   are real ProfileStats; no invented level/rank/faculty data.
   ========================================================================= */
/* Slim styled scrollbar on the profile scroll container (was the default OS
   bar — visible + ugly on desktop and some Android WebViews). Matches the
   marketplace/settings treatment. */
.profile-root {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
}
.profile-root::-webkit-scrollbar {
  width: 8px;
}
.profile-root::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.22);
  border-radius: 4px;
}
.profile-root::-webkit-scrollbar-track {
  background: transparent;
}

.profile-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 22px;
  padding: 22px 18px 20px;
  margin: 4px 0 6px;
  background:
    radial-gradient(120% 120% at 50% -10%, rgba(201, 162, 232, 0.34), rgba(0, 0, 0, 0.2) 65%),
    rgba(255, 255, 255, 0.02);
}
.profile-hero-av {
  position: relative;
  width: 88px;
  height: 88px;
  flex: none;
  border-radius: 24px;
  background: rgba(215, 25, 33, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.5);
  padding: 0;
  overflow: hidden;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: transform 0.12s var(--cm-ease, ease);
}
.profile-hero-av:active {
  transform: scale(0.96);
}
.profile-hero-av.is-busy {
  opacity: 0.85;
  pointer-events: none;
}
/* Upload can take a few seconds on mobile data — show a spinner so the tap
   doesn't read as "nothing happened". */
.profile-hero-av.is-busy::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  animation: cm-spin 0.7s linear infinite;
}
.profile-hero-av-initial {
  font-family: var(--font-mono);
  font-size: 40px;
  line-height: 1;
}

/* Uploaded avatar filling the round hub/identity disc (cm-avatar primitive). */
.cm-avatar-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}
.profile-hero-av-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.profile-hero-av-edit {
  position: absolute;
  right: -1px;
  bottom: -1px;
  z-index: 2;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--cm-red);
  border: 2px solid #0c0708;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.profile-hero-name {
  font-family: var(--font-mono);
  font-size: 22px;
  letter-spacing: 0.03em;
  margin-top: 14px;
  /* A long unbroken display name must wrap, not overflow + clip on 320-360px. */
  max-width: 100%;
  overflow-wrap: anywhere;
}
.profile-hero-tags {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 10px;
}
.profile-hero-rank {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 11px;
  border-radius: 125px;
  background: rgba(143, 185, 224, 0.16);
  border: 1px solid rgba(143, 185, 224, 0.3);
  color: #bcd6ef;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
}
.profile-hero-rank-gem {
  color: #8fb9e0;
}
.profile-hero-sub {
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.5);
}

/* CAREER KPI tiles */
.profile-career {
  margin: 10px 0 4px;
}
.profile-career-head {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
  margin: 6px 2px 10px;
}
.profile-career-head::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(255, 255, 255, 0.1);
}
.profile-career-tiles {
  display: flex;
  gap: 10px;
}
.profile-career-tile {
  flex: 1;
  border-radius: 15px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  padding: 16px 8px;
  text-align: center;
}
.profile-career-val {
  font-family: var(--font-mono);
  font-size: 26px;
  letter-spacing: 0.02em;
  line-height: 1;
}
.profile-career-label {
  font-size: 8px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 8px;
}

/* =========================================================================
   EQUIP / LOADOUT — pre-battle chrome (matchup banner + chips + stat strip)
   layered above the existing arcana rail/list. Ported from Loadout Variants.
   ========================================================================= */
.eq-vs {
  position: relative;
  display: flex;
  align-items: center;
  height: 104px;
  /* The equip column is a flex parent — stop it compressing the banner. */
  flex: none;
  border-radius: 16px;
  overflow: hidden;
  margin: 6px 0 12px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: #140709;
}
/* Blurred battlefield backdrop (static — rendered once, no per-frame reblur). */
.eq-vs::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  /* the player's selected battle background (set via --eq-bg inline) */
  background: var(--eq-bg, url('/src/assets/bg/board-bg.jpg')) center/cover;
  opacity: 0.92;
}
.eq-vs::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  /* darken only the edges (behind YOU / ENEMY text) — center stays clear so the
     battlefield reads through, matching what the player sees in the match. */
  background: linear-gradient(
    90deg,
    rgba(8, 6, 9, 0.74) 0%,
    rgba(8, 6, 9, 0.22) 32%,
    rgba(8, 6, 9, 0.22) 68%,
    rgba(8, 6, 9, 0.74) 100%
  );
}
.eq-vs > * {
  position: relative;
  z-index: 2;
}

/* Section header (ARCANA RAIL · x/5 slotted) */
.eq-sech {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
  margin: 4px 2px 8px;
}
.eq-sech-t {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
}
.eq-sech-t::after {
  content: '';
}
.eq-sech-x {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.4);
}

/* Active set-bonus line */
.eq-setline {
  flex: none;
  margin: 10px 2px 4px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.42);
  line-height: 1.4;
}
.eq-setline.is-on {
  color: rgba(255, 255, 255, 0.72);
}
.eq-vs-side {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.eq-vs-side--enemy {
  text-align: right;
  align-items: flex-end;
}
.eq-vs-tag {
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.eq-vs-name {
  font-family: var(--font-mono);
  font-size: 17px;
  letter-spacing: 0.04em;
  margin-top: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.eq-vs-mid {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 0 14px;
  flex: none;
}
.eq-vs-glyph {
  color: var(--equip-accent, #fff);
  font-size: 16px;
}
.eq-vs-word {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--cm-red);
}

.eq-chips {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
  flex: none;
}
.eq-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 12px;
  border-radius: 125px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
}
.eq-chip-k {
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
}
.eq-chip-v {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.eq-stats {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex: none;
}
.eq-stat {
  flex: 1;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  padding: 13px 6px;
  text-align: center;
}
.eq-stat-v {
  font-family: var(--font-mono);
  font-size: 22px;
  line-height: 1;
}
.eq-stat-k {
  font-size: 8px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 7px;
}

/* ARCANA PICKER — bottom sheet holding the catalog (opened from a rail slot) */
.arcana-picker-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: #100a0c;
  border-top-left-radius: 22px;
  border-top-right-radius: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding: 14px 16px calc(env(safe-area-inset-bottom) + 16px);
  box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.6);
}
.arcana-picker-title {
  flex: none;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  padding: 4px 0 12px;
}
.arcana-picker-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
}
.arcana-picker-scroll::-webkit-scrollbar {
  width: 8px;
}
.arcana-picker-scroll::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.22);
  border-radius: 4px;
}

/* LOADOUT TUTORIAL COACH — guided overlay over the real equip scene. Light dim
   (non-blocking) + a glow ring on the spotlighted element; Jager dialog on top. */
.tut-coach-dim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.42);
  pointer-events: none;
  z-index: 40;
}
/* On narration (manual) steps the dim swallows taps on the real equip UI so the
   player can't equip early and skip the slot/pick steps. The Jager dialog sits
   above (higher z-index) and stays tappable. */
.tut-coach-dim--block {
  pointer-events: auto;
}
.tut-coach-spot {
  position: relative;
  z-index: 65;
  /* Keep the element's OWN border-radius (was `inherit`, which took the parent's
     0 and made the glow ring square) so the ring hugs its rounded corners. */
  animation: tut-ring-pulse 1.25s ease-in-out infinite;
}
/* Picker cards round a touch more so the highlight ring reads clearly rounded. */
.equip-card.tut-pick-target.tut-coach-spot {
  border-radius: 16px;
}
@keyframes tut-ring-pulse {
  0%,
  100% {
    box-shadow:
      0 0 0 2px rgba(246, 223, 145, 0.92),
      0 0 14px 3px rgba(215, 25, 33, 0.42);
  }
  50% {
    box-shadow:
      0 0 0 2px rgba(246, 223, 145, 1),
      0 0 24px 6px rgba(215, 25, 33, 0.72);
  }
}

/* Tutorial loadout — pre-slotted arcana are locked (badge, dimmed), and in the
   picker every card except the pulsating target is disabled. */
.equip-slot.tut-locked {
  position: relative;
  opacity: 0.8;
  cursor: default;
}
.equip-slot-lock {
  position: absolute;
  top: 5px;
  right: 7px;
  font-size: 11px;
  opacity: 0.85;
  pointer-events: none;
}
.equip-card.tut-pick-disabled {
  opacity: 0.32;
  pointer-events: none;
  filter: grayscale(0.5);
}
.tut-coach-dialog {
  /* The Core-v2 item action lives in the shared detail modal (z-index: 1000).
     Keep Jager visible while the real modal CTA remains the active target. */
  z-index: 1090 !important;
}

/* TUTORIAL — highlight interactive targets (ARCANIUM button + ability cards).
   The base .tutorial-spotlight only sets z-index; buttons/cards need a visible
   glow ring so the player knows exactly what to tap. */
.tutorial-root.tutorial-dim .game-action-row:has(.tutorial-spotlight) {
  z-index: 31;
}
/* ARCANIUM button lives in the action row (no clipping parent) — full glow. */
.tutorial-root.tutorial-dim .arcanium-btn.tutorial-spotlight {
  position: relative;
  z-index: 33;
  box-shadow:
    0 0 0 3px #fff,
    0 0 22px 6px rgba(255, 68, 102, 0.85) !important;
  animation: tutorial-mana-pulse 1.4s ease-in-out infinite;
}
/* Ability cards sit in an overflow-y:auto scroll list, so an OUTER glow gets
   clipped and a scale pulse pushes the card under the panel's rounded border.
   Use an INSET ring that PULSES (no scale, no outer spread) — stays perfectly
   inside the card; the sharp card already pops against its blurred neighbours. */
.tutorial-root.tutorial-dim .ability-btn.tutorial-spotlight {
  position: relative;
  z-index: 33;
  animation: tut-inset-pulse 1.4s ease-in-out infinite;
}
@keyframes tut-inset-pulse {
  0%,
  100% {
    box-shadow:
      inset 0 0 0 2px var(--cm-red, #d71921),
      inset 0 0 14px rgba(255, 68, 102, 0.35);
  }
  50% {
    box-shadow:
      inset 0 0 0 2px var(--cm-red, #d71921),
      inset 0 0 26px rgba(255, 68, 102, 0.6);
  }
}
/* Blur the non-target ability cards so only the highlighted one reads sharp. */
.tutorial-root.tutorial-dim
  .arcanium-content:has(.ability-btn.tutorial-spotlight)
  .ability-btn:not(.tutorial-spotlight) {
  filter: blur(4px) brightness(0.6);
}

/* ── PARTY scene (friend matches by code) ─────────────────────────────── */
.party-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 8px 4px 0;
}
.party-note {
  margin-bottom: 6px;
}
.party-toggles {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.party-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 48px;
  padding: 0 16px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: transform 0.12s var(--cm-ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}
.party-toggle:active {
  transform: scale(0.97);
}
.party-toggle-state {
  font-size: 10px;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.45);
}
.party-toggle-state.is-on {
  color: #fff;
}
.party-code-label {
  text-align: center;
}
/* Tap-to-copy button rendered to look exactly like the text it replaced. */
.party-code {
  display: block;
  width: 100%;
  box-sizing: border-box;
  background: none;
  border: 0;
  font-family: var(--font-mono);
  font-size: 40px;
  letter-spacing: 0.35em;
  text-align: center;
  padding: 18px 0 10px 0.35em; /* left pad balances the trailing tracking */
  color: #fff;
  cursor: pointer;
  user-select: text;
  -webkit-user-select: text;
  transition: transform 120ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.party-code:active {
  transform: scale(0.97);
}
@media (prefers-reduced-motion: reduce) {
  .party-code {
    transition: none;
  }
}
.party-share {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-align: center;
  color: rgba(255, 255, 255, 0.6);
}
.party-waiting {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-align: center;
  color: rgba(255, 255, 255, 0.45);
  padding: 16px 0 6px;
}
.party-code-input {
  width: 100%;
  box-sizing: border-box;
  height: 56px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 24px;
  letter-spacing: 0.3em;
  text-align: center;
  text-transform: uppercase;
  outline: none;
}
.party-code-input:focus {
  border-color: rgba(255, 255, 255, 0.6);
}
.eq-classic-note {
  text-align: center;
  letter-spacing: 0.14em;
  opacity: 0.7;
  padding: 14px 0;
}

/* ── Shop v2 generic product detail (every catalog product) ──────────────
   Live model card, OWNED pill, second CTA (OPEN NOW for owned packs), and
   narrower stat grids for sparse payloads. */
.sh2-cta {
  gap: 10px;
}
/* Text glyph inside a stat tile (suit/school symbols). */
.sh2-sglyph-txt {
  font-size: 17px;
  line-height: 1;
  color: #fff;
}
/* Inert OWNED pill — replaces ACQUIRE for already-entitled products. */
.sh2-acquire--owned {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.55);
  box-shadow: none;
  cursor: default;
}
.sh2-acquire--owned:active {
  background: rgba(255, 255, 255, 0.1);
  transform: none;
}
/* Fewer stat tiles → narrower grid, never empty placeholder cells. */
.sh2-stats--1 {
  grid-template-columns: 1fr;
}
.sh2-stats--2 {
  grid-template-columns: 1fr 1fr;
}
