/* ============================================================
   OmniTCG design system — v0.2
   Dark ink ground · foil-gold accent · steel secondary.
   Marketing chrome + logged-in app shell + component library.
   ============================================================ */
:root {
  /* Deep navy, not black. "Dark but not black" is the whole difference
     between a page that feels like an app and one that feels like a void:
     every surface carries a blue cast, and surfaces separate by getting
     LIGHTER rather than by casting a shadow (shadows on dark read as murk).
     The hue is constant at ~217deg so the steps look like one material. */
  --bg: #070B14;
  --bg-2: #0B1120;
  --panel: #101A2E;
  --panel-2: #16233B;
  --elev: #1D2E4B;
  --surface: rgba(140, 190, 255, 0.045);
  --surface-2: rgba(140, 190, 255, 0.085);
  --line: rgba(146, 194, 255, 0.11);
  --line-2: rgba(146, 194, 255, 0.2);
  --ink: #F2F7FF;
  --ink-dim: #C3D3E8;
  --muted: #8BA1BE;
  --faint: #5D7290;
  /* ShinyHits ice palette (2026-09-22). The --gold* names are kept as aliases
     because 36 rules across this file reference them; renaming every one would
     be churn with no visual difference. Change the four --ice values below and
     the whole site re-themes. */
  --ice: #6FD3FF;
  --ice-2: #2FA8EC;
  --ice-soft: #CFEDFF;
  --ice-deep: #0E5C96;
  --gold: var(--ice);
  --gold-2: var(--ice-2);
  --gold-soft: var(--ice-soft);
  --steel: #8FBDE4;
  --violet: #3FD8D0;   /* was a lilac; the palette is cold cyan/teal now */
  --pos: #56c08a;
  --neg: #e0736a;
  --warn: #e6b54a;
  --danger: #e0736a;
  --radius: 16px;
  --radius-sm: 11px;
  --radius-xs: 8px;
  --pill: 999px;
  --font: "Satoshi", "Inter", "Avenir Next", "Segoe UI", -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
  --mono: "SF Mono", ui-monospace, "JetBrains Mono", Menlo, Consolas, monospace;
  --shadow: 0 24px 60px -18px rgba(0, 0, 0, 0.6);
  --shadow-sm: 0 8px 24px -12px rgba(0, 0, 0, 0.5);
  /* Foil stays rainbow because that is what a holo card does under a light —
     but it is weighted toward the blue half of the spectrum so it belongs to
     this palette instead of fighting it. */
  --foil: linear-gradient(102deg, #ffffff 0%, #CFEDFF 13%, #6FD3FF 28%, #3FD8D0 44%,
          #8FE9A6 58%, #FFE08A 72%, #FF9FC4 86%, #ffffff 100%);
  --foil-text: linear-gradient(100deg, #ffffff 0%, #D4F0FF 24%, #6FD3FF 48%, #3FD8D0 68%, #ffffff 100%);
  --glow-gold: 0 0 0 1px rgba(111, 211, 255, 0.34), 0 12px 38px -12px rgba(111, 211, 255, 0.45);
  --sidebar-w: 244px;
  --topbar-h: 60px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}
:root[data-theme="light"], html[data-theme="light"] {
  --bg: #f2f0ea;
  --bg-2: #ece9e1;
  --panel: #ffffff;
  --panel-2: #faf9f5;
  --elev: #ffffff;
  --surface: rgba(20, 24, 28, 0.028);
  --surface-2: rgba(20, 24, 28, 0.06);
  --line: rgba(20, 24, 28, 0.1);
  --line-2: rgba(20, 24, 28, 0.2);
  --ink: #1b2026;
  --ink-dim: #333c45;
  --muted: #5d6871;
  --faint: #8a949d;
  --gold: #a67c1c;
  --gold-2: #916c17;
  --gold-soft: #7d5d13;
  --steel: #3a6b96;
  --violet: #6d5cc0;
  --pos: #2e8256;
  --neg: #b8483f;
  --shadow: 0 20px 50px -20px rgba(40, 44, 50, 0.28);
  --shadow-sm: 0 8px 22px -14px rgba(40, 44, 50, 0.24);
  --glow-gold: 0 0 0 1px rgba(166, 124, 28, 0.3), 0 12px 30px -14px rgba(166, 124, 28, 0.35);
}
/* OmniTCG is dark-first (the brand). Light is opt-in only via data-theme="light";
   we intentionally do NOT auto-switch to light on prefers-color-scheme. */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: var(--steel); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; }
h1, h2, h3, h4 { letter-spacing: -0.02em; line-height: 1.12; margin: 0 0 0.5em; text-wrap: balance; }
h1 { font-size: clamp(1.8rem, 4vw, 2.7rem); font-weight: 800; }
h2 { font-size: 1.4rem; font-weight: 750; }
h3 { font-size: 1.08rem; font-weight: 700; }
p { margin: 0 0 1rem; }
.omni, .foil-text {
  background: var(--foil-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.muted { color: var(--muted); }
.dim { color: var(--ink-dim); }
.faint { color: var(--faint); }
.small { font-size: 0.82rem; }
.tiny { font-size: 0.72rem; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.pos { color: var(--pos); }
.neg { color: var(--neg); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.eyebrow {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 0.5rem;
}
.eyebrow a { color: inherit; }
.stack { display: flex; flex-direction: column; gap: 1rem; }
.row { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.grow { flex: 1; }
.hide { display: none !important; }
.divider { height: 1px; background: var(--line); border: 0; margin: 1.4rem 0; }

/* -------------------------------- buttons -------------------------------- */
.btn, button.btn, a.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  font: inherit; font-weight: 650; font-size: 0.9rem; cursor: pointer; text-decoration: none;
  padding: 0.6rem 1.15rem; border-radius: var(--pill); border: 1px solid transparent;
  transition: transform 0.12s var(--ease), box-shadow 0.16s var(--ease), background 0.16s, border-color 0.16s;
  white-space: nowrap; line-height: 1;
}
.btn svg { width: 1.05em; height: 1.05em; }
.btn-primary { background: var(--foil); color: #17130a; box-shadow: var(--shadow-sm); }
.btn-primary:hover { transform: translateY(-1px); box-shadow: var(--glow-gold); text-decoration: none; }
.btn-ghost { background: var(--surface); color: var(--ink); border-color: var(--line-2); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--gold-2); text-decoration: none; }
.btn-solid { background: var(--elev); color: var(--ink); border-color: var(--line-2); }
.btn-solid:hover { border-color: var(--gold-2); text-decoration: none; }
.btn-danger { background: rgba(224, 115, 106, 0.12); color: var(--neg); border-color: rgba(224, 115, 106, 0.4); }
.btn-danger:hover { background: rgba(224, 115, 106, 0.2); text-decoration: none; }
.btn-sm { padding: 0.4rem 0.8rem; font-size: 0.82rem; }
.btn-lg { padding: 0.8rem 1.6rem; font-size: 1rem; }
.btn-block { display: flex; width: 100%; }
.btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}
.linklike {
  background: none; border: 0; color: var(--muted); font: inherit; cursor: pointer; padding: 0;
}
.linklike:hover { color: var(--ink); }
.iconbtn {
  display: inline-grid; place-items: center; width: 38px; height: 38px; border-radius: var(--pill);
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-dim); cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s; position: relative;
}
.iconbtn:hover { background: var(--surface-2); color: var(--ink); border-color: var(--line-2); }
.iconbtn svg { width: 19px; height: 19px; }

/* -------------------------------- forms -------------------------------- */
input, select, textarea {
  font: inherit; color: var(--ink); background: var(--surface); width: 100%;
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); padding: 0.6rem 0.85rem;
  transition: border-color 0.15s, background 0.15s;
}
input::placeholder, textarea::placeholder { color: var(--faint); }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--gold); background: var(--surface-2); }
select { appearance: none; background-image: none; cursor: pointer; }
label.field { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.8rem; color: var(--muted); }
.check { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; color: var(--ink-dim); cursor: pointer; }
.check input { width: auto; }
textarea { resize: vertical; min-height: 80px; }

/* -------------------------------- badges / chips -------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.68rem; font-weight: 650;
  letter-spacing: 0.04em; text-transform: uppercase; padding: 0.18rem 0.5rem; border-radius: var(--pill);
  background: var(--surface-2); color: var(--ink-dim); border: 1px solid var(--line);
}
.badge.gold { color: var(--gold); border-color: rgba(143, 216, 242, 0.34); background: rgba(143, 216, 242, 0.1); }
.badge.pos { color: var(--pos); border-color: rgba(86, 192, 138, 0.34); background: rgba(86, 192, 138, 0.1); }
.badge.neg { color: var(--neg); border-color: rgba(224, 115, 106, 0.34); background: rgba(224, 115, 106, 0.1); }
.badge.violet { color: var(--violet); border-color: rgba(52, 201, 192, 0.34); background: rgba(52, 201, 192, 0.1); }
.chip {
  display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; padding: 0.34rem 0.8rem;
  border-radius: var(--pill); background: var(--surface); border: 1px solid var(--line-2); color: var(--ink-dim);
  cursor: pointer; text-decoration: none; transition: all 0.15s;
}
.chip:hover { border-color: var(--gold-2); color: var(--ink); text-decoration: none; }
.chip.active { background: var(--foil); color: #17130a; border-color: transparent; font-weight: 650; }
.chip-row { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.gamechip { font-size: 0.66rem; padding: 0.14rem 0.45rem; border-radius: 5px; font-weight: 700; letter-spacing: 0.04em; }

/* -------------------------------- panels / cards -------------------------------- */
.panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.3rem 1.4rem;
}
.panel.tight { padding: 1rem 1.1rem; }
.panel.glass {
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  backdrop-filter: blur(8px); box-shadow: var(--shadow-sm);
}
.panel-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.panel-head h2, .panel-head h3 { margin: 0; }
.hairline { border: 1px solid var(--line); }

/* -------------------------------- stat tiles -------------------------------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.9rem; }
.stat {
  position: relative; padding: 1.1rem 1.2rem; border-radius: var(--radius); overflow: hidden;
  background: var(--panel); border: 1px solid var(--line);
}
.stat .label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.stat .value { font-family: var(--mono); font-size: 1.7rem; font-weight: 700; margin-top: 0.3rem; letter-spacing: -0.02em; }
.stat .sub { font-size: 0.78rem; color: var(--muted); margin-top: 0.15rem; }
.stat.hero { padding: 1.1rem 1.2rem;  /* .hero landing rule also matches; keep stat metrics */
  border-color: rgba(143, 216, 242, 0.4); box-shadow: var(--glow-gold); background: linear-gradient(155deg, rgba(143, 216, 242, 0.08), var(--panel) 55%); }
.stat.hero .value { color: var(--gold-soft); font-size: clamp(1.45rem, 5.5vw, 2.1rem); }
.stat .spark { position: absolute; inset: auto 0 0 0; height: 42px; opacity: 0.7; }

/* -------------------------------- tables -------------------------------- */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); }
table { border-collapse: collapse; width: 100%; font-size: 0.88rem; }
thead th {
  font-family: var(--mono); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); text-align: left; padding: 0.75rem 0.9rem; border-bottom: 1px solid var(--line);
  white-space: nowrap; position: sticky; top: 0; background: var(--panel); z-index: 1;
}
tbody td { padding: 0.7rem 0.9rem; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background 0.12s; }
tbody tr:hover td { background: var(--surface); }
td.num, th.num { text-align: right; }

/* -------------------------------- card + set grids -------------------------------- */
.cardgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1.1rem; }
.cardgrid.dense { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 0.8rem; }
.ctile { display: flex; flex-direction: column; gap: 0.4rem; text-decoration: none; color: var(--ink); }
.ctile:hover { text-decoration: none; }
.ctile .frame {
  position: relative; border-radius: 12px; overflow: hidden; background: var(--bg-2);
  aspect-ratio: 63 / 88; box-shadow: 0 10px 26px -12px rgba(0, 0, 0, 0.6);
  transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.ctile .frame img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ctile:hover .frame { transform: translateY(-5px) scale(1.015); box-shadow: 0 20px 40px -14px rgba(0, 0, 0, 0.7); }
.ctile .cname { font-weight: 600; font-size: 0.86rem; line-height: 1.2; }
.ctile .cmeta { font-size: 0.74rem; color: var(--muted); }
.ctile .cprice { font-family: var(--mono); font-size: 0.82rem; color: var(--gold-soft); font-weight: 600; }
.frame .owned-badge, .frame .corner {
  position: absolute; top: 6px; right: 6px; background: rgba(10, 13, 17, 0.82); color: var(--pos);
  border-radius: var(--pill); font-size: 0.66rem; padding: 0.12rem 0.44rem; font-weight: 700; backdrop-filter: blur(6px);
}
.frame .qtypill { left: 6px; right: auto; color: var(--gold-soft); }
.ctile.owned .frame { outline: 2px solid rgba(86, 192, 138, 0.6); outline-offset: -2px; }
.frame.holo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: overlay; opacity: 0.5;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.5) 45%, transparent 60%);
}

.setgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0.95rem; }
.settile {
  display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; padding: 1.1rem;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); color: var(--ink);
  text-decoration: none; transition: transform 0.16s var(--ease), border-color 0.16s, background 0.16s;
}
.settile:hover { transform: translateY(-3px); border-color: rgba(143, 216, 242, 0.45); background: var(--panel-2); text-decoration: none; }
.settile .logo { height: 40px; display: grid; place-items: center; }
.settile .logo img { max-height: 40px; object-fit: contain; }
.settile .sname { font-weight: 650; font-size: 0.92rem; }

/* -------------------------------- progress -------------------------------- */
.progress { height: 7px; border-radius: var(--pill); background: var(--surface-2); overflow: hidden; }
.progress > span { display: block; height: 100%; background: var(--foil); border-radius: inherit; transition: width 0.6s var(--ease); }
.ring { --p: 0; width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
  background: conic-gradient(var(--gold) calc(var(--p) * 1%), var(--surface-2) 0); }
.ring::before { content: ""; position: absolute; width: 42px; height: 42px; border-radius: 50%; background: var(--panel); }
.ring b { position: relative; font-size: 0.74rem; font-family: var(--mono); }

/* -------------------------------- avatars -------------------------------- */
.avatar {
  width: 34px; height: 34px; border-radius: 50%; object-fit: cover; display: inline-grid; place-items: center;
  background: var(--foil); color: #17130a; font-weight: 750; font-size: 0.8rem; overflow: hidden; flex: none;
}
.avatar.lg { width: 72px; height: 72px; font-size: 1.5rem; }
.avatar.sm { width: 26px; height: 26px; font-size: 0.66rem; }

/* -------------------------------- flashes / toasts -------------------------------- */
.toast-wrap { position: fixed; top: 74px; right: 18px; z-index: 200; display: flex; flex-direction: column; gap: 0.6rem; max-width: min(92vw, 380px); }
.toast {
  padding: 0.8rem 1rem; border-radius: var(--radius-sm); font-size: 0.9rem; border: 1px solid var(--line-2);
  background: var(--elev); box-shadow: var(--shadow); display: flex; gap: 0.6rem; align-items: flex-start;
  animation: toastin 0.32s var(--ease); border-left: 3px solid var(--gold);
}
.toast.ok { border-left-color: var(--pos); }
.toast.error { border-left-color: var(--neg); }
@keyframes toastin { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }

/* -------------------------------- marketing chrome -------------------------------- */
.mkt-head {
  position: sticky; top: 0; z-index: 50; display: flex; align-items: center; gap: 1.4rem;
  padding: 0.85rem clamp(1rem, 5vw, 2.6rem); background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(16px); border-bottom: 1px solid var(--line);
}
.brand { font-weight: 800; font-size: 1.28rem; letter-spacing: -0.03em; color: var(--ink); text-decoration: none; display: inline-flex; align-items: center; gap: 0.1rem; }
.mkt-head nav { display: flex; align-items: center; gap: 1.2rem; margin-left: auto; }
.mkt-head nav a { color: var(--muted); font-size: 0.92rem; }
.mkt-head nav a:hover { color: var(--ink); text-decoration: none; }
.mkt-head nav a.btn-primary, .mkt-head nav a.btn-primary:hover { color: #17130a; }
.mkt-main { width: min(84rem, 100% - 2.6rem); margin: 0 auto; padding: 1rem 0 5rem; }
/* Escape the column. Full-width bands give the page a rhythm that a single
   centred sheet of boxes cannot — some sections breathe, others press in. */
.bleed { width: 100vw; margin-left: calc(50% - 50vw); padding-inline: max(1.3rem, calc(50vw - 42rem)); }
.band { background: linear-gradient(180deg, rgba(143,216,242,0.05), transparent 60%),
        var(--bg-2); border-block: 1px solid var(--line); }
.mkt-foot {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: 2rem clamp(1rem, 5vw, 2.6rem); border-top: 1px solid var(--line); color: var(--muted); font-size: 0.8rem;
}
.mkt-foot a { color: var(--muted); }

/* -------------------------------- app shell -------------------------------- */
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }
.sidebar {
  position: sticky; top: 0; height: 100vh; overflow-y: auto; background: var(--bg-2);
  border-right: 1px solid var(--line); padding: 1rem 0.8rem; display: flex; flex-direction: column; gap: 0.2rem;
}
.sidebar .brand { padding: 0.4rem 0.7rem 1rem; font-size: 1.24rem; }
.nav-group { font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--faint); padding: 0.9rem 0.8rem 0.35rem; }
.nav-link {
  display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 0.75rem; border-radius: var(--radius-sm);
  color: var(--ink-dim); font-size: 0.9rem; font-weight: 500; text-decoration: none; transition: background 0.14s, color 0.14s;
}
.nav-link:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.nav-link.active { background: var(--surface-2); color: var(--ink); font-weight: 600; box-shadow: inset 2px 0 0 var(--gold); }
.nav-link svg { width: 18px; height: 18px; flex: none; opacity: 0.85; }
.nav-link .count { margin-left: auto; font-size: 0.68rem; background: var(--surface-2); color: var(--muted); padding: 0.05rem 0.42rem; border-radius: var(--pill); }
.nav-link.active .count { background: rgba(143, 216, 242, 0.18); color: var(--gold); }

.topbar {
  position: sticky; top: 0; z-index: 40; height: var(--topbar-h); display: flex; align-items: center; gap: 0.8rem;
  padding: 0 clamp(1rem, 3vw, 1.8rem); background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: blur(16px); border-bottom: 1px solid var(--line);
}
.topbar .searchbtn {
  display: flex; align-items: center; gap: 0.6rem; flex: 1; max-width: 460px; padding: 0.5rem 0.9rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--pill); color: var(--faint);
  cursor: pointer; font-size: 0.88rem;
}
.topbar .searchbtn kbd { margin-left: auto; font-family: var(--mono); font-size: 0.68rem; background: var(--surface-2); padding: 0.1rem 0.4rem; border-radius: 5px; border: 1px solid var(--line); }
.appmain { padding: clamp(1.1rem, 3vw, 2rem); max-width: 1240px; width: 100%; margin: 0 auto; }
.page-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.4rem; }
.page-head h1 { margin: 0; }
.hamburger { display: none; }

/* menus / dropdowns */
.menu { position: relative; }
.menu-pop {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 240px; background: var(--elev);
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); box-shadow: var(--shadow); padding: 0.5rem;
  z-index: 60; display: none;
}
.menu-pop.open { display: block; animation: pop 0.16s var(--ease); }
@keyframes pop { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.menu-pop a, .menu-pop button { display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left;
  padding: 0.55rem 0.7rem; border-radius: var(--radius-xs); color: var(--ink-dim); font-size: 0.88rem; background: none; border: 0; cursor: pointer; text-decoration: none; }
.menu-pop a:hover, .menu-pop button:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.dot { position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--neg); border: 2px solid var(--bg); }

/* empty states */
.empty { text-align: center; padding: 3rem 1.5rem; color: var(--muted); }
.empty .emoji { font-size: 2.4rem; display: block; margin-bottom: 0.6rem; opacity: 0.8; }

/* command palette / modal */
.overlay { position: fixed; inset: 0; background: rgba(4, 6, 9, 0.62); backdrop-filter: blur(4px); z-index: 120; display: none; }
.overlay.open { display: block; }
.modal {
  position: fixed; z-index: 130; left: 50%; top: 12vh; transform: translateX(-50%); width: min(620px, 94vw);
  background: var(--elev); border: 1px solid var(--line-2); border-radius: var(--radius); box-shadow: var(--shadow);
  display: none; overflow: hidden;
}
.modal.open { display: block; animation: pop 0.18s var(--ease); }
.modal .searchrow { display: flex; align-items: center; gap: 0.6rem; padding: 0.9rem 1.1rem; border-bottom: 1px solid var(--line); }
.modal .searchrow input { border: 0; background: none; font-size: 1.05rem; }
.modal .results { max-height: 54vh; overflow-y: auto; padding: 0.4rem; }
.res-item { display: flex; align-items: center; gap: 0.7rem; padding: 0.5rem 0.7rem; border-radius: var(--radius-xs); cursor: pointer; color: var(--ink); text-decoration: none; }
.res-item:hover, .res-item.active { background: var(--surface-2); text-decoration: none; }
.res-item img { width: 30px; height: 42px; object-fit: contain; border-radius: 4px; background: var(--bg-2); }

/* tabs */
.tabs { display: flex; gap: 0.3rem; border-bottom: 1px solid var(--line); margin-bottom: 1.2rem; overflow-x: auto; }
.tab { padding: 0.6rem 0.9rem; color: var(--muted); font-size: 0.9rem; font-weight: 550; border-bottom: 2px solid transparent; cursor: pointer; white-space: nowrap; text-decoration: none; }
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.active { color: var(--ink); border-bottom-color: var(--gold); }

/* auth card */
.authwrap { min-height: 100vh; display: grid; place-items: center; padding: 2rem 1.2rem; }
.authbox { width: min(26rem, 100%); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 2rem; box-shadow: var(--shadow); }
.authbox form { display: flex; flex-direction: column; gap: 0.9rem; }

/* landing bits */
.hero { padding: clamp(1.5rem, 5vh, 3.5rem) 0 clamp(1rem, 3vh, 2rem); }
.hero h1 { font-size: clamp(2.7rem, 5.6vw, 4.9rem); font-weight: 880; line-height: 1.0; letter-spacing: -0.035em; max-width: 16ch; }
.hero .lede { font-size: clamp(1.02rem, 1.3vw, 1.2rem); color: var(--ink-dim); max-width: 32rem; line-height: 1.6; }
.hero .lede strong { color: var(--gold-soft); }
.pillrow { display: flex; gap: 0.6rem; flex-wrap: wrap; margin: 1.6rem 0; }
.glowcard {
  position: relative; border-radius: var(--radius); padding: 1.4rem 1.6rem; background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line); box-shadow: var(--shadow);
}
.glowcard::before {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(120deg, rgba(143, 216, 242, 0.6), rgba(123,166,201,0.25) 45%, transparent 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
}
.pricerow { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: 0.7rem 0; border-top: 1px solid var(--line); }
.pricerow:first-of-type { border-top: 0; }
.pricerow small { display: block; color: var(--muted); font-size: 0.74rem; }
.pricerow b { font-family: var(--mono); font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.pricerow.local span, .pricerow.local b { color: var(--gold-soft); }
.feat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; }
.feat { padding: 1.4rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); transition: transform 0.16s var(--ease), border-color 0.16s; }
.feat:hover { transform: translateY(-3px); border-color: var(--line-2); }
.feat .ic { width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center; background: rgba(143, 216, 242, 0.12); color: var(--gold); margin-bottom: 0.8rem; }
.feat .ic svg { width: 22px; height: 22px; }
.feat h3 { color: var(--gold-soft); font-size: 1rem; }
.feat p { color: var(--muted); font-size: 0.9rem; margin: 0; }
.logos { display: flex; gap: 1.4rem; flex-wrap: wrap; align-items: center; opacity: 0.7; font-family: var(--mono); font-size: 0.8rem; }

/* card detail page */
.cardpage { display: grid; grid-template-columns: minmax(240px, 360px) 1fr; gap: clamp(1.4rem, 4vw, 3rem); align-items: start; }
@media (max-width: 760px) { .cardpage { grid-template-columns: 1fr; } .cardhero { max-width: 320px; margin: 0 auto; } }
.cardhero { position: relative; border-radius: 18px; overflow: hidden; box-shadow: var(--shadow); aspect-ratio: 63/88; background: var(--bg-2); }
.cardhero img { width: 100%; height: 100%; object-fit: contain; transition: transform 0.3s var(--ease); }
.cardhero:hover img { transform: scale(1.03); }
.metricgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 0.7rem; }
.metric { padding: 0.85rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); }
.metric .m-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.metric .m-val { font-family: var(--mono); font-size: 1.35rem; font-weight: 700; }
.metric.local { border-color: rgba(143, 216, 242, 0.4); }
.metric.local .m-val { color: var(--gold-soft); }

/* charts */
.chart-box { position: relative; width: 100%; }
.chart-box canvas { width: 100%; display: block; }
.legend { display: flex; gap: 0.9rem; flex-wrap: wrap; font-size: 0.8rem; color: var(--muted); }
.legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.donut-wrap { display: flex; gap: 1.4rem; align-items: center; flex-wrap: wrap; }

/* toolbar */
.toolbar { display: flex; gap: 0.7rem; flex-wrap: wrap; align-items: center; margin-bottom: 1.2rem; }
.viewtoggle { display: inline-flex; border: 1px solid var(--line-2); border-radius: var(--pill); overflow: hidden; }
.viewtoggle a { padding: 0.4rem 0.7rem; color: var(--muted); font-size: 0.82rem; }
.viewtoggle a.active { background: var(--surface-2); color: var(--ink); }
.bulkbar { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin-top: 1rem; padding: 0.8rem 1rem; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); }

/* misc list rows */
.listrow { display: flex; align-items: center; gap: 0.9rem; padding: 0.7rem 0; border-bottom: 1px solid var(--line); }
.listrow:last-child { border-bottom: 0; }
.listrow img.thumb { width: 38px; height: 53px; object-fit: contain; border-radius: 5px; background: var(--bg-2); flex: none; }
.mini-thumb { width: 30px; height: 42px; object-fit: contain; border-radius: 4px; background: var(--bg-2); }

.prose { max-width: 46rem; }
.prose h2 { color: var(--gold-soft); font-size: 1.2rem; margin-top: 2rem; }
.prose li { margin-bottom: 0.4rem; }
.prose code { background: var(--surface-2); padding: 0.1rem 0.35rem; border-radius: 5px; font-family: var(--mono); font-size: 0.85em; }

/* responsive: collapse sidebar */
@media (max-width: 860px) {
  .app { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; left: 0; top: 0; width: 260px; z-index: 110; transform: translateX(-100%);
    transition: transform 0.24s var(--ease); box-shadow: var(--shadow);
  }
  .sidebar.open { transform: none; }
  .hamburger { display: inline-grid; }
  .appmain { padding-bottom: 5rem; }
}
@media (max-width: 560px) {
  .stat .value { font-size: 1.4rem; }
  .page-head h1 { font-size: 1.5rem; }
}

/* ============================================================
   v0.2.1 — ULTRA-MODERN LAYER
   Deeper ground, layered glow, grain, motion, glass, bento,
   3D card tilt, mobile bottom nav. Overrides earlier rules.
   ============================================================ */
:root {
  --bg: #06080b;
  --bg-2: #0a0e13;
  --panel: #0e131a;
  --panel-2: #141a22;
  --glow: rgba(143, 216, 242, 0.5);
  --holo: linear-gradient(115deg, #ffe9a8 0%, #f0cd76 24%, #e6b54a 48%, #d4a641 62%, #f3d488 82%, #e6b54a 100%);
  --sheen: linear-gradient(105deg, transparent 20%, rgba(255,255,255,0.14) 42%, rgba(255,255,255,0.28) 50%, rgba(255,255,255,0.14) 58%, transparent 80%);
}
:root[data-theme="light"] {
  --bg: #eef0f4; --bg-2: #e7e9ef; --panel: #ffffff; --panel-2: #f7f8fb;
  --glow: rgba(166, 124, 28, 0.35);
}

body {
  background:
    radial-gradient(1100px 640px at 88% -8%, rgba(123,166,201,0.13), transparent 55%),
    radial-gradient(900px 560px at -6% 8%, rgba(143, 216, 242, 0.11), transparent 52%),
    radial-gradient(700px 700px at 50% 120%, rgba(52, 201, 192, 0.08), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}
/* fine grain overlay for depth */
body::before {
  content: ""; position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}
.app, .mkt-head, .mkt-main, .mkt-foot, .authwrap { position: relative; z-index: 1; }

/* --- motion --- */
@keyframes floaty { 0%,100% { transform: translateY(0) rotate(var(--r,0deg)); } 50% { transform: translateY(-14px) rotate(var(--r,0deg)); } }
@keyframes glowpulse { 0%,100% { box-shadow: 0 0 0 1px rgba(143, 216, 242, 0.22), 0 10px 40px -12px var(--glow); } 50% { box-shadow: 0 0 0 1px rgba(143, 216, 242, 0.4), 0 18px 60px -10px var(--glow); } }
@keyframes shimmer { from { background-position: -180% 0; } to { background-position: 180% 0; } }
@keyframes revealUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
/* transition-based (never conflicts with a tile's own `animation:` like glowpulse) */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: 0.07s; } .reveal.d2 { transition-delay: 0.14s; }
.reveal.d3 { transition-delay: 0.21s; } .reveal.d4 { transition-delay: 0.28s; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; transition: none; } }

/* shimmering foil brand + headings */
.foil-text, .omni {
  background: var(--holo); background-size: 220% auto;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: shimmer 6s linear infinite;
}

/* --- panels: glass + inner highlight --- */
.panel {
  background: linear-gradient(168deg, rgba(255,255,255,0.04), rgba(255,255,255,0.012));
  border: 1px solid var(--line); border-radius: 18px; position: relative;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.panel::after {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px; border-radius: 18px 18px 0 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.14), transparent); pointer-events: none;
}
:root[data-theme="light"] .panel { background: var(--panel); box-shadow: var(--shadow-sm); }
:root[data-theme="light"] body::before { display: none; }

/* --- buttons: glow + sheen --- */
.btn-primary { position: relative; overflow: hidden; box-shadow: 0 8px 30px -10px var(--glow); }
.btn-primary::after {
  content: ""; position: absolute; inset: 0; background: var(--sheen); background-size: 220% 100%;
  background-position: -180% 0; opacity: 0; transition: opacity 0.2s;
}
.btn-primary:hover::after { opacity: 1; animation: shimmer 0.9s linear; }
.btn-primary:hover { box-shadow: var(--glow) 0 0 0 1px, 0 14px 44px -8px var(--glow); }

/* --- stat tiles: richer --- */
.stat { background: linear-gradient(165deg, rgba(255,255,255,0.045), rgba(255,255,255,0.01)); backdrop-filter: blur(6px); border-radius: 18px; overflow: hidden; }
.stat::before { content: ""; position: absolute; inset: -40% 40% auto -10%; height: 120px; background: radial-gradient(circle, rgba(143, 216, 242, 0.10), transparent 70%); pointer-events: none; }
.stat.hero { animation: glowpulse 5.5s ease-in-out infinite; }
.stat .value { letter-spacing: -0.03em; }

/* --- bento grid --- */
.bento { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1rem; }
.bento > * { grid-column: span 12; }
@media (min-width: 720px) {
  .col-3 { grid-column: span 3; } .col-4 { grid-column: span 4; } .col-5 { grid-column: span 5; }
  .col-6 { grid-column: span 6; } .col-7 { grid-column: span 7; } .col-8 { grid-column: span 8; }
  .col-9 { grid-column: span 9; } .col-12 { grid-column: span 12; }
}
.row-2 { grid-row: span 2; }

/* --- 3D card tilt + holo shine --- */
.tilt { transform-style: preserve-3d; transition: transform 0.2s var(--ease); will-change: transform; }
.tilt .shine {
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; mix-blend-mode: overlay;
  background: radial-gradient(circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,0.55), transparent 45%);
  transition: opacity 0.2s;
}
.tilt:hover .shine { opacity: 0.9; }

/* floating hero cards */
.hero-cards { position: relative; height: 380px; perspective: 1200px; }
.hero-cards::before { content: ""; position: absolute; inset: -18% -12% -18% -6%; z-index: 0; pointer-events: none;
  background: radial-gradient(circle at 58% 46%, rgba(143, 216, 242, 0.22), rgba(52, 201, 192, 0.10) 42%, transparent 66%); filter: blur(24px); }
.hero-cards .hc {
  position: absolute; width: 168px; aspect-ratio: 63/88; border-radius: 12px; overflow: hidden;
  box-shadow: 0 30px 60px -20px rgba(0,0,0,0.75); border: 1px solid rgba(255,255,255,0.08);
  animation: floaty 7s ease-in-out infinite; background: var(--bg-2);
}
.hero-cards .hc img { width: 100%; height: 100%; object-fit: cover; }
.hero-cards .hc::after { content:""; position:absolute; inset:0; background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,0.22) 48%, transparent 56%); }

/* --- hero (marketing) --- */
.hero h1 { letter-spacing: -0.04em; }
.hero-eyebrow { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.85rem; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line-2); font-size: 0.78rem; color: var(--ink-dim); }
.hero-eyebrow .pip { width: 7px; height: 7px; border-radius: 50%; background: var(--pos); box-shadow: 0 0 10px var(--pos); }

/* section headings */
.section-title { font-size: clamp(2rem, 4.4vw, 3.4rem); font-weight: 850; letter-spacing: -0.035em; line-height: 1.05; }
.section-lede { color: var(--muted); max-width: 40rem; }

/* feature card upgrade */
.feat { background: linear-gradient(165deg, rgba(255,255,255,0.04), rgba(255,255,255,0.008)); border-radius: 18px; overflow: hidden; position: relative; }
.feat::before { content: ""; position: absolute; inset: -1px; border-radius: inherit; padding: 1px; background: linear-gradient(140deg, rgba(143, 216, 242, 0.35), transparent 45%); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.25s; }
.feat:hover::before { opacity: 1; }
.feat .ic { background: linear-gradient(140deg, rgba(143, 216, 242, 0.22), rgba(143, 216, 242, 0.06)); box-shadow: inset 0 0 0 1px rgba(143, 216, 242, 0.2); }

/* mockup frame for dashboard preview */
.mock { border-radius: 18px; border: 1px solid var(--line-2); overflow: hidden; box-shadow: var(--shadow); background: var(--bg-2); }
.mock .bar { display: flex; gap: 6px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.mock .bar i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); }

/* count-up nums use tabular */
[data-countup] { font-variant-numeric: tabular-nums; }

/* landing responsive splits */
.hero-split { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(1.5rem, 3vw, 2.6rem); align-items: center; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: center; }
@media (max-width: 860px) { .hero-split, .two-col { grid-template-columns: 1fr; } }
/* on mobile the floating hero cards collapse into a centred, overlapping fan
   under the copy (rather than vanishing — the header would feel empty) */
@media (max-width: 860px) {
  .hero-split .hero-cards {
    height: auto; margin: 1.8rem 0 0.4rem; perspective: none;
    display: flex; justify-content: center; align-items: flex-start;
  }
  .hero-cards::before { display: none; }
  .hero-cards .hc {
    position: static; top: auto !important; left: auto !important;
    width: min(23vw, 104px); margin-left: -26px; animation: none;
    transform: rotate(var(--r));
  }
  .hero-cards .hc:first-child { margin-left: 0; }
}

/* --- MOBILE bottom nav --- */
.mobile-nav { display: none; }
@media (max-width: 860px) {
  .mobile-nav {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(18px);
    border-top: 1px solid var(--line); padding: 0.4rem 0.3rem calc(0.4rem + env(safe-area-inset-bottom));
    justify-content: space-around;
  }
  .mobile-nav a { display: flex; flex-direction: column; align-items: center; gap: 2px; flex: 1; padding: 0.35rem 0; color: var(--faint); font-size: 0.6rem; text-decoration: none; }
  .mobile-nav a svg { width: 22px; height: 22px; }
  .mobile-nav a.active { color: var(--gold); }
  .appmain { padding-bottom: 5.5rem !important; }
  .topbar .searchbtn span { display: none; }
  .topbar .searchbtn { flex: none; width: 42px; justify-content: center; padding: 0.5rem; }
  .topbar .searchbtn kbd { display: none; }
}
@media (max-width: 640px) {
  .cardgrid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 0.7rem; }
  .cardgrid.dense { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 0.6rem; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); gap: 0.6rem; }
  .stat { padding: 0.85rem 0.9rem; }
  .stat .value { font-size: 1.35rem; }
  .metricgrid { grid-template-columns: 1fr; }
  .page-head { gap: 0.6rem; }
  h1 { font-size: clamp(1.5rem, 7vw, 2.1rem); }
  .panel { padding: 1rem; border-radius: 14px; }
  .toolbar { gap: 0.5rem; }
  .toolbar .field { flex: 1 1 44%; }
  .tablewrap { font-size: 0.82rem; }
  .mkt-head nav { gap: 0.7rem; }
  .mkt-head nav a:not(.btn) { display: none; }
}

/* smoother everything */
a, .chip, .settile, .ctile .frame, .nav-link, .iconbtn, .stat, .feat { transition-timing-function: var(--ease); }
::selection { background: rgba(143, 216, 242, 0.28); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 999px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: content-box; }

/* ============================================================
   Landing — games shelf + language band (v0.3)
   ============================================================ */
.game-shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 1.1rem; }
.game-tile {
  --accent: var(--gold);
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  min-height: 282px; padding: 1.4rem 1.1rem 1.15rem; border-radius: 18px; overflow: hidden;
  text-decoration: none; isolation: isolate;
  background: linear-gradient(168deg, color-mix(in srgb, var(--accent) 15%, var(--panel)), var(--panel) 68%);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--line-2));
  transition: transform .32s var(--ease), box-shadow .32s var(--ease), border-color .32s var(--ease);
}
.game-tile .gt-glow {
  position: absolute; inset: -45% -25% 30% -25%; z-index: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 34%, color-mix(in srgb, var(--accent) 55%, transparent), transparent 62%);
  opacity: .42; filter: blur(34px); transition: opacity .32s var(--ease);
}
.game-tile .gt-card {
  position: relative; z-index: 1; width: 62%; aspect-ratio: 63/88; border-radius: 11px; overflow: hidden;
  box-shadow: 0 26px 44px -18px rgba(0,0,0,.85), inset 0 0 0 1px rgba(255,255,255,.06);
  transform: rotate(-3.5deg); transition: transform .38s var(--ease);
}
.game-tile .gt-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.game-tile .gt-meta { position: relative; z-index: 1; margin-top: 1.05rem; text-align: center; display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.game-tile .gt-badge {
  font-size: .62rem; font-weight: 700; letter-spacing: .09em; padding: .16rem .5rem; border-radius: 999px;
  color: color-mix(in srgb, var(--accent) 82%, white);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
}
.game-tile .gt-name { font-weight: 750; font-size: .95rem; color: var(--ink); line-height: 1.2; letter-spacing: -.01em; }
.game-tile .gt-count { font-size: .78rem; font-variant-numeric: tabular-nums; color: color-mix(in srgb, var(--accent) 62%, var(--muted)); }
.game-tile:hover { transform: translateY(-7px); border-color: color-mix(in srgb, var(--accent) 65%, var(--line)); box-shadow: 0 30px 60px -26px color-mix(in srgb, var(--accent) 55%, transparent); }
.game-tile:hover .gt-glow { opacity: .85; }
.game-tile:hover .gt-card { transform: rotate(0deg) scale(1.05); }

.langband .langband-inner {
  display: grid; grid-template-columns: 1.15fr .85fr; gap: 2rem; align-items: center;
  padding: 2rem 2.2rem; border-radius: 22px; position: relative; overflow: hidden;
  background: radial-gradient(120% 140% at 100% 0%, rgba(143, 216, 242, .10), transparent 55%), var(--panel);
  border: 1px solid var(--line-2);
}
.langchips { display: flex; flex-direction: column; gap: .7rem; align-items: flex-end; }
.langchip {
  font-size: clamp(1.1rem, 2.2vw, 1.55rem); font-weight: 700; letter-spacing: -.01em;
  padding: .5rem 1.1rem; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--line-2); color: var(--ink);
}
.langchip:nth-child(2) { color: var(--gold-soft); border-color: color-mix(in srgb, var(--gold) 40%, var(--line-2)); }
.langchip:nth-child(3) { color: color-mix(in srgb, var(--holo) 85%, var(--ink)); }
@media (max-width: 760px) {
  .langband .langband-inner { grid-template-columns: 1fr; }
  .langchips { flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: wrap; }
}
@media (max-width: 640px) {
  .game-shelf { grid-template-columns: repeat(2, 1fr); gap: .8rem; }
  .game-tile { min-height: 232px; padding: 1.1rem .8rem .9rem; }
}

/* --- no-art placeholder + language badge (2026-08-02) ------------------- */
.noart {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0.5rem;
  color: var(--muted); opacity: 0.6; font-size: 0.72rem; letter-spacing: 0.05em;
  text-transform: uppercase; text-align: center; padding: 0.6rem;
  background:
    radial-gradient(ellipse at 50% 38%, rgba(131, 143, 155, 0.09), transparent 68%),
    var(--bg-2);
}
.noart .ico { width: 1.7em; height: 1.7em; opacity: 0.8; }
.cardhero .noart.big { position: relative; aspect-ratio: 63 / 88; border-radius: 14px; font-size: 0.82rem; }
.langtag {
  font-size: 0.92em; padding: 0 0.32em; border-radius: 4px;
  border: 1px solid rgba(131, 143, 155, 0.35); white-space: nowrap;
}

/* --- file input theming (was default white browser chrome) --------------- */
input[type="file"] { padding: 0.55rem 0.7rem; color: var(--muted); }
input[type="file"]::file-selector-button {
  background: var(--surface); color: var(--ink); border: 1px solid var(--line-2);
  border-radius: 10px; padding: 0.45rem 0.9rem; margin-right: 0.8rem;
  font: inherit; cursor: pointer;
}
input[type="file"]::file-selector-button:hover { border-color: var(--gold-2); }

/* ============================================================ ShinyHits ====
   Holographic treatments. The name is the product promise, so the foil is a
   real effect rather than a static gradient: the sweep below animates, which
   is what makes a card read as "shiny" instead of "yellow-blue". */

/* Wordmark: foil fill plus a highlight that travels across it. */
.brand .shiny {
  background: var(--foil-text);
  background-size: 260% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: foilsweep 7s var(--ease) infinite;
}
@keyframes foilsweep { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }

/* Hero headline accent. */
.icewords {
  background: var(--foil-text); background-size: 220% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: foilsweep 9s var(--ease) infinite;
}

/* Frost panel: a cold pane of glass rather than a flat dark card. */
.frost {
  position: relative; overflow: hidden;
  /* Solid, lifted by lightness. The translucent version read as a glass card,
     which is the single most generated-looking surface on the web. */
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: none;
}
.frost::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, 0.11) 47%, transparent 56%);
  transform: translateX(-100%);
  animation: glint 6.5s var(--ease) infinite;
}
@keyframes glint { 0%, 72% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

/* Reduced motion: keep the colour, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  .brand .shiny, .icewords { animation: none; background-position: 30% 50%; }
  .frost::after { animation: none; opacity: 0; }
}

.ice-divider { height: 1px; border: 0; margin: 0;
  background: linear-gradient(90deg, transparent, rgba(143, 216, 242, 0.42), transparent); }

.proofrow { display: flex; flex-wrap: wrap; gap: 1.3rem; margin-top: 1.5rem;
  color: var(--muted); font-size: 0.85rem; }
.proofrow svg { width: 15px; height: 15px; color: var(--ice); vertical-align: -2px; }

.nlflag { display: inline-flex; flex-direction: column; width: 17px; height: 12px; border-radius: 2px;
  overflow: hidden; vertical-align: -1px; margin-right: 0.35rem; box-shadow: 0 0 0 1px rgba(255,255,255,0.18); }
.nlflag i { flex: 1; }
.nlflag i:nth-child(1) { background: #AE1C28; }
.nlflag i:nth-child(2) { background: #fff; }
.nlflag i:nth-child(3) { background: #21468B; }

/* ===================================================== holographic card ====
   The product is shiny cards, so the landing should contain a genuinely shiny
   card rather than a picture of one. Two stacked layers do the work:

     ::before  repeating rainbow bands in color-dodge — the foil itself
     ::after   a white glare in overlay — the light source

   Both are positioned from --mx/--my (pointer, in %) and the whole card
   rotates on --rx/--ry, so the foil shifts hue as it turns, the way a real
   one does. JS only writes those four variables; everything else is CSS. */

.holo {
  --mx: 50%; --my: 50%; --rx: 0deg; --ry: 0deg; --int: 0;
  position: relative;
  aspect-ratio: 63 / 88;                 /* real trading-card proportions */
  border-radius: 4.5% / 3.2%;
  transform: perspective(900px) rotateY(var(--rx)) rotateX(var(--ry));
  transform-style: preserve-3d;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
  box-shadow: 0 28px 60px -22px rgba(0, 0, 0, 0.8),
              0 0 0 1px rgba(255, 255, 255, 0.07);
  isolation: isolate;
  overflow: hidden;
  background: var(--panel);
}
.holo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.holo::before {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background-image:
    repeating-linear-gradient(112deg,
      hsl(190, 100%, 70%) 0%,  hsl(215, 100%, 72%) 6%,
      hsl(265, 100%, 74%) 12%, hsl(320, 100%, 72%) 18%,
      hsl(10, 100%, 72%)  24%, hsl(50, 100%, 70%)  30%,
      hsl(140, 100%, 70%) 36%, hsl(190, 100%, 70%) 42%);
  background-size: 260% 260%;
  background-position: var(--mx) var(--my);
  mix-blend-mode: color-dodge;
  opacity: calc(0.16 + var(--int) * 0.34);
  filter: brightness(0.9) contrast(1.5);
  transition: opacity 0.35s var(--ease);
}
.holo::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: radial-gradient(farthest-corner circle at var(--mx) var(--my),
              rgba(255, 255, 255, 0.72) 2%, rgba(255, 255, 255, 0.12) 22%,
              rgba(0, 0, 0, 0.5) 100%);
  mix-blend-mode: overlay;
  opacity: calc(0.35 + var(--int) * 0.45);
  transition: opacity 0.35s var(--ease);
}
.holo:hover { box-shadow: 0 40px 90px -26px rgba(47, 136, 180, 0.6),
                          0 0 0 1px rgba(143, 216, 242, 0.35); }

/* Hero arrangement: one big card, two smaller ones fanned behind it. */
.cardstage { position: relative; display: grid; place-items: center; min-height: 440px; }
.cardstage::before {
  content: ""; position: absolute; inset: 4% 0 10%; pointer-events: none;
  background: radial-gradient(52% 48% at 50% 45%, rgba(143, 216, 242, 0.24), transparent 70%);
  filter: blur(14px);
}
.cardstage .holo { width: min(300px, 62vw); z-index: 3; }
.cardstage .holo.side {
  position: absolute; width: min(216px, 44vw); z-index: 1; opacity: 0.55;
  filter: saturate(0.8) brightness(0.72);
}
.cardstage .holo.side.l { left: 2%;  transform: perspective(900px) rotate(-15deg) translateY(16px); }
.cardstage .holo.side.r { right: 2%; transform: perspective(900px) rotate(15deg)  translateY(16px); }
@media (max-width: 720px) { .cardstage .holo.side { display: none; } .cardstage { min-height: 380px; } }

/* ============================================================== devices ====
   Real frames, because "also on your phone" is a claim better shown. */
.devices { display: flex; align-items: flex-end; justify-content: center; gap: clamp(1rem, 4vw, 3rem); flex-wrap: wrap; }
.device {
  position: relative; width: clamp(200px, 26vw, 252px); aspect-ratio: 9 / 19;
  border-radius: 34px; padding: 9px; background: linear-gradient(160deg, #262d36, #10151b);
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(255, 255, 255, 0.07),
              inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}
.device .screen { position: relative; width: 100%; height: 100%; border-radius: 26px; overflow: hidden;
  background: var(--bg); display: flex; flex-direction: column; }
.device .notch { position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 34%; height: 17px; border-radius: 999px; background: #0a0d11; z-index: 5; }

.scr-top { padding: 1.5rem 0.85rem 0.6rem; border-bottom: 1px solid var(--line); }
.scr-label { font-size: 0.56rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); }
.scr-val { font-family: var(--mono); font-size: 1.32rem; font-weight: 700; color: var(--ice-soft); letter-spacing: -0.02em; }
.scr-delta { font-size: 0.6rem; color: var(--pos); }
.scr-rows { padding: 0.5rem 0.6rem; display: grid; gap: 0.4rem; }
.scr-row { display: flex; align-items: center; gap: 0.45rem; padding: 0.38rem 0.45rem;
  border-radius: 9px; background: var(--surface); border: 1px solid var(--line); }
.scr-thumb { width: 22px; height: 30px; border-radius: 3px; flex: none;
  background: linear-gradient(150deg, var(--ice-2), var(--ice-deep)); }
.scr-name { flex: 1; min-width: 0; font-size: 0.6rem; color: var(--ink-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.scr-price { font-family: var(--mono); font-size: 0.62rem; color: var(--ice-soft); }
.scr-spark { margin: 0.5rem 0.6rem 0; height: 44px; display: flex; align-items: flex-end; gap: 3px; }
.scr-spark i { flex: 1; background: var(--foil); border-radius: 2px 2px 0 0; opacity: 0.8; }

/* ========================================================= feature rows ====
   Alternating rows instead of a grid of equal boxes: each claim gets its own
   visual, which a 6-up grid cannot give. */
.frow { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 5vw, 4rem);
  align-items: center; margin: clamp(3rem, 8vw, 5.5rem) 0; }
.frow:nth-child(even) .frow-media { order: -1; }
.frow-copy h3 { font-size: clamp(1.7rem, 3.6vw, 2.7rem); line-height: 1.06; letter-spacing: -0.03em; margin: 0.5rem 0 0.9rem; }
.frow-copy p { color: var(--ink-dim); font-size: 1rem; margin: 0; }
.frow-media { position: relative; }
@media (max-width: 800px) { .frow { grid-template-columns: 1fr; }
  .frow:nth-child(even) .frow-media { order: 0; } }

/* Price comparison: bars, so the gap is visible instead of arithmetic. */
.cmp { display: grid; gap: 0.75rem; }
.cmp-row { display: grid; grid-template-columns: 7.5rem 1fr auto; align-items: center; gap: 0.8rem; }
.cmp-row .k { font-size: 0.78rem; color: var(--muted); }
.cmp-row .k small { display: block; font-size: 0.66rem; color: var(--faint); }
.cmp-bar { height: 12px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.cmp-bar i { display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--ice-deep), var(--ice-2)); }
.cmp-row.win .cmp-bar i { background: var(--foil); box-shadow: 0 0 18px -2px rgba(143, 216, 242, 0.7); }
.cmp-row .v { font-family: var(--mono); font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.cmp-row.win .v { color: var(--ice-soft); font-weight: 700; }

/* Aurora backdrop for the page as a whole — cold light from above. */
.aurora { position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0.85;
  background:
    radial-gradient(900px 520px at 12% -6%, rgba(143, 216, 242, 0.13), transparent 60%),
    radial-gradient(760px 460px at 88% 4%, rgba(52, 201, 192, 0.10), transparent 62%),
    radial-gradient(600px 420px at 50% 100%, rgba(47, 136, 180, 0.09), transparent 70%); }

@media (prefers-reduced-motion: reduce) {
  .holo { transition: none; }
  .holo::before, .holo::after { transition: none; }
}

/* ------------------------------------------------- landing, second pass ---
   First attempt kept every section inside one narrow column as a bordered
   box on a dark sheet, so the page read as a template with glows. These
   rules give it scale and rhythm instead: the card is large enough to be the
   subject, the numbers sit in a full-width band rather than four tiles, and
   the phones are big enough to actually read. */

.cardstage { min-height: 520px; overflow: visible; }
.cardstage .holo { width: min(340px, 68vw); }
.cardstage .holo.side { width: min(238px, 46vw); opacity: 0.5; }
.cardstage .holo.side.l { left: 0;  transform: perspective(1000px) rotate(-16deg) translate(-27%, 7%); }
.cardstage .holo.side.r { right: 0; transform: perspective(1000px) rotate(16deg)  translate(27%, 7%); }
.cardstage::before { inset: -4% -22% 2%; filter: blur(26px); }
/* At narrow widths the flanking cards have nowhere to go. */
@media (max-width: 1100px) { .cardstage .holo.side { display: none; } }
@media (max-width: 720px) { .cardstage { min-height: 420px; } .cardstage .holo { width: min(310px, 76vw); } }

/* Numbers as a band: hairline-separated columns, no boxes. */
.numband { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; }
.numband > div { padding: clamp(1.4rem, 3vw, 2.4rem) clamp(0.8rem, 2vw, 1.6rem); border-left: 1px solid var(--line); }
.numband > div:first-child { border-left: 0; }
.numband .label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.13em; color: var(--muted); }
.numband .value { font-family: var(--mono); font-size: clamp(1.7rem, 3.4vw, 2.9rem); font-weight: 700;
  letter-spacing: -0.03em; margin-top: 0.45rem; color: var(--ink);
  font-variant-numeric: tabular-nums; }
.numband .sub { font-size: 0.78rem; color: var(--faint); margin-top: 0.25rem; }
.numband > div:last-child .value { background: var(--foil-text); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
@media (max-width: 760px) { .numband { grid-template-columns: repeat(2, 1fr); }
  .numband > div:nth-child(3) { border-left: 0; }
  .numband > div:nth-child(n+3) { border-top: 1px solid var(--line); } }

/* Phones: large enough to read, lit from behind. */
.devices { gap: clamp(1.2rem, 5vw, 4rem); position: relative; }
.devices::before { content: ""; position: absolute; inset: 12% 8% 22%; pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgba(143,216,242,0.2), transparent 72%); filter: blur(30px); }
.device { width: clamp(248px, 30vw, 330px); position: relative; }
.device.lead { z-index: 2; }
.device.trail { transform: translateY(26px) scale(0.93); opacity: 0.9; }
@media (max-width: 720px) { .device.trail { display: none; } }
.scr-val { font-size: clamp(1.4rem, 4.4vw, 1.9rem); }
.scr-name { font-size: 0.68rem; }
.scr-price { font-size: 0.7rem; }
.scr-label { font-size: 0.6rem; }

/* Section eyebrow: smaller, wider tracked, less shouty than a heading. */
.eyebrow { font-size: 0.7rem; letter-spacing: 0.18em; }

/* A lead paragraph that is allowed to be large. */
.section-lede { font-size: clamp(1rem, 1.35vw, 1.18rem); line-height: 1.6; color: var(--ink-dim); }

/* ======================================================== fourth pass =====
   Brief: "modern android/ios/web app landing page for a TCG app — dark but
   not black, white and blue, no weird typography, shiny, has to wow."

   Four things carry that and everything below serves one of them:
     1. One clean sans at every size. The display serif is gone.
     2. Deep navy instead of near-black (see :root), lit from inside.
     3. Shine as a *material*, not a decoration: foil, sweeps, sparkles.
     4. Real card art at scale — a moving wall of holos says "TCG app"
        faster than any copy on the page can.
   ========================================================================= */

/* Self-hosted so the CSP stays 'self' only, the PWA works offline, and no
   visitor is announced to a font CDN. ~25 KB per weight, five weights.
   Satoshi: a geometric grotesk — clean and contemporary at UI size, and
   genuinely heavy at 900 for display, so headings need no second family. */
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 300; font-display: swap;
  src: url("/static/fonts/satoshi-300.woff2") format("woff2"); }
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/static/fonts/satoshi-400.woff2") format("woff2"); }
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("/static/fonts/satoshi-500.woff2") format("woff2"); }
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/static/fonts/satoshi-700.woff2") format("woff2"); }
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 900; font-display: swap;
  src: url("/static/fonts/satoshi-900.woff2") format("woff2"); }

/* Grain. Flat gradients are the giveaway that a surface was generated rather
   than photographed; a little noise puts a texture over everything and the
   banding in the dark gradients disappears with it. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  opacity: 0.05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------- type ------
   One family, separated by weight and tracking rather than by a second face.
   Display sizes get 900 and tight negative tracking, which is what makes a
   heading read as an app's and not a document's. */
.hero h1, .section-title, .frow-copy h3, .bento-cell h3, .display {
  font-weight: 900; letter-spacing: -0.042em; line-height: 0.95;
}
.hero h1 { font-size: clamp(2.9rem, 7.4vw, 6.2rem); max-width: 15ch; }
.section-title { font-size: clamp(2.1rem, 4.8vw, 3.8rem); }
.frow-copy h3 { font-size: clamp(1.8rem, 3.8vw, 2.9rem); }

/* The shine word. A foil gradient that actually travels, because a static
   gradient on text is the oldest tell in the book. */
.icewords {
  background: linear-gradient(100deg,
      #ffffff 0%, #CFEDFF 18%, #6FD3FF 34%, #3FD8D0 46%,
      #A8ECFF 58%, #ffffff 72%, #CFEDFF 88%, #ffffff 100%);
  background-size: 280% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: foilshift 7s linear infinite;
}
@keyframes foilshift { to { background-position: 280% 0; } }

/* --------------------------------------------------------- atmosphere ----
   Light comes from behind the content, in slow motion. Two blurred blooms on
   opposite drifts never repeat visibly, so the background never reads as a
   looping gradient. */
.aurora {
  background:
    radial-gradient(42vw 38vw at 18% 8%,  rgba(47, 168, 236, 0.30), transparent 62%),
    radial-gradient(38vw 34vw at 84% 18%, rgba(63, 216, 208, 0.20), transparent 64%),
    radial-gradient(52vw 44vw at 60% 92%, rgba(14, 92, 150, 0.28),  transparent 66%);
  filter: blur(18px); opacity: 1;
  animation: auroradrift 26s ease-in-out infinite alternate;
}
@keyframes auroradrift {
  from { transform: translate3d(-2%, -1%, 0) scale(1.02); }
  to   { transform: translate3d(3%, 2%, 0)  scale(1.12); }
}

/* Sparkles. The one motif that says "shiny" without borrowing anything that
   belongs to Pokemon — a four-point star, drawn once as a mask so every
   instance can be tinted and sized from CSS alone. */
.spark {
  position: absolute; pointer-events: none; width: var(--s, 16px); height: var(--s, 16px);
  background: var(--c, #ffffff);
  -webkit-mask: var(--spark-url) center / contain no-repeat;
          mask: var(--spark-url) center / contain no-repeat;
  filter: drop-shadow(0 0 6px rgba(111, 211, 255, 0.9));
  opacity: 0; animation: twinkle var(--dur, 3.6s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}
:root {
  --spark-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 0c0 7 5 12 12 12-7 0-12 5-12 12 0-7-5-12-12-12 7 0 12-5 12-12z'/%3E%3C/svg%3E");
}
@keyframes twinkle {
  0%, 100% { opacity: 0; transform: scale(0.4) rotate(0deg); }
  45%      { opacity: 1; transform: scale(1) rotate(35deg); }
  70%      { opacity: 0.35; transform: scale(0.8) rotate(55deg); }
}

/* A light sweep that crosses a surface every few seconds. Attached to the
   elements that are meant to feel like foil: the CTA, the stat band, the
   phone frames. */
.sheen { position: relative; overflow: hidden; isolation: isolate; }
.sheen::after {
  content: ""; position: absolute; inset: -120% -40%; z-index: 2; pointer-events: none;
  background: linear-gradient(74deg, transparent 42%, rgba(255, 255, 255, 0.5) 50%, transparent 58%);
  transform: translateX(-120%); animation: sweep 6s var(--ease) infinite;
}
@keyframes sweep {
  0%, 62% { transform: translateX(-120%); }
  100%    { transform: translateX(120%); }
}

/* ------------------------------------------------------------- hero ------ */
.hero { position: relative; padding-top: clamp(1rem, 4vh, 2.5rem); }
/* Guarded by the breakpoint: the unguarded version of this rule sat after the
   860px collapse above and re-applied two columns on phones, which squeezed
   the headline into a 175px gutter and pushed the card off screen. */
@media (min-width: 861px) { .hero-split { grid-template-columns: 1.02fr 0.98fr; align-items: center; } }
.hero .lede { font-size: clamp(1.04rem, 1.3vw, 1.2rem); max-width: 31rem; color: var(--ink-dim); }
.hero .lede strong { color: var(--ink); font-weight: 700; }
@media (min-width: 1100px) {
  .hero { overflow: visible; }
  .cardstage { margin-right: calc(-1 * max(1.3rem, 50vw - 42rem) - 1rem); }
  .cardstage .holo { width: min(372px, 70vw); }
}

/* Availability strip under the CTAs: three platforms, stated as fact. */
.platforms { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.5rem; }
.plat {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0.9rem; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line);
  font-size: 0.8rem; color: var(--ink-dim);
}
.plat svg { width: 16px; height: 16px; color: var(--ice); }
.plat b { color: var(--ink); font-weight: 600; }
.plat small { color: var(--faint); font-size: 0.68rem; }

/* ------------------------------------------------------- the card river --
   Real catalog art, two rows, opposite drifts, faded out at both edges so it
   reads as a shelf continuing past the screen rather than a carousel that
   ends. The track holds the set twice; the animation travels exactly half its
   width, so the seam never lands. */
.river { position: relative; overflow: hidden; padding: 1.1rem 0; }
.river + .river { padding-top: 0; }
.river-track {
  display: flex; gap: 16px; width: max-content;
  animation: drift var(--dur, 72s) linear infinite;
}
.river.rev .river-track { animation-direction: reverse; }
.river:hover .river-track { animation-play-state: paused; }
@keyframes drift { to { transform: translateX(-50%); } }
.river-card {
  width: clamp(104px, 11vw, 148px); aspect-ratio: 63 / 88; flex: none;
  border-radius: 4.5%; overflow: hidden; position: relative;
  background: var(--panel-2); border: 1px solid var(--line);
  box-shadow: 0 14px 34px -18px rgba(0, 0, 0, 0.9);
}
.river-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The same foil the hero card uses, at a fraction of the strength — enough
   that the row shimmers as it moves without any card becoming unreadable. */
.river-card::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(112deg, transparent 38%, rgba(255, 255, 255, 0.34) 49%, transparent 60%);
  mix-blend-mode: overlay; opacity: 0.85;
}
.riverwrap {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

/* ---------------------------------------------------------- surfaces -----
   Radius is deliberate rather than uniform, but on the app-shaped end of the
   scale: 14px actions, 18px surfaces, 26px phone screens, 4.5% cards. A 4px
   corner reads as a website; a 16-18px corner reads as an app. */
.frost, .stat, .feat, .mock, .panel, .glowcard, .bento-cell { border-radius: 18px; }
.numband > div { border-radius: 0; }

.eyebrow { display: inline-flex; align-items: center; gap: 0.6rem;
  font-size: 0.68rem; letter-spacing: 0.2em; color: var(--ice); font-weight: 600; }
.eyebrow::before { content: ""; width: 1.6rem; height: 1px;
  background: linear-gradient(90deg, transparent, var(--ice)); }

/* Feature rows: the copy column is narrower than the media so the two sides
   stop mirroring each other, and the media sits slightly low. */
.frow { grid-template-columns: 0.82fr 1.18fr; align-items: start; }
.frow .frow-media { margin-top: clamp(0, 2vw, 1.6rem); }
.frow:nth-child(even) { grid-template-columns: 1.18fr 0.82fr; }
@media (max-width: 800px) {
  .frow, .frow:nth-child(even) { grid-template-columns: 1fr; }
  .frow .frow-media { margin-top: 0; }
}

/* Numbers want to be seen as numbers. */
.numband { border-radius: 20px; overflow: hidden;
  background: linear-gradient(160deg, rgba(47,168,236,0.09), rgba(11,17,32,0.4) 60%);
  border: 1px solid var(--line); }
.numband .value { font-size: clamp(1.9rem, 3.8vw, 3.1rem); font-weight: 700;
  font-family: var(--font); letter-spacing: -0.04em; }
.numband .label { color: var(--ice-2); font-weight: 600; }

/* A specification list, not a grid of cards. Two columns of hairline-ruled
   rows: denser, faster to scan, and it does not pretend six one-line claims
   each deserve their own panel. */
.spec { display: grid; grid-template-columns: 0.75fr 1.25fr; gap: clamp(1.5rem, 5vw, 4rem); align-items: start; }
.spec-head .section-title { margin-top: 0.6rem; }
.spec-list { display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(1.5rem, 4vw, 3rem); margin: 0; }
.spec-list > div { padding: 1.1rem 0; border-top: 1px solid var(--line); }
.spec-list dt { font-size: 0.95rem; color: var(--ink); font-weight: 700; margin-bottom: 0.25rem; }
.spec-list dd { margin: 0; font-size: 0.87rem; color: var(--muted); line-height: 1.5; }
@media (max-width: 860px) { .spec, .spec-list { grid-template-columns: 1fr; } }

/* ============================================================== bento =====
   Unequal tiles on an explicit grid: the large one carries the argument, the
   small ones carry a fact each. Seven tiles — below four it looks sparse,
   past twelve it reads as a wall. Gutter is half the inner padding, which
   keeps the cells related rather than floating. */
.bento {
  display: grid; grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: minmax(108px, auto); gap: 14px;   /* padding is 28px */
}
.bento-cell {
  position: relative; overflow: hidden;
  background: linear-gradient(168deg, var(--panel), var(--bg-2) 78%);
  border: 1px solid var(--line);
  padding: 26px;
  display: flex; flex-direction: column; justify-content: flex-start;
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
/* A single highlight running along the top edge — the thing that makes a dark
   tile look lit rather than printed. It brightens on hover, which is the
   whole hover state; the tile does not also grow a shadow. */
.bento-cell::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(111, 211, 255, 0.55), transparent);
  opacity: 0.6; transition: opacity 0.25s var(--ease);
}
.bento-cell:hover { border-color: var(--line-2); transform: translateY(-3px); }
.bento-cell:hover::before { opacity: 1; }
.bento-cell h3 { font-size: clamp(1.25rem, 2vw, 1.75rem); margin: 0 0 0.45rem; }
.bento-cell p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.55; }
.bento-cell .kicker { font-size: 0.64rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ice-2); font-weight: 600; margin-bottom: 1.1rem; }
.bento-cell .huge {
  font-weight: 900; letter-spacing: -0.05em;
  font-size: clamp(2.6rem, 6vw, 4.4rem); line-height: 0.88;
  font-variant-numeric: tabular-nums; margin-top: auto; margin-bottom: 0.5rem;
  background: var(--foil-text); background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: foilshift 9s linear infinite;
}
.bento-cell .huge sup, .bento-cell .huge span {
  font-size: 0.4em; vertical-align: 0.14em; margin-left: 0.06em;
  -webkit-text-fill-color: var(--muted);
}
.b-wide  { grid-column: span 4; grid-row: span 2; justify-content: flex-end; }
.b-tall  { grid-column: span 2; grid-row: span 2; justify-content: flex-end; }
.b-half  { grid-column: span 3; }
.b-third { grid-column: span 2; }
@media (max-width: 900px) {
  .bento { grid-template-columns: repeat(2, 1fr); }
  .b-wide, .b-tall, .b-half, .b-third { grid-column: span 2; grid-row: auto; }
}

/* ------------------------------------------------------------ actions ----
   The primary CTA is the only lit object on the page: white, rounded like an
   app button, glowing in the brand blue, with the foil sweeping across it.
   It presses down rather than sliding, which is how a native button behaves. */
.btn-hard {
  border-radius: 14px; border: 0;
  background: linear-gradient(180deg, #ffffff, var(--ice-soft));
  color: #062036; font-weight: 700; letter-spacing: -0.01em;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5),
              0 10px 30px -8px rgba(47, 168, 236, 0.65),
              0 2px 0 0 rgba(255, 255, 255, 0.9) inset;
  transition: transform 0.14s var(--ease), box-shadow 0.14s var(--ease);
  position: relative; overflow: hidden; isolation: isolate;
}
.btn-hard::after {
  content: ""; position: absolute; inset: -120% -40%; z-index: 2;
  background: linear-gradient(74deg, transparent 42%, rgba(255, 255, 255, 0.85) 50%, transparent 58%);
  transform: translateX(-120%); animation: sweep 4.5s var(--ease) infinite;
}
.btn-hard:hover { text-decoration: none; transform: translateY(-2px);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6),
              0 16px 40px -8px rgba(47, 168, 236, 0.8); }
.btn-hard:active { transform: translateY(1px);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.4), 0 4px 14px -6px rgba(47, 168, 236, 0.6); }

/* ------------------------------------------------------------- phones ----
   Brought in to the content instead of floating in a void, and lit from
   behind so the frames read as glass rather than as rectangles. */
.devices { align-items: center; }
.device { aspect-ratio: 9 / 17.6; }
.device .screen { border-radius: 26px; }
.devices::before { inset: 6% 14% 10%; }

/* Hero headline: 6.2rem filled four lines on a desktop and read as a poster
   rather than a product. Smaller, and allowed to breathe next to the card. */
.hero h1 { font-size: clamp(2.5rem, 5.4vw, 4.4rem); max-width: 13ch; line-height: 0.96; }

/* The page ground. --bg alone is very close to black once the aurora has
   faded out behind the fold; this keeps a navy cast from top to bottom, which
   is the difference between "dark app" and "empty void". */
body {
  background:
    linear-gradient(180deg, #0D1828 0%, #080E1B 32%, #070C17 62%, #0C1728 100%) fixed,
    var(--bg);
}

/* Sparkles never fully disappear — a star that blinks to zero reads as a
   rendering glitch on a static screen, and the screenshot in the app stores
   is a static screen. */
@keyframes twinkle {
  0%, 100% { opacity: 0.22; transform: scale(0.55) rotate(0deg); }
  45%      { opacity: 1;    transform: scale(1) rotate(35deg); }
  70%      { opacity: 0.45; transform: scale(0.82) rotate(55deg); }
}

@media (min-width: 1100px) {
  /* Was far enough out that the third card was sliced flat by the viewport
     edge, which reads as a layout bug rather than as a deliberate crop. */
  .cardstage { margin-right: calc(-1 * max(1.3rem, 50vw - 42rem) + 1rem); }
}

/* ======================================================== phone screens ===
   The frames were two-thirds empty: a header, four rows and a lot of dark.
   What makes a mockup read as a native app is the chrome around the content —
   a status bar at the top and a tab bar pinned to the bottom — so both are
   real here, and the content between them is dense enough to fill the glass. */
.device { width: clamp(212px, 27vw, 266px); }
.device .screen { justify-content: flex-start; }

.scr-status {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.5rem 0.85rem 0.1rem; font-size: 0.5rem; font-weight: 700;
  color: var(--ink); letter-spacing: 0.01em; position: relative; z-index: 6;
}
.scr-status .sig { display: inline-flex; align-items: flex-end; gap: 1.5px; height: 7px; }
.scr-status .sig i { width: 2px; border-radius: 1px; background: var(--ink); }
.scr-status .sig i:nth-child(1) { height: 3px; }
.scr-status .sig i:nth-child(2) { height: 4.5px; }
.scr-status .sig i:nth-child(3) { height: 6px; }
.scr-status .sig i:nth-child(4) { height: 7px; opacity: 0.35; }
.scr-batt { width: 15px; height: 7.5px; border-radius: 2px;
  border: 1px solid rgba(255, 255, 255, 0.5); position: relative; }
.scr-batt::before { content: ""; position: absolute; inset: 1px; right: 5px;
  background: var(--ink); border-radius: 1px; }
.scr-batt::after { content: ""; position: absolute; right: -3px; top: 2px;
  width: 1.5px; height: 3.5px; border-radius: 0 1px 1px 0; background: rgba(255, 255, 255, 0.5); }

.scr-appbar { display: flex; align-items: center; justify-content: space-between;
  padding: 0.35rem 0.85rem 0.2rem; }
.scr-appbar b { font-size: 0.72rem; font-weight: 700; letter-spacing: -0.02em; }
.scr-avatar { width: 16px; height: 16px; border-radius: 50%;
  background: linear-gradient(150deg, var(--ice), var(--ice-deep)); }

.scr-chips { display: flex; gap: 4px; padding: 0.3rem 0.6rem 0.1rem; }
.scr-chip { font-size: 0.47rem; padding: 0.2rem 0.45rem; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted); white-space: nowrap; }
.scr-chip.on { background: var(--ice); border-color: var(--ice); color: #062036; font-weight: 700; }

/* Card art inside the detail screen — a real image, because a grey rectangle
   where the card should be is what every generated mockup does. */
.scr-hero { display: flex; gap: 0.55rem; padding: 0.5rem 0.6rem 0.15rem; align-items: center; }
.scr-hero .art { width: 46px; aspect-ratio: 63 / 88; flex: none; border-radius: 4px;
  overflow: hidden; background: var(--panel-2); box-shadow: 0 6px 16px -8px rgba(0,0,0,.9); }
.scr-hero .art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.scr-hero .meta { min-width: 0; }

.scr-tabs {
  margin-top: auto; display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 0.45rem 0.2rem 0.6rem; border-top: 1px solid var(--line);
  background: rgba(146, 194, 255, 0.04);
}
.scr-tab { display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-size: 0.43rem; color: var(--faint); letter-spacing: 0.01em; }
.scr-tab svg { width: 13px; height: 13px; }
.scr-tab.on { color: var(--ice); }

/* The row list is the only part of a phone screen allowed to be cut off by
   the bottom of the glass — the tab bar below it is not, so the list shrinks
   and clips instead of pushing the chrome out of the frame. */
.device .scr-rows { flex: 0 1 auto; min-height: 0; overflow: hidden; }
.device .scr-tabs { flex: none; }
/* Real card art in the list rows. A flat gradient rectangle where a card
   should be is the single clearest sign a mockup was drawn rather than
   screenshotted. */
.scr-thumb { overflow: hidden; background: var(--panel-2); border: 1px solid var(--line); }
.scr-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Headline wrap. 13ch broke "Every price that's / real." and left a one-word
   orphan on its own line; the measure now holds the longer of the two
   sentences, and the <br> in the markup does the breaking. */
.hero h1 { max-width: 22ch; font-size: clamp(2.3rem, 4.6vw, 3.9rem); }

/* Sparkles read as grey stars rather than light: white alone is not bright
   against a lit card, so each one carries its own bloom. */
.spark {
  background: #ffffff;
  filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.95))
          drop-shadow(0 0 16px rgba(111, 211, 255, 0.85));
}

@media (min-width: 1100px) {
  /* The fanned card on the right was translated far enough to be sliced off
     by the viewport. Keep the fan, keep it inside the page. */
  .cardstage .holo.side.r { right: 4%; transform: perspective(1000px) rotate(14deg) translate(12%, 7%); }
  .cardstage .holo.side.l { left: 0;   transform: perspective(1000px) rotate(-14deg) translate(-16%, 7%); }
}

/* The list fades out into the tab bar instead of a row being chopped in half
   at an arbitrary height. */
.device .scr-rows {
  -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
}

/* ------------------------------------------------------------- phones ---- */
@media (max-width: 860px) {
  /* The card stage sits under the copy on a phone and is allowed to be wide,
     but never wider than the screen. */
  .cardstage { margin-right: 0 !important; min-height: 360px; }
  .cardstage .holo { width: min(272px, 74vw); }
  .hero h1 { font-size: clamp(2.1rem, 9.2vw, 3rem); max-width: none; }
  .hero .lede { max-width: none; }
  /* Full-width actions: a 140px pill next to a 150px pill is a desktop
     pattern that looks accidental on a phone. */
  .pillrow { display: grid; grid-template-columns: 1fr; gap: 0.6rem; }
  .pillrow .btn { width: 100%; }
  /* Three platform pills fit one row at phone width if they stop trying to
     be buttons. */
  .platforms { gap: 0.4rem; }
  .plat { padding: 0.42rem 0.6rem; font-size: 0.72rem; }
  .plat small { display: none; }
  .proofrow { gap: 0.9rem; font-size: 0.8rem; }
  .river-card { width: clamp(84px, 26vw, 116px); }
}

/* Full-bleed sections were landing 48px right of everything else, so the stat
   band and the spec list sat off the page grid and pushed ~48px of horizontal
   overflow onto the document. The cause is the percentage in the original
   `calc(50% - 50vw)`: it resolves against the containing block, and .mkt-main
   is `min(84rem, 100% - 2.6rem)`, so the two halves of that subtraction were
   measuring different things. Restated without a percentage — the gutter is
   computable directly from the same two values .mkt-main uses, so the pull-out
   and the push-in are guaranteed to be the same number. */
.bleed {
  width: 100vw;
  margin-inline: calc(-1 * max(1.3rem, (100vw - 84rem) / 2));
  padding-inline: max(1.3rem, (100vw - 84rem) / 2);
}

/* The two feature tiles bottom-aligned everything, which left the kicker
   floating in dead space at the top of the wide cell while the small tiles
   had theirs on the top edge. Kicker up, content down, one reading line. */
.b-wide, .b-tall { justify-content: space-between; }

/* NOTE for anyone adding a .bleed section: set margin-block, never the margin
   shorthand. An inline `margin: 2rem 0` also writes margin-left/right: 0,
   which cancels the negative pull-out above and leaves the section sitting one
   gutter to the right of the page grid while overflowing the same amount off
   the other edge. That is exactly what was wrong here. */

/* space-between spread the heading and its paragraph apart inside the two
   feature tiles. Push from the kicker instead: it stays on the top edge and
   everything after it travels down together as one block. */
.b-wide, .b-tall { justify-content: flex-start; }
.b-wide .kicker, .b-tall .kicker { margin-bottom: auto; }
.b-wide h3, .b-tall h3 { margin-top: 1.4rem; }

/* Banded sections were painted with --bg-2, which is flatter and darker than
   the body's navy, so every band read as a black rectangle cut out of the
   page. Same principle as everywhere else here: a surface separates from the
   ground by being LIGHTER, so the band is a blue wash over the ground rather
   than a different, darker colour. */
.band {
  background:
    radial-gradient(70% 100% at 50% 0%, rgba(47, 168, 236, 0.16), transparent 70%),
    linear-gradient(180deg, rgba(146, 194, 255, 0.055), rgba(146, 194, 255, 0.02));
  border-block: 1px solid var(--line);
}

/* The primary action was a 1rem pill under a 3.8rem heading. Give it the
   weight the rest of the page implies. */
.btn-lg { padding: 0.95rem 1.9rem; font-size: 1.04rem; border-radius: 14px; }
