/* AIREI — HOME page rules only. Everything global lives in tokens/base/shell.
   Nothing here re-implements a base class; these are the four compositions the
   home page needs that no other page does (hero, chain, machines, credential
   wall, founder band, close lane) plus one documented contrast correction. */

/* ─────────────────────────────────────────────────────────────────────────
   CONTRAST — WITHDRAWN OVERRIDE, kept as a record rather than deleted.
   This page shipped a page-scoped `:root{--ink-ghost:#808F9F}` because the
   original shared token #4A5A6C measured 2.60:1 on Deep Water — far below the
   4.5:1 floor for the 10.5-11px mono it carries (telemetry strip, stat source
   lines, language switch, whole footer). While this page was in build, tokens.css
   was raised repo-wide to --ink-ghost:#7E99B7 / --ink-subtle:#8899AA, which is
   strictly better than the local override on every ground we use:
       ground        #4A5A6C   #808F9F(ours)   #7E99B7(token)
       deep-water     2.60        5.56            6.24
       panel-navy     2.12        4.54            5.10
       mill-navy      2.00        4.27            4.79
   (WCAG 2.x relative luminance; the formula was sanity-checked at 21.00 for
   black-on-white and 1.00 for white-on-white before any of these were trusted.)
   The override is therefore REMOVED so index / smart-mill / ai-ffb-grading /
   proof all render the same footer from the one token. Do not re-add it.
   ───────────────────────────────────────────────────────────────────────── */

/* ── HERO — Operator Promise. The photograph is the grading rig's own
      segmentation output; the scrim exists so type clears contrast over it. ── */
/* .hero was display:grid. A grid ITEM with `margin:0 auto` (which .wrap carries, from
   base.css) does NOT stretch to the track — auto margins absorb the free space and the
   item shrink-wraps to max-content. Measured at 1440: the hero's .wrap came out 768px
   wide and centred at x=336, while every other section's .wrap was 1240px starting at
   x=164. So the hero was silently mis-aligned with the whole page, AND the copy column
   was pushed out to 72% of the viewport, past the scrim plateau that guarantees its
   contrast. Block layout restores both. Nothing here needed grid: min-height + padding
   already do the work `align-items:end` was doing. */
.hero{position:relative;isolation:isolate;border-top:0;padding:0;overflow:hidden;
  min-height:clamp(540px,84vh,840px);display:block}
.hero-media{position:absolute;inset:0;z-index:0}
/* THE FRAMING IS BREAKPOINT-DEPENDENT, because what the copy covers changes.
   The graded zones live at source x 448-930 of 1280.
   >=940px the hero is two-column: the copy holds the left ~640px under a .965 plateau,
   so the zones must land to its RIGHT — 0% does that (they render at 65-86% of frame).
   <940px the copy runs full width, so the zones must land BELOW it, and the horizontal
   window is only ~367 source px wide; 0% showed source x 0-367 there, which is roadside
   vegetation and a concrete wall — no graded load at all, under a stamp and a grading
   card that both point at "the graded zones over the load at the top of this page".
   55% centres that narrow window on the load. Measured both ways at both widths. */
/* The three graded zones are the SUBJECT. In the source they occupy x450-921 (centre
   53.5%) and y352-694 (centre 72.6%) of 1280x720. object-position must aim at that
   centroid, or `cover` crops the subject away and the hero shows the embankment and the
   access road instead. A previous revision used 0% above 940px, which anchors the LEFT
   edge and cut the right-hand zone at 940-1024. One position serves every width. */
/* 80% 40% chosen by A/B against 53%/68% (tuned for the OLD photograph), 50%/50% and
   100%/50%. The hero box is 1440x975 for a 16:9 drawing, so cover crops ~293px of width;
   80/40 keeps the roof trusses, the full press line and both tanks in frame while leaving
   the headline ground clear. Re-A/B this if the drawing is ever re-rendered. */
.hero-media img{width:100%;height:100%;object-fit:cover;object-position:80% 40%}
.hero-media::after{content:"";position:absolute;inset:0;background:
  /* HORIZONTAL SCRIM — SUPERSEDED, and left here only because the rest of this declaration
     still paints. The 100deg rule near the end of this file (search: SCRIM — LIGHTENED) is the
     one the browser computes for .hero-media::after; editing THESE stops changes nothing, which
     I proved by changing them and watching all twelve contrast measurements stay identical to
     two decimal places. If you are tuning the hero scrim, tune the later rule. */
  linear-gradient(to right,rgba(11,21,32,.90) 0%,rgba(11,21,32,.82) 44%,
    rgba(11,21,32,.30) 58%,rgba(11,21,32,.18) 76%,rgba(11,21,32,.16) 100%),
  linear-gradient(to bottom,rgba(11,21,32,.34) 0%,rgba(11,21,32,.10) 32%,
    rgba(11,21,32,.38) 100%)}

/* THE CONTRAST GUARANTEE — held where the GLYPHS are, not across half the photograph.
   The previous version was a .965 plateau, which is opaque for practical purposes. Measured
   against the bare photograph it hid 33.7% of the hero and, at the left third, 68% of every
   column — and what it hid was the dawn sun, the one thing in the frame worth looking at.

   So measure what each element actually needs instead of covering everything equally. Against
   the unaided photograph, white text scores (worst 10% of the area behind it):
       eyebrow 6.28:1   hud 4.86:1   stamp 17.15:1     -> need nothing
       sub     3.09:1                                   -> needs a little
       h1      1.59:1                                   -> needs real help, and it sits ON the sun

   Two mechanisms, each doing the job it is good at:
   1. A WHISPER of a scrim — .16, not .965 — feathered on both axes.
      .62 was the first attempt and it was still wrong: measured against the bare photograph it
      returned only 12% of the warm pixels the slab had been hiding. Sweeping the value while
      measuring contrast at every step showed the shadow carries almost all the work on its own
      (at a scrim of ZERO the headline still measures 6.0:1 against a 3.0 requirement), so the
      scrim can fall to a level that tints rather than covers. At .16 every element clears its
      threshold and 2.7x more of the photograph survives than at .62.
   2. A text-shadow on the display line, which lifts contrast AT the letterforms and nowhere
      else — the operator's own suggestion, and the correct tool for a 100px headline.

   The composited result is measured from PIXELS in qa/hero-contrast.py, not from the CSS
   background colour: a text-shadow is invisible to a computed-style check, so a checker that
   reads background-color alone would report this as a regression when it is an improvement. */
.hero-copy,.hero-stamp{position:relative}
.hero-copy::before,.hero-stamp::before{content:"";position:absolute;z-index:-1;
  left:-60vw;right:-180px;top:-84px;bottom:-44px;pointer-events:none;
  background:linear-gradient(to right,rgba(11,21,32,.16) 0,
    rgba(11,21,32,.16) calc(100% - 300px),rgba(11,21,32,0) 100%);
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 14%,#000 84%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 14%,#000 84%,transparent 100%)}
/* The shadow does the close work. Three stacked blurs: a tight one for edge definition and
   two wide soft ones that darken the immediate ground without drawing a visible halo. */
.hero-copy h1{text-shadow:0 1px 2px rgba(11,21,32,.85), 0 2px 14px rgba(11,21,32,.75),
                          0 4px 34px rgba(11,21,32,.55)}
.hero-copy .sub{text-shadow:0 1px 2px rgba(11,21,32,.9), 0 2px 12px rgba(11,21,32,.7)}
/* The eyebrow is the tightest element in the whole hero — at a .16 scrim it measured 4.7:1
   against a 4.5 requirement, which is 4% of headroom and not enough to survive a viewport
   this check does not sample. Two extra stops give it the same margin the others have. */
/* The eyebrow is small mono on the brightest part of the sky and is the only element in the
   hero without margin — at 1100px it measured 4.54:1 against a 4.5 requirement, one percent of
   headroom. The answer is a denser shadow on that element, not a darker photograph: darkening
   the frame to rescue one line of 12px type is what produced the slab this whole change removes. */
.hero-copy .eyebrow,.hero-stamp{text-shadow:0 1px 1px rgba(11,21,32,1),
  0 0 4px rgba(11,21,32,.98), 0 1px 10px rgba(11,21,32,.92),
  0 2px 22px rgba(11,21,32,.7)}

/* ── THE READOUT PLATE ─────────────────────────────────────────────────────────
   Added 2026-08-27. Measured from PIXELS with qa/hero-contrast.py's own method, on
   index.html: the amber eyebrow read 1.68:1 at 390px and 4.47:1 at 1100px, and the HUD
   values read 1.98:1 against the median sky. Both fail AA, and both fail for the same
   reason the shadow stack above cannot fix: they are SMALL MONO SITTING ON THE SUNSET.
   Amber ink on an amber sky and pale blue on the same are not a shadow problem — a
   shadow darkens a rim at the letterform while the ground the eye actually reads
   against stays the bright sky, which is why h1 and .sub clear 7.5-11.8:1 with the same
   treatment and these two do not.

   A readout needs a substrate, and a substrate is also what it IS: the label of one
   instrument and its values. So they take one plate. Flat tint, never a blur —
   glassmorphism is a named ban, and a blur would cost the photograph the sharpness the
   whole hero is built on. The plate is bounded to the readout so the .16 scrim decision
   above (2.7x more photograph than at .62) still stands everywhere else.
   ──────────────────────────────────────────────────────────────────────────── */
.hero .hero-copy > .eyebrow,
.hero .hero-copy > .fxh-hud{
  --plate-pad:clamp(13px,1.5vw,18px);
  background:rgba(9,17,26,.86);
  padding-left:var(--plate-pad);padding-right:var(--plate-pad);
  margin-left:calc(-1 * var(--plate-pad));
  /* ONE rectangle, not two. Both halves take the same width at every viewport, so the
     plate has a single right edge: at 1440 that is 30em of 13px mono (390px), which is
     the eyebrow's own single-line measure with ~45px to spare, and below ~430px it
     collapses to 100% of the copy column and the two halves stay flush. If the eyebrow
     is ever rewritten longer it wraps to two lines inside the plate, which is what it
     already does on a phone — it never breaks the rectangle. */
  width:min(100%,33em);max-width:min(100%,33em)}
.hero .hero-copy > .eyebrow{padding-top:11px;padding-bottom:9px;margin-bottom:0}
.hero .hero-copy > .fxh-hud{padding-top:4px;padding-bottom:11px}
/* The plate supplies the ground; the shadow stack that was doing the whole job alone is
   now redundant on the eyebrow and would only muddy 13px mono against a flat tint. */
.hero .hero-copy > .eyebrow{text-shadow:none}
.hero-stamp::before{top:-18px;bottom:-18px}
@media (max-width:940px){
  /* Below the two-column threshold the copy runs full width. The .965 contrast
     plateau now rides on .hero-copy/.hero-stamp themselves, so this layer only has
     to set tone — a flat .93 on top of that plateau would black the photograph out
     entirely. Measured after this change: eyebrow 6.09, sub 8.83, stamp 5.27 at 390px. */
  .hero-media::after{background:
    linear-gradient(to bottom,rgba(11,21,32,.62) 0%,rgba(11,21,32,.42) 34%,
      rgba(11,21,32,.58) 100%)}
}
.hero>.wrap{position:relative;z-index:1;
  padding-top:clamp(84px,14vw,164px);padding-bottom:clamp(52px,7vw,96px)}
.hero-copy{max-width:min(640px,46vw)}
@media (max-width:940px){.hero-copy{max-width:none}}
.hero h1{margin:22px 0 0;font-size:clamp(44px,7.6vw,104px);letter-spacing:-0.0119em;
  max-width:11ch}
.hero .sub{margin:26px 0 0;max-width:52ch;font-size:clamp(17px,1.5vw,20px);
  color:var(--ink-muted);line-height:1.5}
.hero .sub b{color:var(--ink);font-weight:600}
.hero-ctas{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(30px,3.4vw,44px)}
/* THE STAMP CARRIES A LINK NOW — the frame above it is the grading rig's own output,
   and the page that reads it out (coordinates, file, the withheld figures) is one click
   away. At 10.5px, uppercase, inside a dense mono run, a colour change alone is not a
   findable affordance: the rule under it is what makes it read as a link. AIREI Blue is
   correct here and only here — DESIGN.md §3 reserves it for "interactive only", and this
   is the one interactive thing in the stamp. #3A93D6 on the .965 plateau computes 5.30:1
   at 10.5px, over the 4.5 floor. */
.hero-stamp a{color:var(--airei-blue-lift);
  border-bottom:1px solid rgba(58,147,214,.5)}
@media (hover:hover) and (pointer:fine){
  .hero-stamp a:hover{color:var(--signal-gold);border-bottom-color:var(--signal-gold)}}

/* Sentence case per .sec-note above. This is the Star citation, and the masthead is the
   reason the line exists: uppercase turned "The Star, 19 Nov 2024" into a shout and made
   the quotation marks around the claim do all the work of separating quote from source.
   Re-measured after the change with qa/hero-contrast.py, which reads this element from
   PIXELS because it sits on the photograph. */
.hero-stamp{position:relative;z-index:1;margin-top:clamp(34px,5vw,64px);
  padding-top:12px;border-top:1px solid var(--hairline);
  font-family:var(--f-mono);font-size:12.5px;letter-spacing:.02em;
  color:var(--ink-ghost);max-width:74ch}

/* ── THE CHAIN — six positions, then the platform band ── */
/* Was a repeat(2/3/6) equal-column grid -- flagged as the named AI-tell
   `three-col-cards` at the 660-1080px step, and worth killing outright rather than
   just moving the breakpoint: this content is a SEQUENCE (nursery -> plantation ->
   dealer -> mill -> refinery -> kernel crushing), and a card wall of equal boxes
   argues nothing about order. Replaced 2026-08-23 with a connected register --
   one continuous rule, each position a row threaded by a single vertical line
   through its own ord tick, station numbers as ties on a rail rather than tiles
   in a wall. No new interaction pattern (no scroll, no snap) and no grid at any
   width, so there is no column count left to divide six by.
   DOM is unchanged (still bare <span class=ord>, <svg>, <h3>, <p> siblings, no
   wrapper) -- CSS Grid places each by line number instead of relying on source
   order, which is what makes a single-row-per-station layout possible without
   touching markup. The vertical rail is a per-row ::before the width of a hairline;
   consecutive rows sharing the same left offset and zero row-to-row gap is what
   makes it read as one continuous line rather than six short dashes. */
.chain{position:relative;margin-top:clamp(34px,4vw,56px);border-top:1px solid var(--hairline)}
.chain .pos{position:relative;display:grid;
  grid-template-columns:34px 22px 1fr;grid-template-rows:auto auto;
  align-items:center;column-gap:12px;row-gap:10px;
  padding:20px 2px;border-bottom:1px solid var(--hairline)}
.chain .pos::before{content:"";position:absolute;top:0;bottom:0;left:19px;width:1px;
  background:var(--hairline-strong)}
.chain .pos .ord{position:relative;z-index:1;grid-column:1;grid-row:1;min-width:0;
  display:flex;align-items:center;justify-content:center;width:34px;height:22px;
  background:var(--deep-water);border:1px solid var(--hairline-strong);
  font-family:var(--f-mono);font-size:12px;letter-spacing:.1em;color:var(--crude-amber)}
.chain .pos svg{grid-column:2;grid-row:1;color:var(--crude-amber);width:20px;height:20px}
.chain .pos h3{grid-column:3;grid-row:1;margin:0;min-width:0;font-size:18px;
  letter-spacing:-0.0051em;overflow-wrap:anywhere}
.chain .pos p{grid-column:1/-1;grid-row:2;margin:0;min-width:0;font-size:14px;
  line-height:1.5;color:var(--ink-muted)}
@media (min-width:660px){
  /* One row per station: ord / icon / title-column / description-column, all four
     siblings on grid-row:1 -- the register reads left to right like a spec sheet,
     the opposite silhouette of the equal-width tiles it replaces. */
  .chain .pos{grid-template-columns:40px 28px minmax(180px,240px) 1fr;
    grid-template-rows:auto;column-gap:22px;padding:24px 6px}
  .chain .pos::before{left:26px}
  .chain .pos .ord{width:40px;height:24px;font-size:12.5px;letter-spacing:.14em}
  .chain .pos h3{font-size:19px}
  .chain .pos p{grid-column:4;grid-row:1;max-width:50ch}
}
@media (min-width:1080px){
  /* Left-anchored rather than stretched full `--wrap` width -- the open ground to
     the right is the same asymmetric-composition move the 60/40 machines section
     already makes (see .two below), not empty space left over by accident. */
  .chain{max-width:920px}
}
.chain-band{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 20px;
  margin-top:clamp(28px,3.4vw,44px);padding:26px 0 0;border-top:1px solid var(--hairline-strong)}
.chain-band .k{font-family:var(--f-mono);font-size:13px;font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-subtle)}
.chain-band .p{font-family:var(--f-display);font-size:clamp(34px,4.6vw,58px);
  line-height:1;letter-spacing:-0.0102em;color:var(--signal-gold)}
.chain-band .n{font-size:15px;color:var(--ink-muted);max-width:46ch}

/* ── THE TWO MACHINES — asymmetric 60/40 on purpose. Not equal cards. ── */
.machines{display:grid;gap:clamp(30px,3.4vw,48px);grid-template-columns:1fr;
  margin-top:clamp(34px,4vw,56px)}
@media (min-width:940px){.machines{grid-template-columns:1.52fr 1fr;align-items:start}}
.machine figure{margin:0;border:1px solid var(--hairline);background:var(--panel-navy)}
.machine figure img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
/* THE COLUMNS ARE UNEQUAL ON PURPOSE; THE HEADINGS WERE NOT. With 16/9 on both images the
   wider column produced a taller picture, so the two h3s — "AI Smart Mill" and "Unmanned AI
   FFB Grading", presented as the two products — landed 124px out of register (measured at
   1440) and the right column ran out early, leaving a hole under its CTA. Two reviewers
   independently read that as the layout breaking rather than as hierarchy, which means the
   hierarchy was not reading. Locking the picture HEIGHT instead of the ratio keeps the 60/40
   width statement and puts both headings on one line. */
@media (min-width:940px){.machine figure img{aspect-ratio:auto;height:clamp(230px,22vw,320px)}}
.machine h3{margin:22px 0 0;font-size:clamp(27px,3vw,40px)}
.machine .lede{margin:14px 0 0;color:var(--ink-muted);max-width:56ch}
.machine .note{margin:16px 0 0;padding-top:14px;border-top:1px solid var(--hairline);
  font-family:var(--f-mono);font-size:13px;line-height:1.65;letter-spacing:.04em;
  color:var(--ink-subtle);max-width:56ch}
.stations{list-style:none;margin:20px 0 0;padding:0;display:grid;gap:1px;
  background:var(--hairline);border-top:1px solid var(--hairline);
  border-bottom:1px solid var(--hairline);grid-template-columns:repeat(auto-fit,minmax(184px,1fr))}
.stations li{background:var(--deep-water);padding:11px 2px;font-family:var(--f-mono);
  font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-muted);
  display:flex;gap:10px;min-width:0}
.stations li b{color:var(--crude-amber);font-weight:600;flex:none}
.machine .go{display:inline-flex;gap:9px;margin-top:20px;font-family:var(--f-mono);
  font-size:13px;letter-spacing:.09em;text-transform:uppercase}

/* ── CREDENTIAL WALL — categorised rows on paper. Named, not a grey logo strip. ── */
.creds{margin:clamp(30px,3.4vw,48px) 0 0;display:block}
.creds .row{display:grid;gap:6px 30px;padding:22px 0;border-top:1px solid rgba(22,32,43,.16)}
.creds .row:last-child{border-bottom:1px solid rgba(22,32,43,.16)}
@media (min-width:760px){.creds .row{grid-template-columns:236px 1fr;align-items:baseline}}
.creds dt{font-family:var(--f-mono);font-size:13px;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:#8A5E14}
.creds dd{margin:0;font-size:clamp(17px,1.6vw,21px);line-height:1.45;color:#16202B}
.creds .sep{color:#8A5E14;padding:0 10px}
.creds dd small{display:block;margin-top:8px;font-family:var(--f-mono);font-size:13px;
  letter-spacing:.05em;line-height:1.6;color:#4C5A66;text-transform:none}

/* ── FOUNDER BAND ── */
.founder{display:grid;gap:clamp(28px,3.6vw,60px);grid-template-columns:1fr;align-items:center}
@media (min-width:860px){.founder{grid-template-columns:.82fr 1.18fr}}
.founder .shot{border:1px solid var(--hairline)}
.founder img{width:100%;height:auto}
.founder blockquote{margin:20px 0 0;font-family:var(--f-display);font-weight:400;
  font-size:clamp(25px,3.1vw,42px);line-height:1.16;letter-spacing:-0.0085em;color:var(--ink)}
.founder cite{display:block;margin-top:18px;font-style:normal;font-family:var(--f-mono);
  font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-subtle)}
.founder .links{display:flex;flex-wrap:wrap;gap:10px 26px;margin-top:26px;
  font-family:var(--f-mono);font-size:13px;letter-spacing:.08em;text-transform:uppercase}
/* The founder block's outbound links measured 141x21 at 390px CSS px (is_mobile +
   has_touch, 2026-08-26) — under the 24px WCAG 2.5.8 AA floor. They are flex items in a
   wrapping row, so height comes from the line box alone; a min-height gives them the
   floor without touching the 10px/26px gap rhythm the row is set on. Coarse pointers
   only, per shell.css:332. */
@media (pointer:coarse){
  .founder .links a{min-height:44px;display:inline-flex;align-items:center}
}

/* ── CLOSE — dual lane. SEA: WhatsApp is a real channel, not a widget. ── */
.lanes{display:grid;gap:1px;background:var(--hairline);border:1px solid var(--hairline);
  grid-template-columns:1fr;margin-top:clamp(30px,3.4vw,48px)}
@media (min-width:820px){.lanes{grid-template-columns:1fr 1fr}}
.lane{background:var(--panel-navy);padding:clamp(26px,3vw,42px)}
.lane .k{font-family:var(--f-mono);font-size:12.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--crude-amber)}
.lane h3{margin:14px 0 0;font-size:clamp(24px,2.4vw,32px)}
.lane p{margin:12px 0 0;font-size:15.5px;color:var(--ink-muted);max-width:40ch}
.lane .btn{margin-top:24px}
/* max-width added 2026-08-27. `.trust` had none, so it took the full 1112px column:
   142.6ch measured at 1280/1440/1920 (the widest prose block on the site), which at 13px
   mono with .06em tracking is 130 characters to a line, set at line-height 1.9 — the
   worst possible combination for finding the next line. 620px is the same cap the mono
   note voice uses below and in proof.css: 79.5ch, 72 real characters here.
   .06em -> .05em: that fix took the WIDTH into the mono note voice and left the tracking
   behind, leaving .trust the only member still at .06em while its sibling
   `.creds .fold-body p` (same 13px mono, same cap) sits at .05em with its measure computed
   FOR .05em. Following the sibling beats inventing a third number. 99 characters of running
   prose here at 1440, measured — a paragraph, not a label. */
.trust{margin-top:clamp(26px,3vw,40px);padding-top:20px;max-width:620px;
  border-top:1px solid var(--hairline);font-family:var(--f-mono);font-size:13px;
  line-height:1.9;letter-spacing:.05em;color:var(--ink-ghost)}
.trust b{color:var(--ink-subtle);font-weight:500}

/* ── shared small pieces ── */
.lede-2{max-width:var(--measure);color:var(--ink-muted);font-size:clamp(17px,1.5vw,19.5px);
  margin-top:20px}
h2.big{font-size:clamp(34px,4.8vw,64px);max-width:18ch;margin-top:20px}
/* max-width added 2026-08-27, and the reason generalises. `.sec-note` inherited its width
   from `.fold-wide .fold-body{max-width:var(--measure)}` — but `--measure` is 66ch, and a
   ch is a property of the ELEMENT'S OWN font, so 66ch resolved against the 17px body face
   (686px) and was then handed to a 13px mono child, where the same 686px is 87.4ch. A
   measure token set on a parent does not survive a font change in a child. Measured at
   1280/1440/1920: 87.4ch over 5 lines. 620px is the mono note cap: 79.5ch, 69 characters
   here at .09em. */
/* Sentence case per the note on .src-line in proof.css. The longest run on this class is
   316 characters (ms/index) and 263 (index) — a five-line paragraph of citation, in tracked
   uppercase mono, carrying the sources for four figures.
   The measure moves with the tracking: 620px of 13px mono holds ~69 characters at .09em and
   ~77 at .02em, which is past the 75ch cap, so the box comes in to 600px (~74ch). */
.sec-note{margin-top:16px;max-width:600px;font-family:var(--f-mono);font-size:13px;letter-spacing:.02em;
  line-height:1.7;color:var(--ink-ghost)}
.paper .sec-note{color:#4C5A66}

/* proof bar spacing. The `.eyebrow` wrap correction that used to sit here has MOVED to
   base.css, which is where `.eyebrow` is declared — it was fixing this page only while
   four wrapped eyebrows on smart-mill, demo and proof/minsawi kept the defect. */
.proof .statband{margin-top:clamp(38px,4.4vw,64px)}
.stat .u{margin-bottom:0}
.stat .src{margin-bottom:0}
.paper .lede-2{color:#3C4A57}

/* PROVENANCE BAND. index.html loads base + shell + home only, so .lede/.note/.measure
   (which live in proof.css) resolve to nothing here — the first draft of this section
   rendered its lede hard against the h2 with no gap and its note in the body face at
   lede size, i.e. the hierarchy upside down. Uses the home vocabulary instead and gives
   the mono note the same treatment .machine .note already has. */
.pictures-note{max-width:var(--measure)}
.pictures-note .lede-2{margin-top:20px}
.pictures-note .note{margin:26px 0 0;padding-top:16px;border-top:1px solid var(--hairline);
  font-family:var(--f-mono);font-size:13px;line-height:1.75;letter-spacing:.04em;
  color:var(--ink-subtle);max-width:640px}
.pictures-note .note b{color:var(--ink);font-weight:600}
.founder .fdr-h{font-size:clamp(28px,3.2vw,44px)}

/* ── SHELL CORRECTIONS — MOVED to shell.css § MASTHEAD FIT. ──
   The nowrap rule and the 901-1359 lockup tightening lived here, and byte-identically
   in smart-mill.css and proof.css. Three copies of one rule is exactly how demo.html
   and privacy.html ended up with none. The measured numbers travelled with the rule;
   they are in shell.css now. Nothing about the masthead is decided in this file. */

/* S6 — eight stations in a 3-up grid left an EMPTY ninth cell, which rendered as a
   pale hairline-coloured box. Two columns divides 8 evenly at every width this
   column ever reaches (max ~640px inside the 60% lane, so auto-fit never returns 3). */
/* EIGHT stations, so 1, 2, 4 or 8 columns only. auto-fit returned THREE at exactly
   900px — below the 940px machines breakpoint the card runs full width (810px of
   content), which fits 3x240 and leaves one empty cell. The earlier reasoning that
   this column never exceeds 640px was only true ABOVE 940. Pinned. */
.stations{grid-template-columns:repeat(1,minmax(0,1fr))}
@media (min-width:520px){.stations{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* S7/S10 — photographic grade, DESIGN.md §6. Both machine frames and the founder
   still carry a blown white sky / grey wall; §6 states plainly that "a white
   mid-morning sky destroys this palette". Sink the top of the frame toward Deep
   Water and pull saturation back under the 38% green cap rather than shipping the
   raw frame. This is a treatment, not a fabrication — nothing is added or removed. */
.machine figure{position:relative}
.machine figure img,.founder img{filter:saturate(.86) contrast(1.06) brightness(.95)}
/* The hero asset is already finished in the FILE, so nothing here has to correct it.
   An earlier revision blurred the whole hero 2.4px, which also hid the graded zones —
   the only reason this photograph is on the page. No blur. */
.hero-media img{filter:saturate(.94) contrast(1.02)}
.machine figure::after{content:"";position:absolute;inset:0;pointer-events:none;background:
  linear-gradient(to bottom,rgba(11,21,32,.60) 0%,rgba(11,21,32,.08) 46%,rgba(11,21,32,.34) 100%)}
.founder .shot{position:relative;display:block}
.founder .shot::after{content:"";position:absolute;inset:0;pointer-events:none;background:
  linear-gradient(to bottom,rgba(11,21,32,.34) 0%,rgba(11,21,32,.06) 40%,rgba(11,21,32,.30) 100%)}

/* S5b — at 68px the widest stat value ("+1.17 pp") measured 238px against a 238px
   column, so any wider glyph run wrapped the gold unit onto a second line. Capped
   to 60px, which leaves ~28px of slack on the widest of the four. */
.proof .stat .v{font-size:clamp(36px,4.6vw,60px)}

/* ── OVERFLOW FIX — CREDENTIAL WALL. ──
   The name spans were written with no whitespace between them, so min-content for that
   grid column was one unbreakable 484px run — overflowing at 390 AND at 768. Real
   spaces now sit between the spans; .sep padding drops to match, and min-width:0 stops
   any future long token doing the same thing.

   The <=900px HEADER half of this fix has MOVED to shell.css § MASTHEAD FIT — it was a
   shell defect described in three page files and fixed in none of the shared ones. */
.creds .row > *{min-width:0}
.creds dd{overflow-wrap:break-word}
.creds .sep{padding:0 2px}

/* ── SKIP LINK + ANCHOR LANDING — MOVED to shell.css. ──
   The --hdr breakpoint ladder, `[id]{scroll-margin-top}` and the `main[tabindex="-1"]`
   outline suppression are shell concerns: every page has a sticky header, every page
   has anchor targets, every page has a skip link. They now live once, in shell.css
   § STICKY-HEADER HEIGHT / ANCHOR LANDING / SKIP LINK TARGET, with the measurements. */


/* FOUR stats: 1, 2 or 4 columns, never 3 (which strands one on its own row). */
.proof .statband{grid-template-columns:repeat(1,minmax(0,1fr))}
@media (min-width:600px){.proof .statband{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1120px){.proof .statband{grid-template-columns:repeat(4,minmax(0,1fr))}}

/* The footer-column orphan fix has MOVED to shell.css § FOOTER COLUMNS. `footer .cols`
   is declared in shell.css, so its breakpoint correction belongs beside it — not in
   three page files, one of which (demo/privacy) never got a copy. */

/* ═══ FOUNDER BAND — FOLD + LINEAGE ═══════════════════════════════════════════
   Owned by section.founderband#founder. Everything here is namespaced under
   .founderband on purpose: this file is being appended to by more than one lane
   at once, and an unscoped `details{}` or `summary{}` rule would reach into
   sections this lane does not own.

   The band read 55 visible words and gave 567px of height to a 604px photograph
   with ~180px of dead navy under it — the type, not the picture, was the centre
   of gravity, and two Fraunces blocks (h2 + blockquote) at near-identical size
   competed instead of ranking. Fixed by making the photograph a large PORTRAIT
   and cutting the type down to one claim plus its structure.

   PORTRAIT FROM A 16:9 SOURCE. founder.jpg is 1600x900; the crop is done in CSS
   with aspect-ratio + object-fit:cover, so the intrinsic width/height attributes
   on the <img> still describe the file on disk and qa/img-descriptor.py keeps
   reading true. object-position sits left of centre because he is left of centre
   in the frame — a centred crop cut the projected AIREI slide in half and pushed
   him toward the edge. Verified by screenshot at 1440 and 390, not by arithmetic. */
.founderband .founder{align-items:center}
/* Centred while the fold is CLOSED — closed, the type column runs a little taller
   than the square and centring balances the two. OPEN, the type column triples and
   a centred photograph drifts to the middle of a 1568px row with dead navy above
   and below it, which is what the screenshot showed. :has() switches the row to
   top-alignment for exactly that state; an engine without :has() keeps the centred
   rule, which is the current behaviour, so nothing regresses. */
.founderband .founder:has(.fold[open]){align-items:start}
@media (min-width:860px){.founderband .founder{grid-template-columns:.95fr 1.05fr}}
.founderband .founder .shot{aspect-ratio:1/1;overflow:hidden}
.founderband .founder img{width:100%;height:100%;object-fit:cover;object-position:46% 50%}

/* WHY 1:1 AND NOT A TALLER PORTRAIT. A 4:5 box out of a 16:9 source crops
   HORIZONTALLY ONLY — the full 900px of height is shown at every ratio narrower
   than the source, so a taller box removes no sky and adds no subject. What it
   removes is the dark ballast: at 4:5 both chair backs and the shadowed table ends
   leave the frame, the near-white projection screen becomes 52% of a large panel,
   and the band reads as a lightbox on a Deep Water page — the failure DESIGN.md §6
   names when it says a blown white field destroys this palette. Shot both and
   looked: 1:1 keeps the chairs, keeps the whole two-handed gesture the photographer
   framed, and still carries far more vertical presence than the 16:9 strip it
   replaces. The ratio is the same at every width, so there is one behaviour to
   reason about instead of two. */

/* Grade, scoped. The shared .machine/.founder filter above is tuned for the two
   machine frames; this crop lifts the screen's share of the frame, so it needs more
   highlight restraint than they do. Same treatment class DESIGN.md §6 sanctions —
   nothing added, nothing removed, the highlights sunk toward the ground. */
.founderband .founder img{filter:saturate(.84) contrast(1.10) brightness(.86)}
.founderband .founder .shot::after{background:
  linear-gradient(to bottom,rgba(11,21,32,.46) 0%,rgba(11,21,32,.06) 44%,rgba(11,21,32,.38) 100%)}

/* ── LINEAGE RAIL ──
   Not decoration: the headline states a count, this states who, in order, and
   terminates on the generation in the photograph. Fixed viewBox, so it cannot
   wrap, cannot overflow and reads identically at 320px and 1920px. Colours are
   existing tokens only — every fill here is a value already proven AA on
   --deep-water elsewhere on this page. Node 03 is Crude Amber (accent metal,
   DESIGN.md §3 "<=10%") because it is the one rung that is present tense. */
.founderband .lineage{display:block;width:100%;max-width:392px;height:auto;
  margin:clamp(26px,3vw,38px) 0 0}
.founderband .lineage .ln-rail{stroke:var(--hairline-strong);stroke-width:1}
.founderband .lineage .ln-node{fill:none;stroke:var(--ink-ghost);stroke-width:1.5}
.founderband .lineage .ln-now{fill:var(--crude-amber);stroke:var(--crude-amber)}
.founderband .lineage text{font-family:var(--f-mono);font-weight:500}
.founderband .lineage .ln-num{font-size:13px;letter-spacing:.06em;fill:var(--ink-ghost)}
.founderband .lineage .ln-lab{font-size:15px;letter-spacing:.16em;fill:var(--ink-muted)}
.founderband .lineage .ln-num-now{fill:var(--crude-amber)}
.founderband .lineage .ln-lab-now{fill:var(--ink)}

/* ── THE FOLD — DELIBERATELY NOT RE-DECLARED ──
   This lane originally shipped its own `.founderband .fold` + summary + marker
   rules. They are GONE, and their absence is the point. By the time this section
   landed, the chain lane had declared the house `.fold` (mono uppercase summary on
   a hairline, amber "+" that becomes "–", no chevron rotation, no max-height
   transition) and thirteen summaries across four sections were already using it.
   A scoped copy here rendered at 12px/.1em/--ink-muted against the house
   11.5px/.2em/600/--ink-subtle — measured with getComputedStyle across every
   summary on the page, which is how the divergence was caught — so this lane was
   quietly running a FOURTEENTH fold design that looked almost, but not quite, like
   the other thirteen.

   The proof lane wrote the rule this now follows: two unscoped `.fold{}` blocks in
   one file is how a later append silently restyles an earlier section, so a lane
   inherits the house fold and overrides ONLY what is wrong at its own size. Nothing
   is wrong at this size — 11.5px/.2em reads correctly in a 620px column — so there
   is nothing to override, and a future change to the house fold now reaches this
   section for free instead of leaving it behind.

   What stays below is only what belongs to THIS panel and nobody else declares:
   its measure, and the three content classes inside it. */
.founderband .fold-body{max-width:58ch}
/* Sentence case per .sec-note above. */
.founderband .fold-src{margin:22px 0 0;font-family:var(--f-mono);font-size:13px;
  line-height:1.7;letter-spacing:.02em;color:var(--ink-subtle)}
.founderband .fold-body > .fold-src:first-child{margin-top:14px}
.founderband .fold-q{margin:10px 0 0;padding-left:18px;
  border-left:1px solid var(--hairline-strong);
  font-family:var(--f-body);font-weight:400;font-size:15.5px;line-height:1.62;
  letter-spacing:0;color:var(--ink-muted)}
.founderband .fold-lim{margin:26px 0 0;padding-top:18px;
  border-top:1px solid var(--hairline);
  font-size:14.5px;line-height:1.68;color:var(--ink-subtle)}
.founderband .fold-lim b{color:var(--ink);font-weight:600}

/* THE STEAM TICKET, PROMOTED OUT OF THE FOLD, and the plain-English biography that
   replaced the magazine paragraph. Both are --ink-muted on --deep-water, the exact
   pairing .fold-q and .lineage .ln-lab already ship here, so no new colour pair
   enters the contrast surface. */
.founderband .fdr-ticket{margin:clamp(22px,2.6vw,30px) 0 0;max-width:var(--measure);
  color:var(--ink-muted);font-size:clamp(16px,1.35vw,18px);line-height:1.62}
.founderband .fdr-ticket b{color:var(--ink);font-weight:600}
.founderband .fold-t{margin:12px 0 0;font-size:15.5px;line-height:1.62;color:var(--ink-muted)}

/* Print: a folded panel on paper is a panel nobody can open. Force every fold
   open and drop the marker, matching how @media print already neutralises .rev. */
@media print{
  /* A closed <details> hides its children through the UA's details-content slot,
     not through a `display` on the child — so `display:block` on .fold-body alone
     reveals nothing. ::details-content is the one property that reaches it. Where
     the engine has no ::details-content the rule is simply ignored and the panel
     prints closed, which is no worse than it printed before this section existed. */
  .founderband .fold::details-content{content-visibility:visible;block-size:auto}
  .founderband .fold:not([open]) > .fold-body{display:block}
  .founderband .founder .shot{aspect-ratio:auto;overflow:visible}
  .founderband .founder img{height:auto;object-fit:contain}
}


/* ── THE CHAIN, FOLDED (2026-08-24) ──────────────────────────────────────────
   The section states ONE claim in the open — six positions, different businesses,
   one record — and draws it. The 150-word register that used to be the visible
   layer is not cut; it is folded into a native <details> below the drawing, where
   it keeps its own markup and the .chain rules above unchanged.

   TWO DRAWINGS, ONE DIAGRAM. A six-across rail is unreadable at 390px; a stacked
   one throws away the left-to-right sweep that IS the sequence. So there are two
   hand-authored SVGs and a width toggle, not one compromise. `display:none` (not
   visibility/clip) is deliberate: the hidden twin contributes nothing to
   document.body.innerText, so the page's visible word count is the same number at
   both widths rather than double-counting six station names.
   No transition and no @keyframes anywhere below — nothing here needs a
   prefers-reduced-motion counterpart because nothing here moves. */
.chainfig{margin:clamp(30px,4vw,52px) 0 0;padding:0;max-width:1120px}
.chainfig svg{display:block;width:100%;height:auto;overflow:visible}
.chainfig .cf-wide{display:none}
.chainfig .cf-tall{display:block;max-width:420px}
@media (min-width:760px){
  .chainfig .cf-wide{display:block}
  .chainfig .cf-tall{display:none}
}
/* Hairline rail + amber nodes: the same two-value vocabulary the .pos rows used,
   so the drawing and the folded register read as one object, not two designs. */
.cf-rail{fill:none;stroke:var(--hairline-strong);stroke-width:1}
.cf-tick{fill:none;stroke:var(--hairline);stroke-width:1}
.cf-brace{fill:none;stroke:var(--hairline-strong);stroke-width:1}
.cf-node{fill:var(--crude-amber)}
.cf-icon{fill:none;stroke:var(--crude-amber);stroke-width:1.5;
  stroke-linecap:butt;stroke-linejoin:miter}
.cf-tall .cf-icon{stroke-width:1.75}
.cf-ord{font-family:var(--f-mono);font-size:13px;letter-spacing:.14em;fill:var(--crude-amber)}
.cf-name{font-family:var(--f-mono);font-size:13px;letter-spacing:.1em;fill:var(--ink)}
.cf-plat{font-family:var(--f-display);font-size:34px;letter-spacing:-0.0102em;fill:var(--signal-gold)}
.cf-kick{font-family:var(--f-mono);font-size:13px;letter-spacing:.2em;fill:var(--ink-subtle)}

/* ── FOLD — native <details>, styled as a plant label, not a widget ──
   Mono all-caps summary on a hairline, amber +/- marker. NO chevron rotation and
   NO max-height transition: it opens or it does not. The marker swap is a content
   change, which costs nothing at reduced motion and cannot half-play. */
.fold{margin-top:clamp(26px,3.4vw,44px);
  border-top:1px solid var(--hairline-strong);border-bottom:1px solid var(--hairline)}
.fold > summary{display:flex;align-items:baseline;gap:12px;list-style:none;cursor:pointer;
  padding:16px 2px;font-family:var(--f-mono);font-size:13px;font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-subtle)}
.fold > summary::-webkit-details-marker{display:none}
.fold > summary::before{content:"+";font-family:var(--f-mono);font-size:15px;font-weight:600;
  line-height:1;color:var(--crude-amber);width:12px;flex:none}
.fold[open] > summary::before{content:"–"}
@media (hover:hover) and (pointer:fine){.fold > summary:hover{color:var(--ink)}}
.fold > summary:focus-visible{outline:2px solid var(--signal-gold);outline-offset:3px}
.fold-body{padding:2px 2px 30px}
/* Inside the fold the register loses its top rule — the summary's hairline is
   already the line above it, and two rules 16px apart read as a mistake. */
.fold-body .chain{margin-top:18px;border-top:0}
.fold-lede{margin:0;max-width:60ch;font-size:16px;line-height:1.6;color:var(--ink-muted)}
.fold-note{margin:22px 0 0;max-width:60ch;font-size:15px;line-height:1.6;color:var(--ink-muted)}

/* ══ PROOF BAND — RAILS, and the fold TUNED for a 239px stat column ══════════
   Owned by section.proof#proof. The band carried 425 visible words: a lede, four
   caveat paragraphs, four scope lines and a 120-word provenance note. NOTHING was
   cut — every sentence moved inside a native <details>, because this site's whole
   credibility is that it prints its own hedges, and deleting them would remove the
   only thing its competitors do not have.

   THE FOLD ITSELF IS THE HOUSE ONE (`.fold`, declared above by the chain lane) and
   is deliberately NOT re-declared here — two unscoped `.fold{}` blocks in one file
   is how a later append silently restyles an earlier section. Only the two things
   that are wrong AT THIS SIZE are overridden, both scoped under .proof: at 11.5px
   with .2em tracking a four-word summary wraps to two lines in a 239px column and
   the four folds stop aligning, and clamp(26px,3.4vw,44px) of top margin is a
   section-sized gap inside a stat.

   THE RAILS are geometry only. Every value a rail draws is ALSO set in HTML beside
   it, so the picture is never the only place a figure exists (DESIGN.md §5) and a
   reader whose AT skips the <svg role="img"> loses no number. Each rail is drawn
   against ITS OWN before-state — 150 user units = that figure's pre-retrofit
   baseline — which is what "a delta on that mill's own baseline" means in §7, and
   the tick at x=150 IS that baseline, so amber past the tick reads as an increase
   and amber short of it as a decrease with no axis to misread. A shared zero-based
   axis was tried first and is wrong here: OER moved 17.85 -> 19.02, which on a
   common scale is a bar indistinguishable from its own baseline next to a headcount
   bar that halves. preserveAspectRatio="none" is safe because nothing VERTICAL
   encodes anything — only bar length carries data, and length is horizontal.
   The payback rail is DASHED because the source bounds that payback inside a
   two-year window without measuring where in it it lands; a solid bar drawn to a
   point would invent the one number nobody has.
   ─────────────────────────────────────────────────────────────────────────── */
/* Sentence case per .sec-note above. `max-width:var(--measure)` and `line-height:1.8` were
   already the declarations of a paragraph; only the case still said label. */
.proof-src{margin-top:20px;max-width:var(--measure);font-family:var(--f-mono);font-size:13px;
  line-height:1.8;letter-spacing:.02em;color:var(--ink-ghost)}
/* THE ARROW MUST NOT BREAK OFF ON ITS OWN. Caught by looking at the phone render right after
   widening the proof band above: at 390 the credit now fits "All four // The Edge Malaysia,
   25 May 2026" on one line and put the "↗" alone on a second, under a stub of its own
   underline — a one-glyph orphan, and worse, a link whose affordance is separated from what
   it names. `nowrap` on the anchor makes the credit break BEFORE the link or not at all; at
   its widest the anchor is ~250px against 280px of content at a 320px viewport, so it never
   overflows. This is a break rule, not a measure rule — the paragraph still wraps. */
.proof-src a{white-space:nowrap}
/* THE TAP TARGET, not the look. Measured 2026-08-27 at 390px in Chrome: this credit wraps
   onto two lines, and `document.elementFromPoint` at the CENTRE of the anchor's box returns
   `P.proof-src` — the paragraph, not the link. Two things put dead space where a thumb aims:
   the anchor shares line 1 with "All four //", so its bounding box spans text it does not own;
   and line-height 1.8 on a 13px face leaves a ~10px gutter between the two line fragments that
   belongs to nobody. A reader who taps the middle of what LOOKS like the link gets nothing —
   which is what "the article is not opening" looks like from the other side of a phone.
   Vertical padding on an INLINE element extends the hit area without changing the line box, so
   each fragment grows .4em up and down, the two meet, and the gutter closes. Nothing reflows.
   The underline sits .4em lower as a result; that is the whole visual cost. */
.proof-src a{color:var(--ink-subtle);border-bottom:1px solid var(--hairline-strong);
  padding-block:.4em}

.rail{margin:16px 0 0}
.rail-fx{display:block;width:100%;height:22px}
.rl-track{fill:var(--mill-steel)}
.rl-bar{fill:var(--crude-amber)}
.rl-dash{stroke:var(--crude-amber);stroke-width:4;stroke-dasharray:7 5}
.rl-tick{stroke:var(--ink-ghost);stroke-width:1}
/* .08em -> .02em on the ROW, .08em kept on the FIGURES. One selector was serving two
   contents. Three of the four rails read "17.85 → 19.02" — digits, where .08em is doing
   real work separating numerals. The fourth reads "on RM4–5 million invested", a
   sentence-case phrase, and caps tracking on sentence case opens the letter gaps until
   they rival the word spaces: the line stops reading as a phrase and starts reading as a
   machine stamp, directly under a caps label ("REPORTED PAYBACK") that IS legitimately
   tracked at .2em. .02em is the house value for sentence-case mono — it is what
   `.src-line`, `.stat .src`, `.pband .src`, `news.css .src` and `.facts td.s` are all set
   to, and smart-mill.css records the same correction being made for the same reason. */
.rail-t{display:block;margin-top:9px;font-family:var(--f-mono);font-size:13px;
  letter-spacing:.02em;color:var(--ink-ghost)}
.rail-t b{letter-spacing:.08em;color:var(--ink-muted);font-weight:600}

/* The two size corrections, scoped. Nothing else about .fold is touched. */
.proof .stat .fold{margin-top:16px;border-top-color:var(--hairline)}
.proof .stat .fold > summary{padding:13px 2px;font-size:12.5px;letter-spacing:.14em;
  font-weight:500;gap:10px}
.proof .stat .fold > summary::before{font-size:13px;width:9px}
.proof .stat .fold-body{padding:2px 2px 20px}
.proof .stat .fold-body .u{margin-top:12px}
.proof .fold-wide .fold-body{max-width:var(--measure);padding-bottom:24px}
.proof .fold-wide .sec-note{margin-top:14px}

@media print{
  /* A capex committee prints this page, and paper cannot be clicked open: whatever
     the reader left closed on screen must still be ON the sheet. Chromium hides a
     closed panel two different ways depending on version — the old UA display:none
     on non-summary children, and content-visibility:hidden on the newer
     ::details-content box — so both are lifted. An engine without ::details-content
     ignores that rule rather than invalidating the block. Scoped to .proof: the
     founder lane already does this for its own fold, and reaching into a section
     this lane does not own is how two appends start fighting. */
  .proof .fold > .fold-body{display:block !important}
  .proof .fold::details-content{content-visibility:visible !important;block-size:auto !important}
  .proof .fold > summary::before{content:"//"}
  .proof .fold,.proof .fold-body,.proof .rail{break-inside:avoid;page-break-inside:avoid}
}

/* ── CREDENTIAL WALL, FOLDED (2026-08-24) ───────────────────────────────────────
   The section carried 195 visible words: a 46-word lede plus three mono caveats set
   as running copy. NOTHING WAS CUT. The lede's own argument — "the steel is yours,
   the instruments are not ours either" — is now DRAWN as a three-layer section
   through the plant, and every measurement, hedge and limit moved verbatim inside a
   native <details>.

   NATIVE <details>, NEVER A JS ACCORDION, for three reasons that each bite here:
   it works with JavaScript off (qa/e2e/test_no_js.py loads every page that way),
   it is keyboard-reachable and screen-reader-announced for free, and it needs no
   motion — so there is no transition for motion-lint's REDUCED rule to demand a
   counterpart for, and prefers-reduced-motion is satisfied by construction rather
   than by a fallback. No chevron rotation, no max-height animation: it opens, or
   it does not.

   THE STACK'S ALIGNMENT IS STRUCTURAL, NOT COORDINATED. The three rows share no
   x-coordinate and need none: each instrument riser is drawn to the very top and
   very bottom edge of its own cell, while the amber bus (last path of the AIREI
   drawing) and the mill's ground line both span 0→620 of their viewBox. Adjacent
   grid rows with NO row-gap therefore make every riser meet both lines at every
   viewport width. Change `row-gap` here and the drawing comes apart. */
.stack{margin:clamp(30px,3.4vw,46px) 0 0;display:block}
.stack .lyr{display:grid;align-items:center;column-gap:clamp(10px,1.7vw,26px);row-gap:0;
  grid-template-columns:clamp(76px,12.6vw,168px) minmax(0,1fr) clamp(52px,8.4vw,104px)}
.stack .who,.stack .own{font-family:var(--f-mono);font-size:12.5px;font-weight:600;
  letter-spacing:.15em;text-transform:uppercase;line-height:1.5;color:#4C5A66}
.stack .own{text-align:right}
.stack .lyr-ai .who,.stack .lyr-ai .own{color:#8A5E14}
.stack .art{display:block;min-width:0;line-height:0}

/* AIREI — the reading layer. The tint sits on the ART cell only, never on the row:
   a wash that exists for the drawing must not become the ground a label is graded
   against. */
.lyr-ai .art{background:rgba(200,136,40,.06)}
.lyr-ai .art svg{display:block;width:100%;height:30px}

/* Field instruments — EIGHT separate glyphs, not one wide drawing, and that is the
   whole responsive trick: each balloon keeps a constant on-screen size while the row
   distributes them. One SVG spanning the column would either shrink the balloons to
   nothing at 390px (preserveAspectRatio=meet) or stop spanning it at 1440px. */
.lyr-inst .art{display:flex;justify-content:space-between;align-items:stretch;
  height:clamp(52px,5.8vw,78px)}
.lyr-inst .art svg{display:block;height:100%;width:auto;flex:none}

/* The mill — CROPPED, never distorted. `xMidYMax slice` pins the ground line to the
   bottom edge at every width and trims the run of vessels from the outside in; the
   drawing is an EVEN run of plant for exactly that reason, so a narrow crop still
   reads as a plant rather than as half of one machine. */
.lyr-mill .art svg{display:block;width:100%;height:clamp(50px,7.2vw,104px)}

/* The name wall. Separators are a hairline RULE, not a "·" glyph: a punctuation mark
   between every pair is three more tokens a screen reader reads aloud and three more
   words in the visible count, for a job a 1px border does better. */
.creds .names{display:flex;flex-wrap:wrap;align-items:baseline;gap:7px 0;margin:0;
  line-height:1.45}
.creds .names span{padding:0 clamp(9px,1.05vw,16px)}
.creds .names span:first-child{padding-left:0}
.creds .names span+span{border-left:1px solid rgba(138,94,20,.5)}

/* The fold — CONVERGED ONTO THE HOUSE BASE (2026-08-24). This block used to
   re-declare the whole control: its own display, gap, font-family, size, weight,
   tracking, text-transform and its own "+" / "–" marker at width:1ch. That made it
   a SECOND implementation of a control the chain lane had already declared, and it
   drifted — measured live on the rendered page at 11px / 1.65px tracking against the
   base's 11.5px / 2.30px, and spelling its body `.foldbody` where every other lane
   spells it `.fold-body`. Four summary sizes were shipping on one page.

   Everything structural now comes from the bare `.fold` base (~line 497) and is
   deliberately NOT repeated here — re-stating a value is how the next drift starts.
   What survives is only what is genuinely different about THIS section, and each of
   the four has a reason that is not taste:

   1. COLOUR. The base is built for the dark ground: `--ink-subtle` #8899AA on
      Deep Water, `--crude-amber` #C88828, `--signal-gold` #FFD658 for the focus ring.
      This section is `.paper`. All three fail on Kernel White, so the paper-ground
      derived values from DESIGN.md §3b stand in — #8A5E14 print-safe amber for the
      summary and its marker, #7A520F on hover, #10598E for the focus outline (a gold
      ring on warm paper is not a visible focus indicator).
   2. NO FLOOR RULE. The base closes the panel with a border-bottom. Every `.creds .row`
      already draws its own bottom hairline ~14px below it, and two rules that close
      read as a mistake rather than as a card — the base's own reasoning, applied here.
   3. SPACING. margin-top 14px, not the base's section-sized clamp(26px,3.4vw,44px):
      this fold lives INSIDE a register row, under the names it qualifies.
   4. THE FOLD BODY IS MONO. These three panels are provenance notes, not prose —
      the telemetry voice (DESIGN.md §4), sized down and set to 84ch.

   NO rotation and NO transition anywhere, here or in the base: it opens or it does
   not. Summary text NAMES WHAT IS INSIDE — "what the logos don't prove", never
   "read more", which is the generic-SaaS tell DESIGN.md §8 bans by name. */
.creds .fold{margin-top:14px;
  border-top:1px solid rgba(22,32,43,.14);border-bottom:0}
.creds .fold > summary{padding:11px 0 1px;color:#8A5E14}
.creds .fold > summary::before{color:#8A5E14}
.creds .fold > summary:focus-visible{outline-color:#10598E}

/* LINKS ON THE PAPER GROUND. The register block carried no links at all until
   2026-08-27, when three landed in one day — the letters citation in the partner fold,
   and two in the client offer. The global anchor colour is --airei-blue-lift #3D9AE0,
   drawn for Deep Water; measured on Kernel White #FAFAF8 it reads 2.91:1 against a
   4.5:1 requirement at 13px and 17px, and qa/contrast.py caught all three at once.
   Nothing new is invented here: this reuses the SAME paper-ground pair the summary
   above already uses, from DESIGN.md §3b — #8A5E14 print-safe amber (5.44:1), #7A520F
   on hover (6.61:1), #10598E for the focus ring, because a gold ring on warm paper is
   not a visible focus indicator. Scoped to .creds, which exists only inside the
   .paper #credentials section of index.html and ms/index.html. */
.creds a{color:#8A5E14;border-bottom:1px solid rgba(138,94,20,.4)}
.creds a:focus-visible{outline-color:#10598E}
@media (hover:hover) and (pointer:fine){.creds a:hover{color:#7A520F;border-bottom-color:#7A520F}}
@media (hover:hover) and (pointer:fine){.creds .fold > summary:hover{color:#7A520F}}
.creds .fold-body{padding:0 0 4px}
/* 84ch -> 79ch, 2026-08-27. This one was already deliberate and already in the right
   unit — the cap is in `ch` and the element's own font is the 13px mono the `ch` is
   measured in, so unlike `.sec-note` above there was no font mismatch to correct. It was
   simply set 4ch over the ceiling: 84ch measured on home and ms at all three desktop
   widths, the last two blocks on either page still above 80. 79ch is 616px, which lands
   within a pixel of the 620px every other mono note on the site now uses, and delivers
   71 characters to a line at .05em. */
.creds .fold-body p{margin:11px 0 0;font-family:var(--f-mono);font-size:13px;
  letter-spacing:.05em;line-height:1.65;color:#4C5A66;max-width:79ch}

@media print{
  /* Paper has no disclosure triangle. Folding was to shorten the SCREEN, never to
     lose the record, so everything folded prints open. BEST-EFFORT BY ENGINE: the
     ::details-content arm is the modern one, the child arm covers engines that still
     hide children with display; an engine honouring neither prints only the summary,
     and that is a known limit, not a silent one. */
  .creds .fold::details-content{content-visibility:visible;block-size:auto}
  .creds .fold:not([open]) > .fold-body{display:block}
  .creds .fold > summary{color:#7A520F}
  .creds .fold > summary::before{content:"";width:0}
  .stack,.creds .fold{break-inside:avoid;page-break-inside:avoid}
}

/* Print, chain lane: a folded panel on paper is a panel nobody can open, so the
   six-position register prints OPEN. ::details-content is the one property that
   reaches a closed panel's children — the UA hides them through that slot, not
   through a `display` on the child. Where an engine has no ::details-content the
   rule is ignored and the panel prints closed, which is no worse than before.
   The two drawings swap the other way on paper: a sheet is wide, so the wide rail
   prints and the tall one is suppressed. Print values are declared derived tokens
   (DESIGN.md §3b) — #101820 ink, #3C4A57 muted, #7A5310 the print-safe amber —
   because the screen amber and the gold both fail on white. */
@media print{
  .spine .fold::details-content{content-visibility:visible;opacity:1}
  .spine .fold > summary::before{display:none}
  .spine .fold > summary{color:#101820}
  .chainfig .cf-wide{display:block;max-width:100%}
  .chainfig .cf-tall{display:none}
  .cf-name{fill:#101820}
  .cf-ord{fill:#7A5310}
  .cf-node{fill:#7A5310}
  .cf-icon{stroke:#7A5310}
  .cf-plat{fill:#101820}
  .cf-kick{fill:#3C4A57}
  .cf-rail,.cf-brace,.cf-tick{stroke:#55636F}
}


/* ═══ THE TWO MACHINES — MAP + FOLD (2026-08-24) ══════════════════════════════
   Owned by section.two#machines. Everything below is namespaced under `.two` or
   `.millmap` on purpose — this file is appended to by several lanes at once, and
   an unscoped `details{}` or `summary{}` rule would reach into sections this lane
   does not own.

   THE CLAIM OF THIS SECTION IS A SHAPE, so it is drawn rather than described.
   "One retrofits the mill. One replaces the eye at the ramp." is a statement
   about GEOMETRY: one machine spans the whole line, the other lands on a single
   point of it. That is a span-versus-point diagram, and it is a DIFFERENT drawing
   from the hero blueprint (an isometric picture of the plant, with its own amber
   station dots). The map below deliberately does NOT re-name all eight stations,
   because the hero already marks them, smart-mill.html lists them, and the fold
   inside the first card carries the full list — repeating them here would be the
   third copy on one page.

   TWO DRAWINGS, ONE DIAGRAM — the same conclusion the chain lane reached
   independently above, for the same measured reason. Eight nodes across need a
   wide viewBox; at a 760px viewport the lane is 684px, which scales this drawing's
   13.5px label type to 9.2px. So the switch is at 1000px (lane 900, scale .90,
   13.5px -> 12.2px) and below it an upright twin carries the SAME words.
   `display:none` (not visibility/clip) is deliberate: the hidden twin contributes
   nothing to document.body.innerText, so the section's visible word count is one
   number at both widths rather than a double count.

   Nothing here transitions and nothing animates, so no prefers-reduced-motion arm
   is needed — there is no motion to reduce. */
.millmap{margin:clamp(30px,3.8vw,54px) 0 0;padding:clamp(22px,2.6vw,36px) 0 0;
  border-top:1px solid var(--hairline)}
.millmap svg{display:block;width:100%;height:auto;overflow:visible;margin:0 auto}
.millmap .mm-wide{display:none}
.millmap .mm-tall{display:block;max-width:300px}
@media (min-width:1000px){
  /* Fills the lane rather than sitting capped inside it. Measured at 1440 with a
     1000px cap: the rail landed 100px inboard of the section's left text edge and
     20px inboard of the right — asymmetric, so it read as mis-set rather than as
     padded. The drawing carries symmetric 20px margins in its own viewBox instead. */
  .millmap .mm-wide{display:block;max-width:100%}
  .millmap .mm-tall{display:none}
}

/* Palette: hairline + amber only, the same two-value vocabulary the .stations
   strip and the .chainfig rail already use, so the drawing and the photographs
   read as one object. AIREI Blue is absent BY RULE — DESIGN.md §3 reserves it for
   the mark and for interactive elements, and a diagram is neither. Every fill
   below is a token already proven AA on --deep-water elsewhere on this page;
   --mill-steel appears only as a STROKE, never as type, because it measures
   3.53:1 on this ground and would fail as text. */
.mm text{font-family:var(--f-mono);font-weight:500}
.mm .t-main{fill:var(--ink);font-weight:600;letter-spacing:.13em}
.mm .t-sub{fill:var(--ink-subtle);letter-spacing:.16em}
.mm .t-num{fill:var(--ink-subtle);font-weight:600;letter-spacing:.05em}
.mm .t-end{fill:var(--ink-muted);letter-spacing:.13em}
.mm .t-amber{fill:var(--crude-amber);font-weight:600;letter-spacing:.13em}
.mm .rail{fill:none;stroke:var(--mill-steel)}
.mm .drop{fill:none;stroke:var(--ink-subtle)}
.mm .brace{fill:none;stroke:var(--crude-amber)}
.mm .node{fill:var(--crude-amber)}
.mm .head{fill:var(--ink-subtle)}
.mm .ring{fill:none;stroke:var(--hairline-strong)}
/* The unit is a SOLID box and the retrofit is an OPEN bracket. The two machines
   are told apart by FORM, not by a second accent colour — which is what keeps
   Crude Amber inside its <=10% share while still marking every station. */
.mm .unitbox{fill:var(--panel-navy);stroke:var(--hairline-strong)}

/* ── THE FOLD, inside a machine card ──
   THIS LANE DECLARES ALMOST NOTHING ABOUT THE FOLD ON PURPOSE. Measured while
   writing this: `.fold`, `.fold > summary` and `.fold-body` are declared UNSCOPED
   at page level by more than one lane in this same file, and the last one in the
   cascade wins for every section. Redeclaring the summary here would make this
   section the one that looks different the moment that order changes — so the
   marker, the type and the rail are taken as given, and only the two genuinely
   local things are set: the gap to the picture above and the gap to the CTA below.

   `border-bottom:0` is the one defensive line. One page-scope declaration gives
   .fold a top rule only; another gives it top AND bottom. Two stacked folds under
   the second would print one hairline 1px above another, which reads as a
   rendering fault and not as a divider. Dropping the bottom rule leaves exactly
   one hairline between the two summaries under EITHER declaration. */
.two .machine .fold{margin-top:0;border-bottom:0}
.two .machine .fold:first-of-type{margin-top:20px}
.two .machine .go{margin-top:24px}
/* Inside a fold the mono note loses its own rule and its own top gap: the
   summary's hairline is already the line above it. Same correction the chain lane
   made to .fold-body .chain. */
.two .fold-body .note{margin-top:18px;padding-top:0;border-top:0}
.two .fold-body > .lede:first-child,
.two .fold-body > .note:first-child{margin-top:0}
.two .fold-body .stations{margin-top:20px}

/* Print: a folded panel on paper is a panel nobody can open, and a light-ink
   diagram on white paper is an invisible diagram. Both are fixed here rather than
   left to the reader. ::details-content is the only property that reaches a closed
   panel's children — the UA hides them through that slot, not through a `display`
   on the child. The two drawings swap the other way on paper: a sheet is wide, so
   the wide rail prints and the tall one is suppressed. Every print value below is
   a declared derived token (DESIGN.md §3b) — #101820 / #3C4A57 / #55636F /
   #7A5310, and #FFF, which that same section scopes to print — never a new
   colour, because the screen amber and the gold both fail on white. */
@media print{
  .two .fold::details-content{content-visibility:visible;opacity:1}
  .two .fold > .fold-body{display:block}
  .two .fold > summary::before{display:none}
  .two .fold > summary{color:#101820}
  .millmap .mm-wide{display:block;max-width:100%}
  .millmap .mm-tall{display:none}
  .mm .t-main{fill:#101820}
  .mm .t-sub,.mm .t-num,.mm .t-end{fill:#3C4A57}
  .mm .t-amber{fill:#7A5310}
  .mm .brace{stroke:#7A5310}
  .mm .node{fill:#7A5310}
  .mm .rail,.mm .drop,.mm .ring{stroke:#55636F}
  .mm .head{fill:#55636F}
  .mm .unitbox{fill:#FFF;stroke:#55636F}
}
/* One column: the fold's floor rule and the NEXT stat's top rule become two
   parallel hairlines ~40px apart, which reads as a mistake rather than as a card.
   At 4-up the floor closes each card and is kept. */
@media (max-width:599px){.proof .stat .fold{border-bottom:0}}

/* ── CREDENTIAL WALL — corrections made by LOOKING at 1440 and 390 ──────────────
   1. THE MILL IS NO LONGER CROPPED. `slice` at 390px showed the centre 55% of the
      run and cut the CPO tank in half at the frame edge — a dome sliced down the
      middle reads as a rendering bug, not as a section that continues. `meet` with
      an intrinsic height shows the whole plant at every width (≈107px at 1440,
      ≈32px at 390) and never cuts an object.
   2. THE LABEL COLUMNS GIVE THE DRAWING ITS WIDTH BACK below 680px, where a 168px
      label rail was eating half the viewport and squeezing eight instrument
      balloons into 200px.
   3. THE NAME WALL GOES VERTICAL below 1000px. The hairline divider is a
      `border-left`, and CSS cannot know which flex item starts a wrapped line — so
      at 390px "VEGA" carried a leading tick with nothing to its left. Below the
      width where the wall fits on one line it becomes a hairline-separated list,
      which has no line-start to get wrong.
   4. THE SECTION NOTE BINDS DOWN, not up. Sitting 16px under the drawing it read as
      the drawing's caption; it is the heading for the three rows beneath it. */
.stack .lyr-mill .art svg{width:100%;height:auto}
@media (max-width:680px){
  .stack .lyr{grid-template-columns:74px minmax(0,1fr) 46px;column-gap:9px}
  /* 9.5px was the smallest type on the site. These are one-to-two-word labels pinned to a
     drawing, so they sit under the 11px reading floor by design — but not that far under.
     10.5px is the site's own micro-label size, and the tracking pays for the extra width:
     "INSTRUMENTS" is 11 characters, and 11 x (6.3 + .42) = 74px still clears the 76px
     minimum column, where 11 x (6.3 + 1.05) at .1em would have been 81px and clipped. The
     row-gap:0 geometry above depends on this label block not growing a line. */
  .stack .who,.stack .own{font-size:10.5px;letter-spacing:.04em}
  .lyr-ai .art svg{height:24px}
  .lyr-inst .art{height:50px}
}
@media (max-width:999px){
  .creds .names{display:block}
  .creds .names span{display:block;padding:8px 0;
    border-left:0;border-top:1px solid rgba(138,94,20,.28)}
  .creds .names span:first-child{border-top:0;padding-top:0}
}
.paper .stack+.sec-note{margin-top:clamp(30px,3.4vw,44px)}
.paper .sec-note+.creds{margin-top:14px}

/* ── CREDENTIAL WALL — second look at 390px ─────────────────────────────────────
   The stacked one-name-per-row list fixed the stray tick and introduced two worse
   things: `.creds .names span+span` (0,2,2) outranked the `border-left:0` I wrote at
   (0,2,1), so the tick was still there — and five full-height rows cost ~200px of a
   page whose whole brief is to get shorter. Below the width where the wall fits on
   one line it is now a WRAPPING wall with no rule at all: proper nouns at 17px with
   a 22px column gap separate themselves, and a gap has no line-start to get wrong. */
@media (max-width:999px){
  .creds .names{display:flex;flex-wrap:wrap;column-gap:22px;row-gap:5px}
  .creds .names span,.creds .names span+span,.creds .names span:first-child{
    display:inline;padding:0;border:0}
}
@media (max-width:680px){
  .lyr-ai .art svg{height:26px}
  .lyr-inst .art{height:56px}
}

/* ── FOUNDER BAND — THE OPEN-STATE VOID (append, 2026-08-24) ────────────────
   Owned by section.founderband#founder. Appended at the file end rather than
   edited into the lane's own block above, because four other lanes are writing
   this file concurrently and an append cannot collide with their line numbers.
   It also lands last, so it wins at equal specificity without needing any.

   WHAT I SAW, not what I inferred. Screenshot at 1440x1000 dsf=2 with the fold
   OPEN: the band grows from 764px to 1571px, the photograph is 502px, and the
   `:has(.fold[open])` top-alignment the lane already ships pins it to the top —
   correctly. The cost it does not cover is what is left BELOW it: ~740px of
   empty Deep Water in a column running nearly half the page width, beside
   eleven hundred pixels of biography. The reader who opened the panel reads
   his words with his face scrolled off the screen, next to a void.

   (That sentence first gave the width as a percentage numeral, and
   deploy-check refused the file: that exact token is BANNED in claims.json —
   a conference labour figure that contradicts the site-specific Minsawi one
   and must never print beside it. The register does not care that mine was a
   CSS comment about a column width, and it is right not to: a scanner that
   exempted comments is a scanner an author can argue their way past. So the
   sentence says it in words. Fixed the input, did not bypass the wall — and
   note this comment cannot restate the banned figure either, which is why it
   names the ban rather than quoting it.)

   THE PHOTOGRAPH TRAVELS INSTEAD. `position:sticky` is not a new idea on this
   site — the masthead (shell.css), the smart-mill rail and both proof columns
   already use it — so this is the house pattern applied to the same problem,
   not an invention. It is layout, not animation: no transition, no transform,
   no scroll listener, nothing for prefers-reduced-motion to fall back FROM, and
   nothing on the §5 banned list (it is not parallax — the photo moves at the
   page's own rate until it pins, then stops).

   SCOPED TO THE OPEN STATE ONLY. Closed, the type column runs shorter than the
   square, so the row is exactly photo-height, there is no travel, and sticky
   would be inert anyway — but gating it on :has() keeps the closed band's
   centred rule provably untouched instead of merely believed untouched. An
   engine without :has() gets today's behaviour, which is the current shipping
   behaviour, so nothing regresses.

   ≥860px ONLY: below that the grid is one column, the photo is stacked ABOVE
   the type rather than beside it, and a sticky image there would ride down over
   the biography it is supposed to introduce. Verified at 390 with the fold open,
   not assumed. */
@media (min-width:860px){
  .founderband .founder:has(.fold[open]) .shot{
    position:sticky;
    /* Clears the sticky masthead by its own token, so the two never overlap at
       any of the three --hdr steps (65/80/84px). */
    top:calc(var(--hdr) + 24px);
    align-self:start;
  }
}

/* ══ PROOF BAND — THE KEY, and the rails redrawn so before/after READS ═══════
   Appended 2026-08-24 by the proof lane. Scoped to .proof throughout; nothing
   declared earlier in this file is edited, only overridden at higher specificity.

   WHY: measured on the rendered page at 1440, the two rails sat 4px tall and 10
   units apart inside a 22-unit frame stretched across a 330px column — near the
   same weight, near the same colour value, close enough together to read as ONE
   two-tone line rather than as a baseline and a result. The comparison the band
   exists to make was the thing the drawing was worst at.

   THE FIX IS WEIGHT, NOT COLOUR. The baseline rail is now the THIN one (3 units)
   and the after-state the THICK one (6), 11 units apart in a 26-unit frame. A
   reader who cannot separate Mill Steel from Crude Amber — the deuteranopic case
   this palette has to survive — still reads "thin line up here, fat line down
   there, one is longer". Colour is the second channel, never the only one.

   AND THE KEY REPLACES A SENTENCE. The band spent eight visible words explaining
   its own chart. Those words are folded verbatim into "the hedges, kept verbatim";
   the grammar is drawn instead. A legend is information, so it is not decoration.
   ─────────────────────────────────────────────────────────────────────────── */
.proof .rail-fx{height:26px}

/* UNREFERENCED SINCE 2026-08-27 — kept, not deleted, and this comment is the reason.
   index.html cut its rail legend on 08-26 (the rails carry "17.85 -> 19.02" underneath, so
   the legend taught a grammar nobody needed); ms/index.html was cut to match on 08-27.
   `grep -rln 'rl-key\|rl-kk\|rl-sw' --include='*.html'` now returns nothing, so these three
   rules style no element on the site. They stay because the decision above was a judgement
   about one page's composition, not about the component, and deleting the CSS would make
   restoring the legend a rebuild rather than one line of markup. `.rl-track` / `.rl-bar`
   below are NOT dead — they draw the rails themselves, on both homepages. */
.rl-key{display:flex;flex-wrap:wrap;gap:8px 26px;margin:18px 0 0;
  font-family:var(--f-mono);font-size:12.5px;line-height:1;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-ghost)}
.rl-kk{display:inline-flex;align-items:center;gap:10px}
.rl-sw{display:block;width:26px;height:10px;flex:none}

/* The key sits directly above the band it explains, so it needs air under it
   rather than the section-sized gap .statband already carries above itself. */
.proof .rl-key + .statband{margin-top:clamp(30px,3.6vw,46px)}

/* The payback card's "<" is an operator, not a numeral. Fraunces sets the "+" and
   "−" on the other three cards cleanly and this glyph badly — it collided with the
   2 at every viewport measured. Mono, optically sized, with its own gap. */
.proof .v .op{font-family:var(--f-mono);font-style:normal;font-weight:500;
  font-size:.44em;letter-spacing:0;margin-right:.1em;vertical-align:.32em;
  color:var(--ink-muted)}

/* ── THE CLOSED LOOP, appended by the .two#machines lane (2026-08-24) ──────────
   `.mm .loop` / `.mm .head-a` are the return path drawn from station 08 back into
   station 02 in BOTH mill maps. Scoped under `.mm`, which only this section uses,
   so this append cannot reach another lane's drawing.

   DASHED ON PURPOSE, and it is the whole reason the line is legible: the solid
   amber `.brace` beneath the rail is a PHYSICAL span (these eight stations are
   retrofitted); this is a SIGNAL returning. Measured by eye at 1440 and at 390 —
   drawn solid it read as a second rail and the map lost the one-versus-eight
   contrast it exists to carry. Dashes are static geometry, not motion, so there
   is nothing here for prefers-reduced-motion to reduce.

   The dark-ground colour is --crude-amber, the same token as .brace and .node,
   because the loop belongs to AI Smart Mill; the print arm below restores the
   darker #7A5310 the print block already uses for every other amber mark, so the
   line does not disappear into white paper. */
.mm .loop{fill:none;stroke:var(--crude-amber);stroke-dasharray:4 5;stroke-linecap:butt}
.mm .head-a{fill:var(--crude-amber)}
@media print{
  .mm .loop{stroke:#7A5310}
  .mm .head-a{fill:#7A5310}
}

/* ── HERO DETECTION LATTICE (2026-08-24) ───────────────────────────────────────────────────
   The overlay + its scrim. Electric blue #2E9BFF is AIREI Blue #1875BC pushed into the range
   measured on the companies who own this aesthetic — Skydio #0060F0, Applied Intuition #0030F0,
   Waymo #0060D8 — so it is an evolution of the palette, not a borrowed cyan. */
/* fx-hero.js builds its readouts as SVG <text> and stamps font-family="ui-monospace,Menlo,
   monospace" on each one (assets/js/fx-hero.js:63,82). That stack does not contain Geist Mono,
   so the labels on the hero lattice — the one place on the page a reader sees a machine
   readout — were set in the OS monospace while every other mono label on the site was set in
   the brand's. A CSS rule out-ranks an SVG presentation attribute, so this puts the token back
   in charge and leaves the attributes standing as their own fallback. */
.hero-media .fxh-svg text{font-family:var(--f-mono)}
.hero-media .fxh-svg{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none;
  /* THE LATTICE IS FENCED OUT OF THE READING COLUMN. The scrim above was lightened twice
     (08-24, 08-25) because "the overlay blocked about half the hero"; both fixes changed LUMA.
     It was never luma. Overlay ink measured IN PIXELS inside the hero's own text boxes on the
     live site 2026-08-26 (render at svg opacity 1 and 0, diff, count) — not by rect geometry,
     which a mask cannot change:
       .hero .sub    28.09% of its pixels at 1200px, 24.80% at 1440px
       .hero-ctas    16.81% at 1000px
       .hero-stamp   37.62% at 1920px, 30.42% at 901px   <- the Star citation
     Confirmed at 1:1: the label "x398 y700 232x112" printed across the word "milling.".
     Right edge of hero-copy ink: 1100px 54.8% · 1200px 51.0% · 1280px 52.6% · 1366px 55.3%
     · 1440px 55.8% · 1920px 54.4% — stable ~55%, so transparent to 57%, full at 70%. Keyed to
     the frame, like `.hero-copy{min(640px,46vw)}`, so both track the viewport together.
     fx-hero.js's regions were re-placed into the band this leaves. Now 0px at every width. */
  -webkit-mask-image:linear-gradient(to right,transparent 0,transparent 57%,#000 70%,#000 100%);
          mask-image:linear-gradient(to right,transparent 0,transparent 57%,#000 70%,#000 100%)}

/* SCRIM — LIGHTENED 2026-08-24 after measuring what it destroyed. It was stacking on a
   PRE-EXISTING full-frame scrim thirty lines up (.hero-media::after inside the mobile block,
   to-bottom .62/.42/.58) that I did not check for before adding a second one. Two scrims
   multiply. Measured luma kept, against the raw file:
       x 0-15%  48%   ·  x30-45%  50%  ·  x45-60%  44%
   Half the photograph was gone across the left sixty percent of the frame — the operator saw it
   immediately and was right. Now .72 -> 0 by 56%, and contrast is re-verified at five points
   across the animation rather than assumed.
   Original note follows. */
/* The eyebrow sits on sky at RGB(154,148,137) and Signal Gold
   scored 2.16:1 against it — a real WCAG failure at EVERY point of the pass, not only at the
   start. A first measurement averaged the whole copy block instead and read 12:1, because the
   block spans the dark headline area and that average hid it. Measure the element that looks
   wrong, not the box around it.
   A left-anchored gradient rather than a flat panel, so it never becomes a card. */
.hero-media::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(100deg,
    rgba(11,21,32,.34) 0%, rgba(11,21,32,.26) 18%,
    rgba(11,21,32,.14) 34%, rgba(11,21,32,.04) 46%, rgba(11,21,32,0) 56%)}
/* LIGHTENED AGAIN 2026-08-25, and this time the copy carries itself. The .72 opening stop was
   correct while the headline sat on a .965 slab and needed the scrim to do half the work. That
   slab is gone: the copy panel is a .16 whisper and a three-stop text-shadow does the close
   work at the letterforms. Swept from .90 down while measuring every hero element from PIXELS
   (qa/hero-contrast.py) — at these stops the headline holds ~7:1 against a 3:1 requirement.
   The operator's note was that the overlay blocked about half the hero. It did. */
.hero .hero-copy,.hero .hero-stamp{position:relative;z-index:4}

/* The live readout. Every value is a READING of the frame — the sweep's own y in source pixels,
   and counts of things actually drawn. Never a performance figure. */
.fxh-hud{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px 22px;margin:0 0 20px;
  max-width:340px;font-family:var(--f-mono);font-size:13px;line-height:1.35;
  font-weight:600;letter-spacing:.10em}
.fxh-hud div{display:flex;justify-content:space-between;gap:12px;padding-bottom:5px;
  border-bottom:1px solid rgba(46,155,255,.28)}
/* --ink-ghost measured 3.60:1 on the scrimmed sky, a fail for 13px text. --ink-muted clears it.
   This label is small AND mono AND letterspaced, three things that each cost legibility. */
.fxh-hud span{color:var(--ink-muted);text-transform:uppercase}
.fxh-hud b{color:#7FC4FF;font-variant-numeric:tabular-nums}
@media (max-width:620px){ .fxh-hud{grid-template-columns:1fr;max-width:250px;margin-bottom:16px} }

/* No JS, or reduced motion: the photograph and the copy carry the hero on their own.
   Nothing in the overlay is content, so nothing is lost when it does not run. */
@media (prefers-reduced-motion:reduce){ .hero-media .fxh-svg *{transition:none!important;animation:none!important} }

/* COORDINATE LABELS ARE DESKTOP-ONLY, and this is a legibility decision the overflow check
   forced into the open. The SVG uses preserveAspectRatio="slice" on a 16:9 viewBox, so at narrow
   widths the sides are CROPPED — a label pinned at source x135 lands outside the viewport
   entirely. e2e-responsive-ink measured 47 overflows across 320-660px, every one a coordinate
   label sitting off the LEFT edge at negative x.
   Hiding them is the right fix rather than repositioning: they are 13px mono strings like
   "x135 y712 250x118", and on a 390px phone the frame is cropped so hard that a coordinate
   pinned to a region you cannot fully see tells the reader nothing. The HUD keeps the live
   numbers — it is DOM text in the copy column, so it stays readable at every width. */
@media (max-width:660px){ .fxh-coord{display:none} }


/* ── TWO REAL DEFECTS IN THE LATTICE, MEASURED AND FIXED (2026-08-24) ──────────────────────
   The overflow check refused to go green and it was right twice over.

   1. THE OVERLAY WAS NEVER ALIGNED TO THE PHOTOGRAPH. The <img> cropped with
      object-position:80% 40%; the <svg> cropped with preserveAspectRatio="xMidYMid slice".
      Those are DIFFERENT windows. Measured at 1360px: the image showed source x312..x1842 while
      the overlay showed x195..x1725 — 117 source px apart. Every box sat 117px left of the canopy
      it appeared to be reading. Both now crop from the centre, so they agree by construction.

   2. BELOW ~900px THE CROP WINDOW IS TOO NARROW FOR THE EFFECT TO MEAN ANYTHING. Measured:
        320px -> only source x779..x1141 is visible (362 of 1920 px)
        390px -> x723..x1197
      Five of the seven regions AND the mill lock itself fall outside that window. The overlay was
      not merely overflowing on a phone, it was pointing at things nobody could see. So it is
      desktop-only, and the HUD — DOM text in the copy column — carries the live numbers at every
      width instead. Hiding a broken effect beats shipping a confusing one. */
/* RAISED 900px -> 1100px, 2026-08-26. The 900px cut answered "can the reader SEE the
   regions?". It never answered "is the overlay printed ON the copy?", and below 1100px the
   answer was yes by construction: `.hero-copy{max-width:min(640px,46vw)}` forty lines up is
   dropped at 940px, so from 901-940px the copy runs the full wrap — measured ink right edge
   95.0% of the viewport at both ends — leaving 64 and 66 source units of frame beside it. Two
   thresholds that had to agree, one here and one in fx-hero.js, never reconciled. At
   960-1080px the free band is still too tight for a 230px region plus its 186px label to clear
   the 70% mask stop; 1100px is the first width where it fits. The HUD is DOM text in the copy
   column and keeps the live numbers below it — the trade this file already made at 900px. */
@media (max-width:1100px){ .hero-media .fxh-svg{display:none} }
.hero-media img{object-position:50% 40%}

/* The two `.go` links on the machine cards are the only route from the home page into the
   product pages, and at 390px they measured 224x21 and 153x21 — the primary path deeper
   into the site was the smallest tap target on it. Touch only; the desktop rhythm is unchanged. */
@media (pointer:coarse){
  .machine .go{min-height:44px;display:inline-flex;align-items:center;padding:4px 0}
}

/* ══ .fits — how the three products relate ═══════════════════════════════════════
   Codex, reading the site as a buyer: "I cannot tell whether Traceability is a fourth product
   or a MyPalm capability, whether I should have read MyPalm first, whether Smart Mill supplies
   the source data, or which one I need." Seven nav items cannot answer that; a picture of the
   hierarchy can, in one screen, before any product page is opened.
   Built from the site's own facts: two hardware retrofits that produce readings, one software
   family that holds them, and Traceability as a capability INSIDE that family. */
.fits{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;
  background:var(--hairline);border:1px solid var(--hairline);margin:var(--d3) 0}
.fits>a{background:var(--mill-navy);padding:clamp(20px,2.4vw,30px);text-decoration:none;
  display:flex;flex-direction:column;gap:10px;color:inherit;transition:background .2s var(--e-quad)}
@media (hover:hover){ .fits>a:hover{background:var(--panel-navy)} }
/* Sentence case per .sec-note above. All four tiers are phrases, not one-word labels, and
   the fourth is "Sold on its own · AIREI calls it Supply Chain & Traceability" — a product
   name AIREI capitalises, which uppercase erased. 11px/1 also gave a two-line phrase no
   leading at all; 1.45 lets it breathe. */
/* 11px -> 12.5px, third pass (see `.stat .src`, base.css). The note above already
   established this is a phrase and not a label. It is also the only sub-12px text left in
   this card: `.fits .need` two rules below is already 12.5px mono, so the tier line was the
   one member of the card set below its own siblings. */
.fits .tier{font:600 12.5px/1.45 var(--f-mono);letter-spacing:.02em;
  color:var(--airei-blue-lift)}
.fits h3{margin:0;font-size:clamp(19px,1.7vw,25px);line-height:1.1;letter-spacing:-0.0048em;
  font-weight:600;color:var(--ink)}
.fits p{margin:0;font-size:15.5px;line-height:1.55;color:var(--ink-muted)}
.fits .need{font:500 12.5px/1.5 var(--f-mono);color:var(--ink-ghost);margin-top:auto;padding-top:10px}
.fits .go{font:600 12px/1 var(--f-mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--airei-blue-lift);display:inline-flex;gap:6px;align-items:center}
.fits .span2{grid-column:1 / -1}
/* ABSOLUTE BAN — side-stripe borders. A `border-left` thicker than 1px used as a coloured
   accent on a card, a list item, a callout or an alert is the first item on the DON'T list
   in the impeccable skill, and it is the one AI tell this site was still carrying in six
   places. The prescribed rewrites are full borders, background tints, leading
   numbers/icons, or nothing, and each of the six below takes whichever of those the
   surrounding component already uses. */
/* The stripe here was saying "this cell is a CHILD of the row above it". A leading marker
   on the tier label says the same thing and says it in words a screen reader can reach the
   context of, which a 3px rule cannot. The panel tint carries the rest. */
.fits .child{background:var(--panel-navy)}
.fits .child .tier::before{content:"\21B3";margin-right:7px;color:var(--airei-blue-lift)}
.fits .child .tier{color:var(--ink-ghost)}
@media (pointer:coarse){ .fits .go{min-height:44px;align-items:center} }
@media (max-width:760px){ .fits{grid-template-columns:minmax(0,1fr)} }

/* The product map's cards lift on hover. Nothing depends on the movement — the card is a link
   whatever it does — so under reduced motion the colour simply changes at once. */
@media (prefers-reduced-motion:reduce){ .fits>a{transition:none} }

/* ── THE RECORD, MOVING — the three drawings below the hero, animated (2026-08-25) ──
   The operator asked for the static line diagrams under the hero to move: "those
   graphic, and line please animate it, or like those dots." What moves is ONE mark per
   drawing, travelling the drawing's own direction, and nothing else.

   SMIL, INLINE IN THE SVG, NOT JAVASCRIPT, for three reasons that each bite here:
     · it runs with scripting off, and qa/e2e/test_no_js.py loads every page that way;
     · smart-mill.html's four closed-loop step icons already animate this way
       (fx-plant.css § LOOP STEP ICONS), so this is the site's existing idiom rather
       than a second mechanism to maintain;
     · there is no scroll observer, no rAF loop and no replay control to keep alive.

   ONLY COLOURS ALREADY IN EACH DRAWING. The chain mark is --crude-amber, the same
   token as .cf-node, because the mark IS a record moving between the positions the
   nodes mark; the MyPalm stem that lights is --signal-gold, which is already the
   colour of the MyPalm wordmark two lines below it in the same figure. The mill map
   gets NO gold at all — .mm's own palette note above rules Signal Gold out of that
   drawing to keep Crude Amber inside its <=10% share, so both of its marks are
   --crude-amber and the two are told apart by TIME and DIRECTION, not by a colour.
   The credentials stack is a light-ground section drawn in literal hex, so its rising
   mark is #8A5E14, the AIREI amber already on the bus it is rising towards.

   THE MARKS ARE SMALLER THAN THE NODES THEY PASS (3.6 / 4.5 / 4 against 5 / 6 / 5.5).
   A mark the size of a station reads as a ninth station.

   NO LAYOUT CONSEQUENCE. Every element is a sibling inside an existing viewBox; no
   viewBox, width, height or CSS box changes, and `display` is the only property this
   block ever sets on them.

   REDUCED MOTION AND PRINT both remove the SMIL elements AND the marks themselves.
   Hiding the <animate*> elements is what stops SMIL — a media query cannot reach it —
   and that is fx-plant.css's idiom; hiding the mark as well means the resting state
   does not depend on SMIL semantics at all. On paper a mark caught mid-flight is a
   dot with no meaning, so print removes it for the same reason.

   REGISTERED: qa/motion-allow.json § smil declares the four carriers, the elements
   allowed, and a duration FLOOR and CEILING per carrier; qa/motion-lint.py rule SMIL
   fails the build on an unregistered carrier, a missing reduce rule, or a duration
   outside the registered band. That floor is what keeps this restrained: nothing on
   this page may be sped up to a flicker without the gate saying so. */
.cf-flow{fill:var(--crude-amber)}
.cf-reg{fill:none;stroke:var(--signal-gold);stroke-width:1.6;stroke-linecap:butt}
.mm .mm-flow,.mm .mm-return{fill:var(--crude-amber)}
.lyr-inst .cw-flow{fill:#8A5E14}

@media (prefers-reduced-motion:reduce){
  .chainfig animate,.chainfig animateMotion,
  .millmap animate,.millmap animateMotion,
  .stack animate,.stack animateMotion{display:none}
  .cf-flow,.cf-reg,.mm .mm-flow,.mm .mm-return,.lyr-inst .cw-flow{display:none}
}
@media print{
  .chainfig animate,.chainfig animateMotion,
  .millmap animate,.millmap animateMotion,
  .stack animate,.stack animateMotion{display:none}
  .cf-flow,.cf-reg,.mm .mm-flow,.mm .mm-return,.lyr-inst .cw-flow{display:none}
}

/* ── CLIENT WALL ─────────────────────────────────────────────────────────────
   Replaces the "Named clients available under NDA" line. These twelve marks are
   the ones AIREI publishes itself, on the "Our Clientele" page of its company
   profile — so printing them here adds no claim the client has not already made.
   Third-party marks are shown at their own proportions and never recoloured: a
   trademark redrawn to match a palette is a trademark misused. They sit on the
   light `paper` ground the section already uses, which is what they were drawn for. */
.clientwall{list-style:none;margin:10px 0 0;padding:0;
  display:grid;gap:22px 30px;
  grid-template-columns:repeat(auto-fill,minmax(112px,1fr));align-items:center}
.clientwall li{display:flex;align-items:center;justify-content:center;min-height:52px}
/* The wall's own two lines, 2026-08-26. They used to be one 62-word paragraph inside a
   closed fold titled "How to see the client list" — so the one sentence a mill owner can
   act on ("we will arrange a reference call") was the THIRD clause of an apology nobody
   opened. Split by job: the sourcing note is a micro line in the house telemetry voice,
   the offer is set at reading size in ink. `.src` is the 10.5px mono the stat band already
   uses; `--ink-ghost` is built for Deep Water and fails on Kernel White, so the paper
   ground takes #4C5A66 — the same substitution `.creds .fold` documents twenty lines up. */
/* 11px -> 12.5px, the `.stat .src` third pass in base.css. This one reads "Source — the
   client list AIREI publishes in its own company profile", 68 characters, and it is the
   line that qualifies the whole credentials wall. */
.creds .src{margin:14px 0 0;font-family:var(--f-mono);font-size:12.5px;letter-spacing:.02em;
  line-height:1.6;color:#4C5A66}
.creds .offer{margin:10px 0 0;color:#16202B}
.creds .offer b{font-weight:600}
/* OPTICAL AREA, NOT HEIGHT. A flat `max-height:46px` across aspect ratios from 4.74:1
   (United Plantations, a long wordmark) to 0.875:1 (PT Paluta Inti Sawit, a roundel) gives the
   wide mark 218px of width and the tall one 40px. Rendered box area, measured live at 1440px:
   Simpang Kanan 98x46 = 4,484px² down to PT Paluta 40x46 = 1,852px² — a 2.42x ink SPREAD
   across a row whose whole job is to say these twelve are equally customers. Every wall that
   reads as designed normalises optical AREA and lets height follow the mark's own proportion:
   h ~ sqrt(A/r) at A ~ 2,500px², quantised to the five bands below. Now 1.36x.
   THE TRADEMARKS ARE UNTOUCHED — the rule above ("their own proportions, never recoloured") is
   about hue and aspect and both survive: `width:auto;height:auto` keeps every ratio, nothing is
   recoloured, only the scale factor differs per mark, which is what a print art-director does
   by hand. Corrected while measuring, my own misreading: the four different top edges in row
   one are NOT a baseline defect — `align-items:center` aligns optical CENTRES (Sime Darby 26px,
   United Plantations 26px, PHWorld 25.5px), which is the right treatment. */
.clientwall img{display:block;width:auto;height:auto;max-width:100%;
  max-height:var(--lw-h,46px);object-fit:contain;
  /* the marks are full-colour on a near-white ground; a light desaturation keeps the
     row from out-shouting the page without altering any mark's hue */
  filter:saturate(.88)}
.clientwall .lw-4x{--lw-h:25px}   /* aspect >= 4.0  — long wordmark  */
.clientwall .lw-3x{--lw-h:29px}   /* 3.0 - 4.0                      */
.clientwall .lw-2x{--lw-h:36px}   /* 1.6 - 3.0                      */
.clientwall .lw-1x{--lw-h:43px}   /* 1.15 - 1.6                     */
.clientwall .lw-sq{--lw-h:50px}   /* < 1.15 — roundel / square      */
/* The tallest tier is 50px against the old flat 46px, so the row box grows by 4px. */
.clientwall li{min-height:56px}
/* TWELVE MARKS ARE 6x2 / 4x3 / 3x4, AND THE GRID SHOULD SAY SO. `auto-fill` picks the column
   count off the container width, which is how twelve lands as 7+5 (the live wall) or 5+5+2 (my
   first pass at this fix): at the wall's real container width, 846px at a 1440px viewport, a
   126px minimum track computes FIVE columns. Neither is a composition. The 6-up band starts at
   1100px because that is where the track finally clears the widest normalised mark (United
   Plantations, 25px x 4.74 = 118.6px); declaring six earlier just clamps it via
   `max-width:100%` and re-opens the spread (measured 4.37x at 820px). The gap tightens there
   for the same reason — 30px x 5 was spending 150px of an 846px row. */
@media (min-width:1100px){ .clientwall{grid-template-columns:repeat(6,1fr);gap:26px 18px} }
/* The 4-up band stops at 900px, not 640px, because the CONTAINER does not shrink with the
   viewport: `.creds` is a two-column dl above ~640px and stacks below, so the wall's measured
   width runs 723 -> 656 -> 544 -> 425 from 1099px down to 768px and JUMPS BACK to 576 at 640px.
   768px is the pinch; four columns there gave an 84px track that clamped the wide marks back to
   a 1.86x spread. Three columns hold 121.7px at that same pinch. Found by measuring every
   width — the container, not the viewport, is what the marks sit in. */
@media (min-width:900px) and (max-width:1099px){ .clientwall{grid-template-columns:repeat(4,1fr)} }
@media (max-width:899px){ .clientwall{grid-template-columns:repeat(3,1fr)} }
/* THE WALL IS NO LONGER TWELVE, AND SIX/FOUR/THREE ONLY DIVIDE TWELVE. The three counts
   above were chosen when both walls held twelve marks; the partner wall now holds NINE and
   the client wall SIXTEEN, and neither divides every band:
       partners  9   6-up 6+3 ok   4-up 4+4+1 ORPHAN   3-up 3+3+3 ok
       clients  16   6-up 6+6+4 ok 4-up 4+4+4+4 ok     3-up 3x5+1 ORPHAN
   Measured, then looked at: at 820px the client wall printed five rows of three and left
   the sixteenth mark hard against the left edge with two empty tracks beside it, which
   reads as a mark that failed to load rather than a wall that ran out.
   THE TRACK COUNTS ARE NOT TOUCHED — they were measured against the widest normalised mark
   and that argument still holds. A last row of ONE spans the row instead, so the lone mark
   centres under the row above. `.clientwall li` is already a centring flex box and
   `.clientwall img` is sized by `max-height`, never by its cell, so the mark does NOT grow:
   the cell widens, the trademark is identical, and nothing is captioned, named or tiered.
   Written against nth-child rather than a count, so it still holds when a mark is added. */
@media (min-width:1100px){ .clientwall > li:last-child:nth-child(6n+1){grid-column:1/-1} }
@media (min-width:900px) and (max-width:1099px){ .clientwall > li:last-child:nth-child(4n+1){grid-column:1/-1} }
@media (max-width:899px){ .clientwall > li:last-child:nth-child(3n+1){grid-column:1/-1} }
@media (max-width:560px){
  .clientwall{gap:18px 20px}   /* columns are declared in the 3-up band above */
  /* one scale factor, so the five tiers stay in proportion to each other on a phone
     instead of collapsing back to a single flat height */
  .clientwall img{max-height:calc(var(--lw-h,46px) * .82)}
}

/* ── THE PROOF BAND'S OWN BOX ──
   Dialled in the browser by point-at-it and baked into index.html as an inline
   <style id="tweak-baked">. qa/html-lint.py rejects an inline stylesheet on the one
   exemption it allows (a <noscript>-wrapped block), so the three declarations live
   here instead — same selector, same values, same cascade position (home.css already
   owns #proof's siblings), and now they travel with the theme port like every other
   rule rather than riding in the page head. */
#proof{margin-block:-34px;max-width:1350px;padding:44px}
/* 44px WAS DIALLED AT DESKTOP AND SHIPPED UNCONDITIONALLY. On a 390px phone it adds 88px to
   the 40px `.wrap` already carries, so the band's text column measured 262px inside a 390px
   screen — a THIRD of the phone given to margin, on the one band that carries the site's
   four result figures. Measured, then looked at: `.lede-2` ran 25.2ch over 13 lines, and
   four of the six mono labels broke early for want of ~30px ("WHAT COUNTS AS A / BREAKDOWN
   HOUR", "WHERE THIS FIGURE COMES / FROM", "WHO PUBLISHED THESE / FOUR NUMBERS", and the
   eyebrow itself). Every neighbouring section on the page gives its prose the full 350px.
   The band keeps its inset where there is room to spend: 44px above 900, tapering to the
   `.wrap` gutter alone on a phone, where a full-bleed paper band is the normal treatment
   and the 20px gutter is the page's own margin. Vertical padding is kept — it is what
   separates the band from the sections above and below, and it costs no measure.
   NOTHING ABOVE 900px MOVES, so the 1440px honesty measurement (qa/portrait-figure-gap.py)
   is unaffected by construction; re-run and confirmed identical regardless. */
@media (max-width:900px){ #proof{padding:38px 22px} }
@media (max-width:560px){ #proof{padding:32px 0} }

/* The trust-line phone link measured 120x17 at 390. Inline inside a sentence, so
   padding-block only: the hit box grows, the sentence does not reflow. */
@media (pointer:coarse){ .trust b a{padding-block:14px} }
