/* Chess Arrow theme. Every page links this file.
   One token set drives colour, type, spacing and radius; components below only
   consume tokens, so changing a value here changes it everywhere.

   Direction: an engine analysis board. The page is the cool grey-blue of a
   lichess "blue" board, and the single accent is the best-move arrow's amber:
   it marks the move to play on the board and the thing to click on the page,
   and nothing else. Type is one family, Archivo, whose width axis does the
   work: headings run wide and heavy, body text stays at normal width.
   All text pairs meet WCAG AA, in both themes.

   Dark theme: the page turns dark, the board does not. Squares, pieces, the
   evaluation bar and the eval chip use fixed --sq-* / --piece-* tokens that are
   never redefined, so a white piece is white and a black piece is black in
   either theme. Declaring color-scheme also stops browsers from force-darkening
   the page themselves, which is what inverted the pieces before. */

:root {
  /* Colour */
  --paper: #E8ECEF;
  --surface: #F7F9FA;
  --ink: #13202A;
  --ink-2: #3D4D59;
  --muted: #5A6A76;
  --line: #CBD4DA;
  --line-strong: #9FB0BB;
  --sq-light: #DEE3E6;
  --sq-dark: #8CA2AD;
  /* The board itself. Separate from --sq-* (logo mark, step numbers) because it
     darkens in the dark theme, where the dark piece set is drawn with white edges. */
  --board-light: #DEE3E6;
  --board-dark: #8CA2AD;
  --signal: #F28C28;
  --signal-hover: #F7A04A;
  --on-signal: #13202A;

  /* Board and pieces: identical in both themes. */
  --piece-ink: #13202A;
  --piece-light: #FFFFFF;
  --eb-black: #13202A;

  /* Surfaces that change with the theme. */
  --panel: #DEE3E6;
  --check-a: #DEE3E6;
  --check-b: #F7F9FA;
  --field: #FFFFFF;
  --deep: #13202A;
  --err-bg: #FBEEEC; --err-fg: #8A2A22; --err-line: #E9BFB9; --err-edge: #B3372B;
  --ok-bg: #EAF3EC;  --ok-fg: #22492F;  --ok-line: #C1DAC8;  --ok-edge: #2F7A48;
  --info-bg: #EAF0F4; --info-fg: #24404F; --info-line: #C6D5DF; --info-edge: #3D6B85;

  /* Type */
  --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --wide: 118%;
  --wider: 125%;
  --t-xs: 0.75rem;
  --t-sm: 0.875rem;
  --t-base: 1rem;
  --t-lg: 1.125rem;
  --t-xl: 1.375rem;
  --t-h3: 1.0625rem;
  --t-h2: clamp(1.875rem, 1.3rem + 2.2vw, 2.75rem);
  --t-h1: clamp(1.875rem, 1.4rem + 1.9vw, 2.5rem);
  --t-hero: clamp(2.5rem, 1.1rem + 4.6vw, 4.5rem);
  --t-price: clamp(3.5rem, 2.6rem + 3.4vw, 5.25rem);

  /* Spacing */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-section: clamp(64px, 9vw, 120px);
  --s-gutter: clamp(16px, 4vw, 40px);

  /* Shape: squares stay square, surfaces are barely softened, controls a little more. */
  --r-sq: 3px;
  --r-card: 6px;
  --r-ctl: 5px;

  --max: 1160px;
  /* Height of the sticky bar minus its bottom rule, and of the footer; pricing.js
     keeps both exact. */
  --nav-h: 64px;
  --footer-h: 86px;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #141C22;
    --surface: #1B252D;
    --ink: #E4EAEE;
    --ink-2: #B3C0C9;
    --muted: #8C9DA9;
    --line: #2A3740;
    --line-strong: #40515D;
    --panel: #212D36;
    --check-a: #1F2A32;
    --check-b: #182229;
    --field: #0F161B;
    --deep: #0B1115;
    --eb-black: #0B1115;
    --board-light: #7F95A2;
    --board-dark: #566B79;
    --err-bg: #3A1D1A; --err-fg: #F4C4BD; --err-line: #5E2C26; --err-edge: #E0645A;
    --ok-bg: #173022;  --ok-fg: #B9E2C6;  --ok-line: #25503A;  --ok-edge: #4FB477;
    --info-bg: #182A36; --info-fg: #BCD4E4; --info-line: #29455A; --info-edge: #6FA3C6;
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; scroll-padding-top: var(--nav-h); }
body {
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "tnum" 0;
}
img, svg, video { max-width: 100%; }
.wrap {
  max-width: var(--max); margin: 0 auto;
  padding: 0 max(var(--s-gutter), env(safe-area-inset-right, 0px)) 0 max(var(--s-gutter), env(safe-area-inset-left, 0px));
}

/* Anything focused by keyboard gets the same visible ring. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: var(--r-ctl);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* Headings share one voice: wide, heavy, tight. */
h1, h2 {
  font-stretch: var(--wide);
  font-weight: 780;
  letter-spacing: -0.025em;
  line-height: 1.02;
  text-wrap: balance;
}
h3 {
  font-size: var(--t-h3);
  font-weight: 650;
  font-stretch: 108%;
  letter-spacing: -0.005em;
  line-height: 1.3;
}

/* ---------------------------------------------------------------- Nav ---- */
nav {
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--line);
}
nav .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); min-height: 64px;
}
.logo {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: 1.1875rem; font-weight: 800; font-stretch: var(--wider);
  letter-spacing: -0.03em;
  color: var(--ink); text-decoration: none;
  white-space: nowrap; flex-shrink: 0;
}
/* The knight sits on its own board square: the brand mark is a piece on the board. */
.logo-mark {
  font-family: 'Pieces', var(--font);
  display: inline-grid; place-items: center;
  width: 30px; height: 30px;
  font-size: 23px; font-weight: 400; line-height: 1;
  background: var(--sq-dark); color: var(--piece-ink);
  border-radius: var(--r-sq);
}
.nav-links { display: flex; align-items: center; gap: var(--s-5); min-width: 0; }

/* The in-page anchors scroll sideways instead of disappearing on narrow screens,
   so every section stays reachable from the bar. */
.nav-menu {
  display: flex; align-items: center; gap: var(--s-5);
  min-width: 0; overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; -ms-overflow-style: none;
}
.nav-menu::-webkit-scrollbar { display: none; }
.nav-menu a { white-space: nowrap; }

/* :not(.btn) matters: without it this rule outranks .btn-primary and repaints
   the button's label. */
.nav-links a:not(.btn) {
  color: var(--ink-2); text-decoration: none;
  font-size: var(--t-sm); font-weight: 500;
  padding: var(--s-1) 0;
  border-bottom: 2px solid transparent;
}
.nav-links a:not(.btn):hover { color: var(--ink); border-bottom-color: var(--signal); }

/* ------------------------------------------------------------- Buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-2);
  padding: 9px var(--s-4);
  border-radius: var(--r-ctl);
  font-family: inherit; font-size: var(--t-sm); font-weight: 650;
  font-stretch: 108%;
  line-height: 1.2;
  text-decoration: none; border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.btn-lg { padding: 14px var(--s-5); font-size: var(--t-base); }
/* The amber of the engine arrow: the one thing on the page to act on.
   The inset shadow gives it a pressed edge without a second colour. */
.btn-primary {
  background: var(--signal); color: var(--on-signal);
  box-shadow: inset 0 -2px 0 rgba(19, 32, 42, 0.22);
}
.btn-primary:hover { background: var(--signal-hover); }
.btn-primary:active { box-shadow: inset 0 2px 0 rgba(19, 32, 42, 0.22); }
.btn-ghost {
  background: transparent; color: var(--ink);
  border-color: var(--line-strong);
}
.btn-ghost:hover { border-color: var(--ink); background: var(--surface); }
.btn[disabled] { opacity: 0.55; cursor: default; }

/* ---------------------------------------------------------------- Hero ---- */
section { padding: var(--s-section) 0; border-top: 1px solid var(--line); }
.hero { border-top: none; padding: clamp(40px, 6vw, 88px) 0 clamp(56px, 7vw, 104px); }
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: clamp(36px, 5vw, 80px);
  align-items: center;
}
.hero h1 {
  font-size: var(--t-hero);
  font-stretch: var(--wider);
  font-weight: 820;
  line-height: 0.96;
  letter-spacing: -0.035em;
  margin-bottom: var(--s-5);
}
.hero .lead {
  font-size: var(--t-lg); line-height: 1.6;
  color: var(--ink-2);
  max-width: 54ch; margin-bottom: var(--s-6);
}
.hero-ctas { display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap; }
/* Three actions share one row on a desktop column (~525px): same height as the
   other large buttons, a little less side padding and normal-width type. */
.hero-ctas .btn-lg { padding-left: 16px; padding-right: 16px; font-stretch: 100%; }
.hero-note { margin-top: var(--s-5); font-size: var(--t-sm); color: var(--muted); }
.btn .play { width: 14px; height: 14px; fill: currentColor; flex-shrink: 0; }
/* No trial to download: Buy becomes the primary action, so the hero never
   opens without one. */
[data-download="off"] .btn-buy {
  background: var(--signal); color: var(--on-signal); border-color: transparent;
  box-shadow: inset 0 -2px 0 rgba(19, 32, 42, 0.22);
}
[data-download="off"] .btn-buy:hover { background: var(--signal-hover); }

/* The analysis board. */
.analysis { margin: 0; width: 100%; max-width: 520px; justify-self: end; }
.board { display: block; width: 100%; height: auto; }
.board .sl, .mini-board .sl { fill: var(--board-light); }
.board .sd, .mini-board .sd { fill: var(--board-dark); }
.board .coord { font-family: var(--font); font-size: 7.5px; font-weight: 700; }
.board .cl { fill: var(--board-light); }
.board .cd { fill: var(--board-dark); }

/* Pieces are the app's own art (/assets/pieces-*.svg). Every piece is placed
   twice; the theme decides which set shows: dark-edged pieces on the light
   board, white-edged pieces on the darker board of the dark theme. */
.pd { display: none; }
@media (prefers-color-scheme: dark) {
  .pl { display: none; }
  .pd { display: inline; }
}
.ghost { opacity: 0.32; }

.arrow { fill: var(--signal); }
.arrow-line {
  fill: none; stroke: var(--signal);
  stroke-width: 10; stroke-linejoin: miter; stroke-linecap: butt;
  opacity: 0.92;
}
.arrow-head { opacity: 0.92; }
.mini-board .arrow-line { stroke-width: 9; }
.trail { fill: none; stroke: var(--piece-ink); stroke-width: 2; stroke-dasharray: 3 5; opacity: 0.55; }
.cursor { fill: var(--piece-light); stroke: var(--piece-ink); stroke-width: 1.6; stroke-linejoin: round; }

/* The outline keeps Black's share of the bar visible on the dark page. */
.evalbar .eb-track { fill: var(--eb-black); stroke: var(--line-strong); stroke-width: 1; }
.evalbar .eb-fill { fill: var(--piece-light); }
.evalbar .eb-num {
  font-family: var(--font); font-size: 7px; font-weight: 700;
  text-anchor: middle; fill: var(--piece-ink);
}

/* The one orchestrated moment on the page: the engine thinks, the evaluation
   swings to White, and the arrow is drawn to the winning square. */
.board .eb-fill {
  transform-box: fill-box; transform-origin: 50% 100%;
  transform: scaleY(0.88);
  animation: eb-swing 1.1s cubic-bezier(.2,.7,.2,1) 0.35s both;
}
.board .arrow-line {
  stroke-dasharray: 94; stroke-dashoffset: 0;
  animation: arrow-draw 0.55s cubic-bezier(.5,0,.2,1) 1.1s both;
}
.board .arrow-head { animation: arrow-head 0.2s ease-out 1.6s both; }
.engine-line .eval { animation: fade-in 0.3s ease-out 1.3s both; }
@keyframes eb-swing { from { transform: scaleY(0.5); } to { transform: scaleY(0.88); } }
@keyframes arrow-draw { from { stroke-dashoffset: 94; } to { stroke-dashoffset: 0; } }
@keyframes arrow-head { from { opacity: 0; } to { opacity: 0.92; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Engine output under the board, set like the analysis line in a chess GUI. */
.engine-line {
  display: flex; align-items: baseline; gap: var(--s-3);
  margin: var(--s-3) 0 0 calc(24 / 344 * 100%);
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sq);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  min-width: 0;
}
.engine-line .eval {
  font-weight: 800; font-stretch: var(--wide); color: var(--piece-ink);
  background: var(--piece-light); border: 1px solid var(--line);
  padding: 1px var(--s-2); border-radius: var(--r-sq);
}
.engine-line .pv { font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.engine-line .mv { color: var(--muted); font-weight: 500; }
.engine-line .depth { margin-left: auto; color: var(--muted); white-space: nowrap; }

/* The sites whose boards the app recognises, between the hero and Features. */
.platforms { border-top: 1px solid var(--line); padding: var(--s-5) 0; }
.platforms-row {
  display: flex; justify-content: flex-start; align-items: baseline; flex-wrap: wrap;
  gap: var(--s-2) var(--s-7);
  font-size: var(--t-lg); font-weight: 700; font-stretch: var(--wide);
  letter-spacing: -0.02em;
  color: var(--ink-2);
}
.platforms-label {
  font-size: var(--t-sm); font-weight: 500; font-stretch: 100%; letter-spacing: 0;
  color: var(--muted);
}

/* ------------------------------------------------------------- Section ---- */
section h2 { font-size: var(--t-h2); margin-bottom: var(--s-4); }
section .section-lead {
  font-size: var(--t-lg); color: var(--ink-2);
  max-width: 60ch; margin-bottom: var(--s-7);
}

/* Image placeholders: drawn as an empty board region so they read as intended. */
.img-slot {
  background:
    repeating-conic-gradient(var(--check-a) 0 25%, var(--check-b) 0 50%) 0 0 / 28px 28px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: var(--t-xs);
  text-align: center; padding: var(--s-5);
  min-height: 160px;
}
.img-slot img { display: block; width: 100%; height: auto; border-radius: var(--r-card); }
.img-slot:has(img) { padding: 0; background: none; }

/* ------------------------------------------------------------ Features ---- */
/* The modes are the product; they lead, three across. */
.modes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: var(--s-5);
  margin-bottom: var(--s-8);
}
.mode {
  display: grid; grid-template-columns: 104px minmax(0, 1fr);
  gap: var(--s-4); align-items: start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--s-5);
}
.mini-board { display: block; width: 104px; height: 78px; border-radius: var(--r-sq); overflow: hidden; }
.mode h3 {
  font-size: var(--t-lg); font-weight: 780; font-stretch: var(--wide);
  letter-spacing: -0.02em; margin-bottom: var(--s-1);
}
.mode p { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.55; }
/* Coach's verdict badge, as the app draws it on the board. */
.verdict circle { fill: #C8453A; stroke: var(--piece-light); stroke-width: 2; }
.verdict text {
  fill: #FFFFFF; font-family: var(--font); font-size: 15px; font-weight: 800;
  text-anchor: middle; dominant-baseline: central;
}

/* The rest of the toolkit: a ruled list, not a wall of cards. */
.features-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--s-6) var(--s-5);
}
.feature {
  display: grid; grid-template-columns: 22px minmax(0, 1fr);
  column-gap: var(--s-3); align-content: start;
  padding-top: var(--s-4); border-top: 1px solid var(--line-strong);
}
.feature-icon {
  grid-row: span 2;
  width: 22px; height: 22px; margin-top: 1px;
  display: inline-flex; color: var(--ink);
}
.feature-icon svg { width: 100%; height: 100%; stroke: currentColor; stroke-width: 1.6; fill: none; }
.feature h3 { margin-bottom: var(--s-1); }
.feature p { font-size: var(--t-sm); color: var(--muted); line-height: 1.55; }

/* --------------------------------------------------------------- Setup ---- */
/* Numbered because installing really is a sequence. The rule behind the
   numbers ties the three steps into one line. */
.steps-grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--s-6);
  position: relative;
}
/* Column layout so the screenshots share a baseline even when one step's text
   runs longer than the others. */
.step { display: flex; flex-direction: column; position: relative; }
.step::before {
  content: ""; position: absolute; left: 40px; right: calc(-1 * var(--s-6)); top: 19px;
  border-top: 1px dashed var(--line-strong);
}
.step:last-child::before { display: none; }
.step-num {
  position: relative; z-index: 1;
  width: 40px; height: 40px;
  display: inline-grid; place-items: center;
  font-size: var(--t-lg); font-weight: 800; font-stretch: var(--wide);
  background: var(--sq-dark); color: var(--piece-ink);
  border-radius: var(--r-sq);
  margin-bottom: var(--s-4);
}
.step:nth-child(2) .step-num { background: var(--sq-light); box-shadow: inset 0 0 0 1px var(--line-strong); }
.step h3 { margin-bottom: var(--s-1); }
.step p { font-size: var(--t-sm); color: var(--muted); line-height: 1.55; margin-bottom: var(--s-4); }
.step .img-slot { min-height: 150px; margin-top: auto; aspect-ratio: 8 / 5; }

/* --------------------------------------------------------------- Video ---- */
.video-frame {
  background: var(--deep);
  border-radius: var(--r-card);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  display: flex; align-items: center; justify-content: center;
  color: var(--sq-dark); font-size: var(--t-sm);
  text-align: center; padding: var(--s-5);
}
.video-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.video-frame:has(iframe) { padding: 0; }

/* ------------------------------------------------------------- Pricing ---- */
/* Terms on the left, one compact card on the right. One product, one block
   to act on: price, what is included, the button, in reading order. */
.pricing-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(32px, 6vw, 96px);
  align-items: center;
}
.pricing-copy .section-lead { margin-bottom: 0; }
.price-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-card);
  padding: clamp(24px, 3.5vw, 36px);
}
.price-card .amount {
  font-size: var(--t-price); line-height: 0.9; font-weight: 820;
  font-stretch: var(--wider); letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  display: flex; align-items: flex-start;
  margin-bottom: var(--s-3);
}
.price-card .amount .cents {
  font-size: 0.42em; letter-spacing: -0.02em; margin-top: 0.12em; color: var(--ink-2);
}
.price-card .cadence { font-size: var(--t-sm); color: var(--muted); margin-bottom: var(--s-5); }
.price-card .btn { white-space: normal; text-align: center; }
.price-note { font-size: var(--t-sm); color: var(--ink-2); margin-top: var(--s-3); text-align: center; }

.price-list { list-style: none; border-top: 1px solid var(--line); margin-bottom: var(--s-5); }
.price-list li {
  font-size: var(--t-base); padding: var(--s-3) 0; color: var(--ink);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-start; gap: var(--s-3);
}
.check { color: var(--ink); width: 16px; height: 16px; flex-shrink: 0; margin-top: 5px; }

/* Purchase disabled - no Creem key, or Creem rejected it. The server sets
   body[data-purchase="off"]; [data-buy] leads to a payment, [data-buy-off] explains
   why it is gone. Hidden by default so a missing attribute never shows both.
   No component rule below sets `display` on these elements, or it would outrank
   the switch and show both at once. */
[data-buy-off] { display: none !important; }
[data-purchase="off"] [data-buy] { display: none !important; }
[data-purchase="off"] [data-buy-off] { display: revert !important; }
[data-purchase="off"] .btn[data-buy-off] { display: inline-flex !important; }
.btn-off {
  background: var(--paper); color: var(--ink-2);
  border-color: var(--line-strong);
  cursor: default; pointer-events: none;
}
[data-purchase="off"] .price-card .amount { color: var(--muted); }

/* Same switch for the installer: [data-dl] leads to /download, which has nothing to
   hand out until the installer is uploaded. */
[data-download="off"] [data-dl] { display: none !important; }
[data-dl-off] { display: none !important; }
[data-download="off"] [data-dl-off] { display: inline-flex !important; }
.sale-off {
  margin-top: var(--s-3);
  font-size: var(--t-sm); line-height: 1.55; color: var(--ink-2);
}
.price-trial { font-size: var(--t-base); color: var(--ink-2); margin-top: var(--s-5); }
.price-fineprint { font-size: var(--t-xs); color: var(--muted); margin-top: var(--s-4); }

/* ----------------------------------------------------------------- FAQ ---- */
/* Questions open in place, one under another. */
.faq-list { max-width: 760px; }
.faq-item { border-top: 1px solid var(--line-strong); }
.faq-item summary {
  list-style: none;
  display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s-4);
  padding: var(--s-4) 0;
  font-size: var(--t-base); font-weight: 650; font-stretch: 106%;
  color: var(--ink); cursor: pointer;
}
.faq-item summary::-webkit-details-marker { display: none; }
/* A plus that turns into a cross when open: shows the question can close again. */
.faq-item summary::after {
  content: ""; flex-shrink: 0;
  width: 12px; height: 12px; margin-top: 6px;
  background:
    linear-gradient(var(--ink), var(--ink)) center / 100% 2px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center / 2px 100% no-repeat;
  transition: transform 0.2s ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item summary:hover { color: var(--ink-2); }
.faq-item p {
  font-size: var(--t-sm); color: var(--ink-2); line-height: 1.6;
  max-width: 60ch; padding-bottom: var(--s-5); margin-top: calc(-1 * var(--s-1));
}

/* ------------------------------------------------------------- Contact ---- */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(24px, 5vw, 72px); align-items: start;
}
.contact-info p {
  color: var(--ink-2); margin-bottom: var(--s-5);
  line-height: 1.6; max-width: 54ch;
}
.contact-email {
  display: inline-block;
  font-size: clamp(1.25rem, 0.9rem + 1.4vw, 1.75rem); font-weight: 780;
  font-stretch: var(--wide); letter-spacing: -0.025em;
  color: var(--ink); text-decoration: none;
  border-bottom: 3px solid var(--signal);
  padding-bottom: 2px;
  overflow-wrap: anywhere;
}
.contact-email:hover { border-bottom-color: var(--ink); }
.contact-meta { border-top: 1px solid var(--line-strong); }
.contact-meta > div {
  display: grid; grid-template-columns: minmax(110px, 0.8fr) minmax(0, 1.4fr);
  gap: var(--s-4); padding: var(--s-4) 0;
  border-bottom: 1px solid var(--line);
}
.contact-meta dt { font-size: var(--t-sm); color: var(--muted); }
.contact-meta dd { font-size: var(--t-sm); color: var(--ink); font-weight: 500; }

/* -------------------------------------------------------------- Footer ---- */
footer {
  padding: var(--s-6) 0 calc(var(--s-6) + env(safe-area-inset-bottom, 0px));
  background: var(--deep);
  color: var(--sq-dark);
  font-size: var(--t-sm);
}
footer .wrap {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: var(--s-3) var(--s-5);
}
.footer-brand { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--sq-light); }
.footer-brand .logo-mark { width: 22px; height: 22px; font-size: 16px; }
footer a { color: var(--sq-light); text-decoration: none; }
footer a:hover { color: #FFFFFF; text-decoration: underline; text-underline-offset: 3px; }
.footer-links { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); }
footer :focus-visible { outline-color: var(--sq-light); }

/* --------------------------------------------- Functional pages (shared) ---- */
.page { padding: clamp(40px, 7vw, 88px) 0 var(--s-section); border-top: none; }
/* Helper pages (activate, thank-you, checkout error, 404): one centred column.
   The bar and the footer take the same width so their edges line up with the
   content, and the footer stays at the bottom of short pages. */
.narrow { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; }
.narrow > main { flex: 1 0 auto; }
.narrow .wrap { max-width: calc(720px + 2 * var(--s-gutter)); }
.narrow .card { max-width: none; }
.page h1 { font-size: var(--t-h1); margin-bottom: var(--s-4); }
.page .lead { font-size: var(--t-lg); color: var(--ink-2); max-width: 60ch; margin-bottom: var(--s-6); }
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: clamp(20px, 4vw, 32px); max-width: 680px;
}
.card + .card { margin-top: var(--s-5); }
.card h2 {
  font-size: var(--t-xl); font-weight: 750; font-stretch: var(--wide);
  letter-spacing: -0.02em; margin-bottom: var(--s-3);
}
.card p { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.6; }
.card p + p { margin-top: var(--s-3); }

.field { margin-bottom: var(--s-5); }
.field label { display: block; font-size: var(--t-sm); font-weight: 650; margin-bottom: var(--s-2); color: var(--ink); }
.field input {
  width: 100%; padding: 11px var(--s-3); font: inherit;
  /* 16px keeps iOS from zooming when the field takes focus. */
  font-size: var(--t-base);
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--line-strong); border-radius: var(--r-ctl);
  background: var(--field); color: var(--ink);
  letter-spacing: 0.03em;
  text-overflow: ellipsis;
}
.field input:hover { border-color: var(--ink-2); }
.field input:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; border-color: var(--ink); }
.field input::placeholder { color: var(--muted); opacity: 1; letter-spacing: 0.03em; }
.field .hint { font-size: var(--t-xs); color: var(--muted); margin-top: var(--s-2); }
.field .muted { font-weight: 400; }
.actions { display: flex; gap: var(--s-3); flex-wrap: wrap; align-items: center; margin-top: var(--s-2); }

.alert {
  border-radius: var(--r-ctl); padding: var(--s-3) var(--s-4);
  font-size: var(--t-sm); line-height: 1.5; margin: var(--s-4) 0;
  border: 1px solid; border-left-width: 4px;
}
.alert-error { background: var(--err-bg); color: var(--err-fg); border-color: var(--err-line); border-left-color: var(--err-edge); }
.alert-ok { background: var(--ok-bg); color: var(--ok-fg); border-color: var(--ok-line); border-left-color: var(--ok-edge); }
.alert-info { background: var(--info-bg); color: var(--info-fg); border-color: var(--info-line); border-left-color: var(--info-edge); }

.key-box {
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  /* Shrinks before it overflows: the key is 29 characters wide. */
  font-size: clamp(0.8125rem, 0.55rem + 1.3vw, 1.125rem);
  letter-spacing: 0.06em;
  background: var(--field); border: 1px solid var(--line-strong); border-left: 4px solid var(--signal);
  border-radius: var(--r-ctl);
  padding: var(--s-3) var(--s-3) var(--s-3) var(--s-4);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); flex-wrap: wrap;
  margin: var(--s-4) 0;
}
.key-box code { font-family: inherit; overflow-wrap: anywhere; min-width: 0; }
.key-box button { flex-shrink: 0; }

.steps { list-style: none; counter-reset: s; margin: var(--s-4) 0 var(--s-5); }
.steps li {
  counter-increment: s; position: relative; padding-left: 38px;
  font-size: var(--t-sm); color: var(--ink-2); line-height: 1.55; margin-bottom: var(--s-3);
  min-height: 26px;
}
.steps li::before {
  content: counter(s); position: absolute; left: 0; top: -1px;
  width: 26px; height: 26px; border-radius: var(--r-sq);
  background: var(--sq-dark); color: var(--piece-ink);
  font-size: var(--t-xs); font-weight: 800;
  display: inline-grid; place-items: center;
}
.steps li:nth-child(even)::before { background: var(--sq-light); box-shadow: inset 0 0 0 1px var(--line-strong); }

/* Links inside prose: ink text with the accent as the underline, since amber
   text on these light surfaces would fail contrast. */
.card a:not(.btn), .steps a, .page .lead a, .contact-info a:not(.contact-email), .faq-item a, .sale-off a, .price-trial a {
  color: var(--ink);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--signal);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.card a:not(.btn):hover, .steps a:hover, .page .lead a:hover,
.contact-info a:not(.contact-email):hover, .faq-item a:hover, .sale-off a:hover, .price-trial a:hover { text-decoration-color: var(--ink); }

.muted { color: var(--muted); font-size: var(--t-sm); }
.hidden { display: none !important; }
details.card > summary {
  cursor: pointer; font-size: var(--t-sm); font-weight: 650; color: var(--ink);
}
details.card[open] > summary { margin-bottom: var(--s-4); }

/* ------------------------------------------------------ One screen each ---- */
/* On a desktop screen every section a nav link leads to fills exactly the view
   under the bar: its top rule tucks under the bar and the next section's rule sits
   on the last visible row. Spacing follows the screen height, so tall sections fit
   and short ones do not float in empty space. Below 860px of height the tallest
   section (Features) no longer fits, so phones and laptop screens keep the normal
   flow instead of showing a screen cut off at the bottom. */
:root { --screen: 100vh; --pad-y: clamp(32px, 7vh, 104px); }
@supports (height: 100svh) {
  :root { --screen: 100svh; --pad-y: clamp(32px, 7svh, 104px); }
}
@media (min-width: 901px) and (min-height: 860px) {
  /* Hero and platform strip together are the first screen. */
  .first-screen {
    min-height: calc(var(--screen) - var(--nav-h) - 2px);
    display: flex; flex-direction: column;
  }
  .first-screen .hero { flex: 1 0 auto; display: flex; align-items: center; padding-block: var(--pad-y); }
  main > section,
  .faq-contact {
    min-height: calc(var(--screen) - var(--nav-h) - 1px);
    display: flex; flex-direction: column; justify-content: center;
    padding-block: var(--pad-y);
  }
  .first-screen .hero > .wrap,
  main > section > .wrap { width: 100%; }
  section .section-lead { margin-bottom: clamp(24px, 4.5vh, 48px); }
  .modes { margin-bottom: clamp(24px, 4.5vh, 64px); }
  /* The video is as large as the screen allows, never cut off at the bottom. */
  .video-frame { width: min(100%, calc((var(--screen) - var(--nav-h) - 2 * var(--pad-y) - 170px) * 16 / 9)); }

  /* Questions and contact share the last screen, side by side. Top-aligned, so
     opening an answer never moves the list. Both nav links land on this screen:
     each section's scroll margin reaches back to the shared top rule. */
  .faq-contact {
    flex-direction: row; justify-content: center; align-items: flex-start;
    gap: clamp(40px, 6vw, 96px);
    /* The last screen ends with the footer: questions, contact and footer fill
       the view exactly, so no empty band sits above the footer. */
    min-height: calc(var(--screen) - var(--nav-h) - var(--footer-h));
    padding-bottom: clamp(24px, 4vh, 64px);
    border-top: 1px solid var(--line);
    padding-inline: max(var(--s-gutter), calc((100% - var(--max)) / 2 + var(--s-gutter)));
  }
  .faq-contact > section {
    border-top: none; padding: 0;
    scroll-margin-top: calc(var(--pad-y) + 1px);
  }
  .faq-contact > section > .wrap { max-width: none; padding: 0; }
  .faq-contact > #faq { flex: 1.35 1 0; }
  .faq-contact > #contact { flex: 1 1 0; min-width: 0; }
  .faq-contact .contact-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
}

/* ---------------------------------------------------------- Responsive ---- */
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
  .pricing-grid { grid-template-columns: minmax(0, 1fr); }
  .price-card { max-width: 480px; }
  .analysis { justify-self: start; max-width: 480px; }
  .nav-links { gap: var(--s-4); }
  .nav-menu { gap: var(--s-4); }
}
@media (max-width: 760px) {
  .step::before { display: none; }
}

/* Narrow: the bar becomes two rows - brand and call to action, then the section
   links across the full width. display:contents lifts the children of .nav-links
   into the bar's own flex row so they can be ordered independently. */
@media (max-width: 720px) {
  nav .wrap { flex-wrap: wrap; row-gap: 0; min-height: 56px; padding-top: var(--s-2); }
  /* Only the marketing bar splits; the simple bars on the other pages have no
     .nav-menu and keep their layout. */
  .nav-links:has(.nav-menu) { display: contents; }
  .nav-menu {
    order: 3; width: 100%;
    justify-content: space-between; gap: var(--s-4);
    padding: var(--s-2) 0 var(--s-1);
  }
  :root { --nav-h: 89px; }
}
@media (max-width: 520px) {
  .btn { white-space: normal; text-align: center; }
  .hero-ctas { flex-direction: column; align-items: stretch; }
  .actions .btn { flex: 1 1 auto; }
  .mode { padding: var(--s-4); }
  .engine-line .depth { display: none; }
  .platforms-row { justify-content: flex-start; font-size: var(--t-base); gap: var(--s-2) var(--s-5); }
}
