/* =========================================================================
   OmaScan AI — design system

   ONE VOICE, ONE ACCENT. When in doubt, remove.

   TYPOGRAPHY — two typefaces, hard limit.
     Newsreader (serif)  Display-scale PROSE: h1, h2, and the one pull-quote
                         (.quote). Never italic. Never accent-coloured.
                         The test is not the tag and not the size alone. A
                         few things sit at --text-head and stay sans on
                         purpose, because they are figures rather than
                         prose: .stat .n, .markers .m-n, .member .initials.
                         Those are set in sans at weight 600 so they read as
                         data. Prose at that size reads as voice: serif.
     Inter (sans)        everything else: body, subheads, h3/h4, buttons, nav,
                         captions, labels, stat figures, the quote attribution.
     There is no monospace on this site. Eyebrows, kickers, step numbers and
     compliance text are uppercase sans, letter-spaced, in --ink-muted.

   FOUR SIZES, no one-offs: --text-display, --text-head, --text-body,
   --text-small. h3/h4 are body size at weight 600 — hierarchy below a section
   head comes from weight, not from inventing a fifth size.

   EMPHASIS — one technique at a time. Inline emphasis picks colour OR weight
   OR size, never stacked. Structural headings are the one documented
   exception: body copy is --ink-muted, so a heading is --ink at 600. That
   pairing is the site's baseline text convention, not decoration.

   COLOUR — five palette variables, below. Nothing else is a colour source.
   --accent is for interactive things only: buttons, links, form focus. If text
   is not clickable, it is not teal. At most one deliberate accent-coloured
   word or figure per page.

   NO gradients. NO shadows (off by default). NO decorative dividers. Tone and
   whitespace do the separating.

   MEASURE TRAVELS WITH ITS CENTRING. Every max-width on a text block is paired
   with margin-inline:auto by the centred-context rule below. Constrain a block
   without that pairing and the box parks at the inline start while its text
   centres inside, so a label reads as slightly off to one side of a centred
   heading. Centring keys off the context (.center/.hero/.capture), never off a
   list of element types, so adding an element cannot silently break alignment.
   Left-aligned layouts — the split hero, the about-page columns, card interiors —
   are deliberate and sit outside those three contexts.

   Three deliberate exceptions, all confined to the logo lockup: the wordmark
   keeps the serif, keeps the accent on its "AI", and keeps a fixed 21px rather
   than a type token. It is a brand mark inside a link, sized like an icon, not
   running text. It is the only font-size in this file that is not a token.
   ========================================================================= */

/* Fonts load from each page's <head> (preconnect + stylesheet link), not from
   here: an @import only starts the font CSS after styles.css has downloaded,
   and that serial chain delayed first paint on every page. */

/* ---- Utilities ---- */
/* Skip link: the first focusable element on every page. Off-canvas until it
   receives focus, then it parks in the top-left corner like a .btn. */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--accent);color:var(--bg)!important;font-weight:600;font-size:var(--text-small);padding:var(--s2) var(--s3);border-radius:0 0 var(--radius) 0}
.skip:focus{left:0;text-decoration:none}
/* Visually hidden, screen-reader only (the One Pass long description). */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

:root{
  /* ---- Palette. Five variables. Do not add a sixth. ---- */
  --ink:#1E2C48;         /* headings, strong text                              */
  --ink-muted:#5B6478;   /* body, captions, labels. AA on --bg and --bg-alt    */
  --accent:#017074;      /* interactive only. 5.6:1 as text, 5.9:1 behind #fff */
  --bg:#FBFAF7;          /* warm off-white page                                */
  --bg-alt:#F2F0E9;      /* one quiet step darker, for section alternation     */

  /* ---- Derived from the five above. Not new colours. ---- */
  --surface:color-mix(in srgb, var(--ink) 4%, transparent);  /* card fill, reads on either bg */
  --rule:color-mix(in srgb, var(--ink) 14%, transparent);    /* form borders only */
  --accent-hover:color-mix(in srgb, var(--accent) 86%, var(--ink));
  --accent-wash:color-mix(in srgb, var(--accent) 8%, transparent);

  /* ---- Type: four sizes ---- */
  --text-display:clamp(36px,5.2vw,56px);
  --text-head:clamp(25px,3.4vw,34px);
  --text-body:17px;
  --text-small:14px;

  /* ---- Measure. Line length, in characters. ---- */
  --measure:66ch;        /* body prose                                        */
  --measure-head:24ch;   /* a section head wants to break earlier than prose  */

  /* ---- Spacing: 8px base ---- */
  --s1:8px; --s2:16px; --s3:24px; --s4:32px;
  --s5:48px; --s6:64px; --s7:96px; --s8:128px;

  /* ---- One radius ---- */
  --radius:8px;
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--ink-muted);font-family:'Inter',system-ui,sans-serif;font-size:var(--text-body);line-height:1.6;-webkit-font-smoothing:antialiased}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto}}
img{max-width:100%;height:auto;display:block}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:2px}

/* ---- Layout ---- */
.wrap{max-width:1040px;margin:0 auto;padding:0 var(--s3)}
.narrow{max-width:680px;margin:0 auto;padding:0 var(--s3)}
section{padding:var(--s7) 0}
.band{background:var(--bg-alt)}   /* tone alternates sections; no borders */

/* ---- Nav ---- */
nav{display:flex;align-items:center;justify-content:space-between;padding:var(--s3) 0}
.brand{display:flex;align-items:center;gap:var(--s1);color:var(--ink)}
.brand:hover{text-decoration:none}
.brand img{width:26px;height:26px}
/* Logo lockup. The three documented exceptions live on these two lines: serif
   outside h1/h2, accent on non-heading text, and a fixed size. Brand mark. */
.brand .wordmark{font-family:'Newsreader',Georgia,serif;font-weight:500;font-size:21px;letter-spacing:-.01em}
.brand .wordmark .ai{color:var(--accent)}
.nav-links{display:flex;align-items:center;gap:var(--s3)}
.nav-links a{font-size:var(--text-small);color:var(--ink-muted)}
.nav-links a.active{color:var(--ink)}

/* ---- Buttons: exactly two styles ---- */
.btn{font-family:inherit;font-weight:600;font-size:var(--text-body);padding:var(--s2) var(--s4);border-radius:var(--radius);border:1px solid transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;min-height:48px;background:var(--accent);color:var(--bg)!important;transition:background .18s}
.btn:hover{background:var(--accent-hover);text-decoration:none}
.btn-secondary{background:transparent;color:var(--ink)!important;border-color:var(--ink)}
.btn-secondary:hover{background:var(--surface)}
/* Size modifier only, still the primary style, so the set stays at two. */
.btn-compact{padding:var(--s1) var(--s3);font-size:var(--text-small)}

/* ---- Type ---- */
h1{font-family:'Newsreader',Georgia,serif;font-weight:400;font-size:var(--text-display);line-height:1.08;letter-spacing:-.02em;color:var(--ink)}
h2{font-family:'Newsreader',Georgia,serif;font-weight:400;font-size:var(--text-head);line-height:1.15;letter-spacing:-.015em;color:var(--ink)}
/* The serif never wears a costume: no italic, no accent, no second colour. */
h1 em,h2 em{font-style:normal;color:inherit}
h3,h4{font-family:inherit;font-weight:600;font-size:var(--text-body);line-height:1.35;color:var(--ink)}
p{max-width:var(--measure)}
/* A measure is a reading aid, so it applies to prose only. On a short uppercase
   label it does nothing but create a box wider than the text — and a stray box is
   what drifts out of alignment. */
.eyebrow,.kicker,.trust-line,.spots,.demo-caption,.formnote,.line-note{max-width:none}

/* Eyebrow (above an h1) and kicker (above an h2): the same quiet label at two
   altitudes. Uppercase sans, muted. Never accent, never prose. */
.eyebrow,.kicker{font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted)}
.eyebrow,.kicker{display:block;margin-bottom:var(--s2)}
.sub{font-size:var(--text-body);color:var(--ink-muted)}
/* The lead sits between the h1 and the product line and has to outrank the line
   below it. It does that on colour alone — full ink against the muted body —
   rather than a fifth size or a heavier weight, per the emphasis rule above. */
.sub-lead{color:var(--ink)}
.section-sub{color:var(--ink-muted);max-width:60ch;margin-top:var(--s2)}

/* ---- Centred contexts ----
   A max-width must always travel with its centring rule. Constrain a block
   without one and the box sits at the inline start while the text centres inside
   it, so a label reads as "slightly to the side" of a centred heading. One rule
   for every centred context, matching on the context rather than on a list of
   element types, so a new element cannot silently drift. */
.center,.hero,.capture{text-align:center}
/* Depth-independent on purpose: the form sections wrap their heading and subhead
   in a view-switching div, so a direct-child selector would miss them. Restricted
   to block text elements, and :where() keeps specificity at zero so anything with
   its own margin still wins. */
:is(.center,.hero,.capture) :where(p,h1,h2,h3,h4,figure,blockquote,ul,ol,dl){margin-inline:auto}
:is(.center,.hero,.capture) h2{max-width:var(--measure-head)}

/* ---- Hero ---- */
/* padding-block, not the shorthand: .hero is applied alongside .wrap, and a
   four-side shorthand would zero .wrap's inline gutter and run the hero text
   into both screen edges on a narrow phone. */
.hero{padding-block:var(--s7) var(--s5)}
.hero .sub{max-width:56ch;margin:var(--s3) auto 0}
/* max-width:100% is load-bearing: as centred children of a flex column these
   take their max-content width, which on narrow screens grows past .wrap and
   widens the whole document (which then clips every page at mobile widths). */
.hero-cta{margin-top:var(--s4);display:flex;flex-direction:column;align-items:center;gap:var(--s2);max-width:100%}
.hero-cta .row{display:flex;gap:var(--s2);flex-wrap:wrap;justify-content:center;max-width:100%}
/* Sentence case on purpose. The compliance line directly below is the page's
   one uppercase instrument; two letter-spaced caps lines in a row read as two
   competing badges. */
.spots{font-size:var(--text-small);color:var(--ink-muted)}
/* Compliance: one quiet line, not a row of badges. */
.trust-line{font-size:var(--text-small);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted);margin:var(--s4) auto 0;max-width:none}

/* Hero figure: the drafted artefact leads, the capture sits beside it as one
   input. Bottom-aligned so the two panels share a baseline. */
.hero-figure{margin:var(--s6) auto 0;max-width:960px;display:grid;grid-template-columns:1.5fr 1fr;gap:var(--s3);align-items:end}
.hero-figure img{border-radius:var(--radius)}
.hero-figure figcaption{grid-column:1/-1;font-size:var(--text-small);color:var(--ink-muted);text-align:center;margin-top:var(--s1)}
.hero-shot{margin:var(--s6) auto 0;max-width:820px;border-radius:var(--radius);overflow:hidden}
.hero-shot.square{max-width:540px}

/* ---- Split hero (families) ---- */
.hero-split{display:grid;grid-template-columns:1.05fr .95fr;gap:var(--s6);align-items:center;padding-block:var(--s7)}
.hero-split .sub{margin-top:var(--s3);max-width:48ch}
.proofline{margin-top:var(--s2);font-size:var(--text-small);color:var(--ink-muted);max-width:46ch}

/* ---- Split section (organizations referrals) ----
   Text left, image right. Left-aligned on purpose, outside the centred
   contexts: this is one argument the reader scans line by line, so it takes
   a left rail. Same columns and gap as .hero-split without its padding. */
.split{display:grid;grid-template-columns:1.05fr .95fr;gap:var(--s6);align-items:center;text-align:left}
.split img{border-radius:var(--radius)}

/* ---- Pull-quote ---- */
/* Display scale, so it takes the display face. Without the font-family this
   inherited Inter and rendered at --text-head, i.e. the same size as the
   serif h2s on either side of it but in a different typeface, which read as
   a third voice on the page. Typeface follows scale here: display-scale text
   is serif, body-scale text is sans. .quote-attr below is body scale and so
   stays sans. */
.quote{font-family:'Newsreader',Georgia,serif;font-weight:400;font-size:var(--text-head);line-height:1.3;letter-spacing:-.015em;color:var(--ink);max-width:30ch;margin:0 auto;text-align:center}
.quote-attr{text-align:center;color:var(--ink-muted);margin:var(--s3) auto 0}

/* ---- 3-step "how it works" ---- */
.steps{max-width:1160px;margin:var(--s5) auto 0;display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4);align-items:start}
.step{text-align:center}
.step .num{font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--s3)}
.step-shot{display:flex;justify-content:center;margin-bottom:var(--s3)}
.step-shot img{height:clamp(400px,46vw,520px);width:auto;border-radius:var(--radius)}
.step h3{margin-bottom:var(--s1)}
.step p{color:var(--ink-muted);font-size:var(--text-small);max-width:34ch;margin:0 auto}

/* ---- Two-up cards. Fill, no border, no shadow. ---- */
.twoup{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3);max-width:880px;margin:var(--s5) auto 0}
.card{background:var(--surface);border-radius:var(--radius);padding:var(--s4)}
.card .q{font-size:var(--text-small);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--s1)}
.card h4{margin-bottom:var(--s1)}
.card p{font-size:var(--text-small);color:var(--ink-muted)}
/* A card that takes the whole row: for the one answer that runs long and
   carries its sources, so it never sits alone in one column of the grid. */
.card.wide{grid-column:1/-1}
/* margin-inline:0 pins the measured paragraph to the card's left edge; the
   centred-context rule would otherwise centre it under left-set headings. */
.card.wide p{max-width:var(--measure);margin-inline:0}

/* ---- FAQ disclosures ----
   Native details/summary: no JS, keyboard and screen-reader behaviour for
   free. Hairline separators are functional here (they are the click
   affordance's bounds), not decoration. The + rotates to × when open. */
.faq{max-width:640px;margin:var(--s5) auto 0;text-align:left}
.faq details{border-bottom:1px solid var(--rule)}
.faq details:first-of-type{border-top:1px solid var(--rule)}
.faq summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:var(--s2);padding:var(--s3) 0;font-weight:600;color:var(--ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-weight:400;font-size:22px;line-height:1;color:var(--ink-muted);transition:transform .18s;flex-shrink:0}
.faq details[open] summary::after{transform:rotate(45deg)}
.faq summary:hover{color:var(--accent)}
.faq .a{padding:0 var(--s4) var(--s3) 0;color:var(--ink-muted);margin-inline:0}

/* ---- Pricing: plan cards (pricing.html) ----
   Each card: name, one sentence on who it is for, price at display size (a
   figure, so sans at 600), the count and per-assessment figure, then the
   ask. No feature lists and no tags: the per-assessment figure is the
   comparison. The featured card swaps ink and page
   background, still the five colours; its muted text is a mix of the two,
   the same device as the demo's scrims. Buttons: the featured card takes
   the primary, the others the secondary, so one ask leads.
   margin-inline:0 on the <p>s is load-bearing: the centred-context rule
   gives every <p> auto inline margins, and in a flex column that centres
   the paragraph as a flex item. */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3);max-width:960px;margin:var(--s6) auto 0;align-items:stretch;text-align:left}
.plan{background:var(--surface);border-radius:var(--radius);padding:var(--s4);display:flex;flex-direction:column;gap:var(--s1)}
.plan>*{margin-inline:0;max-width:none;text-align:left}
.plan h3{font-size:var(--text-head);font-family:'Newsreader',Georgia,serif;font-weight:400;letter-spacing:-.015em;line-height:1.15}
.plan .p-desc{font-size:var(--text-small);color:var(--ink-muted)}
.plan .p-price{font-size:var(--text-display);font-weight:600;line-height:1;letter-spacing:-.02em;color:var(--ink);margin-top:var(--s3)}
.plan .p-unit{font-size:var(--text-small);color:var(--ink-muted)}
.plan .btn{margin-top:var(--s3);width:100%}
.plan .p-math{font-size:var(--text-small);font-weight:600;color:var(--ink);margin-top:var(--s2)}
.plan .p-desc{flex-grow:1}   /* cards stay level: the price row lines up whatever the sentence length */
.plan.featured{background:var(--ink)}
.plan.featured h3,.plan.featured .p-price,.plan.featured .p-math{color:var(--bg)}
.plan.featured .p-desc,.plan.featured .p-unit{color:color-mix(in srgb,var(--bg) 72%,transparent)}
.tier-note{margin-top:var(--s4)}
.tier-note+.tier-note{margin-top:var(--s1)}


/* ---- "The line" block (organizations) ---- */
/* text-align:left is load-bearing: this block sits inside .wrap.center, and the
   inherited centring strands the checklist's absolutely-positioned marks in a
   left column away from their text. */
.line-block{max-width:640px;margin:var(--s5) auto 0;background:var(--surface);border-radius:var(--radius);padding:var(--s5);text-align:left}
.line-block ul{list-style:none;display:flex;flex-direction:column;gap:var(--s1)}
.line-block li{font-size:var(--text-small);color:var(--ink)}
/* A label, not a rule: the two lists are separated by space, not a hairline. */
/* Now a label above each half of the list, not a divider between them. */
.line-rule{margin:0 0 var(--s2);font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted)}
.line-rule+ul+.line-rule{margin-top:var(--s4)}
.line-note{font-size:var(--text-small);color:var(--ink-muted);margin-top:var(--s3)}
.checklist{list-style:none;display:flex;flex-direction:column;gap:var(--s1);margin-top:var(--s2)}
.checklist li{position:relative;padding-left:var(--s3);font-size:var(--text-small);color:var(--ink-muted)}
.checklist li::before{content:"";position:absolute;left:2px;top:6px;width:8px;height:14px;border:solid var(--ink-muted);border-width:0 1.5px 1.5px 0;transform:rotate(45deg)}

/* ---- Stats (families) ----
   Each column is three tiers: figure, then the sentence the figure begins, then
   the citation. Two things were wrong before and both were about grouping.

   1. A flex row of differently-sized items gave every column its own height, so
      the citations landed at three different heights and the trio read as three
      unrelated blocks. Now an explicit grid, with row subgrid so all three
      figures, all three claims and all three citations share a line. Browsers
      without subgrid fall back to top-aligned columns, i.e. the old behaviour.
   2. The claim was the same size and colour as its citation, so the source
      competed with the fact. The claim moves up to body size; the citation stays
      small. No new size and no new colour — the opacity fudge is gone, since
      contrast belongs to the palette, not to a filter.

   Proximity does the grouping: the figure sits tight against the sentence it
   starts, and the citation sits further away. */
.stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:auto auto auto;gap:var(--s2) var(--s5);margin-top:var(--s5)}
/* Left-aligned on purpose. Centring a three-to-four line claim in a narrow
   column ragged both edges and made it harder to read than the heading above it,
   which stays centred. */
.stat{display:grid;grid-row:span 3;grid-template-rows:subgrid;text-align:left}
.stat .n{font-size:var(--text-head);font-weight:600;color:var(--ink);line-height:1.1}
.stat .l{font-size:var(--text-body);color:var(--ink-muted)}
.stat .src{font-size:var(--text-small);color:var(--ink-muted);margin-top:var(--s2)}
/* Citations carry the only links in this section, and at --text-small the accent
   colour alone is a thin affordance — and colour alone is not an accessible way to
   mark a link inside running text. Underlined, matching the legal pages. */
.src a{text-decoration:underline;text-underline-offset:2px}
.stat-note{text-align:center;color:var(--ink-muted);font-size:var(--text-small);max-width:64ch;margin:var(--s5) auto 0}
/* A citation inside a note drops to its own line rather than trailing the claim. */
.stat-note .src{display:block;margin-top:var(--s1)}

/* ---- Credibility markers ---- */
.markers{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3);max-width:900px;margin:var(--s5) auto 0;list-style:none}
.markers li{background:var(--surface);border-radius:var(--radius);padding:var(--s4);text-align:center}
.markers .m-n{display:block;font-size:var(--text-head);font-weight:600;line-height:1.1;color:var(--ink)}
.markers .m-l{display:block;font-size:var(--text-small);color:var(--ink-muted);margin-top:var(--s1)}

/* ---- Pilot quote ---- */
.pilot-quote{max-width:620px;margin:var(--s4) auto 0;text-align:center}
.pilot-quote blockquote{color:var(--ink);margin:0 auto;max-width:44ch}
.pilot-quote cite{display:block;margin-top:var(--s2);font-style:normal;font-size:var(--text-small);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted)}

/* ---- Mechanism cards (organizations) ---- */
.mech{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3);max-width:1000px;margin:var(--s5) auto 0}
.mech .m{background:var(--surface);border-radius:var(--radius);padding:var(--s4);text-align:left}
.mech .m-num{font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--s2)}
.mech h3{margin-bottom:var(--s1)}
.mech p{font-size:var(--text-small);color:var(--ink-muted)}

/* ---- Numbered process list (families) ---- */
.numsteps{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4);max-width:920px;margin:var(--s5) auto 0;list-style:none;counter-reset:ns;text-align:left}
.numsteps li{counter-increment:ns}
.numsteps li::before{content:counter(ns,decimal-leading-zero);display:block;font-size:var(--text-small);font-weight:500;letter-spacing:.1em;color:var(--ink-muted);margin-bottom:var(--s1)}
.numsteps .t{font-weight:600;color:var(--ink);margin-bottom:var(--s1)}
.numsteps p{font-size:var(--text-small);color:var(--ink-muted)}

/* ---- Trust items ---- */
/* Grid, not flex: with 4 items a wrapping flex row broke 3+1. auto-fit keeps
   the row even whether a page has 3 items or 4. */
.trust-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:var(--s5) var(--s4);max-width:1000px;margin:var(--s5) auto 0}
.trust-item{text-align:center}
.trust-item .h{font-weight:600;color:var(--ink);margin-bottom:var(--s1)}
.trust-item .d{font-size:var(--text-small);color:var(--ink-muted)}

/* ---- Forms ---- */
form.lead{max-width:480px;margin:var(--s5) auto 0;text-align:left}
.field{margin-bottom:var(--s2)}
legend,label{display:block;font-size:var(--text-small);font-weight:500;margin-bottom:var(--s1);color:var(--ink)}
.optional{font-weight:400;color:var(--ink-muted)}
input[type=email],input[type=text],select,textarea{width:100%;padding:var(--s2);border:1px solid var(--rule);border-radius:var(--radius);font-family:inherit;font-size:var(--text-body);background:var(--bg);color:var(--ink)}
/* Same field treatment, only taller. Vertical resize only: horizontal dragging
   would break the form's measure. line-height matches body so multi-line typing
   sits on the same rhythm as the rest of the page. */
textarea{min-height:120px;line-height:1.6;resize:vertical;display:block}
/* The arrow fill is the one value that cannot be a token: a data: URI cannot
   read CSS custom properties. It mirrors --ink-muted; change both together. */
select{-webkit-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%235B6478' d='M6 8 0 0h12z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--s2) center}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}
.pay-opts{display:grid;grid-template-columns:1fr 1fr;gap:var(--s1)}
.pay-opt input{position:absolute;opacity:0;pointer-events:none}
.pay-opt label{padding:var(--s2);border:1px solid var(--rule);border-radius:var(--radius);cursor:pointer;font-weight:400;color:var(--ink-muted);margin-bottom:0;transition:.15s}
.pay-opt input:checked + label{border-color:var(--accent);background:var(--accent-wash);color:var(--ink)}
.pay-opt input:focus-visible + label{outline:2px solid var(--accent);outline-offset:2px}
/* Three fixed choices in a row (the family waitlist). Same option style. */
.pay-opts.three{grid-template-columns:repeat(3,1fr)}
/* A single consent checkbox, unchecked by default. The native control stays
   (it is the clearest signal of consent there is); only spacing and colour. */
.check-opt{display:grid;grid-template-columns:auto 1fr;gap:var(--s2);align-items:start}
.check-opt input{margin-top:5px;width:16px;height:16px;accent-color:var(--accent)}
.check-opt label{font-weight:400;color:var(--ink-muted);margin-bottom:0}
.check-opt input:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.submit{width:100%;background:var(--accent);color:var(--bg);font-family:inherit;font-weight:600;font-size:var(--text-body);padding:var(--s2);border:none;border-radius:var(--radius);cursor:pointer;min-height:48px;margin-top:var(--s1);transition:background .18s}
.submit:hover{background:var(--accent-hover)}
.submit:disabled{opacity:.6;cursor:default}
.formnote{font-size:var(--text-small);color:var(--ink-muted);text-align:center;margin-top:var(--s2)}
/* The failure notice is carried by words, not by a colour. No red in the palette. */
.lead-error{margin-top:var(--s2);font-size:var(--text-small);color:var(--ink);text-align:center}
.success{display:none;text-align:center;max-width:460px;margin:var(--s5) auto 0}
/* No font-family here: the success heading is an h2 in the markup, so it already
   gets the serif. Serif stays h1/h2-only. */
.success h2{margin-bottom:var(--s1)}
.success p{color:var(--ink-muted);margin-left:auto;margin-right:auto}

/* ---- Footer ---- */
footer{padding:var(--s6) 0}
.footer-grid{display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--s4)}
.footer-links{display:flex;gap:var(--s6);flex-wrap:wrap}
.footer-col h5{font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--s2)}
.footer-col a{display:block;font-size:var(--text-small);color:var(--ink-muted);margin-bottom:var(--s1)}
.footer-col a:hover{color:var(--ink)}
.footer-meta{margin-top:var(--s5);font-size:var(--text-small);color:var(--ink-muted);text-align:center}
.footer-meta p{max-width:none}
.footer-meta p+p{margin-top:var(--s1)}
.footer-meta a{color:var(--ink-muted);text-decoration:underline;text-underline-offset:2px}

/* =========================================================================
   Demo launch panel + guided editor host
   The walkthrough is the compiled DemoEditorClient from the omascan.com repo.
   It paints itself position:fixed at 100vw/100dvh, so it is never laid out
   inside this page: .demo-stage is only the launch panel that precedes it, and
   the editor mounts into #omascanEditorHost appended to <body>.
   --stage-ink is scoped here. It is the embedded viewer's chrome (the scan
   needs a dark viewport), not a sixth site colour.
   ========================================================================= */
.demo-stage{--stage-ink:#141F33;--stage-text:#C3CCDA;position:relative;max-width:1160px;margin:var(--s5) auto 0;aspect-ratio:16/10;min-height:420px;border-radius:var(--radius);overflow:hidden;background:var(--stage-ink)}
.demo-launch-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.34}
/* Flat scrim, not a gradient: it only has to hold contrast over the photo. */
.demo-launch-inner{position:relative;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--s2);text-align:center;padding:var(--s4);background:color-mix(in srgb, var(--stage-ink) 82%, transparent)}
.demo-launch-inner .pl{font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--stage-text)}
.demo-launch-inner .pm{font-size:var(--text-small);color:var(--stage-text);max-width:40ch}
.demo-status{font-size:var(--text-small);color:var(--stage-text);max-width:44ch}
.demo-caption{font-size:var(--text-small);color:var(--ink-muted);text-align:center;margin:var(--s2) auto 0}
/* While the editor is open it owns the viewport; stop the page behind it from
   scrolling, since the editor traps its own gestures. */
.demo-open,.demo-open body{overflow:hidden}
#omascanEditorHost{position:relative;z-index:9999}

/* ---- Text-link CTA ----
   The hero's secondary ask is a plain link, not a second button: two buttons
   in the hero split the click. Accent because it is interactive. */
.cta-link{font-size:var(--text-small)}

/* ---- Founder note (index "who it's for") ----
   Prose only, left-aligned, one measure: the section is meant to read like the
   founder talking, so it takes none of the card or checklist treatments. */
.founder-note{max-width:640px;text-align:left}
.founder-note h2{margin-bottom:var(--s3)}

/* ---- Steps without screenshots ---- */
.steps.text-only{max-width:1040px}
.steps.text-only .step{text-align:left}
.steps.text-only .num{margin-bottom:var(--s2)}
.steps.text-only .step p{font-size:var(--text-body);max-width:none;margin:0}

/* ---- The email fallback form (index #ask) ----
   The founding-offer section it once lived in is gone from the markup;
   these three rules are what the fallback still needs. */
.offer-fallback{margin-top:var(--s5)}
.offer-fallback>[data-formview]>.formnote{margin-top:0}
.offer-fallback form.lead{margin-top:var(--s3)}

/* ---- Responsive ---- */
@media(max-width:860px){
  section{padding:var(--s6) 0}
  .hero{padding-block:var(--s6) var(--s5)}
  .hero-split{grid-template-columns:1fr;gap:var(--s5);padding-block:var(--s6)}
  .split{grid-template-columns:1fr;gap:var(--s4)}
  .steps{grid-template-columns:1fr;gap:var(--s6)}
  .markers,.mech,.numsteps{grid-template-columns:1fr}
  /* One column, and the rows stop being shared: with a single column there is
     nothing to align across, so subgrid is dropped and each stat closes up. */
  .stats{grid-template-columns:1fr;grid-template-rows:none;gap:var(--s5)}
  .stat{grid-row:auto;grid-template-rows:none;display:block}
  .hero-figure{grid-template-columns:1fr;gap:var(--s2)}
  .demo-stage{aspect-ratio:4/3;min-height:0}
}
@media(max-width:720px){
  .twoup,.pay-opts,.pay-opts.three,.plans{grid-template-columns:1fr}
  /* Wrap the nav onto a second row rather than hiding the links entirely. */
  nav{flex-wrap:wrap;gap:var(--s2)}
  .nav-links{width:100%;justify-content:space-between;gap:var(--s1) var(--s2);flex-wrap:wrap}
  .nav-links a:not(.btn){padding:var(--s1) 0}
  .footer-links{gap:var(--s4)}
}
@media(max-width:600px){
  .offer-stack li{grid-template-columns:1fr;gap:var(--s1)}
  /* The launch panel is only a poster and a button; let it get taller than wide. */
  .demo-stage{aspect-ratio:4/5;min-height:0}
}

/* =========================================================================
   "One pass" hero animation (index.html + assets/js/onepass.js)
   One visit becoming one report: the left half is a first-person capture
   viewport, the right half is the report drafting itself. Live DOM + inline
   SVG, no video.

   Scope notes against the design system above:
     • --stage-* are the capture viewport's chrome, same precedent as
       .demo-stage: an embedded viewer needs a dark viewport. Not new site
       colours. --stage-accent is derived from --accent, not invented.
     • The px font sizes inside .op-doc and the phone HUD are the artwork's
       content — a depicted document and a depicted screen, like the text
       inside the product screenshots — not page typography.
     • Accent inside the artwork depicts the product's own UI, where accent
       is doing its normal interactive job.
   All motion is class-driven; the JS clock toggles classes and these
   transitions carry them. prefers-reduced-motion kills every transition
   globally (rule at top of file) and onepass.js renders one finished frame.
   ========================================================================= */
.hero .onepass-head{margin-top:var(--s7)}
/* In its own section (index.html, since Sep 1 2026) the demo follows the hero
   directly, so the section carries a short top pad and the heading none. */
.demo-section{padding-top:var(--s4)}
.demo-section .onepass{margin-top:0}
.onepass{margin:var(--s6) auto 0;max-width:960px}
.onepass-head+.onepass{margin-top:var(--s4)}
.onepass figcaption{font-size:var(--text-small);color:var(--ink-muted);text-align:center;margin-top:var(--s2)}
.op-stage{--stage-ink:#141F33;--stage-line:#C3CCDA;--stage-accent:color-mix(in srgb,var(--accent) 46%,#fff);
  position:relative;display:flex;aspect-ratio:16/9;border-radius:var(--radius);overflow:hidden;background:var(--stage-ink);text-align:left}
.op-stage p{max-width:none;margin:0}

/* ---- Left: the visit ---- */
.op-visit{position:relative;flex:0 0 50%;overflow:hidden;transition:flex-basis .9s cubic-bezier(.6,0,.2,1)}
.op-stage.op-focus .op-visit{flex-basis:23%}
.op-scene{position:absolute;inset:0;width:100%;height:100%;color:var(--stage-line);transition:transform .9s cubic-bezier(.6,0,.2,1)}
/* Real footage above the wireframe (which remains the instant fallback),
   graded toward the stage with a flat scrim — same device as .demo-launch-inner.
   Dimmed during the wipe so the loop's jump cut reads as the recording
   restarting rather than a glitch. */
.op-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;background:var(--stage-ink);transition:opacity .4s}
.op-vscrim{position:absolute;inset:0;background:color-mix(in srgb,var(--stage-ink) 24%,transparent);pointer-events:none}
.op-lineart{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.op-lineart .soft,.op-lineart.soft{opacity:.32}

/* Phone HUD: the capture timer, top right */
.op-hud{position:absolute;top:0;left:0;right:0;display:flex;justify-content:flex-end;align-items:center;padding:10px 12px;font-size:11px;font-weight:500;letter-spacing:.1em;color:var(--stage-line)}
/* Same scrim device as the caption bar, so the timer holds up over bright
   footage (the window blows the top-right out otherwise). */
.op-hud>span{background:color-mix(in srgb,var(--stage-ink) 62%,transparent);border-radius:var(--radius);padding:4px 9px}
@keyframes opRecDot{from{opacity:1}to{opacity:.3}}

/* Replay: appears centred on the footage once the demonstration is done.
   display:none on [hidden] is load-bearing: the flex display below would
   otherwise override the browser's default hidden-attribute styling and
   show the button during playback. */
.op-replay[hidden]{display:none}
.op-replay{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:6px;font-family:inherit;font-size:var(--text-small);font-weight:600;color:var(--stage-line);background:color-mix(in srgb,var(--stage-ink) 72%,transparent);border:1px solid color-mix(in srgb,var(--stage-line) 40%,transparent);border-radius:var(--radius);padding:10px 16px;cursor:pointer;transition:background .18s}
.op-replay:hover{background:color-mix(in srgb,var(--stage-ink) 88%,transparent)}
.op-replay:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* Photo snap: a flash, then a thumbnail */
.op-flash{position:absolute;inset:0;background:#fff;opacity:0;pointer-events:none;transition:opacity .4s}
.op-flash.on{opacity:.7;transition:none}
.op-snap{position:absolute;left:12px;bottom:116px;width:88px;border-radius:6px;overflow:hidden;color:var(--stage-line);background:color-mix(in srgb,var(--stage-line) 12%,var(--stage-ink));border:1px solid color-mix(in srgb,var(--stage-line) 35%,transparent);opacity:0;transform:translateY(8px) scale(.92);transition:opacity .4s,transform .4s}
.op-snap.on{opacity:1;transform:none}
.op-snap svg,.op-snap img{display:block;width:100%;height:auto}
.op-snap-tag{display:block;font-size:9px;letter-spacing:.06em;padding:3px 6px 4px}

/* Live caption + voice waveform */
.op-capbar{position:absolute;left:12px;right:12px;bottom:12px;display:flex;flex-direction:column;gap:7px;background:color-mix(in srgb,var(--stage-ink) 78%,transparent);border-radius:var(--radius);padding:10px 12px;transition:opacity .5s}
.op-wave{display:flex;align-items:center;gap:3px;height:15px}
.op-wave i{width:3px;height:3px;border-radius:2px;background:var(--stage-accent);animation:opWave .6s ease-in-out infinite alternate;animation-play-state:paused}
.op-wave.on i{animation-play-state:running}
@keyframes opWave{from{height:3px}to{height:var(--h,12px)}}
.op-livecap{font-size:12.5px;line-height:1.45;color:var(--stage-line);min-height:2.9em;max-height:4.4em;overflow:hidden;transition:opacity .3s,max-height .45s,min-height .45s}

/* ---- Right: the report ---- */
.op-report{flex:1 1 auto;background:var(--bg-alt);padding:16px;display:flex;min-width:0}
.op-doc{flex:1;background:var(--bg);border:1px solid var(--rule);border-radius:6px;padding:18px 20px;overflow:hidden;display:flex;flex-direction:column;min-width:0}
.op-doc-head{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;flex-wrap:wrap}
.op-doc-title{font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink)}
/* The automation telling on itself: listening → drafting → draft ready.
   State strings swap on the stage's op-live / op-done classes. The teal is
   the product's own UI accent inside the artwork, same as the chip. */
.op-ai-badge{display:flex;align-items:center;gap:5px;font-size:10.5px;color:var(--ink-muted);white-space:nowrap}
.op-ai-badge img{width:14px;height:14px}
.op-ai-name{font-weight:600;color:var(--ink)}
.op-ai-dot{width:6px;height:6px;border-radius:50%;background:var(--accent);animation:opRecDot 1.1s ease-in-out infinite alternate}
.op-ai-state span{display:none}
.op-stage:not(.op-live):not(.op-done) .st-listen{display:inline}
.op-stage.op-live:not(.op-done) .st-draft{display:inline}
/* Done: the status text goes away, the dot rests, and the pencil appears —
   the visual cue that the notes are now editable. Clicking it focuses the
   document. */
.op-stage.op-done .op-ai-dot{animation:none;opacity:.35}
.op-stage.op-done .op-ai-state{display:none}
.op-edit-flag{display:inline-flex;align-items:center;gap:4px;font-family:inherit;font-size:10.5px;font-weight:600;color:var(--ink-muted);background:transparent;border:1px solid var(--rule);border-radius:6px;padding:3px 8px;cursor:pointer;transition:color .18s,border-color .18s}
.op-edit-flag:hover{color:var(--accent);border-color:var(--accent)}
.op-edit-flag:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.op-doc-meta{display:flex;gap:14px;flex-wrap:wrap;margin-top:7px;padding-bottom:11px;border-bottom:1px solid var(--rule);font-size:10.5px;color:var(--ink-muted)}
.op-doc-meta b{font-weight:600;color:var(--ink);margin-right:4px}
/* min-height:0 so the report body yields to the chat instead of shoving it past
   the bottom of a fixed 16:9 stage. The chat is the interactive part — losing a
   line off the end of the report reads as the sheet continuing; losing the
   buttons reads as broken. Without this the chat had zero headroom: one extra
   line of question clipped the answer buttons. */
.op-doc-body{position:relative;flex:1;min-height:0;padding-top:11px;transition:opacity .45s ease .3s}

/* The blank template: faint ruled lines. The blankness is the tension. */
/* pointer-events:none is load-bearing: this layer sits over the doc body,
   and once the draft is editable it must never eat the visitor's clicks. */
.op-rules{position:absolute;top:16px;left:0;right:2px;display:flex;flex-direction:column;gap:21px;transition:opacity .6s;pointer-events:none}
.op-rules i{border-bottom:1px solid var(--rule)}
.op-rules i:nth-child(3){width:86%}.op-rules i:nth-child(5){width:64%}.op-rules i:nth-child(7){width:42%}
.op-stage.op-live .op-rules{opacity:0}

/* Sections hold their layout from the start (opacity does the reveal), so
   text never reflows mid-draft — content streams into place, not around. */
.op-sec{margin-top:11px;opacity:0;transform:translateY(5px);transition:opacity .35s,transform .35s}
.op-sec.on{opacity:1;transform:none}
.op-sec-h{font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:4px}
.op-doc p,.op-doc li{font-size:12.5px;line-height:1.55;color:var(--ink)}
.op-recs{list-style:decimal}
.op-equip{list-style:disc}
.op-recs,.op-equip{padding-left:16px;display:flex;flex-direction:column;gap:2px}
.op-recs li,.op-equip li{opacity:0;transform:translateY(4px);transition:opacity .3s,transform .3s}
.op-recs li.on,.op-equip li.on{opacity:1;transform:none}
.op-recs li::marker,.op-equip li::marker{color:var(--ink-muted)}

/* The doorway photo, dropped into the findings */
/* clear:right stacks the photos down the sheet's right edge */
.op-doc-photo{position:relative;float:right;clear:right;width:96px;margin:2px 0 6px 10px;color:var(--ink-muted);opacity:0;transform:translateY(-6px);transition:opacity .4s,transform .4s}
/* Once the document is editable, photos behave like document objects:
   click to enlarge, × to remove. */
.op-photo-x{position:absolute;top:2px;right:2px;width:18px;height:18px;display:none;align-items:center;justify-content:center;font-family:inherit;font-size:12px;line-height:1;color:var(--bg);background:color-mix(in srgb,var(--ink) 72%,transparent);border:none;border-radius:50%;cursor:pointer;padding:0}
.op-photo-x:hover{background:var(--ink)}
.op-photo-x:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.op-stage.op-done .op-photo-x{display:flex}
.op-stage.op-done .op-doc-photo img{cursor:zoom-in}
.op-doc-photo.on{opacity:1;transform:none}
.op-doc-photo svg,.op-doc-photo img{display:block;width:100%;height:auto;background:var(--bg-alt);border:1px solid var(--rule);border-radius:4px}
.op-doc-photo figcaption{font-size:9px;color:var(--ink-muted);margin-top:3px;text-align:left}

/* The assistant's ask, pinned to the bottom of the sheet. visibility (not
   just opacity) keeps its buttons out of the tab order until it appears. */
.op-chat{display:flex;gap:8px;align-items:flex-start;margin-top:10px;border:1px solid var(--rule);border-radius:6px;padding:9px 11px;background:var(--surface);visibility:hidden;opacity:0;transform:translateY(5px);transition:opacity .35s,transform .35s,visibility .35s}
.op-chat.on{visibility:visible;opacity:1;transform:none}
.op-chat>img{margin-top:1px}
.op-chat-main{flex:1;min-width:0}
.op-chat-q{font-size:12.5px;line-height:1.5;color:var(--ink);min-height:1.5em}
.op-chat-actions{display:flex;gap:6px;margin-top:7px;visibility:hidden;opacity:0;transition:opacity .3s,visibility .3s}
.op-chat-actions.on{visibility:visible;opacity:1}
.op-chat-actions button{font-family:inherit;font-size:10.5px;font-weight:600;border-radius:6px;padding:5px 11px;cursor:pointer;transition:background .18s,border-color .18s}
.op-chat-actions [data-op-chat-yes]{background:var(--accent);color:var(--bg);border:1px solid transparent}
.op-chat-actions [data-op-chat-yes]:hover{background:var(--accent-hover)}
.op-chat-actions [data-op-chat-no]{background:transparent;color:var(--ink-muted);border:1px solid var(--rule)}
.op-chat-actions [data-op-chat-no]:hover{border-color:var(--ink-muted)}
.op-chat-actions button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* Carets and the closing beat */
/* The insertion caret. It blinks while OmaScan AI writes, and the last one
   (end of Equipment) never turns off: after the handover it keeps blinking
   at the end of the text, the standing signal that typing will input text.
   It yields the moment the visitor clicks in: the browser's real caret
   takes over, so the fake one hides while the document holds focus.
   (Under reduced motion the blink animation is disabled globally and the
   caret shows solid, which still reads as an insertion point.) */
.op-caret{display:inline-block;width:2px;height:12px;margin-left:2px;vertical-align:-2px;background:var(--accent);opacity:0}
.op-caret.on{opacity:1;animation:opBlink 1s linear infinite}
.op-doc-body[contenteditable]:focus-within .op-caret{opacity:0;animation:none}
@keyframes opBlink{0%,48%{opacity:1}52%,100%{opacity:0}}
/* ---- The handover: the report becomes one editable document ----
   onepass.js sets contenteditable on the whole .op-doc-body, so it behaves
   like a normal document surface: click anywhere, edit anything. The sheet
   signals focus with its border, the way a form field would. */
.op-doc-body[contenteditable]{cursor:text;outline:none}
.op-stage.op-done .op-doc{transition:border-color .2s}
.op-stage.op-done .op-doc:focus-within{border-color:var(--accent)}

/* Focused phase: the visit is a thumbnail rail, and it tidies itself — the
   snap has served its purpose. The caption STAYS: she keeps assessing while
   the report drafts, and that parallelism is the story. (Hidden on mobile,
   where the short rail has no room — see the media query.) */
.op-stage.op-focus .op-snap{opacity:0}

/* Enlarged-photo view, scoped to the stage. The flat scrim is the same
   device as the caption bar. display:none on [hidden] outranks the flex. */
.op-lightbox[hidden]{display:none}
.op-lightbox{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:28px;background:color-mix(in srgb,var(--stage-ink) 88%,transparent)}
.op-lightbox img{max-width:min(82%,560px);max-height:72%;width:auto;height:auto;border-radius:6px}
.op-lightbox-cap{font-size:12.5px;color:var(--stage-line)}
.op-lightbox-close{position:absolute;top:10px;right:10px;width:28px;height:28px;display:flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;line-height:1;color:var(--stage-line);background:transparent;border:1px solid color-mix(in srgb,var(--stage-line) 40%,transparent);border-radius:50%;cursor:pointer;padding:0}
.op-lightbox-close:hover{border-color:var(--stage-line)}
.op-lightbox-close:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ---- The funding form: an editor over the rail ----
   Appears when the visitor says yes to the chat's first question. The rail
   widens back out and the form covers it completely (no footage behind it,
   like a document editor taking the pane). The sequencer in onepass.js
   fills it field by field, then the values become editable. Type sizes are
   the artwork's content, like .op-doc's. */
.op-stage.op-form .op-visit{flex-basis:46%}
/* The narrowed notes reflow taller than their box; without this they paint
   over the chat and steal its clicks. min-height:0 lets the flex child
   shrink; the notes scroll inside it while the form is up. */
.op-stage.op-form .op-doc-body{overflow-y:auto;min-height:0}
.op-stage.op-form .op-hud,
.op-stage.op-form .op-capbar,
.op-stage.op-form .op-snap{opacity:0}
/* Replay stays reachable in the editor's top bar row. */
.op-stage.op-form .op-replay{top:5px;right:10px;left:auto;bottom:auto;transform:none;padding:4px 10px;font-size:11px;z-index:3;background:transparent;border-color:transparent;color:var(--ink-muted)}
.op-stage.op-form .op-replay:hover{color:var(--accent)}
.op-pdf{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;background:var(--bg-alt);visibility:hidden;opacity:0;transform:translateY(10px);transition:opacity .4s,transform .4s,visibility .4s}
.op-stage.op-form .op-pdf{visibility:visible;opacity:1;transform:none}
.op-pdf-bar{display:flex;align-items:center;gap:8px;padding:8px 96px 8px 14px;border-bottom:1px solid var(--rule);background:var(--bg)}
.op-pdf-doctitle{font-size:10px;letter-spacing:.04em;color:var(--ink-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.op-pdf-edit{display:inline-flex;align-items:center;gap:4px;font-size:9.5px;font-weight:600;color:var(--accent);white-space:nowrap}
.op-pdf-edit[hidden]{display:none}
/* The page: a sheet of paper. Drawn as a printed clinic form: letterhead,
   title, shaded numbered section bars, hairline cells (the 1px gap over a
   --rule background draws every grid line once), printed labels in the
   corner of each cell, typed values inside. The px sizes are the depicted
   document's content, like .op-doc's, not page typography. The letterhead
   name takes the serif because it is a wordmark on the depicted paper. */
.op-pdf-page{flex:1;background:var(--bg);margin:10px;border:1px solid var(--rule);border-radius:2px;padding:14px 18px 10px;overflow-y:auto;display:flex;flex-direction:column;gap:0;color:var(--ink)}
/* flex-shrink:0 is load-bearing: without it a too-tall page compresses its
   rows into each other instead of scrolling. */
.op-pdf-page>*{flex-shrink:0}
.op-pdf-lh{display:flex;align-items:center;gap:10px;padding-bottom:8px;border-bottom:2px solid var(--ink)}
.op-pdf-logo{flex:0 0 auto;color:var(--ink)}
.op-pdf-org{flex:1;min-width:0}
.op-pdf-orgname{font-family:'Newsreader',Georgia,serif;font-size:14px;font-weight:500;letter-spacing:-.01em;color:var(--ink);line-height:1.1}
.op-pdf-orgsub{font-size:8.5px;color:var(--ink-muted);margin-top:2px}
.op-pdf-formno{font-size:8px;line-height:1.35;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-muted);text-align:right;white-space:nowrap}
.op-pdf-title{font-size:11.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink);text-align:center;padding:9px 0 7px}
.op-pdf-sec{font-size:8.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink);background:var(--surface);padding:3px 7px;margin-top:6px;border:1px solid var(--rule);border-bottom:none}
/* Cells: a grid with 1px gaps over the rule colour, inside a rule border. */
.op-pdf-grid{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule)}
.op-pdf-grid.c3{grid-template-columns:1fr 1fr 1.1fr}
.op-pdf-grid.c2{grid-template-columns:1.2fr 1fr}
.op-pdf-grid.c1{grid-template-columns:1fr;border-top:none}
.op-pdf-cell{background:var(--bg);padding:3px 7px 4px;min-height:28px;display:flex;flex-direction:column;gap:1px;min-width:0}
.op-pdf-l{font-size:7.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-muted);line-height:1.3}
.op-pdf-v{font-size:10.5px;line-height:1.4;font-weight:500;color:var(--ink);opacity:0;transition:opacity .3s;border-radius:2px}
/* Printed checkboxes and inline options. The X is the typed value. */
.op-pdf-opts{display:flex;gap:10px;align-items:center;flex-wrap:wrap;font-size:10px;color:var(--ink);line-height:1.3;padding-top:2px}
.op-pdf-opt{display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
.op-pdf-box{display:inline-flex;align-items:center;justify-content:center;width:9px;height:9px;border:1px solid var(--ink);font-style:normal;flex:0 0 auto}
.op-pdf-box .op-pdf-v{font-size:8px;line-height:1;font-weight:700;border-radius:0}
.op-pdf-box .op-pdf-v::after{display:none}
/* Table rows: a printed row header, then the typed entry. */
.op-pdf-table{border:1px solid var(--rule);display:flex;flex-direction:column;gap:1px;background:var(--rule)}
.op-pdf-tr{display:flex;background:var(--bg);min-height:18px}
.op-pdf-th{flex:0 0 78px;padding:3px 7px;font-size:8px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-muted);border-right:1px solid var(--rule);line-height:1.5}
.op-pdf-th.num{flex-basis:22px;text-align:center;color:var(--ink)}
.op-pdf-tr .op-pdf-v{flex:1;padding:3px 7px}
/* the fill: a field being written shows the accent caret; done fields settle */
[data-pdf-f].filling .op-pdf-v{opacity:1;background:var(--accent-wash)}
[data-pdf-f].filling .op-pdf-v::after{content:"";display:inline-block;width:2px;height:10px;margin-left:2px;vertical-align:-1px;background:var(--accent);animation:opBlink 1s linear infinite}
[data-pdf-f].on .op-pdf-v{opacity:1;background:transparent}
/* once handed over, values are fields under the cursor */
.op-pdf-page[contenteditable]{cursor:text;outline:none}
.op-pdf-page[contenteditable] .op-pdf-v:hover{background:var(--accent-wash)}
/* Signature and date lines, then the printed page footer. */
.op-pdf-foot{display:flex;gap:18px;align-items:flex-end;margin-top:auto;padding-top:22px}
.op-pdf-sigcell{flex:1;display:flex;flex-direction:column;gap:2px;position:relative}
.op-pdf-sigcell.short{flex:0 0 32%}
.op-pdf-sig{display:block;border-bottom:1px solid var(--ink);height:14px}
.op-pdf-await{position:absolute;right:0;top:-2px;font-size:8px;color:var(--ink-muted);white-space:nowrap;opacity:0;transition:opacity .3s}
.op-pdf-foot.on .op-pdf-await{opacity:1}
.op-pdf-pagefoot{margin-top:10px;font-size:7.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-muted);text-align:center}

/* Static-frame mode (?op-t= debug, reduced motion): states land instantly. */
.op-stage.op-static,.op-stage.op-static *{transition:none!important;animation:none!important}

@media(max-width:720px){
  /* Stacked stage: the visit on top, the report beneath it at full width.
     flex-basis is now a height, so the phase transitions carry over unchanged
     (op-focus shrinks the visit to a rail; op-form widens it under the PDF). */
  .op-stage{flex-direction:column;aspect-ratio:auto;height:660px}
  .op-visit{flex:0 0 40%}
  .op-stage.op-focus .op-visit{flex-basis:20%}
  /* min-height:0 lets the report pane shrink inside the stage; without it the
     pane's content height forces the chat out past the stage's bottom edge. */
  .op-report{min-height:0;padding:10px}
  .op-doc{padding:13px 15px}
  /* The report body scrolls inside its own slot, so the findings text and the
     photo column can never shove the sections or the chat out of the pane:
     the chat keeps its pinned slot at the bottom of the document at every
     phase. (Same contract op-form already relies on.) */
  .op-doc-body{overflow-y:auto}
  .op-doc p,.op-doc li{font-size:11.5px}
  .op-sec{margin-top:9px}
  /* The photo column stacks down the document's right edge; at 74px wide
     three photos plus their captions alone overran the pane on a phone. */
  .op-doc-photo{width:60px}
  .op-snap{bottom:104px;width:72px}
  .op-stage.op-form .op-visit{flex-basis:56%}
  .op-pdf-page{margin:8px;padding:11px 12px;gap:5px}
  .op-livecap{font-size:11.5px}
  .op-rules{gap:19px}
  /* No room for the caption in the short focused rail on mobile. */
  .op-stage.op-focus .op-livecap{opacity:0;min-height:0;max-height:0}
}

/* =========================================================================
   Legal documents (terms.html, privacy.html)
   Long-form reading: one narrow measure, no bands, no borders. The text is
   ported verbatim from the approved policy PDFs, so the styling has to absorb
   whatever structure the source uses: bold lead-ins, nested subheadings,
   bullet lists, and address blocks.
   ========================================================================= */
.legal{max-width:690px;margin:0 auto;padding:var(--s6) var(--s3) var(--s7)}
/* No font-size override here: the document title takes --text-display like every
   other h1, so it outranks the --text-head section headings. Overriding it to
   head size collapsed the two into one level. */
.legal .updated{font-size:var(--text-small);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted);margin-top:var(--s2)}
.legal .lead{margin-top:var(--s3);color:var(--ink-muted)}

/* Table of contents. Not in the source documents; added because both run to
   ~20 sections and cross-reference each other by number.
   display:block is load-bearing: this is a <nav>, and the global nav rule sets
   display:flex + align-items:center, which would sit the label beside the
   columns instead of above them. */
.legal .toc{display:block;margin-top:var(--s5);background:var(--surface);border-radius:var(--radius);padding:var(--s4)}
.legal .toc h2{font-family:inherit;font-size:var(--text-small);font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-muted);margin-bottom:var(--s2)}
.legal .toc ol{list-style:none;columns:2;column-gap:var(--s5)}
.legal .toc li{margin-bottom:var(--s1);font-size:var(--text-small);break-inside:avoid;line-height:1.4}

/* Override the global section padding: these are text blocks, not page bands. */
.legal section{padding:0;margin-top:var(--s6)}
.legal section h2{scroll-margin-top:var(--s3)}
.legal h3{margin-top:var(--s4)}
.legal p{margin-top:var(--s2);color:var(--ink-muted);line-height:1.7;max-width:none}
/* Weight only. The lead-in stays the same colour as the sentence it opens. */
.legal strong{color:inherit;font-weight:600}
.legal ul{margin-top:var(--s2);padding-left:var(--s3);display:flex;flex-direction:column;gap:var(--s1)}
.legal ul li{color:var(--ink-muted);line-height:1.65}
.legal ul li::marker{color:var(--ink-muted)}
.legal address{font-style:normal;margin-top:var(--s2);color:var(--ink-muted);line-height:1.75}
.legal a{text-decoration:underline;text-underline-offset:2px}
.legal-foot{margin-top:var(--s6);font-size:var(--text-small);color:var(--ink-muted)}
@media(max-width:640px){.legal .toc ol{columns:1}}

/* =========================================================================
   About page
   Two-column story splits, the team grid, and the supporter logo row.
   The logo files arrive with white backgrounds; mix-blend-mode:multiply lets
   the warm page show through instead of stamping white boxes on it. Grayscale
   at rest keeps the row quiet — colour returns on hover, where it is a link.
   ========================================================================= */
.about-split{display:grid;grid-template-columns:1.05fr .95fr;gap:var(--s6);align-items:center;max-width:1040px;margin:var(--s5) auto 0}
.about-split.flip>.photo{order:-1}
.about-split .photo img{border-radius:var(--radius)}
.about-split h2{margin-bottom:var(--s2)}
.about-split p+p{margin-top:var(--s2)}
/* A CTA needs more air after body copy than one paragraph needs after another. */
.about-split p:has(>.btn){margin-top:var(--s3)}
/* Weight only, per the emphasis rule: the realization line is the page's spine. */
.about-split .keyline{color:var(--ink);font-weight:600}

.team-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4) var(--s3);max-width:920px;margin:var(--s5) auto 0}
.member .photo{aspect-ratio:1;border-radius:var(--radius);overflow:hidden;background:var(--surface)}
.member .photo img{width:100%;height:100%;object-fit:cover;object-position:top}
/* Monogram tile for a member with no headshot yet: a deliberate placeholder,
   not a missing asset. One step darker than the card surface so the tile
   reads as an object on the band, with ink initials instead of muted. */
.member .photo.mono{background:color-mix(in srgb, var(--ink) 9%, transparent)}
.member .initials{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-weight:600;font-size:var(--text-head);letter-spacing:.06em;color:var(--ink)}
.member .name{font-size:var(--text-small);font-weight:600;color:var(--ink);margin-top:var(--s2)}
/* Name links keep the ink of the grid at rest; the interactive accent
   arrives on hover, per the one-technique emphasis rule. */
.member .name a{color:inherit}
.member .name a:hover{color:var(--accent)}
.member .role{font-size:var(--text-small);color:var(--ink-muted)}

.logo-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:var(--s4) var(--s6);max-width:860px;margin:var(--s4) auto 0}
.logo-row img{height:96px;width:auto;mix-blend-mode:multiply;filter:grayscale(1);opacity:.72;transition:opacity .18s,filter .18s}
.logo-row a:hover img{filter:none;opacity:1}

@media(max-width:860px){
  .about-split{grid-template-columns:1fr;gap:var(--s4)}
  .about-split.flip>.photo{order:0}
  .team-grid{grid-template-columns:1fr 1fr}
  .logo-row img{height:72px}
}

/* Two of the source photos ship on square canvases with baked-in white
   letterboxing (Canva exports). Cropping the frame to 4:3 with cover removes
   the bars without editing the files. */
.about-split .photo.r43{aspect-ratio:4/3;overflow:hidden;border-radius:var(--radius)}
.about-split .photo.r43 img{width:100%;height:100%;object-fit:cover}

/* =========================================================================
   "One pass" voice toggle (index.html + assets/js/onepass-sound.js)
   Top-left of the footage, the mirror of the timer chip top-right, in the
   same scrim-on-stage treatment. Two icons, one shown at a time by the
   button's .on class. Hidden in static-frame mode: nothing plays there.
   ========================================================================= */
.op-sound{position:absolute;top:10px;left:12px;z-index:2;display:flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;color:var(--stage-line);background:color-mix(in srgb,var(--stage-ink) 62%,transparent);border:1px solid color-mix(in srgb,var(--stage-line) 30%,transparent);border-radius:var(--radius);cursor:pointer;transition:background .18s,border-color .18s}
.op-sound:hover{background:color-mix(in srgb,var(--stage-ink) 84%,transparent);border-color:color-mix(in srgb,var(--stage-line) 60%,transparent)}
.op-sound:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.op-sound svg{display:block}
.op-sound .ic-on{display:none}
.op-sound.on .ic-off{display:none}
.op-sound.on .ic-on{display:block}
.op-stage.op-static .op-sound{display:none}
