/* ============================================================================
   fx-refine.css  GENERATED, DO NOT EDIT BY HAND.

   Source of truth is _refine/*.css. Edit a shard, then run:
       python3 tools/build-refine.py

   This is the LAST stylesheet the page loads, after styles.css, fx-type.css,
   fx-surfaces.css, fx-motion.css and fx-fixes.css. Its corrections win
   equal-specificity ties by source order, which is why no shard needs
   !important and none of them use it.

   Shards, in cascade order: 01-type.css, 02-chrome.css, 03-stand.css, 04-witness.css, 05-toys.css, 06-market.css, 07-archive.css, 08-plates.css, 09-receipts.css, 10-mobile.css
============================================================================ */


/* ==== 01-type.css =================================================== */
/* ============================================================================
   MOKI - _refine/01-type.css  (refine shard 01)
   Owns: the TYPOGRAPHY surface only. Headings, the eyebrow, measure, mono
   and numeral treatment, tracking, scale contrast. Applies across sections.

   Direction implemented: "The Printed Dossier". Type does the press work
   here: the eyebrow becomes a stamped plate-number strip instead of a rival
   headline, #name's heading steps down off the page's top rank, #witness's
   thesis sentence steps up into a deck line, and the market rail's numerals
   finally get the stat tier the token scale reserved for them, gated hard
   to real data states so nothing decorative ever renders big.

   Loads after styles.css, fx-type.css, fx-surfaces.css, fx-motion.css and
   fx-fixes.css, so equal-specificity ties resolve to this file by source
   order. Nothing here uses !important and nothing here animates: zero
   transitions, zero keyframes, zero motion properties. Every colour below
   is an existing token or a color-mix of two existing tokens, a pattern
   styles.css already established (#verify small).
   ========================================================================= */

/* ----------------------------------------------------------------------------
   1. THE EYEBROW AS PLATE STAMP
   (winner move "eyebrow as plate stamp"; answers the eyebrow/h3/h2 scale
   collision finding.)

   The eyebrow was set at --text-lg, the same clamp h3 uses, and could tie
   h2's floor at some widths, so the label tier was competing with the
   heading tier it exists to caption. Fixing the eyebrow's size, not the
   headings', is the press reading: a plate number on a printed sheet is
   small, tracked wide, and ruled, and it never argues with the title.

   The size is a fixed 11px on purpose, decoupled from the fluid clamp: a
   stamp does not scale with the page it is stamped on. That also retires
   the older finding about the fixed margin compressing against a fluid
   eyebrow, because the eyebrow is no longer fluid.

   width: fit-content, not inline-block: several eyebrows are grid items
   (#name's spans the full grid), and grid blockifies inline-block, which
   would stretch the rules to column width and turn the stamp into ruling.
   fit-content keeps the strip hugging its own text everywhere, so the
   treatment stays a mark, never wallpaper. */
.eyebrow {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  border-block: 1px solid var(--moki-rule);
  padding-block: var(--space-1);
  display: block;
  width: fit-content;
}

/* ----------------------------------------------------------------------------
   2. H3, A LABELED SUB-ENTRY, NOT A SMALLER H2
   (answers the "h1/h2/h3 differ by font-size alone" hierarchy finding.)

   With the eyebrow off --text-lg, h3 owns that step alone, but rank should
   never ride on size alone: an h3 inside a sticky archive card is read in
   isolation, with no h2 beside it to compare against. The hairline is the
   site's existing rule language (archive labels, receipts rows, verify
   entries), so a ruled top edge reads as "a filed sub-entry opens here".
   Where an .archive__label precedes the h3, its bottom rule and this top
   rule sit a beat apart, which is how a printed ledger double-rules the
   boundary between a tab and its entry, so the adjacency is kept, not
   suppressed. */
h3 {
  border-block-start: 1px solid var(--moki-rule);
  padding-block-start: var(--space-2);
}

/* ----------------------------------------------------------------------------
   3. #witness: THE THESIS GETS THE DECK LINE
   (graft from Direction 4, promotion side of the hierarchy-inversion
   finding: "#name's h2 silently claims the page's top type-scale step,
   outranking #witness's actual thesis heading".)

   "It does not blink for the camera." is the page's declared thesis
   (invariant 3 in the file's own terms), and it was sitting at the same
   --text-xl rank as every routine section heading. It steps up to
   --text-2xl here, but NOT in the house 900 weight: it takes the Fraunces
   Light Italic instance instead. That weight swap is the required
   differentiator (the veto on three unrelated elements converging on one
   token undistinguished): #name's demoted heading stays Black with CJK
   glyphs, the market digits are mono, and this line alone is the light
   italic deck. Three meanings, one token, three unmistakable voices.

   14ch caps the measure so the sentence breaks as a stacked pull-quote,
   not a long banner; the existing text-wrap: balance from styles.css
   balances the lines inside that cap. Light italic at display size wants
   no negative tracking and a touch more leading than the 900 headings'
   1.05, or ascenders collide across lines. */
#witness h2 {
  font-size: var(--text-2xl);
  font-weight: 300;
  font-style: italic;
  letter-spacing: 0;
  line-height: 1.12;
  max-width: 14ch;
}

/* ----------------------------------------------------------------------------
   4. #name: DEMOTED OFF THE PAGE'S TOP RANK
   (winner move "#name demotion"; answers the same hierarchy finding from
   the demotion side, and the mobile CJK-wrap finding below.)

   --text-3xl's own comment reserves it for "the wordmark, hero-scale
   marks", and no h1 exists, so #name was silently the loudest text on the
   page, louder than the thesis. --text-2xl keeps it visibly the biggest
   heading of any content section (every other section h2 is --text-xl)
   without inheriting the reserved top step. The glyph pair itself, kanji
   at full 900 ink weight beside Latin caps, is the heading's authored
   differentiator at this size, so no extra mark is added here. */
#name h2 {
  font-size: var(--text-2xl);
}

/* Mixed CJK + Latin + interpunct in one line follows two different
   line-break rulebooks, and balance cannot pick a safe break at phone
   widths at near-hero scale. On mobile the heading joins the h2 tier the
   rest of the page already uses there. */
@media (max-width: 767px) {
  #name h2 {
    font-size: var(--text-xl);
  }
}

/* ----------------------------------------------------------------------------
   5. #market: NUMERAL DISCIPLINE, THEN SIZE
   (graft from Direction 5, the tabular-nums cascade bug; winner move
   "ledger stat grid", the type half of it.)

   font-variant-numeric is inherited, but a value declared ON an element
   beats one inherited from an ancestor: every stat value sits in a <dd>,
   and fx-type's prose rule declares oldstyle proportional figures on dd
   directly, silently defeating the tabular figures the rail requested on
   the ancestor. Column alignment is the entire credibility of a ledger,
   so the data declaration lands on the dd itself. */
/* DEDUPED (coherence pass): 06-market.css authors the identical tabular
   figures fix on .market__cell dd. Column alignment is the credibility of a
   ledger and it is market data discipline, so it lives with the rail rather
   than in the cross-cutting type shard. */

/* The stat tier. --text-2xl's token comment names "big stat numerals" as
   its job and it had zero consumers; the page's most decision-relevant
   numbers were rendering at the same --text-sm as incidental mono chrome.

   HARD GATE, per the honesty spine and the explicit veto: this fires only
   on [data-state="live"] and [data-state="stale"], never on the "soon" or
   "loading" shells, so no value is ever sized like data before it IS
   data. And absences stay quiet: dd.is-missing is excluded, because an
   honest "Unavailable" printed at stat scale would give an absence the
   visual weight of a number, which is the exact decoration the spine
   forbids.

   dd.is-curve is excluded too, for the same reason via a second door.
   live.js's setVal() only flips .is-missing on its null branch; a
   bonding-curve pair (pump.fun, pre-graduation) is a real, non-null
   response, so it takes the text branch and paints "No pool yet" into
   .val with .is-missing never applied (live.js:395-404). Un-gated, that
   sentence is not a number, but sized at stat scale it reads as
   confidently as one, which is exactly the fake liveness the honesty
   spine forbids: the absence borrows the visual weight of data. live.js
   already marks this exact cell with .is-curve for its own purposes
   (live.js:401); this selector is the second consumer of that same
   class. */
#market[data-state="live"] .market__cell dd:not(.is-missing):not(.is-curve) .val,
#market[data-state="stale"] .market__cell dd:not(.is-missing):not(.is-curve) .val {
  font-size: var(--text-2xl);
  line-height: 1.1;
}

/* An absence must read differently from a value, or the "absent or true"
   promise is prose only. Oblique plus a muted step down, for both ways a
   cell can hold no number: dd.is-missing ("Unavailable", live.js's null
   branch) and dd.is-curve ("No pool yet", live.js's pre-graduation
   branch). The finding suggested --moki-rule for the mute, but
   rule-as-text measures ~1.6:1 on this ground (its own separate
   finding), and these words are honesty content, not decoration, so the
   mute is the 65% ink mix instead: the same formula family styles.css
   already uses for #verify small, held at a ratio that clears AA. */
.market__cell dd.is-missing .val,
.market__cell dd.is-curve .val {
  font-style: italic;
  color: color-mix(in srgb, var(--moki-ink) 65%, var(--moki-paper));
}

/* Rank inside the rail: caveats are real content but they are footnotes,
   and they were rendering at the same size and colour as the price. One
   step down plus the muted ink keeps them present, legible and visibly
   subordinate to the cells above them. */
#market .market__caption,
#market .market__venue,
#market .market__conc {
  font-size: var(--text-xs);
  color: color-mix(in srgb, var(--moki-ink) 65%, var(--moki-paper));
}

/* ----------------------------------------------------------------------------
   6. #verify: ENTRY TITLES YOU CAN SCAN
   (answers the "link-as-heading has no distinction" and the inverted
   title-to-body rhythm findings.)

   Each entry opens with a link that functions as its heading, but it
   inherited plain body weight, so the underline was the only cue for
   where a title ends and its description begins. Bold reuses the exact
   weight strong already declares, no new weight ships. inline-block lets
   the title carry its own explicit gap to the body, smaller than the
   body-to-caveat gap, restoring the title/body beat every heading on the
   page already keeps. The pending entries' mono spans are titles of their
   entries too, so they take the same gap, and the shipped Plex Medium
   instance instead of serif bold, so a not-yet-public entry never
   masquerades as a link. */
.verify__list a,
.verify__list .verify__pending {
  display: inline-block;
  margin-block-end: var(--space-2);
}
.verify__list a {
  font-weight: 700;
  text-decoration-thickness: 1px;
}
.verify__list .verify__pending {
  font-weight: 500;
}

/* ----------------------------------------------------------------------------
   7. MICRO-LABEL LEGIBILITY, DEDUPE NOTE (coherence pass)

   This section originally restated two fixes that belong to other shards'
   declared surfaces and had drifted out of sync with them:

     - .stand__caption (the exhibit-stamp caption line-break) is #stand's
       surface; 03-stand.css §3 ships the identical rule under its own
       ownership header. Two files independently authoring the same
       selector is harmless while the values match, but it is dead weight
       and a future edit to one copy silently stops matching the other.

     - .plate__no had been fixed here to a 65% ink mix while 08-plates.css
       §1 (the file that actually owns #plates and wins the cascade by
       loading later at equal specificity) fixed the same selector to 62%,
       matching 07-archive.css's directly-measured value for --text-xs
       mono on the --moki-blaze ground (~4.9:1). Both percentages clear
       AA, but shipping two different "correct" answers for one token's
       job is exactly the incoherence this pass exists to remove; 08-
       plates.css is the section owner and the rendered value, so it is
       the single source of truth here.

   Both rules are removed from this file; nothing in the page's paint
   changes, since 03-stand.css and 08-plates.css already render byte-
   identical layout and a corrected, AA-passing colour respectively. */


/* ==== 02-chrome.css ================================================= */
/* ============================================================================
   MOKI, refine shard 02: CHROME  (loads after styles.css and every fx-*.css,
   specificity ties resolve to this file, no !important needed anywhere)

   Owns: #nav (rail, drawer, mark, progress), the #tape ticker, #curtain,
   and the skip link. Nothing else.

   Direction: The Printed Dossier. The chrome is the file's index card and
   its filing stamps, so every fix here pulls the browser-default chrome back
   toward printed-ledger conventions: ink text with witness used as a MARK
   (a tick, a ring), never as text fill; controls that meet the same tap
   floor as the rest of the site; stamps that never overlap other stamps.

   Every rule traces to a named critic finding or an approved graft. No new
   hues, no new tokens beyond a fallback that mirrors the agreed
   --shadow-lift consolidation value.
   ========================================================================= */

/* ----------------------------------------------------------------------------
   1. NAV ACTIVE TICK
   Finding [high][colour]: fx-motion.css:228 sets the active rail link's TEXT
   to --moki-witness, which is ~1.8:1 on paper, the exact failure the token's
   own comment forbids ("never body text on paper"). Fix per the winning
   move: text stays full-contrast ink, witness moves to a 2px underline tick,
   which is squarely inside the token's documented job ("marks and lines
   only... the active nav tick").

   Finding [medium][motion]: the old tick snapped with zero motion right next
   to the continuously animating fill rail. The tick here is an absolutely
   positioned ::after revealed by clip-path, so the state change gets a
   whitelist-legal (clip-path) cue that matches the rail's continuity, and,
   because the element is out of flow, the veto about a border-block-end
   forcing reflow is satisfied by construction: zero layout impact.
--------------------------------------------------------------------------- */
.nav__rail a {
  position: relative; /* anchor for the tick, no layout change */
}

/* Beats fx-motion.css:228 by load order at equal specificity. */
.nav__rail a[aria-current="true"] {
  color: var(--moki-ink);
}

.nav__rail a::after {
  content: "";
  position: absolute;
  inset-inline: var(--space-3); /* aligns the tick with the label, not the tap box */
  /* Label is a ~23px line box centered in a 44px flex box, so its bottom
     edge sits ~10px up. 7px tucks the tick just under the baseline without
     touching the nav's bottom hairline. */
  inset-block-end: 7px;
  block-size: 2px;
  /* Colour is set once and never animated; only the clip-path reveal moves,
     which keeps colour outside the animated-property whitelist as specced. */
  background-color: var(--moki-witness);
  clip-path: inset(0 100% 0 0);
}
.nav__rail a[aria-current="true"]::after {
  clip-path: inset(0 0 0 0);
}
@media (prefers-reduced-motion: no-preference) {
  .nav__rail a::after {
    transition: clip-path var(--duration-fast) var(--ease-out-expo);
  }
}

/* ----------------------------------------------------------------------------
   2. NAV HOVER CASCADE
   Finding [medium][colour]: styles.css:393's ember hover and the active rule
   tie at (0,1,1) vs (0,2,1), so the active link never showed hover feedback.
   Ember stays exclusive to non-active links. The active link cannot take
   ember text: ember text directly above a witness tick would put the two
   accents adjacent inside one component, which the token block bans as a
   hard rule. Instead the active link's hover reaction is the tick itself
   pressing to ink, a colour snap (snaps are the file's documented rule for
   colour), which reads as the stamp taking the pointer's weight.
--------------------------------------------------------------------------- */
.nav__rail a:hover:not([aria-current="true"]) {
  color: var(--moki-ember);
}
.nav__rail a[aria-current="true"]:hover::after,
.nav__rail a[aria-current="true"]:focus-visible::after {
  background-color: var(--moki-ink);
}

/* ----------------------------------------------------------------------------
   3. DRAWER TAP TARGETS
   Finding [high][mobile]: the drawer's anchors are the ENTIRE mobile nav and
   ship with a bare ~26-29px line box, while .nav__rail a documents a 44px
   floor two selectors away. Same floor, same flex recipe, mirrored here.
--------------------------------------------------------------------------- */
.nav__drawer a {
  display: flex;
  align-items: center;
  min-height: 44px; /* §11.10 tap-target floor, matching .nav__rail a */
  padding-inline: var(--space-3);
}

/* ----------------------------------------------------------------------------
   4. DRAWER SHADOW, THE --shadow-lift CONSOLIDATION
   Graft (D3): the three hand-tuned lifted-plate shadows (.witness__crop img,
   .nav__drawer, plates) collapse into one signature. The surfaces shard owns
   declaring --shadow-lift; this shard consumes it for the drawer. The
   fallback is the agreed consolidated value (ink 21,19,15, not a new hue),
   so the drawer cannot regress to shadowless if shards land out of order.
--------------------------------------------------------------------------- */
.nav__drawer {
  box-shadow: var(--shadow-lift, 0 20px 40px -28px rgba(21, 19, 15, 0.3));
}

/* ----------------------------------------------------------------------------
   5. #curtain MOVES TO THE EMPTY CORNER
   Finding [medium][stand]: at first paint the curtain stamp (fixed, z 50,
   bottom-left) sits directly on top of #stand's Exhibit 01 stamp (absolute,
   bottom-left), two filing stamps fighting for one corner during the page's
   very first impression. The exhibit stamp owns bottom-left for the whole
   pinned run; the curtain takes bottom-right, which nothing occupies at
   load. The wipe/fade keyframes are clip-path plus opacity with no
   horizontal directionality, so relocation changes nothing about the motion.
--------------------------------------------------------------------------- */
#curtain {
  left: auto;
  right: var(--space-5);
}

/* ----------------------------------------------------------------------------
   6. SKIP LINK
   Invariant 7 (keyboard reachable, visible focus) plus the [medium][a11y]
   skip-link finding. No stylesheet styles .skip-link at all today, so it
   paints as a visible serif text line sitting above the masthead on every
   load, chrome that was never designed. Standard dossier treatment instead:
   parked off-canvas by transform (never display:none, it must stay first in
   tab order), and on keyboard focus it drops in as a stamped mono control
   above the nav. No transition: it appears the way the site's colour states
   do, as a snap, so there is nothing to reduced-motion-gate.
--------------------------------------------------------------------------- */
.skip-link {
  position: fixed;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: var(--z-stamp); /* above the sticky nav it exists to bypass */
  padding: var(--space-2) var(--space-3);
  background-color: var(--moki-paper);
  color: var(--moki-ink);
  border: 1px solid var(--moki-ink);
  box-shadow: 0 3px 0 var(--moki-ink); /* the site's one pressable-plate language */
  font-family: "IBM Plex Mono", "Plex Mono Fallback", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  /* Parked: fully off the top edge, out of paint but in tab order. */
  transform: translateY(calc(-100% - var(--space-4)));
}
.skip-link:focus {
  transform: none;
}

/* ----------------------------------------------------------------------------
   7. #tape PAUSE CONTROL (CSS-only wire)
   Finding [medium][a11y]: a 36s infinite marquee with no user-operable pause
   fails WCAG 2.2.2; hover and tab-visibility are not controls. JS edits are
   vetoed this pass, so the wire is a native checkbox plus :has(), zero
   script. The orchestrator inserts the input and label (see markup request);
   this shard makes them work and keeps them honest:
     - hidden without JS (no clone means no animation, nothing to pause)
     - hidden under prefers-reduced-motion (fx-motion already parks the tape
       as a static scrollable row, nothing to pause)
     - hidden where :has() is unsupported (a control that cannot function
       must not render, per the honesty spine)
   Checked state inverts to ink exactly like .kit__lock[aria-pressed="true"],
   the site's existing engaged-control surface swap.
--------------------------------------------------------------------------- */
.masthead {
  position: relative; /* anchor for the pause control; .masthead has no other rules anywhere */
}

/* Off unless every precondition for a running marquee holds: previously only
   the LABEL was gated here, which left the checkbox itself (position:
   absolute, never display:none) as a real, unlabeled, focusable tab stop
   whenever JS was absent, reduced-motion was on, or :has() was unsupported.
   A keyboard/AT user would land on a nameless control that does nothing,
   which is exactly the "must not render" failure the honesty spine forbids.
   Both the input and its label now share the same off-by-default rule, and
   only the gated block below (identical preconditions) restores either. */
.tape__pause,
.tape__pause-label { display: none; }

@media (prefers-reduced-motion: no-preference) {
  @supports selector(:has(*)) {
    /* Visually hidden input, restored to the DOM/tab order only now that it
       can actually do something; native checkbox semantics carry the
       pressed state to assistive tech for free. */
    html.js .tape__pause {
      display: inline-block;
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }

    /* SUMMONED, NOT PARKED. Looked at on a real page, an always-visible
       paper chip pinned over the right end of the ticker sat ON TOP of the
       running text and sliced a case note mid-word, every second, forever.
       A control that permanently damages the thing it controls is worse
       than the problem it solves.
       So it rests at zero and arrives on hover or keyboard focus anywhere in
       the masthead. WCAG 2.2.2 asks for a mechanism to pause, not for that
       mechanism to be permanently on screen; this is the same contract the
       skip link already runs on, and the tape stops the moment the pointer
       is over it anyway (fx-motion's own hover rule), so a visitor reaching
       for this has already frozen the text they are reading. */
    html.js .tape__pause-label {
      display: inline-flex;
      align-items: center;
      min-height: 44px; /* §11.10 tap-target floor, it is a control */
      padding-inline: var(--space-3);
      position: absolute;
      inset-inline-end: var(--gutter);
      inset-block-start: 50%;
      transform: translateY(-50%); /* static centering, not motion */
      z-index: 1; /* above the tape strip it governs */
      opacity: 0;
      pointer-events: none; /* invisible must also mean unclickable */
      transition: opacity var(--duration-press, 60ms) linear;
      background-color: var(--moki-paper);
      color: var(--moki-ink);
      border: 1px solid var(--moki-rule);
      font-family: "IBM Plex Mono", "Plex Mono Fallback", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
      font-size: var(--text-xs);
      letter-spacing: 0.08em; /* matches .tape__group span so it reads as tape chrome */
      text-transform: uppercase;
      cursor: pointer;
    }

    /* Summoned by pointer, by keyboard, or by being already engaged: a
       visitor who paused the tape must be able to see how to unpause it. */
    html.js .masthead:hover .tape__pause-label,
    html.js .masthead:focus-within .tape__pause-label,
    html.js .tape__pause:checked ~ .tape__pause-label {
      opacity: 1;
      pointer-events: auto;
    }

    /* Engaged: ink inversion, the .kit__lock pressed-surface pattern. */
    html.js .tape__pause:checked ~ .tape__pause-label {
      background-color: var(--moki-ink);
      color: var(--moki-paper);
      border-color: var(--moki-ink);
    }

    /* The actual pause. Same play-state mechanism fx-motion already uses
       for hover and data-paused, just driven by the checkbox. */
    .masthead:has(.tape__pause:checked) .tape__track {
      animation-play-state: paused;
    }
  }
}

/* Focus ring lands on the visible label, not the hidden input. Witness ring
   per the sitewide contract; the label is paper and ink so the two accents
   never meet in this component. */
.tape__pause:focus-visible ~ .tape__pause-label {
  outline: 2px solid var(--moki-witness);
  outline-offset: 2px;
}


/* ==== 03-stand.css ================================================== */
/* ============================================================================
   REFINE SHARD 03 · #stand · THE STANDING FRAME
   Direction: "MOKI: The Printed Dossier" (press/ledger elevation pass).
   Owns: the dark hero only. Loads after styles.css and every fx-*.css, so
   equal-specificity ties resolve to this file by order. No !important needed.

   HARD LINE, restated because it is the thesis: .stand__cat and .stand__eyes
   get ZERO rules here. The cat never animates, never transforms, never fades.
   Everything in this shard paints or places the world AROUND him.

   Both JS tickets this shard originally deferred have since landed in app.js,
   and section 5 below is the CSS half of the first one:
   - activateExhibit() now publishes data-exhibit onto #stand, which is what
     lets the wash below exist at all.
   - activateExhibit() now toggles aria-hidden on the four inactive stamps, so
     a screen reader stops reciting all five captions as one paragraph.
============================================================================ */

/* ----------------------------------------------------------------------------
   1. THE CAT'S WIDTH CEILING (critic: [medium][mobile] --stand-cat-h has no
   viewport-width term, so tall-aspect phones let the rendered width pass
   100vw and .stand__pin's overflow:clip silently eats his paws and tail).
   The photograph losing limbs to an unannounced crop argues against the
   stillness thesis, so the height now also answers to width: 0.529 is the
   measured source ratio (658 / 1244, assets/manifest.json), and 92vw keeps
   a small safe margin inside the pin. The eye band derives all of its own
   math from this same variable, so it re-aligns for free; the two measured
   source-px origins in styles.css stay untouched.
   Declared twice, exactly like styles.css does it: the plain-vh rule first,
   then the svh upgrade, so this shard does not accidentally strip the
   URL-bar-collapse stability the original @supports block bought.
--------------------------------------------------------------------------- */
:root {
  --stand-cat-h: min(84vh, calc(92vw / 0.529), 70rem);
}
@supports (height: 1svh) {
  :root {
    --stand-cat-h: min(84svh, calc(92vw / 0.529), 70rem);
  }
}

/* ----------------------------------------------------------------------------
   2. MID-PLANE PAINT (critic: [high][stand] the mid plane moves but paints
   nothing, so the 3-layer depth system is really 1 layer; graft approved
   from Directions 1/2). A fine scan-line ruling in the plane's own inherited
   ink (--moki-line-void via currentColor, faded further so it stays a wash,
   never a rule you could write on). The pitch is --space-2, deliberately
   far from the ledger texture's 2rem pitch: this must read as photographic
   grain crossing the frame under parallax, not a second ledger. Static
   texture only; the 14 percent translate that makes it mean something is
   fx-motion's existing keyframe, untouched.
   Where this plane is display:none (reduced motion, and mobile via the
   existing 767px rule) the paint goes with it, which is correct: parked,
   the lines are noise.
--------------------------------------------------------------------------- */
/* TUNED AFTER LOOKING AT IT ON A REAL SCREEN. The first pass shipped 55
   percent of the plane's ink at a --space-2 pitch, and that is not grain, it
   is a CRT: hard horizontal banding across the full bleed, competing with the
   one photograph this section exists to show. The brief for this plane was
   depth, not texture as a feature. Down to 22 percent at a --space-3 pitch,
   which still reads as a surface when it slides under parallax and disappears
   when it is still. Rule of thumb for anyone retuning it: if you can see the
   lines without looking for them, it is too strong. */
.stand__plane--mid {
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 calc(var(--space-3) - 1px),
    color-mix(in srgb, currentColor 22%, transparent)
      calc(var(--space-3) - 1px) var(--space-3)
  );
}

/* ----------------------------------------------------------------------------
   3. STAMP CAPTION BREAK (critic: [medium][stand] "EXHIBIT 01 · DUSK" runs
   inline into its sentence-case caption with no structural break). The
   stamp was always two registers, a case-index line and a narrative note;
   giving the caption its own line lets a reader parse the index before the
   sentence, which is how a real evidence stamp is set. fx-type.css already
   un-uppercases the caption; this only adds the line break and one breath
   of space. No motion, so the print-wipe clips the whole taller stamp
   exactly as before.
--------------------------------------------------------------------------- */
.stand__caption {
  display: block;
  margin-block-start: var(--space-1);
}

/* ----------------------------------------------------------------------------
   4. CURTAIN CORNER DE-COLLISION, DEDUPE NOTE (coherence pass)

   This shard's header claims "the dark hero only," but #curtain is global
   chrome (it sits above every section, not inside #stand), and this file
   shipped the exact same fix (left: auto; right: var(--space-5);) as
   02-chrome.css §5, which explicitly declares #curtain as one of its owned
   selectors. Two shards independently spotted and fixed the same first-
   paint stamp collision without knowing about each other; the values were
   already identical so nothing rendered incorrectly, but per this section's
   own stated scope the rule belongs in 02-chrome.css alone. Removed here;
   see 02-chrome.css §5 for the fix and its rationale.
--------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------------
   5. THE LIGHTING ARC (completeness critic, ranked #2 of the whole pass:
   "your hero does not tell the story it promises").

   The five exhibit stamps are labelled DUSK, PERIMETER, NIGHT, LEDGER and
   DAWN. That is a promise about light, and nothing on the page was keeping
   it: the three parallax planes only translated, so the entire pinned run
   was shot under one bulb and the labels were text-only cosplay of a
   lighting change that had never been built. On a page whose whole argument
   is that it does not claim what it cannot show, that gap was not a missing
   flourish, it was a small lie in the loudest section.

   NO NEW HUE ENTERS. Every step below is --moki-void with a few percent of a
   token that already exists, so the arc is the palette doing work rather
   than a second palette: ember for the last warmth of dusk, nothing at all
   for night, witness for the instrument light of the ledger, paper for the
   neutral lift of dawn. The percentages are deliberately small. This should
   read as the same room at five different hours, not as five colours.

   THE CAT IS NOT TOUCHED. .stand__cat and .stand__eyes get no rule here and
   never will. The light around him changes; he does not. That is the thesis,
   and an arc that dimmed or warmed the photograph itself would break it far
   more expensively than a flat background ever did.

   background-color, not opacity on an overlay: the property audit in
   fx-motion.css bans layout-bound properties (width, height, top, left,
   margin, padding, border-width) and this is none of them. It is a paint,
   it composites cheaply on a single full-bleed element, and doing it with a
   real overlay would have cost a markup element that carries no meaning.
--------------------------------------------------------------------------- */
#stand {
  /* The pre-JS and no-JS value stays exactly what styles.css:415 paints, so
     a visitor without scripts sees the section as it always was, not as a
     half-lit accident. */
  transition: background-color 900ms var(--ease-out-expo, ease);
}

#stand[data-exhibit="1"] { background-color: color-mix(in srgb, var(--moki-ember)   6%, var(--moki-void)); }
#stand[data-exhibit="2"] { background-color: color-mix(in srgb, var(--moki-ember)   3%, var(--moki-void)); }
#stand[data-exhibit="3"] { background-color: color-mix(in srgb, var(--moki-ink)    30%, var(--moki-void)); }
#stand[data-exhibit="4"] { background-color: color-mix(in srgb, var(--moki-witness) 5%, var(--moki-void)); }
#stand[data-exhibit="5"] { background-color: color-mix(in srgb, var(--moki-paper)   7%, var(--moki-void)); }

/* Reduced motion keeps the arc but drops the fade: the five states are
   information (which exhibit you are in), not decoration, so removing them
   would remove meaning. Only the crossfade goes. */
@media (prefers-reduced-motion: reduce) {
  #stand { transition: none; }
}


/* ==== 04-witness.css ================================================ */
/* ============================================================================
   MOKI - _refine/04-witness.css  (refine shard 04)
   OWNS: #witness (the eyes, §5.5) and #name (honest etymology, §5.6).
   Nothing else. Other shards own the other sections; this file never
   targets a selector outside these two surfaces.

   DIRECTION: "The Printed Dossier". Ink density, ruled-ledger conventions
   and deliberate breath do the hierarchy work here; zero new hues, zero new
   motion. This sheet loads after styles.css and every fx-*.css, so
   equal-specificity ties resolve to this file by source order alone.
   No !important anywhere; none is needed.

   Every rule traces to the agreed move list or a ranked critic finding:
     1. rhythm     - #witness carries the page's one escalated breath out of
                     #stand's dark register (the "escalating plate breath"
                     move; --space-8 finally gets a job).
     2. hierarchy  - the thesis line ("It does not blink for the camera.")
                     is already this section's h2 in shipped markup, so the
                     D4 pull-quote graft lands on the heading itself: deck
                     scale, narrow measure, no markup change needed.
     3. hierarchy  - #name's h2 hands --text-3xl back to the reserved
                     hero/wordmark tier and steps down to --text-2xl (the
                     top-ranked finding: etymology must not outrank the
                     thesis).
     4. depth      - the glyph pair gets the stamped-exhibit hairline
                     (.archive__label's own pattern), which doubles as the
                     trio differentiator the veto list demands now that
                     #name, the witness deck and #market's live digits all
                     sit at or near one size token: #name is the one marked
                     by a rule, not by size alone.
     5. surfaces   - the legally load-bearing disclosure paragraph gets the
                     existing ledger ruling at receipts strength, and the
                     lede gets a larger trailing beat before the register
                     shifts into it.
     6. grafts     - the witness crop takes --radius-lg (its documented,
                     currently dead "big photo plates" tier) and the shared
                     --shadow-lift signature, consumed via var() with the
                     agreed value as fallback so whichever shard declares
                     the token wins with no collision here.

   Explicitly NOT here, per the veto list: no viewfinder corner brackets on
   .witness__crop (that technique is vetoed outright), no hand-typed
   "PL. 02" plate-mark span (static ordinals are vetoed; sequence numbering
   is a CSS-counter job at page level, not a per-section shard's), no
   .eyebrow restyle (global type, owned elsewhere), no JS, and no new
   animation of any kind. Everything below is static paint and static
   layout, so there is nothing to gate behind prefers-reduced-motion.
   ========================================================================= */

/* ----------------------------------------------------------------------------
   1. #witness - the exit from the dark register gets more air.
   The handoff from the pinned void of #stand to the paper case file is the
   page's single true scene change, and it was getting the same breath as
   every routine paper-to-paper seam. A printed dossier paces its plates
   unevenly: the scene change earns the extra measure. --space-8 (4rem) was
   declared and consumed nowhere; this is its documented job. Padding is
   static layout, never animated, so it is safe outside fx-motion.
--------------------------------------------------------------------------- */
#witness {
  padding-block-start: calc(var(--space-section) + var(--space-8));
}

/* ----------------------------------------------------------------------------
   2. The thesis, promoted. "It does not blink for the camera." is invariant
   #3 stated in copy, and until now the loudest text on the page was #name's
   etymology heading. Fixing that from the demotion side alone (below) still
   leaves the thesis at the same rank as every routine section title, so the
   D4 graft promotes the right sentence too: deck scale, and a hard 14ch
   measure so it breaks as a stacked claim, not a long title. text-wrap:
   balance from the base h2 rule keeps the short lines even. No secondary
   mark is added HERE on purpose: the veto only requires one of the three
   --text-2xl tenants to carry a differentiator, and #name's hairline stamp
   (section 3) is it; a second corner-mark grammar on this heading would be
   exactly the uniform-treatment wallpaper the anti-slop rule bans.
--------------------------------------------------------------------------- */
/* DEDUPE NOTE (coherence pass): 01-type.css §3 already sets this exact h2
   to --text-2xl at max-width: 14ch, plus the light-italic deck weight this
   file never declared (font-weight/font-style/letter-spacing/line-height).
   This file's header claims exclusive ownership of #witness, which turned
   out to be false once 01-type.css's cross-section typography pass landed
   the same promotion; rather than ship the size on two selectors (one
   using max-width, one max-inline-size, two different properties that only
   coincidentally agree in this LTR-only page), the scale lives solely in
   01-type.css, the file that also carries the differentiator weight. */

/* ----------------------------------------------------------------------------
   3. #name - demoted heading, stamped glyph pair.
   --text-3xl is documented as "the wordmark, hero-scale marks" and #name was
   its only borrower, silently outranking the thesis. --text-2xl keeps this
   the loudest heading of any content section (every other h2 sits at
   --text-xl) without inheriting the page's absolute top rank, which returns
   to reserved-but-intentional.

   The hairline under the glyph pair is .archive__label's own pattern
   (padding then a 1px --moki-rule block-end), so the pair reads as a
   stamped exhibit label rather than a stray oversized heading. This rule
   is also the deliberate differentiator between the three unrelated
   --text-2xl tenants (witness deck, this heading, #market's live digits):
   #name is the one that carries a rule, so the shared size step reads
   authored, not accidental. #name's grid gives the h2 align-items: start,
   so the box hugs its content and the hairline sits directly under the
   glyphs, not at the bottom of the spanned rows.
--------------------------------------------------------------------------- */
/* font-size: var(--text-2xl) is owned by 01-type.css §4 (same coherence
   note as #witness h2 above). This file adds only the hairline stamp,
   its unique contribution and the trio differentiator itself. */
#name h2 {
  padding-block-end: var(--space-3);
  border-block-end: 1px solid var(--moki-rule);
}

/* ----------------------------------------------------------------------------
   4. The disclosure as filed evidence. This paragraph makes the riskiest
   claim on the page (the name is our reading, not an attested compound) and
   was visually indistinguishable from filler prose. The site already has
   exactly one "this is a documented claim" texture: --surface-ledger.
   Consumed here at the same faint 28% ink already proven on .receipts__list,
   so the formula count stays at one and the ruling reads as paper grain
   under the admission, never competing with the text. Inline padding pulls
   the prose off the texture's edge so it reads as set ON the ruled page,
   not butted against it. The paragraph stays Georgia prose: the veto list
   is explicit that voice-driven copy must not be flattened into a mono
   data register.
--------------------------------------------------------------------------- */
.name__disclosure {
  --ledger-ink: color-mix(in srgb, var(--moki-rule) 28%, transparent);
  background-image: var(--surface-ledger);
  padding: var(--space-4);
}

/* The register shift into the disclosure gets its own beat. The generic
   p + p gap (--space-4) treated the lede-to-legal transition like any other
   paragraph break; --space-6 marks the tone change. Adjacent block margins
   collapse, so the rendered gap is exactly 2rem, not 3. */
.name__lede {
  margin-block-end: var(--space-6);
}

/* ----------------------------------------------------------------------------
   5. The witness crop joins the top of the object hierarchy.
   --radius-lg was declared with the comment "for the big photo plates" and
   consumed nowhere; the most prominent photograph outside #stand was sitting
   at the same corner weight as an ordinary text card. The shadow moves onto
   the shared --shadow-lift signature (the D3 consolidation graft): consumed
   via var() with the agreed value as the fallback, so if the shard that owns
   the token declaration ships it, that single source wins, and if not, this
   surface still renders the agreed depth. The fallback's rgba is --moki-ink
   at low alpha, the exact convention every existing lifted shadow already
   uses; no new hue is introduced. The plate-turn reveal animates this img's
   opacity and scale in fx-motion; radius and shadow are static and ride
   along untouched.
--------------------------------------------------------------------------- */
.witness__crop img {
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift, 0 20px 40px -28px rgba(21, 19, 15, 0.3));
}

/* ----------------------------------------------------------------------------
   6. MOBILE, DEDUPE NOTE (coherence pass). This file shipped its own
   max-width: 767px step-down for #name h2 to --text-xl, for the same
   CJK-wrap reason documented in 01-type.css §4 and restated defensively
   in 10-mobile.css §2 (the file whose declared job is owning every
   responsive correction on the page). Three shards independently landing
   the identical breakpoint override is the redundancy this pass exists to
   flag; 10-mobile.css is the correct single owner going forward (it loads
   last by contract and already states the override "wins either way"), so
   it is removed here. The witness deck keeps --text-2xl on phones
   deliberately: its 14ch measure already controls the wrap, and the
   thesis staying the loudest text on the page is the point of the fix.
--------------------------------------------------------------------------- */


/* ==== 05-toys.css =================================================== */
/* ============================================================================
   REFINE SHARD 05 · #toys / Night Rounds
   Owns: the #toys section shell internals, the .toy plate, the wake-meter toy.
   Direction: "MOKI: The Printed Dossier" - this shard implements the #toys
   moves only: the two-column desk layout (critic: #toys is the one content
   section with no considered grid), the photo/controls seam (critic: figure
   and panel fuse with zero divider), the --moki-fail token split (graft from
   Directions 3/5, veto-mandated: --moki-alert must go back to its one
   documented job in #market), and the ember-CTA focus-ring fix (graft from
   Direction 2: witness ring around an ember fill puts the two accents
   adjacent, which §2's own hard rule forbids).
   Loads after styles.css and every fx-*.css file, so equal-specificity ties
   resolve to this shard by order. No !important anywhere.
   Out of scope, logged not shipped: the new-best flash (low/motion finding)
   requires a class toggle in game.js, and JS edits are vetoed this pass.
============================================================================ */

/* ----------------------------------------------------------------------------
   1. TOKEN SPLIT - the fail flash stops spending --moki-alert.
   styles.css:38 scopes --moki-alert to "negative price delta ONLY, inside
   #market only. Never decorative." Its only real consumer today is the #toys
   fail flash (fx-motion.css:441), which is exactly the decorative use the
   comment forbids, and it blocks #market's shard from wiring the token to
   .is-down without diluting its meaning. The split is semantic, not chromatic:
   --moki-fail carries the identical hex, so no new colour enters the palette.
   It is game-feedback red, declared on #toys so it can never leak into a
   section that did not ask for it. If --moki-alert's hex ever changes, change
   this one in the same commit; they are the same pigment with two names.
--------------------------------------------------------------------------- */
/* COLLAPSED: this shard declared a --moki-fail token whose value was the
   literal hex of --moki-alert, so the flash could avoid "using" --moki-alert
   outside #market. It changed nothing on screen and created one hex to keep
   in sync forever. fx-motion.css:441 already paints this overlay with
   var(--moki-alert), and fx-motion.css:16 names the game's fail flash as an
   explicit exemption from the #market-only rule, so the purity problem the
   token solved was not real. The rule below now names the token directly. */

/* Repoint the flash overlay. Same selector as fx-motion.css:437, so this
   shard's later position in the cascade wins the background-color; the
   overlay's geometry, its steps(2) animation, and its reduced-motion kill
   switch (fx-motion.css:549) all stay exactly where they are. */
.toy__figure::after {
  background-color: var(--moki-alert);
}

/* ----------------------------------------------------------------------------
   2. THE DESK LAYOUT - #toys stops being the page's one un-gridded section.
   Critic (medium/art-direction): #witness runs a 12-column overlap, #name a
   5fr/7fr split, #plates a real contact sheet, and #toys stacks a 658x1244
   portrait straight on top of its control panel as default block children.
   The fix is the unequal two-column split the finding prescribes: the
   evidence photo in the narrower column, the procedural controls in the
   wider one, collapsing back to a stack below the site's one 767px
   breakpoint. Mobile-first: the base rules ARE the collapsed state, so no
   max-width query has to un-write anything.
--------------------------------------------------------------------------- */

/* The panel's internal rhythm. Critic (medium/depth): under the global
   * { margin: 0 } reset, only the two status <p>s get any separation (the
   generic p + p rule); Start, the meter, and the status line run flush.
   A grid gap paces all of it with one value instead of per-child margins.
   align-content: start keeps the short panel from stretching its rows when
   it sits beside the tall photo at desktop widths. */
.toy__panel {
  display: grid;
  gap: var(--space-4);
  align-content: start;
}

/* Grid gap does not collapse an item's own margin the way flow-layout
   sibling margins collapse into one another: styles.css:263's global
   `p + p { margin-block-start: var(--space-4) }` still fires on the
   .toy__status/.toy__best pair (they are adjacent <p> siblings), and that
   margin stacks ON TOP of the grid gap instead of being absorbed by it -
   without this reset, that one transition would render at 2rem while every
   other row in the panel sits at the intended 1rem, reintroducing exactly
   the uneven rhythm this shard exists to fix. Zero it out so gap is the
   single source of spacing inside the panel, as the rule above intends. */
.toy__panel p + p {
  margin-block-start: 0;
}

/* Grid items stretch by default, which would inflate the two buttons to
   full column width and break the pressable-plate read (a button-shaped
   plate, not a banner). Pin just the buttons back to content width; the
   meter row keeps the stretch because its <progress> is width:100% of it. */
.toy__panel .toy__start,
.toy__panel .toy__share {
  justify-self: start;
}

/* The seam. Critic (medium/depth): everywhere else the page marks a
   photo-to-text transition with a rule (.archive__label's underline,
   .kit__row's hairlines, #receipts' row rules); the toy plate is the one
   place two very different content types touch with nothing between them.
   Base = stacked mobile state, so the seam is horizontal here and rotates
   to vertical inside the desktop query below. */
.toy__panel {
  margin-block-start: var(--space-5);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--moki-rule);
}

@media (min-width: 768px) {
  .toy {
    display: grid;
    /* 1fr / 1.4fr: the unequal ratio language #name already established,
       photo narrow, panel wide, per the finding's own prescription. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    column-gap: var(--space-6);
    align-items: start;
  }

  /* Rotate the seam: side by side now, so the hairline stands between the
     columns instead of under the photo. The block-start seam is explicitly
     zeroed or the mobile rule above would ghost a second divider in. */
  .toy__panel {
    margin-block-start: 0;
    padding-block-start: 0;
    border-block-start: 0;
    padding-inline-start: var(--space-6);
    border-inline-start: 1px solid var(--moki-rule);
  }
}

/* ----------------------------------------------------------------------------
   3. FOCUS ON THE EMBER CTA - keep witness and ember out of one component.
   Graft (Direction 2) + critic (medium/coherence): the sitewide
   :focus-visible ring is --moki-witness (styles.css:234), and .toy__start is
   one of the page's two ember-filled elements, so tabbing to Start drew the
   cool accent directly around the warm one, the exact adjacency §2's hard
   rule bans. Ink is the page's proven-legible mark colour on paper, so the
   ring stays loud without breaking the two-accent budget. (#pfp-download,
   the other ember fill, lives in the parked #generator markup and is not
   this shard's surface; its twin rule ships when that section returns.) */
.toy__start:focus-visible {
  outline-color: var(--moki-ink);
}


/* ==== 06-market.css ================================================= */
/* ============================================================================
   MOKI - _refine/06-market.css  (refine shard 06)

   Surface owned: #market only. The stat rail (.market__cells / .market__cell,
   built by live.js:193-208), the status line and its pulse dot, the flow bar,
   the venue / concentration / caption footnotes, and the .market__chart mount.

   Direction implemented: The Printed Dossier. #market is where the actual buy
   decision happens and it shipped as the flattest surface on the page (ranked
   high, art-direction). This shard turns the rail into the ledger opening:
   ruled column cells set on the site's one paper texture, red ink for a loss
   and plain ink for a gain, and numerals promoted to the stat tier ONLY once
   real data exists. Nothing here invents a hue, a texture, or a motion
   mechanic; every value below is an already-declared token doing the job its
   own comment names.

   Load-order contract: this file is linked after styles.css and every fx-*
   layer, so equal-specificity ties resolve to this shard by design. No
   !important anywhere below, and the only transition in this file is the
   press release on the chart button, motion-gated like every press on the
   site.
   ========================================================================= */

/* ----------------------------------------------------------------------------
   1. THE LEDGER GRID (move: market / ledger stat grid; findings: "#market is
   the single flattest surface", "stat rail ships with zero layout or surface
   CSS", "the two sections that ARE the checkable evidence carry none of the
   case-file surface vocabulary")

   A printed data table, not a card grid: gap 0, one vertical hairline opening
   each column, the shared --surface-ledger formula as the ground at the same
   faint 28% ink #receipts already uses. The REAL rules here are the column
   hairlines; the ruling must read as paper grain behind them, never compete
   (the receipts precedent, fx-surfaces.css consumer 3, verbatim reasoning).
--------------------------------------------------------------------------- */
.market__cells {
  display: grid;
  /* 11rem, not 9rem. Measured on the live rail rather than reasoned about: a
     pump.fun sub-cent price is 13 mono characters ("$0.000003336"), and at the
     stat clamp's own floor that string is about 171px wide, which walked
     straight over the neighbouring 24h cell inside a 144px column. The column
     now fits the widest value this rail can actually be asked to print. */
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0;
  margin-block: var(--space-4) var(--space-5);
  --ledger-ink: color-mix(in srgb, var(--moki-rule) 28%, transparent);
  background-image: var(--surface-ledger);
}

.market__cell {
  padding-block: var(--space-3);
  padding-inline-start: var(--space-3);
  border-inline-start: 1px solid var(--moki-rule);
  /* Containment so the promoted numeral below can size itself against the
     column it actually landed in, not against the viewport. */
  container-type: inline-size;
}

/* Each cell's <dt> takes the site's micro-label voice (the exact .label
   recipe from fx-type.css section 3) so it reads as a ruled column header
   sitting above its figure, which is the ranked fix for "nothing in the rail
   signals which line is the headline and which is a footnote". */
.market__cell dt {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-block-end: var(--space-1);
}

/* ----------------------------------------------------------------------------
   2. NUMERAL DISCIPLINE + THE STAT TIER (findings: "live price numerals render
   in the micro-label tier"; graft: the D5 tabular-nums cascade fix)

   fx-type.css's :where(dd) prose rule declares oldstyle proportional figures
   ON the dd itself, which beats the tabular-nums the rail inherits from
   .market__rail. Column alignment is the entire credibility of a ledger, so
   the data variant is restated here at class specificity where it wins.
--------------------------------------------------------------------------- */
.market__cell dd {
  font-variant-numeric: lining-nums tabular-nums slashed-zero;
  font-feature-settings: "zero" 1;
  line-height: 1.1;
}

/* The promotion to --text-2xl, the token whose own comment reads "big stat
   numerals" and which had zero consumers. HARD-GATED to live and stale: on
   the initial data-state="soon"/"loading" shell there is no value in the DOM
   and no rule below may ever make an empty or placeholder cell look like
   data (HONESTY SPINE, and the explicit veto on ungated promotion).
   is-missing / is-curve are excluded because "Unavailable" and "No pool yet"
   are words, not stats; dressing an absence in the stat tier would be the
   exact decorative-absence the spine forbids.

   Scale-collision discipline (veto: three unrelated elements converging on
   one token): these digits are Plex Mono tabular figures against the Fraunces
   900 of every promoted heading, so the shared size step never reads as the
   same voice; the mono family IS the secondary differentiator.

   Two font-size declarations on purpose: the clamp() with cqi is the real
   rule (a sub-cent Solana price is up to 12 mono characters, and 12 chars at
   the raw 2xl floor overflows a 9rem column, so the size fits the column and
   rises toward 2xl only where the column affords it). Browsers without
   container-query units drop the invalid clamp() and keep the plain token
   line above it. */
#market[data-state="live"] .market__cell dd:not(.is-missing):not(.is-curve) .val,
#market[data-state="stale"] .market__cell dd:not(.is-missing):not(.is-curve) .val {
  font-size: var(--text-2xl);
  /* The floor is --text-base, not --text-md. With --text-md as the floor the
     clamp could not shrink far enough to hold 13 mono characters in a rail
     column, so the longest real value on the page overflowed its cell no
     matter what cqi said. A price that fits quietly beats a price that is
     large and wrong. */
  font-size: clamp(var(--text-base), 13cqi, var(--text-2xl));
}

/* ----------------------------------------------------------------------------
   3. RED INK FOR A LOSS (move: market / negative delta as press; finding:
   "--moki-alert is never wired to the price-delta cell")

   The token's one documented job, finally performed where it was declared to
   happen. .is-up stays plain ink on purpose: a printed ledger marks a loss in
   red and marks a gain with nothing, and the one-warm/one-cool/one-alert
   budget has no green to spend (explicit veto on colouring the up state).
--------------------------------------------------------------------------- */
.market__cell[data-cell="change"] dd.is-down {
  color: var(--moki-alert);
}

/* ----------------------------------------------------------------------------
   4. HONEST ABSENCE (finding: "an honest Unavailable reads identically to a
   real fetched number")

   Muted and italic so an absence is visibly an absence, never typographically
   equal to a figure. The finding's literal fix suggested --moki-rule, but the
   same audit measured --moki-rule at ~1.6:1 on paper: unreadable, and these
   words are honesty-spine content. The 64% ink mix is the audit's own
   corrected formula for muted-but-AA text (the #verify caveat fix), reused
   here instead of inventing a value.
--------------------------------------------------------------------------- */
.market__cell dd.is-missing .val,
.market__cell dd.is-curve .val {
  font-style: italic;
  color: color-mix(in srgb, var(--moki-ink) 64%, var(--moki-paper));
}

/* ----------------------------------------------------------------------------
   5. THE STATUS LINE (surface: statusline + pulse dot)

   The pulse dot: fx-motion.css section 9 animates .market__pulse in the live
   state, but no stylesheet ever painted the span, so the animation fires on
   an invisible element (the same authored-but-unpainted class of bug the
   audit ranked high on .stand__plane--mid). The witness token's own comment
   names "the live-pulse dot" as one of its jobs: a mark, not a fill, exactly
   inside its documented budget. Static paint only; the pulse itself stays
   fx-motion's, and in stale/error the dot holds solid per that file's own
   reasoning ("a live badge above an n/a can never happen").
--------------------------------------------------------------------------- */
.market__pulse {
  display: inline-block;
  inline-size: 0.5em;
  block-size: 0.5em;
  border-radius: var(--radius-full);
  background-color: var(--moki-witness);
  vertical-align: baseline;
}

/* The line itself keeps the rail's mono --text-sm: it is the stamp above the
   table, and the table's own margin-block-start provides the beat between
   them (the reset's * { margin: 0 } otherwise leaves the <p> flush against
   the <dl>). */
.market__statusline {
  margin-block-end: 0;
}

/* ----------------------------------------------------------------------------
   6. THE FLOW BAR (surface: flow bar; finding class: "the stat rail, the
   section's entire visual payload, ships with zero surface CSS")

   live.js only unhides this <progress> once real buy/sell counts exist, so
   styling it is styling data, never a placeholder. Ink share on a ruled
   track: buys fill in ink, the remainder is bare paper behind a hairline
   frame. Square corners, because it is a printed bar in a ledger, not a
   meter in a dashboard. accent-color is the fallback for engines that ignore
   appearance: none on progress.

   BUG FIXED HERE: `display: block` on the bare .market__flow-bar class is an
   author-origin rule at the same specificity as styles.css's own
   `[hidden] { display: none; }` (line 208), and this shard loads after
   styles.css, so on an equal-specificity tie the later rule was winning.
   That silently defeated live.js's `flowBar.hidden = true` and rendered the
   bar (with no value attribute set, i.e. HTML's native indeterminate state)
   before any real buy/sell counts exist: exactly the "even bar with no data
   behind it reads as data" case live.js's own comment forbids, and the worst
   possible defect for this file (HONESTY SPINE). Every declaration below is
   re-scoped to :not([hidden]) so the hidden attribute keeps display:none and
   this shard only ever paints the bar once live.js has already unhidden it.
--------------------------------------------------------------------------- */
.market__flow {
  margin-block-start: 0;
}
.market__flow-bar:not([hidden]) {
  display: block;
  inline-size: min(100%, 20rem);
  block-size: 0.375rem;
  margin-block-start: var(--space-2);
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--moki-rule);
  background-color: var(--moki-paper);
  accent-color: var(--moki-ink);
}
.market__flow-bar::-webkit-progress-bar {
  background-color: var(--moki-paper);
}
.market__flow-bar::-webkit-progress-value {
  background-color: var(--moki-ink);
}
.market__flow-bar::-moz-progress-bar {
  background-color: var(--moki-ink);
}

/* ----------------------------------------------------------------------------
   7. FOOTNOTES RANKED BELOW THE FIGURES (finding: "nothing in the rail
   signals which line is the headline and which is a footnote")

   Venue, concentration and the FDV caption are real qualifiers, not
   decoration, so they stay fully readable: one size step down and the muted
   ink mix, at a mix percentage that still clears AA (the same 64-65% band
   the audit computed for the verify caveats). Solid mix, not transparency,
   so the ledger ruling behind them can never eat the contrast. The 58ch
   measure matches .market__note and .market__chart-note so every explanatory
   line in this section holds one prose width.
--------------------------------------------------------------------------- */
.market__venue,
.market__conc,
.market__caption {
  font-size: var(--text-xs);
  color: color-mix(in srgb, var(--moki-ink) 65%, var(--moki-paper));
  max-width: 58ch;
}

/* ----------------------------------------------------------------------------
   8. THE ERROR STATE DIMS TOO (finding, high/motion: "the state machine's
   worst outcome has zero treatment, so it reads as healthier than stale")

   Same 0.45 demotion the stale state already gets, applied unconditionally
   like fx-motion's own stale rule; the 400ms fade into it is that file's
   existing motion-gated transition and needs nothing from this shard.
--------------------------------------------------------------------------- */
#market[data-state="error"] .market__rail {
  opacity: 0.45;
}

/* ----------------------------------------------------------------------------
   9. THE CHART BUTTON JOINS THE PRESS (move: controls / press-plate
   unification; finding: "the chart-load button drops the site's one control
   language for buttons")

   The canonical pressable plate: hard 3px ink offset that physically
   collapses on :active, which is itself the printing-press metaphor (the
   plate strikes down). Existing padding from fx-fixes.css is preserved
   untouched; min-height 44px raises the control to the same tap-target floor
   every other button on the page declares (the veto requires the floor be
   preserved, not just matched). The transition list restates fx-fixes'
   background/border fade because a later same-name declaration would
   otherwise silently drop it.
--------------------------------------------------------------------------- */
.market__chart-btn {
  min-height: 44px;
  box-shadow: 0 3px 0 var(--moki-ink);
}
@media (prefers-reduced-motion: no-preference) {
  .market__chart-btn {
    transition:
      transform        var(--duration-press) linear,
      box-shadow       var(--duration-press) linear,
      background-color var(--duration-press) linear,
      border-color     var(--duration-press) linear;
  }
}
.market__chart-btn:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow: none;
}
/* A disabled control has no travel left in it: the raised shadow would
   promise a press that cannot land. */
.market__chart-btn:disabled {
  box-shadow: none;
}

/* ----------------------------------------------------------------------------
   10. MOBILE: RULED ROWS, NOT ORPHANED COLUMNS (graft: D1's mobile
   ledger-rule override, named required-not-optional)

   Under the site's one structural breakpoint the vertical column rules go
   and each cell opens with a horizontal rule instead: on a narrow wrap the
   cells read as ruled ledger rows, and a single-column collapse can never
   strand a lone left-edge line.
--------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .market__cell {
    border-inline-start: 0;
    padding-inline-start: 0;
    border-block-start: 1px solid var(--moki-rule);
  }
}


/* ==== 07-archive.css ================================================ */
/* ============================================================================
   MOKI - _refine/07-archive.css  (shard 07)
   Owns: the #archive sticky-stack dossier cards and the prompt list inside
   them. Nothing else. Loads after styles.css, fx-type.css, fx-surfaces.css,
   fx-motion.css and fx-fixes.css, so equal-specificity ties resolve here by
   design; no !important anywhere below.

   Direction implemented: The Printed Dossier. The archive cards become
   counter-numbered file cards (generated, never hand-typed, so the sequence
   cannot drift when a card is added), the fourteen-item unshot queue gets the
   internal rhythm it was owed, and the ledger card's decorative margin rule
   stops taxing the narrow-screen reading column.

   Property discipline matches the frozen sheets: static surface and type
   properties only. Zero transitions, zero keyframes, zero animated
   properties, so fx-motion.css stays the sole motion owner and the grep
   audit stays meaningful. Nothing here needs a reduced-motion block because
   nothing here moves.
   ========================================================================= */

/* ----------------------------------------------------------------------------
   1. CARD NUMBERING - the dossier counts its own cards.
   #plates ships PLATE 01..13 micro-labels; the three archive cards shipped
   none, so the page's two collections read as one numbered gallery and one
   anonymous stack. This extends the micro-label convention to #archive as an
   INDEPENDENT sequence (CARD 01..03), deliberately not continuing the plate
   count: a consecutive 01-16 spanning two sections goes silently stale the
   first time either section gains or loses an item.

   CSS counters, not markup spans, for the same reason: the number is derived
   from document order, so it can never disagree with it. The counter
   increments on the card and renders inside the existing .archive__label
   figcaption, which already carries the mono/uppercase/tracked micro-label
   voice from fx-type.css - the prefix inherits all of it for free, and the
   hairline under the label now underlines number and title as one tab.

   fx-motion.css claims ::after on plate-reveal elements (the drawn hairline)
   and reserves ::before on those same elements for surfaces; .archive__label
   is a child, not a reveal element, and no frozen sheet touches its pseudos,
   so ::before here collides with nothing. */
.archive__stack {
  counter-reset: archive-card;
}
.archive__card {
  counter-increment: archive-card;
}
.archive__label::before {
  content: "Card " counter(archive-card, decimal-leading-zero) " \00B7  ";
  /* Resting legibility, learned from the .plate__no finding: bare --moki-rule
     on a blaze ground measures ~1.6:1, invisible until hover. Same formula
     as ruled there (ink mixed into the ground it sits on, no new hue), but
     bumped from 55% to 62%: measured, 55% only clears ~3.91:1 against
     --moki-blaze, still short of the 4.5:1 AA floor this --text-xs (12px),
     non-bold prefix needs. 62% measures ~4.92:1, holding the same
     dark-enough-before-interaction intent with an actual AA margin. */
  color: color-mix(in srgb, var(--moki-ink) 62%, var(--moki-blaze));
}

/* ----------------------------------------------------------------------------
   2. THE UNSHOT QUEUE - internal rhythm for the densest block on the page.
   The global reset zeroes every margin and no frozen sheet ever countered it
   for this list, so fourteen multi-line prompts run back to back with only
   line-height separating them, inside the one card that most needed pacing.
   A half-step gap (--space-2), deliberately smaller than the card's own
   2rem padding, keeps the two tiers of spacing legible as different beats:
   the card breathes in --space-6, the entries inside it breathe in
   --space-2. */
.archive__prompts > li + li {
  margin-block-start: var(--space-2);
}

/* ----------------------------------------------------------------------------
   3. LEDGER MARGIN ON SMALL SCREENS - the ruling yields to the prose.
   fx-surfaces.css fixes the ledger card's red margin line at 2.75rem and
   starts prose 1rem past it. The 767px block in styles.css shrinks the
   shared card padding to --space-5 but never touches --margin-x, so on a
   390px screen the decorative ruling still costs 60px of the left edge
   while every other side dropped to 24px, squeezing the heaviest content
   block exactly where width is scarcest.

   Only --margin-x is overridden: fx-surfaces derives its
   padding-inline-start from the same variable (calc(--margin-x + 1rem)),
   so the clearance follows the line automatically and the two values can
   never drift apart. */
@media (max-width: 767px) {
  .archive__card--ledger {
    --margin-x: 1.5rem;
  }
}

/* ----------------------------------------------------------------------------
   4. THE PROMPT LIST'S MARKERS (found by looking at 390px, not by reading code)

   app.js wraps every prompt <li>'s text in a <button> so that Enter, Space and
   the accessible name come from the platform instead of being re-implemented.
   That button carries inline styles and no display, so it stays inline. On a
   phone each prompt wraps to three or four lines, and an inline child that
   tall drags the <li>'s baseline down with it: the list marker ended up
   painted beside the LAST line of each item, so the sheet read "text, text,
   text, 1." Numbers below the thing they number is not a style opinion, it is
   a list that has stopped working.

   display: block on the button puts the marker back beside the first line.
   app.js sets display on nothing, so this lands without fighting an inline
   style and without !important.
--------------------------------------------------------------------------- */
.archive__prompt-btn {
  display: block;
}


/* ==== 08-plates.css ================================================= */
/* ============================================================================
   _refine/08-plates.css  (refine shard 08)

   OWNS: the #plates field archive contact sheet and the .plate-lb lightbox
   gallery.js builds. Nothing else. Loads after styles.css and every fx-*.css,
   so equal-specificity ties resolve to this file on purpose; no !important
   anywhere below.

   DIRECTION: "The Printed Dossier". The plates join the site's existing plate
   family (radius, lifted shadow, reveal entrance) instead of standing apart
   as a flat bordered grid, the sheet gets the one recurring ledger texture at
   the faint #receipts intensity, Plate 01 becomes the sheet's single focal
   cell, and the lightbox chrome adopts the site's one press affordance (the
   plate strikes down) instead of its own weaker hover language.

   VETO COMPLIANCE, stated up front because the review will check:
     - radius is capped at --radius-md, never --radius-lg (contact-sheet
       register stays rawer than the witness crop, per the veto list)
     - no viewfinder corner brackets, no registration marks: the corner-mark
       grammars were vetoed off this surface entirely
     - no hand-typed renumbering: the PLATE 01..13 spans already in markup
       number this collection independently and are left alone
     - lightbox controls KEEP their existing padding and gain a 44px floor;
       the press shadow does not shrink the tap target
============================================================================ */

/* ----------------------------------------------------------------------------
   1. PLATE NUMBER LEGIBILITY
   fx-fixes sets .plate__no to bare --moki-rule, which measures ~1.6:1 on the
   blaze ground: the label is invisible until hover swaps it to ember. Muted
   is the intent, unreadable is a bug. Ink mixed at 55% only reached ~3.9:1,
   still under the 4.5:1 text floor; 62% clears it (~4.9:1) with a small
   margin for rendering variance, while still reading as a stamped
   micro-caption, not body text. The ember hover swap in fx-fixes stays the
   only accent-coloured state.
--------------------------------------------------------------------------- */
.plate__no {
  color: color-mix(in srgb, var(--moki-ink) 62%, var(--moki-blaze));
}

/* Same fix inside the lightbox: the position counter uses the same bare
   --moki-rule on the same blaze ground and fails the same way. */
.plate-lb__count {
  color: color-mix(in srgb, var(--moki-ink) 62%, var(--moki-blaze));
}

/* ----------------------------------------------------------------------------
   2. THE PLATE JOINS THE PLATE FAMILY
   Every other bordered photo surface (witness crop, archive card, kit canvas)
   is a rounded, lifted object; the thirteen plates, the section that most
   literally uses the word, shipped square and shadowless. --radius-md, not
   --radius-lg: the veto list caps it there so the contact sheet stays one
   step rawer than the single witness plate.

   The shadow reads the shared --shadow-lift token if a sibling shard has
   declared it (the D3 consolidation), and falls back to the same value that
   consolidation names, derived from ink so no new colour exists here.
--------------------------------------------------------------------------- */
.plate figure {
  border-radius: var(--radius-md);
  box-shadow: var(
    --shadow-lift,
    0 20px 40px -28px color-mix(in srgb, var(--moki-ink) 30%, transparent)
  );
}

/* ----------------------------------------------------------------------------
   3. THE SHEET SITS ON RULED PAPER
   The section's own comment claims the plates "read as evidence pinned to a
   board" but ships no board. Reuse the one ledger formula at the faint 28%
   intensity #receipts already established, so the ruling reads as paper
   grain behind the bordered plates, never competing with them. One texture,
   one formula, third consumer at the subordinate strength.
--------------------------------------------------------------------------- */
.plates__sheet {
  --ledger-ink: color-mix(in srgb, var(--moki-rule) 28%, transparent);
  background-image: var(--surface-ledger);
}

/* ----------------------------------------------------------------------------
   4. PLATE 01 IS THE POINT OF ENTRY
   #archive, with three cards, still marks one as the lead with an ember top
   rule. This sheet has thirteen interchangeable cells and no place for the
   eye to land first. Plate 01 (the cockpit opener) gets the same ember cap
   rule and a double-width cell at the 3-column width only; below 1024px the
   grid is 2-up or 1-up and a spanning cell would just read as a broken row.

   Ember budget check for this screen: the disclosure's left rule and this
   cap rule are the section's two resting ember uses, at the cap. The hover
   border swap is a transient state, not a third resting fill.

   Requires class="plate--lead" on the first <li class="plate"> (markup
   request, applied by the orchestrator, not this file).
--------------------------------------------------------------------------- */
.plate--lead figure {
  border-block-start: 3px solid var(--moki-ember);
}

/* THE SPAN IS GONE, THE CAP RULE ABOVE STAYS. Rendered at 1440 the
   double-width cell did give the eye somewhere to land, and then charged too
   much for it: plate 01 at two columns wide is also close to twice as tall, so
   the row's height was set by a 700px cell while plate 02 beside it finished
   around 500px, and the entire third column below plate 02 became an empty
   field of ledger ruling before plate 03 could begin. That void does not read
   as editorial whitespace. It reads as a grid that failed to load.

   The ember cap rule already does what the graft was asking for: one plate is
   marked, the eye lands there first, and every cell keeps the native aspect
   ratio this whole section exists to preserve. Emphasis was worth one rule. It
   was not worth a hole. The 10-mobile.css release of this span is now a no-op
   and is left in place as a comment there, not as a rule.
--------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------------
   5. ENTRANCE REVEAL INTEGRATION
   The 13 plates are the only repeating collection excluded from the site's
   one reveal family, even though every <li> already carries the --i stagger
   token the family reads. The wiring itself is markup (class="reveal"
   data-reveal="plate" on each figure, requested, not made here); this block
   handles the collision that wiring creates:

   fx-motion's reveal base rule (html.js .reveal[data-reveal="plate"]) owns
   both `transform` and `transition` on the figure at higher specificity than
   fx-fixes' hover lift, so once the figures are reveal members the -2px
   hover lift would either die or inherit the 900ms settle clock. Fighting
   that with specificity on the figure would corrupt the reveal's own
   transition list, so the lift MOVES to the <li>, which nothing else
   transforms. The figure keeps only its border-color hover; that colour now
   snaps instead of easing 60ms, which matches the site's stated rule that
   colour snaps.
--------------------------------------------------------------------------- */
.plate figure:hover,
.plate:focus-within figure {
  /* ties with fx-fixes at (0,2,1); this file loads later and wins the tie,
     which is exactly why the lift lives on the li below */
  transform: none;
}

@media (prefers-reduced-motion: no-preference) {
  .plate {
    transition: transform 180ms var(--ease-out-expo);
  }
  .plate:hover,
  .plate:focus-within {
    /* same small evidence-sheet lift fx-fixes gave the figure, same clock,
       compositor-friendly transform only */
    transform: translateY(-2px);
  }
}

/* ----------------------------------------------------------------------------
   6. A RESTING AFFORDANCE FOR THE LIGHTBOX
   The only cue that a plate opens anything is a hover state, which touch
   devices never see. A small mono "+" chip in the photo's corner is the
   honest resting signal. It lives on ::after of .plate__btn, NOT the figure:
   fx-motion has claimed figure::after for the plate-turn hairline and
   fx-surfaces holds the ::before option, so the button (built by gallery.js,
   so the mark only exists when the lightbox does; JS-off pages never show a
   dead affordance) is the one unclaimed host.

   The chip carries its own blaze ground because it sits over thirteen
   unpredictable photographs; the glyph uses the same legible ink mix as the
   plate number (62%, see §1). Ember swap on hover only, NOT on focus-within:
   the focus ring is witness, and witness and ember must never sit adjacent
   in one component, so the focused state keeps the ink glyph.
--------------------------------------------------------------------------- */
.plate__btn {
  position: relative;
}

.plate__btn::after {
  content: "+";
  position: absolute;
  inset-block-end: var(--space-2);
  inset-inline-end: var(--space-2);
  padding: 0 var(--space-1);
  font-family: "IBM Plex Mono", "Plex Mono Fallback", ui-monospace, Menlo, monospace;
  font-size: var(--text-xs);
  line-height: 1.5;
  background-color: var(--moki-blaze);
  border: 1px solid var(--moki-rule);
  border-radius: var(--radius-sm);
  color: color-mix(in srgb, var(--moki-ink) 62%, var(--moki-blaze));
  pointer-events: none;
}

.plate figure:hover .plate__btn::after {
  color: var(--moki-ember);
  border-color: var(--moki-ember);
}

/* ----------------------------------------------------------------------------
   7. LIGHTBOX CHROME JOINS THE PRESS
   Previous/Next/Close are the newest buttons on the site and the only ones
   that invented their own hover-only language. They get the canonical
   control recipe: hard 3px offset shadow, :active collapses the full 3px of
   travel, 60ms linear release. The press metaphor (the plate strikes down)
   is the direction's own thesis applied mechanically.

   Tap-target veto honoured explicitly: existing padding is untouched and a
   44px min-height floor is ADDED (these three controls are the whole touch
   flow and previously computed ~40px). inline-flex centres the label inside
   the new floor without touching the padding.
--------------------------------------------------------------------------- */
.plate-lb__nav,
.plate-lb__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px; /* §11.10 tap-target floor, same as every other control */
}

.plate-lb__nav {
  /* the paper resting surface the press recipe collapses from; fx-fixes left
     these transparent on the blaze dialog */
  background-color: var(--moki-paper);
  border-color: var(--moki-ink);
  box-shadow: 0 3px 0 var(--moki-ink);
}

.plate-lb__close {
  /* ember variant of the same recipe, matching #pfp-download / .toy__start */
  box-shadow: 0 3px 0 color-mix(in srgb, var(--moki-ember) 55%, var(--moki-ink));
}

/* fx-fixes gives .plate-lb__close a permanent ember fill (background-color:
   ember, border-color: ember, not just on hover), and the sitewide
   :focus-visible ring is --moki-witness (styles.css:234): tabbing to Close
   would draw the cool accent directly around the warm fill, the exact
   adjacency the §2 hard rule bans. Same fix as .toy__start:focus-visible
   (05-toys.css), same reasoning: ink is the page's proven-legible mark
   colour on paper, so the ring stays loud without breaking the two-accent
   budget. .plate-lb__nav does not need this: its resting surface is paper,
   never ember. */
.plate-lb__close:focus-visible {
  outline-color: var(--moki-ink);
}

/* Pressed state applies always; only the 60ms release is motion-gated,
   mirroring fx-motion's own pattern for the kit and toy buttons. */
.plate-lb__nav:active,
.plate-lb__close:active {
  transform: translateY(3px);
  box-shadow: none;
}

@media (prefers-reduced-motion: no-preference) {
  .plate-lb__nav,
  .plate-lb__close {
    /* supersedes the fx-fixes transition list on these selectors, so the
       border/background hover recolours are restated alongside the press */
    transition:
      border-color var(--duration-press, 60ms) linear,
      background-color var(--duration-press, 60ms) linear,
      transform var(--duration-press, 60ms) linear,
      box-shadow var(--duration-press, 60ms) linear;
  }
}

/* ----------------------------------------------------------------------------
   8. THE BACKDROP STOPS BORROWING THE VOID
   The dark register is #stand's alone; the lightbox backdrop hand-converted
   --moki-void into an rgba and spent the page's one meaningful darkness on
   casual modal chrome. Ink, the page's other neutral, darkens the backdrop
   just as well without diluting what the void means. The plain rgba line is
   the fallback for engines where ::backdrop cannot resolve custom
   properties; it is ink at the same alpha, not a new colour.
--------------------------------------------------------------------------- */
.plate-lb::backdrop {
  background-color: rgba(21, 19, 15, 0.7);
  background-color: color-mix(in srgb, var(--moki-ink) 70%, transparent);
}


/* ==== 09-receipts.css =============================================== */
/* ============================================================================
   MOKI - _refine/09-receipts.css  (shard 09)
   Owns: the #receipts honesty ledger and the #verify footer list.
   Direction: The Printed Dossier - extend the one ledger-paper texture across
   the two sections doing the page's actual evidentiary work, and give each
   #verify entry a scannable printed-index structure (bold title, explicit
   title-to-body beat, caveats muted but AA-legible).

   Loads after styles.css and every fx-*.css, so equal-specificity ties fall
   to this file by cascade order. No !important anywhere; nothing here
   animates, so there is no motion to gate behind prefers-reduced-motion.
   Tokens only - zero new colours, zero new sizes.
   ========================================================================= */

/* ----------------------------------------------------------------------------
   1. #verify JOINS THE LEDGER.
   Critic: "#verify has zero surface treatment despite being the section that
   makes the site's honesty claims falsifiable." #receipts already carries
   the faint ruling (fx-surfaces.css consumer 3); #verify hands the reader
   the actual outbound proof links, so it is the same class of evidence and
   gets the byte-identical formula: same texture, same 28% ink, so the site
   still has exactly one paper texture, never a second invention. The REAL
   rules remain the per-entry hairlines styles.css draws; this ruling is
   paper grain behind them, never competition (same reasoning as receipts).
--------------------------------------------------------------------------- */
.verify__list {
  --ledger-ink: color-mix(in srgb, var(--moki-rule) 28%, transparent);
  background-image: var(--surface-ledger);
}

/* ----------------------------------------------------------------------------
   2. ENTRY TITLES READ AS TITLES.
   Critic: each #verify entry opens with a link that functions as that
   entry's heading but inherits the plain body `a` rule - the underline
   reads "clickable", not "heading". Weight 700 is already a declared step
   (styles.css `strong`), so no new weight ships; the thinner underline
   keeps the affordance without letting a heavy default rule shout over
   bolded Georgia.
--------------------------------------------------------------------------- */
.verify__list > li > a {
  font-weight: 700;
  text-decoration-thickness: 1px;
}

/* ----------------------------------------------------------------------------
   3. THE TITLE-TO-BODY BEAT, MADE EXPLICIT.
   Critic: the title-to-body gap is 0 while body-to-caveat is a full
   --space-4 via the generic `p + p` rule - the biggest structural jump in
   each entry reads tighter than the smaller one, backwards from the h2/h3
   rhythm everywhere else. --space-2 keeps it deliberately SMALLER than the
   body-to-caveat gap so the two beats stay legible as different sizes.
   The three pending entries title with a <span class="verify__pending">,
   not an <a>; they get the same beat so all six entries share one printed
   structure (the mono "not yet public" register itself is untouched - it
   is a status stamp, not a link, and faux-bolding Plex Mono would
   synthesize a weight §3 never shipped).
--------------------------------------------------------------------------- */
.verify__list > li > a,
.verify__list .verify__pending {
  display: inline-block;
  margin-block-end: var(--space-2);
}

/* ----------------------------------------------------------------------------
   4. CAVEATS: MUTED, BUT ABOVE THE AA FLOOR.
   Critic: the shipped mute (55% ink) measures ~3.95:1 at --text-sm, just
   under the 4.5:1 floor, and the "what this does NOT tell you" lines are
   honesty-spine content, not decoration. 64% ink lands ~5.3:1 against
   paper: still visibly subordinate to full-ink body text, cleanly legible.
   Note the markup's caveats are <p class="verify__caveat"> - styles.css
   only ever muted `#verify small`, so the caveats currently render at FULL
   ink, indistinguishable from the claims they qualify. Both selectors get
   the one formula so the mute exists and is consistent wherever the markup
   lands. (No color-mix fallback needed: an unsupported browser drops the
   declaration and the text stays full-ink, which is safe, never invisible.)
--------------------------------------------------------------------------- */
.verify__caveat,
#verify small {
  color: color-mix(in srgb, var(--moki-ink) 64%, var(--moki-paper));
}

/* ----------------------------------------------------------------------------
   5. THE CONTRACT-ADDRESS CHIP IS CUT FROM THE RULED PAGE.
   Critic: the CA chip floats on the receipts ledger texture with no formal
   relationship to the grain behind it - a UI chip pasted on, not an object
   filed within the ledger. One property fixes it: the chip inherits
   --ledger-ink (28%) from its .receipts__list ancestor, so painting the
   same texture costs zero new values and the chip reads as clipped from
   the same ruled sheet it sits on.
--------------------------------------------------------------------------- */
.receipts__ca {
  background-image: var(--surface-ledger);
}


/* ==== 10-mobile.css ================================================= */
/* ============================================================================
   MOKI - _refine/10-mobile.css  (shard 10 of 10)

   Owns: responsive corrections at 390 / 599 / 767 / 1023, across every
   section. Implements the Printed Dossier direction's narrow-viewport
   discipline: the ledger keeps ruling when its columns collapse, tap targets
   hold the 44px floor on the one nav path phones actually use, and the
   promoted stat numerals step down before they can force horizontal scroll.

   Loaded LAST by contract, after styles.css, the four fx-*.css files and the
   other nine _refine shards. Every selector here deliberately matches or
   exceeds the specificity of the rule it corrects and then wins on source
   order - no !important anywhere, none needed.

   Nothing in this file animates, so it carries no prefers-reduced-motion
   block: every rule is static layout, size or surface state. Zero new
   colours, zero new tokens - only §2 tokens are consumed.
============================================================================ */

/* ----------------------------------------------------------------------------
   1. <= 1023px - touch-first widths (tablet and down)

   The plates lightbox is opened and driven entirely by tapping these three
   controls (gallery.js ships no swipe gesture), yet they were the only
   controls on the site without the explicit 44px floor every other button
   declares (fx-surfaces.css §4). Padding alone computes to roughly 40px at
   --text-sm, a few px under the floor, exactly where the interaction is
   touch-only. min-height changes the resting box, it does not undo the
   press-plate shadow/travel another shard extends to these buttons.
--------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  .plate-lb__nav,
  .plate-lb__close {
    min-height: 44px; /* §11.10 tap-target floor, same value as .nav__toggle */
  }
}

/* ----------------------------------------------------------------------------
   2. <= 767px - the structural breakpoint styles.css §6 already owns
--------------------------------------------------------------------------- */
@media (max-width: 767px) {

  /* -- nav drawer links: the entire mobile navigation ---------------------
     Below 767px the rail is display:none and these anchors are the only way
     to move through the file, yet fx-surfaces.css styles only the drawer
     sheet, never the links inside it. Bare inline anchors give a tap box of
     one line-height, roughly 26-29px. Mirror .nav__rail a's own treatment
     (styles.css:382-392, "§11.10 tap-target floor") so the one nav path
     every phone visitor uses meets the floor the desktop rail already does. */
  .nav__drawer a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding-inline: var(--space-3);
  }

  /* -- #name heading: CJK + Latin at wordmark scale does not fit ----------
     #name's h2 is the one heading promoted above the shared h2 tier, and the
     767px block in styles.css rewrites its grid but never its size. At 390px
     the promoted clamp still computes near 59px for a mixed run (kanji,
     middle dot, Latin caps) that text-wrap:balance cannot break safely: CJK
     breaks anywhere, "MOKI" and the dot cannot. Step it to the --text-xl
     tier every other section's h2 uses at this width. The desktop demotion
     to --text-2xl is another shard's move; this override wins below 767px
     either way, and it also keeps the demoted #name heading off the same
     size step as #market's promoted numerals on small screens, where the
     two CAN share a viewport. */
  #name h2 {
    font-size: var(--text-xl);
  }

  /* -- archive ledger card: the ruling must shrink with the page ----------
     .archive__card--ledger hardcodes --margin-x at 2.75rem and pads prose
     past it, which the 767px block in styles.css never touches: at 390px the
     card keeps 60px of left clearance while every other side drops to 24px,
     squeezing the densest content block on the page (the 14-item prompt
     list) hardest exactly where width is scarcest. Shrinking the custom
     property moves the painted margin line AND the prose together, because
     both read the same variable - the ledger stays a ledger, just set on a
     narrower page. */
  /* COHERENCE FIX: this block also carried an explicit
     `padding-inline-start: calc(var(--margin-x) + var(--space-3))` line
     (space-3 = 0.75rem), which silently overrode fx-surfaces.css's own
     `padding-inline-start: calc(var(--margin-x) + 1rem)` (styles.css's
     established 1rem clearance past the ruling) at this same 767px
     breakpoint, a smaller undecided 0.75rem gap nobody actually chose.
     07-archive.css §3 fixes this identical surface by touching ONLY
     --margin-x and explicitly relies on fx-surfaces' formula to carry the
     clearance along "so the two values can never drift apart", so this file
     was breaking that exact promise. Re-declaring --margin-x here is now
     redundant with 07-archive.css too (same value, same breakpoint), but
     harmless; the padding-inline-start override is removed so the
     clearance follows fx-surfaces' single formula again. */
  .archive__card--ledger {
    --margin-x: 1.5rem;
  }

  /* -- #stand: the photograph must never be cropped by its own pin --------
     --stand-cat-h scales the cat purely off viewport height; width follows
     the 658:1244 source ratio with max-width:none, inside overflow:clip. On
     any viewport taller than about 2.25x its width the rendered cat is wider
     than the screen and the pin silently crops both edges. The invariant
     says the cat never animates because the stillness IS the thesis; losing
     his edges to an unannounced crop works against the same thesis. Add a
     width-derived ceiling: rendered width = height x (658/1244), so height
     <= 92vw / (658/1244) = 173.9vw keeps him inside a 92vw safe box.
     .stand__eyes computes --f off this same variable, so the measured
     eye-band overlay follows the resize automatically, nothing else to
     retune. Same :root specificity as styles.css; this file loads later,
     so the override wins at these widths only. */
  :root {
    --stand-cat-h: min(84vh, 173.9vw, 70rem);
  }
  @supports (height: 1svh) {
    :root {
      /* svh, not vh, for the same URL-bar reason as styles.css:94-101 */
      --stand-cat-h: min(84svh, 173.9vw, 70rem);
    }
  }

  /* -- #market cells: column rules become row rules -----------------------
     The market shard's ledger grid draws a 1px border-inline-start per cell,
     the printed stock-column convention. When auto-fill packs fewer columns
     down here, a left-edge rule on a wrapped cell is an orphaned line
     hanging off nothing - the spec's own risk list calls this override
     required, not optional. Swap the vertical column rule for a horizontal
     row rule: on narrow paper a ledger rules its rows, not its columns, so
     the metaphor survives the collapse instead of breaking with it. #market
     prefix so this outranks the shard's rule whether it scoped to the id
     or not. */
  #market .market__cell {
    border-inline-start: 0;
    padding-inline-start: 0;
    border-block-start: 1px solid var(--moki-rule);
    padding-block-start: var(--space-3);
  }

  /* -- #toys: the bench folds back to one column --------------------------
     The desktop shard splits .toy into the unequal photo/panel grid the
     rest of the page's compositional grammar uses. Its own move text names
     767px as the collapse point; this is that collapse. Inert if the grid
     never shipped (grid-template-columns does nothing on a block box), so
     the two shards cannot strand each other. */
  #toys .toy {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ----------------------------------------------------------------------------
   3. <= 599px - phone widths
--------------------------------------------------------------------------- */
@media (max-width: 599px) {

  /* -- #market: one stat per ruled row ------------------------------------
     Two minmax(9rem, 1fr) columns still fit at 390px, but a promoted price
     like "$0.00001234" in big mono tabular figures does not fit half of a
     350px content column - and an overflowing number in the honesty section
     is the worst possible place to fail the §11.10 no-horizontal-scroll
     sweep. One full-width cell per row, each carrying the row rule from the
     767px block above: the panel reads as a printed ledger page, one fact
     per line. */
  #market .market__cells {
    grid-template-columns: minmax(0, 1fr);
  }

  /* -- promoted numerals step down one tier, state gate intact ------------
     The stat promotion to --text-2xl is desktop-sized; at phone widths the
     same clamp still computes to 44px and long values push the cell past
     its column. Step to --text-xl, still two tiers above the mono chrome
     around it, so the hierarchy the promotion bought survives at a size the
     column can actually carry. The [data-state] gate is a hard veto: this
     selector must NEVER lose the live/stale scoping, or a placeholder gets
     sized like real data and the honesty spine breaks. Size only - the
     tabular-nums discipline rides in from the market shard untouched.

     Selector must MATCH the market shard's own promotion selector
     (06-market.css §2: "#market[data-state] .market__cell dd:not(.is-missing)
     :not(.is-curve) .val"), not just its ancestor chain. That rule carries
     five class-level matches plus a dd type match (specificity 1,5,1); the
     earlier ".market__rail .val" form this shard shipped only carried three
     class-level matches (1,3,0), so the market shard's own clamp(...,13cqi,
     var(--text-2xl)) kept winning under this file's cascade position and the
     step-down never actually painted. Restating the exact selector here
     matches that specificity; this file's later position in the link order
     then wins the tie and the single flat value replaces both of the market
     shard's font-size declarations for this property. */
  #market[data-state="live"] .market__cell dd:not(.is-missing):not(.is-curve) .val,
  #market[data-state="stale"] .market__cell dd:not(.is-missing):not(.is-curve) .val {
    font-size: var(--text-xl);
  }

  /* -- #plates: the lead plate's span release is no longer needed ---------
     This block used to reset .plate--lead's grid-column, because a leftover
     span 2 in the 599px single-column sheet forced an implicit second column
     and sheared the grid sideways. The span itself was removed upstream in
     08-plates.css after rendering it at 1440, where it left a column-tall void
     beside the lead plate, so there is nothing here to release any more. Kept
     as a note rather than a rule: if anyone reinstates that span, this is the
     breakpoint that has to answer for it. */
}
