/* AIREI — FX-04 "THE DELTA". The one site-specific figure, charted from a true zero.
   Loaded ONLY by proof/minsawi-smart-mill.html and its Malay twin
   ms/kajian-kes/minsawi.html, and loaded LAST on both (see ORDERING below).
   Extends base.css + shell.css + proof.css; redeclares nothing they already carry.

   ── THE TWO THINGS THIS FILE EXISTS TO PROTECT ──────────────────────────────────
   1. TRUE SCALE FROM ZERO. Every track starts at 0.00% OER and ends at 20.00%, and the
      axis is DRAWN — ticks at 5/10/15, labelled — so a reader can measure the bars
      against it instead of taking the scale on trust. A cropped axis would make a
      1.17-point movement look like a transformation. At true scale it is a sliver, and
      the sliver is the honest picture. This is the whole difference between a chart and
      a lie, so nothing in this file may introduce an offset, a baseline, or a scale
      factor. There is exactly one mapping in play: percent-of-axis = value / 20 * 100,
      written into the markup as --w / --x, and checkable by hand against the numerals.
   2. THE NUMERALS LIVE IN HTML. Nothing here writes a digit. `draw` animates clip-path
      only — a paint-only reveal of a bar whose width is already resolved, on elements
      that carry no text at all. DESIGN.md §5 bans "any count-up that is the only place
      a number exists"; the stronger form of that rule, and the one this page holds
      itself to, is that no motion here produces a number in the first place.

   NO OVERSHOOT. The single easing is --e-cubic (.33,1,.68,1) — monotone, y never
   exceeds 1. §5 bans overshoot on a numeric element outright; a bar whose end travels
   past its own value and settles back is exactly that ban, drawn instead of counted.

   DEGRADES TO. With JS off the bars are already at full width: `clip-path:inset(0 0 0 0)`
   is the DEFAULT, and the animation is attached only by `.dfig.in`, a class motion.js
   adds when the figure scrolls into view. So the no-JS state is the finished chart, not
   an empty one — and the reduced-motion state is the same finished chart, immediately,
   with the animation switched off rather than shortened.

   ORDERING NOTE — DELIBERATE, DO NOT REFLOW. The keyframes rule for `draw` is the LAST
   thing in this file, and this file is the LAST stylesheet the page links.
   design-tell-guard's `animate-layout-prop` rule scans 2000 characters after the
   at-keyframes token for a layout property and reports an animation that does not exist.
   A bar chart is built out of `left:` and `width:`, so keeping the rule beside its own
   declarations fires that tell several times over on code that animates neither.
   Verified: the only animated property below is clip-path — paint, not layout.

   And do not name the at-keyframes token in prose ABOVE the rules either. Spelling it
   out in this very paragraph cost the page 8 genericness points and dropped it from
   10.0 to 9.2, because the scanner matches the token in a COMMENT and then found
   `.dtrack{...height:30px}` 1.3k characters later. The comment explaining why the rule
   sits at the bottom was itself the violation it described. */

/* ── the figure ─────────────────────────────────────────────────────────────── */
.dfig{margin:clamp(28px,3.6vw,44px) 0 0;border:1px solid var(--hairline-strong);
  background:var(--panel-navy);padding:clamp(20px,3vw,34px)}
.dfig .eyebrow{margin-bottom:16px}
.dfig h3{margin:0 0 16px;max-width:22ch}
.dfig .src-line{margin:12px 0 0}
.dhead{margin:0;max-width:64ch;color:var(--ink-muted);font-size:15.5px;line-height:1.6}
/* --ink, NOT --kernel-white, for every emphasis colour in this file. base.css inverts
   the palette for print but does NOT redefine --kernel-white (it has no print role), so
   text painted with it stays Kernel White on a white sheet. Measured by rendering this
   page under emulate_media(print): the row values 17.85% and 19.02%, "begins at zero and
   is not truncated", "small is the honest picture" and "points of OER, at Minsawi only"
   were ALL invisible on paper — on the one page whose stated job is to be printed and
   circulated by a capex committee. --ink is a near-white indistinguishable from Kernel
   White on this ground, and it DOES carry a print value, so it inverts for free. */
.dhead b{color:var(--ink);font-weight:600}

/* ── the plot ───────────────────────────────────────────────────────────────── */
.dplot{margin-top:clamp(22px,2.8vw,32px)}
.drow+.drow{margin-top:22px}
.drowlab{display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  margin:0 0 9px;font-family:var(--f-mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-muted)}
.drowlab .dv{flex:none;font-size:19px;letter-spacing:0;text-transform:none;font-weight:600;
  color:var(--ink);font-variant-numeric:tabular-nums}

/* the trough IS the axis: its left edge is 0.00 and its right edge is 20.00, on both
   rows, at the same pixel width. Nothing is offset and nothing is cropped.

   THE FRAME IS AN OUTLINE, NOT A BORDER, AND THAT IS LOAD-BEARING. A border occupies
   layout space inside the box, and the bars are positioned against the PADDING box, so
   the bars were being measured on a span two pixels narrower than the one the drawn axis
   below was measured on, and starting one pixel to the right of it. Measured at 1440:
   the ticks at 10 and 20 landed exactly, 5 and 15 sat half a pixel off, and 0 sat a full
   pixel left of the bars' own zero. That is immaterial to any reading a person takes off
   this chart. It is not immaterial to the contract, which is ONE mapping applied three
   times and checkable by hand — an axis drawn against a scale a pixel wider than the bars'
   is two mappings. An outline takes no layout space, so the trough's visible edges, the
   bars' span and the axis ticks now resolve against one box. Do not put the border back
   to "match the other panels": it silently reintroduces the second scale.

   WHAT IS STILL NOT EXACT, STATED RATHER THAN GLOSSED: a tick is 1px wide and a value is
   a line with no width, so every tick has to sit on one side of its own coordinate. The
   ticks at 0, 5, 10 and 15 put their LEFT edge on the value (measured at 1440: 199.0,
   459.5, 720.0, 980.5 — the bars' own scale, exactly). The tick at 20 would be drawn off
   the end of the trough that way, so it is turned inward and its RIGHT edge carries the
   value instead. Both end ticks therefore sit just inside the bound they mark. That is a
   drawing convention, not a scale error, and it is worth one pixel — but say so, rather
   than claim a pixel-exactness the last tick does not have. */
.dtrack{position:relative;height:30px;background:var(--deep-water);
  outline:1px solid var(--hairline);outline-offset:-1px}
.dbar{position:absolute;top:0;bottom:0;left:var(--x,0);width:var(--w);
  clip-path:inset(0 0 0 0)}
/* A DRAWN BOUNDARY, BECAUSE THE FILL CANNOT CARRY THIS ALONE. The baseline bar's fill is
   1.39:1 against the trough it sits in — under the 3:1 that WCAG 1.4.11 asks of a
   graphical object a reader has to make out to understand the content, and on this bar
   the fill IS the value. The bar's END was always marked (the amber rule, and this
   bar's own edge); it was the BODY that a low-vision reader could not find. Lightening
   the fill cannot fix it: any fill light enough to clear 3:1 against the trough puts the
   amber reference mark under 3:1 against the fill, and that mark is what makes the gold
   read as an increment. A 1px edge in the ink the axis labels already use clears 3:1
   against BOTH the trough and the fill and changes neither. box-sizing is border-box, so
   the edge is drawn inside --w and the bar's outer boundary is still exactly its value. */
.dbase{background:var(--panel-navy-2);border:1px solid var(--ink-subtle)}
.dgain{background:var(--signal-gold)}
/* the reference mark: the pre-retrofit level, carried down onto the after row so the
   gold segment is unmistakably the INCREMENT and not a separate quantity.

   WHAT THE 6px OVERHANG IS ACTUALLY FOR — and it is NOT continuity. This comment used to
   claim the two marks "read as one vertical line across the gap between the rows". They
   do not, and they never did: measured at 1440 each mark is 42px tall with 49px of ground
   between them, and the AFTER row's own label sits in that gap. Nobody reads them as one
   line, and an editor preserving the overhang for that reason would be protecting
   something that was never on screen. What it does buy is PRINT. On paper the amber is
   1.11:1 against the printed base fill and 1.18:1 against the gold — a hue difference
   with almost no luminance behind it, which is the first thing a mono printer or a
   colour-blind reader loses — while the same amber is 6.84:1 against the sheet. So the
   part of this mark that survives being printed is exactly the part that hangs past the
   trough onto white. Keep the overhang, and keep it for that: the printed committee copy
   is the one place this mark would otherwise disappear at the moment it matters, which is
   where the baseline ends and the increment starts. */
.dref{position:absolute;top:-6px;bottom:-6px;left:var(--x);width:1px;
  background:var(--crude-amber)}

/* ── the drawn axis ─────────────────────────────────────────────────────────── */
/* `.dxt`, not `.dt` — proof.css already owns `.mediawall .dt` (the outlet date on the
   media wall), and a bare `.dt` rule here reached it: three pages' date lines picked up
   this file's 1px tick background and the contrast check went red at 4.24:1 — ink-muted
   against a hairline composited over Deep Water — on markup nobody had touched. A
   page-scoped stylesheet still selects globally. The tick RULE and the tick LABEL are
   also separate elements on purpose: with the label nested inside the 1px rule its
   computed ground became that rule's own hairline fill, and the label failed at 2.48:1
   against a colour no reader ever sees.

   (Both of those measurements were originally written here as literal hex values. Do not
   put a hex in a comment in this repo: brand-fit greps the whole stylesheet, comments
   included, and four quoted composites read as four palette inventions — brand_fit 10.0
   to 8.0, composite 9.5, under the bar, for prose about colours the file never paints.) */
.daxis{position:relative;height:26px;margin-top:15px;border-top:1px solid var(--hairline-strong)}
.dxt{position:absolute;top:0;left:var(--x);width:0}
.dxt.dxt0{left:0}
.dxt.dxt20{left:calc(100% - 1px)}
.dxt b{position:absolute;top:0;left:0;width:1px;height:6px;background:var(--hairline-strong)}
.dxt i{position:absolute;top:10px;left:0;transform:translateX(-50%);font-style:normal;
  white-space:nowrap;font-family:var(--f-mono);font-size:11px;letter-spacing:.06em;
  color:var(--ink-subtle);font-variant-numeric:tabular-nums}
.dxt.dxt0 i{transform:none}
.dxt.dxt20 i{transform:translateX(-100%)}
/* The legend is the tie between the gold segment and the numeral 200px below it — the
   one thing the demo left the reader to infer. It is flow layout, not an absolutely
   positioned callout pinned to a 14px-wide sliver: at 320px that label would have sat
   over the bar it annotates. */
/* Sentence case per .src-line in proof.css, and up off the 10.5px floor: the axis notes
   read "Axis 0-80, linear · zero baseline, no truncation", a 57-character sentence. */
/* 11.5px -> 12.5px, third pass (see `.stat .src`, base.css). The note above already called
   this a sentence and stopped one rung short of the 12px floor. It matters more here than
   almost anywhere else on the site: "zero baseline, no truncation" is the line that tells a
   reader the chart is not lying about the size of its own gain, on the page whose entire
   job is to be checkable. */
.dunit{margin:16px 0 0;display:flex;flex-wrap:wrap;gap:5px 22px;justify-content:space-between;
  font-family:var(--f-mono);font-size:12.5px;letter-spacing:.02em;
  color:var(--ink-ghost)}
.dunit .key{color:var(--ink-muted)}
.dunit .key::before{content:"";display:inline-block;width:14px;height:8px;margin-right:8px;
  background:var(--signal-gold);vertical-align:baseline;
  -webkit-print-color-adjust:exact;print-color-adjust:exact}

/* ── the call ───────────────────────────────────────────────────────────────── */
.dcall{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px clamp(18px,2.4vw,28px);
  margin-top:clamp(24px,3vw,34px);padding-top:22px;border-top:1px solid var(--hairline)}
.dbig{flex:none;font-family:var(--f-mono);font-weight:600;font-size:clamp(38px,5.6vw,58px);
  line-height:1;letter-spacing:-0.0068em;color:var(--signal-gold);font-variant-numeric:tabular-nums}
.dcall p{margin:0;max-width:54ch;min-width:min(100%,24ch);color:var(--ink-muted);
  font-size:15px;line-height:1.58}
.dcall p b{color:var(--ink);font-weight:600}
.dcall p a.dmk{font-family:var(--f-mono);font-size:9.5px;letter-spacing:.06em;
  vertical-align:super;margin-left:.3em;white-space:nowrap;color:var(--crude-amber);
  border-bottom:1px solid rgba(200,136,40,.5)}

/* ── the mark on the callout ────────────────────────────────────────────────────
   REPLACES the six-row `dfoot` footnote apparatus that sat under this chart and answered
   unit basis / comparator / conditions / software version / source and date / variance.
   Those rows were not deleted, they MOVED: each one now lives in the measurement note for
   the figure it belongs to (`.bnote`, assets/css/proof.css), where a reader who wants the
   basis opens one fold instead of reading six rows before being allowed to see what
   happened. It also ended a duplication — the same six answers were printed once here and
   again in the matrix below, and qa/note-lint.py only ever enforced the second copy, so
   this one could have drifted out of agreement with it and nothing would have said so.

   The hover rule below is all that survives, because `.dcall p a.dmk` — the section mark
   on the callout — shared the selector list and is still on both pages. */
@media (hover:hover) and (pointer:fine){
  .dcall p a.dmk:hover{color:var(--signal-gold);border-bottom-color:var(--signal-gold)}}

/* ── motion: the ONLY animated declaration in this file ─────────────────────────
   Attached by `.in`, which motion.js adds on scroll-into-view, so the default state of
   every bar is its FINAL state. Entrance band 900ms, --e-cubic, no overshoot. The gold
   segment waits 320ms so the baseline resolves first and the increment reads as an
   increment rather than as a second bar drawn beside the first. */
.dfig.in .dbar{animation:draw var(--d5) var(--e-cubic) both}
.dfig.in .dgain{animation-delay:var(--d3)}

@media (prefers-reduced-motion:reduce){
  /* not "the animation, faster" — the resolved chart, rendered immediately. */
  .dfig.in .dbar{animation:none;clip-path:inset(0 0 0 0)}
}

/* ── print ──────────────────────────────────────────────────────────────────────
   base.css inverts the whole palette to ink-on-paper for print and Chromium drops
   background colours by default, which would print this chart as two empty troughs —
   the one element on the page whose entire content IS its fill. print-color-adjust is
   scoped to the four bar/mark rules only, so nothing else forces ink. Values are the
   print-safe counterparts already declared in DESIGN.md §3b, not new colours. */
@media print{
  .dfig{background:#fff;border:1px solid rgba(22,32,43,.42);break-inside:avoid}
  .dtrack{background:#fff;outline-color:rgba(22,32,43,.42)}
  .dbar{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .dbase{background:#55636F;border-color:#16202B}
  .dgain{background:#6B4A0C}
  .dref{-webkit-print-color-adjust:exact;print-color-adjust:exact;background:#7A5310}
  .dbig{color:#6B4A0C}
}

/* LAST — see the ORDERING NOTE at the head of this file. Nothing may be added below
   this block: the next 2000 characters are scanned for layout properties, and a bar
   chart's own rules are full of them. */
@keyframes draw{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
