/* app-skins.css — SKINS — the html[data-skin="…"] variable overrides.

   ⚖ ONE STYLESHEET, TEN PARTS, AND THE ORDER IS THE CASCADE. This was web/app.css, a single
   5,357-line file, until the 2026-08-05 split (it held lines 3559-3767). The parts must be
   linked in this order on every page:
     app.css → app-rank.css → app-curation.css → app-moderation.css → app-profile.css → app-feeds.css → app-tagrows.css → app-skins.css → app-builder.css → app-viewer.css
   That is not tidiness, it is the specificity tie-break: two rules of equal weight are
   resolved by which one comes LAST, and this file's own sections rely on it — "THE LAST WORD
   ON MODIFIER VERBS" (in app-viewer.css) says in its heading that it must be the final say.
   Re-ordering the <link> tags re-orders the cascade and changes what the site looks like,
   silently, on whichever surface the tie mattered. server/tests/cssparts.test.js pins the
   order on all 18 pages.

   ⚠ The xp-*.css files load AFTER every part, exactly as they loaded after the whole of
   app.css before. Do not insert a part below them. */
/* =====================================================================
   SKINS (owner request 2026-07-26) — `html[data-skin="…"]` var overrides ONLY.
   The default (terminal) is the bare :root above; no data-skin attribute means
   terminal, so a skin can never break the default surface. common.js applies
   the attribute at parse time (before <body>) so there is no repaint flash,
   and stamps data-light="1" for the light skins.

   ADDING A SKIN: one block of vars here + one entry in SKINS in common.js.
   Nothing else. If a skin needs a rule that is not a var, the var seam is
   missing — add the var rather than a per-skin structural rule.

   ⚖ A SKIN'S --faint IS BOUND BY THE 4.5:1 FLOOR (owner ruling 2026-08-19,
   docs/DECISIONS.md "The quiet still has to be readable"). Every --faint below was
   RECOMPUTED on 2026-08-19: each is the SMALLEST lightness-only move off its old value
   that clears 4.5:1 against the worst background that skin puts it on — hue and
   saturation held to within rounding, L moved and nothing else, and one 8-bit step back
   toward the old colour measures below 4.5. The old values scored 2.65–4.16:1 and were
   751 of the 753 CONTRAST findings in the harness's 6,921-row first run.
   ⛔ These are floor values, not taste values. Do not lower them back down, and do not
   raise them further "for consistency" — a new skin computes its OWN minimum the same
   way. --faint is used at 10–14px, so no large-text exemption is ever available.

   ⚖ AND SO IS --dim, THE TIER ABOVE IT (owner ruling 2026-08-20, docs/DECISIONS.md
   "The tier above the quiet had the same floor" — forage-8tu). forage-40p aimed each
   --faint at "the worst background the tier ABOVE it already clears", and on three skins
   --dim itself was under 4.5:1 on --raised (yotsuba 3.16 and 4.02 on --panel too,
   yotsuba-b 4.03, tomorrow 4.30). Those three --dim values were RECOMPUTED on 2026-08-20
   by the same method — smallest lightness-only move, H/S held, one 8-bit step back
   measures below 4.5 — and the --raised salmon/periwinkle were left alone because they
   are the REAL 4chan palette and retinting them is an owner taste call, not a mechanical
   one. ⛔ NEVER close this gap from below: pushing --faint past --dim inverts the tonal
   ladder and is the closed road in that ruling. **ink > dim > faint holds on all seven
   skins on all four surface tokens** and that ordering is the invariant — check it before
   you touch any of the three.

   ⚖ AND THE MONEY COLOUR HAS THE SAME FLOOR, ON THE TWO LIGHT SKINS ONLY (owner 2026-08-26:
   *"perhaps we also color the coins numbers as the same gold?"*). The masthead purse's number
   took `--coin-ink` that day, which defaults to `--gold` (#d9a441) — 7.3-9.1:1 on every dark
   skin, and **2.23:1 on yotsuba's #ffffee and 2.01:1 on yotsuba-b's #eef2ff**, which is worse
   than the two contrast defects fixed the same day. So those two skins move it, by the identical
   method: hue 0.109 and saturation 0.667 held to the digit, LIGHTNESS ONLY, the smallest move
   that clears 4.5 — #996e1f (4.52, one 8-bit step lighter measures 4.47) and #8f671d (4.55, one
   step lighter 4.49). It is the SAME GOLD, darker, which is the whole reason it is one token and
   not a second colour. ⛔ `--gold` itself is NOT overridden here and must not be: the casino
   paints it on its own hardcoded dark chrome (`.cas-mast`, `linear-gradient(#15120c,#0e0c08)`)
   at every skin, so darkening it would break the floor there to fix it here.
   ⚠ `--mult-ink` IS THE SAME STORY WITH AN OLDER BUG UNDER IT. The arcade multiplier badge
   hardcoded #ffd98a, which is **1.05:1 on yotsuba's --panel and 1.03:1 on yotsuba-b's** — cream
   on cream. That was ALREADY the deck bar's verdict pill on those two skins and nothing had
   looked; putting the readout in the masthead is what made it obvious. Same method again, and
   computed against --panel because that is the DARKEST thing it lands on (the pill's own
   background) and dark ink is hardest there: #895d00 (4.50, one step lighter 4.48) and #835800
   (4.51, one step lighter 4.46). ⚠ The badge's cream BORDER and glow are left alone — they are
   decoration, not text, and no floor binds them.
   ===================================================================== */

/* YOTSUBA — 4chan's classic red board. The palette is taken from the real
   thing: #FFFFEE page, #F0E0D6 reply boxes, #D9BFB7 borders, #800000 text,
   BLUE links with a red hover, green names. The two non-color moves are what
   actually sell it: Arial, and --caps/--track off, which turns this UI's
   uppercase letter-spaced micro-labels into sentence-case board chrome. */
html[data-skin="yotsuba"]{
  --void:#ffffee; --panel:#f0e0d6; --raised:#f0c0b0; --sunk:#ffffff;
  --hair:#d9bfb7; --hair-hi:#b8907f;
  --ink:#800000; --dim:#60534e; --faint:#72625c; --bright:#3d0000;   /* dim: was #7a6a63, 3.16:1 → 4.52:1 on --raised (forage-8tu). faint: was #9b8a82 → #84726a (4.52 on --void) → this, 3.55:1 → 4.52:1 on --panel — --dim now clears --panel at 5.74 WITH ROOM, so --panel became a legal target. --raised is still not one: --dim clears it at the floor (4.52), leaving a 0.02 window no quieter tier fits in. */
  --accent:#af0a0f; --accent-deep:#800000;
  --link:#0000ee; --link-hover:#dd0000;
  --navy:#34345c;
  --bad:#cc1105; --good:#117743; --info:#34345c;
  --coin-ink:#996e1f;   /* 2.23:1 → 4.52:1 on --void; see the MONEY COLOUR note in this file's header */
  --mult-ink:#895d00;   /* 1.05:1 → 4.50:1 on --panel (5.73 on --void) */
  --ui:Arial,Helvetica,"Liberation Sans",sans-serif;
  --caps:none; --track:0;
  --scanline:transparent; --wm-op:.03;
}
/* YOTSUBA B — the blue board: same bones, cooler paper, #34345C ink. */
html[data-skin="yotsuba-b"]{
  --void:#eef2ff; --panel:#d6daf0; --raised:#c8ccec; --sunk:#ffffff;
  --hair:#b7c5d9; --hair-hi:#8f9fc0;
  --ink:#000000; --dim:#4e5870; --faint:#56607d; --bright:#000000;   /* dim: was #555f7a, 4.03:1 → 4.50:1 on --raised (forage-8tu). faint: was #7a84a3, 2.68:1 → 4.50:1 on --panel; it stays there — --dim clears --raised at the floor, so there is no window under it. */
  --accent:#34345c; --accent-deep:#1d1d3d;
  --link:#34345c; --link-hover:#dd0000;
  --navy:#34345c;
  --bad:#cc1105; --good:#117743; --info:#0044aa;
  --coin-ink:#8f671d;   /* 2.01:1 → 4.55:1 on --void; see the MONEY COLOUR note in this file's header */
  --mult-ink:#835800;   /* 1.03:1 → 4.51:1 on --panel (5.59 on --void) */
  --ui:Arial,Helvetica,"Liberation Sans",sans-serif;
  --caps:none; --track:0;
  --scanline:transparent; --wm-op:.03;
}
/* TOMORROW — 4chan's dark theme. Board typography, dark paper, so it needs
   none of the light corrections. */
html[data-skin="tomorrow"]{
  --void:#1d1f21; --panel:#282a2e; --raised:#31343a; --sunk:#1a1c1e;
  --hair:#3f4247; --hair-hi:#55595f;
  --ink:#c5c8c6; --dim:#9a9c9a; --faint:#8e928e; --bright:#f0f2f0;   /* dim: was #969896, 4.30:1 → 4.51:1 on --raised (forage-8tu). faint: was #707470, 3.03:1 → 4.55:1 on --panel; it stays there — --dim clears --raised at the floor, so there is no window under it. */
  --accent:#81a2be; --accent-deep:#5f89ab;
  --link:#81a2be; --link-hover:#b294bb;
  --navy:#b294bb;
  --bad:#cc6666; --good:#b5bd68; --info:#8abeb7;
  --ui:Arial,Helvetica,"Liberation Sans",sans-serif;
  --caps:none; --track:0;
  --scanline:rgba(255,255,255,.010); --wm-op:.05;
}
/* PHOSPHOR — the terminal skin taken all the way: green CRT, monospace kept,
   caps kept, scanlines up. The two phosphors are the same tube, different gun. */
html[data-skin="phosphor"]{
  --void:#020604; --panel:#04140c; --raised:#062012; --sunk:#010806;
  --hair:#0d3a22; --hair-hi:#155c36;
  --ink:#4fe08a; --dim:#2f9a5c; --faint:#2b955a; --bright:#c7ffd9;   /* faint: was #1f6b41, 2.65:1 → 4.54:1 on --raised */
  --accent:#5cff9d; --accent-deep:#2fd177;
  --link:#c7ffd9; --link-hover:#ffffff;
  --navy:#9ff7c4;
  --bad:#ff6b6b; --good:#5cff9d; --info:#7fe8ff;
  --scanline:rgba(120,255,180,.030); --wm-op:.07;
}
/* PHOSPHOR AMBER (owner request 2026-07-26) — the P3 amber tube. Warmer and
   easier on the eye than the green; the archive's brand amber taken to the CRT. */
html[data-skin="phosphor-amber"]{
  --void:#0a0500; --panel:#1a0f01; --raised:#241503; --sunk:#070300;
  --hair:#4a2c05; --hair-hi:#70440a;
  --ink:#ffb027; --dim:#c07a12; --faint:#b47210; --bright:#ffe0a3;   /* faint: was #8a570c, 2.91:1 → 4.52:1 on --raised */
  --accent:#ffc043; --accent-deep:#e09512;
  --link:#ffe0a3; --link-hover:#fff6e2;
  --navy:#ffd79a;
  --bad:#ff6b4a; --good:#ffc043; --info:#ffd79a;
  --scanline:rgba(255,176,39,.032); --wm-op:.07;
}

/* APERTURE (owner request 2026-07-26) — Aperture Science, derived from the amber
   phosphor but rebuilt around the real brand language rather than a CRT:
   · TYPE. Aperture's identity is set in Univers Bold/Regular ULTRA CONDENSED
     (Frutiger, 1957). Nobody has Univers installed, so the stack falls through
     the condensed grotesques that ship with real systems — Helvetica Neue
     Condensed (mac), Arial Narrow (win/mac), Liberation Sans Narrow + Noto Sans
     Condensed (linux) — and only then to plain sans. --track goes WIDE: the
     facility's signage voice is spaced-out uppercase, which this UI's micro-label
     idiom already speaks natively.
   · COLOR. Industrial off-white on near-black, Aperture orange as the accent, and
     PORTAL BLUE as the counterpoint — the orange/blue duality is the whole visual
     signature of the games. Steel hairlines, no CRT scanline.
   · MARK. The iris replaces the shred spiral in the masthead AND as the slowly
     rotating background watermark — which is what the aperture logo wants to be
     doing anyway. The masthead underline becomes a signage rule in orange. */
html[data-skin="aperture"]{
  --void:#0c0d0f; --panel:#15171a; --raised:#1e2126; --sunk:#08090b;
  --hair:#2b3037; --hair-hi:#454d57;
  --ink:#e4e7ea; --dim:#98a0a9; --faint:#808992; --bright:#ffffff;   /* faint: was #6d757e, 3.46:1 → 4.54:1 on --raised */
  --accent:#ff9f1c; --accent-deep:#e07b00;
  --link:#ff9f1c; --link-hover:#ffc76b;
  --navy:#00b4ff;
  --bad:#ff5a4a; --good:#00b4ff; --info:#00b4ff;
  --ui:"Univers","Univers LT Std","Helvetica Neue Condensed","HelveticaNeue-CondensedBold",
       "Arial Narrow","Liberation Sans Narrow","Nimbus Sans Narrow","Noto Sans Condensed",
       Helvetica,Arial,sans-serif;
  --caps:uppercase; --track:1.6;
  --brand-logo:url(/aperture-logo.png); --wm-logo:url(/aperture-logo.png);
  --mast-rule:2px solid var(--accent);
  --wm-size:min(190vmin,190vmax); /* ~2.1x (owner ruling 2026-07-26) — the iris now
                                     overflows the viewport like the spiral does, so
                                     what reads is the SWEEP of the blades, not the
                                     whole symbol. */
  --scanline:transparent; --wm-op:.06;
}

/* ---- LIGHT-SKIN CORRECTIONS ----
   The things a var swap alone cannot fix on a light page. Keyed off
   data-light="1" so EVERY light skin (present and future) gets them at once. */
/* The rank palette is tuned for glow on a dark void — on cream it is invisible.
   Same ladder, darkened, glows dropped. */
html[data-light="1"] .rk-lurker  {color:#7a7a7a}
html[data-light="1"] .rk-slave   {color:#5f5f5f}
html[data-light="1"] .rk-denizen {color:#333}
html[data-light="1"] .rk-citizen {color:#0b6e8c;text-shadow:none}
html[data-light="1"] .rk-freeman {color:#117743;text-shadow:none}
html[data-light="1"] .rk-noble   {color:#8a5a00}
html[data-light="1"] .rk-royalty {color:#6b2fa0}
html[data-light="1"] .rk-demonic {color:#c00;text-shadow:none}
html[data-light="1"] .rk-divine  {color:#8a6a00;text-shadow:none}
html[data-light="1"] .ulink.rk-lurker:hover{color:#555}
html[data-light="1"] .ulink.rk-slave:hover{color:#3d3d3d}
html[data-light="1"] .ulink.rk-citizen:hover{color:#084e63}
html[data-light="1"] .ulink.rk-freeman:hover{color:#0c5530}
html[data-light="1"] .ulink.rk-noble:hover{color:#7a5000}
html[data-light="1"] .ulink.rk-royalty:hover{color:#4e1f77}
html[data-light="1"] .ulink.rk-demonic:hover{color:#900}
html[data-light="1"] .ulink.rk-divine:hover{color:#6b5200}
/* White-on-dark overlay tricks read as haze on paper — darken them. */
html[data-light="1"] .hc-act{background:rgba(0,0,0,.05)}
html[data-light="1"] .hc-act:hover{background:rgba(0,0,0,.10)}
html[data-light="1"] .hc-volslider::-webkit-slider-runnable-track{background:rgba(0,0,0,.25)}
html[data-light="1"] .hc-volslider::-moz-range-track{background:rgba(0,0,0,.25)}
html[data-light="1"] .hc-foot{background:rgba(250,248,240,.90)}
/* brand-shred.png is a WHITE spiral, chosen for the dark void — on paper it is an
   invisible logo and an invisible watermark. Invert both to a dark spiral. */
html[data-light="1"] .brand img.brandlogo{filter:invert(1)}
html[data-light="1"] .shredbg img{filter:invert(1)}
/* ---- THE TWO PALETTES THAT LIVED OUTSIDE THE SEAM (fixed 2026-08-01) ----
   The tag-kind hues and the awards ladder are declared once in :root and overridden by NO
   skin, so both were tuned for the dark void and shipped unreadable on cream. Measured on
   the light skins' white --sunk before this block existed:
       .k-humor      #6fe0b0  1.62:1      --r-legendary #ffd98a  1.34:1
       .k-character  #7fd4ff  1.65:1      --r-uncommon  #5fc46b  1.96:1
       .k-nsfw       #ff6fae  2.58:1      --prism gradients      1.03-1.17:1
   The comment above --cat-character claims they are "all readable on --sunk"; that was true
   on five skins and false on two. A member on yotsuba could not read a humour tag, and could
   not see their own title tier at all.
   ⚖ CORRECTED AS TOKENS, NOT AS RULES. Both palettes are consumed through var() everywhere,
   so darkening the TOKEN here fixes every consumer at once — and keeps app.css:3219's rule
   ("if a skin needs a rule that is not a var, the var seam is missing") true. The dark values
   in :root are untouched: this is an addition to the seam, not a retune of the LAW.
   Hues are held; only lightness moves, and each lands on a value the rank ladder above
   already uses, so the two systems agree on what "green" and "gold" mean on paper. */
html[data-light="1"]{
  --cat-character:#0e6a8a;   /* was #7fd4ff — matches .rk-citizen's paper blue */
  --cat-media:#6b2fa0;       /* was #a98bff — matches .rk-royalty */
  --cat-humor:#117743;       /* was #6fe0b0 — matches .rk-freeman (and yotsuba's own green) */
  --cat-general:#4a5566;     /* was #9aa6b8 */
  /* also the BACKGROUND of .nsfwtoggle.cat-nsfw.on, whose text is --void: cream on this is
     ~9:1 where cream on #ff6fae was 2.56:1. The ON state of the only safety control in the
     app was its least legible chip. */
  --cat-nsfw:#b0004f;        /* was #ff6fae */
  /* one step darker than the rank ladder's paper values: a title chip sits on its OWN tinted
     fill, not on the bare page, so the same hex measures lower here. These clear 4.5:1 on
     both light skins against that tint. */
  --r-common:#474e58; --r-uncommon:#0d5c34; --r-rare:#08556d;
  --r-epic:#712180; --r-legendary:#6f4800; --r-mythic:#a3001c;
  /* The prismatic apex is a dark-void effect; on paper the whitened spectra are grey smear
     (this is the defect the orphan comment here used to describe with no rule under it).
     Same seven-stop rainbow, taken to paper depth so the frame and the glow still read. */
  --prism:linear-gradient(90deg,#0a8f4a,#0b7fa8,#5a3fb5,#b3197f,#b35c00,#8a7a00,#0a8f4a);
  --prism-sat:linear-gradient(90deg,#068a45,#0a72a8,#5232ad,#c2007a,#c46200,#a08c00,#068a45);
  --prism-lite:linear-gradient(90deg,#3aa86c,#3d95c0,#7d63c9,#cc5ba3,#cc8a44,#b3a233,#3aa86c);
}
/* ⚠ THE GRADIENT ALONE IS NOT ENOUGH — THE GLOW HAD TO GO TOO. .prism-text paints the
   spectrum through background-clip and then hangs two WHITE drop-shadows off it (app.css:1086)
   for the halo it needs on a dark void. At title size on cream those blurs bleed straight
   across the glyphs and eat them: with the darkened spectrum in place the apex chip still
   rendered as a pale smudge until the filter came off. Same for the chip's near-white border
   and its keyframed pastel cycle, which are simply invisible on paper — the reduced-motion
   rule at app.css:1193 already knew to freeze it, so this takes the same road. */
html[data-light="1"] .prism-text{filter:none}
html[data-light="1"] .title-chip.prismchip{animation:none;border-color:#7d63c9;color:#3a3a3a}
/* .lbl/.console-k micro-labels lean on --dim being readable on the void; on the
   light skins --dim is already dark, so nothing else is needed here. */

/* the skin picker inside the settings panel.
   ⚰ `.skinchips` / `.skinchip` ARE DELETED (forage-fxj, 2026-08-20) — DEAD, not shrunk. The
   picker became a `<select class="cset-select">` when the skin list outgrew a chip row
   (common-chrome.js, owner mockup *"UI SKIN is a dropdown now"*), and nothing in `web/` has
   minted either class since; `tools/uishot_harness.js` already carries both on its RETIRED list.
   They surfaced as a 26px control in the tap census, which is the census reporting on furniture
   that does not exist — the cheapest possible answer to "is this worth 44px" is that there is
   nothing there to hit. `.skinrow`/`.skinnote` STAY: the row and its note are still emitted. */
.skinrow{align-items:flex-start}
.skinnote{padding-top:0;padding-bottom:10px;text-align:right}

