/* ═══════════════════════════════════════════════════════════════════════════
   THE ILLUMINATED MANUSCRIPT — the deviations patch
   ═══════════════════════════════════════════════════════════════════════════
   Loaded AFTER the main sheet — index.html carries it one line under
   style.css, and tools/stamp.js walks the whole of public/css, so the two
   links always wear the same ?v= and cannot be served out of step.

   Every rule here is either (a) a role the sheet's own colour literals are
   reaching for and cannot name, or (b) a place the sheet breaks a rule its own
   header states. Nothing is a new look. The findings, with counts and line
   numbers, are in docs/AUDIT.md; the section numbers match. The reference it
   is all measured against is /language.html.

   HOW IT RETIRES. Specificity is matched, never escalated, and there is no
   !important anywhere — so a finding fixed upstream in style.css simply wins,
   and its line here can be deleted. When this file is empty the sweep is done.

   THE ONE HAZARD OF A LOAD-AFTER PATCH, and why three of the hand-off's own
   drafted rules are not in it. Loading last beats EVERY same-selector rule in
   the main sheet on source order — including a rule LATER in style.css that
   was deliberately overriding an earlier one. Three drafts did exactly that,
   and were caught before landing:
     · `#mapframe { background }` would have flattened the translucent
       cartouche at style.css:5684 (the vellum "under the candle", let go to
       ~0.83 alpha so the battlefield reads through the page) back to the
       opaque base rule at 426;
     · `.build { transition }` would have replaced the tactile press at 5220
       — transform on --e-back, filter included — with a plain settle;
     · `[data-mode='1v1']` matched nothing, because the duel's key is `h2h`,
       so the duel would have kept its ⚔. The swords ride the generic
       mode-button rule instead, which is where the sheet's own default is.
   Before adding a line here: list every rule in style.css with the same
   selector and the same property. If there is more than one, the fix belongs
   upstream, not here.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── §1 THE ROLES THE LITERALS ARE REACHING FOR ─────────────────────────────
   The second material. The token block describes one — gilt struck into
   leather — and the game has two: aged paper, the thing a war-room draws on.
   The cartouche, the campaign sheet, the war map and the results scroll each
   mixed it independently out of #33281a / #1b140d / #0f0b07 and a foxing
   wash. Named once, here.

   --parchment was already being READ at two call sites (.sc-line and
   .pf-oath b) and never defined, so both took their fallback. The value
   below IS that fallback, so nothing moves; the reference stops dangling.

   The cartouche is deliberately not rebuilt from these here — see the hazard
   above. Its live rule is the translucent one at style.css:5684, whose washes
   are stronger than these and whose vellum is let go to ~0.83 alpha; folding
   it onto the roles wants an alpha step for the vellum and belongs upstream. */
:root {
  --vellum-lit:    #33281a;  /* the lit face of the sheet — a cartouche's top */
  --vellum:        #1b140d;  /* the body of it */
  --vellum-deep:   #0f0b07;  /* its shadowed underside, and the seat of a fold */
  --parchment:     #e8dcc0;  /* INK ON vellum. The one already referenced twice. */
  --parchment-dim: #c8b68a;  /* the same hand, faded — a legend, a footnote */
  --foxing: rgba(196, 150, 74, 0.13);     /* old-paper stain. Corners only. */
  --fibre:  rgba(var(--lit-rgb), 0.030);  /* the grain, at the light's own angle */
  /* the whole sheet as one value, for every panel that is PAPER rather than plate */
  --vellum-plate: linear-gradient(158deg, var(--vellum-lit), var(--vellum) 62%, var(--vellum-deep));

  /* a category colour that is missing is grey-gold, not black — ui.js already
     falls back to this exact literal at the point of use (ui.js:4823) */
  --cat-none: #b8a06a;
}

/* ── §2 SIXTEEN DINGBATS → THE ENGRAVED SET ────────────────────────────────
   icons.js exists for exactly this, and its own header says so. Each mark
   below is that file's path byte for byte, stroked in black because a mask
   reads only alpha, and carried as a token so a rule names the mark rather
   than pasting it — the same "name a role" the colours keep.
   Three kinds of site, three treatments:
     · a GLYPH STANDING ALONE — a price's purse, a button's device — becomes
       an empty box inked in currentColor through the mark, so it keeps the
       colour, position and size the sheet already gave the glyph;
     · a STAR WITH A GLOW keeps the glow. A mask clips everything the element
       paints — its text-shadow, its filter, its box-shadow — so the halo the
       ★ wore is carried as a second mask layer rather than lost;
     · a TICK ON A DISC keeps the disc. The owned badge is a filled green
       coin, and a mask would cut the whole coin down to a tick, so there the
       mark is laid OVER the disc as an image, inked the badge's own ink. */
:root {
  --mark-spark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.4l1.7 6.9 6.9 1.7-6.9 1.7-1.7 6.9-1.7-6.9-6.9-1.7 6.9-1.7z' fill='black' fill-opacity='0.16'/%3E%3C/svg%3E");
  --mark-coin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.4'/%3E%3Ccircle cx='12' cy='12' r='5.5'/%3E%3Cpath d='M12 9.2v5.6M9.6 12h4.8'/%3E%3C/svg%3E");
  --mark-swords: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.1 3.9 15.6 13.4l-2.2 2.2L3.9 6.1z' fill='black' fill-opacity='0.18'/%3E%3Cpath d='M17.9 3.9 8.4 13.4l2.2 2.2 9.5-9.5z' fill='black' fill-opacity='0.18'/%3E%3Cpath d='M6.1 3.9 15.6 13.4M17.9 3.9 8.4 13.4'/%3E%3Cpath d='M3.9 6.1 13.4 15.6M20.1 6.1 10.6 15.6'/%3E%3Cpath d='M9.2 17.4h5.6M9.2 17.4 7.4 20.4M14.8 17.4l1.8 3' stroke-width='2'/%3E%3Ccircle cx='6.6' cy='21' r='1.3' fill='black' stroke='none'/%3E%3Ccircle cx='17.4' cy='21' r='1.3' fill='black' stroke='none'/%3E%3C/svg%3E");
  --mark-banner: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 3.4v17.2'/%3E%3Cpath d='M7 4.8h10.4l-2.4 3.6 2.4 3.6H7z' fill='black' fill-opacity='0.14'/%3E%3C/svg%3E");
  --mark-crown: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.6 17.6L3.9 8.8l4.5 3.3L12 6.2l3.6 5.9 4.5-3.3-.7 8.8z' fill='black' fill-opacity='0.14'/%3E%3Cpath d='M4.6 20h14.8' /%3E%3Ccircle cx='12' cy='13.6' r='1' fill='black' stroke='none'/%3E%3C/svg%3E");
  --mark-castle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.4 20V9.4h2.7V7.4h2v2h3.8v-2h2v2h2.7V20z' fill='black' fill-opacity='0.12'/%3E%3Cpath d='M10.5 20v-3.8a1.5 1.7 0 0 1 3 0V20'/%3E%3C/svg%3E");
  /* the spark, struck SOLID: at the 10–12px a corner star is drawn at, the
     set's 1.8 outline is under a pixel wide, and a star that has to be read
     at a glance cannot be a hairline */
  --mark-spark-solid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black' stroke='black' stroke-width='1.8' stroke-linejoin='round'%3E%3Cpath d='M12 3.4l1.7 6.9 6.9 1.7-6.9 1.7-1.7 6.9-1.7-6.9-6.9-1.7 6.9-1.7z'/%3E%3C/svg%3E");
  /* the tick PRE-INKED, in the #06150b the sheet's own badge sets its ✓ in —
     for the one site where the mark sits on a fill and so cannot be a mask.
     Struck at 3 rather than the set's 2.6: the glyph it replaces was 800. */
  --mark-tick-on-ready: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2306150b' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.2 12.8l4.3 4.4 9.3-10.4'/%3E%3C/svg%3E");
}

/* The mechanics, once. Every site in this list is an empty box inked in
   currentColor through whichever mark its own rule below names as --mk. The
   fallback is a mask that hides everything: a site that forgot its --mk
   shows nothing, rather than a solid square of gilt. */
.rules li::before,
.rd-p.gd::before,
#fortifybtn .fb-cost::before,
.reswarpath::before {
  content: '';
  background-color: currentColor;
  -webkit-mask: var(--mk, linear-gradient(transparent, transparent)) center / contain no-repeat;
  mask: var(--mk, linear-gradient(transparent, transparent)) center / contain no-repeat;
}

/* the chronicle's bullet — a struck spark, not a fleur-de-lis. No markup
   builds a .rules list any more; kept so a revived one is born in the set. */
.rules li::before { --mk: var(--mark-spark); width: 0.92em; height: 0.92em; top: 0.18em; }

/* the purse, wherever a price is prefixed by one — its trailing space was
   the glyph's own gap, and is a margin now */
.rd-p.gd::before { --mk: var(--mark-coin); display: inline-block; width: 0.95em; height: 0.95em;
  vertical-align: -0.12em; margin-right: 4px; }
#fortifybtn .fb-cost::before { --mk: var(--mark-coin); display: inline-block; width: 0.95em; height: 0.95em;
  vertical-align: -0.12em; }

/* the war path's own device on the results scroll — the sixteenth site, the
   one the audit's count missed because its content: is double-quoted. The
   glyph's line box stood 1.5em tall and was the tallest thing in the strip,
   so the box keeps that height (the mark is contained, centred, inside it)
   rather than letting the strip drop 3px the moment the glyph goes. */
.reswarpath::before { --mk: var(--mark-swords); width: 1em; height: 1.5em; flex: none; }

/* (THE MODE BUTTONS' devices stood here — six ::before marks standing in for
   the ⚔ ⚑ ♛ ⛁ ♜ glyphs the sheet printed on them. Retired upstream: the home
   screen's battles are two-line plates now, a name over the one fact that
   makes each battle that battle, and wear no device at all; the campaign is a
   door in the row under them, with its keep struck in its own icon slot.) */

/* SIGNATURE — the gold star a kingdom's own troop wears, in three places.
   The box grows past the glyph by the reach of the glow it wore (a 6px
   text-shadow), and the margins pull it back so the spark's centre lands on
   the ★'s: measured, the glyph's box was ~0.83em wide and ~1.45em tall (a
   line of `normal` height), which is why the two pulls are not equal. The
   colour is still the sheet's own --gilt-lit. */
.md-troop.sig::after,
.achip.sig::after,
.armcard.sig .armiconwrap::after {
  content: '';
  width: 2.1em; height: 2.1em;
  margin: -0.32em -0.63em 0 0;
  background-color: currentColor;
  -webkit-mask: var(--mark-spark-solid) center / 48% 48% no-repeat,
    radial-gradient(closest-side, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
  mask: var(--mark-spark-solid) center / 48% 48% no-repeat,
    radial-gradient(closest-side, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}

/* OWNED — the tick the engraved set was missing, on the green coin the sheet
   already strikes for it. Only the glyph changes: the disc, its rim, its glow
   and its corner are all still the sheet's. */
.md-troop.own::before,
.achip.owned::before,
.armcard.owned .armiconwrap::before {
  content: '';
  background: var(--mark-tick-on-ready) center / 62% 62% no-repeat,
    linear-gradient(180deg, var(--ready-lt), var(--ready-dk));
}

/* THE GLYPHS IN MARKUP, which no stylesheet can reach, are fixed at source:
   icons.js gained `tick`, `close` and `link`, and ui.js wears them on
   '✓ Owned' (three places), '✕ Clear filters' (two), '🔗 Copy Link' and the
   '✔ Copied' it flips to. What is still open in markup is in docs/AUDIT.md. */

/* ── §3 BARE `ease` → THE TWO CURVES ───────────────────────────────────────
   130 declarations use a bare keyword. The distinction kept: an INFINITE
   BREATHING LOOP (bready, auraBreathe, msBreathe, emBob, flicker) is a sine,
   not an arrival, and genuinely wants ease-in-out — those are left alone.
   TRANSITIONS and ONE-SHOT ENTRANCES take the tokens. Each selector below has
   exactly one transition or animation rule in style.css, checked, so nothing
   later in the sheet is overridden. */
.chip.minted { animation: mintFlash 0.75s var(--e-back); }
.build.levelup { animation: blevelup 0.9s var(--e-out); }
.buygold { transition: transform var(--t-1) var(--e-out), filter var(--t-1) var(--e-out); }
.armcard { transition: transform var(--t-1) var(--e-out), border-color var(--t-2) var(--e-out), box-shadow var(--t-2) var(--e-out); }
#emotebtn, #marchallbtn, #stopbtn { transition: transform var(--t-2) var(--e-out), filter var(--t-2) var(--e-out); }

/* ── §4 THE RADII BACK ONTO THE EIGHT-STEP SCALE ──────────────────────────
   2px and 3px → --r-xs · 4px and 6px → --r-sm · 14px → --r-xl. Mechanical:
   the scale's large end is for things that are genuinely soft, and none of
   these is. Each selector has a single radius rule in style.css, checked. */
.rk-rung, .fg-sw span, .cp-mapkey i { border-radius: var(--r-xs); }
.cg-cell.mirror::before, .cta-banner, .rd-pb, .rd-pb i, .rd-p { border-radius: var(--r-xs); }
.rd-bar, .rd-bar i, .wp-rail, .wp-fill, .cp-dot { border-radius: var(--r-sm); }
/* the parley bubble (style.css:10469) is the sheet's one 14px. The hand-off
   aimed this line at .pb-code-big, which was already on --r-xl. */
.plb { border-radius: var(--r-xl); }

/* ── §5 THE LAST ITALIC ───────────────────────────────────────────────────
   style.css:12655. The sheet resets em/i to normal two hundred lines above
   it and then slants this one line by hand. Voice is colour, size and the
   speaker's crest — never a slant — so the aside keeps its quieter voice in
   the campaign sheet's own faded ink instead. */
.cp-boonsempty { font-style: normal; color: var(--parchment-dim); }

/* ── §6 THE PIXEL RULE, STATED PROPERLY ──────────────────────────────────
   THE BAKE DECIDES, NOT THE TASTE. Sprites are baked large and the HUD
   draws them smaller, so nearly every figure in the interface is a DOWNSCALE
   and smoothing is what keeps the armour crisp — which is why .ms-art and
   #unittip .ut-art both keep auto on purpose (the reasoning is at
   style.css:5069). Nearest-neighbour is right only for art drawn at or above
   its bake, AND only for art that is pixels to begin with.
   .pb-kc is on the wrong side of both: a painted crest squeezed into a 34×40
   canvas and shown at 30×36 — a downscale on a 1× screen, and an uneven,
   non-integer blow-up on a 2× or 3× one. Nearest-neighbour is wrong for both,
   and it is where the war-band rail's kingdom heads lose their outline. */
.pb-kc { image-rendering: auto; }

/* ── §7 WHAT IS DELIBERATELY NOT IN THIS FILE ────────────────────────────
   · The 141 gold literals. They want retiring screen by screen behind the
     roles in §1 — not a global override, which would flatten four screens'
     worth of deliberate hand-tuning in one line.
   · The 254 hand-rolled box-shadows. Half of them are GLOWS, which are a
     different job from elevation; the ladder applies to the other half, and
     telling the two apart needs eyes on each one.
   · The cartouche's vellum (see §1) — upstream, not here.
   All three are in docs/AUDIT.md with counts, in the order worth doing them. */
