@font-face{
  font-family:"Mulish";
  src:url("fonts/mulish-latin-var.woff2") format("woff2");
  font-weight:200 1000;font-style:normal;font-display:swap;
}

/* =========================================================================
   Tokens — 4basecare.com design language (context.md §2, checked against the
   live site's published :root, which matches value for value).
   ====================================================================== */
:root{
  --primary:#0E76BC; --primary-hover:#2080C0; --primary-active:#2985C3; --on-primary:#fff;
  /* The site's hover/active blues are lighter than the base, which drops white
     text to 4.28:1 and 4.11:1. For filled buttons we darken instead, so white
     on blue stays above AA in every state. */
  --primary-btn-hover:#0B5E97; --primary-btn-active:#094E7D;
  --primary-08:#0E76BC14; --primary-12:#0E76BC1F;
  --secondary:#953873; --secondary-tint:#FFAEDA;

  --surface:#F2F2F4; --surface-variant:#EFF0F7; --surface-variant-hover:#DEDFE6;
  --surface-container:#EEEDF1; --surface-container-hover:#DDDCE0; --card:#FFFFFF;

  --on-surface:#191C20; --on-surface-variant:#3C4949; --outline:#C1C7D2;
  /* The site's --outline is a 1.5:1 hairline. It is fine for dividers, but a
     control boundary needs 3:1 (WCAG 1.4.11), so interactive edges use this
     darker grey: 3.57:1 on white, 3.19:1 on the page. */
  --outline-strong:#828892;
  --on-surface-08:#191C2014; --on-surface-12:#191C201F;

  --radius-card:12px; --radius-panel:20px; --radius-pill:999px;
  --shadow-card:0 4px 12px rgba(0,0,0,.08);
  --shadow-raised:0 4px 12px rgba(0,0,0,.12);
  --glass:rgba(255,255,255,.6); --glass-blur:blur(8px);
  --font:"Mulish",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --ease:cubic-bezier(.4,0,.2,1);

  /* Semantic tints for the result blocks. The site has no status colours, so
     these are the prototype's meanings desaturated to sit on #F2F2F4, with
     plum as the single "attention" accent so the page still reads 4baseCare. */
  --guide-ink:#7A4A12; --guide-bg:#FBF4EA; --guide-line:#E8DCC8;
  --stop-ink:#8E2F2F;  --stop-bg:#FBEFEF;  --stop-line:#EBD3D3;
  --cmp-ink:#3E5C28;   --cmp-bg:#F2F6EC;   --cmp-line:#DCE6CF;
  --sample-ink:#0E5E7A;--sample-bg:#EAF2F6;--sample-line:#CFE0E9;
  --mono-ink:#3C4949;

  --toolbar-h:72px;
  --safe-t:env(safe-area-inset-top); --safe-b:env(safe-area-inset-bottom);
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}

/* =========================================================================
   THE PAGE CANNOT SCROLL
   ---------------------------------------------------------------------
   The document itself is locked to the viewport: overflow is hidden on both
   html and body, so documentElement.scrollHeight can never exceed
   clientHeight. Everything below is about making a step FIT inside that,
   rather than about hiding a scrollbar.

   #app is a flex column the exact height of the viewport. 100vh is written
   first as the fallback; 100dvh then wins where it is supported, which is
   what stops a phone's collapsing address bar from leaving the action bar
   below the fold. Header, progress and chip rail are fixed-size rows; the
   content region is the one that flexes, and it carries min-height:0 so a
   tall child shortens it instead of pushing the action bar off the end.

   Only #main may scroll, and on a question step it is not supposed to need
   to — verify fails the build if it does at a desktop size. The result
   screen is a long clinical document and scrolls inside #main by design.
   ====================================================================== */
html,body{margin:0;padding:0;height:100%;overflow:hidden}
body{
  background:var(--surface); color:var(--on-surface);
  font-family:var(--font); font-size:16px; line-height:1.55; font-weight:400;
  overscroll-behavior-y:none;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}
#app{
  display:flex;flex-direction:column;
  height:100vh;      /* fallback first */
  height:100dvh;     /* wins where supported; survives a collapsing URL bar */
  max-height:100vh;max-height:100dvh;overflow:hidden;
  /* Containing block for the visually-hidden "required" spans. They are
     position:absolute, and without a positioned ancestor they resolve against
     the initial containing block - which let one sitting deep in the scrolled
     content report a document 20px taller than the viewport. */
  position:relative;
}
#app > header,#app > .rail,#app > footer{flex:0 0 auto}

/* =========================================================================
   Header — the site's floating translucent toolbar, inset from the edges.
   ====================================================================== */
header{
  position:relative;z-index:30;
  padding:calc(8px + var(--safe-t)) 16px 0;background:transparent;
}
.hrow{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  height:60px;padding:8px 10px 8px 16px;
  background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  border-radius:var(--radius-card);box-shadow:var(--shadow-raised);
}
.lock{display:flex;align-items:center;gap:12px;min-width:0}
.logo-img{height:28px;width:auto;display:block;flex:0 0 auto}
.lock .rule{width:1px;height:18px;background:var(--outline);flex:0 0 auto}
.lock .tool{
  font-size:14px;font-weight:400;color:var(--on-surface-variant);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
@media (max-width:409px){ .lock .tool,.lock .rule{display:none} }

.restart{
  flex:0 0 auto;background:var(--primary-08);border:none;color:var(--on-surface);
  font:inherit;font-size:13px;font-weight:600;padding:7px 16px;min-height:36px;
  border-radius:var(--radius-pill);cursor:pointer;box-shadow:var(--shadow-card);
  transition:background .2s var(--ease);
}
.restart:hover{background:var(--primary-12)}
.restart:active{background:var(--primary-12)}
.restart:focus-visible{outline:3px solid var(--primary);outline-offset:2px}

/* progress: see PROGRESS at the end of this file */

/* =========================================================================
   Answer chips (edit-and-rerun rail) — translucent white pills.
   Always ONE row (P23): chips that do not fit are gathered behind a final
   "+N more" chip, which opens them over the page (.railpop), so the rail's
   height never depends on how many answers there are.
   ====================================================================== */
.rail{
  display:flex;flex-wrap:nowrap;gap:8px;overflow:hidden;padding:8px 16px 0;
  width:100%;min-width:0;background:transparent;
}
.rail button,.railpop button{
  flex:0 0 auto;background:var(--glass);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  border:1px solid var(--outline-strong);color:var(--on-surface-variant);
  font:inherit;font-size:13px;padding:5px 12px;min-height:30px;border-radius:var(--radius-pill);
  white-space:nowrap;cursor:pointer;max-width:56vw;overflow:hidden;text-overflow:ellipsis;
  transition:background .2s var(--ease),border-color .2s var(--ease);
}
.rail button:hover,.railpop button:hover{background:#fff;border-color:var(--primary)}
/* Inset: the one-row rail clips anything outside it. */
.rail button:focus-visible{outline:3px solid var(--primary);outline-offset:-3px}
.railpop button:focus-visible{outline:3px solid var(--primary);outline-offset:2px}
.rail .more-chip{color:var(--primary-btn-hover);font-weight:600;border-color:var(--primary)}
.railpop{
  position:absolute;z-index:40;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
  padding:10px;background:var(--card);border:1px solid var(--outline);border-radius:var(--radius-card);
  box-shadow:var(--shadow-raised);max-width:min(420px, calc(100vw - 16px));max-height:60vh;overflow:auto;
}
.railpop button{max-width:100%}

/* =========================================================================
   Step body — a comfortable reading column on desktop.
   ====================================================================== */
/* The only scrollable region, and on a question step it should not need to
   scroll at all. min-height:0 is what lets it shrink instead of pushing the
   action bar off the bottom; scrollbar-gutter keeps the column from shifting
   sideways when the result screen does scroll. */
main{
  flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;
  scrollbar-gutter:stable;
  width:100%;max-width:1680px;margin:0 auto;padding:10px 16px 4px;
}
.step-no{
  font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:none;
  color:var(--on-surface-variant);margin:0 0 2px;line-height:1.35;font-variant-numeric:tabular-nums;
}
h1{font-size:23px;line-height:1.25;font-weight:600;letter-spacing:-.02em;margin:0 0 4px}
/* The step heading is focused programmatically on every step change so screen
   readers announce the new question. Chromium treats that as :focus-visible
   and paints its default outline round the whole heading, which every control
   here replaces with the 3px brand ring. Suppressing it is the standard
   route-change focus-target pattern; the move is still announced. */
h1[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible{outline:none}
.sub{font-size:14px;font-weight:300;color:var(--on-surface-variant);margin:0 0 8px;line-height:1.45}
/* .hint doubles as the per-question label on multi-question steps, which is
   why it is 15px/600 rather than body copy. */
.hint{font-size:15px;font-weight:600;color:var(--on-surface-variant);margin:0 0 5px;line-height:1.3}

.search{
  display:block;width:100%;max-width:440px;padding:8px 16px;font:inherit;font-size:14px;font-weight:400;
  border:1px solid var(--outline-strong);border-radius:var(--radius-pill);
  background:var(--card);margin-bottom:8px;color:var(--on-surface);min-height:38px;
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease);
}
.search::placeholder{color:var(--on-surface-variant);opacity:1}
.search:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-12)}
.search:focus-visible{outline:3px solid var(--primary);outline-offset:2px}

/* option cards */
/* Options flow into columns instead of growing downward. auto-fit means a
   two-option question sits side by side on desktop and stacks on a phone,
   with no per-question column count to maintain. */
.opts{display:grid;grid-template-columns:repeat(auto-fit,minmax(165px,1fr));gap:5px;margin:0 0 5px}
.opt{
  display:flex;align-items:flex-start;gap:10px;width:100%;text-align:left;
  background:var(--card);border:1px solid transparent;border-radius:12px;
  padding:11px 14px;font:inherit;cursor:pointer;color:var(--on-surface);
  min-height:44px;box-shadow:var(--shadow-card);
  transition:border-color .2s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease);
}
.opt:hover{border-color:var(--outline);box-shadow:var(--shadow-raised)}
.opt:active{background:var(--surface-variant)}
.opt.sel{border-color:var(--primary);background:var(--primary-08);box-shadow:var(--shadow-raised)}
.opt:focus-visible{outline:3px solid var(--primary);outline-offset:2px}
.tick{
  flex:0 0 18px;width:18px;height:18px;border-radius:var(--radius-pill);
  border:1.5px solid var(--outline-strong);margin-top:1px;display:grid;place-items:center;background:#fff;
  transition:background .2s var(--ease),border-color .2s var(--ease);
}
.opt.sel .tick{background:var(--primary);border-color:var(--primary)}
.tick svg{width:11px;height:11px;display:none}
.opt.sel .tick svg{display:block}
.otxt b{display:block;font-weight:400;font-size:15px;line-height:1.3;letter-spacing:-.01em}
/* The one-line clinical note is a REVEAL, not a removal. It stays in the DOM
   and is collapsed with max-height:0 rather than display:none, so a screen
   reader still reads it, textContent still contains it, and the UI golden
   does not churn. It opens on hover, on keyboard focus and when selected. */
.otxt small{
  display:block;color:var(--on-surface-variant);font-size:13px;font-weight:300;
  line-height:1.4;max-height:0;overflow:hidden;margin-top:0;
  transition:max-height .18s var(--ease),margin-top .18s var(--ease);
}
.opt:hover .otxt small,
.opt:focus-visible .otxt small,
.opt.sel .otxt small{max-height:2.9em;margin-top:2px}
@media (prefers-reduced-motion:reduce){ .otxt small{transition:none} }

/* =========================================================================
   Action bar
   ====================================================================== */
/* Pinned by being the last row of the #app flex column, not by position:
   sticky - a flex row cannot be pushed off a container it is sized against. */
footer{
  position:relative;z-index:30;width:100%;max-width:none;margin:0;
  height:76px;background:var(--card);border-top:1px solid var(--outline);
  box-shadow:0 -2px 10px rgba(0,0,0,.05);
  padding:12px 16px calc(12px + var(--safe-b));display:flex;gap:12px;align-items:center;
}
.btn{
  flex:1;border:none;border-radius:var(--radius-pill);font:inherit;font-size:15px;font-weight:600;
  padding:10px 24px;cursor:pointer;min-height:44px;
  transition:background .2s var(--ease),box-shadow .2s var(--ease),color .2s var(--ease);
}
.btn:focus-visible{outline:3px solid var(--primary);outline-offset:2px}
.btn.prim{background:var(--primary);color:var(--on-primary);box-shadow:var(--shadow-card)}
.btn.prim:hover:not(:disabled){background:var(--primary-btn-hover)}
.btn.prim:active:not(:disabled){background:var(--primary-btn-active)}
.btn.prim:disabled{background:var(--surface-container);color:var(--on-surface-variant);cursor:default;box-shadow:none}
.btn.ghost{
  flex:0 0 96px;background:var(--surface-variant);color:var(--on-surface);
  border:1px solid var(--outline-strong);box-shadow:var(--shadow-raised);
}
.btn.ghost:hover{background:var(--surface-variant-hover)}

/* =========================================================================
   Result — white card, no navy slab. Wider column than the questions.
   ====================================================================== */
.slip{
  background:var(--card);border-radius:var(--radius-panel);overflow:hidden;
  border:none;box-shadow:var(--shadow-card);margin-bottom:20px;
}
.slip-top{background:var(--card);color:var(--on-surface);padding:32px 32px 24px;border-bottom:1px solid var(--outline)}
.slipmark{display:flex;align-items:center;gap:10px;margin-bottom:20px}
.slipmark .logo-img{height:30px}
.slip-top .lab{
  font-size:16px;font-weight:400;letter-spacing:.08em;color:var(--secondary);margin-bottom:8px;
}
.slip-top h1{margin:0;font-size:32px;line-height:1.32;font-weight:300;letter-spacing:-.02em;color:var(--on-surface)}
.slip-top .meta{margin-top:12px;font-size:16px;font-weight:300;color:var(--on-surface-variant);line-height:1.5}
.slip-body{padding:24px 32px 28px}
.kv{display:flex;gap:16px;padding:14px 0;border-top:1px solid var(--outline);font-size:16px}
.kv:first-child{border-top:none;padding-top:4px}
.kv dt{flex:0 0 120px;color:var(--on-surface-variant);font-size:16px;font-weight:300}
.kv dd{margin:0;flex:1;font-weight:400}

/* tinted blocks — meanings preserved, tints harmonised to the palette */
.blk{
  border-radius:var(--radius-card);padding:20px;margin-bottom:16px;
  font-size:16px;line-height:1.55;font-weight:300;
}
.blk h2{margin:0 0 10px;font-size:18px;font-weight:400;letter-spacing:-.01em}
.blk.g{background:var(--guide-bg);border:1px solid var(--guide-line)}       /* guidance */
.blk.g h2{color:var(--guide-ink)}
.blk.m{background:var(--card);border:1px solid var(--outline);box-shadow:var(--shadow-card)}  /* monitoring */
.blk.m h2{color:var(--primary)}
.blk.w{background:var(--stop-bg);border:1px solid var(--stop-line)}          /* caution */
.blk.w h2{color:var(--stop-ink)}
.blk.c{background:var(--cmp-bg);border:1px solid var(--cmp-line)}            /* comparison */
.blk.c h2{color:var(--cmp-ink)}
.blk.s{background:var(--sample-bg);border:1px solid var(--sample-line)}      /* sample */
.blk.s h2{color:var(--sample-ink)}
.blk ul{margin:10px 0 0;padding-left:22px}
.blk li{margin-bottom:8px}
.blk li:last-child{margin-bottom:0}

.verdict{font-size:22px;font-weight:300;line-height:1.35;color:var(--on-surface);margin:8px 0 4px;letter-spacing:-.02em}
.strategy{font-size:16px;font-weight:300;color:var(--on-surface-variant);margin-bottom:16px}
.meters{display:flex;flex-direction:column;gap:10px}
.meter{
  display:flex;align-items:center;gap:12px;background:var(--card);
  border:1px solid var(--outline);border-radius:var(--radius-card);padding:12px 16px;
}
.ml{flex:1;font-size:16px;font-weight:300;color:var(--on-surface-variant);line-height:1.4}
.mv{font-size:16px;font-weight:400;padding:4px 12px;border-radius:var(--radius-pill);white-space:nowrap}
.mv.hi{background:var(--cmp-bg);color:var(--cmp-ink)}
.mv.mid{background:var(--guide-bg);color:var(--guide-ink)}
.mv.lo{background:var(--stop-bg);color:var(--stop-ink)}
.ms{font-size:16px;font-weight:300;color:var(--on-surface-variant);white-space:nowrap}

.cmp{width:100%;border-collapse:collapse;margin-top:12px;font-size:16px;line-height:1.45}
.cmp thead td{border-top:none;padding:0}
.cmp th{text-align:left;font-weight:400;color:var(--cmp-ink);padding:0 10px 8px 0;font-size:16px;letter-spacing:.08em}
.cmp td{padding:10px 10px 10px 0;border-top:1px solid var(--cmp-line);vertical-align:top;overflow-wrap:break-word;font-weight:300}
.cmp td.k{font-weight:400;width:31%}
.cmp td.b{width:1%;white-space:nowrap;padding-right:0}
.win{display:inline-block;font-size:16px;font-weight:400;padding:4px 12px;border-radius:var(--radius-pill);white-space:nowrap}
.win.f{background:var(--cmp-bg);color:var(--cmp-ink)}
.win.i{background:var(--primary-12);color:#0B5A90}
.win.w{background:var(--guide-bg);color:var(--guide-ink)}

.genes{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.gene{
  background:var(--card);border:1px solid var(--outline);color:var(--on-surface);
  border-radius:var(--radius-pill);padding:8px 16px;font-size:16px;font-weight:400;font-style:italic;
}
.gene.plain{font-style:normal;font-weight:300;color:var(--on-surface-variant)}

.disc{font-size:16px;font-weight:300;color:var(--on-surface-variant);line-height:1.55;padding:4px 2px 12px}
.hidden{display:none}

.ref{background:var(--card);border:1px solid var(--outline-strong);border-radius:var(--radius-card);margin-bottom:16px;overflow:hidden}
.ref summary{padding:18px 20px;font-size:18px;font-weight:400;color:var(--primary);cursor:pointer;list-style:none;min-height:56px;display:flex;align-items:center}
.ref summary::-webkit-details-marker{display:none}
.ref summary:focus-visible{outline:3px solid var(--primary);outline-offset:-3px}
.ref summary::after{content:"+";margin-left:auto;color:var(--on-surface-variant);font-weight:400;font-size:20px;line-height:1}
.ref[open] summary::after{content:"\2013"}
.ref[open] summary{border-bottom:1px solid var(--outline)}
.refrow{padding:16px 20px;border-top:1px solid var(--outline)}
.refrow:first-of-type{border-top:none}
.refrow b{display:block;font-size:16px;font-weight:400;color:var(--on-surface);margin-bottom:4px}
.refrow p{margin:0 0 6px;font-size:16px;font-weight:300;color:var(--on-surface-variant);line-height:1.5}
.refrow cite{font-size:16px;font-weight:300;color:var(--on-surface-variant);font-style:normal}

/* =========================================================================
   Desktop — the questions keep a reading column, the result gets more room.
   ====================================================================== */
@media (min-width:768px){
  header{padding:calc(8px + var(--safe-t)) 20px 0}
  .hrow{height:60px;padding:8px 12px 8px 20px;max-width:1680px;margin:0 auto}
  .logo-img{height:30px}
  .bar{max-width:1680px;margin:0 auto}
  .rail{width:100%;max-width:1680px;margin:0 auto;padding:8px 20px 0}
  main{padding:10px 20px 4px}
  footer{padding:12px max(20px, calc((100% - 1680px) / 2 + 20px)) calc(12px + var(--safe-b));justify-content:flex-start}

  .rail button{max-width:none}

  /* Content-width pills in the site's style, not buttons stretched across
     the whole column. */
  .btn{flex:0 0 auto;padding:10px 32px}
  .btn.ghost{flex:0 0 auto;padding:10px 24px}
  /* The compact scale holds at every width. The result screen keeps a larger
     heading: it is a document to read, not a question to answer, and it is
     the one screen allowed to scroll inside #main. */
  .slip-top h1{font-size:30px}

  /* the result is wider than the question column */
  main:has(.slip){max-width:1032px}
  #app:has(main .slip) footer{padding-left:max(20px, calc((100% - 1032px) / 2 + 20px));padding-right:max(20px, calc((100% - 1032px) / 2 + 20px))}
}
@media (min-width:1440px){
  main:has(.slip){max-width:1180px}
  #app:has(main .slip) footer{padding-left:max(20px, calc((100% - 1180px) / 2 + 20px));padding-right:max(20px, calc((100% - 1180px) / 2 + 20px))}
}

/* Fallback for engines without :has() — the result simply keeps the
   reading column, which is a narrower layout, never a broken one. */

/* =========================================================================
   Phones: four columns of 16px text leave the comparison cells narrow enough
   that words break inside themselves ("Afforda|bility"). Below 768px each
   factor becomes its own card with its two values labelled, so nothing has to
   be squeezed. The labels are CSS generated content, which is deliberate:
   innerText ignores it, so the harness sees exactly the same words as before.
   ====================================================================== */
@media (max-width:767px){
  .cmp,.cmp tbody,.cmp tr,.cmp td{display:block;width:auto}
  .cmp thead{display:none}
  .cmp{margin-top:8px}
  .cmp tr{
    background:var(--card);border:1px solid var(--cmp-line);border-radius:var(--radius-card);
    padding:16px;margin-top:12px;
  }
  .cmp td{border-top:none;padding:0;overflow-wrap:normal}
  .cmp td.k{width:auto;font-size:18px;font-weight:400;margin-bottom:12px;letter-spacing:-.01em}
  .cmp td:nth-child(2),.cmp td:nth-child(3){margin-bottom:10px}
  .cmp td:nth-child(2)::before,.cmp td:nth-child(3)::before{
    display:block;font-size:16px;font-weight:400;letter-spacing:.08em;
    color:var(--cmp-ink);margin-bottom:2px;
  }
  .cmp td:nth-child(2)::before{content:"First"}
  .cmp td:nth-child(3)::before{content:"Indiegene"}
  .cmp td.b{width:auto;white-space:normal;padding:0;margin-top:4px}
  .cmp td.b:empty{display:none}
}

@media (prefers-reduced-motion:no-preference){
  main.anim{animation:in .22s var(--ease)}
  @keyframes in{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
}

/* =========================================================================
   Print — logo and result on white, no toolbar and no action bar.
   ====================================================================== */
@media print{
  header,footer,.rail,.pager{display:none}
  body,#app{background:#fff}
  main,main:has(.slip){max-width:none;padding:0}
  .printhead{
    display:flex;align-items:center;gap:12px;padding:0 0 16px;margin-bottom:16px;
    border-bottom:1px solid var(--outline);
  }
  .printhead .logo-img{height:36px}
  .printhead .tool{font-size:16px;color:var(--on-surface-variant)}
  .slip{box-shadow:none;border:1px solid var(--outline)}
  .slip,.blk,.meter,.ref{break-inside:avoid}
  .opt,.restart{box-shadow:none}
}
.printhead{display:none}

/* =========================================================================
   REQUIRED FIELDS
   ---------------------------------------------------------------------
   An asterisk on its own is announced as "star", which tells a screen-reader
   user nothing. So the asterisk is decorative (aria-hidden) and the meaning
   is carried by visually-hidden text plus aria-required on the group.
   ====================================================================== */
/* Set apart from the text it follows. Hard against a question mark it read as
   a typo ("for?*"); with a clear gap it reads as the form convention it is. */
.req{color:var(--stop-ink);font-weight:600;margin-left:.4em}
h1 .req{font-size:.8em;vertical-align:.15em}
.vh{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
.reqlegend{font-size:12px;font-weight:400;color:var(--on-surface-variant);margin-left:10px}

/* The question currently asking to be answered. Paired with focus moving to
   its first option, so the highlight and the keyboard are never in different
   places. */
.qblock{margin:0 0 4px}
/* The site blue is 4.33:1 on the page grey, just short of AA for 15px text;
   the darker button-hover blue is 6.4:1. Same reason the filled buttons use it. */
.qblock.active > .hint{color:var(--primary-btn-hover)}
.qblock.active > .opts{
  outline:2px solid var(--primary-12);outline-offset:6px;border-radius:8px;
}
@media (prefers-reduced-motion:reduce){ .qblock.active > .opts{transition:none} }

/* =========================================================================
   SMALL SCREENS
   The scale the prompt sets for phones. Pagination is Prompt 17; this only
   makes the shell itself fit.
   ====================================================================== */
@media (max-width:640px){
  .hrow{height:54px}
  footer{height:78px}
  /* 6px, not 10: with the 26px bar the constraints step with two notes open sat
     on a 1px boundary at 390x844. Spacing, not content, pays for the bar. */
  main{padding:6px 14px 4px}
  h1{font-size:21px}
  .opts{grid-template-columns:1fr;gap:6px}
}

/* Group name inside the cancer picker, and the explanatory line a question may
   carry under its label. Both were inline-styled .hint before; they are now
   named, because .hint means "question label" and these are not that. */
.grouphead{
  font-size:13px;font-weight:600;letter-spacing:.04em;color:#12242F;
  margin:5px 0 3px;break-after:avoid;line-height:1.3;
}
.qblock > .opts + .grouphead,.grouphead:first-child{margin-top:0}
.qnote{
  font-size:12px;font-weight:300;color:var(--on-surface-variant);
  margin:-4px 0 6px;line-height:1.4;
}

/* Step 1 (P29): sites across the top as tiles, the open site's types below.
   One layout at every size. The open tile's name is the darker button blue:
   #0E76BC on #E7F1F9 is 4.23:1, short of AA; #0B5E97 is 5.99:1. */
.pk-title{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:4px 24px}
.pk-hd{flex:1 1 400px;min-width:0}
.pk-title .search{flex:0 1 380px;width:380px;max-width:100%;margin-bottom:8px}
.pk .pk-lab{font-size:13px;font-weight:600;letter-spacing:.04em;color:#12242F;line-height:1.3;margin:0 0 4px}
.sites{display:grid;grid-template-columns:repeat(var(--sc,9),minmax(0,1fr));gap:6px;margin:0 0 10px}
.site{
  display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:1px;min-width:0;
  min-height:44px;padding:6px 10px;font:inherit;text-align:left;cursor:pointer;color:var(--on-surface);
  background:var(--card);border:1.5px solid transparent;border-radius:10px;box-shadow:var(--shadow-card);
  transition:background .2s var(--ease),border-color .2s var(--ease);
}
.site .sn{display:block;max-width:100%;overflow:hidden;font-size:14px;font-weight:600;line-height:1.2;overflow-wrap:normal;word-break:normal}
.site .cnt{font-size:12px;font-weight:400;color:var(--on-surface-variant);font-variant-numeric:tabular-nums;white-space:nowrap}
.sites.rows .site{flex-direction:row;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:0 8px;min-height:36px}
.site:hover{border-color:var(--outline)}
.site[aria-selected="true"]{background:#E7F1F9;border-color:var(--primary)}
.site[aria-selected="true"] .sn{color:var(--primary-btn-hover)}
.site:focus-visible{outline:3px solid var(--primary);outline-offset:2px}
/* Last resort, three columns on a very narrow phone: smaller text and padding
   until the longest word fits unbroken (layoutPicker measures it). */
.sites.tight .site{padding:5px 6px}
.sites.tight .site .sn{font-size:11px}
.sites.tight .site .cnt{font-size:10.5px}
.site.dim{opacity:.45;cursor:default}
.site.dim:hover{border-color:transparent}
.typepane{min-width:0}
/* Up to three type cards a row, each at most 400px. Notes on one line. */
.pk-opts{grid-template-columns:repeat(var(--tc,1),minmax(0,400px));margin:0;gap:6px;align-items:start}
.pk-opts .opt{min-height:40px;padding:8px 14px}
.pk:not(.nonotes) .pk-opts .otxt small{max-height:none;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pk:not(.nonotes) .pk-opts .otxt{min-width:0;overflow:hidden}
.pk.nonotes .pk-opts .otxt small{max-height:0 !important;margin-top:0 !important}
.hit{display:flex;flex-direction:column;gap:2px;min-width:0}
.hitsite{font-size:12px;font-weight:400;color:var(--on-surface-variant);line-height:1.3;padding-left:2px}
.pk-empty{font-size:14px;font-weight:300;color:var(--on-surface-variant);margin:8px 0 0;line-height:1.45}
/* A landscape phone: the search takes less width so it can share the title row. */
@media (max-height:519px){
  .pk-title .search{flex-basis:300px;width:300px;min-height:34px;padding-top:6px;padding-bottom:6px}
  .pk-hd{flex-basis:360px}
  .sites{gap:4px;margin-bottom:6px}
  .site,.sites.rows .site{padding:2px 8px;min-height:28px}
  .pk .pk-lab{margin-bottom:2px}
}
@media (max-width:699px){
  .site .sn{font-size:12.5px}
  .site .cnt{font-size:11px}
  .site{padding:5px 8px}
  .pk-opts{grid-template-columns:minmax(0,1fr)}
}

/* A multi-question step flows its questions into columns. Same reason as the
   options: the viewport height is fixed, so growing downward is not available.
   break-inside keeps a question whole, so a label never parts from its
   options across a column boundary. */
/* Only split the questions into columns once there is enough width that each
   column still holds a multi-column option grid. Splitting earlier is a false
   economy: it starves the grid down to one option per row, and the step ends
   up TALLER than it was. */
/* (P21) the multi-column question flow and its :has() override are replaced
   by ONE LAYOUT MODEL FOR QUESTION STEPS, at the end of this file. */


/* The legend shares the counter's line but stays its own element, so the
   step counter's text is exactly "Step n of 10" and nothing reading it has
   to learn about the legend. */
.stepline{display:flex;align-items:baseline;gap:0;margin:0 0 2px}
.stepline .step-no{margin:0}

/* =========================================================================
   PAGINATION
   The hidden attribute must win over every display rule above - .opt is
   flex, .opts is grid - or a hidden option would still take up room.
   ====================================================================== */
[hidden]{display:none !important}

/* The step label reads "Step 2 of 10 · 1 of 2" when a step splits. */
.subpage{font-size:13px;font-weight:600;color:var(--on-surface-variant);margin-left:.35em}
.subpage:empty{display:none}

/* The pager rides in the action bar, between Back and the primary button
   (P23), so it takes no row of its own. From 768px it always holds that
   middle space - empty when the step is one page - so the primary button
   does not jump between steps. On a phone it takes room only when shown. */
.pager{
  flex:1 1 auto;min-width:0;height:44px;display:flex;align-items:center;justify-content:center;gap:2px;
  padding:0;background:transparent;
}
@media (min-width:768px){ #foot .pager[hidden]{display:flex !important;visibility:hidden} }
@media (max-width:767px){
  #foot:has(.pager:not([hidden])){gap:6px}
  #foot:has(.pager:not([hidden])) .btn.ghost{flex:0 0 auto;padding-left:12px;padding-right:12px}
  #foot:has(.pager:not([hidden])) .btn.prim{flex:1 1 0;min-width:0;padding-left:10px;padding-right:10px;font-size:14px;line-height:1.2}
  /* Its own width - previous, one dot, next - never squeezed by a long label.
     40px targets here, so "See recommendation" still fits beside it at 360px. */
  #foot .pager{flex:0 0 auto}
  #foot .pg{width:40px;min-width:40px}
}
.pg-dots{display:flex;gap:0}
.pg{
  width:44px;height:44px;min-width:44px;padding:0;border:none;background:transparent;
  border-radius:var(--radius-pill);cursor:pointer;display:grid;place-items:center;
  color:var(--primary);font:inherit;
}
.pg:hover:not([aria-disabled="true"]){background:var(--primary-08)}
.pg:focus-visible{outline:3px solid var(--primary);outline-offset:-3px}
.pg[aria-disabled="true"]{color:var(--outline-strong);cursor:default}
.pg-dot i{
  display:block;width:10px;height:10px;border-radius:50%;
  border:1.5px solid var(--primary);background:transparent;
}
.pg-dot[aria-current="page"] i{background:var(--primary)}

/* A windowed row of dots fades at the ends, so it reads as "there is more"
   rather than as the whole set. */
.pg-dots.windowed{
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
          mask-image:linear-gradient(to right,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
}

/* The last word of a required label and its asterisk never part. */
.nw{white-space:nowrap}

/* While pagination measures, every unselected note stays shut - hover and
   keyboard focus included - so the measurement does not depend on where a
   pointer happens to rest. The reserve pays for one note opening afterwards. */
#main.measuring .opt:not(.mopen) .otxt small{max-height:0 !important;margin-top:0 !important;transition:none !important}
/* ...except the tallest note of each question, held open whichever option is
   chosen (P23 C4), so an answer can never change how many pages a step has. */
#main.measuring .opt.mopen .otxt small{max-height:2.9em !important;margin-top:2px !important;transition:none !important}
/* Choosing a question's column count (bestCols): each option at its own
   height, every note shut, then every note open. */
.og.gmeasure{align-items:start}
.og.allshut .opt .otxt small{max-height:0 !important;margin-top:0 !important;transition:none !important}
.og.allopen .opt .otxt small{max-height:2.9em !important;margin-top:2px !important;transition:none !important}
/* A multi-select shows one note at a time: the most recently chosen option's.
   The others stay in the DOM as each option's description. */
.opt[data-multi].sel:not(.noteopen):not(:hover):not(:focus-visible) .otxt small{max-height:0;margin-top:0}

/* P23 C5 - phones only: a question too tall for the room by itself scrolls
   inside its own option list. The inset shade at the lower edge is the cue
   that more options are below; it goes when the list reaches its end. */
.opts.scrolls{overflow-y:auto;overscroll-behavior:contain;padding:3px;margin-left:-3px;margin-right:-3px;
  border-bottom:2px solid transparent;transition:box-shadow .2s var(--ease),border-color .2s var(--ease)}
.opts.scrolls.more{box-shadow:inset 0 -18px 14px -12px rgba(25,28,32,.45);border-bottom-color:var(--primary)}

/* PROGRESS - full 46px only when >= 800 tall AND >= 700 wide; 26px slim
   otherwise; none below 520 tall */
.bar{display:flex;align-items:center;gap:10px;height:46px;padding:4px 4px 0}
/* The assembled helix (P28). Fades in over its first 20px and out over its
   last 10px; the two layers slide left one turn every 7s and loop; the split
   (clip-path) and the marker stay put and move only on a step. */
.hx{flex:1 1 auto;min-width:0;height:100%;position:relative;overflow:hidden;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 20px,#000 calc(100% - 10px),transparent 100%);
          mask-image:linear-gradient(to right,transparent 0,#000 20px,#000 calc(100% - 10px),transparent 100%)}
.hx-part{position:absolute;inset:0;transition:clip-path .42s ease}
.hx-spin{position:absolute;left:0;top:0;display:block;will-change:transform;animation:hxturn 7s linear infinite}
@keyframes hxturn{from{transform:translateX(0)}to{transform:translateX(calc(var(--turn,64px) * -1))}}
.hx-mark{position:absolute;left:0;top:0;width:20px;height:100%;transition:transform .42s ease}
.hx-mark svg{position:absolute;left:0;top:0;display:block;overflow:visible}
.hx-pulse{position:absolute;box-sizing:border-box;border:1px solid #0E76BC;border-radius:50%;
  will-change:transform,opacity;animation:hxpulse 2.4s ease-in-out infinite}
@keyframes hxpulse{0%,100%{opacity:.2;transform:scale(.7)}50%{opacity:.9;transform:scale(1.2)}}
.hx-pct{flex:0 0 44px;width:44px;text-align:right;font-size:15px;font-weight:700;color:#0B5E97;
  font-variant-numeric:tabular-nums;line-height:1;white-space:nowrap}
.fk{flex:0 0 auto;width:34px;height:42px;overflow:visible}
.fk-line{fill:none;stroke:#44474E;stroke-width:1.7px;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.fk-liq{fill:#0E76BC;fill-opacity:.8;transition:transform .42s ease}
.bub{fill:#fff;opacity:0;animation:fkbub 2.8s ease-in infinite}
.bub.b2{animation-delay:1.4s}
@keyframes fkbub{0%{transform:translateY(0);opacity:0}15%{opacity:.95}100%{transform:translateY(calc(var(--rise,4px) * -1));opacity:0}}
@media (max-height:799px), (max-width:699px){
  .bar{height:26px;gap:8px;padding-top:2px}
  .fk{width:20px;height:24px}
  .hx-pct{flex-basis:34px;width:34px;font-size:12px}
}
@media (max-height:519px){ .bar{display:none} }
@media (prefers-reduced-motion:reduce){
  .hx-spin,.hx-pulse,.bub{animation:none}
  .bub{display:none}
  .hx-part,.hx-mark,.fk-liq{transition:none}
}

/* =========================================================================
   SHORT SCREENS - a landscape phone. The subtitle goes (the heading still
   asks the question) and the header and chip rail tighten; nothing else.
   ====================================================================== */
@media (max-height:520px){
  .sub{display:none}
  header{padding-top:calc(4px + var(--safe-t))}
  .hrow{height:46px;padding-top:4px;padding-bottom:4px}
  .logo-img{height:24px}
  .restart{min-height:32px;padding:5px 14px}
  .rail{padding-top:4px}
  .rail button{min-height:26px;padding:3px 10px}
  main{padding-top:6px}
}

/* =========================================================================
   ONE LAYOUT MODEL FOR QUESTION STEPS (P21)
   A step with several questions shows each as a card. Cards sit in a 6-track
   grid and ui.js sets each card's span, so the number per row is decided -
   min(questions, 3) from 1280px, min(questions, 2) from 1024px, 1 below - and
   a short last row shares its row equally. No multi-column anywhere on a
   question step, so no column box can be reserved and left empty.
   Pagination is the only overflow mechanism.
   ====================================================================== */
/* align-items:start (P21a C1): a card is as tall as its own content, not the
   tallest in its row. The row is still as tall as its tallest card. */
.qflow{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px;align-items:start}
.qflow > .qblock{
  grid-column:span var(--sp,6);min-width:0;margin:0;position:relative;
  background:var(--surface-variant);border:1px solid var(--outline);
  border-radius:var(--radius-card);padding:10px 12px 8px;
}
.qflow > .qblock > .opts{margin-bottom:0}
.qflow > .qblock.active{border-color:var(--primary)}
.qflow > .qblock.active > .opts{outline:none}
/* Option grids on steps 2-9: exactly the tracks ui.js sets (--oc), each at most
   360px from 1024px up, so a two-option question never makes 690px buttons. */
.og{grid-template-columns:repeat(var(--oc,1),minmax(0,1fr))}
@media (min-width:1024px){ .og{grid-template-columns:repeat(var(--oc,1),minmax(0,360px))} }
/* The container widened; prose keeps a reading measure. */
main > h1,.qblock .hint,.qnote{max-width:72ch}
/* Sex glyphs: beside the word, not instead of it. */
.sx{width:16px;height:16px;vertical-align:-3px;margin-right:6px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}


/* =========================================================================
   YOUR DETAILS (v8, P25) - v8's form and "Requested by" block, in this
   page's tokens. Inputs keep v8's 16px type and 52px height; the control edge
   is the 3:1 --outline-strong, as for every other control here. --fc is the
   column count layoutDetails() measured; .worst reserves every error line
   while it measures.
   ====================================================================== */
.fields{display:grid;grid-template-columns:repeat(var(--fc,1),minmax(0,1fr));gap:13px 16px;max-width:calc(var(--fc,1) * 480px)}
/* A phone that cannot hold the form: the field list scrolls, as option lists do (P23). */
.fields.scrolls{overflow-y:auto;overscroll-behavior:contain;padding:3px 3px 6px;margin-left:-3px;margin-right:-3px;
  border-bottom:2px solid transparent;transition:box-shadow .2s var(--ease),border-color .2s var(--ease)}
.fields.scrolls.more{box-shadow:inset 0 -18px 14px -12px rgba(25,28,32,.45);border-bottom-color:var(--primary)}
.field{display:block;min-width:0}
.flab{display:block;font-size:13.5px;font-weight:600;color:var(--on-surface);margin-bottom:6px}
.field input{
  width:100%;padding:14px 15px;font:inherit;font-size:16px;border:1.5px solid var(--outline-strong);
  border-radius:12px;background:var(--card);color:var(--on-surface);min-height:52px;
  transition:border-color .12s,box-shadow .12s;
}
.field input::placeholder{color:#6B7580;opacity:1}
.field input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-12)}
.field input:focus-visible{outline:3px solid var(--primary);outline-offset:2px}
.field.bad input{border-color:#C0524F;background:#FDF7F7}
.field.bad input:focus{box-shadow:0 0 0 3px rgba(192,82,79,.14)}
.ferr{display:block;min-height:0;font-size:12.5px;color:#9B2C2C;line-height:1.35}
.field.bad .ferr,.fields.worst .ferr{min-height:18px;margin-top:5px}
.ctclear{margin:12px 0 0;font-size:13.5px}
.lnk{color:var(--primary-btn-hover);text-decoration:underline;text-underline-offset:2px}
.lnk:focus-visible{outline:3px solid var(--primary);outline-offset:2px;border-radius:2px}

.requester{
  display:flex;flex-direction:column;gap:2px;background:var(--card);border:1px solid var(--outline);
  border-radius:12px;padding:12px 15px;margin-bottom:12px;
}
.requester .rq{font-size:11.5px;color:var(--on-surface-variant)}
.requester b{font-size:15px;line-height:1.3}
.requester span:not(.rq){font-size:13px;color:var(--on-surface-variant);line-height:1.35}
.requester .rqc{font-size:12.5px}
@media print{ .requester{border:none;padding:0 0 10px;border-bottom:1px solid var(--outline);border-radius:0} }

/* The consent line under the details form (P26): muted and small, like the
   other hints. Its wording is not yet legal-approved. */
.consent{font-size:12.5px;font-weight:300;color:var(--on-surface-variant);line-height:1.45;margin:0;max-width:72ch;grid-column:1 / -1}

/* =========================================================================
   UI POLISH (P30)
   ====================================================================== */
/* 3. Pick-several questions get square tick boxes; pick-one keeps round. */
.opt[data-multi] .tick{border-radius:4px}

/* 4. A note is clamped at two lines and ends with "…" when cut; the full
   note shows in .notetip (position:fixed) on hover and keyboard focus. */
.otxt small{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}
.pk:not(.nonotes) .pk-opts .otxt small{display:block;-webkit-line-clamp:unset;line-clamp:none}
#main.notefull .otxt small{display:block !important;max-height:none !important;-webkit-line-clamp:unset !important;line-clamp:none !important}
.notetip{position:fixed;z-index:60;padding:8px 12px;background:var(--card);color:var(--on-surface);
  border:1px solid var(--outline);border-radius:10px;box-shadow:var(--shadow-raised);
  font-size:13px;font-weight:400;line-height:1.45;pointer-events:none}
.notetip[hidden]{display:none}

/* 2. Why Continue is greyed out, to its left. No room on a phone. */
.foot-hint{flex:0 1 auto;min-width:0;font-size:13.5px;color:var(--on-surface-variant);text-align:right;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:699px){ .foot-hint{display:none} }

/* 6. The result, answer first: compact header and grid. */
.requester{flex-direction:row;flex-wrap:nowrap;align-items:baseline;gap:10px;padding:8px 14px;margin-bottom:10px;
  white-space:nowrap;overflow:hidden}
.requester .rqc{overflow:hidden;text-overflow:ellipsis;min-width:0}
.slip-top{padding:16px 24px 12px}
.slip-head{display:flex;align-items:center;justify-content:space-between;gap:16px}
.slip-head .slipmark{margin:0}
.slip-head .slipmark .logo-img{height:24px}
.slip-top .lab{margin:0}
.slip-top h1{font-size:28px;line-height:1.25;margin-top:2px}
.slip-top .meta{margin-top:4px;font-size:14px;line-height:1.45}
.slip-body{padding:6px 24px 10px}
.kvgrid{display:grid;grid-template-columns:1fr 1fr;column-gap:24px;margin:0}
.kvgrid .kv{padding:8px 0;font-size:15px;border-top:1px solid var(--outline)}
.kvgrid .kv:nth-child(-n+2){border-top:none}
.kvgrid .kv.wide{grid-column:1 / -1}
.kvgrid .kv dt{flex-basis:96px;font-size:14px}
@media (max-width:699px){
  .kvgrid{grid-template-columns:1fr}
  .kvgrid .kv:nth-child(2){border-top:1px solid var(--outline)}
  .requester{flex-wrap:wrap;white-space:normal}
}

/* 7. Step 1 on a phone: once a site is open, the tiles collapse to that site
   and "Change site"; the button brings the grid back. */
.chg-site{display:none}
.site-row{display:block}
@media (max-width:699px), (max-height:499px){
  .pk.hasopen:not(.expanded) .site-row{display:flex;align-items:stretch;gap:8px;margin-bottom:10px}
  .pk.hasopen:not(.expanded) .sites{display:block;flex:1 1 auto;margin:0}
  .pk.hasopen:not(.expanded) .site:not([aria-selected="true"]){display:none}
  .pk.hasopen:not(.expanded) .site[aria-selected="true"]{width:100%;flex-direction:row;align-items:baseline;justify-content:space-between;min-height:40px}
  .pk.hasopen:not(.expanded) .chg-site{display:block;flex:0 0 auto;padding:0 14px;min-height:40px;font:inherit;font-size:13.5px;font-weight:600;
    color:var(--primary-btn-hover);background:var(--card);border:1px solid var(--outline-strong);border-radius:10px;cursor:pointer}
  .chg-site:focus-visible{outline:3px solid var(--primary);outline-offset:2px}
}

/* 8. One arrangement per tile grid: all stacked if any tile must stack. */
.sites.rows.stacked .site{flex-direction:column;align-items:flex-start;flex-wrap:nowrap;gap:1px}
