  /* Självhostade typsnitt (ersätter fonts.googleapis.com/fonts.gstatic.com,
     2026-08-16 - samma skäl som blood-test-price-check: varje besökares IP
     gick annars till Google vid varje sidladdning). Space Grotesk och
     JetBrains Mono, variabla woff2, subset latin + latin-ext (åäö ligger
     redan i "latin"). font-weight:400 700 täcker de vikter CSS:en nedan
     faktiskt begär (400/500/600/700 för Space Grotesk, 400/500/700 för
     JetBrains Mono) - båda är variabla filer, en enda url per subset. */
  @font-face{
    font-family:"Space Grotesk";
    font-style:normal;
    font-weight:400 700;
    font-display:swap;
    src:url("fonts/space-grotesk-latin.woff2") format("woff2");
    unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
  }
  @font-face{
    font-family:"Space Grotesk";
    font-style:normal;
    font-weight:400 700;
    font-display:swap;
    src:url("fonts/space-grotesk-latin-ext.woff2") format("woff2");
    unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
  }
  @font-face{
    font-family:"JetBrains Mono";
    font-style:normal;
    font-weight:400 700;
    font-display:swap;
    src:url("fonts/jetbrains-mono-latin.woff2") format("woff2");
    unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
  }
  @font-face{
    font-family:"JetBrains Mono";
    font-style:normal;
    font-weight:400 700;
    font-display:swap;
    src:url("fonts/jetbrains-mono-latin-ext.woff2") format("woff2");
    unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
  }

  :root{
    /* Was previously overwritten at runtime by theme.js's palette switcher
       (removed 2026-08-17 along with the light/dark toggle) — these are
       the exact values that switcher computed for "light", baked in as
       literals so removing the JS caused no visible change. */
    --paper:#F4F5F5; --card:#FFFFFF; --ink:#243040; --ink2:#9298A0;
    --line:#E0E2E4; --line2:#F0F1F2;
    --pine:#00A087; --pine-d:#007361; --pine-t:#DBF2EE;
    --clay:#E64B35; --clay-d:#A63626; --clay-t:#FCE6E3;
    --pat:#4DBBD5; --flag:#E23B3B; --neutral:#E7E8EA;
    --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
    --disp:'Space Grotesk',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
    --colStudy:210px;
  }
  *{box-sizing:border-box}
  html,body{margin:0}
  body{background:var(--paper); color:var(--ink); font-family:var(--disp); font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased}
  /* width:100% is NOT cosmetic - same bug blood-test-price-check's own
     app.css documents on its .wrap: body is display:flex; flex-direction:
     column (sticky-footer rule below), so .wrap's horizontal margin:auto
     disables flexbox stretch, and without an explicit width .wrap falls
     back to shrink-to-fit sizing - stretching only as wide as its widest
     child's max-content width instead of the parent's width. Measured
     2026-08-20: on /compare/, /new/ and /privacy/ (no wide fixed-width
     content to accidentally force it wide) this meant .wrap rendered far
     narrower than .mini-band-inner above it at desktop widths - h1 and
     the band's nav row/language selector didn't share a left/right edge
     even though both use the same max-width:1160px;margin:0 auto rule,
     because only .mini-band-inner is a plain block (stretches to
     max-width normally); .wrap is a flex item of body (shrink-to-fit
     without this). Landing's main.wrap happened to escape the bug by
     accident - .landing-grid's two 1fr grid columns drag shrink-to-fit
     width up near max-width anyway - which is exactly why it's not safe
     to leave unfixed elsewhere. */
  .wrap{width:100%; max-width:1160px; margin:0 auto; padding:24px 22px 60px}

  .topbar{display:flex; justify-content:flex-end; gap:8px; margin-bottom:8px}
  .lang{font-family:var(--mono); font-size:11px; letter-spacing:.03em; color:var(--ink); background:var(--card); border:1px solid var(--line); border-radius:8px; padding:6px 8px; cursor:pointer}
  .lang:focus-visible{outline:2px solid var(--pat); outline-offset:1px}

  header{margin-bottom:20px}
  .eyebrow{font-family:var(--mono); font-size:11px; font-weight:500; letter-spacing:.22em; text-transform:uppercase; color:var(--pine); margin:0 0 10px}
  h1{font-family:var(--disp); font-weight:700; font-size:31px; line-height:1.08; margin:0 0 9px; letter-spacing:-.02em}
  .thesis{max-width:74ch; color:var(--ink2); margin:0; font-size:14.5px}

  /* Patient bar */
  .pbar{background:var(--card); border:1px solid var(--line); border-radius:14px; padding:16px 18px; margin-bottom:18px}
  .pbar-grid{display:grid; grid-template-columns:repeat(5,1fr); gap:14px; align-items:end}
  .pf label{display:block; font-size:11.5px; color:var(--ink2); margin-bottom:5px; font-weight:500}
  .seg{display:flex; gap:6px}
  .seg button{flex:1; font-family:var(--disp); font-size:13.5px; font-weight:500; padding:8px 0; border:1px solid var(--line); background:var(--card); color:var(--ink2); border-radius:8px; cursor:pointer; transition:.12s}
  .seg button.on{background:var(--ink); color:var(--card); border-color:var(--ink)}
  .seg button:focus-visible{outline:2px solid var(--pat); outline-offset:2px}
  input[type=number]{width:100%; font-family:var(--mono); font-size:15px; color:var(--ink); padding:8px 10px; border:1px solid var(--line); border-radius:8px; background:var(--card)}
  input[type=number]:focus{outline:2px solid var(--pat); outline-offset:1px; border-color:var(--pat)}
  .actual input{font-weight:600}
  .bmi{font-family:var(--mono); font-size:11px; color:var(--ink2)}
  .lblrow{display:flex; justify-content:space-between; align-items:baseline; gap:8px; margin-bottom:5px}
  .lblrow label{margin-bottom:0}
  .bmi b{color:var(--ink); font-weight:700}
  .pbar-extra{display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-top:14px; padding-top:14px; border-top:1px solid var(--line2)}
  details.opt{margin-top:12px; padding-top:12px; border-top:1px solid var(--line2)}
  summary{font-family:var(--mono); font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink2); cursor:pointer; font-weight:600; list-style:none}
  summary::-webkit-details-marker{display:none}
  summary::before{content:"+ "; color:var(--pine)}
  details[open] summary::before{content:"– "}
  .opt-hint{font-size:11px; color:var(--ink2); margin:8px 0 0}

  /* Privacy policy prose */
  .policy{max-width:74ch}
  .policy h2{font-family:var(--disp); font-weight:700; font-size:17px; margin:26px 0 8px; letter-spacing:-.01em}
  .policy h2:first-of-type{margin-top:4px}
  .policy p{color:var(--ink2); font-size:14.5px; line-height:1.65; margin:0 0 12px}
  .policy a{color:var(--pine-d)}
  .policy .updated{margin-top:22px; font-size:12px; opacity:.7}

  /* Results table */
  .panel{background:var(--card); border:1px solid var(--line); border-radius:14px; padding:18px 18px 20px; margin-bottom:18px}
  .panel-head{display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-bottom:14px}
  .panel-head h2{font-family:var(--disp); font-weight:700; font-size:19px; margin:0; letter-spacing:-.01em}
  .panel-head .k{font-family:var(--mono); font-size:11px; color:var(--ink2)}

  .thead{display:grid; grid-template-columns:var(--colStudy) 1fr 1fr; gap:16px; align-items:start; padding-bottom:8px; border-bottom:1.5px solid var(--line)}
  .col-h{font-family:var(--disp); font-weight:700; font-size:14px; margin-bottom:6px}
  .col-cap{font-family:var(--mono); font-size:10px; letter-spacing:.04em; color:var(--ink2); margin-top:3px}
  .axiswrap{position:relative; padding:0 7px}
  .ruler{position:relative; height:44px}
  .ruler .scaleline{position:absolute; left:0; right:0; top:27px; height:1px; background:var(--line)}
  .tick{position:absolute; top:27px; transform:translateX(-50%); text-align:center}
  .tick i{display:block; width:1px; height:4px; background:var(--line); margin:0 auto}
  .tick span{font-family:var(--mono); font-size:9px; color:var(--ink2); display:block; margin-top:2px}
  .jdot{position:absolute; width:7px; height:7px; border-radius:50%; background:var(--pine-d); opacity:.45; transform:translate(-50%,-50%); pointer-events:none}
  .jdot.low{background:var(--clay); opacity:.6}
  .jdot.out{background:var(--flag); opacity:.7}
  .bellbox{position:relative}
  .jitter{position:absolute; inset:0; pointer-events:none}

  /* .trow itself no longer carries the grid - .trow-main does, so a row
     can grow a second, full-width child (.trow-detail) below the grid
     without fighting its column tracks. */
  .trow{padding:11px 0; border-bottom:1px solid var(--line2)}
  .trow-main{display:grid; grid-template-columns:var(--colStudy) 1fr 1fr; gap:16px; align-items:center}
  .trow.off{opacity:.45}
  .trow.off .cell-strip,.trow.off .cell-read,.trow.off .cell-grp{visibility:hidden}

  .scell{display:flex; gap:9px; align-items:flex-start}
  .box{flex:none; width:17px; height:17px; border:2px solid var(--line); border-radius:5px; margin-top:2px; position:relative; cursor:pointer; transition:.12s}
  .on-box .box{background:var(--pine); border-color:var(--pine)}
  .on-box .box::after{content:""; position:absolute; left:4.5px; top:1px; width:5px; height:9px; border:solid var(--card); border-width:0 2px 2px 0; transform:rotate(45deg)}
  .box.radio{border-radius:50%}
  .on-box .box.radio::after{left:50%; top:50%; width:7px; height:7px; border:0; border-radius:50%; background:var(--card); transform:translate(-50%,-50%)}
  .box.dis{opacity:.4; cursor:not-allowed}
  .snm{font-size:13px; font-weight:600; line-height:1.18}
  .smt{font-family:var(--mono); font-size:10px; color:var(--ink2); margin-top:2px}
  .sflag{font-family:var(--mono); font-size:9.5px; color:var(--flag); margin-top:3px; line-height:1.2}
  .sbadge{display:inline-block; font-family:var(--mono); font-size:9px; letter-spacing:.03em; color:var(--clay-d); background:var(--clay-t); border-radius:4px; padding:1px 5px; margin-top:3px}

  /* height/weight-vs-study-data detail panel (DEL 2, 2026-08-20) - the
     toggle is neutral text (a link, not a button-styled control) since
     it's disclosure, not an action with a consequence; the marker dot
     is deliberately --ink2 (the site's ordinary muted-text colour), NOT
     --flag/--clay - a genuine 2-SD distance isn't a warning the way an
     out-of-range age/BMI flag is, just something worth a glance. */
  .anthro-toggle{display:flex; align-items:center; gap:5px; margin-top:3px; font-family:var(--mono); font-size:9.5px; color:var(--pine); background:none; border:none; padding:0; cursor:pointer}
  .anthro-toggle:hover{text-decoration:underline}
  .anthro-marker{width:5px; height:5px; border-radius:50%; background:var(--ink2); flex:none}
  /* left padding matches .scell's text column (.box's 17px + the flex gap's
     9px, DEL 5 2026-08-22) so the panel's text starts flush with the study's
     own name/country line above it, not under the checkbox. */
  .trow-detail{padding:8px 0 2px 26px; margin-top:2px; border-top:1px dashed var(--line2)}
  .anthro-row{font-family:var(--mono); font-size:11px; color:var(--ink2); line-height:1.5}
  .anthro-row.outside{color:var(--flag)}
  /* DEL 4, 2026-08-21: the population panel's three layers need three visually
     distinct treatments, none of them the --flag/--clay warning colours -
     .outside above is the only one of the three that's a genuine extrapolation
     signal. */
  /* DEL 5, 2026-08-22: the sex-dependency + predictor-list header sits above
     the demographic rows, set apart by a dashed rule (matching the panel's
     own top border) rather than a colour change - it's a structural fact
     about the equation, not a verdict about this patient. */
  .anthro-meta{padding-bottom:6px; margin-bottom:6px; border-bottom:1px dashed var(--line2)}
  /* The printed-equation row (2026-08-22, kept permanently - see app.js's
     own comment above where it's built). Background tint (not just text
     colour) keeps it visually distinct from the rest of .anthro-meta: it's
     a technical/verification detail (the literal formula, Swedish only),
     not phrased in the same clinical prose as the sex-dependency/predictor
     line above it. */
  .anthro-eq{margin-top:6px; padding:6px 8px; background:var(--line2); border-radius:6px}
  .anthro-eq-label{font-weight:700}
  .anthro-eq-when{color:var(--ink2); font-style:italic}
  .anthro-eq-text{margin-top:2px; word-break:break-word}
  .anthro-eq-note{margin-top:2px; color:var(--ink2); font-style:italic}
  /* DEL 3 substitution row (BMI shown in place of an unreported weight) -
     italic is enough to mark "this line is standing in for another", no
     colour change, since it's neither a warning nor a different data type
     from the rest of the panel. */
  .anthro-row.substitute{font-style:italic}

  .celllab{display:none; font-family:var(--mono); font-size:9.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink2); margin-bottom:4px}
  .cell-read{font-family:var(--mono); font-size:11.5px; margin-bottom:4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
  .cell-read .big{font-size:14px; font-weight:700; color:var(--ink)}
  .cell-read .sep{color:var(--line); margin:0 2px}
  /* Same font/size/spacing rhythm as .cell-read on purpose (moved 2026-09-07,
     see HANDOVER.md) - deliberately NOT nowrap/ellipsis, so the matched norm
     cell's own sex+age span (.grp/.v-na inside) wraps instead of silently
     losing characters on a narrow viewport or a longer-language label. */
  .cell-grp{font-family:var(--mono); font-size:11.5px; margin-bottom:4px}
  .v-ok{color:var(--pine-d); font-weight:700} .v-low{color:var(--clay-d); font-weight:700} .v-na{color:var(--ink2)}
  .cell-empty{font-family:var(--mono); font-size:11px; color:var(--ink2); padding:6px 0}

  .strip{position:relative; height:30px; background:var(--line2); border-radius:6px; overflow:hidden}

  /* normative distribution curves */
  .normkey{position:relative; padding:0 7px}
  .bellwrap{position:relative; height:30px}
  .bell{display:block; width:100%; height:30px; overflow:visible}
  .bax{stroke:var(--line); stroke-width:.5}
  .bcurve{fill:var(--pine-t); stroke:var(--pine); stroke-width:.9; vector-effect:non-scaling-stroke}
  .btail{fill:var(--clay-t)}
  .bmean{stroke:var(--ink2); stroke-width:.9; vector-effect:non-scaling-stroke; stroke-dasharray:2 2}
  .bkey-labels{position:relative; height:12px; margin-top:2px}
  .bkey-labels span{position:absolute; transform:translateX(-50%); font-family:var(--mono); font-size:8.5px; color:var(--ink2)}
  .normcap{font-family:var(--mono); font-size:8.5px; letter-spacing:.02em; color:var(--ink2); text-align:center; margin-top:2px}
  .stmt{font-weight:700}
  .grp{color:var(--ink2)}
  .band{position:absolute; top:0; bottom:0}
  .band.normal{background:var(--pine-t)} .band.below{background:var(--clay-t)} .band.neutral{background:var(--neutral)}
  .edge{position:absolute; top:0; bottom:0; width:2px; background:var(--pine)}
  .pred{position:absolute; top:50%; width:10px; height:10px; border-radius:50%; transform:translate(-50%,-50%); background:var(--ink); border:2px solid var(--card)}
  .median{position:absolute; top:0; bottom:0; width:2px; background:var(--ink2)}
  .patdot{position:absolute; top:50%; width:11px; height:11px; border-radius:50%; transform:translate(-50%,-50%); background:var(--pat); border:2px solid var(--card); z-index:5}
  .legend-top{margin-top:0; margin-bottom:6px; padding-top:0; border-top:0}

  .ast{color:var(--clay-d); font-size:9px; font-weight:700; margin-left:1px; top:-.4em}
  .tblnote{font-size:11px; color:var(--ink2); line-height:1.5; margin:13px 0 0; max-width:96ch}
  .tblnote .ast{position:static; margin-right:2px}
  .legend{display:flex; flex-wrap:wrap; gap:12px 18px; margin-top:15px; padding-top:13px; border-top:1px solid var(--line2)}
  .legend div{display:flex; align-items:center; gap:7px; font-size:11px; color:var(--ink2)}
  .sw{width:14px; height:10px; border-radius:3px; flex:none}

  .interp p{margin:0 0 11px; font-size:14.5px; line-height:1.62}
  .interp p:last-child{margin-bottom:0}
  .interp .lead{font-weight:500}
  .interp b{color:var(--ink)}
  .caveat{background:var(--pine-t); border-radius:10px; padding:13px 15px; font-size:13px; color:var(--pine-d); line-height:1.55; margin-top:4px}

  /* copy-summary panel (DEL 4, 2026-08-20) */
  .copy-summary-row{display:flex; align-items:center; gap:14px; flex-wrap:wrap}
  .copy-summary-status{font-size:13px; color:var(--pine-d); font-weight:600; opacity:0; transition:opacity .15s ease}
  .copy-summary-status.show{opacity:1}
  .copy-summary-fallback{margin-top:14px}
  .copy-summary-fallback p{margin:0 0 8px; font-size:13px; color:var(--ink2); line-height:1.5}
  .copy-summary-fallback textarea{width:100%; font-family:var(--mono); font-size:12.5px; line-height:1.5; color:var(--ink); padding:12px; border:1px solid var(--line); border-radius:8px; background:var(--card); resize:vertical}
  .copy-summary-fallback textarea:focus{outline:2px solid var(--pat); outline-offset:1px; border-color:var(--pat)}

  footer{margin-top:26px; padding-top:18px; border-top:1px solid var(--line); color:var(--ink2); font-size:12px; line-height:1.6}
  footer b{color:var(--ink)}
  footer a{color:var(--pine-d)}
  footer .updated{margin-top:10px; opacity:.7}

  @media (max-width:820px){
    h1{font-size:24px}
    .pbar-grid{grid-template-columns:1fr 1fr}
    .pbar-extra{grid-template-columns:1fr}
    .thead{display:none}
    .trow{padding:14px 0}
    .trow-main{grid-template-columns:1fr; gap:10px}
    .trow.off .cell-strip,.trow.off .cell-read,.trow.off .cell-grp{visibility:visible}
    .celllab{display:block}
    .axiswrap{padding:0}
  }

/* ───────── cross-page nav (compare / new-test / privacy) ─────────
   Lives inside .mini-band-inner now (left side, language selector on
   the right), not in .wrap below the band - see .mini-band-inner's own
   comment. The base rule keeps light-surface colours (pine/line/ink2)
   for any page that hasn't adopted a band, so nothing regresses if this
   is reused somewhere without .mini-band; the .mini-band-scoped block
   right after it repaints for the dark band surface, the same way
   .band-topbar .lang / .mini-band .lang already do below.
   2026-08-20, matching blood-test-price-check's .topband/.bandtabs
   pattern: no arrows on the link labels any more (see i18n.js's
   NAV_TEXT), no "·" separators between items (spacing comes from the
   flex gap + each item's own padding instead), and the current page
   (.here) is a solid pill - background/text swapped, not just a
   muted-vs-bright colour difference - so the row reads as a row of tabs
   rather than a breadcrumb. */
.pagenav{display:flex; gap:2px; align-items:center; font-family:var(--mono); font-size:11.5px; flex-wrap:wrap}
.pagenav a, .pagenav .here{padding:7px 12px; border-radius:8px; font-weight:600}
.pagenav a{color:var(--pine); text-decoration:none}
.pagenav a:hover{text-decoration:underline}
.pagenav .here{color:var(--ink2)}

/* ───────── landing page ───────── */
.landing-grid{display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-bottom:18px}
@media (max-width:820px){ .landing-grid{grid-template-columns:1fr} }
.card-link{display:block; background:var(--card); border:1px solid var(--line); border-radius:14px; padding:22px 20px; text-decoration:none; color:inherit; transition:.12s border-color, .12s transform}
.card-link:hover{border-color:var(--pine); transform:translateY(-1px)}
.card-link:focus-visible{outline:2px solid var(--pat); outline-offset:2px}
.card-link .tag{font-family:var(--mono); font-size:10.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--pine); margin-bottom:8px}
.card-link h2{font-family:var(--disp); font-size:19px; font-weight:700; margin:0 0 8px; letter-spacing:-.01em}
.card-link p{margin:0; font-size:13.5px; color:var(--ink2); line-height:1.55}
.card-link .go{display:inline-block; margin-top:12px; font-family:var(--mono); font-size:11.5px; font-weight:600; color:var(--pine)}

/* ───────── landing page: sandwich band (top band / uncoloured middle / bottom
   band), scoped under body.landing so /compare/, /new/ and /privacy/ — which
   keep the plain shared footer{} below — are untouched. See CLAUDE.md for the
   pattern this is meant to be copied from for other tools. ─────────
   --band-* tokens are literal, deliberately NOT var(--pine)/var(--paper): a
   future edit to the content palette must never silently break the band's
   contrast.

   2026-08-19, second pass: --band-bg is --hero-bg from the sibling project
   blood-test-price-check (#28425F, dark navy) - reused verbatim, not
   re-derived, along with --hero-fg/--hero-muted/--hero-accent/--hero-
   surface(-strong)/--hero-border for the matching --band-* tokens below.
   This reverses the 2026-08-19 olive attempt earlier the same day (light-
   on-dark again, not dark-on-light) - see git history if you need the
   olive values for reference; they're gone from here now.
   Contrast checked against WCAG AA (4.5:1 normal text / 3:1 non-text),
   all measured against --band-bg #28425F (reusing blood-test-price-check's
   own measurements where its tokens are reused unmodified):
     --band-bg vs --band-fg (#FFFFFF)                10.32:1
     --band-bg vs --band-muted (#C7D3D8)               6.75:1
     --band-bg vs --band-accent-d (#8FE0D2)            6.76:1
   --band-accent is, as before, left at --pine's own raw value (unused
   directly - see --band-accent-d for what's actually painted).
   --band-border (28% white over --band-bg, blood-test-price-check's own
   --hero-border) measures only 2.24:1 against --band-bg *in that project's
   own design* - reused as-is anyway (see the --band-panel note below for
   why: matching their value exactly beats a "better" one that would just
   make the two sites diverge without fixing anything real). */
:root{
  --band-bg:#28425F; --band-fg:#FFFFFF; --band-muted:#C7D3D8;
  --band-accent:#00A087; --band-accent-d:#8FE0D2;
  --band-surface:rgba(255,255,255,.07); --band-surface-strong:rgba(255,255,255,.13);
  --band-border:rgba(255,255,255,.28);
}

/* Sticky footer: body becomes a flex column and the (band) footer's
   margin-top:auto eats the leftover space on short pages, instead of the
   page background showing below a footer that stops where the content
   does. Generalized beyond landing (was body.landing-scoped) so any page
   whose <footer class="landing-band"> is a direct <body> child gets the
   same behaviour automatically — no page-type class needed, the DOM
   shape (direct child + that class) is the opt-in. Inert on pages that
   haven't adopted the pattern yet: with a single non-growing .wrap child,
   body just reports a taller (still same-coloured) box, nothing visibly
   moves. See CLAUDE.md for the shared-identity pattern this belongs to. */
body{display:flex; flex-direction:column; min-height:100vh}
body > footer.landing-band{margin-top:auto; flex-shrink:0}

/* NOT ".band" — that class already exists (line ~159) for the results-
   table's coloured range strips (.band.normal/.below/.neutral, position:
   absolute). Reusing it here would silently inherit position:absolute
   and collapse the whole sandwich layout to one overlapping stack. */
.landing-band{background:var(--band-bg)}
/* Bottom padding trimmed 34px->22px (2026-08-20) - matches the top
   padding now, instead of carrying extra weight the copy didn't need.
   See .band-sub's own margin-bottom for the other half of this gap. */
.band-inner{max-width:1160px; margin:0 auto; padding:20px 22px 22px}
body.landing .wrap{padding-top:0}
/* The middle section (studies row + two cards) is shorter than the space
   the sticky footer leaves for it on tall/short-content viewports — center
   it as a group in that space instead of leaving the leftover gap glued to
   the bottom, above the footer. No effect once content exceeds the
   viewport (mobile, or a future taller middle section): flex-shrink still
   respects the content's own min height, so this never crops anything.
   Landing-only on purpose — work pages (/compare/, /new/) must stay
   top-aligned, not centered, so their forms don't jump around as content
   height changes. */
body.landing main.wrap{flex:1; display:flex; flex-direction:column; justify-content:center}

/* Thin top band: carries the cross-page nav (left) and language
   selector (right) on every work page (/compare/, /new/, /privacy/) —
   unlike .landing-band's hero content, nothing here needs to differ per
   page, so one shared height/markup works everywhere. See CLAUDE.md for
   why work pages get this instead of the landing page's full hero band.
   The nav used to sit below the band, inside .wrap - moved in here so
   the page's own scroll position doesn't cost a whole extra row: the
   band grows by one line, but .wrap's former nav row disappears, so the
   net height is unchanged (measured on /new/ at 390px, see HANDOVER.md). */
.mini-band{background:var(--band-bg)}
.mini-band-inner{max-width:1160px; margin:0 auto; padding:10px 22px; display:flex; justify-content:space-between; align-items:center; gap:10px 16px; flex-wrap:wrap}
.mini-band .pagenav{flex-wrap:wrap}
.mini-band .pagenav a{color:var(--band-accent-d)}
.mini-band .pagenav a:hover{color:var(--band-fg); text-decoration:none}
.mini-band .pagenav .here{background:var(--band-fg); color:var(--band-bg)}

.band-topbar{display:flex; justify-content:flex-end; margin-bottom:22px}
.band-topbar .lang, .mini-band .lang{color:var(--band-fg); background:var(--band-surface); border-color:var(--band-border)}
.band-topbar .lang:hover, .mini-band .lang:hover{border-color:var(--band-accent-d)}
.band-topbar .lang:focus-visible, .mini-band .lang:focus-visible{outline-color:var(--band-accent-d)}
.band-topbar .lang option, .mini-band .lang option{color:var(--ink); background:var(--card)}

.landing-band .eyebrow{color:var(--band-accent-d)}
.landing-band h1{color:var(--band-fg); font-size:clamp(28px,4.2vw,42px); margin:0 0 14px; text-wrap:balance}
/* margin-bottom trimmed 28px->14px (2026-08-20), matching h1's own
   margin-bottom for the same vertical rhythm - combined with
   .band-inner's own trim above, the gap between this paragraph and the
   band's bottom edge went from 62px to 36px (measured via
   getBoundingClientRect at 1400px: was 232.25->294.25, now
   232.25->268.25 with the same content). Not flush - the ask was less
   air, not none. */
.band-sub{max-width:58ch; color:var(--band-muted); font-size:16px; line-height:1.55; margin:0 0 14px}

/* example panel — non-interactive hero example. The bell curve + jitter
   dots inside .example are built by normviz.js's own bellboxWithLabels()/
   jitterDotsHTML(), the exact functions app.js uses for /compare/'s
   normative column.

   2026-08-20: moved out of the band entirely, onto .wrap's plain paper
   background — it used to sit inside the band on a darkened --band-panel
   surface (see git history for that version), which only existed to give
   --pat (a light cyan) enough contrast against a dark surface. That was
   solving the wrong problem: --clay/--flag/--pat are the SAME colours
   /compare/ uses to encode a patient's status (below LLN / out of range /
   the patient's own marker), and they must never render differently
   between the hero example and /compare/ - a red dot has to mean the same
   thing in both places. Keeping the panel on a dark surface meant every
   future palette tweak had to re-fight that contrast problem. Moving the
   panel onto the same white/paper surface /compare/ itself uses removes
   the conflict at the root: .example now carries ZERO colour overrides of
   its own anywhere below - card background, border, text, axis lines,
   tick labels, all of it falls through to the exact same rules /compare/
   uses (.panel, body text colours, .bax/.scaleline/.tick/.bkey-labels
   starting around line 150). See CLAUDE.md's "Sandwich landing page"
   section for the policy this is an instance of.

   2026-08-20: dropped the panel's own max-width:980px and the negative
   margin that pulled it up over the band's bottom edge. Both were wrong:
   the max-width made .example narrower than its siblings .landing-grid
   and .studies (which have none, so they simply fill .wrap's content
   box) - their left/right edges didn't line up. The negative margin
   made it overlap the band again, which the rest of this comment's
   history says was deliberately undone. .example needs no width rule at
   all: it's a plain block, a direct child of the same main.wrap as
   .landing-grid/.studies, so it already inherits their width for free -
   giving it one of its own is what broke the alignment. margin-top is
   ordinary positive spacing now, not a pull-up hack. */
.example{background:var(--card); border:1px solid var(--line); border-radius:16px; padding:22px 24px 20px; margin-top:32px}
.example-head{display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:16px}
.example-tag{font-family:var(--mono); font-size:10px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--pine-d); background:var(--pine-t); padding:3px 9px; border-radius:999px}
.example-profile{font-family:var(--mono); font-size:12.5px; color:var(--ink2)}

/* two panels — prediction (ruler, shared with /compare/'s #rulerP code)
   and normative placement (bell curve, shared with /compare/'s normKey) —
   side by side on desktop, stacked under the breakpoint. */
.example-panels{display:grid; grid-template-columns:1fr 1fr; gap:32px}
.example-panel-title{font-family:var(--disp); font-weight:700; font-size:14px; margin:0 0 12px; letter-spacing:-.01em}
@media (max-width:720px){ .example-panels{grid-template-columns:1fr; gap:28px} }

.example .bellbox{margin-top:0}

.example-note{font-size:12.5px; color:var(--ink2); line-height:1.55; margin:20px 2px 0; max-width:60ch}
.example-legend{display:flex; flex-wrap:wrap; gap:8px 18px; margin-top:14px; padding-top:12px; border-top:1px solid var(--line2)}
.example-legend div{display:flex; align-items:center; gap:7px; font-size:11.5px; color:var(--ink2)}
.example-legend i{width:9px; height:9px; border-radius:50%; flex:none}

@media (max-width:720px){ .example{padding:18px 16px; margin-top:24px} }

/* middle section: study row + the two cards (.landing-grid above) */
.studies{padding:34px 0 30px; text-align:center}
.studies-label{font-family:var(--mono); font-size:11px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink2); margin:0 0 16px}
.studies-label b{color:var(--ink); font-weight:700}
.study-pills{display:flex; gap:8px; justify-content:center; flex-wrap:wrap; max-width:920px; margin:0 auto}
.study-pill{font-family:var(--mono); font-size:12px; color:var(--ink2); background:var(--card); border:1px solid var(--line); border-radius:999px; padding:6px 13px}

/* bottom band (footer) — resets the shared footer{} box model (padding-top/
   border-top/margin-top), since .footer-inner below owns the real padding */
footer.landing-band{margin-top:0; padding-top:0; border-top:0}
.footer-inner{padding:30px 22px 34px; color:var(--band-muted); font-size:12.5px; line-height:1.62}
.footer-inner b{color:var(--band-fg)}
.footer-inner a{color:var(--band-accent-d); font-weight:600; text-decoration:none}
.footer-inner a:hover{text-decoration:underline}
.footer-inner .updated{margin-top:10px; opacity:.8; font-size:11.5px}

/* ───────── new-test page: timer + lap counter ───────── */
.timer-panel{text-align:center}
.timer-display{font-family:var(--mono); font-weight:700; font-size:64px; letter-spacing:-.02em; margin:6px 0 4px; color:var(--ink); font-variant-numeric:tabular-nums}
.timer-display.warn{color:var(--clay-d)}
.timer-sub{font-family:var(--mono); font-size:12px; color:var(--ink2); margin-bottom:18px}
.timer-controls{display:flex; gap:10px; justify-content:center; margin-bottom:18px; flex-wrap:wrap}
.btn{font-family:var(--disp); font-weight:600; font-size:14px; padding:10px 18px; border-radius:10px; border:1px solid var(--line); background:var(--card); color:var(--ink); cursor:pointer; transition:.12s}
.btn:hover{border-color:var(--pine)}
.btn:disabled{opacity:.4; cursor:not-allowed}
.btn.primary{background:var(--pine); border-color:var(--pine); color:#fff}
.btn.primary:hover{background:var(--pine-d)}
.btn.ghost{background:transparent}
.btn.danger{background:transparent; border-color:var(--clay); color:var(--clay-d)}
.btn.danger:hover{background:var(--clay-t)}
.hold-btn{position:relative; overflow:hidden; -webkit-touch-callout:none; -webkit-user-select:none; user-select:none; touch-action:none}
.hold-fill{position:absolute; inset:0; width:0%; background:var(--clay); opacity:.3; pointer-events:none}
.hold-label{position:relative; z-index:1; -webkit-touch-callout:none; -webkit-user-select:none; user-select:none}
.lap-btn{display:block; width:100%; max-width:420px; margin:0 auto 16px; padding:30px 0; font-family:var(--disp); font-weight:700; font-size:22px; border-radius:16px; border:2px solid var(--pine); background:var(--pine-t); color:var(--pine-d); cursor:pointer; transition:.1s transform}
.lap-btn:active{transform:scale(.97)}
.lap-btn:disabled{opacity:.35; cursor:not-allowed; border-color:var(--line); background:var(--neutral); color:var(--ink2)}
.lap-stats{display:flex; justify-content:center; flex-wrap:wrap; gap:28px; margin-bottom:6px}
.lap-stat{text-align:center}
.lap-stat b{display:block; font-family:var(--mono); font-size:22px; color:var(--ink)}
.lap-stat span{font-family:var(--mono); font-size:10.5px; color:var(--ink2); text-transform:uppercase; letter-spacing:.06em}
.setup-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:14px}
@media (max-width:820px){ .setup-grid{grid-template-columns:1fr 1fr} }
.setup-grid .pf label{display:block; font-size:11.5px; color:var(--ink2); margin-bottom:5px; font-weight:500}
.finish-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-bottom:14px}
@media (max-width:820px){ .finish-grid{grid-template-columns:1fr 1fr} }
.result-big{text-align:center; padding:18px 0}
.result-big b{display:block; font-family:var(--disp); font-size:40px; font-weight:700; color:var(--pine-d)}
.result-big span{font-family:var(--mono); font-size:12px; color:var(--ink2)}
.field-hint{font-family:var(--mono); font-size:11px; color:var(--clay-d); margin-top:5px}
.recovery-panel{margin:18px 0; padding-top:14px; border-top:1px solid var(--line2)}
#recoveryPreStart .pf{margin-bottom:14px}
.recovery-status{font-family:var(--mono); font-size:12px; color:var(--ink2); text-align:center; margin:0 0 10px}
.pf.pf-missing label{color:var(--clay-d)}
.pf.pf-missing input{border-color:var(--clay)}
.pf.pf-invalid label{color:var(--clay-d)}
.pf.pf-invalid input{border-color:var(--clay)}
.compare-missing{font-family:var(--mono); font-size:12px; color:var(--clay-d); text-align:center; margin-top:12px}
.btn-sub{display:block; font-size:10.5px; font-weight:500; opacity:.75; margin-top:2px}
.chipgroup{display:flex; flex-wrap:wrap; gap:8px; margin-top:8px}
.chip{font-family:var(--disp); font-size:13px; font-weight:500; padding:7px 14px; border:1px solid var(--line); background:var(--card); color:var(--ink2); border-radius:999px; cursor:pointer; transition:.12s}
.chip.on{background:var(--ink); color:var(--card); border-color:var(--ink)}
.chip:focus-visible{outline:2px solid var(--pat); outline-offset:2px}
.modal-overlay{position:fixed; inset:0; background:rgba(0,0,0,.5); display:flex; align-items:center; justify-content:center; padding:20px; z-index:50}
.modal-box{background:var(--card); border-radius:14px; padding:24px; max-width:420px; width:100%; box-shadow:0 20px 60px rgba(0,0,0,.35)}
.modal-box h3{margin:0 0 10px; font-family:var(--disp); font-size:19px; font-weight:700}
.modal-box p{margin:0 0 20px; font-size:14px; color:var(--ink2); line-height:1.5}
.modal-actions{display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap}
.lap-summary{margin-top:18px; padding-top:16px; border-top:1px solid var(--line2); text-align:left}
.lap-summary-stats{font-family:var(--mono); font-size:12.5px; color:var(--ink); margin:0}
.lap-summary-caveat{font-family:var(--mono); font-size:11px; color:var(--ink2); margin:5px 0 0; font-style:italic}
.lap-list{max-height:220px; overflow-y:auto; margin-top:10px; border:1px solid var(--line2); border-radius:8px}
.vitals-strip-label{font-family:var(--mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--ink2); text-align:center; margin:18px 0 8px}
.vitals-strip{display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-bottom:14px}
.vitals-slot{font-family:var(--mono); font-size:11px; text-align:center; padding:8px 6px; border:1px solid var(--line); border-radius:10px; background:var(--card); color:var(--ink2); cursor:pointer; transition:.12s; min-width:58px}
.vitals-slot b{display:block; font-size:12.5px; color:var(--ink); margin-top:3px; font-weight:700}
.vitals-slot.pending{border-color:var(--pat); animation:vitalsPulse 1.6s ease-in-out infinite}
.vitals-slot.filled{border-color:var(--pine); background:var(--pine-t)}
.vitals-slot.active{border-color:var(--ink); background:var(--ink); color:var(--card)}
.vitals-slot.active b{color:var(--card)}
.vitals-slot:disabled{opacity:.35; cursor:not-allowed}
.vitals-slot.missed{border-color:var(--clay); background:var(--clay-t); color:var(--clay-d)}
.vitals-slot.missed b{color:var(--clay-d)}
@keyframes vitalsPulse{0%,100%{box-shadow:0 0 0 2px rgba(77,187,213,.3)} 50%{box-shadow:0 0 0 5px rgba(77,187,213,.05)}}
.vitals-editor{max-width:340px; margin:0 auto 14px; padding:16px; border:1px solid var(--line); border-radius:12px; background:var(--card)}
.vitals-editor-title{font-family:var(--mono); font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--ink2); text-align:center; margin:0 0 12px}
.vitals-field{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:12px}
.vitals-field label{font-size:13px; color:var(--ink2); font-weight:500}
.stepper{display:flex; align-items:center; gap:10px}
.stepper-btn{width:36px; height:36px; border-radius:50%; border:1px solid var(--line); background:var(--card); font-size:18px; font-weight:700; color:var(--ink); cursor:pointer}
.stepper-btn:active{background:var(--neutral)}
.stepper-value{font-family:var(--mono); font-size:17px; font-weight:700; min-width:38px; text-align:center}
.lap-row{display:flex; align-items:center; gap:8px; padding:6px 10px; font-family:var(--mono); font-size:12px; color:var(--ink2); border-bottom:1px solid var(--line2)}
.lap-row:last-child{border-bottom:none}
.lap-row span:first-child{flex:0 0 auto; color:var(--ink); font-weight:600}
.lap-row span:nth-child(2){flex:1}
.lap-row.lap-row-rest{background:var(--neutral)}
.lap-rest-tag{font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--pine-d); background:var(--pine-t); border-radius:4px; padding:2px 6px}
.lap-short-tag{font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--ink2); background:var(--neutral); border-radius:4px; padding:2px 6px}
.hidden{display:none !important}
