/* ==========================================================================
   ChaseCard — public marketing home page
   Deliberately separate from dashboard.html/admin.html's styling — this
   page has its own design system and should not share classes/variables
   with the logged-in app.
   ========================================================================== */

/* BETA corner ribbon — pinned to the top-left corner of the viewport,
   independent of header layout. Shared identical block copy-pasted across
   every page (home/dashboard/admin/login/register/etc — each is its own
   single-file monolith with no shared stylesheet to hang this off). */
.beta-ribbon {
  position: fixed;
  top: 0;
  left: 0;
  width: 130px;
  height: 130px;
  overflow: hidden;
  z-index: 1000;
  pointer-events: none;
}
.beta-ribbon span {
  position: absolute;
  top: 24px;
  left: -34px;
  width: 170px;
  padding: 5px 0;
  background: #e8251a;
  color: #fff;
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .1em;
  text-align: center;
  text-transform: uppercase;
  transform: rotate(-45deg);
  box-shadow: 0 2px 8px rgba(0,0,0,.35);
}

:root {
  --bg: #0a0a0b;
  --bg-raised: #141416;
  --surface: #1a1a1d;
  --border: rgba(255, 255, 255, 0.09);
  --border-strong: rgba(255, 255, 255, 0.18);
  --text: #f5f5f6;
  --muted: #9b9ba3;
  --dim: #6a6a72;
  --brand: #e8251a;
  --brand-hover: #ff3a2e;
  --header-h: 76px;
  --placeholder-border: rgba(232, 37, 26, 0.35);
  --placeholder-bg: rgba(232, 37, 26, 0.04);

  /* Pokémon type accent colors — full reference table, even though only
     a subset of types are wired up to a live card overlay today. Each
     type's background art already exists at
     static/home-hero-pokemon-type-bgs/home-hero-{type}-type-bg.png (see
     the POKEMON_TYPE_BACKGROUNDS map in the page's <script> for the
     type → filename lookup used once this becomes dynamic). */
  --type-fire: #ff4208;
  --type-water: #00aeff;
  --type-grass: #63ff19;
  --type-electric: #ffe500;
  --type-psychic: #ff39e9;
  --type-ghost: #a86cff;
  --type-dragon: #7b38ff;
  --type-fighting: #ff6a00;
  --type-ground: #ff9b1c;
  --type-rock: #ffc34a;
  --type-ice: #83f2ff;
  --type-flying: #5aaeff;
  --type-poison: #c33cff;
  --type-fairy: #ff63d1;
  --type-steel: #f5faff;
  --type-dark: #e5d8ff;
  --type-bug: #8fff12;
  --type-normal: #ffffff;
}

/* Maps .hero-media's data-pokemon-type attribute to that type's accent
   color, exposed as --card-accent for the gradient border/glow below. */
.hero-media[data-pokemon-type="fire"]     { --card-accent: var(--type-fire); }
.hero-media[data-pokemon-type="water"]    { --card-accent: var(--type-water); }
.hero-media[data-pokemon-type="grass"]    { --card-accent: var(--type-grass); }
.hero-media[data-pokemon-type="electric"] { --card-accent: var(--type-electric); }
.hero-media[data-pokemon-type="psychic"]  { --card-accent: var(--type-psychic); }
.hero-media[data-pokemon-type="ghost"]    { --card-accent: var(--type-ghost); }
.hero-media[data-pokemon-type="dragon"]   { --card-accent: var(--type-dragon); }
.hero-media[data-pokemon-type="fighting"] { --card-accent: var(--type-fighting); }
.hero-media[data-pokemon-type="ground"]   { --card-accent: var(--type-ground); }
.hero-media[data-pokemon-type="rock"]     { --card-accent: var(--type-rock); }
.hero-media[data-pokemon-type="ice"]      { --card-accent: var(--type-ice); }
.hero-media[data-pokemon-type="flying"]   { --card-accent: var(--type-flying); }
.hero-media[data-pokemon-type="poison"]   { --card-accent: var(--type-poison); }
.hero-media[data-pokemon-type="fairy"]    { --card-accent: var(--type-fairy); }
.hero-media[data-pokemon-type="steel"]    { --card-accent: var(--type-steel); }
.hero-media[data-pokemon-type="dark"]     { --card-accent: var(--type-dark); }
.hero-media[data-pokemon-type="bug"]      { --card-accent: var(--type-bug); }
.hero-media[data-pokemon-type="normal"]   { --card-accent: var(--type-normal); }

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-width: 360px;
  background: var(--bg);
  color: var(--text);
  font-family: 'Sora', system-ui, -apple-system, sans-serif;
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
img, svg { display: block; }

/* ── Header ────────────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 32px;
  background: rgba(10, 10, 11, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.site-logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
/* Sizing/swap matches dashboard.html's header logo exactly (.logo-desktop
   80px / .logo-mobile 70px, swapping at the same 800px breakpoint). */
.site-logo .logo-mobile { display: none; }
.site-logo .logo-desktop { display: block; height: 80px; width: auto; object-fit: contain; }

.site-nav {
  display: flex;
  align-items: center;
  gap: 34px;
  flex: 1;
  justify-content: center;
}
.site-nav a {
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
  transition: color .15s;
}
.site-nav a:hover { color: var(--text); }

.site-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 20px;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.btn-ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text);
}
.btn-ghost:hover { border-color: var(--dim); }
.btn-brand {
  background: var(--brand);
  color: #fff;
}
.btn-brand:hover { background: var(--brand-hover); }
/* Replaces "Log in" when the user is authenticated (see the auth-check
   script near the bottom of the page) — avatar + first name, links to
   the app root same as "Start Free" -> "Dashboard" does. */
.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 14px 4px 4px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  text-decoration: none;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  transition: border-color .15s;
}
.user-chip:hover { border-color: var(--dim); }
.user-chip-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-raised);
  flex-shrink: 0;
}

/* Right-hand cluster — actions always sit next to the burger (when it's
   shown) as one group, so justify-content: space-between on the header
   only ever splits it into two groups (logo | this), not three drifting
   apart on mobile once the nav in between disappears. */
.header-right {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}

/* Burger — mobile only */
.burger-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  color: var(--text);
  cursor: pointer;
  flex-shrink: 0;
}
.burger-btn svg { pointer-events: none; }

/* Login/Start Free stay in the header on mobile too — only the nav links
   collapse into this dropdown. */
.mobile-nav {
  display: none;
  flex-direction: column;
  gap: 2px;
  padding: 12px 20px 20px;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
}
.mobile-nav a {
  padding: 12px 4px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}

body.mobile-nav-open .mobile-nav { display: flex; }

/* ── Hero ──────────────────────────────────────────────────────────── */

/* Full-bleed black; content itself is capped at a fixed 1200px, centered
   (the header/nav is unaffected — it stays full-width on its own). */
.hero {
  position: relative;
  width: 100%;
  background: #000000;
}
.hero-inner {
  position: relative;
  max-width: 1200px;
  margin: 0 auto;
  min-height: 500px;
}

.hero-copy {
  position: relative;
  z-index: 2;
  width: 583px;
  padding: 90px 0 88px 48px;
  box-sizing: border-box;
}

.hero-copy .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--brand);
  border: 1px solid var(--placeholder-border);
  background: var(--placeholder-bg);
  border-radius: 20px;
  padding: 6px 14px;
  margin-bottom: 20px;
}
.eyebrow-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand);
  flex-shrink: 0;
  animation: eyebrow-pulse 2.2s ease-in-out infinite;
}
@keyframes eyebrow-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .35; transform: scale(0.7); }
}
@media (prefers-reduced-motion: reduce) {
  .eyebrow-dot { animation: none; }
}

.hero-headline {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 44px; /* fixed on desktop — never scales; lines are hard-broken with <br>, not wrapped */
  line-height: 1.08;
  letter-spacing: -.01em;
  margin: 0 0 20px;
}
.hero-headline .accent { color: var(--brand); }

.hero-sub {
  font-size: 16px;
  color: var(--muted);
  max-width: 46ch;
  margin: 0 0 32px;
}

.hero-cta-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.btn-lg { padding: 14px 26px; font-size: 15px; }

/* Hero media — a fixed 742.42x500px window (500px * 980/660, the art's
   natural width at a fixed 500px tall) that's always right-anchored, all
   the way from 1200px down to the 800px mobile breakpoint. No separate
   crop phase, no cap — it just slides left as the page narrows, going
   increasingly behind .hero-copy (z-index).

   Instead, the art itself compensates: .hero-img and .hero-card-frame
   (inside the fixed window, via .hero-media-inner) both get an identical
   extra rightward pan — 0px at 1200px page width, growing to 200px at
   800px (1px of pan per 2px the page narrows: (1200px - 100vw) / 2,
   clamped to [0, 200]). Panning right means the window's left edge shows
   more blank space (which just reveals the black .hero background behind
   it — seamless) while its right edge clips more of the art away. Since
   both the art and the card overlay pan by the exact same amount, they
   stay locked in alignment with each other throughout. */
.hero-media {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1;
  height: 500px;
  width: calc(500px * 980 / 660);
  overflow: hidden;
  margin-top: 25px;
  /* Hidden until the live-hero fetch below resolves — avoids a flash of
     the static "Team Rocket's Mewtwo / psychic" placeholder markup on
     every page load. .is-ready is added once the fetch settles, whether
     it swapped in real data or (rare — DB unreachable, or before the
     very first background refresh has ever run) fell through to keep
     showing this same static markup as a genuine last-resort fallback. */
  opacity: 0;
  transition: opacity 1.1s ease;
}
.hero-media.is-ready { opacity: 1; }
.hero-media-inner {
  position: absolute;
  top: 0;
  left: 0;
  width: calc(500px * 980 / 660);
  height: 500px;
  line-height: 0;
  /* Card overlay position/size — quick to nudge together, all in one place. */
  --card-w: 33%;
  --card-top: 14.5%;
  --card-left: 33.5%;
  --card-rotate: 0deg;
  /* Shared pan offset — see the big comment on .hero-media above. */
  --media-pan: clamp(0px, calc((1200px - 100vw) / 2), 200px);
}
.hero-img {
  display: block;
  position: relative;
  left: var(--media-pan);
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Ambient cursor-repelled particle field — shared with beta.html (which
   reuses this file already), moved here from beta.css so both pages get it
   from one rule. Sits inside .hero-media-inner as the next sibling after
   .hero-img and before .hero-card-frame — default DOM-order stacking
   already puts it above the background art and below the card, no
   z-index needed. inset:0 fills the exact same box the JS measures via
   .hero-media's own getBoundingClientRect(). pointer-events:none so the
   card frame underneath stays clickable/hoverable. */
.hero-particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Card overlay frame — positioned/rotated/rounded once here; the image and
   stats panel inside are plain rects clipped to this shape via
   overflow:hidden, so their corners always match exactly (no separate
   border-radius math to keep in sync between the two).

   Gradient border: plain CSS borders can't take a gradient directly, so
   this uses the two-background trick (see
   https://medium.com/@limjoshen/gradient-borders-with-pure-css-db55c83c840b) —
   a solid layer clipped to the padding-box (so it never shows once the
   image/stats children paint over it) plus a gradient layer clipped to the
   border-box (only visible in the 2px border ring itself). The gradient
   runs the type's accent color at 60% opacity at the card's bottom up to
   fully transparent at the top. --card-accent comes from whichever
   data-pokemon-type is set on .hero-media (falls back to fire). */
.hero-card-frame {
  position: absolute;
  top: var(--card-top);
  left: calc(var(--card-left) + var(--media-pan));
  width: var(--card-w);
  aspect-ratio: 5 / 7;
  border-radius: 5% / 4%;
  border: 2px solid transparent;
  background:
    linear-gradient(#000, #000) padding-box,
    linear-gradient(to top,
      color-mix(in srgb, var(--card-accent, var(--type-fire)) 60%, transparent) 0%,
      transparent 100%) border-box;
  overflow: hidden;
  box-shadow:
    0 0 10px color-mix(in srgb, var(--card-accent, var(--type-fire)) 56%, transparent),
    0 10px 10px rgba(0, 0, 0, 0.55);
  /* "Materialize" reveal — starts scaled down/blurred/transparent, settles
     to normal once .hero-media picks up .is-ready (see the reveal-timing
     comment on .hero-media above). Runs a beat behind .hero-media's own
     fade so the art appears first, then the card focuses into view on top
     of it. transform includes --card-rotate in both states since that's
     also this element's static per-listing tilt, not part of the reveal. */
  opacity: 0;
  transform: rotate(var(--card-rotate)) scale(0.92);
  filter: blur(6px);
  transition:
    opacity .5s cubic-bezier(.2, .8, .2, 1) .1s,
    transform .5s cubic-bezier(.2, .8, .2, 1) .1s,
    filter .5s cubic-bezier(.2, .8, .2, 1) .1s;
}
.hero-media.is-ready .hero-card-frame {
  opacity: 1;
  transform: rotate(var(--card-rotate)) scale(1);
  filter: blur(0);
  animation: hero-glow-bloom 1.1s cubic-bezier(.2, .8, .2, 1) .1s both;
}
/* One-shot brighten-then-settle on the card's own ambient glow, landing
   back on the exact static box-shadow values above so nothing jumps once
   the animation ends. */
@keyframes hero-glow-bloom {
  0% {
    box-shadow:
      0 0 0 color-mix(in srgb, var(--card-accent, var(--type-fire)) 0%, transparent),
      0 10px 10px rgba(0, 0, 0, 0.55);
  }
  45% {
    box-shadow:
      0 0 36px color-mix(in srgb, var(--card-accent, var(--type-fire)) 85%, transparent),
      0 10px 10px rgba(0, 0, 0, 0.55);
  }
  100% {
    box-shadow:
      0 0 10px color-mix(in srgb, var(--card-accent, var(--type-fire)) 56%, transparent),
      0 10px 10px rgba(0, 0, 0, 0.55);
  }
}
/* Holo-foil light sweep — a diagonal band crosses the card once on
   reveal, like real holo Pokémon cards catching the light. Clipped to
   the card's rounded corners by .hero-card-frame's own overflow:hidden.
   Percentage-based size/travel so it scales with the card at any
   viewport width instead of assuming a fixed pixel card size. */
.hero-card-frame::after {
  content: '';
  position: absolute;
  top: -60%;
  left: -60%;
  width: 60%;
  height: 220%;
  z-index: 1;
  background: linear-gradient(115deg,
    transparent 30%,
    rgba(255, 255, 255, 0.55) 48%,
    color-mix(in srgb, var(--card-accent, var(--type-fire)) 70%, white 30%) 52%,
    transparent 70%);
  transform: rotate(20deg) translateX(-150%);
  opacity: 0;
  pointer-events: none;
}
.hero-media.is-ready .hero-card-frame::after {
  animation: hero-holo-sweep 1s ease-in-out .45s both;
}
@keyframes hero-holo-sweep {
  0%   { opacity: 0; transform: rotate(20deg) translateX(-150%); }
  15%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: rotate(20deg) translateX(250%); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-card-frame {
    transition: opacity .25s ease;
    transform: rotate(var(--card-rotate));
    filter: none;
    animation: none;
  }
  .hero-media.is-ready .hero-card-frame {
    transform: rotate(var(--card-rotate));
    animation: none;
  }
  .hero-card-frame::after { display: none; }
}
.hero-card {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.85;
}

/* Stats overlay — bottom half of the card. Solid black for the bottom
   third, then fades up to 60%-opaque black for the remaining two-thirds.
   Top corners rounded to mimic the card frame's own curve (bottom corners
   don't need their own radius — the frame's overflow:hidden already clips
   those). Placeholder values only (£XXX.XX / XX.X%) — these become real,
   updatable fields later. */
.hero-card-stats {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 43%;
  /* Above .hero-card-frame::after's holo sweep (z-index:1) — the sweep
     should pass behind the stats panel, not wash out the numbers. */
  z-index: 2;
  background: linear-gradient(to top,
    rgba(0, 0, 0, 1) 0%,
    rgba(0, 0, 0, 1) 33.33%,
    rgba(0, 0, 0, 0.6) 100%);
  border-radius: 4.5% 4.5% 0 0 / 6.4% 6.4% 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  column-gap: 10px;
  row-gap: 4px;
  padding: 7% 8%;
  box-sizing: border-box;
}
.hero-card-stats .stat {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}
.hero-card-stats .stat.flip { justify-content: center; }
.hero-card-stats .stat-label {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.65);
  line-height: 1.2;
}
.hero-card-stats .stat-value {
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.01em;
  color: #fff;
  line-height: 1.1;
}
.hero-card-stats .stat-value.down::before { content: '▼ '; font-size: 14px; }
.hero-card-stats .stat-green .stat-value,
.hero-card-stats .stat-green .stat-label { color: #22c55e; }

/* Sits entirely outside .hero-card-frame — a sibling in .hero-media-inner,
   not clipped by the frame's overflow:hidden/border-radius/glow at all.
   Positioned just below the card's bottom-left corner: --card-top (14.5%
   of the 500px-tall container = 72.5px) + the card's own height (--card-w
   at 33% of the 742.42px-wide container = 245px, times the 7/5 aspect
   ratio = 343px) + a small gap ≈ 429.5px, expressed below as a % of the
   500px container height. left tracks the card's own left edge (+ the
   hero-wide pan offset) so it stays aligned as the page narrows. */
.stat-found {
  position: absolute;
  top: 85.9%;
  left: calc(10px + var(--card-left) + var(--media-pan));
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: #fff;
}
.stat-found .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--card-accent, var(--type-fire));
  flex-shrink: 0;
}

.img-placeholder {
  width: 490px;
  height: 330px;
  max-width: 100%;
  border: 2px dashed var(--placeholder-border);
  border-radius: 14px;
  background: var(--placeholder-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--dim);
}
.img-placeholder svg { width: 40px; height: 40px; color: var(--dim); }
.img-placeholder .dims {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--muted);
}

/* ── Platform performance ─────────────────────────────────────────── */

.performance {
  background: var(--bg);
  padding: 56px 0;
  border-top: 1px solid var(--border);
}
.performance-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  box-sizing: border-box;
}
/* Lives inside .stats-strip's grid as its own full-width first row, styled
   like .highlight-header (small uppercase label + accent color) rather
   than a standalone page heading. */
.performance-heading {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--brand);
  margin: 0;
}
.performance-heading svg { width: 22.5px; height: 22.5px; flex-shrink: 0; }

/* Icon-led stat strip — explicit column counts at each breakpoint (not
   flex-wrap or auto-fit, both of which produced unpredictable in-between
   states — an uneven "3 then 1 alone" row, or a huge single gap when only
   2 of 4 pills fit a row) so it always reflows as a clean 4 → 2 → 1. */
.stats-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px 24px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 26px;
  margin-bottom: 24px;
  box-sizing: border-box;
}
.stat-pill {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Large + bold per spec — icons stay big even though the surrounding
   spacing below is trimmed to fit all 5 across in one row at 1200px. */
.stat-pill-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: color-mix(in srgb, var(--pill-accent) 16%, transparent);
  color: var(--pill-accent);
}
.stat-pill-icon svg { width: 28px; height: 28px; }
.stat-pill-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.stat-pill-value {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 24px;
  line-height: 1.1;
  color: var(--text);
}
.stat-pill-label {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}

/* Deal of the Week / Reviews / Collector of the Week / Weekly Best
   Sellers — always a 2x2 grid on desktop (never 4-across), one per row
   on mobile. */
.highlight-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
.highlight-card {
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-sizing: border-box;
}
.highlight-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--card-accent);
}
.highlight-header svg { width: 22.5px; height: 22.5px; flex-shrink: 0; }
/* Only used when a header also carries a trailing badge/pill group (Deal
   of the Week's save pills) — pushes title and badge to opposite ends
   instead of the badge overlapping the title text at narrower widths. */
.highlight-header.has-badge { justify-content: space-between; }
.highlight-title { display: flex; align-items: center; gap: 8px; min-width: 0; }

/* Deal of the Week — large thumbnail, big bold price with a small, dim,
   non-strikethrough market-price caption underneath. */
.deal-body { display: flex; gap: 16px; }
.deal-thumb {
  aspect-ratio: 5 / 7;
  height: 170px;
  object-fit: cover;
  border-radius: 10px;
  flex-shrink: 0;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}
.deal-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  justify-content: center;
}
.deal-name { font-weight: 700; font-size: 15px; }
.deal-set { font-size: 12px; color: var(--muted); }
.deal-number { font-size: 12px; color: var(--muted); }
.deal-price { font-family: 'Sora', sans-serif; font-weight: 700; font-size: 28px; }
/* "Market price" label stays small/regular; the price itself (in a
   <strong>) is bold at 75% of .deal-price's 28px. */
.deal-market { font-size: 12px; font-weight: 400; line-height: 0.8; color: var(--dim); }
.deal-market strong { font-size: 21px; font-weight: 700; }
/* Plain text, not a pill — bold larger % value, smaller regular label,
   both green. */
.deal-save-pct { margin-top: 6px; font-size: 12px; font-weight: 600; line-height: 0.8; color: #22c55e; }
.deal-save-pct strong { font-size: 19px; font-weight: 800; margin-right: 4px; }
/* Top-right badge (− £X saved) — sits in the header row itself
   (.highlight-header.has-badge), flush right, so it can never overlap
   the title even on a narrow card. */
.deal-save-row { display: flex; gap: 8px; flex-shrink: 0; }
.deal-save-pill {
  font-size: 13px;
  font-weight: 700;
  color: #22c55e;
  background: rgba(34, 197, 94, 0.14);
  padding: 5px 12px;
  border-radius: 20px;
}
.deal-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.deal-meta strong { color: var(--text); font-weight: 600; }
.deal-meta-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, #f5b400, #e8251a);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: #fff;
  flex-shrink: 0;
  overflow: hidden;
}
.deal-meta-avatar img { width: 100%; height: 100%; object-fit: cover; }
/* Shared "First Name @handle" identity treatment — bold name, regular-
   weight muted handle. Used on Deal of the Month's "Won by" line,
   Reviews' author line, and the Collector of the Month leaderboard, so
   public identity reads consistently everywhere on the page. */
.at-handle { font-weight: 400; color: var(--muted); }

/* Reviews — dot-controlled carousel, one .review-slide visible at a
   time (JS toggles .is-active). flex:1 so it fills the same height as
   its taller neighbours (grid stretches all 4 cards equal-height) and
   pushes the dots to the bottom regardless of quote length. */
.review-carousel { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.review-slide { display: none; flex-direction: column; gap: 10px; flex: 1; }
.review-slide.is-active { display: flex; }
.review-quote {
  display: flex;
  align-items: center;
  margin: 0;
  font-size: 21px;
  font-weight: 600;
  font-style: italic;
  line-height: 1.5;
  color: var(--text);
  flex: 1;
}
.review-stars { display: inline-flex; gap: 3px; font-size: 16.8px; }
.rstar { position: relative; display: inline-block; color: rgba(250, 204, 21, .28); }
.rstar-fill { position: absolute; top: 0; left: 0; overflow: hidden; white-space: nowrap; color: #facc15; }
.review-author { display: flex; align-items: center; gap: 10px; margin-top: auto; }
.review-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface);
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.review-name { font-size: 13px; font-weight: 600; }
/* Handle styling is now the shared .at-handle class (see near .deal-meta). */
/* Now sits in the header row (.highlight-header.has-badge), top-right,
   same placement pattern as Deal of the Week's badge. */
.review-dots {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.review-dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--border-strong);
  cursor: pointer;
}
.review-dot.is-active { background: var(--brand); }

/* Collector of the Week — a mocked top-5 leaderboard, same list shape as
   .sellers-list alongside it. */
.collector-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.collector-list li { display: flex; align-items: center; gap: 10px; }
.collector-rank {
  width: 20px;
  flex-shrink: 0;
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: var(--dim);
  text-align: center;
}
.collector-rank.rank-1 { color: #f5b400; }
.collector-rank.rank-2 { color: #c7ccd6; }
.collector-rank.rank-3 { color: #cd7f32; }
.collector-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, #f5b400, #e8251a);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: #fff;
  flex-shrink: 0;
  overflow: hidden;
}
.collector-avatar img { width: 100%; height: 100%; object-fit: cover; }
.collector-name {
  font-size: 13px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Combined £-saved + %-below-market — amount and percentage stacked so
   the row doesn't need to widen to fit both side by side. */
.collector-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex-shrink: 0;
}
.collector-amount { font-size: 13px; font-weight: 700; color: var(--text); line-height: 1.3; }
.collector-pct { font-size: 11px; font-weight: 600; color: #22c55e; line-height: 1.3; }
.collector-sort-caption {
  margin: 10px 0 0;
  font-size: 11px;
  color: var(--dim);
  text-align: center;
}
/* Ranking toggle — no label, deliberately tiny: white = by £ saved
   (default), green = by % saved. Switching swaps which figure in each
   row's .collector-stat is on top (amount vs pct), never their colours. */
.collector-toggle {
  width: 26px;
  height: 15px;
  border-radius: 20px;
  border: 1px solid var(--border-strong);
  background: #fff;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition: background .15s, border-color .15s;
}
.collector-toggle::after {
  content: '';
  position: absolute;
  top: 1px;
  left: 1px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--bg);
  transition: transform .15s;
}
.collector-toggle.is-on {
  background: #22c55e;
  border-color: #22c55e;
}
.collector-toggle.is-on::after { transform: translateX(11px); }

/* Weekly Best Sellers */
.sellers-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sellers-list li { display: flex; align-items: center; gap: 10px; }
.sellers-list img {
  width: 34px;
  height: 34px;
  object-fit: cover;
  border-radius: 6px;
  flex-shrink: 0;
}
.seller-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.seller-name {
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seller-set { font-size: 11px; color: var(--dim); }
.seller-count { font-size: 12px; font-weight: 700; color: var(--text); flex-shrink: 0; }

/* Now sits in the header row (.highlight-header.has-badge), top-right,
   same placement pattern as Deal of the Week's badge. */
.pokepulse-credit {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--dim);
  flex-shrink: 0;
}
.pokepulse-credit svg { width: 14px; height: 14px; }

/* ── How it works ──────────────────────────────────────────────────── */

.how-it-works {
  background: var(--bg);
  padding: 80px 0;
  border-top: 1px solid var(--border);
}
.hiw-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  box-sizing: border-box;
  text-align: center;
}
.hiw-heading {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 40px;
  line-height: 1.15;
  letter-spacing: -.01em;
  margin: 0 0 20px;
}
.hiw-heading .accent { color: var(--brand); }
.hiw-sub {
  font-size: 16px;
  color: var(--muted);
  max-width: 620px;
  margin: 0 auto 64px;
}

/* Mobile-only vertical connector — see the big comment on the mobile
   media query below. Hidden here; .hiw-track::before is desktop's
   equivalent (horizontal) line. */
.hiw-vline { display: none; }

/* Node row — 5 equal columns; the connecting line + chevrons sit behind
   the node circles, spanning column-center to column-center (10%-90% of
   the track for 5 equal 20%-wide columns). */
.hiw-track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: start;
  margin-bottom: 40px;
}
.hiw-track::before {
  content: '';
  position: absolute;
  top: 44px;
  left: 10%;
  right: 10%;
  height: 1px;
  background: var(--border-strong);
  z-index: 0;
}
.hiw-chevron {
  position: absolute;
  top: 44px;
  transform: translate(-50%, -50%);
  color: var(--dim);
  font-size: 16px;
  z-index: 0;
}

.hiw-node-col {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 0 8px;
}
.hiw-num {
  align-self: flex-start;
  margin-left: calc(50% - 44px);
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 12px;
  color: var(--dim);
}
.hiw-node-wrap { position: relative; }
.hiw-node {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
}
.hiw-node svg { width: 30px; height: 30px; }
.hiw-node.accent-red {
  border-color: rgba(232, 37, 26, 0.5);
  color: var(--brand);
  box-shadow: 0 0 24px rgba(232, 37, 26, 0.35);
}

/* All step badges/chips now sit in normal flow below the node circle
   (a plain flex child of .hiw-node-col, same treatment as .hiw-chips) —
   no more absolute-positioned overlays fighting the step number or the
   neighbouring node for space. */
.hiw-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 20px;
  white-space: nowrap;
}
.hiw-badge.red {
  color: var(--brand);
  background: rgba(232, 37, 26, 0.12);
  border: 1px solid rgba(232, 37, 26, 0.4);
}
.hiw-badge.green {
  color: #22c55e;
  background: rgba(34, 197, 94, 0.14);
  border: 1px solid rgba(34, 197, 94, 0.4);
}

.hiw-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}
.hiw-chip {
  font-size: 10px;
  font-weight: 600;
  color: var(--muted);
  border: 1px solid var(--border-strong);
  border-radius: 20px;
  padding: 3px 10px;
}

.hiw-text-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0 16px;
  text-align: center;
}
.hiw-text-col h3 {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 15px;
  margin: 0 0 8px;
}
.hiw-text-col p {
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
  margin: 0;
}

/* ── Features ──────────────────────────────────────────────────────── */

.features {
  background: var(--bg-raised);
  padding: 80px 0;
  border-top: 1px solid var(--border);
}
.features-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  box-sizing: border-box;
  text-align: center;
}
.features-eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 16px;
}
.features-heading {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 40px;
  line-height: 1.15;
  letter-spacing: -.01em;
  margin: 0 0 20px;
}
.features-heading .accent { color: var(--brand); }
.features-sub {
  font-size: 16px;
  color: var(--muted);
  max-width: 620px;
  margin: 0 auto 56px;
}

.features-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
/* A card count that leaves exactly one orphan in the final row (7 today,
   but this keeps working if the count changes) — centre it instead of
   letting it sit flush left with two empty slots beside it. No-ops for
   any other card count. */
.feature-card:last-child:nth-child(3n+1) {
  grid-column: 2;
}
.feature-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 24px;
  text-align: left;
}

.feature-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
  background: color-mix(in srgb, var(--f-accent) 16%, transparent);
  color: var(--f-accent);
}
.feature-icon svg { width: 24px; height: 24px; }

.feature-card h3 {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 17px;
  margin: 0 0 10px;
}
.feature-soon {
  font-family: 'Sora', sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 20px;
  padding: 3px 9px;
}
.feature-card p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  margin: 0;
}
.feature-card p strong { color: var(--text); }

/* ── Marketplace ───────────────────────────────────────────────────── */

.marketplace {
  background: var(--bg);
  padding: 80px 0;
  border-top: 1px solid var(--border);
}
.marketplace-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  box-sizing: border-box;
  text-align: center;
}
.marketplace-eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 16px;
}
.marketplace-heading {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -.01em;
  margin: 0 0 20px;
}
.marketplace-heading .accent { color: var(--brand); }
.marketplace-sub {
  font-size: 16px;
  color: var(--muted);
  max-width: 620px;
  margin: 0 auto 56px;
}

.mp-logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
  gap: 20px;
}
.mp-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 32px;
  min-width: 180px;
}
.mp-logo.soon { opacity: 0.55; }

/* Real brand marks (Simple Icons), tinted to each brand's own colour —
   dimmed to muted grey for the "coming soon" ones via .mp-logo.soon
   below rather than showing full colour for something not live yet. */
.mp-icon { width: 32px; height: 32px; }
.mp-vinted { color: #09b1ba; }
.mp-ebay { color: #e53238; }
.mp-facebook { color: #1877f2; }
.mp-shopify { color: #95bf47; }
.mp-logo.soon .mp-icon { color: var(--dim); }

.mp-wordmark {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 16px;
}
.mp-logo.soon .mp-wordmark { font-size: 14px; font-weight: 600; color: var(--muted); }
.mp-soon-tag {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--dim);
  border: 1px solid var(--border-strong);
  border-radius: 20px;
  padding: 3px 10px;
}

/* ── Pricing ───────────────────────────────────────────────────────── */

.pricing {
  background: var(--bg-raised);
  padding: 80px 0;
  border-top: 1px solid var(--border);
}
.pricing-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  box-sizing: border-box;
  text-align: center;
}
.pricing-eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 16px;
}
.pricing-heading {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -.01em;
  margin: 0 0 16px;
}
.pricing-heading .accent { color: var(--brand); }
.pricing-sub {
  font-size: 16px;
  color: var(--muted);
  margin: 0 0 56px;
}

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  align-items: stretch;
}
.pricing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px 24px;
  text-align: left;
}
.pricing-card.featured {
  border-color: var(--brand);
  box-shadow: 0 0 32px rgba(232, 37, 26, 0.15);
}
.pricing-card-badge {
  position: absolute;
  top: -13px;
  left: 24px;
  background: var(--brand);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 20px;
}
/* Signed-in-only: marks the card matching the viewer's current tier — see
   the auth-aware script near the bottom of the page. Green rather than
   brand-red so it reads as a status indicator, not another marketing
   badge, and is visually distinct from "Most Popular" on the rare case
   both would apply to the same card (that one just swaps its text
   instead of stacking two badges — see the script). */
.pricing-card-badge.your-tier { background: #22c55e; }
.pricing-card-name {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 20px;
}
.pricing-card-tagline {
  font-size: 13px;
  color: var(--muted);
  min-height: 34px;
  margin: 6px 0 20px;
}
.pricing-card-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 24px;
}
.pricing-card-price .amount {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: 32px;
}
.pricing-card-price .period { font-size: 13px; color: var(--muted); }
.pricing-card-features {
  list-style: none;
  margin: 0 0 28px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1;
}
.pricing-card-features li {
  position: relative;
  padding-left: 22px;
  font-size: 13px;
  color: var(--muted);
}
.pricing-card-features li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: #22c55e;
  font-weight: 700;
}
.pricing-card-features strong { color: var(--text); }
.pricing-card-cta {
  display: block;
  text-align: center;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  transition: border-color .15s, background .15s, color .15s;
}
.pricing-card-cta:hover { border-color: var(--dim); }
.pricing-card-cta.primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.pricing-card-cta.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }

/* ── Final CTA ─────────────────────────────────────────────────────── */

.final-cta {
  max-width: 1200px;
  margin: 72px auto;
  padding: 0 32px;
  box-sizing: border-box;
}
.final-cta-inner {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 32px;
  background: #0a0a0b;
  border: 1px solid rgba(232, 37, 26, 0.4);
  border-radius: 20px;
  padding: 48px 56px;
  box-shadow: 0 0 60px rgba(232, 37, 26, 0.15);
}
/* Subtle card-art bleed on the right, reusing an existing hero asset,
   faded out toward the left via a mask so it reads as texture/mood
   rather than a competing image. */
/* Faint background-image bleed — removed per Luke's ask. Kept as
   display:none rather than deleting the rule, since beta.html's own
   final-cta already carries an identical override for the same reason
   (see static/beta.css) — this just makes home.html's copy of the
   section consistent with it. */
.final-cta-inner::before { display: none; }
.final-cta-copy { position: relative; z-index: 1; max-width: 600px; }
.final-cta-copy h2 {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 28px;
  line-height: 1.25;
  margin: 0 0 12px;
}
.final-cta-copy .accent { color: var(--brand); }
.final-cta-copy p { font-size: 15px; color: var(--muted); margin: 0; }
.final-cta-action {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  flex-shrink: 0;
}
.final-cta-note { font-size: 12px; color: var(--dim); }

/* ── Footer ────────────────────────────────────────────────────────── */

.site-footer {
  background: var(--bg);
  border-top: 1px solid var(--border);
  padding: 48px 0 32px;
}
.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 32px;
  box-sizing: border-box;
}
.footer-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 24px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--border);
}
.footer-logo img { height: 44px; width: auto; }
.footer-socials { display: flex; align-items: center; gap: 12px; }
.footer-socials a {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  color: var(--muted);
  transition: color .15s, border-color .15s;
}
.footer-socials a svg { width: 16px; height: 16px; }
.footer-socials a:hover { color: var(--text); border-color: var(--dim); }

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  padding: 24px 0;
}
.footer-links a { font-size: 13px; color: var(--muted); }
.footer-links a:hover { color: var(--text); }

.footer-bottom { font-size: 12px; color: var(--dim); }

/* Anchor-nav targets — offsets the jump so the sticky header doesn't
   cover the top of the section. */
.how-it-works, .features, .marketplace, .pricing {
  scroll-margin-top: calc(var(--header-h) + 16px);
}

/* ── Responsive ────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  /* Only the link list collapses into the burger. Start Free hides here
     too (kept only in the desktop header) — Log in stays visible. */
  .site-nav { display: none; }
  .burger-btn { display: flex; }
  /* Logo sits closer to the edge; tighter right-side gap so Log in +
     burger fit comfortably now that they're the only two remaining. */
  .site-header { padding: 0 16px; }
  .header-right { gap: 8px; }
  .site-actions .btn { padding: 8px 14px; font-size: 13px; }
  .site-actions .btn-brand { display: none; }
}

/* .highlight-row is always 2x2 on desktop already (see above) — only
   .stats-strip still needs a 4→2 step here before mobile's 1-column. */
@media (max-width: 1050px) and (min-width: 801px) {
  .stats-strip { grid-template-columns: 1fr 1fr; }
}

/* Hero + logo mobile breakpoint — matches dashboard.html's own logo-swap
   breakpoint (800px) exactly. Below this, the hero stops being a fixed
   500px-tall two-phase layout and stacks normally, full-width. */
@media (max-width: 800px) {
  .site-logo .logo-desktop { display: none; }
  .site-logo .logo-mobile { display: block; height: 70px; width: auto; object-fit: contain; }

  /* overflow-x:hidden guards against .hero-media below being wider than a
     narrow phone — it's centered and allowed to bleed off both edges
     symmetrically rather than shrinking (see .hero-media's comment). */
  .hero-inner { min-height: 0; overflow-x: hidden; }
  .hero-copy {
    position: static;
    width: 100%;
    padding: 40px 20px;
  }
  .hero-headline {
    font-size: clamp(28px, 8vw, 40px);
  }
  /* Fixed-height (not full-width-scaling) on mobile too, same approach as
     desktop just at 400px instead of 500px — width is auto-derived from
     that height via the art's own aspect ratio, NOT the viewport. This is
     deliberate: the old width:100% approach shrank the box down to
     whatever a given phone's width happened to be, but the card's fonts
     (.hero-card-stats etc.) are fixed px sizes that don't shrink with it —
     on a narrow phone the card became too small for its own text, causing
     overlap/wrapping. Staying at a fixed 400px height keeps every child
     element (art, card frame, stats) at a consistent, legible scale
     regardless of phone width; margin:auto centers the box, and it's
     allowed to bleed off both edges symmetrically on phones narrower than
     ~594px rather than resizing (see overflow-x:hidden above). */
  .hero-media {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    height: 400px;
    width: calc(400px * 980 / 660);
    /* Base margin-top is 25px on desktop — shifted up 100px net on
       mobile per Luke's request, tightening the gap under .hero-copy. */
    margin: -75px auto 0;
  }
  .hero-media-inner {
    position: relative;
    width: 100%;
    height: 100%;
    --media-pan: 0px;
  }
  /* The card itself is ~80% the size it is on desktop now (400px vs
     500px tall), so its fixed-px text needs to scale down by roughly the
     same ratio too, or it no longer fits — this was overflowing/getting
     clipped at the card's right edge before this. */
  .hero-card-stats { column-gap: 8px; row-gap: 3px; }
  .hero-card-stats .stat-label { font-size: 10px; }
  .hero-card-stats .stat-value { font-size: 17px; }
  .hero-card-stats .stat-value.down::before { font-size: 11px; }
  .img-placeholder { width: 100%; height: 260px; }

  .performance-inner { padding: 0 20px; }
  /* Single column — a 2-up grid didn't leave enough room per pill for the
     icon + label without wrapping badly/overflowing (see the annotated
     screenshot). Full width per pill fixes that outright. */
  .stats-strip {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 24px 20px;
  }
  .highlight-row { grid-template-columns: 1fr; }

  /* How it works — 5 columns side by side has no room on mobile, so this
     reflows into a single-column stepper with each icon paired directly
     against its own title/description on the same row. .hiw-track and
     .hiw-text-row (the two DOM containers holding the 5 nodes and the 5
     text blocks respectively) go display:contents so their children —
     .hiw-node-col and .hiw-text-col — become direct items of .hiw-inner's
     own grid, explicitly paired row-by-row via nth-of-type (need :nth-of-
     type rather than :nth-child since .hiw-chevron spans are interspersed
     among the node-cols in source order, but nth-of-type only counts
     same-tag siblings, i.e. the divs, ignoring the spans). .hiw-vline is a
     real element (not a pseudo-element — those don't reliably render
     against a display:contents parent) spanning the node-col rows via
     grid-row, replacing the horizontal ::before line used on desktop. */
  .hiw-heading { font-size: 30px; text-align: left; }
  .hiw-sub { margin-bottom: 40px; text-align: left; }
  .hiw-chevron { display: none; }
  .hiw-track::before { display: none; }

  .hiw-inner {
    display: grid;
    grid-template-columns: 64px 1fr;
    column-gap: 16px;
    row-gap: 32px;
    text-align: left;
  }
  .hiw-heading, .hiw-sub { grid-column: 1 / -1; }
  .hiw-track, .hiw-text-row { display: contents; }

  .hiw-vline {
    display: block;
    grid-row: 3 / 8;
    grid-column: 1;
    justify-self: center;
    width: 1px;
    background: var(--border-strong);
  }
  .hiw-node-col { grid-column: 1; padding: 0; }
  .hiw-node-col:nth-of-type(1) { grid-row: 3; }
  .hiw-node-col:nth-of-type(2) { grid-row: 4; }
  .hiw-node-col:nth-of-type(3) { grid-row: 5; }
  .hiw-node-col:nth-of-type(4) { grid-row: 6; }
  .hiw-node-col:nth-of-type(5) { grid-row: 7; }
  .hiw-num { display: none; } /* redundant once the step order is just a vertical list */
  .hiw-node { width: 64px; height: 64px; }
  .hiw-node svg { width: 24px; height: 24px; }
  .hiw-chips { display: none; } /* no room next to a 64px icon; the desktop-only flourish */
  /* .hiw-badge ("Deal Found"/"£41 Saved") was left visible here while
     .hiw-chips got hidden — meant Deal Found was the only pill showing
     on mobile, inconsistent with every other step. Same desktop-only
     treatment as the chips. */
  .hiw-badge { display: none; }

  .hiw-text-col {
    grid-column: 2;
    align-self: center;
    text-align: left;
  }
  .hiw-text-col:nth-of-type(1) { grid-row: 3; }
  .hiw-text-col:nth-of-type(2) { grid-row: 4; }
  .hiw-text-col:nth-of-type(3) { grid-row: 5; }
  .hiw-text-col:nth-of-type(4) { grid-row: 6; }
  .hiw-text-col:nth-of-type(5) { grid-row: 7; }

  .features-heading { font-size: 30px; }
  .features-grid { grid-template-columns: 1fr; }

  .marketplace-heading, .pricing-heading { font-size: 26px; }
  .mp-logo { min-width: 0; width: 100%; padding: 22px; }

  .pricing-grid { grid-template-columns: 1fr; }
  .pricing-card-tagline { min-height: 0; }

  .final-cta-inner { padding: 32px 24px; }
  .final-cta-action { align-items: flex-start; width: 100%; }
  .final-cta-action .btn { width: 100%; text-align: center; }

  .footer-top { flex-direction: column; align-items: flex-start; }

  /* Deal of the Month's "Won by" line crowds/wraps badly on narrow phones
     once avatar + bold name + handle + timestamp all compete for one row —
     drop the timestamp here, the other three are the important part. */
  .deal-meta-ago { display: none; }
}

/* Narrow window between the hero going full-width (800px) and the next
   phone breakpoint (680px) — enough horizontal room to sit the CTA
   buttons beside the headline instead of below it, so the hero reads as
   one compact block rather than three long stacked lines. Grid areas
   let .hero-cta-row (which comes after .hero-sub in the DOM) span both
   the headline and sub rows without reordering the markup. */
@media (max-width: 800px) and (min-width: 680px) {
  .hero-copy {
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: 20px;
    grid-template-areas:
      "eyebrow eyebrow"
      "headline cta"
      "sub cta";
  }
  .hero-copy .eyebrow { grid-area: eyebrow; }
  .hero-headline { grid-area: headline; }
  .hero-sub { grid-area: sub; }
  .hero-cta-row {
    grid-area: cta;
    flex-direction: column;
    align-items: flex-end;
    justify-content: start;
    flex-wrap: nowrap;
    align-self: stretch;
  }
}

/* Below 680px the CTA row drops back into normal full-width flow under
   .hero-copy (no beside-the-headline layout — not enough room), so the
   full 100px lift on .hero-media from the block above overlaps it by
   ~35px. Softened here to just the amount that still clears the buttons. */
@media (max-width: 679px) {
  .hero-media { margin-top: -30px; }
}

/* Once the viewport itself is narrower than .hero-media's natural
   594.55px width (400px * 980/660), stop bleeding it off both edges and
   instead let it shrink to the viewport (width:auto in spirit — 100% of
   its container). The art/card/found-row don't scale down with it: they
   stay pinned together at their fixed natural size inside .hero-media-inner,
   which is now absolutely positioned and offset via `left` to sit
   horizontally centered within the now-narrower window, cropping equally
   off both sides via .hero-media's overflow:hidden — the same
   fixed-size-content-plus-offset approach as desktop's pan trick, just
   centered instead of right-anchored. */
@media (max-width: 594.55px) {
  .hero-media { width: 100%; }
  .hero-media-inner {
    position: absolute;
    top: 0;
    left: calc((100% - (400px * 980 / 660)) / 2);
    width: calc(400px * 980 / 660);
    height: 400px;
  }
}
