/* Contracked marketing + legal pages. Carmodfinder token system.
   Extracted from the landing page so every public page shares one file. */

/* Self-hosted, not a CDN link: the Content-Security-Policy blocks external
   hosts, so an @import would fail silently and fall back to Inter, which is
   the exact look this face exists to avoid. Variable weight 400-800 in one
   file, latin first so the common case is a single 75kB request. */
@font-face {
  font-family: "Archivo";
  src: url("/fonts/archivo-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-display: swap;
  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";
  src: url("/fonts/archivo-latin-ext.woff2") format("woff2");
  font-weight: 400 800;
  font-display: swap;
  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;
}

/* Carmodfinder token system, adopted verbatim; Contracked adds --marker. */
  :root {
    --bg:       #080809;
    --surface:  #0d0d0f;
    --card:     #111114;
    --elevated: #171719;
    --hover:    #1c1c1f;

    --border:        rgba(255,255,255,0.06);
    --border-subtle: rgba(255,255,255,0.04);
    /* The portal learned this the hard way and left the note: a half-alpha
       brand ring composites to ~2.2:1 on --bg, and the 0.4 alpha this file
       used was fainter still at ~1.7:1 — under the 3:1 WCAG 1.4.11 floor, so
       keyboard focus was effectively invisible on every public page. */
    --focus: #4fd0e8;

    /* --brand is for text/accents on dark (5.5:1). Filled buttons need a
       deeper teal so white label text clears 4.5:1 — #0097b2 only gives 3.5. */
    --brand:       #0097b2;
    --brand-dark:  #007a91;
    --brand-solid: #00758d;
    --brand-solid-hover: #005e73;

    /* Every value below cleared AA (4.5:1) against --card #111114.
       Carmodfinder's originals were tuned for its lighter panels and failed
       here: label 3.3:1, hint 2.1:1, fail 4.0:1. */
    --text:  #f4f4f7;
    --body:  #dcdce2;
    --muted: #a6a6b0;
    --label: #8f8f9a;
    --hint:  #7e7e88;

    --pass: #5cba80;
    --fail: #e0736d;
    --warn: #c9a24d;

    --marker-bg: rgba(230, 205, 100, 0.14);
    --marker-tx: #e9d98a;

    /* Three roles, visibly distinct. Body stays Inter (the Carmodfinder
       system) but headings no longer borrow it: a page whose headlines are
       just bigger body text reads as never having been typeset, and
       Inter-for-everything is the single most-cited tell of a generated site.
       Archivo is self-hosted below: an industrial grotesque with tighter
       apertures than Inter, so it holds authority at display sizes. */
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --display: "Archivo", "Inter", -apple-system, sans-serif;
    --mono: "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;

    /* motion — use only these, no one-off curves */
    --ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);   /* default for almost everything */
    --ease-out:    cubic-bezier(0.17, 1, 0.32, 1);   /* decorative entrances */
    --ease-spring: cubic-bezier(0.35, 1.55, 0.65, 1);/* badges, pops, overshoot */
    --ease-in-out: cubic-bezier(0.66, 0, 0.34, 1);   /* symmetric moves */

    /* depth — layered shadows, hairline ring instead of border (dark-tuned) */
    --shadow-card:
      0 1px 2px rgba(0, 0, 0, 0.35),
      0 2px 4px rgba(0, 0, 0, 0.22),
      0 0 0 0.5px rgba(255, 255, 255, 0.08);
    --shadow-elevated:
      0 4px 8px rgba(0, 0, 0, 0.22),
      0 8px 16px rgba(0, 0, 0, 0.24),
      0 2px 4px rgba(0, 0, 0, 0.2),
      0 1px 2px rgba(0, 0, 0, 0.32),
      0 0 0 0.5px rgba(255, 255, 255, 0.13);
  }

  * { box-sizing: border-box; }
  /* Gated like every other animation in this file — an anchor jump is motion
     too, and this was the one rule that ignored the preference. */
  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }
  body {
    margin: 0; background: var(--bg); color: var(--body);
    font-family: var(--font); font-size: 15.5px; line-height: 1.6;
    letter-spacing: 0.01em;
    -webkit-font-smoothing: antialiased;
  }
  ::selection { background: rgba(0,151,178,0.35); }
  ::-webkit-scrollbar { width: 6px; }
  ::-webkit-scrollbar-track { background: transparent; }
  ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 3px; }

  .wrap { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
  a { color: inherit; }
  h1,h2,h3 {
    font-family: var(--display);
    color: var(--text); font-weight: 700; letter-spacing: -0.025em;
    /* Stops a two-line headline breaking one word onto its own line, which is
       where big type looks accidental rather than set. */
    text-wrap: balance;
  }
  /* One focus treatment for every focusable thing, matching the portal.
     `outline` rather than `box-shadow` so it survives an ancestor's
     `overflow: hidden` — inside .cta the shadow ring was clipped away, so
     tabbing from the email field to the button showed no change at all. The
     radius is left alone: forcing 4px here made buttons and the search box
     visibly change shape on focus. */
  :where(button, a, input, select, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
  }
  .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
  /* Stat placeholder before the live figures land. Dimmed rather than a dash
     glyph, so nothing on screen ever reads as a real value that happens to be
     missing. Removed by the script the moment the number arrives. */
  .pending { color: var(--hint); font-style: italic; }
  .eyebrow {
    color: var(--label); font-size: 0.7rem; font-weight: 500;
    letter-spacing: 0.1em; text-transform: uppercase;
  }

  /* Entrance motion is reserved for the data objects: the ledger, the counters,
     the plan cards. Running one identical fade over every element on the page
     is the most recognisable generated-site tell there is, and it made prose
     arrive hesitantly when prose should simply be there. Scoped to html.js,
     set by the script itself, so a blocked script leaves the page readable
     rather than blank below the hero.

     .reveal  = data objects. Rises and settles.
     .settle  = section headings. A shorter, smaller move, no travel.
     Everything else has no entrance at all, by design. */
  .js .reveal { opacity: 0; transform: translateY(18px) scale(0.995); }
  .js .settle { opacity: 0; }
  @media (prefers-reduced-motion: no-preference) {
    .js .reveal.in {
      opacity: 1; transform: none;
      transition: opacity 0.5s var(--ease-out), transform 0.62s var(--ease-out);
    }
    .js .settle.in { opacity: 1; transition: opacity 0.45s var(--ease-smooth); }
  }
  @media (prefers-reduced-motion: reduce) {
    .js .reveal, .js .settle { opacity: 1; transform: none; }
  }

  /* ── nav ── (2b: solid, sits above the media band) */
  header {
    position: sticky; top: 0; z-index: 10;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
  }
  .nav { display: flex; align-items: center; justify-content: space-between; padding: 15px 0; }
  /* ── logo: "Sweep" (direction 4a) ──
     Concentric signal rings cut by a skewed slash, with a solid centre dot.
     Rings inherit currentColor at low opacity so the mark reads on any
     surface; the slash carries the single brand accent. */
  .wordmark {
    display: inline-flex; align-items: center; gap: 8px;
    font-weight: 800; font-size: 1.05rem; color: var(--text);
    text-decoration: none; letter-spacing: -0.04em;
  }
  .logomark { width: 1.5em; height: 1.5em; flex: none; overflow: hidden; display: block; }
  .logomark .ring { fill: none; stroke: currentColor; }
  .logomark .ring-outer { opacity: 0.3; }
  .logomark .ring-inner { opacity: 0.5; }
  .logomark .slash { fill: var(--brand); }
  .logomark .dot { fill: currentColor; }
  @media (prefers-reduced-motion: no-preference) {
    .logomark .slash { transition: transform 0.5s var(--ease-smooth); transform-origin: 32px 32px; }
    .wordmark:hover .logomark .slash, .wordmark:focus-visible .logomark .slash { transform: rotate(360deg); }
  }
  nav.links { display: flex; gap: 26px; align-items: center; }
  nav.links a { font-size: 0.85rem; font-weight: 500; color: var(--muted); text-decoration: none; transition: color 0.2s var(--ease-smooth); }
  nav.links a:hover { color: var(--text); }
  .btn {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-solid); color: #fff; font-weight: 600; font-size: 0.875rem;
    border: none; border-radius: 6px; padding: 10px 20px; cursor: pointer;
    transition: background-color 0.2s var(--ease-smooth); white-space: nowrap; text-decoration: none;
  }
  .btn:hover { background: var(--brand-solid-hover); }
  .btn.ghost {
    background: transparent; border: 1px solid rgba(0,151,178,0.4); color: var(--brand);
    transition: background-color 0.2s var(--ease-smooth), box-shadow 0.2s var(--ease-smooth), border-color 0.2s var(--ease-smooth);
  }
  .btn.ghost:hover { background: rgba(0,151,178,0.08); border-color: rgba(0,151,178,0.6); }
  .btn.sm { padding: 7px 14px; font-size: 0.8rem; }

  /* ── 2b media band: footage beneath the nav, claim centred on the film ── */
  /* nav (~62px) + band = exactly one viewport */
  .band { position: relative; height: clamp(540px, calc(100svh - 62px), 1000px); overflow: hidden; background: var(--card); }
  .band video, .band .fallback { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  /* Held transparent until the first frame exists, so the gradient shows
     through while it buffers rather than a black rectangle appearing over it. */
  .band video { opacity: 0; transition: opacity 0.8s var(--ease-smooth); }
  .band video.ready { opacity: 1; }
  .band .fallback {
    background:
      radial-gradient(120% 90% at 85% 15%, rgba(0,151,178,0.22), transparent 55%),
      radial-gradient(90% 80% at 15% 85%, rgba(0,122,145,0.16), transparent 60%),
      linear-gradient(160deg, #0d1214 0%, #080809 70%);
    background-size: 160% 160%;
  }
  @media (prefers-reduced-motion: no-preference) {
    .band .fallback { animation: drift 16s var(--ease-in-out) infinite alternate; }
    @keyframes drift { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }
  }
  /* Centred claim: scrim darkens evenly rather than from one edge. */
  .band .scrim {
    position: absolute; inset: 0;
    background:
      radial-gradient(130% 85% at 50% 45%, rgba(8,8,9,0.42) 0%, rgba(8,8,9,0.74) 100%),
      linear-gradient(180deg, rgba(8,8,9,0.55) 0%, transparent 26%, transparent 62%, rgba(8,8,9,0.92) 100%);
  }
  .band .content {
    position: relative; z-index: 2; height: 100%;
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    text-align: center; padding-bottom: 20px;
  }
  .band h1 {
    /* The one place the display face is allowed to be loud. */
    font-size: clamp(2.7rem, 7vw, 5.2rem); font-weight: 800; letter-spacing: -0.045em;
    line-height: 0.98; margin: 0 0 16px; max-width: 16ch; color: #fff; text-wrap: balance;
    text-shadow: 0 2px 24px rgba(0,0,0,0.5);
  }
  .band p.sub {
    color: rgba(255,255,255,0.88); margin: 0 0 34px; font-size: 1.1rem; max-width: 48ch;
    text-shadow: 0 1px 12px rgba(0,0,0,0.5);
  }

  /* Email capture: one unified control on the film, not a floating pair. */
  form.cta {
    display: flex; width: 100%; max-width: 620px; border-radius: 8px; overflow: hidden;
    background: rgba(8,8,9,0.62); backdrop-filter: blur(8px);
    box-shadow: 0 0 0 1.5px rgba(255,255,255,0.22), 0 10px 30px rgba(0,0,0,0.45);
    transition: box-shadow 0.2s var(--ease-smooth);
  }
  form.cta:focus-within { box-shadow: 0 0 0 2px var(--brand), 0 10px 30px rgba(0,0,0,0.45); }
  form.cta input[type="email"] {
    flex: 1; min-width: 0; background: transparent; border: none; color: #fff;
    padding: 16px 18px; font-family: var(--font); font-size: 0.98rem; outline: none;
  }
  form.cta input::placeholder { color: rgba(255,255,255,0.5); }
  form.cta .btn {
    border-radius: 0; padding: 16px 26px; font-size: 0.9rem;
    letter-spacing: 0.03em; flex-shrink: 0;
  }
  .band .fine {
    color: rgba(255,255,255,0.7); font-size: 0.8rem; margin: 14px 0 0;
    display: flex; gap: 14px; align-items: center; flex-wrap: wrap; justify-content: center;
  }
  .band .fine i {
    width: 6px; height: 6px; border-radius: 50%; background: var(--pass); display: inline-block;
    margin-right: 7px; vertical-align: middle;
  }
  @media (prefers-reduced-motion: no-preference) {
    .band .fine i { animation: blink 2.4s var(--ease-in-out) infinite; }
    @keyframes blink { 50% { opacity: 0.35; } }
  }

  /* Closing CTA reuses form.cta on a flat surface, so soften the film styling. */
  .closing form.cta { margin: 0 auto; background: var(--card); backdrop-filter: none; }
  .closing form.cta input[type="email"] { color: var(--text); }
  .closing form.cta input::placeholder { color: var(--hint); }

  /* stat strip — every number says what it counts and where it came from */
  .statsblock { padding: 56px 0 0; }
  .statshead { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-bottom: 14px; }
  .statshead h2 { font-size: 1.15rem; margin: 0; }
  .statshead .mono { font-size: 0.72rem; color: var(--label); }
  .stats { display: flex; gap: 12px; justify-content: flex-start; flex-wrap: wrap; }
  .stat {
    background: var(--card); box-shadow: var(--shadow-card); border-radius: 8px;
    padding: 16px 22px 14px; flex: 1 1 200px; text-align: left;
    transition: background-color 0.2s var(--ease-smooth), box-shadow 0.2s var(--ease-smooth), border-color 0.2s var(--ease-smooth);
  }
  .stat:hover { background: var(--elevated); box-shadow: var(--shadow-elevated); }
  .stat .num { font-family: var(--mono); font-size: 1.6rem; color: var(--text); font-variant-numeric: tabular-nums; }
  .stat .num.brand { color: var(--brand); }
  .stat .what { color: var(--text); font-size: 0.86rem; font-weight: 600; margin-top: 2px; }
  .stat .gloss { color: var(--muted); font-size: 0.76rem; line-height: 1.45; margin-top: 3px; }
  .statsfoot { color: var(--muted); font-size: 0.8rem; margin: 14px 0 0; }
  .statsfoot a { color: var(--brand); text-decoration: none; }
  .statsfoot a:hover { text-decoration: underline; }

  /* demo profile — makes MATCH pills and highlighted words self-explaining */
  .demobar {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    background: var(--surface); box-shadow: var(--shadow-card);
    border-radius: 8px; padding: 11px 16px; margin-bottom: 10px;
  }
  .demobar .lead { color: var(--body); font-size: 0.8rem; }
  .demobar .chip { background: rgba(0,151,178,0.1); border-color: rgba(0,151,178,0.3); color: var(--brand); }
  .demobar .tail { color: var(--muted); font-size: 0.8rem; }
  .demobar .tail mark { background: var(--marker-bg); color: var(--marker-tx); padding: 0 3px; border-radius: 3px; }
  .pill.static {
    display: inline-flex; background: rgba(92,186,128,0.12); color: var(--pass);
    font-size: 0.66rem; font-weight: 600; letter-spacing: 0.05em;
    padding: 2px 7px; border-radius: 4px; vertical-align: middle;
  }

  /* ── live ledger ── */
  section.feed { padding: 72px 0 0; }
  .feedhead { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; gap: 16px; }
  .feedhead h2 { font-size: 1.15rem; margin: 0; }
  .feedhead .mono { font-size: 0.72rem; color: var(--label); }
  /* The ledger is the hero object on this page, so it gets its own treatment
     rather than the same 8px card as everything else: tighter corners and a
     teal rail down the left, so it reads as a live register rather than a
     marketing panel. */
  .panel {
    background: var(--card); box-shadow: var(--shadow-card);
    border-radius: 3px; overflow: hidden;
  }
  #ledger { border-left: 2px solid var(--brand); border-radius: 0 3px 0 0; }
  /* Welded to the ledger above it. The old version overlapped two .panel
     elements with a negative margin, which drew each one's hairline shadow
     ring across the join as a visible seam. */
  .ledgerfoot {
    background: var(--surface); border-left: 2px solid var(--brand);
    border-radius: 0 0 3px 0; box-shadow: var(--shadow-card);
  }
  .row {
    display: grid; grid-template-columns: 92px 1fr auto auto; gap: 4px 24px; align-items: center;
    padding: 15px 20px; border-top: 1px solid var(--border-subtle);
    text-decoration: none; transition: background-color 0.2s var(--ease-smooth);
  }
  .row:first-child { border-top: none; }
  .row:hover { background: var(--elevated); }
  .row .pill {
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(92,186,128,0.12); color: var(--pass);
    font-size: 0.68rem; font-weight: 600; letter-spacing: 0.05em;
    padding: 3px 8px; border-radius: 4px;
  }
  .row .t { color: var(--text); font-weight: 600; font-size: 0.95rem; }
  .row .t mark { background: var(--marker-bg); color: var(--marker-tx); padding: 0 3px; border-radius: 3px; }
  .row .m { color: var(--muted); font-size: 0.78rem; }
  /* arrival time lives with the other time info, so the pill column keeps one
     vocabulary: MATCH or nothing */
  .row .m .justin { color: var(--brand); font-weight: 600; }
  .row .v { font-family: var(--mono); color: var(--text); font-size: 0.95rem; text-align: right; }
  .row .d { font-family: var(--mono); font-size: 0.72rem; color: var(--muted); text-align: right; min-width: 76px; }
  .row .d.soon { color: var(--fail); font-weight: 600; }
  @media (prefers-reduced-motion: no-preference) {
    .row.slidein { animation: slidein 0.5s var(--ease-out); }
    @keyframes slidein {
      from { opacity: 0; transform: translateY(-12px); background: rgba(0,151,178,0.08); }
      to { opacity: 1; transform: none; }
    }
    .row.slidein .pill { animation: pop 0.45s var(--ease-spring) 0.25s backwards; }
    @keyframes pop {
      from { opacity: 0; transform: scale(0.6); }
      to { opacity: 1; transform: scale(1); }
    }
  }
  .feedfoot { display: flex; justify-content: space-between; gap: 16px; padding: 13px 20px; border-top: 1px solid var(--border); font-size: 0.8rem; color: var(--muted); }
  .feedfoot a { color: var(--brand); text-decoration: none; }
  .feedfoot a:hover { text-decoration: underline; }

  /* ── steps ── */
  section.how { padding: 88px 0 0; }
  .sectionhead { text-align: center; margin-bottom: 40px; }
  .sectionhead h2 { font-size: 1.7rem; letter-spacing: -0.025em; margin: 0 0 8px; }
  .sectionhead p { color: var(--muted); margin: 0; }
  /* One vertical track the eye follows down, not three floating cards. The
     card chrome is gone deliberately: marketing prose reads better on the page
     ground with strong type than boxed, and boxing everything identically is
     what flattens a generated page into one texture. */
  .track { list-style: none; margin: 0; padding: 0; max-width: 720px; }
  .leg { position: relative; padding: 0 0 38px 42px; }
  .leg:last-child { padding-bottom: 0; }
  /* The connecting rail. Drawn on the marker, not the item, so it stops
     cleanly at the last node instead of trailing into the next section. */
  .leg::before {
    content: ""; position: absolute; left: 7px; top: 20px; bottom: -4px;
    width: 1px; background: linear-gradient(var(--brand), rgba(0,151,178,0.06));
  }
  .leg:last-child::before { display: none; }
  .legmark {
    position: absolute; left: 0; top: 6px; width: 15px; height: 15px;
    border-radius: 50%; border: 2px solid var(--brand); background: var(--bg);
  }
  /* The text column beside the marker. Declared rather than left bare so the
     class is not a hook that reads as intentional and does nothing. */
  .legbody { min-width: 0; }
  .leg .n {
    font-family: var(--mono); font-size: 0.7rem; color: var(--brand);
    display: block; margin-bottom: 8px; letter-spacing: 0.06em;
  }
  .leg h3 { font-size: 1.15rem; margin: 0 0 8px; }
  .leg p { color: var(--muted); font-size: 0.92rem; margin: 0; max-width: 58ch; }
  .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
  .chip {
    background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.08);
    color: var(--muted); font-size: 0.7rem; font-weight: 500; padding: 2px 8px; border-radius: 4px;
  }
  /* The sample verdict is specimen content: show it as the artifact the
     product actually produces, not as an italic pull-quote. */
  .verdict {
    margin: 14px 0 0; padding: 0; max-width: 54ch;
    background: var(--card); box-shadow: var(--shadow-card); border-radius: 6px; overflow: hidden;
  }
  .verdict figcaption {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 8px 13px; background: var(--surface);
    box-shadow: inset 0 -1px 0 rgba(255,255,255,0.06);
  }
  .verdict .vlabel {
    font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.11em;
    color: var(--label); text-transform: uppercase;
  }
  .verdict .vscore { font-size: 0.72rem; font-weight: 700; color: var(--pass); }
  .verdict blockquote {
    margin: 0; padding: 12px 13px; font-size: 0.88rem; color: var(--body); line-height: 1.55;
  }

  /* ── pricing ── */
  section.pricing { padding: 88px 0 0; }
  .plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: stretch; }
  /* Grid alignment, not a magic height. min-height only worked while every
     string happened to wrap to the same number of lines; between ~820px and
     ~945px the longest one took a third line and knocked that card out of
     step. Rows do the job at any width. */
  .plan { display: grid; grid-template-rows: auto auto auto 1fr auto; }
  .plan-for { color: var(--label); font-size: 0.82rem; margin: 6px 0 0; }
  /* Team is real enough to compare against, but recessed: it cannot be bought
     today, and a card indistinguishable from Pro would have implied it could. */
  /* Placed after .plan:hover below would be fragile; scope it instead so the
     recession survives hover. A card you cannot buy must not light up like
     one you can, least of all at the moment the cursor is on it. */
  .plan.soon, .plan.soon:hover { background: var(--surface); box-shadow: var(--shadow-card); transform: none; }
  .plan.soon .price { color: var(--muted); }
  .plan-note { color: var(--hint); font-size: 0.82rem; margin: 16px 0 0; }
  .plan {
    background: var(--card); box-shadow: var(--shadow-card); border-radius: 8px;
    padding: 26px 24px; display: flex; flex-direction: column;
    transition: background-color 0.2s var(--ease-smooth), box-shadow 0.2s var(--ease-smooth), transform 0.3s var(--ease-smooth);
  }
  .plan:hover { background: var(--elevated); box-shadow: var(--shadow-elevated); transform: translateY(-2px); }
  .plan.pro { box-shadow: var(--shadow-elevated), 0 0 0 1px rgba(0,151,178,0.4); background: var(--elevated); position: relative; }
  .plan { position: relative; }
  .plan .flag {
    position: absolute; top: -11px; left: 20px;
    /* --brand-solid, not --brand: white on #0097b2 is 3.46:1, and at 10px bold
       this is nowhere near "large text", so it needs the full 4.5:1. The token
       exists for exactly this and the portal already uses it here. */
    background: var(--brand-solid); color: #fff; font-size: 0.7rem; font-weight: 700;
    letter-spacing: 0.08em; padding: 3px 9px; border-radius: 4px;
    /* One line, always. "DAILY ALERTS + AI VERDICTS" is 37% longer than the
       string this was sized for, and a badge that wraps at top:-11px overlaps
       the plan heading beneath it. */
    white-space: nowrap; max-width: calc(100% - 40px);
    overflow: hidden; text-overflow: ellipsis;
  }
  /* Team's flag states a limitation, so it must not wear the brand colour and
     read as a recommendation. #a6a6b0 on #171719 is 6.4:1. */
  /* --elevated on --surface is ~1.08:1, so the pill had no visible shape at
     all next to Pro's solid teal. A real border gives it one without
     borrowing the brand colour, which would read as a recommendation. */
  .plan .flag.muted {
    background: var(--card); color: var(--muted);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.18);
  }
  .plan h3 { margin: 0; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); }
  .plan .price { font-family: var(--mono); font-size: 2rem; color: var(--text); margin: 12px 0 2px; }
  .plan .price small { font-size: 0.8rem; color: var(--label); font-family: var(--font); }
  .plan ul { list-style: none; margin: 16px 0 24px; padding: 0; display: grid; gap: 9px; font-size: 0.87rem; }
  .plan li { padding-left: 18px; position: relative; }
  /* content: "→" / "" gives the arrow empty alternative text, so a screen
     reader announces the list item instead of prefixing every line with
     "right arrow". app.css already does this for the same pattern. */
  .plan li::before { content: "→" / ""; position: absolute; left: 0; color: var(--brand); }
  .plan .spacer { flex: 1; }

  /* ── FAQ ── */
  section.faq { padding: 88px 0 0; }
  /* Ledger rows, not stacked cards. Each question is a line in a register
     with a hairline between, which is the page's own vocabulary; a column of
     identical rounded cards with a +/- marker is the stock component. */
  .faqlist { max-width: 720px; }
  .faqlist details {
    border-top: 1px solid var(--border);
    transition: background-color 0.2s var(--ease-smooth);
  }
  .faqlist details:last-of-type { border-bottom: 1px solid var(--border); }
  .faqlist details[open] { background: rgba(255,255,255,0.014); }
  .faqlist summary {
    cursor: pointer; padding: 16px 4px; list-style: none;
    color: var(--text); font-weight: 600; font-size: 0.95rem;
    display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
    transition: color 0.2s var(--ease-smooth);
  }
  .faqlist summary:hover { color: var(--brand); }
  .faqlist summary::-webkit-details-marker { display: none; }
  /* A rotating caret rather than swapping "+" for a dash: one glyph that
     moves reads as a control, two glyphs that replace each other read as
     text changing. Empty alt text so it is never announced. */
  .faqlist summary::after {
    content: "›" / ""; color: var(--brand); font-size: 1.25rem; line-height: 1;
    transform: rotate(90deg); transform-origin: center;
    transition: transform 0.28s var(--ease-smooth); flex-shrink: 0;
  }
  .faqlist details[open] summary::after { transform: rotate(270deg); }
  .faqlist details p {
    margin: 0; padding: 0 4px 18px; color: var(--muted); font-size: 0.9rem; max-width: 62ch;
  }
  @media (prefers-reduced-motion: no-preference) {
    .faqlist details[open] p { animation: faqin 0.3s var(--ease-out); }
    @keyframes faqin { from { opacity: 0; transform: translateY(-4px); } }
  }

  /* ── closing ── */
  .closing { text-align: center; padding: 96px 0 90px; }
  .closing h2 { font-size: clamp(1.6rem, 3.6vw, 2.3rem); letter-spacing: -0.03em; margin: 0 0 10px; max-width: 560px; margin-inline: auto; text-wrap: balance; }
  .closing h2 em { font-style: normal; color: var(--fail); }
  .closing p { color: var(--muted); margin: 0 0 30px; }
  footer { border-top: 1px solid var(--border); padding: 34px 0 46px; }
  footer .wrap { font-size: 0.75rem; color: var(--hint); }
  .footgrid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 28px 32px; align-items: start; }
  .footlinks { display: grid; gap: 8px; align-content: start; }
  .footlinks a { color: var(--muted); text-decoration: none; transition: color 0.2s var(--ease-smooth); }
  .footlinks a:hover { color: var(--text); }
  .foot-note { margin: 8px 0 0; line-height: 1.6; }
  .foot-legal { grid-column: 1 / -1; border-top: 1px solid var(--border-subtle); padding-top: 18px; }
  @media (max-width: 820px) { .footgrid { grid-template-columns: 1fr; } }

  /* ── legal / long-form pages ── */
  .doc { max-width: 720px; padding: 96px 0 80px; }
  .doc h1 { font-size: clamp(1.9rem, 4vw, 2.5rem); letter-spacing: -0.03em; margin: 0 0 8px; }
  .doc .updated { color: var(--hint); font-size: 0.8rem; margin: 0 0 40px; }
  .doc h2 { font-size: 1.05rem; margin: 36px 0 10px; letter-spacing: -0.01em; }
  .doc p, .doc li { color: var(--body); font-size: 0.95rem; line-height: 1.7; }
  .doc ul { padding-left: 20px; display: grid; gap: 6px; }
  /* Underlined, not colour alone: --brand against the surrounding body text is
     2.56:1, so on these text-heavy legal pages the links were effectively
     undetectable without colour vision (WCAG 1.4.1). */
  .doc a { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
  .doc .callout {
    border: 1px solid var(--border); background: var(--card);
    border-radius: 10px; padding: 16px 18px; margin: 24px 0;
  }
  .doc .callout p { margin: 0; }

  @media (max-width: 820px) {
    .plans { grid-template-columns: 1fr; }
    .row { grid-template-columns: 80px 1fr; }
    .row .v, .row .d { grid-column: 2; text-align: left; }
    /* Keep the two links that are the point of the page. Hiding the whole nav
       left phone visitors — most of the marketing traffic — with no way to log
       in or sign up from the header, and there is no menu button standing in
       for it. Every public page ends this nav with "Log in" then "Start free",
       so the last two survive and the wayfinding links drop. */
    nav.links { gap: 14px; }
    nav.links a:not(:nth-last-child(-n + 2)) { display: none; }
    nav.links a { font-size: 0.8rem; }
  }
