/* ============================================================
   Sleevz — Marketing Site
   "Midnight Gold", ported from the app's own theme so the page and
   the product read as the same object. Graphite surfaces, one gold
   accent, jade and garnet reserved strictly for money moving the
   right and the wrong way.

   Every product surface on this page is live: the console runs the
   real proportional-split arithmetic, the vizzes are data, and the
   position panel in the hero is wired to both. Nothing here is a
   drawing of software.
   ============================================================ */

/* ---------- Fonts ----------
   Self-hosted rather than linked from fonts.googleapis.com: that link is a
   render-blocking request to a third party on every page load, and it leaks
   the visitor to Google. Both families are variable, so one file per subset
   covers every weight the site uses — and Archivo's width axis gives the
   hero its expanded cut without a second download.
   Refresh with: scripts/fetch-fonts.sh */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Design Tokens ---------- */
:root {
  /* --- Color. Values come from the app's dark theme in
         vendor-tracker-app/src/index.css — keep them in step. --- */
  --bg: #0a0c10;              /* canvas */
  --bg-2: #12151b;            /* raised band */
  --bg-3: #171a21;            /* panel */
  --surface: rgba(255, 255, 255, 0.025);
  --surface-2: rgba(255, 255, 255, 0.05);
  --border: rgba(255, 255, 255, 0.07);
  --border-strong: rgba(255, 255, 255, 0.13);

  --text: #e7ecf4;
  --text-2: #98a2b3;          /* 7.6:1 on canvas — safe for body copy */
  --text-3: #7d8697;          /* muted step; 5.0:1 on --bg-2, 5.3:1 on --bg */

  --accent: #d9ab4e;          /* the app's gold; 9.2:1 on canvas */
  --accent-hover: #e8bf6a;
  --accent-deep: #c2933a;
  --accent-ink: #1b1508;      /* text on accent buttons — 8.5:1 on gold */
  --accent-rgb: 217, 171, 78;   /* for alpha variants of the accent */
  --accent-dim: rgba(var(--accent-rgb), 0.1);
  --accent-border: rgba(var(--accent-rgb), 0.3);

  --pos: #45d68f;             /* profit */
  --neg: #f0776c;             /* loss */
  --info: #8ab4f8;            /* other people's goods */

  /* --- Type. Archivo for display, Inter for text. Paired on a
         contrast axis (grotesque vs. neo-grotesque) rather than two
         near-identical sans faces. --- */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Archivo', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-hero: clamp(38px, 5.4vw, 66px);
  --font-h2: clamp(28px, 4vw, 44px);

  /* --- Layout --- */
  --container: 1160px;
  /* Corner scale, applied by role and never mixed: --radius on buttons and
     fields, --radius-lg on panels, --radius-pill on tags and toggles. */
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 18px;
  --radius-pill: 999px;
  --section-pad: clamp(72px, 9vw, 128px);

  /* --- Stacking. Named steps, never arbitrary 9999s. --- */
  --z-menu: 50;               /* dropdowns, over their own panel only */
  --z-sticky: 100;
  --z-nav: 200;
  --z-drawer: 300;
  --z-toast: 400;

  /* --- Elevation. Two steps: resting panels and the hover lift.
         Tinted toward the canvas hue rather than pure black. --- */
  --shadow-panel: 0 34px 80px -44px rgba(0, 0, 0, 0.9);
  --shadow-lift: 0 22px 46px -26px rgba(4, 6, 10, 0.95);

  /* --- Motion. One family of exponential ease-outs, no bounce. --- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --dur-fast: 0.18s;
  --dur: 0.34s;
  --dur-slow: 0.72s;
}

/* ---------- Reset / Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, h4, p { margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, select { font-family: inherit; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding-inline: clamp(20px, 5vw, 40px);
}

/* Money and figures. The app sets these in Inter with tabular figures
   rather than a monospace face — a ledger, not a terminal. .mono is the
   older name, still used by the dashboard page. */
.money, .mono {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'ss01';
  letter-spacing: -0.01em;
}

/* A value that just changed. JS adds .tick for one beat; the flash is how
   you notice a number two panels away moved because of what you typed.

   The repeated class names are deliberate. Money colour has to beat
   element-plus-class rules further down (`.out-line b`, `.off-item b`),
   which outrank a single class; doubling raises specificity without an
   !important and without coupling these to every container they sit in.
   Flash beats sign, sign beats container. */
.money { transition: color 0.5s ease; }
.is-pos.is-pos { color: var(--pos); }
.is-neg.is-neg { color: var(--neg); }
.money.tick.tick { color: var(--accent); }

/* ---------- Shared type ---------- */
.h2 {
  font-family: var(--font-display);
  font-size: var(--font-h2);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.03em;
  text-wrap: balance;
  color: var(--text);
}

.section-lede {
  font-size: 17px;
  color: var(--text-2);
  max-width: 56ch;
  margin-top: 14px;
  text-wrap: pretty;
}

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 12px 22px;
  border-radius: var(--radius);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  transition: transform var(--dur) var(--ease-out), background var(--dur-fast) ease,
    box-shadow var(--dur) ease, border-color var(--dur-fast) ease, color var(--dur-fast) ease;
}

.btn > span { position: relative; z-index: 1; }

.btn-primary {
  background: linear-gradient(180deg, var(--accent), var(--accent-deep));
  color: var(--accent-ink);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset,
    0 8px 24px rgba(var(--accent-rgb), 0.24);
}

/* A slow light sweep across the primary CTA on hover. One surface on the
   page does this, so it reads as emphasis rather than as decoration. */
.btn-primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%,
    rgba(255, 255, 255, 0.45) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform 0.85s var(--ease-out);
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset,
    0 14px 34px rgba(var(--accent-rgb), 0.36);
}

.btn-primary:hover::after { transform: translateX(120%); }

.btn-ghost {
  border: 1px solid var(--border-strong);
  color: var(--text);
  background: var(--surface);
}

.btn-ghost:hover {
  border-color: rgba(255, 255, 255, 0.28);
  background: var(--surface-2);
  transform: translateY(-2px);
}

.btn-lg { min-height: 52px; padding: 15px 30px; font-size: 16px; }
.btn-sm { min-height: 38px; padding: 8px 16px; font-size: 14px; }

.btn:active { transform: translateY(0) scale(0.98); transition-duration: 0.08s; }

/* ---------- Scroll reveals ----------
   Hidden states apply only once JS tags <html class="js">, so a no-JS
   visitor sees the whole page. main.js also force-reveals on load as a
   safety net; content must never depend on a transition having fired. */
.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
.js .reveal.visible { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: 0.09s; }
.reveal.d2 { transition-delay: 0.18s; }
.reveal.d3 { transition-delay: 0.27s; }
.reveal.d4 { transition-delay: 0.36s; }

/* ---------- Page texture ----------
   Fine noise over the accent glows. Dark radial gradients band badly on
   8-bit panels; a couple of percent of grain removes the rings. */
.grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: overlay;
  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='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
}

/* ---------- Reading progress ---------- */
.progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: calc(var(--z-nav) + 1);
  pointer-events: none;
}

.progress span {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent-hover));
}

/* ============================================================
   NAV
   ============================================================ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.nav.scrolled {
  background: rgba(10, 12, 16, 0.72);
  backdrop-filter: blur(18px) saturate(1.5);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  border-bottom-color: var(--border);
}

.nav-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 14px clamp(20px, 5vw, 40px);
  display: flex;
  align-items: center;
  gap: 28px;
  transition: padding var(--dur) var(--ease-out);
}

.nav.scrolled .nav-inner { padding-block: 9px; }

.brand {
  display: flex;
  align-items: center;
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--text);
}

.brand-word { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.025em; }
.brand-z { color: var(--accent); display: inline-block; transition: transform var(--dur) var(--ease-out); }
.brand:hover .brand-z { transform: translateY(-2px) rotate(-6deg); }

.nav-links {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  margin-right: auto;
}

.nav-link {
  position: relative;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-2);
  padding: 8px 12px;
  border-radius: 8px;
  transition: color var(--dur-fast) ease;
}

.nav-link::after {
  content: '';
  position: absolute;
  left: 12px; right: 12px;
  bottom: 3px;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur) var(--ease-out);
}

.nav-link:hover { color: var(--text); }
.nav-link:hover::after,
.nav-link.is-current::after { transform: scaleX(1); }
.nav-link.is-current { color: var(--text); }

/* Rolling labels: the duplicate line rolls into place on hover/focus, like
   the Motion button pattern. The visible text stays aria-hidden while the
   link's aria-label provides one clean accessible name. */
.nav-roll__viewport {
  display: block;
  height: 1.6em;
  overflow: hidden;
}

.nav-roll__track {
  display: flex;
  flex-direction: column;
  transition: transform 500ms var(--ease-out);
}

.nav-roll__track > span {
  display: block;
  height: 1.6em;
  line-height: 1.6;
}

.nav-roll:hover .nav-roll__track,
.nav-roll:focus-visible .nav-roll__track { transform: translateY(-50%); }

.nav-actions { display: flex; align-items: center; gap: 10px; }

.nav-toggle {
  display: none;
  width: 42px; height: 42px;
  align-items: center;
  justify-content: center;
  color: var(--text);
  margin-left: auto;
}

/* Three CSS rules instead of an inline icon: the middle bar fades, the
   outer two rotate into an X. */
.nav-burger,
.nav-burger::before,
.nav-burger::after {
  display: block;
  width: 20px;
  height: 1.8px;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) ease;
}

.nav-burger { position: relative; }
.nav-burger::before,
.nav-burger::after { content: ''; position: absolute; left: 0; }
.nav-burger::before { top: -6px; }
.nav-burger::after { top: 6px; }

.nav-toggle[aria-expanded='true'] .nav-burger { background: transparent; }
.nav-toggle[aria-expanded='true'] .nav-burger::before { transform: translateY(6px) rotate(45deg); opacity: 1; }
.nav-toggle[aria-expanded='true'] .nav-burger::after { transform: translateY(-6px) rotate(-45deg); opacity: 1; }

.nav-mobile {
  display: none;
  flex-direction: column;
  gap: 4px;
  max-height: 0;
  padding: 0 clamp(20px, 5vw, 40px);
  opacity: 0;
  overflow: hidden;
  visibility: hidden;
  background: rgba(10, 12, 16, 0.97);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid transparent;
  transition:
    max-height var(--dur-slow) var(--ease-out),
    padding var(--dur-slow) var(--ease-out),
    opacity 0.25s ease,
    border-bottom-color var(--dur) ease,
    visibility 0s linear var(--dur-slow);
}

.nav-mobile.open {
  max-height: 440px;
  padding: 10px clamp(20px, 5vw, 40px) 20px;
  opacity: 1;
  visibility: visible;
  border-bottom-color: var(--border);
  transition:
    max-height var(--dur-slow) var(--ease-out),
    padding var(--dur-slow) var(--ease-out),
    opacity 0.3s ease 0.05s,
    border-bottom-color var(--dur) ease,
    visibility 0s;
}

.nav-mobile a {
  padding: 12px 4px;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-2);
  border-bottom: 1px solid var(--border);
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.3s ease, transform 0.4s var(--ease-out), color var(--dur-fast) ease;
}

.nav-mobile.open a { opacity: 1; transform: none; }
/* Staggered so the drawer unrolls rather than appearing all at once. */
.nav-mobile.open a:nth-child(1) { transition-delay: 0.05s; }
.nav-mobile.open a:nth-child(2) { transition-delay: 0.09s; }
.nav-mobile.open a:nth-child(3) { transition-delay: 0.13s; }
.nav-mobile.open a:nth-child(4) { transition-delay: 0.17s; }
.nav-mobile.open a:nth-child(5) { transition-delay: 0.21s; }
.nav-mobile.open a:nth-child(6) { transition-delay: 0.25s; }

.nav-mobile a:hover { color: var(--text); }
.nav-mobile .btn { margin-top: 12px; color: var(--accent-ink); border-bottom: none; }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  padding-top: clamp(116px, 15vh, 170px);
  padding-bottom: clamp(24px, 4vw, 48px);
  overflow: hidden;
}

.hero-glow {
  position: absolute;
  top: -280px;
  left: 18%;
  transform: translateX(-50%);
  width: min(1100px, 140vw);
  height: 720px;
  background:
    radial-gradient(closest-side, rgba(var(--accent-rgb), 0.115), transparent 70%),
    radial-gradient(closest-side, rgba(255, 255, 255, 0.035), transparent 60%);
  pointer-events: none;
  animation: glowDrift 22s ease-in-out infinite alternate;
}

@keyframes glowDrift {
  from { transform: translateX(-50%) translateY(0) scale(1); }
  to   { transform: translateX(-46%) translateY(26px) scale(1.06); }
}

.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  align-items: center;
  gap: clamp(36px, 5vw, 68px);
}

.hero-copy { display: flex; flex-direction: column; align-items: flex-start; }

.hero-headline {
  font-family: var(--font-display);
  font-size: var(--font-hero);
  font-weight: 700;
  font-stretch: 112%;
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--text);
}

/* Each line is its own mask, so the headline wipes up from underneath
   instead of fading in as a block. The padding is descender clearance —
   without it the "y" in "easy" gets sliced by the overflow. */
.hero-headline .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
}

.hero-headline .line > span {
  display: block;
  transform: translateY(105%);
  animation: lineUp 1s var(--ease-out) forwards;
}

.hero-headline .line:nth-child(2) > span { animation-delay: 0.11s; }
.hero-headline .line:nth-child(3) > span { animation-delay: 0.22s; }

@keyframes lineUp { to { transform: none; } }

.hero-sub {
  font-size: clamp(16px, 2.1vw, 19px);
  color: var(--text-2);
  max-width: 47ch;
  margin-top: 22px;
  text-wrap: pretty;
}

.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }

.trust-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: 28px;
  padding: 0;
  list-style: none;
}

.trust-item {
  position: relative;
  font-size: 13.5px;
  color: var(--text-2);
  padding-left: 16px;
}

.trust-item::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 5px; height: 5px;
  margin-top: -2.5px;
  border-radius: 50%;
  background: var(--accent);
}

/* ============================================================
   POSITION PANEL — the hero's right column. Real numbers, moved by
   the console further down the page.
   ============================================================ */
.position {
  position: relative;
  padding: clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(168deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.9);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: border-color var(--dur) ease, transform var(--dur) var(--ease-out);
}

.position:hover { border-color: var(--accent-border); transform: translateY(-3px); }

.position::before {
  content: '';
  position: absolute;
  top: 0; left: 14%; right: 14%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.55), transparent);
}

.pos-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.pos-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-3);
}

.pos-live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--pos);
}

.pos-live i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: livePulse 2.6s ease-in-out infinite;
}

@keyframes livePulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(69, 214, 143, 0.4); }
  50%      { opacity: 0.55; box-shadow: 0 0 0 5px rgba(69, 214, 143, 0); }
}

.pos-gain { display: flex; align-items: baseline; gap: 10px; margin-top: 14px; }

.pos-gain-val {
  font-family: var(--font-display);
  font-size: clamp(34px, 4.4vw, 46px);
  font-weight: 700;
  font-stretch: 104%;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--pos);
}

.pos-gain-val.is-neg { color: var(--neg); }
.pos-gain-label { font-size: 13px; color: var(--text-3); }

.spark { margin-top: 14px; height: 72px; }
.spark svg { width: 100%; height: 100%; overflow: visible; }
/* Mitred joins, square ends: the corners are the data, so they stay sharp. */
.spark-line { stroke: var(--accent); stroke-width: 2; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 6; }
.spark-dot { fill: var(--accent); }

/* `d` interpolates in Chrome and Safari when the segment count matches,
   which it always does here. Browsers without it just snap; the chart is
   correct either way. */
.spark-line, .spark-area, .spark-dot {
  transition: d 0.6s var(--ease-out), cx 0.6s var(--ease-out), cy 0.6s var(--ease-out);
}

/* ---------- The stock behind the number ----------
   The cards held, dealt as a hand: sleeves overlapping on an arc rather than
   a row of thumbnails. The face is drawn, not a scan: hue is keyed to the
   card's identity and never to what it is worth. */
.pos-hand {
  /* Sized so the scan is legible — you should be able to read the card, not
     just recognise the silhouette. The step widens to match: bigger cards
     need more angle between them to show the same amount of each face. */
  --fan-h: clamp(104px, 11vw, 150px);
  --fan-step: 11deg;
  margin-top: 8px;
}

/* Every card pivots about one point well below the hand, so a single angle
   per seat produces the spread and the arc together — the way a real fan
   works. Rotation is the only thing that moves; nothing is positioned by
   hand. */
.pos-fan {
  position: relative;
  /* Headroom for the hover lift on top, clearance underneath for the outer
     cards, whose bottom corners swing below the middle of the hand. */
  height: calc(var(--fan-h) + 48px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pos-cards-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 12.5px;
  color: var(--text-3);
}

.pos-card {
  position: absolute;
  left: 50%;
  bottom: 18px;
  /* Seat offset from the middle of the hand: -1.5 … 1.5 for four cards. */
  --off: calc(var(--i) - (var(--n) - 1) / 2);
  z-index: var(--i);
  transform-origin: 50% 300%;
  transform: translateX(-50%) rotate(calc(var(--off) * var(--fan-step)));
  transition: transform var(--dur) var(--ease-out);
}

.pos-card.is-new { animation: dealIn 0.6s var(--ease-out) both; }

/* Sized off the height so the sleeve keeps a card's proportions instead of
   growing into a poster on the wide layout. The ratio is the scan's, not the
   63x88mm card's — the scans carry a little bleed, and matching them is what
   keeps the art from being cropped. */
.pos-card-face {
  position: relative;
  display: block;
  height: var(--fan-h);
  width: auto;
  aspect-ratio: 245 / 337;
  overflow: hidden;
  border: 1px solid hsl(var(--tone) 55% 62% / 0.34);
  border-radius: var(--radius-sm);
  /* Shows through while the scan is still loading, and tints the sliver of
     sleeve the art doesn't reach. */
  background:
    linear-gradient(152deg, hsl(var(--tone) 60% 52% / 0.34), hsl(var(--tone) 45% 26% / 0.1) 66%),
    var(--bg-3);
  /* The dark ring is what separates one sleeve from the one it overlaps. */
  box-shadow:
    0 0 0 2px rgba(6, 8, 12, 0.85),
    0 14px 26px -12px rgba(0, 0, 0, 0.85),
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
  transition: transform var(--dur) var(--ease-out);
}

.pos-card-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Holo sweep. Parked off the left edge; it crosses on hover only. */
.pos-card-face::after {
  content: '';
  position: absolute;
  inset: -40% -130%;
  background: linear-gradient(76deg, transparent 44%, rgba(255, 255, 255, 0.14) 50%, transparent 56%);
  transform: translateX(-34%);
  transition: transform 0.9s var(--ease-out);
}

.position:hover .pos-card-face::after { transform: translateX(34%); }

/* Lift the card under the pointer clear of its neighbours. The lift lives on
   the face so it composes with the seat rotation instead of fighting it. */
.pos-card:hover { z-index: 9; }
.pos-card:hover .pos-card-face { transform: translateY(-14px); }
.pos-card:focus-visible { z-index: 9; outline: none; }
.pos-card:focus-visible .pos-card-face {
  transform: translateY(-14px);
  outline: 2px solid var(--accent-hover);
  outline-offset: 3px;
}

@keyframes dealIn {
  from { opacity: 0; transform: translateX(-50%) translateY(26px) rotate(calc(var(--off) * var(--fan-step) + 14deg)); }
  to { opacity: 1; transform: translateX(-50%) rotate(calc(var(--off) * var(--fan-step))); }
}

/* Names the card on top of the fan, or the one being hovered. Fixed height so
   swapping a long name for a short one never shifts the panel. */
.pos-readout {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  min-height: 18px;
  margin: 10px 0 0;
  font-size: 12px;
  line-height: 1.3;
}

.pos-readout-name {
  overflow: hidden;
  color: var(--text-2);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pos-readout-val { font-weight: 600; color: var(--text); }

.pos-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin: 18px 0 0;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.pos-cell { padding: 12px 14px; background: rgba(10, 12, 16, 0.5); }
.pos-cell dt { font-size: 11.5px; color: var(--text-3); }
.pos-cell dd { margin: 2px 0 0; font-size: 18px; font-weight: 600; }

.pos-foot { margin-top: 14px; font-size: 12.5px; color: var(--text-3); }
.pos-foot a { color: var(--accent); border-bottom: 1px solid rgba(var(--accent-rgb), 0.35); }

/* ============================================================
   PROOF STRIP
   ============================================================ */
.strip {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--bg-2);
  margin-top: clamp(56px, 7vw, 88px);
}

.strip-inner {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding-block: 26px;
}

.strip-item {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--text-3);
  position: relative;
}

.strip-item + .strip-item::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  height: 24px; width: 1px;
  background: var(--border);
}

.strip-num { font-size: 19px; font-weight: 600; color: var(--text); }

/* ============================================================
   SPLIT HEADING — the page's one typographic beat, sat on top of
   the console it asks about. Sizing comes from .h2; this only adds
   the two-line break, the accent italic, and the word rise.
   ============================================================ */
/* No max-width: the two lines are broken by hand below, so a measure
   cap only ever forces a third line. */
.split-h { line-height: 1.12; }

/* Emphasis via the same family's italic and the accent, not a second
   typeface dropped into the middle of a headline. */
.split-h em { color: var(--accent); font-style: italic; }

/* The question sits on its own line, so the claim and the challenge each
   read as one beat instead of colliding mid-sentence. */
.split-h .s-line { display: block; }

/* Word-by-word rise. JS wraps each word and sets --i; without JS the
   heading is simply static text. */
.js .split-h .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  transition: opacity 0.5s ease, transform 0.6s var(--ease-out);
  transition-delay: calc(var(--i) * 42ms);
}
.js .split-h.visible .w { opacity: 1; transform: none; }

/* ============================================================
   THE CONSOLE
   ============================================================ */
.console { padding-block: var(--section-pad); background: var(--bg-2); }

.console-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: clamp(26px, 3vw, 38px);
}

.reset-btn {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-3);
  padding: 8px 14px;
  min-height: 36px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease, background var(--dur-fast) ease;
}

.reset-btn:hover { color: var(--text); border-color: var(--border-strong); background: var(--surface-2); }

.deck {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.008));
  overflow: hidden;
  box-shadow: 0 40px 100px -50px rgba(0, 0, 0, 0.9);
}

.deck-tabs {
  position: relative;
  display: flex;
  gap: 2px;
  padding: 8px;
  border-bottom: 1px solid var(--border);
  background: rgba(10, 12, 16, 0.45);
  overflow-x: auto;
  scrollbar-width: none;
}

.deck-tabs::-webkit-scrollbar { display: none; }

.tab {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  padding: 9px 18px;
  min-height: 40px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-3);
  transition: color var(--dur) ease;
}

.tab:hover { color: var(--text-2); }
.tab.is-active { color: var(--text); font-weight: 600; }
.deck-tabs:not(.has-pill) .tab.is-active { background: var(--surface-2); }

.tab-pill {
  position: absolute;
  top: 0; left: 0;
  z-index: 0;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  will-change: transform;
}

.tab-pill.is-ready {
  opacity: 1;
  transition: transform 0.45s var(--ease-out), width 0.45s var(--ease-out),
    height 0.45s var(--ease-out), opacity 0.2s ease;
}

/* Panels switch with [hidden], so inactive ones leave the a11y tree
   entirely and a no-JS visitor still gets the first one. */
.panel[hidden] { display: none; }
.panel { animation: panelIn 0.5s var(--ease-out) both; }

@keyframes panelIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.panel-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
  align-items: stretch;
}

.pane { padding: clamp(22px, 2.6vw, 32px); }
.pane-form { display: flex; flex-direction: column; gap: 16px; }

/* The form column is usually the taller one. The output column used to push
   its figures to the bottom to fill that out; now that the splits are a line
   or two, centring the whole block reads better than a hole in the middle. */
.pane-out {
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-left: 1px solid var(--border);
  background: rgba(10, 12, 16, 0.42);
}

.pane-out .out-split + .out-note { margin-top: 14px; }

.pane-h {
  font-family: var(--font-display);
  font-size: clamp(19px, 2.2vw, 23px);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.15;
  color: var(--text);
}

.pane-p { font-size: 14.5px; color: var(--text-2); margin-top: -6px; text-wrap: pretty; }

/* ---------- Fields ---------- */
.fld { display: flex; flex-direction: column; gap: 6px; }
.fld-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }

.fld-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3);
}

.fld-tag {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 2px 6px;
  border-radius: 4px;
  color: var(--accent);
  background: var(--accent-dim);
}

.fld-tag.is-lock { color: var(--text-2); background: var(--surface-2); }

.fld-input {
  width: 100%;
  font-size: 16px; /* ≥16px stops iOS zooming on focus */
  color: var(--text);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 11px 13px;
  min-height: 46px;
  font-variant-numeric: tabular-nums;
  transition: border-color var(--dur-fast) ease, background var(--dur-fast) ease,
    box-shadow var(--dur-fast) ease;
}

.fld-input:focus {
  outline: none;
  border-color: var(--accent-border);
  background: rgba(255, 255, 255, 0.055);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

/* The multi-select's closed state is the same control as a single-select,
   so it takes the same rule rather than a copy of it. */
select.fld-input,
.multi-btn {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 34px;
  /* Chevron as a two-stop gradient pair — no icon file, no inline SVG. */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-2) 50%),
    linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 18px) 21px, calc(100% - 13px) 21px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

select.fld-input option { background: var(--bg-2); color: var(--text); }

.fld-wrap { position: relative; display: block; }
.fld-pre {
  position: absolute;
  left: 13px; top: 50%;
  transform: translateY(-50%);
  font-size: 15px;
  color: var(--text-3);
  pointer-events: none;
}
.fld-wrap .fld-input { padding-left: 26px; }

.fld-locked { opacity: 1; }
.fld-static {
  display: flex;
  align-items: center;
  padding: 11px 13px;
  min-height: 46px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-2);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.015);
}

.commit { margin-top: 4px; align-self: flex-start; }
.commit.is-done { pointer-events: none; }

/* ---------- Slider ---------- */
.slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 26px;
  background: transparent;
  cursor: grab;
}
.slider:active { cursor: grabbing; }

.slider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: var(--surface-2);
}
.slider::-moz-range-track { height: 4px; border-radius: 2px; background: var(--surface-2); }

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 18px; height: 18px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid var(--bg-2);
  box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.5), 0 2px 8px rgba(0, 0, 0, 0.5);
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) ease;
}
.slider::-moz-range-thumb {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid var(--bg-2);
  box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.5);
}
.slider:hover::-webkit-slider-thumb { transform: scale(1.15); }
.slider:active::-webkit-slider-thumb {
  transform: scale(1.25);
  box-shadow: 0 0 0 6px rgba(var(--accent-rgb), 0.16);
}

/* ---------- Lot rows ---------- */
.lot-rows { display: grid; gap: 1px; border-radius: var(--radius); overflow: hidden; background: var(--border); }

.lot-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 14px;
  padding: 9px 14px;
  background: rgba(10, 12, 16, 0.55);
  font-size: 14px;
}

.lot-name { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lot-mkt { font-size: 13px; color: var(--text-3); }
.lot-basis { font-weight: 600; min-width: 74px; text-align: right; }

/* ---------- Output pane ---------- */
.out-k {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-3);
}

.out-v {
  font-family: var(--font-display);
  font-size: clamp(30px, 3.8vw, 42px);
  font-weight: 700;
  font-stretch: 104%;
  letter-spacing: -0.035em;
  line-height: 1.05;
  margin-top: 6px;
}

.out-note { margin-top: 14px; font-size: 13px; color: var(--text-3); text-wrap: pretty; }

.out-split { margin-top: 18px; border-top: 1px solid var(--border); }

.out-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  color: var(--text-2);
}

/* The splits run to one or two lines now, so a trailing rule under the last
   one would box the row in rather than separate anything. */
.out-line:last-child { border-bottom: 0; }

.out-line b { font-size: 15px; font-weight: 600; color: var(--text); }
.out-line-strong { font-size: 15px; color: var(--text); }
.out-line-strong b { font-size: 17px; }

/* ---------- The split bar ----------
   Taller since it lost its key: it is now the only picture in the column,
   so it carries the top of the pane on its own. */
.stackbar {
  display: flex;
  height: 76px;
  margin-top: 12px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface-2);
}

.stackbar i {
  display: block;
  min-width: 2px;
  border-right: 1px solid rgba(10, 12, 16, 0.7);
  background: var(--seg, var(--accent));
  transition: flex-grow 0.55s var(--ease-out);
}

.stackbar i:last-child { border-right: none; }


/* ---------- Sell gauge ---------- */
.gauge {
  height: 6px;
  margin-top: 14px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}

.gauge span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent-hover));
  transition: width 0.55s var(--ease-out), background 0.4s ease;
}

.gauge.is-neg span { background: linear-gradient(90deg, #b1483f, var(--neg)); }

/* ---------- Multi-select ----------
   Closed, it is a select: same box, same chevron, same focus ring, straight
   off the .fld-input rules. Open, it is a menu of rows you can tick. */
.multi { position: relative; }

.multi-btn {
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.multi-btn:hover:not(:disabled) { border-color: var(--border-strong); }
.multi-btn:disabled { color: var(--text-3); cursor: default; }
.multi.is-open .multi-btn { border-color: var(--accent-border); }

.multi-menu {
  position: absolute;
  z-index: var(--z-menu);
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 244px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  /* Opaque: it sits over the fields below it. */
  background: var(--bg-3);
  box-shadow: var(--shadow-lift);
  animation: menuIn 0.16s var(--ease-out) both;
}

@keyframes menuIn {
  from { opacity: 0; transform: translateY(-5px); }
  to   { opacity: 1; transform: none; }
}

.multi-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  font-size: 14.5px;
  color: var(--text-2);
  text-align: left;
  transition: background var(--dur-fast) ease, color var(--dur-fast) ease;
}

.multi-opt:hover { background: var(--surface-2); color: var(--text); }
.multi-opt:focus-visible { outline: none; background: var(--surface-2); color: var(--text); }
.multi-opt.is-on { color: var(--accent); }
.multi-opt small { margin-left: auto; font-variant-numeric: tabular-nums; opacity: 0.75; }

/* The tick box. Empty square until it is on, then gold with a check drawn
   from two borders — same trick as the chevron, no icon file. */
.multi-tick {
  flex: none;
  width: 17px;
  height: 17px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  display: grid;
  place-items: center;
  transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

.multi-opt.is-on .multi-tick { background: var(--accent); border-color: var(--accent); }

.multi-opt.is-on .multi-tick::after {
  content: '';
  width: 8px;
  height: 4px;
  margin-top: -2px;
  border-left: 2px solid var(--accent-ink);
  border-bottom: 2px solid var(--accent-ink);
  transform: rotate(-45deg);
}

/* ---------- Breakdown list ---------- */
.breakdown { display: grid; gap: 1px; margin: 12px 0 0; padding: 0; list-style: none; background: var(--border); border-radius: var(--radius); overflow: hidden; }

.breakdown li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: baseline;
  padding: 10px 13px;
  background: rgba(10, 12, 16, 0.55);
  font-size: 13.5px;
  color: var(--text-2);
}

.breakdown li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.breakdown li b { font-weight: 600; }

/* ---------- Ledger ---------- */
.ledger { border-top: 1px solid var(--border); background: rgba(10, 12, 16, 0.5); }

.ledger-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 16px clamp(22px, 2.6vw, 32px) 10px;
}

.ledger-h { font-size: 12px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-3); }
.ledger-count { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }

.ledger-list { margin: 0; padding: 0 clamp(22px, 2.6vw, 32px) 18px; list-style: none; display: grid; gap: 1px; }

.ledger-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}

.ledger-row:last-child { border-bottom: none; }

.ledger-kind {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 4px 8px;
  border-radius: 5px;
  color: var(--text-2);
  background: var(--surface-2);
  white-space: nowrap;
}

.ledger-kind.is-buy { color: var(--accent); background: var(--accent-dim); }
.ledger-kind.is-sell { color: var(--pos); background: rgba(69, 214, 143, 0.12); }
.ledger-kind.is-trade { color: var(--info); background: rgba(138, 180, 248, 0.12); }

.ledger-what { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ledger-amt { font-weight: 600; font-variant-numeric: tabular-nums; }

/* A new entry slides down and a gold wash passes through it once. */
.ledger-row.is-new { animation: rowIn 0.55s var(--ease-out) both; }

@keyframes rowIn {
  0%   { opacity: 0; transform: translateY(-10px); background: rgba(var(--accent-rgb), 0.14); }
  60%  { opacity: 1; transform: none; }
  100% { background: transparent; }
}

/* ============================================================
   SHOWCASE — claim on one side, a working thing on the other.
   ============================================================ */
.engine { padding-block: clamp(72px, 8vw, 116px); }

/* Offline is a footnote, not a headline: it gets a shorter band than the
   sections carrying real weight. */
.field { padding-block: clamp(48px, 5vw, 76px); }

.showcase {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
  align-items: center;
  gap: clamp(32px, 6vw, 76px);
}

.showcase-flip { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); }
.showcase-flip .showcase-copy { order: 2; }
.showcase-flip > :not(.showcase-copy) { order: 1; }

.showcase-p { font-size: 17px; color: var(--text-2); max-width: 60ch; margin-top: 16px; text-wrap: pretty; }

/* Says out loud that the panel next to it is a thing you press, and that
   it keeps going after you press it. Cheaper than making a visitor infer
   both from a switch. */
.showcase-hint {
  margin-top: 18px;
  padding-left: 14px;
  border-left: 2px solid var(--accent-border);
  font-size: 14px;
  color: var(--text-3);
  max-width: 52ch;
  text-wrap: pretty;
}

.showcase-hint b { color: var(--accent); font-weight: 700; }

.tick-list { margin: 24px 0 0; padding: 0; list-style: none; display: grid; gap: 11px; }

.tick-list li {
  position: relative;
  padding-left: 26px;
  font-size: 15px;
  color: var(--text-2);
}

.tick-list li::before {
  content: '';
  position: absolute;
  left: 2px; top: 0.55em;
  width: 9px; height: 5px;
  border-left: 1.8px solid var(--accent);
  border-bottom: 1.8px solid var(--accent);
  transform: rotate(-45deg);
}

/* ---------- Live condition pricer ---------- */
.pricer {
  padding: clamp(22px, 2.6vw, 30px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(168deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.01));
  box-shadow: var(--shadow-panel);
  transition: border-color var(--dur) ease, transform var(--dur) var(--ease-out),
    box-shadow var(--dur) ease;
}

.pricer:hover, .pricer:focus-within {
  border-color: var(--accent-border);
  transform: translateY(-3px);
  box-shadow: var(--shadow-panel), var(--shadow-lift);
}

.pricer-card { font-size: 15px; font-weight: 600; color: var(--text); }
.pricer-card span { display: block; font-weight: 400; font-size: 12.5px; color: var(--text-3); margin-top: 2px; }

.pricer-val {
  font-family: var(--font-display);
  font-size: clamp(36px, 4.6vw, 50px);
  font-weight: 700;
  font-stretch: 104%;
  letter-spacing: -0.035em;
  line-height: 1;
  margin-top: 16px;
  color: var(--text);
}

.pricer-src { font-size: 12px; color: var(--text-3); margin-top: 8px; }

.conds { display: flex; gap: 6px; margin-top: 20px; }

.cond {
  flex: 1;
  padding: 9px 4px;
  min-height: 40px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease,
    background var(--dur-fast) ease;
}

.cond:hover { color: var(--text-2); border-color: var(--border-strong); }
.cond.is-active { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }

/* ============================================================
   TOOLKIT — uneven cells on purpose. Four identical cards in a grid
   is the tell; these are two wide and two narrow, and each carries a
   different kind of visual.
   ============================================================ */
.toolkit { padding-block: var(--section-pad); background: var(--bg-2); }

.bento {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: clamp(36px, 4vw, 56px);
}

/* The six demos are a grid without JavaScript, then a direct-manipulation
   carousel once main.js is available. The track only ever animates transform,
   so a swipe stays responsive even while a clip is decoding. */
.feature-carousel-nav { display: none; }

.js .feature-carousel { margin-top: clamp(36px, 4vw, 56px); }
.js .feature-viewport {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  cursor: grab;
  touch-action: pan-y;
}

.js .feature-viewport.is-dragging {
  cursor: grabbing;
  user-select: none;
}

.js .feature-track {
  display: flex;
  width: max-content;
  gap: clamp(16px, 2vw, 24px);
  margin-top: 0;
  transition: transform 0.52s var(--ease-out);
  will-change: transform;
}

.js .feature-track .cell {
  flex: 0 0 auto;
  width: min(740px, calc(100vw - clamp(140px, 24vw, 300px)));
  min-height: clamp(500px, 48vw, 610px);
  grid-column: auto;
  flex-direction: row;
  align-items: center;
  gap: clamp(28px, 5vw, 72px);
  transform-origin: center center;
  transition: border-color var(--dur) ease, background var(--dur) ease,
    transform 0.52s var(--ease-out), box-shadow var(--dur) ease,
    opacity 0.52s var(--ease-out), filter 0.52s var(--ease-out);
}

.js .feature-track .cell .cell-text { flex: 1 1 43%; }
.js .feature-track .cell .viz { flex: 1 1 57%; margin-top: 0; }
.js .feature-track .cell .clip { max-width: 400px; }

/* The immediate neighbours are a directional affordance, not additional
   content competing for attention. Their perspective points back toward the
   active demo and their subdued treatment makes the drag direction obvious. */
.js .feature-track .cell.is-before,
.js .feature-track .cell.is-after {
  z-index: 1;
  opacity: 0.43;
  filter: saturate(0.7) brightness(0.82);
  cursor: pointer;
}

/* A preview is one large selection target. Its embedded controls only become
   available after it moves to centre, so a tap anywhere on the preview selects
   that feature instead of unexpectedly playing a clip. */
.js .feature-track .cell.is-before > *,
.js .feature-track .cell.is-after > * { pointer-events: none; }

.js .feature-track .cell.is-before {
  transform: perspective(1500px) rotateY(-10deg) scale(0.95);
  transform-origin: right center;
}

.js .feature-track .cell.is-after {
  transform: perspective(1500px) rotateY(10deg) scale(0.95);
  transform-origin: left center;
}

.js .feature-track .cell.is-active { z-index: 2; }

.feature-arrow {
  position: absolute;
  z-index: 3;
  top: 50%;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  color: var(--text);
  background: rgba(10, 12, 16, 0.86);
  box-shadow: var(--shadow-panel);
  transform: translateY(-50%);
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease,
    background var(--dur-fast) ease, transform var(--dur-fast) var(--ease-out);
}

.feature-arrow-prev { left: 14px; }
.feature-arrow-next { right: 14px; }
.feature-arrow span { font-size: 22px; line-height: 1; transform: translateY(-1px); }
.feature-arrow:hover {
  color: var(--accent-ink);
  border-color: var(--accent);
  background: var(--accent);
}
.feature-arrow:active { transform: translateY(-50%) scale(0.94); }
.feature-arrow:focus-visible { outline: 2px solid var(--accent-hover); outline-offset: 3px; }

.js .feature-carousel-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  margin-top: 20px;
}

.feature-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 24px;
  min-width: 24px;
  height: 24px;
  margin-inline: -4px;
  padding: 0;
  border: 0;
  background: transparent;
}

.feature-dot::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--border-strong);
  transition: background var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}

.feature-dot:hover::before { background: var(--text-3); }
.feature-dot.is-active::before {
  background: var(--accent);
  box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.1);
}

.feature-dot:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 4px;
}

.cell {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 2.4vw, 26px);
  padding: clamp(24px, 3vw, 34px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color var(--dur) ease, background var(--dur) ease,
    transform var(--dur) var(--ease-out), box-shadow var(--dur) ease;
}

/* Lift plus a gold outline. The border warms rather than just brightening,
   so the cell under the cursor is unmistakable without moving anything
   around it. */
.cell:hover,
.cell:focus-within {
  border-color: var(--accent-border);
  background: var(--surface-2);
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}

/* The heading picks up the accent when the card does. */
.cell:hover .cell-h { color: var(--accent-hover); }

.cell-wide { grid-column: span 2; flex-direction: row; align-items: center; gap: clamp(24px, 3.5vw, 48px); }
.cell-wide .cell-text { flex: 1 1 46%; }
.cell-wide .viz { flex: 1 1 54%; }

.cell-text, .viz { position: relative; z-index: 2; }

/* Narrow cells are stretched to their row by the grid; sit the chart on
   the floor of the cell rather than letting it float mid-air. */
.cell:not(.cell-wide) .viz { margin-top: auto; }

.cell-h {
  font-family: var(--font-display);
  font-size: clamp(19px, 2.2vw, 24px);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--text);
  text-wrap: balance;
  transition: color var(--dur) ease;
}

.cell p { margin-top: 12px; font-size: 15px; color: var(--text-2); max-width: 52ch; text-wrap: pretty; }

/* Cursor-tracked accent wash. One gradient, no glass. */
.spotlight::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(520px circle at var(--mx, 50%) var(--my, 50%),
    rgba(var(--accent-rgb), 0.08), transparent 62%);
  opacity: 0;
  transition: opacity 0.45s ease;
  pointer-events: none;
  z-index: 1;
}

.spotlight:hover::before { opacity: 1; }

/* ---------- Shows viz ----------
   A clip of the app reading one show's P&L. It replaced three bars with a net
   each: the bars made the claim, the clip shows the page it comes from. */
.viz-shows { display: grid; gap: 12px; }

/* ---------- Consignment viz ----------
   A clip of the app taking a card in on consignment and paying it out. It
   replaced a gold/blue split bar with a legend and an "Owed out $105.00" line:
   the bar asserted a ratio nobody can check, and the clip shows the same $105.00
   being owed, on the screen that owes it. The cell's copy carries the teammates
   half; there was an AJ/MK avatar stack under the clip and it is gone, since it
   illustrated nothing the sentence above it doesn't already say. */
.viz-consign { display: grid; gap: 12px; }

/* ---------- Graded slab viz ----------
   A clip of the app reading a slab's cert label. It replaced a ladder of
   grade tiles per company: the ladder made the claim, this shows it. */
.viz-grades { display: grid; gap: 14px; }

/* ---------- The clip ----------
   The app, playing inside the card. The plate around it is page chrome rather
   than part of the video, so the border and the controls stay crisp at any
   size and the file stays small.

   Width is capped rather than fluid: the clip is a window on a phone screen,
   and past about 400px the card grows taller faster than the video gets more
   readable. */
.clip {
  display: grid;
  gap: 14px;
  width: 100%;
  max-width: 400px;
  margin-inline: auto;
}

/* In a half-width cell the clip stacks under the copy rather than sitting
   beside it, so its height is the whole cell's height — and its row-mate
   stretches to match. Give up a little scale to keep that row honest. */
.cell:not(.cell-wide) .clip { max-width: 340px; }

.clip-stage {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: #0a0c10;
  overflow: hidden;
  box-shadow: var(--shadow-panel);
  transition: border-color var(--dur) ease;
}

.cell:hover .clip-stage { border-color: var(--border-strong); }

.clip-video {
  display: block;
  width: 100%;
  height: auto;
}

/* Bottom-right, over the video. Small and quiet until the card is under the
   cursor — the clip is the point, not its buttons. */
.clip-controls {
  position: absolute;
  right: 10px;
  bottom: 26px; /* clear of the scrub bar along the bottom edge */
  display: flex;
  gap: 6px;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--dur) ease, transform var(--dur) var(--ease-out);
}

.cell:hover .clip-controls,
.clip-stage:focus-within .clip-controls { opacity: 1; transform: none; }

/* A clip only runs while the pointer is on its card, so at rest every card
   shows a still. Without this there is nothing on it saying it is a video. */
.clip-stage.is-paused .clip-controls { opacity: 1; transform: none; }

/* Touch has no hover to reveal them with. */
@media (hover: none) {
  .clip-controls { opacity: 1; transform: none; }
}

.clip-btn {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-sm);
  background: rgba(10, 12, 16, 0.72);
  backdrop-filter: blur(6px);
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease,
    color var(--dur-fast) ease;
}

.clip-btn:hover { background: rgba(10, 12, 16, 0.9); border-color: var(--accent-border); color: var(--accent); }

.clip-btn svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Scrub bar ----------
   A range input rather than a div with pointer handlers: dragging, clicking to
   a point, and the arrow keys all come free and correct, and a screen reader
   gets a real slider. It stays visible at rest — the clip loops, and where you
   are in it is worth seeing — but only grows a handle when the card is under
   the cursor, which is when you might want to drag.

   --p (0..1) is written by main.js; the track paints itself off it. */
.clip-scrub {
  position: absolute;
  left: 12px;
  bottom: 0;
  width: calc(100% - 24px);
  /* 24px so the hit area clears the minimum tap target — the track is 3px of
     it, centred, which lands the line 12px in from the bottom to match the
     12px it is inset either side. */
  height: 24px;
  margin: 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}

.clip-scrub::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    var(--accent) 0 calc(var(--p, 0) * 100%),
    rgba(255, 255, 255, 0.18) calc(var(--p, 0) * 100%) 100%
  );
}

.clip-scrub::-moz-range-track {
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    var(--accent) 0 calc(var(--p, 0) * 100%),
    rgba(255, 255, 255, 0.18) calc(var(--p, 0) * 100%) 100%
  );
}

/* margin-top centres an 11px handle on a 3px track. */
.clip-scrub::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px;
  height: 11px;
  margin-top: -4px;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.7);
  opacity: 0;
  transition: opacity var(--dur-fast) ease;
}

.clip-scrub::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.7);
  opacity: 0;
  transition: opacity var(--dur-fast) ease;
}

.cell:hover .clip-scrub::-webkit-slider-thumb,
.clip-scrub:focus-visible::-webkit-slider-thumb { opacity: 1; }
.cell:hover .clip-scrub::-moz-range-thumb,
.clip-scrub:focus-visible::-moz-range-thumb { opacity: 1; }

/* The input itself carries no outline; the ring goes on the track. */
.clip-scrub:focus-visible { outline: none; }
.clip-scrub:focus-visible::-webkit-slider-runnable-track {
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.45);
}
.clip-scrub:focus-visible::-moz-range-track {
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.45);
}

@media (hover: none) {
  .clip-scrub::-webkit-slider-thumb { opacity: 1; }
  .clip-scrub::-moz-range-thumb { opacity: 1; }
}

/* The play triangle is a solid shape, not an outline. */
.clip-i-play { fill: currentColor; stroke: none; }

/* One icon at a time: pause while it runs, play when it doesn't. */
.clip-i-play { display: none; }
.clip-stage.is-paused .clip-i-play { display: block; }
.clip-stage.is-paused .clip-i-pause { display: none; }

/* The label scan, deliberately small: it is a convenience on top of the
   grading support, not the feature itself. Sits under the cell's copy, so it
   carries its own rule above it rather than closing off a viz. */
.scan-foot {
  display: block;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text-3);
  text-wrap: pretty;
}

/* ---------- Clip mode toggle ----------
   For a cell that makes two claims and therefore carries two clips. The QR cell
   had this shape (as .qr-modes) until scan-to-pay was removed on 2026-08-05 and
   the styles went with it; the scanning cell needs it again for the graded-slab
   and raw-card clips, so it comes back generically named this time. */
.clip-modes { display: flex; gap: 8px; margin-top: 12px; }

.clip-mode {
  flex: 1;
  min-height: 34px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease,
    background var(--dur-fast) ease, transform var(--dur-fast) var(--ease-out);
}

.clip-mode:hover { color: var(--text); border-color: var(--border-strong); }
.clip-mode:active { transform: scale(0.97); }
.clip-mode.is-active { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); font-weight: 600; }

/* ---------- QR viz ----------
   One clip of the handoff sheet. It carried a second "Take payment" clip behind
   a .qr-modes toggle until scan-to-pay was removed (2026-08-05); the toggle's
   styles went with it. */
.viz-qr { display: grid; gap: 14px; }

/* ---------- Sealed product viz ----------
   Quantity is the whole feature, so the count is the loud element and the
   product name is the quiet one. */
.viz-sealed { display: grid; gap: 10px; }

.seal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.03);
  transition: border-color var(--dur) ease;
}

.cell:hover .seal-row { border-color: var(--border-strong); }

.seal-name { font-size: 13.5px; color: var(--text-2); }

.seal-qty {
  flex-shrink: 0;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  background: rgba(var(--accent-rgb), 0.14);
  color: var(--accent-hover);
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.5s ease, transform 0.5s var(--ease-out);
}

.seal-row:nth-child(1) .seal-qty { transition-delay: 0.15s; }
.seal-row:nth-child(2) .seal-qty { transition-delay: 0.28s; }
.seal-row:nth-child(3) .seal-qty { transition-delay: 0.41s; }
.cell.visible .seal-qty { opacity: 1; transform: none; }
html:not(.js) .seal-qty { opacity: 1; transform: none; }

/* ---------- Price alert viz ----------
   A clip of the app arming an alert. It replaced a hand-drawn chart with a
   toast: the chart made the claim, the clip shows the feature. */
.viz-alert { display: flex; flex-direction: column; gap: 12px; }

/* ---------- No-JS fallbacks ----------
   The charts grow from zero when their cell reveals, and .visible only
   ever comes from JS. Without it, put every bar at its resting value so
   the section is still a chart rather than an empty box. */
/* Nothing schedules the clip without JS, so show its controls and let the
   built-in ones do the work. The scrub bar goes with them: nothing writes --p
   or seeks on it, so it would be a dead grey rail with a handle stuck at zero. */
html:not(.js) .clip-controls,
html:not(.js) .clip-scrub { display: none; }

/* The console needs JS to compute anything, so say so rather than
   leaving live-looking numbers that do not move. */
.nojs-note {
  display: none;
  margin-top: 14px;
  font-size: 13px;
  color: var(--text-3);
}

html:not(.js) .nojs-note { display: block; }
html:not(.js) .slider, html:not(.js) .commit { display: none; }

/* ---------- Disabled commits ---------- */
.btn:disabled { opacity: 0.45; cursor: default; box-shadow: none; }
.btn:disabled:hover { transform: none; box-shadow: none; }
.btn:disabled::after { display: none; }

/* ============================================================
   DAY ONE — numbered because it genuinely is a sequence: you load
   stock before you log against it, and export after. Numbers are not
   used as decoration anywhere else on this page.
   ============================================================ */
.how {
  padding-block: var(--section-pad);
  overflow: clip;
}

.setup-walkthrough {
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) 34px minmax(360px, 1.12fr);
  column-gap: clamp(34px, 5vw, 76px);
  align-items: start;
  margin-top: clamp(42px, 6vw, 78px);
}

.steps {
  grid-column: 1;
  display: block;
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  position: relative;
  min-height: clamp(420px, 68vh, 660px);
  display: flex;
  align-items: center;
  opacity: 0.28;
  transition: opacity 360ms ease;
}

.step:first-child { margin-top: clamp(-120px, -10vh, -72px); }
.step:last-child { margin-bottom: clamp(-100px, -8vh, -56px); }
.step.is-active { opacity: 1; }

.step-copy {
  width: 100%;
  padding: 26px 0 clamp(38px, 6vh, 68px);
  border-top: 1px solid var(--border-strong);
}

.step-n { display: block; font-size: 12.5px; font-weight: 600; letter-spacing: 0.1em; color: var(--accent); margin-bottom: 14px; }

.step-h {
  font-family: var(--font-display);
  font-size: clamp(23px, 2vw, 31px);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.12;
  margin-bottom: 10px;
  color: var(--text);
  transition: color var(--dur) ease;
}

.step p { font-size: 15px; color: var(--text-2); max-width: 46ch; text-wrap: pretty; }

.setup-rail {
  grid-column: 2;
  position: sticky;
  top: calc(50vh - 72px);
  height: 144px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.setup-rail-line {
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 50%;
  width: 1px;
  background: var(--border-strong);
  transform: translateX(-50%);
}

.setup-dot {
  position: relative;
  z-index: 1;
  width: 9px;
  height: 9px;
  border: 2px solid var(--bg);
  border-radius: 50%;
  background: var(--text-3);
  box-shadow: 0 0 0 1px var(--border-strong);
  transition: transform 360ms var(--ease-out), background 240ms ease,
    box-shadow 240ms ease;
}

.setup-dot.is-active {
  transform: scale(1.55);
  background: var(--accent);
  box-shadow: 0 0 0 5px rgba(217, 171, 78, 0.13);
}

.setup-stage {
  grid-column: 3;
  position: sticky;
  top: clamp(112px, 15vh, 156px);
  min-height: clamp(390px, 58vh, 560px);
  padding: clamp(26px, 3.5vw, 46px);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(150deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.014));
  box-shadow: var(--shadow-panel);
}

.setup-stage::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px);
  background-size: 42px 42px;
  mask-image: linear-gradient(to bottom, rgba(0,0,0,.62), transparent 76%);
}

.setup-stage-top {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 16px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border);
}

.setup-stage-kicker {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

.setup-stage-kicker b { color: var(--accent); font-weight: 650; }

.setup-panels {
  position: relative;
  z-index: 2;
  min-height: clamp(260px, 40vh, 390px);
}

.setup-panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 260ms ease, transform 420ms var(--ease-out);
  pointer-events: none;
}

.setup-panel.is-active { opacity: 1; transform: none; }

.setup-panel h3 {
  margin-bottom: clamp(18px, 2.4vw, 28px);
  font-family: var(--font-display);
  font-size: clamp(27px, 3.1vw, 43px);
  line-height: 1.04;
  letter-spacing: -0.035em;
  color: var(--text);
  text-wrap: balance;
}

.setup-typed {
  max-width: 45ch;
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.65;
  color: var(--text-2);
  text-wrap: pretty;
}

.setup-word {
  opacity: clamp(0.14, calc((var(--type-progress, 0) * var(--word-count) - var(--word-index)) * 2.25), 1);
  transition: opacity 90ms linear;
}

/* The source copy is the mobile/no-script version. Hide it only after the
   enhanced desktop walkthrough has successfully initialised. */
@media (min-width: 861px) {
  .js .setup-spotlight-ready .step p { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
}

@media (max-width: 860px) {
  .setup-walkthrough { display: block; margin-top: 42px; }
  .steps { display: grid; gap: 34px; }
  .step, .step:first-child, .step:last-child { min-height: 0; margin: 0; opacity: 1; }
  .step-copy { padding: 24px 0 0; }
  .step-h { font-size: 22px; }
  .step p { font-size: 15px; }
  .setup-rail, .setup-stage { display: none; }
}

/* Progressive fallback: keep the original three-column explanation when the
   enhancement cannot run. The same complete version is used for print. */
html:not(.js) .setup-walkthrough,
html:not(.js) .steps { display: grid; }
html:not(.js) .setup-walkthrough { grid-template-columns: 1fr; }
html:not(.js) .steps { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: clamp(20px, 3vw, 34px); }
html:not(.js) .step,
html:not(.js) .step:first-child,
html:not(.js) .step:last-child { min-height: 0; margin: 0; opacity: 1; }
html:not(.js) .setup-rail,
html:not(.js) .setup-stage { display: none; }

/* ============================================================
   OFFLINE — a toggle you can actually flip.

   Everything below is in service of one problem: a visitor gives this
   panel about two seconds. In that time they have to work out that the
   switch is theirs, that rows will keep arriving after they press it,
   and which rows are stranded on the phone. So the switch is a labelled
   button rather than a bare iOS pill, the pending row shows a bar that
   counts down to the next arrival, and every row wears its state.
   ============================================================ */
.offline {
  padding: clamp(20px, 2.6vw, 28px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(168deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.01));
  box-shadow: var(--shadow-panel);
  transition: border-color var(--dur) ease, transform var(--dur) var(--ease-out),
    box-shadow var(--dur) ease;
}

.offline:hover, .offline:focus-within {
  border-color: var(--accent-border);
  transform: translateY(-3px);
  box-shadow: var(--shadow-panel), var(--shadow-lift);
}

.off-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* Network state. Says what the phone's radio is doing — not what the
   queue is doing; that is the strip below, and the two never repeat
   each other. */
.off-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--pos);
  transition: color var(--dur) ease;
}

.off-status i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  transition: background var(--dur) ease;
}

.offline[data-net='off'] .off-status { color: var(--text-3); }

/* A naked switch on a marketing page reads as a status light, and nobody
   presses a status light. So it carries its own verb. */
.off-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 5px 6px 5px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.off-toggle:hover { border-color: var(--accent-border); background: var(--accent-dim); }

.off-track {
  position: relative;
  width: 44px; height: 26px;
  border-radius: var(--radius-pill);
  background: rgba(69, 214, 143, 0.22);
  border: 1px solid rgba(69, 214, 143, 0.4);
  transition: background var(--dur) ease, border-color var(--dur) ease;
}

.off-knob {
  position: absolute;
  top: 2px; left: 21px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--pos);
  transition: transform 0.4s var(--ease-out), background var(--dur) ease;
}

.offline[data-net='off'] .off-track { background: var(--surface-2); border-color: var(--border-strong); }
.offline[data-net='off'] .off-knob { transform: translateX(-19px); background: var(--text-3); }

/* One-time nudge when the panel scrolls up, dropped on first press. */
.off-toggle.is-nudge { animation: offNudge 3s var(--ease-out) 0.8s 3; }

@keyframes offNudge {
  0%, 22%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0); }
  8%  { box-shadow: 0 0 0 7px rgba(var(--accent-rgb), 0.15); }
}

/* Queue state, in one glanceable line. This is the count the old note
   text buried at 12px in the muted step. */
.off-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease;
}

.off-bar i {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--pos);
  transition: background var(--dur) ease;
}

.off-bar[data-state='wait'] {
  color: var(--text);
  border-color: var(--accent-border);
  background: var(--accent-dim);
}

.off-bar[data-state='wait'] i { background: var(--accent); animation: offPulse 1.6s ease-in-out infinite; }
.off-bar[data-state='sync'] { color: var(--text); border-color: rgba(69, 214, 143, 0.3); }
.off-bar[data-state='sync'] i { animation: offPulse 1.1s ease-in-out infinite; }

@keyframes offPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.off-queue {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
  align-content: start;
  min-height: 132px;
}

.off-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  padding: 10px 13px;
  font-size: 13px;
  color: var(--text-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius);
  background: rgba(10, 12, 16, 0.5);
  animation: rowIn 0.45s var(--ease-out) both;
  transition: border-color var(--dur) ease, background var(--dur) ease, color var(--dur) ease;
}

.off-what { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.off-item b { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }

/* The marker doubles as the icon in the tag: a filled gold dot while it
   is stranded, a check once it has landed. */
.off-tick {
  position: relative;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  flex-shrink: 0;
  transition: border-color var(--dur) ease, background var(--dur) ease;
}

.off-item.is-wait { color: var(--text); border-left-color: var(--accent); }
.off-item.is-wait .off-tick { border-color: rgba(var(--accent-rgb), 0.6); }
.off-item.is-wait .off-tick::after {
  content: '';
  position: absolute;
  inset: 2.5px;
  border-radius: 50%;
  background: var(--accent);
  animation: offPulse 1.6s ease-in-out infinite;
}

.off-item.is-up { border-left-color: rgba(69, 214, 143, 0.5); }
.off-item.is-up .off-tick { border-color: rgba(69, 214, 143, 0.45); background: rgba(69, 214, 143, 0.12); }
.off-item.is-up .off-tick::after {
  content: '';
  position: absolute;
  left: 3.5px; top: 0.5px;
  width: 4px; height: 8px;
  border: solid var(--pos);
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(42deg);
}

.off-tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
}

.off-item.is-wait .off-tag {
  color: var(--accent);
  background: var(--accent-dim);
  border-color: var(--accent-border);
}

.off-item.is-up .off-tag {
  color: var(--pos);
  background: rgba(69, 214, 143, 0.09);
  border-color: rgba(69, 214, 143, 0.24);
}

/* Deals that were already on the server, collapsed rather than deleted:
   the list should never blank out under the visitor mid-demo. */
.off-rollup {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 13px;
  font-size: 12px;
  color: var(--text-3);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  animation: rowIn 0.45s var(--ease-out) both;
}

.off-rollup::before {
  content: '';
  width: 14px; height: 1px;
  background: var(--border-strong);
  flex-shrink: 0;
}

/* The answer to "is that it?". A placeholder for the deal that has not
   been logged yet, with a bar timed to the arrival so the wait is
   something you watch rather than something that surprises you. */
.off-ghost {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 13px;
  font-size: 12.5px;
  color: var(--text-3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: rgba(10, 12, 16, 0.3);
}

.off-ghost .off-tick { border-style: dashed; }

.off-ghost .off-ghost-bar {
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.75), rgba(var(--accent-rgb), 0.2));
  animation: offFill var(--off-tick, 1.6s) linear infinite;
}

@keyframes offFill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.off-note { margin-top: 14px; font-size: 12.5px; color: var(--text-3); min-height: 2.6em; text-wrap: pretty; }

/* Narrow: the tag drops to its own line under the deal rather than
   squeezing the name to three characters. */
@media (max-width: 560px) {
  .off-item { grid-template-columns: auto minmax(0, 1fr) auto; row-gap: 6px; }
  .off-tag { grid-column: 2 / -1; justify-self: start; }
}

/* ============================================================
   PRICING
   ============================================================ */
.pricing {
  padding-block: var(--section-pad);
  position: relative;
}

.pricing-shell {
  position: relative;
  overflow: hidden;
  padding: clamp(30px, 5vw, 72px);
  border: 1px solid var(--border);
  border-radius: 28px;
  background:
    radial-gradient(circle at 82% 8%, rgba(229, 179, 65, 0.12), transparent 32%),
    var(--surface);
}

.pricing-shell::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: linear-gradient(180deg, transparent 8%, var(--accent) 42%, transparent 88%);
  opacity: 0.75;
}

.pricing-intro {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(280px, 0.65fr);
  align-items: end;
  gap: 28px 64px;
  margin-bottom: clamp(32px, 5vw, 58px);
}

.pricing-intro .eyebrow {
  grid-column: 1 / -1;
  margin-bottom: -10px;
}

.pricing-lede {
  max-width: 52ch;
  color: var(--text-2);
  font-size: clamp(16px, 1.5vw, 19px);
  line-height: 1.65;
}

.pricing-options {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-block: 1px solid var(--border);
}

.pricing-option {
  position: relative;
  min-height: 330px;
  display: flex;
  flex-direction: column;
  padding: 30px;
  color: var(--text);
  border-right: 1px solid var(--border);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.012);
  transition: background 220ms ease, transform 220ms ease;
}

.pricing-option:last-child { border-right: 0; }

.pricing-option:hover,
.pricing-option:focus-visible {
  background: rgba(255, 255, 255, 0.04);
}

.pricing-option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.pricing-option--featured {
  background: linear-gradient(180deg, rgba(229, 179, 65, 0.115), rgba(229, 179, 65, 0.028));
}

.pricing-option__badge {
  position: absolute;
  top: 24px;
  right: 24px;
  padding: 6px 9px;
  border: 1px solid rgba(229, 179, 65, 0.3);
  border-radius: 999px;
  color: var(--accent);
  background: rgba(229, 179, 65, 0.08);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.pricing-option__name {
  color: var(--text-2);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.pricing-option__price {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 34px;
}

.pricing-option__price strong {
  font-family: var(--display);
  font-size: clamp(48px, 5vw, 72px);
  font-weight: 500;
  letter-spacing: -0.055em;
  line-height: 0.9;
}

.pricing-option__price span,
.pricing-option__note {
  color: var(--text-2);
  font-size: 14px;
}

.pricing-option__note { margin-top: 18px; }

.pricing-option__action {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 32px;
  border-top: 1px solid var(--border);
  color: var(--text);
  font-size: 14px;
  font-weight: 650;
}

.pricing-option__action span {
  color: var(--accent);
  transition: transform 220ms ease;
}

.pricing-option:hover .pricing-option__action span { transform: translate(2px, -2px); }

.pricing-fine {
  margin-top: 18px;
  color: var(--text-3, var(--text-2));
  font-size: 12px;
}

@media (max-width: 820px) {
  .pricing-intro { grid-template-columns: 1fr; }
  .pricing-options { grid-template-columns: 1fr; }
  .pricing-option {
    min-height: 230px;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }
  .pricing-option:last-child { border-bottom: 0; }
}

@media (max-width: 520px) {
  .pricing-shell { border-radius: 20px; }
  .pricing-option { padding: 24px 4px; }
  .pricing-option__badge { right: 4px; }
}

/* ============================================================
   FAQ
   ============================================================ */
.faq { padding-block: var(--section-pad); }

.faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.7fr) minmax(0, 1fr);
  gap: clamp(32px, 6vw, 76px);
  align-items: start;
}

.faq-aside { position: sticky; top: 108px; }

.faq-list { border-top: 1px solid var(--border); }

.faq-item {
  position: relative;
  border-bottom: 1px solid var(--border);
  transition: border-color var(--dur) ease;
}

/* Hover wash. It bleeds past the list edges so the row reads as a full
   band rather than a boxed card, and it fades from the left where the
   question starts. */
.faq-item::before {
  content: '';
  position: absolute;
  inset: 0 -16px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.07), rgba(var(--accent-rgb), 0));
  opacity: 0;
  transition: opacity var(--dur) ease;
  pointer-events: none;
}

.faq-item:hover::before, .faq-item[open]::before { opacity: 1; }
.faq-item:hover { border-color: var(--accent-border); }

.faq-item summary {
  position: relative;
  z-index: 1;
  list-style: none;
  cursor: pointer;
  padding: 20px 44px 20px 0;
  font-size: clamp(16px, 1.9vw, 18px);
  font-weight: 600;
  color: var(--text);
  transition: color var(--dur-fast) ease;
}

.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--accent); }

/* Plus that turns into a minus. Two pseudo-elements, no icon. */
.faq-item summary::after,
.faq-item summary::before {
  content: '';
  position: absolute;
  right: 8px; top: 50%;
  background: var(--accent);
  transition: transform var(--dur) var(--ease-out), opacity var(--dur) ease;
}

.faq-item summary::before { width: 14px; height: 1.8px; transform: translateY(-50%); }
.faq-item summary::after { width: 1.8px; height: 14px; right: 14.1px; transform: translateY(-50%); }
.faq-item[open] summary::after { transform: translateY(-50%) rotate(90deg); opacity: 0; }

/* Height animation without measuring anything in JS. The <details> stays
   a real <details>, so it still opens with JS off. */
.faq-body {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s var(--ease-out);
}

.faq-item[open] .faq-body { grid-template-rows: 1fr; }
.faq-body > p { overflow: hidden; }

.faq-item p {
  padding: 0 8px 24px 0;
  font-size: 15.5px;
  color: var(--text-2);
  max-width: 62ch;
  text-wrap: pretty;
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: -9999px; top: 0;
  z-index: var(--z-drawer);
  padding: 12px 20px;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus { left: 0; }

/* ============================================================
   FINAL CTA
   ============================================================ */
.final-cta {
  position: relative;
  text-align: center;
  padding-block: clamp(90px, 12vw, 150px);
  border-top: 1px solid var(--border);
  overflow: hidden;
}

.cta-glow {
  position: absolute;
  bottom: -280px; left: 50%;
  transform: translateX(-50%);
  width: min(900px, 110vw);
  height: 540px;
  background: radial-gradient(closest-side, rgba(var(--accent-rgb), 0.12), transparent 70%);
  pointer-events: none;
}

.final-cta .container { position: relative; max-width: 720px; }
.final-inner { display: flex; flex-direction: column; align-items: center; }

.final-h {
  font-family: var(--font-display);
  font-size: clamp(30px, 4.6vw, 52px);
  font-weight: 700;
  font-stretch: 108%;
  letter-spacing: -0.032em;
  line-height: 1.06;
  color: var(--text);
  text-wrap: balance;
}

.final-note { margin-top: 22px; font-size: 13.5px; color: var(--text-2); }
.final-note a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.final-note a:hover { color: var(--accent); }

/* ---------------------------------------------------------------
   WAITLIST — the final CTA while web signup is closed.
   Reuses the .fld-input look so the one form on the marketing page
   matches the console's inputs rather than inventing a second style.
   --------------------------------------------------------------- */
.final-lede {
  margin-top: 16px;
  max-width: 44ch;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--text-2);
  text-wrap: pretty;
}

.waitlist { width: 100%; margin-top: 32px; }

/* Input and button share a row on desktop and stack on phones. min-width:0 on
   the field is what actually lets it shrink — a flex item defaults to
   min-width:auto and would otherwise refuse to go below its content width and
   push the button off the edge. */
.waitlist-row {
  display: flex;
  gap: 10px;
  max-width: 460px;
  margin-inline: auto;
}

.waitlist-field { flex: 1 1 auto; min-width: 0; }

.waitlist-input {
  width: 100%;
  font-size: 16px; /* ≥16px stops iOS zooming on focus */
  color: var(--text);
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 11px 14px;
  min-height: 48px;
  transition: border-color var(--dur-fast) ease, background var(--dur-fast) ease,
    box-shadow var(--dur-fast) ease;
}

.waitlist-input::placeholder { color: var(--text-3); }

.waitlist-input:focus {
  outline: none;
  border-color: var(--accent-border);
  background: rgba(255, 255, 255, 0.055);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.12);
}

.waitlist-btn { flex: 0 0 auto; min-height: 48px; white-space: nowrap; }
.waitlist-btn[disabled] { opacity: 0.6; cursor: default; }

.waitlist-msg {
  margin-top: 12px;
  font-size: 13.5px;
  color: var(--text-2);
  min-height: 1.2em;
}
.waitlist-msg[data-state='err'] { color: var(--neg); }

/* Honeypot. Off-screen rather than display:none — some bots skip undisplayed
   fields, and one that fills this is telling us what it is. */
.waitlist-hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

@media (max-width: 520px) {
  .waitlist-row { flex-direction: column; }
  .waitlist-btn { width: 100%; }
}

/* The button sits straight under the headline when there is no form (the
   signed-in state), so it needs the gap the paragraph used to hold open. */
.final-cta .btn { margin-top: 38px; }
.final-cta .waitlist .btn { margin-top: 0; }

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  border-top: 1px solid var(--border);
  background: var(--bg-2);
  padding: clamp(48px, 6vw, 72px) 0 32px;
}

.footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: start;
}

.footer-tag { margin-top: 12px; font-size: 14px; color: var(--text-2); max-width: 34ch; }

.footer-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
.footer-col { display: flex; flex-direction: column; gap: 10px; }

.footer-h {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 2px;
}

.footer-col a {
  font-size: 14px;
  color: var(--text-2);
  transition: color var(--dur-fast) ease, transform var(--dur-fast) var(--ease-out);
  width: fit-content;
  /* Padding, not line-height, so the 24px minimum target is real and the
     visual rhythm of the column does not change. */
  padding-block: 2px;
  min-height: 24px;
  display: flex;
  align-items: center;
}

.footer-col a:hover { color: var(--accent); transform: translateX(3px); }

.footer-base {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px 32px;
  margin-top: clamp(40px, 5vw, 64px);
  padding-top: 24px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text-3);
}

/* Legal small print stays legible, so it does not use --text-3. */
.footer-fine { font-size: 12.5px; color: var(--text-2); max-width: 62ch; text-align: right; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1024px) {
  .panel-grid { grid-template-columns: 1fr; }
  .pane-out { border-left: none; border-top: 1px solid var(--border); }
  .showcase, .showcase-flip { grid-template-columns: 1fr; }
  .showcase-flip .showcase-copy,
  .showcase-flip > :not(.showcase-copy) { order: 0; }
  /* Stacked, the flex-basis split that made two columns turns into "the
     chart grows to eat the leftover height", which opens a hole above it. */
  .cell-wide { flex-direction: column; align-items: stretch; }
  .cell-wide .cell-text, .cell-wide .viz { flex: 0 0 auto; }
  .faq-grid { grid-template-columns: 1fr; }
  .faq-aside { position: static; }
}

@media (max-width: 900px) {
  .nav-links, .nav-actions { display: none; }
  .nav-toggle { display: flex; }
  .nav-mobile { display: flex; }
  .hero-grid { grid-template-columns: 1fr; gap: 44px; }
  .hero-sub { max-width: 54ch; }
}

@media (max-width: 860px) {
  .strip-inner { grid-template-columns: 1fr 1fr; gap: 20px 0; }
  .strip-item:nth-child(3)::before { display: none; }
  .bento { grid-template-columns: 1fr; }
  .cell-wide { grid-column: span 1; }
  .js .feature-track .cell {
    min-height: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 26px;
  }
  .js .feature-track .cell .cell-text,
  .js .feature-track .cell .viz { flex: 0 0 auto; }
  .footer-inner { grid-template-columns: 1fr; }
  .footer-fine { text-align: left; }
}

@media (max-width: 720px) {
  .nav-links, .nav-actions { display: none; }
  .nav-toggle { display: flex; }
  .nav-mobile { display: flex; }
  .fld-row { grid-template-columns: 1fr; }
  .hero-ctas .btn { width: 100%; }
  .console-head { align-items: flex-start; }
  .footer-base { flex-direction: column; }
  /* The strip scrolls past the last tab, so fade its right edge rather than
     letting "Trade" look like it was cut off by a bug. */
  .deck-tabs {
    -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent 100%);
    mask-image: linear-gradient(90deg, #000 88%, transparent 100%);
  }

}

/* A 320px viewport previously left the focused feature card only 180px wide.
   Keep enough room for the copy and real-app clip to remain useful; the edge
   arrows still make the adjacent slides discoverable at this smallest size. */
@media (max-width: 340px) {
  .js .feature-track .cell {
    width: calc(100vw - 120px);
    padding: 18px 16px;
  }
}

/* ============================================================
   AUTH PAGE (signin.html)
   ============================================================ */
/* the hidden attribute must beat any display rule below (UA
   [hidden] { display: none } loses to a class selector) */
[hidden] { display: none !important; }

/* app pages (signin/dashboard) use a static solid header — no scroll JS */
.page-app { min-height: 100vh; }

.page-app .brand { white-space: nowrap; }

.app-header { position: sticky; }

.page-loading {
  padding: 140px 20px 40px;
  text-align: center;
  color: var(--text-3);
  font-size: 14px;
}

.auth-main {
  position: relative;
  display: flex;
  justify-content: center;
  /* header is sticky (in flow) on app pages, so this is real whitespace */
  padding: clamp(48px, 10vh, 110px) clamp(20px, 5vw, 40px) 80px;
  overflow: hidden;
}

.auth-glow {
  position: absolute;
  top: -220px;
  left: 50%;
  transform: translateX(-50%);
  width: min(900px, 120vw);
  height: 520px;
  background: radial-gradient(closest-side, rgba(var(--accent-rgb), 0.09), transparent 70%);
  pointer-events: none;
}

.auth-card {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: clamp(28px, 4vw, 40px);
  background: linear-gradient(180deg, var(--bg-2), var(--bg));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 56px rgba(0, 0, 0, 0.45);
}

.auth-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.5), transparent);
}

.auth-title {
  font-size: 26px;
  font-weight: 650;
  letter-spacing: -0.02em;
}

.auth-subtitle {
  font-size: 14.5px;
  color: var(--text-2);
  margin-top: 6px;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 26px;
}

.auth-field { display: flex; flex-direction: column; gap: 6px; }

.auth-label {
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 600;
}

.auth-field input {
  font-family: inherit;
  font-size: 16px; /* ≥16px prevents iOS zoom-on-focus */
  color: var(--text);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 13px;
  min-height: 44px;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.auth-field input::placeholder { color: var(--text-3); }

.auth-field input:focus {
  outline: none;
  border-color: var(--accent-border);
  background: rgba(255, 255, 255, 0.05);
}

.auth-field-error { font-size: 12.5px; color: var(--neg); }

/* "Forgot password?" — a quiet right-aligned link under the password field. */
.auth-forgot {
  align-self: flex-end;
  margin-top: -2px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-2);
  /* Quiet, but still a 24px target. Negative inline margin keeps it visually
     flush with the field's right edge despite the padding. */
  padding: 4px 6px;
  margin-right: -6px;
  min-height: 24px;
  display: inline-flex;
  align-items: center;
}

.auth-forgot:hover { color: var(--accent); }

.auth-message {
  font-size: 13.5px;
  line-height: 1.45;
  padding: 11px 14px;
  border-radius: var(--radius);
}

.auth-message--error {
  color: var(--neg);
  background: rgba(240, 119, 108, 0.08);
  border: 1px solid rgba(240, 119, 108, 0.28);
}

.auth-message--notice {
  color: var(--text);
  background: var(--accent-dim);
  border: 1px solid var(--accent-border);
}

.auth-submit { width: 100%; margin-top: 4px; }
.auth-submit:disabled { opacity: 0.6; cursor: default; }
.auth-submit:disabled:hover { transform: none; }

.auth-toggle {
  margin-top: 22px;
  text-align: center;
  font-size: 14px;
  color: var(--text-2);
}

.auth-toggle-btn {
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
  padding: 4px 6px;
  min-height: 24px;
}

.auth-toggle-btn:hover { text-decoration: underline; }

/* ============================================================
   DASHBOARD (dashboard.html)
   Self-contained .dash-* tiles.
   ============================================================ */
.dash-user {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
}

.dash-email {
  font-size: 13px;
  color: var(--text-2);
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash {
  padding-top: clamp(28px, 5vh, 48px);
  padding-bottom: 80px;
}

.dash-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}

.dash-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 24px;
  font-weight: 650;
  letter-spacing: -0.02em;
}

.dash-ranges {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
}

.dash-range {
  padding: 7px 14px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-3);
  min-height: 36px;
  transition: color 0.2s ease, background 0.2s ease;
}

.dash-range:hover { color: var(--text-2); }
.dash-range.active { color: var(--text); font-weight: 600; background: var(--surface-2); }

/* skeleton loading state */
@keyframes dashPulse {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 1; }
}

.dash-skel {
  border-radius: var(--radius);
  background: var(--surface-2);
  animation: dashPulse 1.4s ease-in-out infinite;
  height: 78px;
}

.dash-skel--hero { height: 140px; border-radius: var(--radius-lg); margin-bottom: 12px; }

.dash-skel-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

/* error + empty panels */
.dash-error,
.dash-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  padding: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  font-size: 14.5px;
  color: var(--text-2);
}

.dash-error { border-color: rgba(248, 113, 113, 0.25); }
.dash-error p { color: var(--neg); }

/* hero KPI tile */
.dash-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(20px, 3vw, 30px);
  background: linear-gradient(180deg, var(--bg-2), var(--bg));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 56px rgba(0, 0, 0, 0.35);
  overflow: hidden;
}

.dash-hero::before {
  content: '';
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.5), transparent);
}

.dash-k {
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 600;
}

.dash-hero-value {
  font-size: clamp(34px, 4.5vw, 46px);
  font-weight: 600;
  color: var(--text);
  line-height: 1.15;
  margin-top: 4px;
}

.dash-hero-sub { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }

/* KPI tile rows */
.dash-kpi-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 12px;
}

.dash-kpi-row--4 { grid-template-columns: repeat(4, 1fr); }

.dash-kpi {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.dash-kpi .dash-k { letter-spacing: 0.02em; text-transform: none; font-size: 11.5px; }

.dash-v { font-size: 17px; font-weight: 600; color: var(--text); }
.dash-v.is-pos, .dash-hero-value.is-pos { color: var(--accent); }
.dash-v.is-neg, .dash-hero-value.is-neg { color: var(--neg); }

.dash-range-note {
  margin-top: 12px;
  font-size: 13px;
  color: var(--text-3);
  padding: 10px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
}

/* inventory section */
.dash-inv { margin-top: clamp(36px, 5vw, 56px); }

.dash-inv-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.dash-inv-title {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.dash-inv-count { font-size: 13px; color: var(--text-3); font-weight: 500; }

.dash-inv-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.dash-search {
  font-family: inherit;
  font-size: 16px; /* ≥16px prevents iOS zoom-on-focus */
  color: var(--text);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  min-height: 40px;
  width: 210px;
  transition: border-color 0.2s ease;
}

.dash-search::placeholder { color: var(--text-3); }
.dash-search:focus { outline: none; border-color: var(--accent-border); }

.dash-filters {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.dash-filters::-webkit-scrollbar { display: none; }

.dash-filter {
  flex: 0 0 auto;
  padding: 6px 12px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-3);
  min-height: 32px;
  white-space: nowrap;
  transition: color 0.2s ease, background 0.2s ease;
}

.dash-filter:hover { color: var(--text-2); }
.dash-filter.active { color: var(--text); font-weight: 600; background: var(--surface-2); }

/* table */
.dash-table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.dash-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  min-width: 640px;
}

.dash-table th {
  text-align: left;
  font-size: 10.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 600;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.015);
  white-space: nowrap;
}

.dash-table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}

.dash-table tbody tr:last-child td { border-bottom: none; }
.dash-table tbody tr:hover td { background: rgba(255, 255, 255, 0.015); }

.dash-num { text-align: right; }

.dash-card-cell { font-weight: 500; }

/* Class-scoped rather than `.dash-card-cell span` so other inline elements in
   this cell (e.g. a consignment badge) aren't restyled as a set-name line. */
.dash-card-cell .dash-card-set {
  display: block;
  font-size: 11.5px;
  font-weight: 400;
  color: var(--text-3);
}

.dash-badge {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 5px;
  white-space: nowrap;
}

.dash-badge.is-instock { color: var(--accent); background: var(--accent-dim); }
.dash-badge.is-sold { color: var(--text-2); background: rgba(255, 255, 255, 0.06); }
.dash-badge.is-traded { color: #93c5fd; background: rgba(147, 197, 253, 0.10); }
/* Consignment. Gold = someone else's goods on your table; info-blue = your
   goods out at an outlet. Same colour language as the app's Inventory badges. */
.dash-badge.is-consigned { color: #e0b341; background: rgba(224, 179, 65, 0.12); }
.dash-badge.is-out { color: #8ab4f8; background: rgba(138, 180, 248, 0.12); }

.dash-table-note {
  padding: 12px 14px;
  font-size: 12.5px;
  color: var(--text-3);
  border-top: 1px solid var(--border);
}

/* Workspace billing sits between day-to-day inventory and destructive account
   controls. It uses the dashboard's restrained surface language, with one gold
   wash to make the best-value cadence legible rather than salesy. */
.dash-billing {
  position: relative;
  overflow: hidden;
  margin-top: clamp(44px, 7vw, 76px);
  padding: clamp(24px, 4vw, 38px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(circle at 85% 0%, rgba(var(--accent-rgb), 0.1), transparent 34%),
    var(--surface);
}

.dash-billing::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: linear-gradient(180deg, transparent, var(--accent), transparent);
}

.dash-billing__head,
.dash-billing__current {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.dash-billing__eyebrow {
  display: block;
  margin-bottom: 5px;
  color: var(--text-3);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.dash-billing__title {
  font-size: clamp(22px, 3vw, 30px);
  font-weight: 650;
  letter-spacing: -0.025em;
}

.dash-billing__status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 650;
}

.dash-billing__status > span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px rgba(var(--accent-rgb), 0.65);
}

.dash-billing__lede,
.dash-billing__member,
.dash-billing__current {
  margin-top: 20px;
  color: var(--text-2);
  font-size: 14px;
  line-height: 1.6;
}

.dash-billing__options {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 22px;
}

.dash-billing__option {
  position: relative;
  min-width: 0;
  min-height: 190px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 20px;
  color: var(--text);
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.014);
  cursor: pointer;
  transition: transform 180ms var(--ease-out), border-color 180ms ease, background 180ms ease;
}

.dash-billing__option:hover,
.dash-billing__option:focus-visible {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  background: rgba(255, 255, 255, 0.035);
}

.dash-billing__option:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dash-billing__option:disabled { opacity: 0.55; cursor: wait; transform: none; }

.dash-billing__option--featured {
  border-color: rgba(var(--accent-rgb), 0.28);
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.1), rgba(var(--accent-rgb), 0.025));
}

.dash-billing__flag {
  position: absolute;
  top: 16px;
  right: 16px;
  color: var(--accent);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.dash-billing__option-top {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.dash-billing__option-top strong {
  font-family: var(--display);
  font-size: clamp(32px, 4vw, 44px);
  font-weight: 550;
  letter-spacing: -0.045em;
}

.dash-billing__option-top > span,
.dash-billing__option-note,
.dash-billing__fine { color: var(--text-3); font-size: 12px; }
.dash-billing__option-note { margin-top: 6px; }

.dash-billing__option-action {
  display: flex;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  font-weight: 600;
}

.dash-billing__option-action span { color: var(--accent); }
.dash-billing__fine { margin-top: 14px; }

.dash-billing__notice,
.dash-billing__error {
  margin-top: 18px;
  padding: 10px 12px;
  border-radius: var(--radius);
  font-size: 13px;
}

.dash-billing__notice {
  color: var(--text);
  background: var(--accent-dim);
  border: 1px solid var(--accent-border);
}

.dash-billing__error {
  color: var(--neg);
  background: rgba(240, 119, 108, 0.08);
  border: 1px solid rgba(240, 119, 108, 0.25);
}

.dash-billing__skeleton {
  height: 190px;
  margin-top: 22px;
  border-radius: var(--radius);
  background: var(--surface-2);
  animation: dashPulse 1.4s ease-in-out infinite;
}

/* dashboard responsive */
@media (max-width: 860px) {
  .dash-kpi-row--4 { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 720px) {
  /* app pages keep their header content visible (no hamburger here) */
  .page-app .nav-inner .dash-user { display: flex; }
  .dash-kpi-row { grid-template-columns: 1fr; gap: 8px; }
  .dash-kpi-row--4 { grid-template-columns: 1fr 1fr; }
  .dash-inv-controls { width: 100%; flex-direction: column; align-items: stretch; }
  .dash-search { width: 100%; }
  .dash-col-md { display: none; }
  .dash-table { min-width: 0; }
  .dash-billing__options { grid-template-columns: 1fr; }
  .dash-billing__option { min-height: 164px; }
  .dash-billing__current { align-items: flex-start; flex-direction: column; }
}

/* ============================================================
   REDUCED MOTION
   Every effect above has a resting state here. Nothing is gated on a
   transition, so switching all of them off still leaves a whole page.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .js .reveal { transition: none; opacity: 1; transform: none; }
  .js .split-h .w { transition: none; opacity: 1; transform: none; }
  .js .feature-track { transition: none; }

  /* Don't make motion-sensitive visitors traverse an artificial scroll
     distance. They get all three steps at once, with the same hierarchy. */
  .setup-walkthrough { display: block; }
  .steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: clamp(20px, 3vw, 34px); }
  .step, .step:first-child, .step:last-child { min-height: 0; margin: 0; opacity: 1; }
  .setup-rail, .setup-stage { display: none; }

  /* Named kills, because a 0.001ms animation still runs its keyframes and
     a masked headline would flash. */
  .hero-headline .line > span { animation: none; transform: none; }
  .hero-glow { animation: none; }
  .pos-live i { animation: none; }
  .panel { animation: none; }
  .multi-menu { animation: none; }
  .dash-billing__skeleton { animation: none; }
  .ledger-row.is-new, .off-item, .off-rollup { animation: none; opacity: 1; transform: none; }
  /* The queue holds still: no pulsing markers, no nudge on the switch, and
     the ghost row's countdown bar sits full rather than sweeping. main.js
     also drops the deals in one go instead of on a timer. */
  .off-bar i, .off-item.is-wait .off-tick::after, .off-toggle.is-nudge { animation: none; }
  .off-ghost .off-ghost-bar { animation: none; transform: scaleX(1); opacity: 0.4; }
  /* Not `transform: none` — that would collapse the fan. The seat angle is
     layout here, not motion; only the deal-in animation goes. */
  .pos-card.is-new { animation: none; opacity: 1; }
  .pos-card, .pos-card-face { transition: none; }
  .pos-card:hover .pos-card-face { transform: none; }
  .pos-card-face::after { display: none; }
  .btn-primary::after { display: none; }
  .spotlight::before { display: none; }
  .grain { display: none; }
  .btn:hover, .btn:active, .cell:hover, .footer-col a:hover,
  .step:hover, .pricer:hover, .offline:hover, .position:hover { transform: none; }

  /* The scan reads as a still frame: no sweep across the label. */
  .seal-qty { opacity: 1; transform: none; transition: none; }
  .tab-pill, .tab-pill.is-ready { transition: none; }
  .nav-mobile, .nav-mobile.open, .nav-mobile a { transition: none; }
  .nav-roll__track { transition: none; }
  .nav-roll:hover .nav-roll__track,
  .nav-roll:focus-visible .nav-roll__track { transform: none; }

  /* Bars and charts still need to reach their value, just without travel. */
  .stackbar i, .gauge span,
  .spark-line, .off-knob, .faq-body {
    transition: none !important;
  }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
  }
}

@media print {
  .setup-walkthrough { display: block; }
  .steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .step, .step:first-child, .step:last-child { min-height: 0; margin: 0; opacity: 1; }
  .setup-rail, .setup-stage { display: none; }
}

/* ============================================================
   LEGAL PAGES (privacy.html)
   A reading document, not a landing page: one narrow measure,
   generous leading, and no motion. It reuses the site's nav and
   footer so it reads as part of the same object, but nothing
   here animates or reveals on scroll — a policy should be
   legible the instant it loads, including with JS disabled.
   ============================================================ */

.legal {
  padding: 140px 0 96px;
}

.legal-inner {
  /* Narrower than --container: ~70 characters is the comfortable
     measure for sustained reading, and this page is all prose. */
  max-width: 760px;
}

/* ---- Head ---- */

.legal-eyebrow {
  margin: 0 0 12px;
  font-family: 'Archivo', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.legal-title {
  margin: 0;
  font-family: 'Archivo', sans-serif;
  font-size: clamp(34px, 6vw, 52px);
  font-stretch: 112%;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--text);
}

.legal-dates {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0 0;
  font-size: 13px;
  color: var(--text-3);
}

.legal-lede {
  max-width: 62ch;
  margin: 24px 0 0;
  font-size: 17px;
  line-height: 1.65;
  color: var(--text-2);
}

/* ---- The short version ----
   Deliberately the most prominent block on the page. The people who
   most need this document are the least likely to read all of it. */

.legal-summary {
  margin: 48px 0 0;
  padding: 28px clamp(20px, 4vw, 32px);
  background: var(--bg-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
}

.legal-summary__title {
  margin: 0 0 16px;
  font-family: 'Archivo', sans-serif;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}

.legal-summary__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.legal-summary__list li {
  position: relative;
  padding-left: 26px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-2);
}

.legal-summary__list li + li {
  margin-top: 12px;
}

/* A gold check, drawn in CSS so the list needs no icon font or SVG. */
.legal-summary__list li::before {
  content: '';
  position: absolute;
  top: 7px;
  left: 2px;
  width: 6px;
  height: 11px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(42deg);
}

.legal-summary__list strong {
  color: var(--text);
  font-weight: 600;
}

/* ---- Contents ---- */

.legal-toc {
  margin: 40px 0 0;
  padding: 24px clamp(20px, 4vw, 28px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.legal-toc__title {
  margin: 0 0 14px;
  font-family: 'Archivo', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}

.legal-toc__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 8px 24px;
  margin: 0;
  padding-left: 20px;
  font-size: 14px;
  color: var(--text-3);
}

.legal-toc__list a {
  color: var(--text-2);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.legal-toc__list a:hover,
.legal-toc__list a:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent-border);
}

/* ---- Body prose ---- */

.legal-body {
  margin-top: 56px;
}

.legal-body h2 {
  margin: 48px 0 14px;
  padding-top: 28px;
  font-family: 'Archivo', sans-serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  border-top: 1px solid var(--border);
  /* Anchor links from the contents land below the sticky header. */
  scroll-margin-top: 96px;
}

.legal-body h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.legal-body h3 {
  margin: 28px 0 10px;
  font-family: 'Archivo', sans-serif;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
}

.legal-body p {
  margin: 0 0 16px;
  font-size: 16px;
  line-height: 1.7;
  color: var(--text-2);
}

.legal-body ul {
  margin: 0 0 20px;
  padding-left: 22px;
}

.legal-body li {
  margin-bottom: 10px;
  font-size: 16px;
  line-height: 1.7;
  color: var(--text-2);
}

.legal-body li::marker {
  color: var(--text-3);
}

.legal-body strong {
  color: var(--text);
  font-weight: 600;
}

.legal-body em {
  font-style: italic;
  color: var(--text);
}

.legal-body a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-border);
}

.legal-body a:hover,
.legal-body a:focus-visible {
  border-bottom-color: var(--accent);
}

.legal-nowrap {
  white-space: nowrap;
}

.legal-code {
  padding: 2px 7px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: var(--accent-dim);
  border: 1px solid var(--accent-border);
  border-radius: 5px;
}

/* ---- Subprocessor table ----
   Wrapped in its own scroller so a narrow phone scrolls the TABLE,
   never the page body. */

.legal-table-wrap {
  margin: 0 0 24px;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.legal-table {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: 14px;
}

.legal-table__caption {
  padding: 14px 16px 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: left;
  color: var(--text-3);
}

.legal-table th,
.legal-table td {
  padding: 12px 16px;
  text-align: left;
  vertical-align: top;
  line-height: 1.55;
  border-bottom: 1px solid var(--border);
}

.legal-table thead th {
  font-family: 'Archivo', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
  background: var(--surface);
}

.legal-table tbody th,
.legal-table tbody td:first-child {
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.legal-table tbody td {
  color: var(--text-2);
}

.legal-table tbody tr:last-child th,
.legal-table tbody tr:last-child td {
  border-bottom: none;
}

/* The legal footer is a single quiet base row — no nav columns. */
.legal ~ .footer .footer-base a {
  color: var(--text-2);
  text-decoration: none;
}

.legal ~ .footer .footer-base a:hover {
  color: var(--accent);
}

@media (max-width: 640px) {
  .legal {
    padding-top: 112px;
  }

  .legal-toc__list {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   DASHBOARD — account deletion (danger zone + confirm dialog)
   Mirrors the app's Settings panel so the two deletion surfaces
   read as the same feature. Garnet only; nothing here competes
   with the gold accent.
   ============================================================ */

.dash-danger {
  max-width: 640px;
  margin: 72px 0 96px;
  padding-top: 28px;
  border-top: 1px solid var(--border);
}

.dash-danger__title {
  margin: 0 0 8px;
  font-family: 'Archivo', sans-serif;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--neg);
}

.dash-danger__hint {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-3);
}

/* Outlined, not filled — a filled garnet button here would read as the
   page's primary action, which it must never look like. */
.dash-danger__btn {
  min-height: 40px;
  padding: 0 18px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--neg);
  background: transparent;
  border: 1px solid rgba(240, 119, 108, 0.35);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.dash-danger__btn:hover,
.dash-danger__btn:focus-visible {
  color: #2a0e0b;
  background: var(--neg);
  border-color: var(--neg);
}

/* ---- Confirm dialog ---- */

.dash-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(4, 6, 9, 0.72);
  backdrop-filter: blur(2px);
}

.dash-modal-overlay[hidden] {
  display: none;
}

.dash-modal {
  width: 100%;
  max-width: 520px;
  max-height: min(86vh, 720px);
  overflow-y: auto;
  padding: clamp(20px, 4vw, 28px);
  background: var(--bg-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
}

.dash-modal__title {
  margin: 0 0 16px;
  font-family: 'Archivo', sans-serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}

.dash-modal__state {
  margin: 0 0 16px;
  font-size: 14px;
  color: var(--text-3);
}

.dash-modal__lede {
  margin: 0 0 16px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--text-2);
}

.dash-modal__lede strong {
  color: var(--text);
  font-weight: 600;
}

.dash-modal__counts {
  margin: 0 0 16px;
  padding: 14px 18px;
  list-style: none;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-2);
  background: rgba(240, 119, 108, 0.08);
  border: 1px solid rgba(240, 119, 108, 0.22);
  border-radius: var(--radius);
}

.dash-modal__counts strong {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.dash-modal__export {
  margin: 0 0 20px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-3);
}

.dash-modal__field {
  display: block;
  margin-bottom: 6px;
}

.dash-modal__label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.dash-modal__input {
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  font-family: inherit;
  font-size: 15px;
  letter-spacing: 0.08em;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.dash-modal__input:focus-visible {
  outline: 2px solid var(--neg);
  outline-offset: 1px;
}

.dash-modal__help {
  margin: 0 0 20px;
  font-size: 13px;
  color: var(--text-3);
}

.dash-modal__error {
  margin: 0 0 16px;
  padding: 10px 14px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--neg);
  background: rgba(240, 119, 108, 0.1);
  border: 1px solid rgba(240, 119, 108, 0.28);
  border-radius: var(--radius-sm);
}

.dash-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* Filled garnet. Inside the dialog this IS the primary action — and by the
   time it is reachable the user has typed the word to arm it. */
.dash-modal__confirm {
  min-height: 40px;
  padding: 0 18px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: #2a0e0b;
  background: var(--neg);
  border: 1px solid var(--neg);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.dash-modal__confirm:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

@media (max-width: 560px) {
  .dash-modal__actions {
    flex-direction: column-reverse;
  }

  .dash-modal__actions > * {
    width: 100%;
  }
}

/* Subprocessor table on a phone. A 3-column table at 390px either scrolls
   sideways or collapses into tall, mostly-empty rows (row height follows the
   off-screen column). Neither is readable, so below 640px each row becomes a
   stacked card and every cell carries its column name from data-label. */
@media (max-width: 640px) {
  .legal-table-wrap {
    overflow-x: visible;
    border: none;
    border-radius: 0;
  }

  .legal-table {
    min-width: 0;
    display: block;
  }

  .legal-table thead {
    /* The column names move into the rows themselves, so the header row is
       redundant here — hidden accessibly, not with display:none, so screen
       readers keep the table semantics. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  .legal-table__caption {
    padding: 0 0 12px;
  }

  .legal-table tbody,
  .legal-table tbody tr,
  .legal-table tbody td {
    display: block;
    width: 100%;
  }

  .legal-table tbody tr {
    margin-bottom: 12px;
    padding: 4px 0 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
  }

  .legal-table tbody tr:last-child {
    margin-bottom: 0;
  }

  .legal-table tbody td {
    padding: 10px 16px 0;
    border-bottom: none;
  }

  .legal-table tbody td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    font-family: 'Archivo', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-3);
  }

  /* The provider name is the row's heading — let it wrap and drop the
     nowrap it carries in the wide layout. */
  .legal-table tbody td:first-child {
    white-space: normal;
    font-size: 15px;
  }
}

/* ---- Dashboard: the last owner's choice (hand over vs destroy) ----
   Mirrors the app's .danger-choice. The safe option is pre-selected and reads
   neutral gold; the destructive one only turns garnet once actually chosen, so
   the dialog doesn't shout before a decision has been made. */

.dash-choice {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 0 18px;
  padding: 0;
  border: none;
}

.dash-choice__opt {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  background: var(--bg);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.dash-choice__opt--on {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.dash-choice__opt--danger.dash-choice__opt--on {
  border-color: var(--neg);
  background: rgba(240, 119, 108, 0.1);
}

.dash-choice__radio {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.dash-choice__opt--danger .dash-choice__radio {
  accent-color: var(--neg);
}

.dash-choice__text {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.dash-choice__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.dash-choice__desc {
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-3);
}

.dash-choice__select {
  width: 100%;
  min-height: 40px;
  margin-top: 8px;
  padding: 0 10px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--bg-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.dash-choice__select:disabled {
  opacity: 0.45;
}

.dash-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
