/* ═══════════════════════════════════════════════════════════════════════════
   OnDeck marketing — shared site stylesheet
   ───────────────────────────────────────────────────────────────────────────
   Nav, footer, buttons, section rhythm, prose, forms, the motion primitives
   and the CSS device frames. Every page in marketing/ loads this after
   tokens.css and keeps only its own page-specific block inline.

   Before this existed, ~250 lines of chrome CSS were copy-pasted across six
   HTML files AND a seventh copy lived inside scripts/gen-updates.mjs. Adding
   a page meant adding an eighth copy. Don't reintroduce that: if a rule is
   needed by two pages, it belongs here.

   Load order matters — tokens.css MUST come first so the custom properties
   resolve:
       <link rel="stylesheet" href="/tokens.css">
       <link rel="stylesheet" href="/site.css">

   brand-aliases.css is NOT needed by pages on this stylesheet; it exists for
   the older pages that still say var(--navy) instead of var(--color-navy).

   ── Token discipline ──────────────────────────────────────────────────────
   The June audit found the marketing HTML was misusing correct tokens rather
   than carrying wrong values. Four rules, all enforced by this file:
     • Primary CTA is --color-navy (the app's primary). NOT teal #005c62.
     • --color-aqua (#00b8c4) is 2.6:1 — decorative only, never text, never a
       background behind text. --color-aqua-text (#005c62, 7.5:1) is the one
       that may carry words.
     • Shadows are navy-tinted --shadow-*; never an aqua glow.
     • Radii come from the scale: 3 / 8 / 12 / full. Nothing else.
   ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --ink:        var(--color-navy);
  --ink-soft:   var(--color-text);
  --ink-faint:  var(--color-text-muted);
  --line:       var(--color-border);
  --line-soft:  var(--color-border-subtle);

  --grad-deep:  linear-gradient(155deg, #0b1b33 0%, var(--color-navy) 42%, #17395f 100%);

  /* On the navy bands the normal text tokens are unreadable. These are the
     on-dark pair, contrast-checked against #0b1b33..#17395f. */
  --on-dark:        rgba(255,255,255,0.78);
  --on-dark-faint:  rgba(255,255,255,0.62);
  --on-dark-accent: #7fe3ea;                  /* 8.4:1 on the band */

  --page-x: clamp(1.25rem, 5vw, 4.5rem);
  --band-y: clamp(4.5rem, 9vw, 9rem);
  --wrap:   1240px;
  --nav-h:  66px;
}

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  background: var(--color-bg);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-default, 300);
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ─── SKIP LINK (WCAG 2.4.1 bypass blocks) ───────────────────────────────── */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--color-navy); color: #fff;
  padding: 0.8rem 1.4rem; border-radius: 0 0 var(--radius-sm) 0;
  font-size: 0.85rem; letter-spacing: 0.04em; text-decoration: none;
}
.skip-link:focus { left: 0; }

/* ─── TYPE ───────────────────────────────────────────────────────────────── */

.display, h1, h2, h3 { font-family: var(--font-display); font-weight: 400; color: var(--ink); }
h1 { font-size: clamp(3rem, 7.5vw, 6.6rem);   line-height: 0.92; letter-spacing: 0.005em; }
h2 { font-size: clamp(2.4rem, 4.6vw, 4.2rem); line-height: 0.96; letter-spacing: 0.01em; }
h3 { font-size: clamp(1.05rem, 1.5vw, 1.25rem); line-height: 1.25; letter-spacing: 0.02em; }
h4 { font-family: var(--font-body); font-size: 0.95rem; font-weight: 500; color: var(--ink); }

/* Marketing-only accent. The app dropped Instrument Serif; marketing keeps it
   (locked 2026-06-21). */
.flourish { font-family: var(--font-accent); font-style: italic; font-size: 1.06em; letter-spacing: -0.01em; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 0.65rem;
  font-family: var(--font-body); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--color-aqua-text); margin-bottom: 1.15rem;
}
.eyebrow::before { content: ''; width: 26px; height: 1px; background: var(--color-aqua); }

.lead    { font-size: clamp(1.02rem, 1.35vw, 1.2rem); line-height: 1.7; color: var(--ink-soft); }
.kicker  { font-size: 0.88rem; line-height: 1.65; color: var(--ink-faint); }
.small   { font-size: 0.78rem; color: var(--ink-faint); }
.mono    { font-family: var(--font-mono); font-size: 0.9em; }
.maxw    { max-width: 46ch; }
.maxw-lg { max-width: 62ch; }

/* ─── LAYOUT ─────────────────────────────────────────────────────────────── */

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--page-x); }
.band { padding-block: var(--band-y); position: relative; }
.band-alt   { background: var(--color-surface); border-block: 1px solid var(--line-soft); }
.band-inset { background: var(--color-surface-inset); }

.band-dark {
  background: var(--grad-deep);
  color: var(--on-dark);
  position: relative; overflow: hidden;
}
.band-dark h1, .band-dark h2, .band-dark h3, .band-dark h4 { color: #fff; }
.band-dark .lead   { color: var(--on-dark); }
.band-dark .kicker,
.band-dark .small  { color: var(--on-dark-faint); }
.band-dark .eyebrow { color: var(--on-dark-accent); }
.band-dark .eyebrow::before { background: var(--on-dark-accent); }
.band-dark .flourish { color: var(--on-dark-accent); }
.band-dark a:not(.btn) { color: var(--on-dark-accent); }

/* Decorative light source. Never sits behind body text. */
.bloom { position: absolute; border-radius: 50%; pointer-events: none; filter: blur(4px); }
.bloom-a { width: 720px; height: 720px; top: -34%; right: -12%;
           background: radial-gradient(circle, rgba(0,184,196,0.20) 0%, transparent 68%); }
.bloom-b { width: 560px; height: 560px; bottom: -30%; left: -10%;
           background: radial-gradient(circle, rgba(36,82,127,0.36) 0%, transparent 70%); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
.stack  { display: flex; flex-direction: column; gap: 1rem; }
.row    { display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap; }
.mt     { margin-top: 1.1rem; }
.mt-lg  { margin-top: clamp(2rem, 4vw, 3.4rem); }
.center { text-align: center; }
.center .eyebrow { justify-content: center; }
.center .row { justify-content: center; }

/* ─── NAV ────────────────────────────────────────────────────────────────── */

.nav {
  position: sticky; top: 0; z-index: 90;
  background: rgba(240,244,247,0.82);
  backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--duration) var(--ease), background var(--duration) var(--ease);
}
.nav.is-stuck { border-bottom-color: var(--line-soft); background: rgba(240,244,247,0.94); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding-block: 0.85rem; }

.wordmark {
  font-family: var(--font-display); font-size: 1.65rem; letter-spacing: 0.06em;
  color: var(--ink); text-decoration: none; line-height: 1;
  /* Bebas Neue has a short cap height, so the footer wordmark measured 23px —
     one pixel under 2.5.8. inline-block so the min-height applies. */
  display: inline-block; min-height: 24px;
}
.wordmark .deck { color: var(--color-aqua-text); }

.nav-links { display: flex; gap: 1.9rem; list-style: none; }
.nav-links a {
  font-size: 0.85rem; color: var(--ink-faint); text-decoration: none;
  position: relative; padding-block: 0.35rem;
  transition: color var(--duration) var(--ease);
}
.nav-links a::after {
  content: ''; position: absolute; left: 0; right: 100%; bottom: 0; height: 1.5px;
  background: var(--color-aqua-text);
  transition: right var(--duration-slow) var(--ease-brand);
}
.nav-links a:hover, .nav-links a[aria-current="page"] { color: var(--ink); }
.nav-links a:hover::after, .nav-links a[aria-current="page"]::after { right: 0; }

.nav-right { display: flex; align-items: center; gap: 1.1rem; }
/* `.nav-login` is asserted by tests/smoke/golden-path.spec.js — keep the class
   name on the log-in anchor even if the styling changes. */
.nav-login { font-size: 0.85rem; color: var(--ink-faint); text-decoration: none; transition: color var(--duration) var(--ease); }
.nav-login:hover { color: var(--ink); }

/* Hamburger. Hidden on desktop; below 900px it replaces the inline link row,
   which becomes a dropdown panel under the sticky bar. */
.nav-toggle {
  display: none; background: none; border: 0; cursor: pointer;
  width: 42px; height: 42px; align-items: center; justify-content: center;
  border-radius: var(--radius); color: var(--ink);
}
.nav-toggle:hover { background: rgba(14,34,64,0.07); }
.nav-toggle svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-open  { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }
/* Dropdown-only Log In row — the inline one overflows the bar at phone widths. */
.nav-item-login { display: none; }

/* ─── BUTTONS ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.78rem 1.55rem; border-radius: var(--radius-sm);
  font-family: var(--font-body); font-size: 0.88rem; font-weight: 500;
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  transition: background var(--duration) var(--ease), transform var(--duration-fast) var(--ease),
              box-shadow var(--duration) var(--ease), color var(--duration) var(--ease);
}
.btn-primary { background: var(--color-navy); color: #fff; box-shadow: var(--shadow); }
.btn-primary:hover { background: var(--color-deep); box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--color-border-strong); }
.btn-ghost:hover { background: var(--color-surface); border-color: var(--ink); }
.btn-white { background: #fff; color: var(--color-navy); box-shadow: var(--shadow-lg); }
.btn-white:hover { background: #eef6f8; transform: translateY(-1px); }
.btn-onDark { background: transparent; color: #fff; border-color: rgba(255,255,255,0.34); }
.btn-onDark:hover { background: rgba(255,255,255,0.10); border-color: rgba(255,255,255,0.6); }
.btn-lg { padding: 0.95rem 2rem; font-size: 0.94rem; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 0.42rem;
  color: var(--color-aqua-text); text-decoration: none;
  font-size: 0.88rem; font-weight: 500;
  /* 23px without this — one pixel under the 2.5.8 minimum. */
  min-height: 24px;
}
.link-arrow::after { content: '→'; transition: transform var(--duration) var(--ease-brand); }
.link-arrow:hover::after { transform: translateX(4px); }
.band-dark .link-arrow { color: var(--on-dark-accent); }

:where(a, button, input, textarea, select, [tabindex]):focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

/* ─── PILLS ──────────────────────────────────────────────────────────────── */

.pill {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.26rem 0.66rem; border-radius: var(--radius-full);
  font-size: 0.7rem; font-weight: 500; letter-spacing: 0.05em; text-transform: uppercase;
  border: 1px solid var(--line); background: var(--color-surface); color: var(--ink-faint);
  white-space: nowrap;
}
.pill-core   { background: var(--color-info-bg);      color: var(--color-info-fg);    border-color: rgba(14,165,233,0.3); }
.pill-optin  { background: var(--color-surface-inset); color: var(--ink-faint); }
.pill-native { background: var(--color-success-bg);   color: var(--color-success-fg); border-color: rgba(47,125,86,0.3); }
.band-dark .pill { background: rgba(255,255,255,0.10); border-color: rgba(255,255,255,0.2); color: rgba(255,255,255,0.86); }

/* ─── CARDS ──────────────────────────────────────────────────────────────── */

.card {
  background: var(--color-surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  padding: 1.6rem;
  transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease),
              transform var(--duration) var(--ease-brand);
}
.card:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-lg); transform: translateY(-3px); }
.band-dark .card { background: rgba(255,255,255,0.055); border-color: rgba(255,255,255,0.13); }
.band-dark .card:hover { background: rgba(255,255,255,0.085); border-color: rgba(255,255,255,0.28); }

.icon-tile {
  width: 40px; height: 40px; border-radius: var(--radius);
  display: grid; place-items: center; margin-bottom: 0.9rem;
  background: rgba(0,184,196,0.12);
}
.icon-tile svg { width: 19px; height: 19px; fill: none; stroke: var(--color-aqua-text);
                 stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.band-dark .icon-tile { background: rgba(0,184,196,0.18); }
.band-dark .icon-tile svg { stroke: var(--on-dark-accent); }

/* Tick list. The on-dark pair is mandatory — --color-text on navy is unreadable
   and the teal tick vanishes entirely. */
.checks { list-style: none; display: flex; flex-direction: column; gap: 0.62rem; margin-top: 1.4rem; }
.checks li { display: flex; gap: 0.7rem; font-size: 0.88rem; color: var(--ink-soft); line-height: 1.55; }
.checks li::before {
  content: ''; flex: 0 0 17px; height: 17px; margin-top: 0.22rem; border-radius: 50%;
  background: rgba(0,184,196,0.15) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23005c62' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/10px no-repeat;
}
.band-dark .checks li { color: rgba(255,255,255,0.8); }
.band-dark .checks li::before {
  background: rgba(0,184,196,0.22) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237fe3ea' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/10px no-repeat;
}

/* ─── STATS ──────────────────────────────────────────────────────────────── */

.stat-num { font-family: var(--font-display); font-size: clamp(2.6rem, 4.4vw, 3.9rem);
            line-height: 1; color: var(--ink); letter-spacing: 0.01em; }
.band-dark .stat-num { color: #fff; }
.stat-label { font-size: 0.78rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-faint); margin-top: 0.45rem; }
.band-dark .stat-label { color: var(--on-dark-faint); }

/* ═══ DEVICE FRAMES ═════════════════════════════════════════════════════════
   Apple's own product bezels, composited into each capture at build time by
   scripts/gen-shots.mjs. One flat image per device — no overlay, no CSS
   enclosure, nothing to align.

   This replaced a set of hand-built CSS frames: a gradient body, a fake
   Dynamic Island, a fake stand and neck. They were not allowed. The App Store
   Marketing Guidelines forbid "graphics, illustrations, or logotypes to
   represent an Apple product" and any "simulation of an Apple product", and
   point at the provided bezels instead. The comment that used to sit here
   argued pure CSS meant "no licensing question" — it WAS the licensing
   question, in the other direction.

   Do NOT add a shadow, reflection, corner radius, hover lift or any transform
   to these. "Use Apple product images as is and without modification" rules
   out cropping, tilting, obstructing and animating them, so .device is
   deliberately a bare box and the enclosure carries its own shading. The
   reveal animation is opted down to a plain fade for the same reason — see
   [data-reveal="fade"] below.

   .d-browser is NOT an Apple product and keeps its CSS chrome. It frames
   captures of the WEB app, which the bezel licence explicitly does not cover
   (it grants use for software running only on Apple operating systems).
   ═══════════════════════════════════════════════════════════════════════════ */

/* flex:none is load-bearing, not tidiness. Every group that shows more than
   one product is a flex row, and a flex item shrinks by default — so the Mac
   would give up width while the iPhone (already at its minimum) would not,
   quietly destroying the relative scale the widths below exist to guarantee.
   Measured before this line: a 306px Mac rendering at 90px beside a
   correctly-sized iPhone. --dev-scale, not flex, does the responsive work. */
.device { position: relative; flex: none; }
/* height:auto and no object-fit: the bezel is sized by the image itself and
   must never be cropped to a slot. Only .d-browser's own capture is fitted. */
.device img { display: block; width: 100%; height: auto; }

/* ── Relative product scale ─────────────────────────────────────────────────
   "If multiple Apple products are shown, display them in the correct relative
   sizes." So the three do NOT get independent widths — they derive from one
   --dev-scale, and a group that wants them bigger or smaller overrides that
   single number. Set a width directly on one of these and the trio silently
   stops being to scale, which is how it was wrong before: the iPhone rendered
   49% oversized next to the Mac.

   Each constant is (real device width in mm) ÷ (the fraction of its bezel PNG
   the device actually occupies, the rest being transparent margin):

     MacBook Air 13"   304.1mm ÷ 0.943 = 322.5
     iPad Air 11"      178.5mm ÷ 0.981 = 181.9
     iPhone 17          71.9mm ÷ 0.971 =  74.0

   --dev-scale is px-per-mm and MUST carry a length unit — the constants above
   are the unitless side of the multiplication. A unitless --dev-scale makes
   every calc() below invalid, and an invalid width silently falls back to
   flex/auto sizing that looks plausible and is not to scale. That is exactly
   what `clamp(0.42, 1.05vw, 0.95)` did here: mixing a unitless number with a
   vw length is invalid clamp(), so write `clamp(0.42px, 1.05vw, 0.95px)`.

   Apple TV is deliberately absent: a television has no fixed physical width,
   so there is nothing to be in scale WITH. It is only ever shown on its own. */
:root { --dev-scale: 2.36px; }

.d-mac    { width: calc(322.5 * var(--dev-scale)); }
.d-tablet { width: calc(181.9 * var(--dev-scale)); }
.d-phone  { width: calc(74.0  * var(--dev-scale)); }
.d-tv     { width: min(700px, 100%); }

.d-browser {
  border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--line); background: var(--color-surface-inset);
  box-shadow: var(--shadow-xl);
}
.d-browser .bar { height: 38px; display: flex; align-items: center; gap: 8px; padding-inline: 14px;
                  background: var(--color-surface-inset); border-bottom: 1px solid var(--line-soft); }
.d-browser .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--color-border-strong); }
.d-browser .url {
  flex: 1; margin-left: 8px; height: 23px; border-radius: var(--radius-full);
  background: var(--color-surface); border: 1px solid var(--line-soft);
  display: flex; align-items: center; padding-inline: 0.75rem;
  font-size: 0.7rem; color: var(--ink-faint);
}

/* ─── APP STORE BADGE ────────────────────────────────────────────────────── */
/* Apple's own artwork, from toolbox.marketingtools.apple.com, used unmodified.
   Do NOT recolour it, add a border or corner radius, drop a shadow on it, or
   append a ™ — the guidelines rule all of that out, and specifically say not
   to add trademark symbols to the badge artwork.
   Two variants because contrast decides which: black on light backgrounds,
   white on the navy bands. Padding gives the required clear space (at least
   1/10 of the badge height on every side) without needing a wrapper. */
.store-badge { display: inline-block; line-height: 0; padding: 5px; }
.store-badge img { display: block; width: 148px; height: auto; }
.store-badge:focus-visible { outline: 2px solid var(--color-aqua-text); outline-offset: 2px; border-radius: 2px; }

/* ─── SCREEN-RECORDING SLOT ──────────────────────────────────────────────── */
/* Silent muted looping clips. `preload="none"` + a poster keeps them off the
   critical path; site.js starts them only once they scroll into view. */
.clip { position: relative; background: #0b1523; overflow: hidden; }
.clip video, .clip img { display: block; width: 100%; height: 100%; object-fit: cover; }
.clip-badge {
  position: absolute; top: 0.85rem; left: 0.85rem; z-index: 4;
  display: inline-flex; align-items: center; gap: 0.42rem;
  padding: 0.3rem 0.68rem; border-radius: var(--radius-full);
  background: rgba(11,21,35,0.72); backdrop-filter: blur(8px);
  color: rgba(255,255,255,0.9); font-size: 0.66rem;
  letter-spacing: 0.09em; text-transform: uppercase;
}
.clip-badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: #2ee6a8;
                      animation: livePulse 2.2s var(--ease) infinite; }
@keyframes livePulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }

/* Shown until a real clip exists at that slot. The scrim has to be heavy —
   the poster frames are mostly white app UI under white text. */
.clip-placeholder {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.75rem;
  background: linear-gradient(150deg, rgba(9,18,31,0.86), rgba(9,18,31,0.68));
  color: #fff; text-align: center; padding: 1.5rem;
}
.clip-play { width: 58px; height: 58px; border-radius: 50%; background: rgba(255,255,255,0.14);
             backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.3); display: grid; place-items: center; }
.clip-play::after { content: ''; width: 0; height: 0; margin-left: 4px;
                    border-left: 15px solid #fff; border-block: 9px solid transparent; }
.clip-cap { font-size: 0.8rem; letter-spacing: 0.03em; }

/* ═══ MOTION PRIMITIVES ═════════════════════════════════════════════════════
   Four of them, zero dependencies. See docs/marketing-redesign-plan-2026-08.md
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 — reveal on enter. `--i` staggers siblings.
   SCOPED TO .js, which the inline head snippet sets on <html> before first
   paint. A bare [data-reveal] { opacity: 0 } leaves a visitor without
   JavaScript staring at a blank page. Do not "simplify" this selector. */
.js [data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.62s var(--ease-brand), transform 0.62s var(--ease-brand);
  transition-delay: calc(var(--i, 0) * 85ms);
}
.js [data-reveal].in { opacity: 1; transform: none; }
.js [data-reveal="scale"] { transform: translateY(24px) scale(0.965); }

/* Opacity only, no transform. Every reveal that wraps an Apple product bezel
   uses this: "animating, flipping, or spinning the images" is prohibited, and
   the scale variant above literally resizes whatever it contains. A fade is
   the most a device block may do. Don't move these back to "scale" because
   the page looks livelier that way. */
.js [data-reveal="fade"] { transform: none; transition: opacity 0.62s var(--ease-brand); }
.js [data-reveal="left"]  { transform: translateX(-26px); }
.js [data-reveal="right"] { transform: translateX(26px); }

/* 2 — scroll-linked. Progressive enhancement: without support the keyframes
   never apply and the element simply renders in its end state. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .parallax-slow { animation: floatUp linear both;     animation-timeline: view(); animation-range: entry 0% exit 100%; }
    .parallax-fast { animation: floatUpFast linear both; animation-timeline: view(); animation-range: entry 0% exit 100%; }
  }
}
@keyframes floatUp     { from { translate: 0 42px; } to { translate: 0 -42px; } }
@keyframes floatUpFast { from { translate: 0 78px; } to { translate: 0 -78px; } }

/* 4 — ambient wave drift. site.js pauses it when off-screen. */
.waves { position: absolute; inset: auto 0 0 0; height: 190px; pointer-events: none;
         opacity: 0.5; mask-image: linear-gradient(to top, #000 10%, transparent 100%); }
.waves svg { position: absolute; bottom: 0; left: 0; width: 250%; height: 100%; }
.waves .w1 { animation: drift 26s linear infinite; }
.waves .w2 { animation: drift 40s linear infinite reverse; opacity: 0.6; }
@keyframes drift { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* The one rule that governs all of it. tokens.css already zeroes the duration
   custom properties here; this handles the things that aren't durations. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .waves .w1, .waves .w2, .clip-badge::before { animation: none !important; }
  .btn:hover, .card:hover { transform: none !important; }
}

/* ─── PROSE (privacy, terms, and any long-form page) ─────────────────────── */

.prose { max-width: 74ch; }
.prose h2 { font-size: clamp(1.5rem, 2.2vw, 2rem); margin-top: 2.8rem; margin-bottom: 0.9rem; }
.prose h3 { font-family: var(--font-body); font-size: 1rem; font-weight: 500; margin-top: 1.8rem; margin-bottom: 0.5rem; }
.prose p, .prose li { font-size: 0.92rem; line-height: 1.75; color: var(--ink-soft); }
.prose p { margin-bottom: 1rem; }
.prose ul, .prose ol { margin: 0 0 1rem 1.2rem; display: flex; flex-direction: column; gap: 0.4rem; }
.prose a { color: var(--color-water); }
.prose strong { font-weight: 500; color: var(--ink); }
.prose-callout {
  background: var(--color-surface); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--color-aqua);
  border-radius: var(--radius); padding: 1.2rem 1.4rem; margin-block: 1.5rem;
}
.prose-callout p:last-child { margin-bottom: 0; }

/* ─── FORMS ──────────────────────────────────────────────────────────────── */

.form { display: flex; flex-direction: column; gap: 1.2rem;
        background: var(--color-surface); border: 1px solid var(--line-soft);
        border-radius: var(--radius-lg); padding: clamp(1.5rem, 3vw, 2.5rem); box-shadow: var(--shadow); }
.form-row   { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.form-group { display: flex; flex-direction: column; gap: 0.4rem; }
.form-group label { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); }
.form-group input, .form-group textarea, .form-group select {
  background: var(--color-bg); border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm); padding: 0.75rem 1rem; color: var(--ink);
  font-family: var(--font-body); font-size: 0.9rem; outline: none; resize: vertical;
  transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.form-group input::placeholder, .form-group textarea::placeholder { color: var(--color-text-faint); }
.form-group input:focus, .form-group textarea:focus, .form-group select:focus {
  border-color: var(--color-aqua-text); box-shadow: 0 0 0 3px rgba(0,184,196,0.15);
}
/* Honeypot — off-screen but still in the layout so bots fill it. */
.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-status { font-size: 0.85rem; line-height: 1.5; min-height: 1.1rem; color: var(--ink-faint); }
.form-status.is-error   { color: var(--color-error); }
.form-status.is-success { color: var(--color-success); font-weight: 500; }
.form.is-submitted .form-row,
.form.is-submitted .form-group:not(:has(.form-status)),
.form.is-submitted .honeypot,
.form.is-submitted button[type="submit"] { display: none; }
.form.is-submitted .form-status { font-size: 1rem; padding: 1.5rem 0; }

/* ─── FOOTER ─────────────────────────────────────────────────────────────── */

.footer { background: var(--color-surface); border-top: 1px solid var(--line-soft); padding-block: 3.2rem 1.6rem; }
.footer-grid { display: grid; grid-template-columns: 1.6fr repeat(3, 1fr); gap: 2.4rem; }
.footer h5 { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.9rem; font-weight: 500; }
/* WCAG 2.2 AA 2.5.8 (Target Size, Minimum) wants 24x24 CSS px. At 0.85rem
   these links were ~16px tall — fine with a mouse, a poor target on a phone,
   and a criterion this site claims to meet. The padding does the work and the
   gap shrinks to match, so the footer looks the same and the tappable area
   grows. Not caught by the axe gate: `target-size` is not in axe's wcag22aa
   tag set, which is why marketing.spec.js now measures it directly. */
.footer ul { list-style: none; display: flex; flex-direction: column; gap: 0.15rem; }
.footer a { font-size: 0.85rem; color: var(--ink-soft); text-decoration: none;
            display: inline-block; padding-block: 0.3rem; }
.footer a:hover { color: var(--color-aqua-text); }
.footer-bottom { margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid var(--line-soft);
                 display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }

/* ─── RESPONSIVE ─────────────────────────────────────────────────────────── */

/* Narrow viewports shrink --dev-scale, NOT individual widths. Setting
   `width: 100%` on one device and not another is how the relative scale broke:
   these three rules used to say `.d-mac { width:100% }`, `.d-tablet
   { max-width:400px }` and `.d-phone { width:200px }`, which at 800px wide
   rendered a MacBook and an iPad at exactly the same size. Apple TV keeps a
   plain width — it is never shown alongside the others. */
@media (max-width: 1080px) {
  :root  { --dev-scale: 1.9px; }
  .d-tv  { width: 100%; max-width: 520px; }
}
@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .nav-links {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 0;
    background: rgba(240,244,247,0.97); backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line-soft);
    padding: 0.4rem var(--page-x) 0.8rem;
    box-shadow: var(--shadow-lg);
  }
  .nav-links.is-open { display: flex; }
  .nav-links a { display: block; padding: 0.85rem 0; font-size: 0.9rem; }
  .nav-links a::after { display: none; }
  .nav-links li + li { border-top: 1px solid var(--line-soft); }
  .nav-login { display: none; }
  .nav-item-login { display: list-item; }

  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  :root { --dev-scale: 1.5px; }
  .form-row { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .footer-grid { grid-template-columns: 1fr; }
  :root { --dev-scale: 1.05px; }
}
