/* Shared marketing-site stylesheet — landing, pricing, feature pages, legal pages.
   Extracted from landing.html on 2026-07-26 so the feature-page family can't drift from it.
   Feature-page-specific components live in the FEATURE PAGES block at the bottom. */

  :root{--font:"Segoe UI",system-ui,-apple-system,Roboto,Arial,sans-serif;
    --green:#2f5c1f; --green-dk:#22461a; --green-lt:#6aaf45; --green-soft:#e9f1e2;
    --green-btn:#3f7a26;   /* same token/value as the app: white on this is 5.2:1 (AA). --green-lt is 2.68:1 and must never sit under white text */
    /* --green-txt / --green-ink are DELIBERATE ALIASES of --green / --green-dk in light — identical
       values, so naming them changed nothing here. They exist because --green does two incompatible
       jobs: it is a FILL under white text (.btn, .ribbon, step bullets) and it is TEXT on a pale
       ground (links, .stat b, .plan h3). In dark those pull opposite ways — the fill must stay dark
       enough for white text, the ink must go light enough to read on a dark card — so the two jobs
       need two tokens. Same split the app made (--green vs --green-txt). Use --green-txt wherever
       the value ends up as INK, --green wherever it ends up as a FILL. */
    --green-txt:#2f5c1f; --green-ink:#22461a;
    --green-ln:#d6e6c9;    /* border of a --green-soft tinted block (.glance) */
    --ink:#16180f; --muted:#5a6152; --line:#e6e8e0; --bg:#ffffff; --soft:#f6f8f2;
    /* Surfaces. --bg is the PAGE; --card is anything that floats on it (cards, plans, the mega-menu,
       the screenshot frame). Both are white in light — which is exactly why the distinction was
       never written down and had to be recovered here: in dark a card has to sit LIGHTER than the
       page, or the whole grid melts into one flat rectangle. */
    --card:#ffffff;
    --line-hi:#d6dccd;     /* card hover border */
    --line-hi2:#d0d8c5;    /* open <details> border — a shade tighter than --line-hi in light */
    --glass:rgba(255,255,255,.86);      /* sticky header, blurred */
    --bar:#eef1ea; --bar-dot:#ccd2c4;   /* the fake browser chrome above the hero screenshot */
    --note-bg:#fdf6e6;     /* .legal .note — amber wash */
    /* Amber "check this" badge, used by pathways.html / cdc-workflow.html. #7a6015 on #faf3dc is
       5.39:1 (the 2026-07-31 styleguard fix); tokenised here so dark gets a matching pair instead
       of a cream block glaring off the page. */
    --warn-tx:#7a6015; --warn-bg:#faf3dc; --warn-ln:#eadfba;
    /* The "why" band is a green FIELD with white text on it. It must NOT follow --green/--green-dk
       into dark: those get lighter so a button fill stays visible, which would drop this band's own
       body copy under 4.5:1. Its own tokens go the other way — darker. */
    --why-1:#22461a; --why-2:#2f5c1f;
    --hero-wash:rgba(106,175,69,.20);
    --amber:#c98a00; --radius:16px; --shadow:0 1px 2px rgba(0,0,0,.04),0 12px 34px rgba(0,0,0,.08);
    --shadow-lg:0 30px 70px rgba(0,0,0,.16);
  }
  /* ---- DARK theme (2026-07-31) -----------------------------------------------------------------
     COLOUR TOKENS ONLY — not one component rule is repeated below. Same discipline, the same storage
     key ('js_theme') and the same pre-paint <head> script as the app, so a choice made on the map
     carries to the marketing site and back with no white frame at either hop.
     Absent on purpose: --green-btn (a filled CTA must keep white text at 4.5:1, so it cannot get
     lighter), --font, --radius. */
  [data-theme="dark"]{
    color-scheme:dark;
    --bg:#0b0f0c;
    --soft:#141a15;        /* full-bleed tinted bands (.trust, .persona, .final, table headers) —
                              a touch LIGHTER than the page, because "recessed" inverts in dark */
    --card:#171e18;        /* lifts off both --bg and --soft; the border does the rest */
    --line:#2b342d; --line-hi:#3f4b41; --line-hi2:#3f4b41;
    --ink:#f0f5ef;         /* 15.4:1 on --card */
    --muted:#93a195;       /* 6.3:1 on --card, 6.5:1 on --soft, 7.2:1 on --bg — this token carries
                              most of the marketing body copy, so it is sized for the worst ground */
    --green:#45802a;       /* FILL: white on it is 4.8:1, and it is 3.6:1 against --card, so the
                              button still has an edge of its own */
    --green-dk:#2c5c1a;    /* the hover/pressed fill — darker, so white text gains rather than loses */
    --green-txt:#8fd15f;   /* INK: 9.3:1 on --card, 10.5:1 on --bg */
    --green-ink:#9ed474;   /* INK on a --green-soft tint: 8.4:1 */
    --green-lt:#9fd97a;    /* ✓ glyphs and accent hairlines: 9.1:1 on --green-soft */
    --green-soft:#1d2a17; --green-ln:#2e4522;
    --hero-wash:rgba(106,175,69,.13);
    --why-1:#16300f; --why-2:#1f4416;   /* white 11:1, the band's own body copy 8.5:1 */
    --amber:#d9a441; --note-bg:#33290f;
    --warn-tx:#f2cf6a; --warn-bg:#3b3210; --warn-ln:#6d5d20;
    --glass:rgba(11,15,12,.86);
    --bar:#1c231d; --bar-dot:#39433b;
    /* Neutral black, deepened — a shadow on a dark ground has to work harder to read as "floating".
       Never tinted: a coloured glow is not part of this design system. */
    --shadow:0 1px 2px rgba(0,0,0,.5),0 12px 34px rgba(0,0,0,.55);
    --shadow-lg:0 30px 70px rgba(0,0,0,.62);
  }
  *{box-sizing:border-box}
  html{scroll-behavior:smooth}
  body{margin:0;font:16px/1.62 var(--font);color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased}
  a{color:var(--green-txt);text-decoration:none}
  .wrap{max-width:1160px;margin:0 auto;padding:0 24px}
  h1,h2,h3{letter-spacing:-.02em}

  .btn{display:inline-flex;align-items:center;gap:8px;background:var(--green);color:#fff;font-family:inherit;font-weight:650;padding:12px 22px;border-radius:11px;border:1px solid var(--green);cursor:pointer;transition:transform .16s ease,box-shadow .16s ease,background .16s ease;box-shadow:0 2px 8px rgba(0,0,0,.18)}
  .btn:hover{background:var(--green-dk);transform:translateY(-2px);box-shadow:0 10px 22px rgba(0,0,0,.24)}
  .btn.ghost{background:var(--card);color:var(--green-txt);box-shadow:none}
  .btn.ghost:hover{background:var(--soft);border-color:var(--green)}
  .btn.lg{padding:15px 30px;font-size:16.5px}

  /* header */
  header{position:sticky;top:0;z-index:60;background:var(--glass);backdrop-filter:blur(10px);border-bottom:1px solid transparent;transition:border-color .2s,box-shadow .2s}
  header.scrolled{border-color:var(--line);box-shadow:0 4px 20px rgba(0,0,0,.05)}
  .nav{display:flex;align-items:center;gap:26px;height:66px}
  .brand{display:flex;align-items:center;gap:10px;font-weight:750;font-size:18px;color:var(--ink)}
  /* Gradient stops at --green-btn, NOT --green-lt: the white 800 wordmark covers the full tile and
     white on --green-lt (#6aaf45) is 2.68:1, failing WCAG 1.4.3. Same fix the app made in its
     2026-07-25 audit — this is now identical to index.html's `.brand .logo`. The green-tinted drop
     shadow is gone with it: shadows are neutral and only mean "this floats". */
  .logo{width:30px;height:30px;border-radius:8px;background:linear-gradient(135deg,var(--green),var(--green-btn));color:#fff;display:grid;place-items:center;font-weight:800;font-size:13px}
  .nav .spacer{flex:1}
  /* min-height 34px: these measured 23px, under the 24px WCAG 2.5.8 AA floor, and 34px is also the
     height every control in the app's topbar uses — so the two headers now agree on target size too. */
  .nav a.link{color:var(--muted);font-weight:600;font-size:14.5px;transition:color .15s;
    display:inline-flex;align-items:center;min-height:34px}
  .nav a.link:hover{color:var(--green-txt)}
  /* ---- theme toggle -------------------------------------------------------------------------
     Same idiom, same class names and the same `js_theme` key as the app's topbar toggle, so the
     control is recognisably the same one on both sides of the site.
     The GLYPH comes from CSS, not from JS, and that is the point: marketing.js is `defer`red, so a
     script that wrote the character would paint ☾ on an already-dark page for a frame. An attribute
     selector on <html> — which the pre-paint <head> script has already set — is correct on the very
     first frame. marketing.js owns only the ARIA state, which no frame depends on.
     34x34 clears the 24px WCAG 2.5.8 floor and matches the height of every other control in this
     bar. It is a <button>, not an `a.link`, so the 820px rule above does not hide it on a phone. */
  .nav .themeBtn{display:inline-flex;align-items:center;justify-content:center;
    min-width:34px;min-height:34px;padding:0 8px;margin:0;
    font:inherit;font-size:15px;line-height:1;color:var(--muted);
    background:none;border:1px solid transparent;border-radius:9px;cursor:pointer;
    transition:color .15s,background .15s,border-color .15s}
  .nav .themeBtn:hover{color:var(--green-txt);background:var(--soft);border-color:var(--line)}
  .nav .themeBtn:focus-visible{outline:2px solid var(--green-txt);outline-offset:2px}
  .nav .themeBtn .themeIco::before{content:"☾"}
  [data-theme="dark"] .nav .themeBtn .themeIco::before{content:"☀"}
  @media(max-width:820px){ .nav a.link:not(.login){display:none} .nav{gap:14px} }
  /* Phone: at 375 the brand, "Log in" and the CTA all wrapped onto two lines and the button
     overflowed the 66px bar (measured 2026-07-31). Shrink + nowrap so the bar stays one line.
     That fix left the bar with ~3px of slack, so ADDING the theme toggle (2026-07-31) pushed it
     16.6px past the viewport and the whole page scrolled sideways — measured, not guessed. Rather
     than drop the "Log in" link or the wordmark, every item gives back a few px: the row now ends
     ~15px inside the right gutter at 375 with nothing removed. Re-measure if anything is added. */
  @media(max-width:480px){
    .nav{gap:8px}
    .brand{font-size:15px;gap:8px;white-space:nowrap}
    .nav a.link{white-space:nowrap}
    .nav .themeBtn{min-width:28px;padding:0 2px}
    .nav .btn{padding:9px 12px;font-size:15px;white-space:nowrap}
  }

  /* ---- Features mega-menu -------------------------------------------------------------------
     Opens on hover AND on focus/click, so it is reachable by keyboard and on touch. The trigger
     stays a real link to /features/ — the menu is an accelerator, never the only way in. Escape
     closes; marketing.js handles the click/Escape half and sets aria-expanded. */
  .navdrop{position:relative;display:flex;align-items:center}
  .navdrop > .link{display:inline-flex;align-items:center;gap:5px}
  .navdrop .caret{font-size:10px;transition:transform .18s ease;opacity:.7}
  .navdrop.open > .link{color:var(--green-txt)}
  .navdrop.open .caret{transform:rotate(180deg)}
  .ndmenu{position:absolute;top:calc(100% + 10px);left:-24px;z-index:70;
    width:min(860px,calc(100vw - 48px));
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-lg);
    padding:22px;display:grid;grid-template-columns:repeat(3,1fr);gap:8px 26px;
    opacity:0;visibility:hidden;transform:translateY(-6px);
    transition:opacity .18s ease,transform .18s ease,visibility .18s}
  .navdrop:hover .ndmenu,.navdrop.open .ndmenu{opacity:1;visibility:visible;transform:none}
  /* invisible bridge so the pointer can cross the gap from trigger to menu without it closing */
  .ndmenu::before{content:"";position:absolute;top:-12px;left:0;right:0;height:12px}
  .ndcol > b{display:block;font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;
    color:var(--green-txt);margin:0 0 6px;padding:0 10px}
  .ndmenu a{display:flex;gap:10px;align-items:flex-start;padding:9px 10px;border-radius:10px;
    transition:background .14s ease}
  .ndmenu a:hover,.ndmenu a:focus-visible{background:var(--soft)}
  .ndmenu a .ndi{flex:0 0 auto;font-size:15px;line-height:1.35}
  .ndmenu a i{font-style:normal;display:block;color:var(--ink);font-weight:640;font-size:14px}
  .ndmenu a em{font-style:normal;display:block;color:var(--muted);font-size:12.5px;line-height:1.4}
  .ndall{grid-column:1/-1;border-top:1px solid var(--line);margin-top:8px;padding-top:12px}
  .ndall a{justify-content:center;font-weight:650;color:var(--green-txt)}
  @media(max-width:1080px){ .ndmenu{grid-template-columns:repeat(2,1fr);width:min(600px,calc(100vw - 48px))} }
  @media(max-width:820px){ .navdrop{display:none} }
  @media(prefers-reduced-motion:reduce){ .ndmenu{transition:none} .navdrop .caret{transition:none} }

  /* hero */
  /* --hero-wash is the brand haze in the top-right corner. It is a BACKGROUND, not a shadow, so it
     is allowed to carry the green — but it is dialled back in dark, where the same alpha over a
     near-black ground reads as a glow rather than a wash. */
  .hero{position:relative;overflow:hidden;background:radial-gradient(900px 460px at 82% -8%,var(--hero-wash),transparent 60%),linear-gradient(180deg,var(--soft),var(--bg) 70%)}
  /* NOTE: these elements also carry `.wrap`, whose 24px side gutters a `padding:X 0 Y`
     shorthand silently zeroes — invisible at 1440 (margin:auto centring) but text sat flush
     against the screen edge at 375 (found 2026-07-31). Keep the 24px sides explicit. */
  .hero-grid{display:grid;grid-template-columns:1.04fr .96fr;gap:52px;align-items:center;padding:76px 24px 84px}
  @media(max-width:920px){ .hero-grid{grid-template-columns:1fr;gap:38px;padding:54px 24px 60px} }
  .eyebrow{display:inline-flex;align-items:center;gap:8px;background:var(--green-soft);color:var(--green-ink);font-weight:700;font-size:13px;padding:6px 13px;border-radius:20px;margin-bottom:20px}
  .eyebrow .dot{width:7px;height:7px;border-radius:50%;background:var(--green-lt)}
  .hero h1{font-size:clamp(34px,4.6vw,54px);line-height:1.04;margin:0 0 20px}
  .hero h1 span{color:var(--green-txt);background:linear-gradient(120deg,var(--green-txt),var(--green-lt));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
  .hero .lead{font-size:19.5px;color:var(--muted);max-width:560px;margin:0 0 30px}
  .hero .cta{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
  .hero .fine{margin-top:16px;color:var(--muted);font-size:14px;display:flex;gap:14px;flex-wrap:wrap}
  .hero .fine b{color:var(--ink);font-weight:600}
  .shot-frame{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow-lg);background:var(--card);transform:translateZ(0)}
  .shot-frame .bar{height:34px;background:var(--bar);display:flex;align-items:center;gap:6px;padding:0 13px;border-bottom:1px solid var(--line)}
  .shot-frame .bar i{width:11px;height:11px;border-radius:50%;background:var(--bar-dot);display:inline-block}
  .shot-frame img{display:block;width:100%;height:auto}

  /* stats */
  .stats{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--bg)}
  .stats .row{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;padding:26px 0;text-align:center}
  @media(max-width:700px){ .stats .row{grid-template-columns:repeat(2,1fr);gap:22px} }
  .stat b{display:block;font-size:26px;font-weight:800;color:var(--green-txt);letter-spacing:-.02em}
  .stat span{font-size:13.5px;color:var(--muted)}

  /* trust */
  .trust{background:var(--soft);padding:22px 0}
  .trust .row{display:flex;gap:12px 26px;flex-wrap:wrap;align-items:center;justify-content:center;color:var(--muted);font-size:13.5px;font-weight:600}
  .trust b{color:var(--ink)}

  section{padding:74px 0}
  .center{text-align:center}
  .eyebrow2{color:var(--green-txt);font-weight:800;letter-spacing:.08em;text-transform:uppercase;font-size:12.5px;margin:0 0 10px}
  h2{font-size:clamp(27px,3.4vw,40px);line-height:1.13;margin:0 0 14px}
  .sub{color:var(--muted);font-size:18px;max-width:620px;margin:0 0 40px}
  .center .sub{margin-left:auto;margin-right:auto}
  .grid{display:grid;gap:18px}
  .g2{grid-template-columns:repeat(2,1fr)} .g3{grid-template-columns:repeat(3,1fr)} .g4{grid-template-columns:repeat(4,1fr)}
  @media(max-width:900px){ .g3,.g4{grid-template-columns:repeat(2,1fr)} }
  @media(max-width:560px){ .g2,.g3,.g4{grid-template-columns:1fr} }
  .card{border:1px solid var(--line);border-radius:var(--radius);padding:24px;background:var(--card);transition:transform .18s ease,box-shadow .18s ease,border-color .18s}
  .card:hover{transform:translateY(-4px);box-shadow:var(--shadow);border-color:var(--line-hi)}
  .card h3{margin:0 0 6px;font-size:18px}
  .card p{margin:0;color:var(--muted);font-size:15px}
  .card .ic{width:44px;height:44px;border-radius:12px;background:var(--green-soft);display:grid;place-items:center;font-size:21px;margin-bottom:14px}

  /* how it works */
  .steps{counter-reset:step}
  .steps .card{position:relative;padding-top:30px}
  .steps .card:before{counter-increment:step;content:counter(step);position:absolute;top:-16px;left:24px;width:34px;height:34px;border-radius:50%;background:var(--green);color:#fff;font-weight:800;display:grid;place-items:center;box-shadow:0 4px 12px rgba(0,0,0,.3)}

  .persona{background:var(--soft)}
  .persona .tag{display:inline-block;font-size:12px;font-weight:800;color:var(--green-ink);background:var(--green-soft);border-radius:20px;padding:3px 11px;margin-bottom:11px}
  .persona .card ul{margin:11px 0 0;padding-left:18px;color:var(--muted);font-size:14.5px}
  .persona .card li{margin:4px 0}

  .why{background:linear-gradient(135deg,var(--why-1),var(--why-2));color:#fff}
  .why .eyebrow2{color:#bfe0ac} .why h2{color:#fff} .why .sub{color:#d6e6cd}
  .why .card{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.16)}
  .why .card:hover{background:rgba(255,255,255,.13);box-shadow:0 18px 40px rgba(0,0,0,.2)}
  .why .card h3{color:#fff} .why .card p{color:#d6e6cd}

  /* pricing */
  .price-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;align-items:stretch}
  @media(max-width:860px){ .price-grid{grid-template-columns:1fr;max-width:420px;margin:0 auto} }
  .plan{border:1px solid var(--line);border-radius:var(--radius);padding:28px;display:flex;flex-direction:column;background:var(--card);transition:transform .18s,box-shadow .18s}
  .plan:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
  .plan.feat{border:2px solid var(--green);box-shadow:var(--shadow);position:relative}
  .plan .ribbon{position:absolute;top:-13px;left:28px;background:var(--green);color:#fff;font-size:12px;font-weight:800;padding:4px 13px;border-radius:20px;box-shadow:0 4px 12px rgba(0,0,0,.3)}
  .plan h3{margin:0;font-size:20px;color:var(--green-txt)}
  .plan .amt{font-size:36px;font-weight:800;margin:10px 0 0;letter-spacing:-.02em}
  .plan .amt small{font-size:14px;font-weight:500;color:var(--muted)}
  .plan .peryr{font-size:13px;color:var(--muted);margin-bottom:6px}
  .plan ul{list-style:none;padding:0;margin:16px 0;flex:1}
  .plan li{padding:7px 0 7px 26px;position:relative;font-size:14.5px}
  .plan li:before{content:"";position:absolute;left:0;top:11px;width:15px;height:9px;border-left:2.5px solid var(--green);border-bottom:2.5px solid var(--green);transform:rotate(-45deg)}
  .plan .btn{justify-content:center}

  /* faq */
  .faq details{border:1px solid var(--line);border-radius:12px;padding:2px 20px;margin-bottom:12px;background:var(--card);transition:border-color .15s}
  .faq details[open]{border-color:var(--line-hi2);box-shadow:var(--shadow)}
  .faq summary{cursor:pointer;font-weight:650;padding:16px 0;list-style:none;display:flex;justify-content:space-between;align-items:center;font-size:16px}
  .faq summary::-webkit-details-marker{display:none}
  .faq summary:after{content:"+";color:var(--green-txt);font-size:22px;font-weight:400;transition:transform .2s}
  .faq details[open] summary:after{transform:rotate(45deg)}
  .faq p{margin:0 0 18px;color:var(--muted);font-size:15px}

  /* final */
  .final{background:linear-gradient(180deg,var(--bg),var(--soft));text-align:center}
  .final h2{margin-bottom:12px}
  .final .sub{margin:0 auto 28px}

  footer{border-top:1px solid var(--line);padding:46px 0 34px;color:var(--muted);font-size:14px}
  footer .cols{display:flex;flex-wrap:wrap;gap:34px;justify-content:space-between;margin-bottom:26px}
  footer b{color:var(--ink)}
  footer .cols a{color:var(--muted);display:block;padding:6px 0;transition:color .15s}   /* block = one link per ROW (stacked column + bigger tap targets); inline-block ran them together — "Launch appHow it worksFeatures" with 0px between tap targets, measured 2026-07-31 at 320 AND 1440 */
  footer .cols a.brand{display:flex;color:var(--ink)}   /* brand stays a row, not a stacked link */
  footer .disc a{display:inline;color:var(--green-txt)}      /* inline links flow inside the paragraph */
  footer a:hover{color:var(--green-txt)}
  footer .disc{border-top:1px solid var(--line);padding-top:18px;font-size:12.5px;line-height:1.55}

  /* scroll reveal */
  .reveal{opacity:0;transform:translateY(18px);transition:opacity .6s ease,transform .6s ease}
  .reveal.in{opacity:1;transform:none}
  @media(prefers-reduced-motion:reduce){ .reveal{opacity:1;transform:none;transition:none} html{scroll-behavior:auto} }

/* ============================================================================
   FEATURE PAGES  (/features/*.html)
   One page per capability. Landchecker's equivalents are SEO long-form with no
   hero CTA, no cross-links and no closing CTA band; we keep the long-form depth
   but graft conversion back on — hero CTA pair, related-features grid, CTA band.
   ========================================================================== */

/* breadcrumb */
.crumb{font-size:14px;color:var(--muted);padding:18px 0 0}
/* The breadcrumb link is a real navigation target, so it gets a real 24x24 one (WCAG 2.5.8) rather
   than leaning on the "inline in a sentence" exception — it measured 36x17 on 20 pages (styleguard
   sweep 2026-07-31). inline-block + a tight line-height so the padding lands the box just over 24px
   without inflating the crumb row: 16.8 line + 8 padding = 24.8. A pseudo-element hit area was the
   alternative, but it leaves the element's own box at 17px — invisible to the guard, and to anything
   else that measures the target rather than the paint. */
.crumb a{color:var(--muted);display:inline-block;line-height:1.2;padding:4px 2px}
.crumb a:hover{color:var(--green-txt);text-decoration:underline}
.crumb span{margin:0 6px;opacity:.5}

/* hero — narrower than the landing hero; copy-led, no screenshot beside it */
.fhero{background:linear-gradient(180deg,var(--soft),var(--bg));border-bottom:1px solid var(--line)}
.fhero .wrap{padding:26px 24px 54px}  /* 24px sides: see .hero-grid gutter note */
.fhero h1{font-size:clamp(30px,5vw,50px);line-height:1.08;letter-spacing:-.02em;margin:12px 0 14px;max-width:16ch}
.fhero .lead{font-size:clamp(17px,2vw,20px);color:var(--muted);max-width:60ch;margin:0 0 26px}
.fhero .cta{display:flex;gap:12px;flex-wrap:wrap}

/* "at a glance" — the scannable spec summary, before the long-form explainer */
.glance{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;
  background:var(--green-soft);border:1px solid var(--green-ln);border-radius:var(--radius);padding:22px}
.glance h3{grid-column:1/-1;margin:0;font-size:15px;letter-spacing:.04em;text-transform:uppercase;color:var(--green-ink)}
.glance div{display:flex;gap:9px;align-items:flex-start;font-size:15px;line-height:1.5}
.glance div::before{content:"✓";color:var(--green-lt);font-weight:800;flex:0 0 auto}

/* alternating text/figure rows */
.frow{display:grid;grid-template-columns:1fr 1fr;gap:46px;align-items:center;margin:56px 0}
.frow:nth-child(even) .ftext{order:2}
.frow h2{font-size:clamp(23px,3vw,32px);line-height:1.18;letter-spacing:-.01em;margin:0 0 12px}
.frow p{color:var(--muted);margin:0 0 12px}
.ffig{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow);background:var(--soft)}
.ffig img{display:block;width:100%;height:auto}
.ffig .cap{font-size:13px;color:var(--muted);padding:10px 14px;border-top:1px solid var(--line);background:var(--card)}

/* Panel captures are UI crops taken at 1× (300–350 px wide). Stretching one to fill the figure
   column blurs it, so these float at natural size on a tinted ground instead — sharper, and it
   reads as "this is a panel" rather than "this is a badly scaled photo". */
.ffig.panel{background:linear-gradient(160deg,var(--green-soft),var(--soft));padding:26px 20px;
  display:grid;place-items:center}
.ffig.panel img{width:auto;max-width:100%;border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,.16)}
.ffig.panel .cap{align-self:end;justify-self:stretch;margin:20px -20px -26px;border-radius:0}

/* A band with no figure yet — one full-width prose column instead of a lopsided half-empty row.
   Preferred over shipping an empty placeholder box. */
.frow.noshot{grid-template-columns:1fr;gap:0}
.frow.noshot .ftext{max-width:74ch}

/* Step list — feature pages only.
   MUST stay scoped to `ol.steps`. The landing page's "How it works" is a
   `<div class="wrap grid g3 steps">`, so a bare `.steps` here outranks nothing but *ties* with the
   `.steps{counter-reset:step}` rule above and, being later, wins — which silently took out the
   landing page's centring (`margin:26px 0` beat `.wrap{margin:0 auto}`), its gutters
   (`padding:0` beat `.wrap{padding:0 24px}`) and its step numbers (`counter-reset:s` meant `step`
   was never reset). Same class, two different components. */
ol.steps{counter-reset:s;list-style:none;padding:0;margin:26px 0;display:grid;gap:16px}
ol.steps li{counter-increment:s;display:grid;grid-template-columns:34px 1fr;gap:4px 14px;align-items:start}
/* Each <li> has THREE grid items — ::before, <b> and <span> — in a two-column track, so auto-flow
   put the <span> back in column 1 and wrapped the body text one word per 34px line. Place all
   three explicitly: number spans both rows in col 1, title and body stack in col 2. */
ol.steps li::before{content:counter(s);grid-column:1;grid-row:1/span 2;
  display:grid;place-items:center;width:34px;height:34px;border-radius:50%;
  background:var(--green);color:#fff;font-weight:700;font-size:15px}
ol.steps li > b{grid-column:2;grid-row:1;display:block;align-self:center;min-height:34px;
  display:flex;align-items:center}
ol.steps li > span{grid-column:2;grid-row:2;color:var(--muted)}

/* comparison table */
.ftable{width:100%;border-collapse:collapse;margin:26px 0;font-size:15px}
.ftable th,.ftable td{text-align:left;padding:13px 14px;border-bottom:1px solid var(--line);vertical-align:top}
.ftable th{background:var(--soft);font-size:13px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.ftable td:first-child{font-weight:600}
@media(max-width:640px){.ftable{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}}   /* the 4-column plan table's min-content width is ~415px — without this it forced the WHOLE PAGE to hscroll at 320 (measured 2026-07-31); now the table scrolls within itself */

/* related features */
.frel{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px;margin-top:24px}
.frel a{display:block;padding:18px;border:1px solid var(--line);border-radius:var(--radius);background:var(--card);
  transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}
.frel a:hover{border-color:var(--green-lt);box-shadow:var(--shadow);transform:translateY(-2px)}
.frel b{display:block;color:var(--ink);margin-bottom:4px}
.frel span{color:var(--muted);font-size:14px;line-height:1.5}

/* provenance / caveat note — where the data comes from and what it can't tell you */
.prov{border-left:3px solid var(--green-lt);background:var(--soft);padding:16px 20px;border-radius:0 8px 8px 0;
  font-size:15px;color:var(--muted);margin:26px 0}
.prov b{color:var(--ink)}

@media(max-width:860px){
  .frow{grid-template-columns:1fr;gap:26px;margin:40px 0}
  .frow:nth-child(even) .ftext{order:0}
}

/* ============================================================================
   LEGAL / PRICING PAGES  (terms, privacy, licences, pricing)
   These used to carry their own inline <style> and a green "← back" bar, so
   clicking through from the landing page was a visible change of website.
   They now use the same header, footer and tokens as everything else; only the
   prose column below is page-specific.
   ========================================================================== */
.lhero{background:linear-gradient(180deg,var(--soft),var(--bg));border-bottom:1px solid var(--line)}
.lhero .wrap{padding:26px 24px 34px}  /* 24px sides: see .hero-grid gutter note */
.lhero h1{font-size:clamp(28px,4vw,42px);line-height:1.1;margin:12px 0 10px}
.lhero .meta{color:var(--muted);font-size:15px;margin:0;max-width:70ch}

/* prose column — narrower than the marketing grid; long text wants ~75 characters */
.legal{max-width:820px;padding-top:44px;padding-bottom:8px}
.legal h2{font-size:19px;letter-spacing:-.01em;margin:34px 0 8px}
.legal h2:first-child{margin-top:0}
.legal p{color:var(--muted);margin:0 0 12px}
.legal ul{color:var(--muted);padding-left:20px;margin:0 0 12px}
.legal li{margin:6px 0}
.legal b,.legal strong{color:var(--ink)}
.legal .note{background:var(--note-bg);border-left:3px solid var(--amber);padding:14px 18px;border-radius:0 8px 8px 0;
  margin:22px 0;font-size:15px;color:var(--muted)}
.legal .updated{border-top:1px solid var(--line);margin-top:38px;padding-top:16px;font-size:13.5px;color:var(--muted)}

/* licence attribution table */
.ltable{width:100%;border-collapse:collapse;margin:20px 0;font-size:14.5px}
.ltable th,.ltable td{text-align:left;padding:12px 14px;border-bottom:1px solid var(--line);vertical-align:top}
.ltable th{background:var(--soft);font-size:12.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.ltable td:first-child{color:var(--ink)}
.ltable td:last-child{white-space:nowrap;color:var(--muted)}
@media(max-width:620px){
  .ltable,.ltable tbody,.ltable tr,.ltable td,.ltable th{display:block}
  .ltable thead{display:none}
  .ltable tr{border:1px solid var(--line);border-radius:12px;padding:6px 4px;margin-bottom:12px}
  .ltable td{border:0;padding:5px 12px}
  .ltable td:last-child{white-space:normal;font-size:13px}
}
