/* ============================================================================
   Last Seen Alive: design system

   The product is an evidence dossier, so the interface is built as a finding
   aid rather than a dashboard: warm paper, ruled lines instead of floating
   cards, monospace for anything an archivist would copy into a catalogue, and
   colour reserved for meaning. See docs/DESIGN.md for the principles.

   Order: tokens · reset · layout · components · pages · board · print.
   ========================================================================= */

:root {
  /* --- paper and ink ---------------------------------------------------
     Warm rather than blue-grey. Archives are paper, card and nitrate; a cold
     interface reads as software about film rather than a tool used on it. */
  --paper:#f6f4ef; --card:#fffefb; --sunk:#ece8df; --raise:#fffdf7;
  --ink:#16130e; --ink-soft:#4d4739; --ink-faint:#7e7565;
  --rule:#d5cfc1; --rule-soft:#e6e1d5; --rule-strong:#16130e;

  /* --- meaning ---------------------------------------------------------
     Five colours, each with exactly one job. Nothing here is decorative:
     if something is accented, it is either interactive or it is a verdict. */
  --accent:#2b3f8f; --accent-bg:#e6eaf7; --accent-ink:#1d2e6e;
  --pass:#2c6349;  --pass-bg:#e1ece6;
  --warn:#8a5910;  --warn-bg:#f7ecd9;
  --crit:#9c2e25;  --crit-bg:#f8e4e0;

  /* --- depth -----------------------------------------------------------
     Almost none. A finding aid is flat; separation comes from rules. */
  --shadow-1:0 1px 0 rgb(22 19 14/.05);
  --shadow-2:0 10px 30px -12px rgb(22 19 14/.16);

  /* --- space (4px base) ------------------------------------------------ */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:72px; --s9:104px;

  --r-sm:3px; --r-md:6px; --r-lg:10px; --r-pill:99px;

  /* --- type ------------------------------------------------------------ */
  --f-display:"Helvetica Neue","Segoe UI",system-ui,-apple-system,Arial,sans-serif;
  --f-body:Georgia,"Iowan Old Style","Times New Roman",serif;
  --f-data:ui-monospace,"Cascadia Mono","SF Mono",Consolas,"Liberation Mono",monospace;

  --t-hero:clamp(2.35rem,6vw,4.05rem);
  --t-h2:clamp(1.8rem,3.4vw,2.5rem);
  --t-h3:1.28rem;
  --t-deck:clamp(1.05rem,1.6vw,1.3rem);
  --t-body:1.0625rem;
  --t-ui:0.875rem;
  --t-small:0.8125rem;
  --t-micro:0.6875rem;

  --shell:1080px;
  --header-h:57px;
  --ribbon-h:41px;

  --ease:cubic-bezier(.2,.7,.3,1);
}

:root[data-theme="dark"] {
  --paper:#0e0d0b; --card:#171612; --sunk:#201e18; --raise:#1d1b15;
  --ink:#ece8df; --ink-soft:#a9a291; --ink-faint:#7a7261;
  --rule:#332f26; --rule-soft:#241f18; --rule-strong:#ece8df;
  --accent:#9cb0ff; --accent-bg:#1a2142; --accent-ink:#bccaff;
  --pass:#66c89a; --pass-bg:#122a20;
  --warn:#e0a458; --warn-bg:#2c2113;
  --crit:#ef7a71; --crit-bg:#2e1a17;
  --shadow-1:0 1px 0 rgb(0 0 0/.4);
  --shadow-2:0 10px 30px -12px rgb(0 0 0/.6);
}

/* ============================ reset ==================================== */

*{box-sizing:border-box}

/* The hidden attribute must beat any component's own display rule, or a
   hidden tab pane with `display:grid` stays on screen. */
[hidden]{display:none!important}

html{
  background:var(--paper); color:var(--ink);
  scroll-behavior:smooth;
  /* Two sticky bars, so an in-page anchor has to clear both. */
  scroll-padding-top:calc(var(--header-h) + var(--ribbon-h) + 16px);
  -webkit-text-size-adjust:100%;
}
body{margin:0;background:var(--paper);font:var(--t-body)/1.65 var(--f-body);overflow-x:hidden}
button,select,input,textarea{font:inherit;color:inherit}
button,a{touch-action:manipulation}
a{color:var(--accent-ink)}
img,video{max-width:100%}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
::selection{background:var(--accent-bg);color:var(--accent-ink)}

.skip{position:fixed;left:12px;top:-80px;z-index:60;background:var(--ink);color:var(--paper);padding:10px 14px;border-radius:var(--r-sm);font:600 var(--t-ui)/1 var(--f-display)}
.skip:focus{top:12px}

.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* Plain / Technical is a real content switch, not a cosmetic one. */
[data-mode="technical"]{display:none}
:root[data-reading="technical"] [data-mode="technical"]{display:block}
:root[data-reading="technical"] [data-mode="plain"]{display:none}

/* ============================ layout =================================== */

.shell{width:min(var(--shell),calc(100% - 40px));margin-inline:auto}

.site-header{
  position:sticky;top:0;z-index:30;
  display:flex;align-items:center;gap:var(--s4);
  min-height:var(--header-h);
  padding:0 max(20px,calc((100vw - var(--shell))/2));
  background:color-mix(in srgb,var(--paper) 92%,transparent);
  border-bottom:1px solid var(--rule);
  backdrop-filter:blur(14px) saturate(1.4);
}
.wordmark{
  font:800 var(--t-small)/1 var(--f-display);letter-spacing:.16em;
  text-decoration:none;color:var(--ink);white-space:nowrap;flex-shrink:0;
}
.site-nav{display:flex;gap:2px;margin-inline:auto}
.site-nav a{
  padding:8px 12px;border-radius:var(--r-sm);
  font:650 var(--t-ui)/1 var(--f-display);color:var(--ink-soft);text-decoration:none;
  white-space:nowrap;transition:background .15s var(--ease),color .15s var(--ease);
}
.site-nav a:hover{background:var(--sunk);color:var(--ink)}
.site-nav a[aria-current="page"]{color:var(--ink);box-shadow:inset 0 -2px 0 var(--accent)}

.header-actions{display:flex;align-items:center;gap:var(--s2);flex-shrink:0}
.segmented{display:flex;background:var(--sunk);padding:3px;border-radius:var(--r-md)}
.segmented button,.quiet-button,.stack-button{
  border:0;background:transparent;color:var(--ink-soft);
  font:650 var(--t-small)/1 var(--f-display);padding:9px 11px;
  border-radius:var(--r-sm);cursor:pointer;white-space:nowrap;
}
.segmented [aria-pressed="true"]{background:var(--card);color:var(--ink);box-shadow:var(--shadow-1)}
.quiet-button:hover{color:var(--ink)}
.stack-button{border:1px solid var(--rule);background:var(--card)}
.stack-button:hover{border-color:var(--ink-faint)}

/* ---- sponsor stack ribbon -------------------------------------------
   On every page, driven by GET /v1/stack, so a service that is down reads as
   down everywhere at once.

   It wraps rather than scrolls: eleven chips do not fit one line at any
   viewport width, and a horizontal scrollbar inside a sticky bar hides content
   a reader has no reason to go looking for. Wrapping costs one row and hides
   nothing. Each chip's status is in its accessible name, not only in the dot
   colour and the tooltip. */
.stack-ribbon{
  position:sticky;top:var(--header-h);z-index:29;
  display:flex;flex-wrap:wrap;align-items:center;gap:6px var(--s4);
  min-height:var(--ribbon-h);padding-block:6px;
  padding-inline:max(20px,calc((100vw - var(--shell))/2));
  background:var(--card);border-bottom:1px solid var(--rule);
}
.ribbon-group{display:flex;flex-wrap:wrap;align-items:center;gap:6px var(--s2);min-width:0}
.ribbon-label{
  font:800 var(--t-micro)/1 var(--f-display);letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-faint);white-space:nowrap;
}
.ribbon-list{display:flex;flex-wrap:wrap;gap:3px;margin:0;padding:0;list-style:none}
.ribbon-item{
  display:flex;align-items:center;gap:5px;
  padding:4px 9px;border:1px solid var(--rule);border-radius:var(--r-pill);
  background:var(--paper);white-space:nowrap;cursor:help;
  font:650 var(--t-small)/1 var(--f-display);color:var(--ink);
  transition:border-color .15s var(--ease);
}
.ribbon-item:hover{border-color:var(--ink-faint)}
.ribbon-item.live{border-color:color-mix(in srgb,var(--pass) 42%,var(--rule))}
.ribbon-item.unavailable{border-color:color-mix(in srgb,var(--crit) 42%,var(--rule))}
.ribbon-item .status-dot{width:7px;height:7px;margin:0;flex-shrink:0}
.ribbon-more{margin-left:auto;font:650 var(--t-small)/1 var(--f-display);white-space:nowrap;padding-left:var(--s4)}

.status-dot{
  display:inline-block;width:9px;height:9px;margin-right:7px;
  border-radius:50%;background:var(--pass);flex-shrink:0;
}
.status-dot.pending{background:var(--warn)}
.status-dot.down{background:var(--crit)}

/* ============================ typography =============================== */

h1,h2,h3{font-family:var(--f-display);line-height:1.08;letter-spacing:-.028em;text-wrap:balance;color:var(--ink)}
h1{max-width:20ch;margin:0;font-size:var(--t-hero);font-weight:800}
h2{max-width:24ch;margin:0 0 var(--s5);font-size:var(--t-h2);font-weight:750}
h3{margin:0 0 var(--s2);font-size:var(--t-h3);font-weight:700;letter-spacing:-.018em}

.eyebrow{
  margin:0 0 var(--s3);
  font:800 var(--t-micro)/1.2 var(--f-display);letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent-ink);
}
.deck{max-width:66ch;margin:var(--s5) 0;color:var(--ink-soft);font-size:var(--t-deck);line-height:1.5}
.lede{max-width:74ch;margin:0 0 var(--s5);color:var(--ink-soft);font:var(--t-ui)/1.65 var(--f-display)}
.small,.muted{color:var(--ink-soft)}
.small{font:var(--t-small)/1.55 var(--f-display)}
code{font-family:var(--f-data);font-size:.88em;background:var(--sunk);padding:2px 5px;border-radius:var(--r-sm);overflow-wrap:anywhere}
.prose>*:not(.eyebrow,h2){max-width:70ch}
.prose p{color:var(--ink-soft)}
.prose ul{color:var(--ink-soft);padding-left:1.2rem}
.prose li{margin-bottom:var(--s2)}
.prose strong,.prose b{color:var(--ink)}

/* ============================ sections ================================= */

.masthead{padding-block:var(--s9) var(--s7)}
.masthead.compact{padding-block:var(--s8) var(--s6)}
.section{padding-block:var(--s8);border-top:1px solid var(--rule-soft)}

/* A film-perforation rule, used only on the two sections that carry the
   product's argument. Any more and it stops meaning anything. */
.section.perf{border-top:0;position:relative}
.section.perf::before{
  content:"";position:absolute;inset-inline:0;top:0;height:9px;
  background:repeating-linear-gradient(90deg,
    var(--rule) 0 7px,transparent 7px 18px);
  opacity:.85;
}

.fact-strip{
  display:grid;grid-template-columns:repeat(4,1fr);
  margin:var(--s7) 0 0;border-block:1px solid var(--rule);
}
.fact-strip div{padding:var(--s4);border-right:1px solid var(--rule)}
.fact-strip div:last-child{border-right:0}
.fact-strip dt{font:700 var(--t-micro)/1.2 var(--f-display);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-faint)}
.fact-strip dd{margin:var(--s2) 0 0;font:650 var(--t-ui)/1.4 var(--f-data);color:var(--ink)}

.cta-row{display:flex;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s6)}
.cta-row a{text-decoration:none;display:inline-block}

/* ============================ controls ================================= */

.primary-button,.secondary-button{
  border-radius:var(--r-sm);padding:12px 18px;
  font:700 var(--t-ui)/1 var(--f-display);cursor:pointer;
  transition:transform .1s var(--ease),background .15s var(--ease),border-color .15s var(--ease);
}
.primary-button{border:1px solid var(--accent);background:var(--accent);color:#fff}
.primary-button:hover:not(:disabled){background:var(--accent-ink);border-color:var(--accent-ink)}
.primary-button:active:not(:disabled){transform:translateY(1px)}
.primary-button:disabled,.secondary-button:disabled{opacity:.55;cursor:progress}
.secondary-button{border:1px solid var(--rule);background:var(--card);color:var(--accent-ink)}
.secondary-button:hover:not(:disabled){border-color:var(--accent)}
:root[data-theme="dark"] .primary-button{color:#0e0d0b}

.link-button{
  font:650 var(--t-ui)/1.3 var(--f-display);color:var(--accent-ink);text-decoration:none;
  border:0;border-bottom:1px solid color-mix(in srgb,currentColor 40%,transparent);
  padding:0 0 2px;cursor:pointer;background:none;
}
.link-button:hover{border-bottom-color:currentColor}
.row-actions{display:flex;flex-wrap:wrap;gap:var(--s4);align-items:center;margin-top:var(--s3)}

select,input[type="text"],input[type="file"],textarea{
  width:100%;background:var(--sunk);color:var(--ink);
  border:1px solid var(--rule);border-radius:var(--r-sm);padding:11px;
  font:var(--t-ui)/1.5 var(--f-display);
}
textarea{font-family:var(--f-data);font-size:var(--t-small);resize:vertical}
select:hover,input:hover,textarea:hover{border-color:var(--ink-faint)}
.check{display:flex;align-items:flex-start;gap:9px;font:var(--t-ui)/1.45 var(--f-display);color:var(--ink-soft);cursor:pointer}
.check input{margin-top:3px;flex-shrink:0;accent-color:var(--accent)}

.tabs{
  display:flex;gap:2px;margin-bottom:var(--s4);
  background:var(--sunk);padding:3px;border-radius:var(--r-md);
  width:fit-content;max-width:100%;flex-wrap:wrap;
}
.tabs button{
  border:0;background:transparent;color:var(--ink-soft);
  font:700 var(--t-small)/1 var(--f-display);padding:10px 15px;
  border-radius:var(--r-sm);cursor:pointer;
}
.tabs button[aria-selected="true"]{background:var(--card);color:var(--ink);box-shadow:var(--shadow-1)}

.card{
  background:var(--card);border:1px solid var(--rule);
  border-radius:var(--r-md);padding:var(--s5);box-shadow:var(--shadow-1);
}
.badge{
  display:inline-block;margin-bottom:var(--s4);padding:5px 8px;
  background:var(--accent-bg);color:var(--accent-ink);
  font:800 var(--t-micro)/1 var(--f-data);letter-spacing:.09em;border-radius:var(--r-sm);
}
.badge-mini{
  font:700 var(--t-micro)/1.4 var(--f-display);letter-spacing:.07em;text-transform:uppercase;
  padding:4px 8px;border-radius:var(--r-pill);background:var(--sunk);color:var(--ink-soft);
}
.badge-mini.req{background:var(--accent-bg);color:var(--accent-ink)}
.badge-mini.live{background:var(--pass-bg);color:var(--pass)}
.badge-mini.unavailable{background:var(--crit-bg);color:var(--crit)}
.badge-mini.unknown{background:var(--warn-bg);color:var(--warn)}
.badge-mini.sealed{background:var(--ink);color:var(--paper)}
.badge-mini.outcome-abstain{background:var(--sunk);color:var(--ink-soft)}
.badge-mini.outcome-candidates{background:var(--warn-bg);color:var(--warn)}
.badge-mini.outcome-identify{background:var(--pass-bg);color:var(--pass)}
.badge-mini.outcome-contradict{background:var(--crit-bg);color:var(--crit)}

/* ============================ landing ================================== */

.clue-stage{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(280px,.75fr);gap:var(--s6)}
.film-frame{
  position:relative;display:grid;place-items:center;min-height:340px;padding:30px;
  border:10px solid var(--ink);
  background:repeating-linear-gradient(93deg,#c8cbd1 0,#e5e7eb 3px,#b9bdc5 5px);
  filter:grayscale(1);box-shadow:var(--shadow-2);
}
.frame-copy{background:#111;color:#eee;padding:18px 24px;text-align:center;font:700 21px/1.4 var(--f-display)}
.marker{
  position:absolute;display:grid;place-items:center;width:28px;height:28px;
  border-radius:50%;background:var(--accent);color:#fff;font:800 12px/1 var(--f-data);
  box-shadow:0 0 0 3px rgb(255 255 255/.85);
}
.marker-one{left:26%;top:64%}
.marker-two{right:16%;top:18%}
.marker-three{bottom:10%;left:10%}
.clue-list{display:grid;gap:2px;margin:0;padding:0;list-style:none}
.clue-list li{display:grid;gap:var(--s1);padding:var(--s4) var(--s5);background:var(--card);border:1px solid var(--rule)}
.clue-list strong{font:700 var(--t-ui)/1.3 var(--f-data);color:var(--ink)}
.clue-list span{color:var(--ink-soft);font:var(--t-ui)/1.5 var(--f-display)}

.flow{margin:0;padding:0;list-style:none;border-top:1px solid var(--rule)}
.flow li{display:grid;grid-template-columns:64px 1fr;gap:var(--s5);padding:var(--s5) 0;border-bottom:1px solid var(--rule)}
.flow p{max-width:70ch;margin:0;color:var(--ink-soft);font:var(--t-ui)/1.6 var(--f-display)}
.step{font:700 var(--t-small)/1.5 var(--f-data);color:var(--ink-faint)}
/* The deterministic steps are the product's whole argument, so they are the
   one place in the flow that gets a fill. The fill bleeds past the text column
   only where there is gutter to bleed into; below that it would push the page
   wider than the viewport. */
.flow .deterministic{background:var(--pass-bg)}
@media(min-width:600px){
  .flow .deterministic{margin-inline:-20px;padding-inline:20px}
}
.flow .deterministic .step{color:var(--pass)}

.metric-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:var(--s3)}
.metric{display:grid;gap:var(--s1);background:var(--card);border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s5)}
.metric span,.metric small{font:var(--t-small)/1.4 var(--f-display);color:var(--ink-soft)}
.metric strong{font:700 1.6rem/1.3 var(--f-data);color:var(--ink)}

.stack-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--s4);margin-bottom:var(--s5)}
.stack-cards .card p{margin:0;color:var(--ink-soft);font:.95rem/1.65 var(--f-body)}
.stack-cards .card b{color:var(--ink)}

.demo-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--s5);align-items:start}
.demo-card{display:grid;gap:var(--s3)}
.demo-card label{font:700 var(--t-ui)/1.2 var(--f-display)}
.preset-video{width:100%;aspect-ratio:4/3;background:#000;border-radius:var(--r-md);border:1px solid var(--rule);object-fit:contain}
.privacy{
  border-left:3px solid var(--warn);background:var(--warn-bg);
  padding:var(--s3) var(--s4);border-radius:0 var(--r-sm) var(--r-sm) 0;color:var(--ink-soft);
}
.api-callout{
  display:flex;justify-content:space-between;align-items:center;gap:var(--s5);
  margin-top:var(--s5);padding:var(--s5);
  background:var(--accent-bg);border:1px solid color-mix(in srgb,var(--accent) 35%,transparent);
  border-radius:var(--r-md);
}
.api-callout div{display:grid;gap:2px}
.api-callout strong{font:700 var(--t-h3)/1.2 var(--f-display);color:var(--ink)}
.api-callout span{font:var(--t-ui)/1.5 var(--f-display);color:var(--ink-soft)}

/* ---- investigation console ------------------------------------------
   An investigation takes 40-120 seconds. That is far too long for a
   spinner, and far too long to show nothing: the value of this product is
   *what it is doing*, so the wait is where the workflow gets explained. */
.run-panel{display:flex;flex-direction:column;gap:var(--s4);min-height:340px}
.run-panel h3{margin:0}
.run-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3)}
.run-clock{font:650 var(--t-small)/1 var(--f-data);color:var(--ink-faint);font-variant-numeric:tabular-nums}

/* The expected duration, stated before the clock starts. It sits between the
   heading and the stage list because that is where a viewer looks first when
   deciding whether to keep the tab open. */
.run-note{margin:0;font:var(--t-small)/1.5 var(--f-body);color:var(--ink-soft)}
.run-note b{color:var(--ink);font-weight:650}

.stagelist{display:grid;gap:1px;margin:0;padding:0;list-style:none;background:var(--rule-soft);border:1px solid var(--rule);border-radius:var(--r-md);overflow:hidden}
.stage{
  display:grid;grid-template-columns:22px 1fr;gap:var(--s3);align-items:start;
  padding:var(--s3) var(--s4);background:var(--card);
  transition:background .25s var(--ease);
}
.stage-mark{
  display:grid;place-items:center;width:20px;height:20px;border-radius:50%;
  border:1px solid var(--rule);background:var(--paper);
  font:700 10px/1 var(--f-data);color:var(--ink-faint);margin-top:2px;
}
.stage b{display:block;font:650 var(--t-ui)/1.35 var(--f-display);color:var(--ink-faint)}
.stage span{display:block;font:var(--t-small)/1.45 var(--f-display);color:var(--ink-faint)}
.stage.active{background:var(--accent-bg)}
.stage.active b{color:var(--accent-ink)}
.stage.active span{color:var(--ink-soft)}
.stage.active .stage-mark{border-color:var(--accent);color:var(--accent-ink);background:var(--card)}
.stage.active .stage-mark::after{
  content:"";width:7px;height:7px;border-radius:50%;background:var(--accent);
  animation:pulse 1.4s var(--ease) infinite;
}
.stage.active .stage-mark{font-size:0}
.stage.done b{color:var(--ink)}
.stage.done span{color:var(--ink-soft)}
.stage.done .stage-mark{border-color:var(--pass);background:var(--pass);color:#fff;font-size:11px}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.7)}}

.run-empty{
  display:grid;place-content:center;justify-items:center;gap:var(--s3);
  flex:1;padding:var(--s6) var(--s5);text-align:center;
  border:1px dashed var(--rule);border-radius:var(--r-md);background:var(--sunk);
}
.run-empty .glyph{font-size:26px;line-height:1;opacity:.5}
.run-empty b{font:650 var(--t-ui)/1.4 var(--f-display);color:var(--ink-soft)}
.run-empty p{margin:0;max-width:34ch;font:var(--t-small)/1.55 var(--f-display);color:var(--ink-faint)}
.run-progress{margin:0;padding-left:22px;font:var(--t-ui)/1.7 var(--f-display);color:var(--ink-soft)}

.run-outcome{display:grid;gap:var(--s2);padding:var(--s4);border-radius:var(--r-md);background:var(--sunk)}
.run-outcome dt{font:700 var(--t-micro)/1.2 var(--f-display);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint)}
.run-outcome dd{margin:0 0 var(--s2);font:var(--t-small)/1.5 var(--f-data);color:var(--ink);word-break:break-word}

.run-error{display:grid;gap:var(--s2);padding:var(--s4);border-radius:var(--r-md);background:var(--crit-bg);border-left:3px solid var(--crit)}
.run-error b{font:700 var(--t-ui)/1.4 var(--f-display);color:var(--crit)}
.run-error p{margin:0;font:var(--t-small)/1.55 var(--f-display);color:var(--ink-soft)}

/* ============================ presets page ============================= */

.preset-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:var(--s4)}
.presetcard{
  display:flex;flex-direction:column;gap:var(--s3);
  background:var(--card);border:1px solid var(--rule);border-radius:var(--r-md);
  padding:var(--s5);box-shadow:var(--shadow-1);
  /* Equal-height cards: the actions block is pushed to the bottom so a row
     of cards lines up regardless of how much copy each one carries. */
}
.presetcard.sealed{border-style:dashed;background:var(--paper)}
.presetcard-top{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.preset-id{
  font:800 var(--t-small)/1 var(--f-data);letter-spacing:.06em;
  padding:5px 8px;background:var(--ink);color:var(--paper);border-radius:var(--r-sm);
}
.presetcard h3{margin:0;font-size:1.15rem}
.presetcard-challenge{margin:0;font:.95rem/1.6 var(--f-body);color:var(--ink-soft)}
.presetcard-why,.presetcard-label{margin:0;font:var(--t-small)/1.6 var(--f-display);color:var(--ink-soft)}
.presetcard-why b,.presetcard-label b{color:var(--ink)}
.presetcard-credit{margin:0;font:var(--t-micro)/1.45 var(--f-display);color:var(--ink-faint)}
.presetcard .row-actions{margin-top:auto;padding-top:var(--s3);border-top:1px solid var(--rule-soft)}
.preset-locked{
  display:grid;place-items:center;align-content:center;gap:var(--s2);aspect-ratio:4/3;
  background:var(--sunk);border:1px dashed var(--rule);border-radius:var(--r-md);
  font:var(--t-small)/1.45 var(--f-display);color:var(--ink-faint);text-align:center;padding:var(--s4);
}
.preset-locked span:first-child{font-size:26px;opacity:.6}
.presetmeta{display:grid;grid-template-columns:auto 1fr;gap:2px var(--s3);margin:0;font:var(--t-small)/1.55 var(--f-data)}
.presetmeta dt{color:var(--ink-faint)}
.presetmeta dd{margin:0;color:var(--ink)}
.presettransforms{font:var(--t-small)/1.55 var(--f-display);color:var(--ink-soft)}
.presettransforms summary{cursor:pointer;color:var(--accent-ink)}
.presettransforms ul{margin:var(--s2) 0 0;padding-left:20px}

/* ============================ API page ================================= */

.keybox{background:var(--card);border:1px solid var(--rule);border-radius:var(--r-lg);padding:var(--s5);display:grid;gap:var(--s4);box-shadow:var(--shadow-1)}
.keybox-actions{display:flex;flex-wrap:wrap;gap:var(--s3)}
.keyout{
  display:block;font:var(--t-small)/1.6 var(--f-data);word-break:break-all;
  background:var(--sunk);border:1px solid var(--rule);border-radius:var(--r-md);
  padding:var(--s4);color:var(--ink-faint);
}
.keyout.has-key{color:var(--ink)}
.keyfacts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:2px var(--s4);margin:0;font:var(--t-small)/1.5 var(--f-display)}
.keyfacts dt{font-size:var(--t-micro);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-faint)}
.keyfacts dd{margin:0 0 var(--s2);font-family:var(--f-data);color:var(--ink)}

.playground{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:var(--s4);align-items:start}
.play-form{display:grid;gap:var(--s3)}
.play-form label{font:700 var(--t-small)/1.2 var(--f-display)}
.play-result{display:grid;gap:var(--s3);align-content:start;min-height:300px}
.play-status{font:700 var(--t-small)/1.3 var(--f-data);padding:9px 12px;border-radius:var(--r-sm);background:var(--sunk);color:var(--ink-soft)}
.play-status.ok{background:var(--pass-bg);color:var(--pass)}
.play-status.bad{background:var(--crit-bg);color:var(--crit)}
.play-out,.snippet{
  margin:0;padding:var(--s4);background:var(--sunk);
  border:1px solid var(--rule);border-radius:var(--r-md);
  font:var(--t-small)/1.6 var(--f-data);white-space:pre-wrap;word-break:break-word;
  max-height:460px;overflow:auto;
}
.snippet{max-height:none;background:#12110d;color:#ece8df;border-color:#12110d}
:root[data-theme="dark"] .snippet{background:#050505;color:#dfe4ec;border-color:var(--rule)}

.table-scroll{overflow-x:auto;border:1px solid var(--rule);border-radius:var(--r-md)}
.reftable{width:100%;border-collapse:collapse;font:var(--t-ui)/1.55 var(--f-display);background:var(--card)}
.reftable caption{caption-side:bottom;padding:var(--s3) var(--s4);text-align:left;font-size:var(--t-small);color:var(--ink-soft)}
.reftable th,.reftable td{padding:var(--s3) var(--s4);text-align:left;border-bottom:1px solid var(--rule-soft);vertical-align:top}
.reftable tbody tr:last-child td{border-bottom:0}
.reftable tbody tr:hover{background:var(--sunk)}
.reftable thead th{font:800 var(--t-micro)/1.2 var(--f-display);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);background:var(--sunk)}
.reftable td:first-child{white-space:nowrap}
.reftable code{font-size:var(--t-small)}

/* ============================ stack page =============================== */

.stack-section{margin-bottom:var(--s7)}
.stack-head{display:flex;align-items:baseline;gap:var(--s4);margin-bottom:var(--s4);padding-bottom:var(--s3);border-bottom:2px solid var(--rule-strong)}
.stack-head h2{margin:0;font-size:1.75rem;max-width:none}
.stack-count{font:700 var(--t-small)/1 var(--f-data);color:var(--ink-faint);letter-spacing:.06em;text-transform:uppercase}
.stackrow{
  background:var(--card);border:1px solid var(--rule);border-left:3px solid var(--ink-faint);
  border-radius:0 var(--r-md) var(--r-md) 0;padding:var(--s4) var(--s5);margin-bottom:var(--s2);
}
.stackrow.live{border-left-color:var(--pass)}
.stackrow.unavailable{border-left-color:var(--crit)}
.stackrow.unknown{border-left-color:var(--warn)}
.stackrow-top{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2);margin-bottom:var(--s2)}
.stackrow-top h3{margin:0;font-size:1.08rem}
.stackrow-role{margin:0 0 var(--s2);font:.95rem/1.65 var(--f-body);color:var(--ink)}
.stackrow-note{margin:0 0 var(--s3);font:.9rem/1.65 var(--f-body);color:var(--ink-soft);padding-left:var(--s3);border-left:2px solid var(--rule)}
.stackrow-note b{color:var(--ink)}
.stackrow-meta{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);font:var(--t-small)/1.5 var(--f-display);color:var(--ink-faint);min-width:0}
.stackrow-meta code{font-size:var(--t-micro);overflow-wrap:anywhere;min-width:0}

/* ---- stack side panel ---- */
.stack-panel{
  position:fixed;z-index:40;inset:0 0 0 auto;width:min(430px,100%);
  padding:var(--s5);background:var(--card);border-left:1px solid var(--rule);
  box-shadow:var(--shadow-2);overflow-y:auto;
}
.panel-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--s3)}
.panel-head h2{font-size:1.6rem;margin:0}
.panel-head button{border:0;background:transparent;color:var(--ink);font-size:30px;line-height:1;cursor:pointer;padding:0 var(--s2)}
.stack-panel ul{padding:0;margin:var(--s4) 0 0;list-style:none}
.stack-panel li{padding:var(--s3) 0;border-bottom:1px solid var(--rule-soft)}
.panel-row{display:flex;align-items:center;gap:var(--s2)}
.panel-row b{font:650 var(--t-ui)/1.3 var(--f-display)}
.panel-vendor{margin-left:auto;font:var(--t-micro)/1 var(--f-display);color:var(--ink-faint);text-transform:uppercase;letter-spacing:.09em}
.stack-panel li p{margin:var(--s1) 0;font-size:var(--t-small)}
.stack-panel li code{display:block;margin-top:var(--s1);font-size:var(--t-micro);word-break:break-all;background:none;padding:0;color:var(--ink-faint)}

/* ============================ evidence board =========================== */

.board{margin-top:var(--s5);display:grid;gap:var(--s4);scroll-margin-top:120px}
.board h3{font:800 var(--t-micro)/1.3 var(--f-display);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-faint);margin:var(--s4) 0 var(--s2)}
.board>section>h3:first-child,.board h3:first-child{margin-top:0}
.colnote{font:var(--t-small)/1.6 var(--f-display);color:var(--ink-soft);margin:0 0 var(--s3)}

/* The verdict reads as an accession stamp: the one piece of the dossier an
   archivist will look at first, and the one that must never look like an
   error state when it says "abstain". */
.verdict{border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s5);border-left-width:4px}
.verdict strong{font:750 1.15rem/1.3 var(--f-display);display:block;color:var(--ink)}
.verdict p{margin:var(--s2) 0 0;font:var(--t-ui)/1.6 var(--f-display);color:var(--ink-soft)}
.verdict-probable{background:var(--pass-bg);border-color:var(--pass)}
.verdict-candidates{background:var(--warn-bg);border-color:var(--warn)}
.verdict-abstain{background:var(--sunk);border-color:var(--ink-faint)}
.verdict-contradicted{background:var(--crit-bg);border-color:var(--crit)}

.boardstats{display:grid;grid-template-columns:repeat(6,1fr);gap:1px;background:var(--rule);border:1px solid var(--rule);border-radius:var(--r-md);overflow:hidden}
.boardstats div{background:var(--card);padding:var(--s3) var(--s4)}
.boardstats b{display:block;font:700 1.4rem/1.15 var(--f-data);color:var(--ink);font-variant-numeric:tabular-nums}
.boardstats span{font:var(--t-micro)/1.35 var(--f-display);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint)}

.boardcols{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);gap:var(--s4);align-items:start}
.boardcol{background:var(--card);border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s5);box-shadow:var(--shadow-1)}

.gategrid{display:grid;gap:1px;background:var(--rule-soft);border:1px solid var(--rule-soft);border-radius:var(--r-md);overflow:hidden}
.gaterow{display:grid;grid-template-columns:auto 1fr;gap:var(--s3);align-items:center;padding:10px var(--s3);font:var(--t-ui)/1.4 var(--f-display)}
.gaterow.ok{background:var(--pass-bg);color:var(--pass)}
.gaterow.no{background:var(--card);color:var(--ink-faint)}
.gmark{display:inline-grid;place-items:center;width:18px;height:18px;border-radius:50%;font-size:11px;line-height:1}
.gaterow.ok .gmark{background:var(--pass);color:#fff}
.gaterow.no .gmark{background:var(--sunk);color:var(--ink-faint);border:1px solid var(--rule)}

.candrow{display:grid;grid-template-columns:1fr auto;gap:var(--s2) var(--s3);align-items:center;padding:var(--s3) 0;border-bottom:1px solid var(--rule-soft)}
.candrow b{font:650 .95rem/1.3 var(--f-display)}
.cmeta{font:var(--t-small)/1.3 var(--f-display);color:var(--ink-faint)}
.cbar{grid-column:1/-1;height:5px;background:var(--sunk);border-radius:var(--r-pill);overflow:hidden}
.cbar i{display:block;height:100%;background:var(--accent)}

.rejrow{display:grid;gap:var(--s1);padding:var(--s3);margin-bottom:var(--s2);border-left:3px solid var(--crit);background:var(--crit-bg);border-radius:0 var(--r-md) var(--r-md) 0}
.rejrow code{font:var(--t-small)/1.45 var(--f-data);word-break:break-all;color:var(--ink);background:none;padding:0}
.rejrow q{display:block;margin-top:var(--s1);font:var(--t-small)/1.55 var(--f-body);color:var(--ink-soft)}
.rreason{font:700 var(--t-micro)/1.35 var(--f-display);letter-spacing:.06em;text-transform:uppercase;color:var(--crit)}

.claim{border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s4);margin-bottom:var(--s3);border-left-width:3px;border-left-color:var(--rule)}
.claim.contradicts{border-left-color:var(--crit)}
.claim.supports{border-left-color:var(--pass)}
.claimtop{display:flex;gap:var(--s2);margin-bottom:var(--s2);flex-wrap:wrap}
.stance,.decisive{font:700 var(--t-micro)/1.4 var(--f-display);letter-spacing:.07em;text-transform:uppercase;padding:3px 8px;border-radius:var(--r-pill)}
.stance.supports{background:var(--pass-bg);color:var(--pass)}
.stance.contradicts{background:var(--crit-bg);color:var(--crit)}
.stance.neutral{background:var(--sunk);color:var(--ink-soft)}
.decisive.yes{background:var(--accent-bg);color:var(--accent-ink)}
.decisive.no{background:var(--sunk);color:var(--ink-faint)}
.claimtext{margin:0 0 var(--s2);font:1rem/1.6 var(--f-body);color:var(--ink)}
.basis{margin:0 0 var(--s3);font:var(--t-small)/1.55 var(--f-display);color:var(--ink-faint)}
.nosrc{font:var(--t-ui)/1.55 var(--f-display);color:var(--ink-faint);margin:0}

/* A source's standing has to be legible without reading the label: verified
   sits on paper, refused is struck through and dimmed. */
.srcrow{background:var(--sunk);border-radius:var(--r-md);padding:var(--s3);margin-top:var(--s2);border-left:2px solid var(--pass)}
.srcrow.unverified{border-left:2px dashed var(--warn);opacity:.75}
.srchead{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s2)}
.dom{font:700 var(--t-small)/1.3 var(--f-data);color:var(--ink)}
.vflag{font:700 var(--t-micro)/1.35 var(--f-display);letter-spacing:.05em;text-transform:uppercase;color:var(--pass)}
.srcrow.unverified .vflag{color:var(--warn)}
.srchead a{margin-left:auto;font:650 var(--t-small)/1.3 var(--f-display)}
.srcrow q{display:block;font:var(--t-small)/1.6 var(--f-body);color:var(--ink-soft)}

.qlist{margin:0;padding-left:1.15rem;font:var(--t-ui)/1.6 var(--f-display);color:var(--ink-soft)}
.qlist li{margin-bottom:var(--s2)}

.auditbox{background:var(--card);border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s5)}
.auditbox.warnbox{border-color:var(--warn);background:var(--warn-bg)}
.auditrow{display:grid;grid-template-columns:auto 1fr;gap:var(--s3);align-items:start;padding:var(--s3);border-radius:var(--r-md);margin-bottom:var(--s2)}
.auditrow.ok{background:var(--pass-bg)}
.auditrow.no{background:var(--crit-bg)}
.auditrow b{display:block;font:650 .92rem/1.4 var(--f-display);color:var(--ink)}
.auditnote{font:var(--t-small)/1.45 var(--f-display);color:var(--ink-soft)}
.auditrow.ok .gmark{background:var(--pass);color:#fff}
.auditrow.no .gmark{background:var(--crit);color:#fff}

.agentstrip{background:var(--card);border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s5)}
.strip{display:grid;gap:var(--s2)}
.agentcard{border:1px solid var(--rule);border-radius:var(--r-md);overflow:hidden}
.agentcard summary{display:flex;align-items:center;gap:var(--s3);padding:var(--s3);cursor:pointer;background:var(--sunk);font:var(--t-ui)/1.35 var(--f-display)}
.agentcard summary:hover{background:var(--rule-soft)}
.anum{display:inline-grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--accent);color:#fff;font:700 var(--t-micro)/1 var(--f-display);flex-shrink:0}
.arole{margin-left:auto;font:var(--t-small)/1.35 var(--f-display);color:var(--ink-faint);text-align:right}
.agentcard pre{margin:0;padding:var(--s4);font:var(--t-small)/1.6 var(--f-data);white-space:pre-wrap;max-height:300px;overflow:auto;background:var(--card);color:var(--ink-soft)}

.boardactions{display:flex;flex-wrap:wrap;gap:var(--s3);justify-content:center}
.boardfoot{font:var(--t-small)/1.6 var(--f-display);color:var(--ink-faint);margin:0;text-align:center;max-width:70ch;margin-inline:auto}

/* A worked example is not a run. It has to be impossible to mistake for one,
   at any scroll position, so the banner is sticky within the board. */
.example-banner{
  position:sticky;top:calc(var(--header-h) + var(--ribbon-h));z-index:5;
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3);
  padding:var(--s3) var(--s4);border-radius:var(--r-md);
  background:repeating-linear-gradient(135deg,var(--warn-bg) 0 12px,color-mix(in srgb,var(--warn-bg) 80%,var(--paper)) 12px 24px);
  border:1px solid var(--warn);
  font:650 var(--t-ui)/1.45 var(--f-display);color:var(--ink);
}
.example-banner b{color:var(--warn);text-transform:uppercase;letter-spacing:.08em;font-size:var(--t-micro)}
.example-banner span{color:var(--ink-soft);font-weight:400;font-size:var(--t-small)}
.board.is-example .boardcol,.board.is-example .auditbox,.board.is-example .agentstrip{border-style:dashed}

/* ============================ footer =================================== */

.footer{
  display:flex;flex-wrap:wrap;gap:var(--s3) var(--s5);align-items:center;
  padding-block:var(--s6) var(--s7);margin-top:var(--s6);
  border-top:1px solid var(--rule);
  font:var(--t-small)/1.6 var(--f-display);color:var(--ink-faint);
}
.footer a{color:var(--ink-soft);text-decoration:none;border-bottom:1px solid var(--rule)}
.footer a:hover{color:var(--ink);border-bottom-color:var(--ink-faint)}

/* ============================ responsive =============================== */

@media(max-width:1000px){
  .playground,.boardcols{grid-template-columns:1fr}
  .boardstats{grid-template-columns:repeat(3,1fr)}
  .demo-grid{grid-template-columns:1fr}
}
@media(max-width:1000px){
  .site-header{flex-wrap:wrap;padding-block:var(--s2);gap:var(--s2)}
  .site-nav{order:3;width:100%;margin:0;overflow-x:auto;padding-bottom:2px}
  .stack-ribbon{position:static}
  html{scroll-padding-top:16px}
  .example-banner{position:static}
  .clue-stage{grid-template-columns:1fr}
  .metric-grid{grid-template-columns:1fr}
  .fact-strip{grid-template-columns:1fr 1fr}
  .fact-strip div:nth-child(2){border-right:0}
  .api-callout{flex-direction:column;align-items:stretch}
  .masthead{padding-block:var(--s7) var(--s6)}
  .section{padding-block:var(--s7)}
}
@media(max-width:560px){
  .wordmark{font-size:var(--t-micro)}
  .header-actions .segmented{display:none}
  .shell{width:min(100% - 28px,var(--shell))}
  .boardstats{grid-template-columns:repeat(2,1fr)}
  .preset-grid{grid-template-columns:1fr}
  .fact-strip{grid-template-columns:1fr}
  .fact-strip div{border-right:0;border-bottom:1px solid var(--rule)}
  .fact-strip div:last-child{border-bottom:0}
  .flow li{grid-template-columns:40px 1fr;gap:var(--s3)}
  .card,.boardcol,.auditbox,.agentstrip,.keybox{padding:var(--s4)}
}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
}

/* ============================ print ====================================
   Archivists print dossiers and file them. The printed page keeps the
   evidence and drops the interface: no navigation, no controls, and every
   source URL written out so a paper copy can be checked years later. */
@media print{
  :root{--paper:#fff;--card:#fff;--sunk:#f4f4f4;--ink:#000;--ink-soft:#333;--ink-faint:#555;--rule:#bbb;--rule-soft:#ddd}
  .site-header,.stack-ribbon,.stack-panel,.skip,.tabs,.cta-row,.row-actions,
  .boardactions,.api-callout,.demo-card,.play-form,.keybox-actions,
  button,.primary-button,.secondary-button,.link-button{display:none!important}
  body{background:#fff;font-size:11pt}
  .board{display:block}
  .boardcols{display:block}
  .boardcol,.auditbox,.agentstrip,.card{border:1px solid #bbb;box-shadow:none;page-break-inside:avoid;margin-bottom:12pt}
  .claim,.srcrow,.gaterow,.auditrow,.presetcard{page-break-inside:avoid}
  .agentcard pre{max-height:none;overflow:visible}
  .agentcard[open] summary{font-weight:700}
  /* A printed citation is worthless without its URL. */
  .srchead a::after{content:" (" attr(href) ")";font:9pt var(--f-data);word-break:break-all}
  .example-banner{position:static;border:2px solid #000}
  a{text-decoration:underline}
  h1{font-size:24pt}h2{font-size:16pt}h3{font-size:12pt}
}

/* Sub-heading inside a section, for the two evaluation arms. */
.subhead{font:800 var(--t-micro)/1.3 var(--f-display);letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-faint);margin:var(--s5) 0 var(--s3);padding-bottom:var(--s2);border-bottom:1px solid var(--rule-soft)}
.metric.warn{border-color:color-mix(in srgb,var(--warn) 40%,var(--rule))}
.metric.warn strong{color:var(--warn)}

/* ==================== dossier archive and practice register ==============
   Two pages added to close the two widest gaps in the product: that the real
   output could not be read without a six-minute wait, and that the only
   evaluation by practitioners was a limitation paragraph rather than a page. */

.dossier-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:var(--s3);
  margin:0 0 var(--s4);padding:0;list-style:none}
.dossier-list li{display:grid}
.dossier-pick{
  display:grid;gap:var(--s1);align-content:start;width:100%;height:100%;
  text-align:left;padding:var(--s4);cursor:pointer;
  background:var(--card);border:1px solid var(--rule);border-radius:var(--r-md);
  border-left-width:3px;border-left-color:var(--rule);color:inherit;font:inherit;
}
.dossier-pick:hover{background:var(--sunk)}
.dossier-pick:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.dossier-pick.active{border-left-color:var(--accent);background:var(--accent-bg)}
.dossier-id{font:750 var(--t-small)/1 var(--f-data);letter-spacing:.06em;color:var(--ink)}
.dossier-title{font:var(--t-small)/1.4 var(--f-display);color:var(--ink-soft)}
.dossier-verdict{font:650 var(--t-micro)/1.3 var(--f-display);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint)}
.dossier-verdict[data-verdict="candidates"]{color:var(--warn)}
.dossier-verdict[data-verdict="abstain"]{color:var(--ink-faint)}
.dossier-verdict[data-verdict="probable"]{color:var(--pass)}
.dossier-meta{font:var(--t-micro)/1.4 var(--f-data);color:var(--ink-faint);font-variant-numeric:tabular-nums}

/* An objection card leads with its status, because the failures are the part
   of this register that earns the rest of it any credibility. */
.obj{border-left:3px solid var(--rule)}
.obj[data-status="met"]{border-left-color:var(--pass)}
.obj[data-status="not_met"],.obj[data-status="partially_met"]{border-left-color:var(--warn)}
.obj-head{display:flex;align-items:center;gap:var(--s3);margin-bottom:var(--s2)}
.obj-id{font:750 var(--t-small)/1 var(--f-data);letter-spacing:.06em;color:var(--ink-faint)}
.obj-status{
  font:650 var(--t-micro)/1 var(--f-display);letter-spacing:.08em;text-transform:uppercase;
  padding:3px var(--s2);border-radius:var(--r-pill);background:var(--sunk);color:var(--ink-soft);
}
.obj-status[data-status="met"]{background:var(--pass-bg);color:var(--pass)}
.obj-status[data-status="not_met"],.obj-status[data-status="partially_met"]{background:var(--warn-bg);color:var(--warn)}
.obj h3{margin:0 0 var(--s3);font:700 1.02rem/1.4 var(--f-display)}
.obj-quote{
  margin:0 0 var(--s3);padding:var(--s3) var(--s4);background:var(--sunk);
  border-left:2px solid var(--rule);border-radius:0 var(--r-sm) var(--r-sm) 0;
}
.obj-quote p{margin:0 0 var(--s2);font:var(--t-ui)/1.65 var(--f-body);color:var(--ink)}
.obj-quote cite{font:var(--t-micro)/1.5 var(--f-display);color:var(--ink-faint);font-style:normal}
.obj-kind{color:var(--ink-faint)}
.obj-close,.obj-evidence{margin:var(--s3) 0 0;font:var(--t-small)/1.6 var(--f-display);color:var(--ink-soft)}
.obj-evidence code{font:var(--t-micro)/1 var(--f-data);background:var(--sunk);padding:2px 5px;border-radius:var(--r-sm)}
.lede-card{background:var(--sunk)}
.lede-card p{margin:0;font:var(--t-ui)/1.65 var(--f-body);color:var(--ink-soft)}

@media print{
  .dossier-list,.dossier-pick{display:none!important}
  .obj-quote{background:#fff;border-left:2px solid #000}
}

/* A pull quote from a primary source. Used where a cited person says the thing
   better than we could, so the page shows the quotation rather than a summary
   of it, with the attribution and a link to check it. */
.pullquote{margin:var(--s5) 0;padding:var(--s5);background:var(--sunk);border-left:3px solid var(--accent);border-radius:0 var(--r-md) var(--r-md) 0}
.pullquote blockquote{margin:0}
.pullquote blockquote p{margin:0;font:var(--t-deck)/1.55 var(--f-body);color:var(--ink)}
.pullquote figcaption{margin-top:var(--s3);font:var(--t-small)/1.6 var(--f-display);color:var(--ink-faint)}
.pullquote cite{font-style:italic}
@media print{.pullquote{background:#fff;border-left:3px solid #000}}

/* ============ progressive disclosure inside a dossier ====================
   A dossier can carry fourteen claims with several sourced excerpts each.
   Rendered flat that was six screens of scrolling before a reader reached the
   audit, and the two things worth seeing first, a refused citation and a
   contradiction, sat in the middle of it.

   Nothing is removed. Each claim is a <details> whose summary carries enough to
   decide whether to open it, the ones that would otherwise be missed open
   themselves, and everything unfolds for print. */

.claimbar{
  display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  margin:var(--s3) 0 var(--s2);padding-bottom:var(--s2);border-bottom:1px solid var(--rule-soft);
}
.claimcount{font:650 var(--t-micro)/1 var(--f-display);letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-faint)}

details.claim{
  border:1px solid var(--rule);border-left-width:3px;border-radius:var(--r-md);
  background:var(--card);margin-bottom:var(--s2);
}
details.claim.supports{border-left-color:var(--rule)}
details.claim.contradicts{border-left-color:var(--crit)}
details.claim.neutral{border-left-color:var(--ink-faint)}

.claimsum{
  display:grid;grid-template-columns:auto auto 1fr auto;gap:var(--s2) var(--s3);
  align-items:baseline;padding:var(--s3) var(--s4);cursor:pointer;list-style:none;
}
.claimsum::-webkit-details-marker{display:none}
.claimsum:hover{background:var(--sunk)}
details.claim:focus-within>.claimsum{outline:2px solid var(--accent);outline-offset:-2px}
.claimsum .claimtext{
  font:var(--t-small)/1.5 var(--f-body);color:var(--ink);margin:0;
  /* Two lines is enough to recognise a claim and short enough to scan a list. */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.srcsum{
  font:650 var(--t-micro)/1.3 var(--f-data);color:var(--ink-faint);white-space:nowrap;
}
.srcsum.has-refused{color:var(--crit)}
.srcsum.has-none{color:var(--warn)}
.claimbody{padding:0 var(--s4) var(--s4);border-top:1px solid var(--rule-soft)}
.claimbody .basis{margin-top:var(--s3)}

/* The audit repeats URLs already shown against their claims, so it folds and
   puts its result in the summary. It opens itself when something was refused. */
.auditfold,.coldfold{margin-top:var(--s3)}
.auditsum{
  display:flex;align-items:baseline;gap:var(--s3);cursor:pointer;list-style:none;
  padding:var(--s3);border:1px solid var(--rule);border-radius:var(--r-md);
  background:var(--paper);font:var(--t-small)/1.4 var(--f-display);
}
.auditsum::-webkit-details-marker{display:none}
.auditsum::after{content:"show";margin-left:auto;font:650 var(--t-micro)/1 var(--f-display);
  letter-spacing:.08em;text-transform:uppercase;color:var(--accent-ink)}
details[open]>.auditsum::after{content:"hide"}
.auditsum:hover{background:var(--sunk)}
.auditbad{color:var(--crit);font-weight:650}

@media print{
  /* An archivist files the paper copy. Nothing may be hidden behind a control
     that does not exist on paper, so every fold prints open. */
  details.claim,.auditfold,.coldfold,.agentcard{display:block!important}
  details.claim>.claimbody,.auditfold>*,.coldfold>*{display:block!important}
  .claimsum{display:block;padding:0 0 4pt}
  .claimsum .claimtext{-webkit-line-clamp:unset;display:block;overflow:visible}
  .claimbar button,.auditsum::after{display:none!important}
  .auditsum{border:0;padding:0;background:none;font-weight:700}
}

/* Context a reader needs once, not on every visit. Folded so it costs a line
   rather than a screen, and the summary states the point so folding it does not
   hide the caveat. */
.readnote{padding:0;margin-bottom:var(--s3)}
.readnote>.auditsum{border:0;border-radius:var(--r-md);background:var(--card);padding:var(--s4)}
.readnote[open]>.auditsum{border-bottom:1px solid var(--rule-soft);border-radius:var(--r-md) var(--r-md) 0 0}
.readnote>p{margin:var(--s3) var(--s5)}
.readnote>p:last-child{margin-bottom:var(--s5)}
@media print{.readnote>*{display:block!important}}

/* A collapsed claim should cost one row, not three. One clamped line of the
   claim itself is enough to recognise it; the rest is behind the fold. */
.claimsum{padding:var(--s2) var(--s3);gap:var(--s2)}
.claimsum .claimtext{-webkit-line-clamp:1;font-size:var(--t-small)}
details.claim[open] .claimsum .claimtext{-webkit-line-clamp:unset;display:block;overflow:visible}
.auditrow{padding:var(--s2) var(--s3)}
.auditrow b{font-size:var(--t-small)}

/* The five roles are identical on every dossier and explained on the overview,
   so the strip folds and only its raw output costs height. */
details.agentstrip{margin-top:var(--s4)}
details.agentstrip>.auditsum{align-items:baseline}
details.agentstrip .strip{margin-top:var(--s3)}
@media print{details.agentstrip>*{display:block!important}}

/* =================== plain-language explainers ==========================
   A small "i" beside any term that carries weight. One sentence, no jargon.

   It opens three ways on purpose: hover for a mouse, focus for a keyboard, and
   click for touch and for anyone who wants it to stay put. Hover alone is the
   usual way this pattern is built and it reaches neither a keyboard nor a phone,
   which would contradict everything else in this stylesheet. */
.explain{position:relative;display:inline-flex;vertical-align:baseline;margin-left:6px}
.explain-btn{
  width:15px;height:15px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:var(--sunk);color:var(--ink-faint);
  font:700 10px/15px var(--f-display);text-align:center;
}
.explain-btn:hover{background:var(--accent-bg);color:var(--accent-ink)}
.explain-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.explain-bubble{
  position:absolute;left:50%;top:calc(100% + 8px);translate:-50% 0;z-index:40;
  width:min(280px,72vw);padding:var(--s3) var(--s4);
  background:var(--ink);color:var(--paper);border-radius:var(--r-md);
  box-shadow:var(--shadow-2);
  font:var(--t-small)/1.5 var(--f-display);text-align:left;
  opacity:0;visibility:hidden;transition:opacity .12s var(--ease);
  pointer-events:none;
}
.explain-bubble b{display:block;margin-bottom:4px;color:var(--paper);font-weight:700}
.explain-bubble::before{
  content:"";position:absolute;left:50%;top:-5px;translate:-50% 0;
  border:5px solid transparent;border-top:0;border-bottom-color:var(--ink);
}
/* Two states, not three. Hovering shows it; toggling pins it. Focus does not
   show it on its own, because a focus rule fought the toggle: the button still
   held focus after a click, so clicking again to close, and pressing Escape,
   both appeared to do nothing. A keyboard user presses Enter on the button,
   which is the same toggle a mouse user gets, and Escape closes it. */
.explain:hover .explain-bubble,
.explain.open .explain-bubble{opacity:1;visibility:visible}

/* Near the right edge the bubble would run off screen; nudge it back. */
.gaterow:last-child .explain-bubble,.stackrow .explain-bubble{left:auto;right:0;translate:0 0}
.gaterow:last-child .explain-bubble::before,.stackrow .explain-bubble::before{left:auto;right:14px;translate:0 0}

@media(prefers-reduced-motion:reduce){.explain-bubble{transition:none}}
@media print{.explain{display:none!important}}

/* ======================= the route ======================================
   Seven items in a nav is a menu, and a menu asks a first-time visitor to guess
   which door is right. The landing page opens with a numbered three-page path,
   and every page ends by naming the next one. */

.pathway{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:var(--s4);margin:var(--s5) 0 var(--s4);padding:0;list-style:none;counter-reset:none;
}
.pathway li{display:grid}
.pathway a{
  display:grid;gap:var(--s2);align-content:start;height:100%;
  padding:var(--s5);background:var(--card);border:1px solid var(--rule);
  border-radius:var(--r-md);border-top:3px solid var(--accent);
  text-decoration:none;color:inherit;
  transition:background .15s var(--ease),transform .15s var(--ease);
}
.pathway a:hover{background:var(--raise);transform:translateY(-2px)}
.pathway a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.path-num{
  display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:50%;background:var(--accent-bg);
  color:var(--accent-ink);font:800 var(--t-small)/1 var(--f-display);
}
.pathway b{font:750 1.1rem/1.3 var(--f-display);color:var(--ink)}
.path-say{font:var(--t-small)/1.6 var(--f-body);color:var(--ink-soft)}
.path-go{
  margin-top:var(--s2);font:650 var(--t-small)/1 var(--f-display);color:var(--accent-ink);
}
.path-go::after{content:" →"}

.nextstep{margin:var(--s8) auto var(--s7);width:min(var(--shell),calc(100% - 40px))}
.nextstep a{
  display:flex;align-items:center;gap:var(--s4);
  padding:var(--s5);background:var(--sunk);border:1px solid var(--rule);
  border-radius:var(--r-md);text-decoration:none;color:inherit;
  transition:background .15s var(--ease);
}
.nextstep a:hover{background:var(--accent-bg)}
.nextstep a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.nextstep-body{display:grid;gap:2px}
.nextstep-kicker{
  font:800 var(--t-micro)/1 var(--f-display);letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-faint);
}
.nextstep b{font:750 1.05rem/1.3 var(--f-display);color:var(--ink)}
.nextstep-blurb{font:var(--t-small)/1.5 var(--f-display);color:var(--ink-soft)}
.nextstep-arrow{margin-left:auto;font-size:1.5rem;color:var(--accent-ink)}

@media(prefers-reduced-motion:reduce){.pathway a{transition:none}.pathway a:hover{transform:none}}
@media print{.pathway,.nextstep{display:none!important}}

/* An absolutely positioned bubble 280px wide cannot fit beside a button near
   the edge of a 390px phone; it ran 94px off screen. Below the point where that
   becomes possible it docks to the bottom of the viewport instead, where it can
   never overflow and is easier to read with a thumb on the screen. */
@media(max-width:620px){
  .explain-bubble{
    position:fixed;left:12px;right:12px;bottom:12px;top:auto;
    width:auto;max-width:none;translate:none;
  }
  .explain-bubble::before{display:none}
}
.explain-bubble{max-width:min(280px,calc(100vw - 32px))}
