/* ============================================================================
   site/site.css — the PUBLIC MARKETING SURFACE, layered on engine/mc-ui.css
   ----------------------------------------------------------------------------
   THIS FILE DEFINES NO COLOUR. Every value below is a token out of
   engine/mc-ui.css, which is the one file in this repo that may define one.
   That is not a stylistic preference here — it is the whole reason the
   marketing site and the product cannot drift apart. Change the accent in
   mc-ui.css and this site follows on the next load, with no build step and no
   second copy of the palette to remember.

   WHAT IS DIFFERENT ABOUT A MARKETING PAGE, AND WHAT IS NOT.
   CLAUDE.md's "no explanatory prose on the page" rule governs MODULE pages: a
   paragraph telling the reader what a CONTROL does belongs in that control's
   MCINFO panel. These pages have no controls. Prose is the entire artifact, and
   a search engine rewards the page that answers the question. So the prose rule
   is out of scope here and the other three are not: no emoji, no hard-coded
   colour, and de-emphasis by ink or a recessed surface, never by opacity.

   TWO SCRIPTS. It used to be none, and the sentence that stood here said so.
   What changed first is site/hero.js — the live 4-D scene on the home page —
   and the terms it is held to are the reason the rule could move: it is
   fetched only AFTER the first paint, the page reads identically with it
   switched off, it sets no cookie, sends no beacon and makes no third-party
   request, and the only thing it fetches is the product's own scheduler out of
   engine/.

   What changed second is site/site-figs.js, which animates the capability
   diagrams once as they scroll into view, on the six pillar pages. It is held
   to the same terms and to one more that is the whole of its design:

     EVERY FIGURE'S STATIC MARKUP IS ITS RESTED, FINAL STATE.

   The SVG in the page is already the finished diagram with every number in it.
   The script rewinds one and plays it forward; it never builds one. So
   prefers-reduced-motion is a one-line early return with no second variant to
   drift, a reader with JavaScript off sees the finished figure rather than an
   empty frame, and a crawler reads the numbers out of the DOM. The tag is
   deferred, so neither script blocks a paint. site/estimating-and-takeoff.html
   additionally loads engine/mc-qs.js and re-derives the girth figure's offsets
   with the product's own measurement engine, and the figure states on its face
   which of the two answers is on screen.

   The two typefaces are self-hosted under vendor/fonts/ and always were.

   Sections: 0 the Animus ground · 1 nav · 2 hero · 2b the 4-D hero
   3 prose measure · 4 pillar cards · 5 fact rows · 6 limits block · 7 FAQ
   8 breadcrumb · 9 footer · 10 diagrams · 10b diagram inks · 11 responsive
   12 print
   ============================================================================ */

/* ---- 0. the Animus ground ------------------------------------------------ */
/* THE FIELD IS NOT DECLARED HERE, and that is deliberate.
   brand/animus/animus-field.js creates its own canvas, appends it to <body> at
   z-index:-1 and sets .animus-field-on on <html>; brand/animus/animus.css owns
   the rule that positions it and moves the page ground off <body>, because a
   z-index:-1 child of <body> paints in the ROOT stacking context and would
   otherwise be buried under body's own background box. This file adds one
   thing only: it lifts the page's own three landmarks into their own stacking
   level, so the lattice reads as ground between them rather than through them.

   MOTION FAILS OPEN, which is the rule site-figs.js already works to: every
   surface here is painted by CSS and is the rested, final state. With the
   field absent, blocked, or stood down by prefers-reduced-motion the page
   loses an animation and not one word, one rule or one contrast ratio.
   Nothing here is hidden pending a script; there is no `html.js` gate on it. */
.mnav,#main,.mfoot,.skip{position:relative;z-index:1}

/* THE READING GROUND, AND IT GOES ON <main>, EDGE TO EDGE.
   The field is a full-viewport canvas, so with nothing over it the lattice runs
   behind every paragraph on the page — and a body of copy sitting on a moving
   spectral gradient is exactly the failure ARCHITECTURE.md § 8 says no gate in
   this repo can see, because nothing computes a contrast ratio through a
   canvas. `--scrim` is animus.css's own near-opaque veil, so the lattice stays
   present as depth behind the reading column and never becomes contrast
   against it.

   IT WAS ON `#main>.wrap` FIRST AND THAT WAS WRONG ON SIGHT. `.wrap` is the
   centred max-width column, so scrimming it painted a slab with two hard
   vertical edges down the page and the field brighter outside them — a panel
   nobody drew. <main> is full-bleed, so the veil has no edge at all.

   The hero is inside it and is veiled too, which costs nothing: on index the
   4-D canvas covers that band completely, and on the six pillar pages the
   subhero paints its own --wash-accent gradient over the veil, so it still
   reads as the lighter band it is. The nav and the footer sit OUTSIDE <main>
   and keep the field at full strength, top and bottom of every page. */
#main{background:var(--scrim)}

/* THE SPECTRUM RULE. The one Animus element that IS the design rather than a
   caption about it: hue running the full circuit in a 1 px band. The class,
   the height and the gradient are animus.css's `.animus-rule-spectrum`; this
   file adds placement — under the nav and across the head of the footer, and
   nowhere else — and the sweep, which is the same travelling brightening the
   field does, on the one element that is already the whole spectrum at rest. */
@media (prefers-reduced-motion:no-preference){
  .animus-rule-spectrum{background-size:200% 100%;animation:spectrum-sweep 14s linear infinite}
}
@keyframes spectrum-sweep{from{background-position:0% 50%}to{background-position:200% 50%}}
@media print{.animus-rule-spectrum{display:none!important}}

/* ---- 1. nav -------------------------------------------------------------- */
.mnav{position:sticky;top:0;z-index:30;background:var(--color-card);
  border-bottom:1px solid var(--color-neutral-200)}
/* A pane of glass over the field rather than a lid on it: the lattice keeps
   travelling underneath and one hairline plus the spectrum band mark the edge.
   Where backdrop-filter is unsupported the token background stands on its own,
   which is the state the contrast audit measures. */
@supports (backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px)){
  .mnav{background:var(--surface-glass,var(--color-card));
    -webkit-backdrop-filter:blur(14px) saturate(1.15);backdrop-filter:blur(14px) saturate(1.15)}
}
.mnav .wrap{display:flex;align-items:center;gap:var(--sp-4);min-height:62px;flex-wrap:wrap;
  padding-top:var(--sp-2);padding-bottom:var(--sp-2)}
.mnav .mlogo{display:flex;align-items:center;gap:var(--sp-2);text-decoration:none;flex:0 0 auto}
.mnav .mlogo img{width:28px;height:28px;display:block}
.mnav .mlogo span{font-family:var(--font-display);font-weight:500;letter-spacing:.16em;
  font-size:12.5px;color:var(--color-text)}
.mnav nav{display:flex;gap:var(--sp-1) var(--sp-4);flex-wrap:wrap;flex:1;
  justify-content:flex-end;align-items:center}
.mnav nav a{font-size:13px;font-weight:600;color:var(--bone-dim);text-decoration:none;
  padding:4px 0;border-bottom:2px solid transparent}
.mnav nav a:hover{color:var(--color-accent-800);border-bottom-color:var(--color-accent-400)}
/* The current page is marked with an ink and a rule, not with a fade on the
   others. Dimming six links to distinguish one is the failure mode rule 3
   exists to stop. */
.mnav nav a[aria-current="page"]{color:var(--color-accent-800);
  border-bottom-color:var(--color-accent-600)}

/* ---- 1b. THE MEASURE IS IN `em`, AND `ch` IS WHY THE DESKTOP PAGES MOVED ---
   `ch` reads as "characters". It is not: `1ch` is THE ADVANCE OF THE DIGIT
   ZERO IN THE ELEMENT'S OWN FONT, so a column capped in it is a column whose
   WIDTH depends on which face has arrived — and both arrive over the network,
   after first paint, behind four render-blocking stylesheets. Zero advance per
   em, measured: Figtree 0.641 / Tektur 0.650, against 0.53906 / 0.55518 for
   the Segoe UI the stack falls through. Tektur's is checkable off the file —
   head unitsPerEm 1000, hmtx advance 650. So every measure was 15-16 % narrow
   until the faces landed. On bim-and-4d.html the subhero lede was 641 px and
   became 763 px (70 x 0.53906 x 17 = 641.5, then 70 x 0.641 x 17 = 762.8), the
   h1 506 -> 593; both dropped a line, the hero lost 71 px, the document 426 px,
   and every block below travelled up by the running total. siteperf measured
   CLS 0.119 / 0.142 / 0.114 on three pages against a 0.10 budget.

   THE PHONE WAS CLEAN FOR A REASON, AND IT IS NOT A RACE: at 375 px the
   viewport is narrower than the cap, so the cap never binds and the column
   measured 327 px in either face. Same markup, same fonts, no shift.

   `em` is the element's own font-size, which is exactly what `ch` was
   proportional to, so every breakpoint still moves its own measure and nothing
   here is a pixel constant that comes apart at another width. Each value is
   the old character count times the shipping face's zero advance, so the
   column is the width it always was once the face is in — and is now that
   width before it is in as well. In characters: Tektur 12.35em = 19, 15.6em =
   24, 10.4em = 16; Figtree 28.204em = 44, 41.024em = 64, 42.306em = 66,
   43.588em = 68, 44.87em = 70, 46.152em = 72, 51.28em = 80, 56.408em = 88.  */

/* ---- 2. hero ------------------------------------------------------------- */
/* --wash-accent / --wash-accent-2 are the two tokens mc-ui.css § 2b declares
   for exactly this gradient. */
.hero{background:linear-gradient(135deg,var(--wash-accent),var(--wash-accent-2));
  border-bottom:1px solid var(--color-neutral-200)}
.hero .wrap{padding-top:var(--sp-7);padding-bottom:var(--sp-7)}
/* The eyebrow is a label, so it is set in the label face at label tracking.
   Scoped to the hero rather than written over the shared .eyebrow, because
   mc-ui.css owns that class for every module page in the product. */
.hero .eyebrow,.crumb{font-family:var(--font-mono,var(--mono));font-weight:500;
  letter-spacing:.26em}
.hero h1{margin:0 0 var(--sp-3);font-size:44px;max-width:12.35em}
.hero .lede{font-size:18px;max-width:42.306em;color:var(--color-text);margin-bottom:var(--sp-5)}
.hero .cta{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:center}
.hero .cta a{text-decoration:none}
.subhero h1{margin:0 0 var(--sp-3);font-size:38px;max-width:15.6em}
.subhero .lede{font-size:17px;max-width:44.87em;color:var(--color-text)}

/* ---- 2b. the 4-D hero ---------------------------------------------------- */
/* The canvas is a LAYER UNDER the headline, not a background image: site/hero.js
   paints a --color-bg ramp into the left of its own bitmap, so the type sits on
   the same ground it would on any other section of this page and keeps exactly
   the contrast engine/mc-ui.css guarantees for it. Nothing here dims text to
   make room for a picture.
   The gradient below is the pre-script state and the no-script state. It is the
   one that was here before the canvas existed, and it stays: a hero that is
   blank until a script arrives is a hero that is blank for anyone who blocks
   scripts. */
.hero4d{position:relative;overflow:hidden;isolation:isolate;
  min-height:clamp(470px,64vh,660px);display:flex;align-items:center}
.hero4d .heroInner{position:relative;z-index:2;width:100%}
/* The measure is short here on purpose: hero.js only ramps its --color-bg
   scrim across the left 58 % of the canvas, so any line that ran past that
   would be sitting on the picture rather than on the page. */
.hero4d h1{max-width:10.4em}
.hero4d .lede{max-width:28.204em;font-size:17px}
.hero4d .cta{max-width:28.204em}
.heroCanvas{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;
  border:0}

/* The live readout. It is the product's own panel chrome, because it is showing
   the product's own numbers: the day, the date on the project calendar, the
   activity the CPM says is in hand, and whether it is on the critical path. */
.heroHud{position:absolute;z-index:3;right:var(--sp-5);bottom:var(--sp-5);
  width:min(346px,calc(100% - var(--sp-5) * 2));
  background:var(--color-card);border:1px solid var(--color-neutral-200);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-md);
  padding:var(--sp-3) var(--sp-4) var(--sp-4)}
.heroHud .hhTop{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.heroHud .hhLab{font-family:var(--font-mono,var(--mono));font-size:9.5px;font-weight:500;
  letter-spacing:.2em;text-transform:uppercase;color:var(--bone-faint)}
.heroHud .hhBig{font-family:var(--font-display);font-size:22px;font-weight:500;
  color:var(--color-text);font-variant-numeric:tabular-nums;line-height:1.1}
.heroHud .hhDate{font-size:12.5px;font-weight:600;color:var(--bone-dim);
  font-variant-numeric:tabular-nums}
.heroHud .hhPct{margin-left:auto;font-size:13px;font-weight:800;
  color:var(--color-accent-800);font-variant-numeric:tabular-nums}
.heroHud .hhTrack{margin:var(--sp-2) 0 var(--sp-2);height:5px;border-radius:3px;
  background:var(--color-neutral-200);overflow:hidden}
.heroHud .hhBar{display:block;height:100%;width:0;background:var(--color-accent-600);
  border-radius:3px}
.heroHud .hhBot{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  min-height:20px}
.heroHud .hhAct{font-size:12.5px;font-weight:600;color:var(--color-text);line-height:1.35}
.heroHud .hhChip{font-size:10px;font-weight:800;letter-spacing:.07em;
  text-transform:uppercase;color:var(--st-critical-ink);
  background:var(--st-critical-tint);border:1px solid var(--color-alarm-300);
  border-radius:999px;padding:2px 7px;white-space:nowrap}

/* What the scene is, and — when the scheduler does not load — what it is not.
   site/hero.js writes this element, including the failure wording. */
.heroNote{margin:var(--sp-4) 0 0;font-size:12.5px;line-height:1.6;
  color:var(--bone-faint);max-width:56.408em;
  border-left:2px solid var(--color-accent-300);padding-left:var(--sp-3)}

/* ---- 3. prose measure ---------------------------------------------------- */
/* A marketing page is read, not scanned, so it gets a real measure: 68
   characters of Figtree — 43.588em, per § 1b — is inside the 45-75 band
   typography has agreed on for a century, and the product's own .lede/.secp
   already cap at 74/80ch. Those two are engine/mc-ui.css's and stay in `ch`:
   they are a MODULE page's measure, and a module page is a fixed-width app
   surface, not a column whose line count moves the rest of a document. */
.prose{max-width:43.588em}
.prose p{margin:0 0 var(--sp-4);color:var(--bone-dim);font-size:15.5px;line-height:1.68}
.prose p.tight{margin-bottom:var(--sp-2)}
.prose p b,.prose li b{color:var(--color-text)}
.prose h2{font-size:26px;margin:var(--sp-7) 0 var(--sp-3);letter-spacing:-.015em}
.prose h3{font-size:18px;margin:var(--sp-5) 0 var(--sp-2)}
.prose ul,.prose ol{margin:0 0 var(--sp-4);padding-left:22px;color:var(--bone-dim);
  font-size:15.5px;line-height:1.68}
.prose li{margin:0 0 var(--sp-2)}
.prose h2+p,.prose h3+p{margin-top:0}
/* A pull quote for the one sentence a section turns on. */
.pull{border-left:3px solid var(--color-accent-500);padding:2px 0 2px var(--sp-4);
  margin:var(--sp-4) 0;font-size:17px;line-height:1.6;color:var(--color-text);max-width:41.024em}

/* ---- 4. pillar cards ----------------------------------------------------- */
.pillars{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:var(--sp-4);margin:var(--sp-5) 0 0}
.pcard{position:relative;background:var(--color-card);border:1px solid var(--color-neutral-200);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);padding:var(--sp-5);
  display:flex;flex-direction:column;overflow:hidden}
.pcard:hover{border-color:var(--color-accent-300);box-shadow:var(--shadow-md)}
/* HUE ADVANCES WITH POSITION. Each capability card takes the next ink from
   mc-ui.css § 3b's categorical `--series-1…8` ramp — the same ramp the product
   uses when the only thing a colour has to say is "which one". The order is
   the order the cards are in, so it is derived from the document rather than
   written down twice, and the six capability pages are marked the same way in
   the diagrams they contain.
   THE INK IS SPENT ON A 2 px EDGE AND NOTHING ELSE. That is non-text, where
   WCAG 2.2 AA asks 3:1 and the series ramp is derived to clear it; the same
   eight inks cannot also promise 4.5:1 on a card heading, and nothing in this
   repo computes a ratio to catch it if they failed. */
/* Square, like the shell's cards and like everything else in the system: the
   Animus geometry note is that corners are cut, not rounded. animus.css sets
   `.card` to --r-0 and leaves the legacy --radius-lg at 8px, and `.pcard` is
   this site's exact analogue of the shell's `.card` — the capability grid a
   reader meets first on each surface — so it takes the panel value rather than
   the legacy one. It also makes the seam below meet the corner: at an 8 px
   radius with overflow:hidden the coloured edge was clipped to a stub at each
   end and read as a mistake. */
.pcard{border-radius:var(--r-0,0)}
.pcard::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:var(--color-neutral-200);transition:background .2s var(--ease),width .2s var(--ease)}
.pcard:nth-child(8n+1)::before{background:var(--series-1)}
.pcard:nth-child(8n+2)::before{background:var(--series-2)}
.pcard:nth-child(8n+3)::before{background:var(--series-3)}
.pcard:nth-child(8n+4)::before{background:var(--series-4)}
.pcard:nth-child(8n+5)::before{background:var(--series-5)}
.pcard:nth-child(8n+6)::before{background:var(--series-6)}
.pcard:nth-child(8n+7)::before{background:var(--series-7)}
.pcard:nth-child(8n+8)::before{background:var(--series-8)}
.pcard:hover::before{width:3px}
.pcard h3{margin:0 0 var(--sp-2);font-size:18px}
.pcard h3 a{text-decoration:none;color:var(--color-accent-800)}
.pcard h3 a:hover{text-decoration:underline}
.pcard p{margin:0 0 var(--sp-3);font-size:14px;line-height:1.6;color:var(--bone-dim)}
.pcard .plist{margin:0 0 var(--sp-3);padding-left:18px;font-size:13px;line-height:1.6;
  color:var(--bone-dim)}
.pcard .pfoot{margin-top:auto;font-size:12.5px;color:var(--bone-faint)}

/* ---- 5. fact rows -------------------------------------------------------- */
/* A claim beside the thing that makes it checkable. The left column is the
   claim; the right column is what it is grounded in. */
.facts{display:grid;grid-template-columns:minmax(0,1fr);gap:0;margin:var(--sp-4) 0;
  border:1px solid var(--color-neutral-200);border-radius:var(--radius-md);
  background:var(--color-card);overflow:hidden}
.facts .frow{display:grid;grid-template-columns:minmax(180px,.9fr) minmax(0,1.4fr);
  gap:var(--sp-4);padding:var(--sp-3) var(--sp-4);
  border-top:1px solid var(--color-neutral-200)}
.facts .frow:first-child{border-top:none}
.facts .fk{font-weight:700;font-size:13.5px;color:var(--color-text);line-height:1.5}
.facts .fv{font-size:13.5px;color:var(--bone-dim);line-height:1.6}
.facts .fv code{background:var(--color-neutral-100);border-radius:4px;padding:1px 5px;font-size:12px}

/* ---- 6. the limits block ------------------------------------------------- */
/* WHAT THIS PRODUCT DOES NOT DO, on the page, in the same type as the claims.
   It is the marketing surface's version of trap 15: a capability we cannot
   deliver is NAMED, never omitted, because an omission reads as a yes to a
   reader who has no way to tell "we don't" from "we didn't mention it".
   It takes a recessed surface and a rule, not an alarm colour — an honest
   limit is a statement, not a failure. */
.limits{background:var(--color-neutral-100);border:1px solid var(--color-neutral-300);
  border-radius:var(--radius-md);padding:var(--sp-5);margin:var(--sp-5) 0}
.limits h2,.limits h3{margin-top:0}
.limits ul{margin:0;padding-left:20px;color:var(--bone-dim);font-size:15px;line-height:1.65}
.limits li{margin:0 0 var(--sp-2)}
.limits li:last-child{margin-bottom:0}
.limits li b{color:var(--color-text)}

/* ---- 7. FAQ -------------------------------------------------------------- */
/* <details> so the answer is in the DOM whether or not it is open — a crawler
   and a screen reader both get the full text, and mc-ui.css § 22 already forces
   every <details> open for print. */
.faq{margin:var(--sp-4) 0 0;max-width:46.152em}
.faq details{border-bottom:1px solid var(--color-neutral-200);padding:var(--sp-3) 0}
.faq summary{font-weight:700;font-size:16px;cursor:pointer;color:var(--color-text);
  list-style:none;display:flex;gap:var(--sp-3);align-items:baseline}
.faq summary::-webkit-details-marker{display:none}
.faq summary::before{content:"\25B8";color:var(--color-accent-600);font-size:13px;flex:0 0 auto}
.faq details[open] summary::before{content:"\25BE"}
.faq summary:hover{color:var(--color-accent-800)}
.faq .fa{padding:var(--sp-2) 0 0 22px;color:var(--bone-dim);font-size:15px;line-height:1.68;
  max-width:42.306em}
.faq .fa p{margin:0 0 var(--sp-3)}
.faq .fa p:last-child{margin-bottom:0}

/* A table caption, printed under the table. mc-ui.css owns the table itself. */
.tcap{caption-side:bottom;text-align:left;font-size:12.5px;color:var(--bone-faint);
  line-height:1.55;padding-top:var(--sp-3);max-width:41.024em;white-space:normal}

/* ---- 8. breadcrumb ------------------------------------------------------- */
.crumb{font-size:12px;color:var(--bone-faint);margin:var(--sp-4) 0 0;
  text-transform:uppercase;letter-spacing:.08em;font-weight:700}
.crumb a{color:var(--bone-faint);text-decoration:none}
.crumb a:hover{color:var(--color-accent-800)}
.crumb span{margin:0 var(--sp-2)}

/* ---- 9. footer ----------------------------------------------------------- */
/* The footer carries the second spectrum rule, flush across its whole width,
   and is the same pane of glass the nav is — the field runs under the page
   from edge to edge, so the last band of it is not a solid slab. */
.mfoot{position:relative;z-index:1;border-top:1px solid var(--color-neutral-200);
  background:var(--color-card);margin-top:var(--sp-7);padding:var(--sp-6) 0 var(--sp-5)}
.mfoot>.animus-rule-spectrum{position:absolute;left:0;right:0;top:-1px}
@supports (backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px)){
  .mfoot{background:var(--surface-glass,var(--color-card));
    -webkit-backdrop-filter:blur(14px) saturate(1.15);backdrop-filter:blur(14px) saturate(1.15)}
}
.mfoot .fgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:var(--sp-5)}
.mfoot h2{font-family:var(--font-mono,var(--mono));font-size:10px;font-weight:500;
  text-transform:uppercase;letter-spacing:.22em;
  color:var(--bone-faint);margin:0 0 var(--sp-3)}
.mfoot ul{list-style:none;margin:0;padding:0}
.mfoot li{margin:0 0 var(--sp-2)}
.mfoot a{font-size:13.5px;color:var(--bone-dim);text-decoration:none}
.mfoot li a{display:inline-block;min-height:24px;padding-top:4px;padding-bottom:4px}
.mfoot a:hover{color:var(--color-accent-800);text-decoration:underline}
.mfoot .fnote{margin-top:var(--sp-5);padding-top:var(--sp-4);
  border-top:1px solid var(--color-neutral-200);font-size:12.5px;color:var(--bone-faint);
  line-height:1.6;max-width:51.28em}
.mfoot .fnote b{color:var(--bone-dim)}

/* ---- 10. diagrams -------------------------------------------------------- */
/* Inline SVG only. Every one carries <title> and <desc> and an aria-labelledby
   pointing at them, which is the accessible-name mechanism for inline SVG the
   same way alt= is for <img>. Strokes and fills are --series-* and status inks
   out of mc-ui.css; nothing here picks a colour. */
.fig{margin:var(--sp-5) 0;border:1px solid var(--color-neutral-200);
  border-radius:var(--radius-md);background:var(--color-card);padding:var(--sp-4);
  overflow-x:auto}
.fig svg{width:100%;height:auto;max-width:640px;margin:0 auto}
.fig figcaption{font-size:12.5px;color:var(--bone-faint);line-height:1.55;
  margin-top:var(--sp-3);max-width:41.024em}
.fig .flab{font-family:var(--font-body);font-size:11px;font-weight:700;
  fill:var(--bone-dim);letter-spacing:.04em}
.fig .fval{font-family:var(--font-body);font-size:12px;font-weight:700;
  fill:var(--color-text);font-variant-numeric:tabular-nums}
/* A column heading inside a figure: the same 10-11px caps the product uses for
   .chart-title, so a diagram on the marketing page and a chart in the product
   are set in the same voice. */
.fig .fsm{font-family:var(--font-body);font-size:10px;font-weight:700;
  fill:var(--bone-faint);letter-spacing:.08em}
/* The one number a figure is ABOUT. */
.fig .fnum{font-family:var(--font-body);font-size:19px;font-weight:800;
  fill:var(--color-text);font-variant-numeric:tabular-nums}
.fig .fmono{font-variant-numeric:tabular-nums}

/* ---- 10b. diagram inks --------------------------------------------------- */
/* NOT ONE COLOUR IS CHOSEN HERE EITHER. Every value below is a token out of
   engine/mc-ui.css, which is why site/site-figs.js can animate these figures
   without ever touching a fill: the script moves geometry and toggles a class,
   and the palette stays in the one file allowed to hold one.

   The pairing is the product's own vocabulary, not a decoration:
     --st-critical-*  the answer that costs money — a clash, an over-claim, a
                      weather day past the allowance, the deterministic date
                      the distribution says you will miss.
     --color-accent-* the derived answer the figure is teaching — P50/P80, the
                      mid-depth plane, the girth on the moving line.
     --series-*       plain categorical data with no status in it. */

/* structure */
.fig .fx-axis {fill:none;stroke:var(--color-neutral-400);stroke-width:1}
.fig .fx-grid {fill:none;stroke:var(--color-neutral-200);stroke-width:1}
.fig .fx-rule {fill:none;stroke:var(--color-neutral-300);stroke-width:1}
.fig .fx-dim  {fill:none;stroke:var(--color-neutral-500);stroke-width:1}
.fig .fx-link {fill:none;stroke:var(--color-neutral-400);stroke-width:1}
.fig .fx-arrow{fill:var(--color-neutral-400);stroke:none}
.fig .fx-dash {stroke-dasharray:5 4}
.fig .fx-hatch{stroke:var(--color-neutral-300);stroke-width:1}

/* bars and volumes */
.fig .fx-ghost      {fill:none;stroke:var(--color-neutral-400);stroke-width:1;stroke-dasharray:3 3}
.fig .fx-ghost-solid{fill:var(--color-neutral-200);stroke:var(--color-neutral-400);stroke-width:1}
.fig .fx-bar        {fill:var(--series-2-fill);stroke:var(--series-2);stroke-width:1}
.fig .fx-bar-solid  {fill:var(--series-2);stroke:none}
.fig .fx-bin        {fill:var(--series-2-fill);stroke:none}
.fig .fx-band       {fill:var(--wash-accent);stroke:none}
.fig .fx-vol-a      {fill:var(--series-4-fill);stroke:var(--series-4);stroke-width:1.25}
.fig .fx-vol-b      {fill:var(--series-8-fill);stroke:var(--series-8);stroke-width:1.25}
.fig .fx-ground     {stroke:var(--color-neutral-400);stroke-width:1}
.fig .fx-cut        {fill:none;stroke:var(--color-neutral-700);stroke-width:1.75}
.fig .fx-conc       {fill:var(--color-neutral-300);stroke:var(--color-neutral-600);stroke-width:1}

/* the girth family: the reference line in ink, the outward and inward bands in
   two series colours so "out" and "in" are told apart without a legend */
.fig .fx-p1      {fill:none;stroke:var(--color-text);stroke-width:2}
.fig .fx-band-out{fill:none;stroke:var(--series-3);stroke-width:1.25;stroke-dasharray:6 3}
.fig .fx-band-in {fill:none;stroke:var(--series-1);stroke-width:1.25;stroke-dasharray:6 3}
.fig .fx-move    {fill:none;stroke:var(--color-accent-600);stroke-width:2.5}
.fig .fx-allow   {fill:none;stroke:var(--color-accent-2-700);stroke-width:2}
.fig .fx-key-obs {fill:var(--series-2-fill);stroke:var(--series-2);stroke-width:1}
.fig .fx-key-exc {fill:var(--st-critical-tint);stroke:var(--st-critical-ink);stroke-width:1}

/* STATUS INKS LAST, so a text that is both .fval and .fx-critf takes the
   status. Equal specificity — source order is the whole mechanism. */
.fig .fx-crit {fill:none;stroke:var(--st-critical-ink);stroke-width:1.5}
.fig .fx-acc  {fill:none;stroke:var(--color-accent-600);stroke-width:1.5}
.fig .fx-hit  {fill:var(--st-critical-tint);stroke:var(--st-critical-ink);stroke-width:1.25}
.fig .fx-exc  {fill:var(--st-critical-tint);stroke:var(--st-critical-ink);stroke-width:1}
.fig .fx-critf{fill:var(--st-critical-ink)}
.fig .fx-accf {fill:var(--color-accent-600)}
.fig .fx-hitf {fill:var(--st-critical-ink)}
.fig .fx-excf {fill:var(--st-critical-ink)}

/* A dimensioned drawing is dense on purpose. Below about 620 px it STOPS
   scaling down — an 11 px label at 58 % is 6.4 px and nobody reads it — and
   scrolls sideways inside .fig instead, which already carries overflow-x:auto.
   The page body never scrolls horizontally; the figure does. */
@media (max-width:620px){ .fig svg{min-width:560px} }

/* ---- 11. responsive ------------------------------------------------------ */
/* Below this width the canvas stops being a layer and becomes a block under the
   headline. hero.js reads the same 860 px off its own bounding box and stops
   painting the text scrim, because there is no longer any text over it. */
@media (max-width:860px){
  .hero4d{display:block;min-height:0}
  .hero4d .heroInner{padding-bottom:var(--sp-5)}
  .heroCanvas{position:relative;inset:auto;height:clamp(240px,42vw,330px);z-index:1}
  .heroHud{position:relative;right:auto;bottom:auto;width:auto;
    margin:var(--sp-4) var(--sp-4) var(--sp-5)}
}

@media (max-width:720px){
  .hero h1{font-size:32px}
  .subhero h1{font-size:28px}
  .hero .lede,.subhero .lede{font-size:16px}
  .prose h2{font-size:22px}
  .facts .frow{grid-template-columns:minmax(0,1fr);gap:var(--sp-1)}
  .mnav nav{justify-content:flex-start}
  /* TAP TARGETS. WCAG 2.2 SC 2.5.8 (Target Size, Minimum) puts the floor at
     24x24 CSS px, and measured at a 375px viewport these were under it: the
     pillar-card headings at 22 px. Footer links use the same target rule at
     every width in section 9 above; target size is not a phone-only need.
     tools/siteperf.py prints every target it finds below the line, which is
     how these were found rather than guessed at. The padding is vertical
     only — widening a block link would not change the hit area, and the
     inline-block is what makes a min-height apply to an anchor at all.
     Body-copy links inside a sentence are deliberately NOT touched: 2.5.8
     exempts them, and padding a link mid-paragraph breaks the line box. */
  .pcard h3 a,.crumb a{display:inline-block;min-height:24px;
    padding-top:4px;padding-bottom:4px}
  .faq summary{min-height:24px;padding:4px 0}
}

/* ---- 12. print ----------------------------------------------------------- */
/* mc-ui.css § 22 already owns page geometry, table headers and break control.
   The only thing a marketing page adds is dropping its own navigation, which
   is a screen affordance and nothing else. */
@media print{
  .mnav,.mfoot{display:none!important}
  .hero{background:none;border-bottom:1px solid var(--color-neutral-300)}
  /* The canvas is a screen affordance and prints as a grey slab on most
     drivers; the HUD is a readout of a scene that is no longer there. Both go,
     and .hero4d gives up its min-height so the headline does not print alone at
     the top of a two-thirds-empty page. The caption under it STAYS — it is the
     line that says what the scene was and, when the scheduler did not load,
     that it was not computed. That is a correctness notice, and CLAUDE.md's
     exemption for those is not a screen-only exemption. */
  .heroCanvas,.heroHud{display:none!important}
  .hero4d{min-height:0;display:block}
}
