/* Mid-Autumn — the first seasonal skin (docs/SKINS.md, issue 121 stage E).

   ONE :root BLOCK, and nothing else is honoured (SKINS.md §4). No selector,
   no media query, no rule that could move a box: a skin changes paint, never
   geometry (§1). Every name below is a slot the app already provides — the
   imagery slots declared in public/spelling/tokens.css, and the colour tokens
   that file names. Anything not listed here keeps its default.

   EVERY url() IS ROOT-RELATIVE, and that is not a style preference. A
   relative url() inside a custom property is resolved against the DECLARING
   stylesheet by the CSS Variables spec and against the SUBSTITUTING one by
   Chromium; this file is served from /spelling/skin.css and its images live
   under /skins/mid-autumn/, which sits exactly on that fault line. A leading
   slash means the same thing to both.

   THE PALETTE IS MEASURED, not sampled. The starting values came off the
   mockups (§7); every one of them was then checked against every surface it
   can land on, and several were darkened until they cleared it. The ratios
   are recorded beside the tokens they belong to. Four things are worth
   knowing before editing any of them:

     * --bg-card carries an ALPHA. The wallpaper is meant to be seen through
       the card face, which is what §1 settled in place of the mockups'
       card-less Home. Text is therefore measured against the COMPOSITE of
       this face over what is behind it, never against the face's own
       channels.
     * --bg-body is the wallpaper's own centre band, measured and then
       lightened by (0, +2, +7). It is almost never seen — body::before covers
       the viewport — but it is what §7 says the sweep composites the alpha
       over, so a value that did not come off the artwork would make every
       ratio in this file a fiction. The derivation, and what the adjustment
       is worth, are recorded beside the token.
     * WHAT IS REALLY BEHIND THE CARD IS THE ARTWORK, AND ITS TOP IS A NIGHT
       SKY. §7's model is the contract and this palette clears it, but the
       model's backdrop is a mean and the wallpaper's darkest pixel is nearly
       black — so every text token here also clears 4.5 against the card face
       composited over THAT: rgb(224, 220, 213). Four tokens were darkened
       until they did (--muted, --strike, --strike-faint, --placeholder), and
       the defect that forced it was real, not theoretical: at the first
       values the Sky's "Word n of m" pill measured 4.24:1 on the screen.
     * --warn-text is darkened here. Its default (#d97706) is 3.19:1 on the
       card and 3.02:1 on the body — an AA gap in the BASE look that this skin
       may not fix for everyone (that is its own issue and its own baseline),
       but must not inherit either: §7 gives a skin no ratchet exceptions. */

:root {
  /* Required. It is what makes the opt-out pill appear (SKINS.md §3); with
     no --skin-name on the page there is no pill and no skin. */
  --skin-name: "mid-autumn";

  /* ── Imagery ─────────────────────────────────────────────────────────
     The app decides where each of these paints. The skin only says what. */

  --wallpaper-portrait: url("/skins/mid-autumn/wallpaper-portrait.webp");
  --wallpaper-landscape: url("/skins/mid-autumn/wallpaper-landscape.webp");

  /* --banner-image and --banner-h are NOT set, and that is a DECISION, not an
     oversight or a blockage. The owner tried the strip on the staged app
     (2026-09-02) and ruled against it: the night sky belongs to the
     wallpaper's own top, and a band across the card's head is a second sky
     competing with it. banner.webp stays in this folder — §6 lists the banner
     as optional and the asset is a legal one — and the slot stays empty.

     THE HISTORY, briefly, because the next skin will want it. A strip does not
     start at the screen's top edge; it starts at the CARD's, and on a session
     screen the card's first row is the Sky's own head. Measured at
     --banner-h: 112px with this folder's banner.webp: the back link read
     1.03 : 1 and the "Word n of m" pill 1.71 : 1 against what the strip put
     behind them. The app has since given that row its own paint (the --sky-…
     slots below), but those are sized for the WALLPAPER through a translucent
     card, not for a banner: a skin that wants a strip has to measure the row
     against it again, and docs/SKINS.md §6 says so. */

  /* The head row, over the wallpaper (SKINS.md §4, issue #142). --ink-2 and
     --muted cannot be lightened for this one row without unreading the rest of
     the card, so the app gives it slots of its own.

     SINCE 2026-09-03 THE ROW SITS ON CHIPS: a cream glass pill under the back
     label and under "Word n of m" — the card face's own cream at 0.82 with
     a 6px blur of the artwork behind it and a hair of shadow to lift it —
     and the ink on them is the card's ordinary dark ink, hover in
     --coral-text. The owner chose this on the staged app after a day with
     the previous answer: near-white ink with a hard dark outline (round 5's
     zero-blur offset copies, still in git), which was legible but fought
     the artwork glyph by glyph, read as a sticker, and would have needed
     re-tuning for every skin. A chip needs none of that: pick a face and
     an ink that read on each other and the row reads on any wallpaper.
     Neither shadow slot is set here any more; the app's defaults (`none`)
     apply. The legibility gate reads the ink against what the screen
     paints, chip included.

     The ink's worst case, by arithmetic rather than hope: over a night-sky
     pixel as dark as rgb(30, 40, 90) the 0.82 face composites to
     rgb(214, 212, 213), and over the palest cloud to the cream itself.
     #26203a reads 10.6 : 1 on the first and 15.0 on the second; #5e180b
     8.9 and 12.6. The gate measures the real pixels. */
  --sky-back-ink: #26203a;
  --sky-back-ink-hover: #5e180b;
  --sky-meta-ink: #26203a;
  --sky-chip-bg: rgba(255, 250, 240, 0.82);
  --sky-chip-shadow: 0 1px 2px rgba(17, 14, 38, 0.18);
  --sky-chip-blur: blur(6px);

  /* Home's greeting (--hello-text-shadow) is NOT set here. The soft cream
     glow behind it is the app's own default in both looks (owner,
     2026-09-03: first a hard ring in this file, then the glow, then "in
     both festival and plain look"), and this skin's greeting is the same
     dark ink on the same cream, so the default is the value. A skin whose
     greeting were light on dark would set a dark glow. */

  /* Muted text on a session screen's face, with no panel of its own behind
     it — Learning's stage labels and (since issue #147 D2 round 2) dictation
     Learn it's caption, both against the wallpaper. --muted measured 2.98 /
     3.15 there at this face's alpha; --ink is the token that clears — 6.99
     and 7.40 on the same two backdrops — and using it leaves the --muted /
     --ink-2 hierarchy alone (owner, 2026-09-02). Renamed from
     --sb-label-ink for the second consumer; the value stands. */
  --session-muted-ink: var(--ink);

  /* The dictation results readout, on the card face with no panel of its
     own. At 320 wide this card reaches the screen's edges, and the wallpaper's
     side blossoms sit under the passage: --ink-2 read 58 % under AA there at
     this face's alpha, invariant to the panel and tray slots because the
     readout sits on neither. Its own face at 0.85 over the 0.25 card is
     ~89 % cream, which every text token clears. */
  --results-diff-bg: rgba(255, 250, 240, 0.85);

  /* The star, dressed rather than replaced (SKINS.md §6): the same mark with
     a Mid-Autumn tassel. PNG, not SVG — no vector source exists in the
     approved set, and §6 permits a 600x600 PNG. Square, like the mark it
     stands in for, so every box it lands in keeps its size. */
  --mascot: url("/skins/mid-autumn/mascot.png");

  --card-corner-tl: url("/skins/mid-autumn/card-corner-tl.webp");
  --card-corner-br: url("/skins/mid-autumn/card-corner-br.webp");
  --btn-ornament: url("/skins/mid-autumn/btn-ornament.webp");

  /* All four, since issue #143. The app fixes where these paint (SKINS.md §6),
     and slot 2 shipped empty because its position was wrong twice over:

       at `calc(100% - 6px)` / 14px  it sat on the Sky's "Word n of m" pill —
                                     69.8 % of that pill on a phone at 320 and
                                     at 390, and 38.2 % / 33.3 % of the pill at
                                     its longest ("Word 500 of 500 · coming
                                     back", three lines at 320). Issue #143
                                     records 69.3 %; the half-point is the
                                     pill's 15.6px height rounding into an
                                     integer area, not a different finding.
       at `calc(100% - 6px)` / 72px  it cleared the pill and landed on Write
                                     it: with the in-app keyboard drawn that
                                     screen's phrase rail rises to y=83, and
                                     the layer repainted 60.2 % of
                                     #btnDictStartNext and 93.8 % of its "Next
                                     phrase" label at 320x568.

     It is at 0% across and 210px down now — the left edge, below slot 3 — and
     ornament-2.webp is off the bench.

     THE LINE, drawn once for the whole folder: an ornament may not repaint
     more than a THIRD of any control or text box. Every reading below is that
     repaint, taken with each layer really on and then off, over 39 screen
     states: eleven screen classes (login, Home, Browse, Ready, Spell it —
     also with the longest pill — Learning, Results, Learn it, Write it,
     Dictation results) at 320x568, 390x844 and 1280x900, plus three more at
     the two PHONE widths only, where the in-app keyboard is drawn, the stage
     is short and everything in it moves up: Spell it, Write it, and Write it
     with its coach row holding the empty-answer nudge. Three kinds of box in
     each — whole controls, whole text elements and glyph line boxes. Worst
     first:

       slot 4 over #btnDictStartNext  29.0 % of its "Next phrase" label and
                                      23.0 % of the button, at 320x568 with no
                                      keyboard — the folder's worst reading,
                                      and the least margin in it
       slot 4 over .sb-label          20.2 % at 390 (Learning's third stage
                                      label); 6.0 % / 3.9 % over Home's h2
       slot 1 over a back link        19.8 % of #btnQuizBack / #btnLearnBack
                                      and 9.4 % of its "Ready" label; 17.8 %
                                      of #btnDictStartBack and 7.6 % of its
                                      "Learn it" label — both phone widths
       slot 1 over #guestBanner       8.4 % at 320, 5.7 % at 390 — its left
                                      end, not the centred sentence
       slot 2 over #btnDictStartPrev  15.9 % of the button and 8.7 % of its
                                      "Previous phrase" label, at 390 with the
                                      keyboard drawn
       slot 2 over span.ready-label   13.8 % of its glyphs at 320
       slot 2 over #browseListName    13.7 % at 320, 9.8 % at 390
       slot 2 over #btnQuizRepeat     11.5 % at 320
       slot 3, anything               6.4 % at most (#startListName at 320) —
                                      its sprite's own ink is 8 % of its file
       ANY slot over #quizSeqPill     0 px. Every slot, every width, both pill
                                      strings, keyboard drawn and not
       every slot at 1280x900         0 px against every control and text box
                                      on every screen — the card is a centred
                                      column and these are anchored to the
                                      viewport

     All four clear the third; slot 4 clears it by 4.3 points and nothing else
     is close. What holds that is `no ornament covers more than a third of any
     control or text box` in test/playwright/mid-autumn-skin.spec.js, which
     re-takes this whole table on every run. It reads the SCREEN, so it is
     about opaque ink rather than about the 72px squares the app positions;
     the squares are held apart, and above the dock, by two gates of their own
     in skin-slots.spec.js. */
  --ornament-1: url("/skins/mid-autumn/ornament-1.webp");
  --ornament-2: url("/skins/mid-autumn/ornament-2.webp");
  --ornament-3: url("/skins/mid-autumn/ornament-3.webp");
  --ornament-4: url("/skins/mid-autumn/ornament-4.webp");

  /* Both dimmers to 0 — SKINS.md §4's wallpaper rule. They are MULTIPLIERS
     over the base look's own opacities, so 0 is what puts the blurred blobs
     and the twinkling glyphs out; leaving them lit would put the base look's
     decoration on top of the artwork's. */
  --decor-blob-opacity: 0;
  --decor-star-opacity: 0;

  /* ── Surfaces ────────────────────────────────────────────────────────── */

  /* The wallpaper's own centre band, measured off the artwork and then
     lightened — measured-THEN-ADJUSTED, not a mean anything produces. The
     mean of the artwork's centred 720x800 band is rgb(253, 234, 201); this is
     that value plus (0, +2, +7), which is the warm cream the mockups' page
     ground actually is. The adjustment is upward, so it makes every ratio in
     this file very slightly more generous than the artwork alone would: the
     palette was therefore checked against BOTH, and clears §7 at 48/48
     against each (its worst pair, --warn-text on this surface, is 5.44
     declared and 5.35 against the measured mean). */
  --bg-body: #fdecd0;
  /* The card face, translucent so the artwork reads through it. Composited
     over --bg-body that is rgb(255, 248, 236) — the colour every text ratio
     in this file is measured against, and the one §7 says the sweep uses. */
  --bg-card: rgba(255, 250, 240, 0.25);
  /* …and the same face at the app's own desktop breakpoint
     (`@media (min-width: 720px)`, tokens.css / index.html, #124) — a flat
     value, filled the same way as any other slot, because this file stays
     one :root regardless (§4). 0.80 is the floor the 1280 AA sweep bisected
     to in the previous round (0.75 leaves two dark-ink readings at
     4.16 / 4.42, just under 4.5); the head-row gate's own regression at that
     alpha is what B' fixes, on the ink side, not this one. */
  --bg-card-desktop: rgba(255, 250, 240, 0.80);
  /* Opaque, deliberately. An answer field is the one surface a child stares
     at while typing, and it is the only place in the app where a wallpaper
     showing through would compete with their own letters. */
  --bg-input: #fffaf0;
  /* THE STICKY TRAY, in two versions, because the browser decides which one
     it can draw. The app gates the pair on backdrop-filter (index.html's
     .dock; a skin is one flat :root and cannot carry an @supports itself).

     --dock-bg is the FALLBACK, and it is opaque on purpose: rgb(254, 240,
     216) is the exact colour --bg-card already resolves to — that face at
     0.25 over --bg-body — which is the surface every text ratio in this file
     is measured against (see the header, and the --bg-card note above). So it
     is not a new surface to check; it is the one the numbers were always
     about, written out. It moved with the face: at 0.88 it was #fff8ec. It may not carry the card's alpha, because the tray
     paints over the card AND again over the page where it full-bleeds, so
     0.88 would double-paint a lighter band and haze the wallpaper under it —
     the defect round 1 fixed, and the state a no-blur browser must not be
     dropped back into.

     --dock-bg-frost + --dock-blur are what a browser with backdrop-filter
     gets, and they exist because opaque cream solved the haze and left an
     asymmetry: at the phone's full bleed those edges sit on the wallpaper's
     dark frame, where flat cream reads as a white bar stuck across the art,
     while on a desktop the same cream sits on the pale centre band and
     vanishes. Frosting makes both the same tray — the frame's own colour
     glows through, blurred, instead of being covered.

     NOTHING MEASURED CONSTRAINS THIS ALPHA, and saying so plainly matters,
     because the opposite is the easy thing to imply and it would be false.

     There IS real text on this face — the Results screen's .result-link
     ("Home", "Try again") declares `background: none`, so its --ink-2 letters
     sit on the frost with the blurred artwork behind them, and "every text
     box clears AA against its own backdrop" screenshots exactly that at
     320x568 and 390x844. NOT at 1280x900: index.html resets `.dock` to
     `background: none` / `backdrop-filter: none` at its own desktop
     breakpoint (#139), so there is no tray there at all and the same links
     are read against the card face instead — a different claim, and one the
     static AA matrix already covers on its own. 0.66 passes what it is
     actually measured against.

     SO DOES 0. The gate was probed at the zero endpoint — the frost removed
     altogether, alpha 0 and no blur — and it still passes, because those
     links are centred over the card, where the backdrop is the card face over
     the wallpaper's calm middle whatever the tray does. A check that accepts
     the whole range gives no lower bound: it neither constrains this number
     nor selects it, and it must not be cited as though it did.

     0.66 IS A DEVICE DECISION, made by eye against the artwork: dark enough
     behind the links, light enough that the frame's colour reads through the
     tray's full-bleed edges. Change it the same way, on a device. */
  --dock-bg: #fef0d8;
  --dock-bg-frost: rgba(255, 248, 236, 0);
  --dock-blur: blur(16px);

  --card: #fffaf1;
  --paper: #faf1e0;
  --paper-2: #f2e5c9;

  --bg-sunken: #f7e8cd;
  --bg-tray: #faf1e0;
  --bg-slot: #fdf8ef;
  --bg-press: #ffefcd;
  --bg-select: #eaeffb;

  --border-card: #f2dcae;
  --border-input: #e8d2a2;
  --hairline: #f0e5d3;
  --dot-idle: #dbcdb2;
  --hover-tint: #fdeccf;

  /* ── The moon: the gold family ───────────────────────────────────────
     Repainted together, as tokens.css requires — --sun with --sun-light,
     --sun-deep, --sun-shadow, --sun-tint, --sun-tile and --on-sun.
     --on-sun on --sun is 9.26:1; the chunky ledge --sun-shadow against the
     gradient's end --sun-deep is 1.40:1, over §7's 1.27 floor, so the 3-D
     step still reads. The base look's own step is 1.277, so this one is a
     little firmer and not a different kind of thing. */
  --sun: #fdc548;
  --sun-light: #ffe08a;
  --sun-deep: #ef9f1e;
  --sun-shadow: #cb8503;
  --sun-tint: #fff5dd;
  --sun-tile: #ffe4a6;
  --on-sun: #3a2400;

  /* ── The lanterns: the coral family ──────────────────────────────────
     --coral stays decorative (borders, fills, the blob that this skin puts
     out anyway); --coral-text is the readable half. Round 4: the head-row
     em's (Home's greeting, login's "Speller!") sit over the wallpaper's grey
     band showing through the 0.25-alpha card face, and #ac3316 only cleared
     2.62-3.73 : 1 there — below AA. The owner's rule is darken the token,
     never raise the face's alpha, so two passes at it: #782110 (luminance
     ~0.051) still measured only 4.17 : 1 on Home's greeting at 390 (composite
     rgb(172, 162, 162), luminance ~0.372), and #6c1c0d (~0.040) still left
     37.6 % of the same run under AA (worst 3.79 : 1) — a darker patch again,
     closer to luminance ~0.29. Round 5 bisected bounded by a luminance floor
     of 0.030 (the owner's line for "the token stops being coral"): #5e180b,
     luminance ~0.0306 — a hair above the floor — clears the Home greeting at
     every width this file sweeps (320/390/1280), so the floor was never
     actually hit. */
  --coral: #f0714c;
  --coral-text: #5e180b;
  --coral-deep: #d9532d;

  /* ── Jade ──────────────────────────────────────────────────────────────
     --mint-text cleared the static AA matrix (body/card/input) at #126750,
     but round 4's own coverage fix (forceLearningBuildIt, mid-autumn-skin.
     spec.js) reached the one place it is real production ink — Learning's
     "See it" stage bar, done, over the card face — for the first time, and
     the composite there is darker still than the coral grey band: 2.33 : 1
     at 390, never clearing AA anywhere in its own glyphs. Same owner's rule
     as --coral-text: darken the token, never the face's alpha. #0a2e23
     (luminance ~0.021) clears the backdrops measured at every width this
     round, with more margin than --coral-text needed, and only helps the
     static matrix further. */
  --mint: #3fbf9a;
  --mint-text: #0a2e23;

  /* ── The night sky: the accent family ────────────────────────────────
     Repainted together, as tokens.css requires — --accent with its five
     --accent-tint-* alphas and --border-focus. The five are written out
     rather than derived for the reason tokens.css gives: relative colour
     syntax is not verified against the devices this app serves.
     --accent-text is 8.60 / 9.47 / 9.60 on the three surfaces and 7.85 on
     --accent-tint; --mint-text clears the same three (round 4's darkening
     above only raises them); --text-primary on --sun-tint 14.34. */
  --accent: #4b6fbe;
  --border-focus: #4b6fbe;
  --accent-tint: #dde4f6;
  --accent-text: #22407e;
  --accent-tint-06: rgba(75, 111, 190, 0.06);
  --accent-tint-07: rgba(75, 111, 190, 0.07);
  --accent-tint-08: rgba(75, 111, 190, 0.08);
  --accent-tint-10: rgba(75, 111, 190, 0.1);
  --accent-tint-25: rgba(75, 111, 190, 0.25);
  --scrim: rgba(18, 17, 41, 0.72);
  --sky: #a9cdf0;

  /* ── Text ────────────────────────────────────────────────────────────
     --ink / --ink-2 are index's names and --text-primary / --text-secondary
     login's, for the same two roles. A skin is the one file that can give
     them one value each, and this one does: the sheet is linked after each
     page's own <style>, so it beats login's surviving :root line on source
     order. Ratios on --bg-body / --bg-card / --bg-input, and in the last
     column on the card face over the wallpaper's darkest pixel:

       --ink            13.40 / 14.76 / 14.95   11.39
       --ink-2           7.87 /  8.67 /  8.78    6.69
       --muted           5.62 /  6.20 /  6.28    4.78
       --strike          5.83 /  6.43 /  6.51    4.96
       --strike-faint    5.49 /  6.04 /  6.12    4.67
       --placeholder     5.72 /  6.30 /  6.39    4.87

     --strike keeps its step over --strike-faint, small as it is: it is the
     only thing separating a word spelled wrong from a word that should not
     have been written at all. --placeholder keeps its own distance from
     --ink, or an empty field reads as a full one. */
  --ink: #26203a;
  --ink-2: #4a4463;
  --text-primary: #26203a;
  --text-secondary: #4a4463;
  --muted: #625a70;
  --text-strong: #1a142b;
  --text-dim: #4f4740;
  --strike: #625a51;
  --strike-faint: #665e55;
  --placeholder: #6d5a33;

  /* ── Feedback ────────────────────────────────────────────────────────
     --warn is the guest banner's label on --warn-bg (5.23:1). --warn-text is
     the dictation table's "missing" mark and lands on the page surfaces
     instead; darkened from the default to 5.44 / 5.99 / 6.07 on body / card /
     input and 4.63 over the artwork's darkest — see the header. --ok-text on
     --ok-bg is 6.84:1; --wrong-text 8.85 / 9.74 / 9.87. */
  --ok-bg: #d8f2e5;
  --ok-border: #14a97e;
  --ok-text: #0a5b45;
  --wrong-text: #7d1b1b;
  --warn: #a04b07;
  --warn-bg: #ffeecb;
  --warn-border: #eed49c;
  --warn-text: #8c5206;
  --danger: #b02318;
  --danger-bg: #fde9e3;
  --danger-border: #f3c1b4;
}

/* A per-width card face was first attempted as a media query IN THIS FILE
   and reverted (issue #142): it broke "one flat :root" (SKINS.md §4) and six
   tests with it, one saying plainly "a nested rule hides a selector where no
   sweep looks". --bg-card-desktop above is the fix that keeps the contract —
   the APP owns the breakpoint (its own existing
   `@media (min-width: 720px)`) and reads the slot there; this file stays
   one flat block and just fills it, like every other slot. */
