/* ═══════════════════════════════════════════════════════════════════════════
   houses.css — THE FOUR HOUSE RAMPS. Single source of truth.
   Built 2026-08-14 (session 13). Spec: Manifesto/NAV_AND_IDENTITY_SPEC.md §3a.
   Palette approved via LLypses workshop brief brief_20260814_042654.md.

   ── WHY THIS FILE EXISTS AS A FILE ──────────────────────────────────────────
   Division pages REDECLARE THE WHOLE PALETTE INLINE. That is how the 2026-08-08
   contrast fix (--rws-white-30 .30 -> .48) shipped to styles.css and athenaeum.css
   and never reached division/, which preflight.py had to catch. Putting the ramps
   in one linked stylesheet means the next correction reaches every house at once.
   Do NOT paste these values into a page's inline <style>. That is the bug.

   ── HOW THE GROUND SWAP WORKS ───────────────────────────────────────────────
   A house block does two things:
     1. declares its own --house-* ramp (base / mid / mid-2 / accent / light)
     2. REMAPS the legacy --rws-* ground tokens the page's existing rules already
        reference (--rws-black, --rws-void, --rws-dark, --rws-dark-mid, --rws-border)
   Because of (2), the whole page changes ground without editing ~100 rules by hand.
   Selector is `body.house-x` (0,1,1) which outranks the inline `:root` (0,1,0)
   regardless of source order, so this is safe even though the inline block is
   physically earlier in <head>.

   ── CRIMSON IS NOT REMAPPED. DELIBERATE. ────────────────────────────────────
   §3a: crimson #C0392B stays as the connecting anchor on every page, "usually as
   a light source (forge glow, emblem, banner), NEVER as the division's own accent."
   So --rws-crimson keeps its value here and stays in glows, emblem lighting and
   the shared CTA button. What moves to the house accent is only what reads as the
   DIVISION'S OWN mark: the wordmark, the hero rule, card edges, glyphs.

   ── MEASURED 2026-08-14 AGAINST THE ACTUAL RAMP, NOT THE SPEC TABLE ─────────
   Body copy survives the ground swap — this was the thing most likely to break:
       --rws-white-80 on #0A0F1C  12.27:1   (was 12.67 on #080809)
       --rws-white-50 on #0A0F1C   5.32:1   (was  5.32) PASS AA
       --rws-white-30 on #0A0F1C   4.99:1   (was  4.97) PASS AA  [.48, not .30]
       --rws-white-30 on #162033   4.77:1                PASS AA

   🚨 TWO HARD LIMITS FOUND WHILE MEASURING. Both are easy to violate by accident:

   1. THE ACCENT IS NOT AA ON THE CARD SURFACE.
        sapphire #4F7BE8 on base #0A0F1C  4.86:1  PASS  (§3b's number, confirmed)
        sapphire #4F7BE8 on mid  #162033  4.14:1  LARGE TEXT ONLY
        sapphire #4F7BE8 on mid2 #2F4F6B  2.17:1  FAIL
      Bastion is the tightest of the four houses to begin with. So --rws-label is
      the house LIGHT (#E6EEF5, 16.31:1 on base / 13.90:1 on mid), NOT the accent —
      which also matches the existing decision that --rws-label is a light rather
      than a colour. Use --house-accent for rules, borders, glyphs and glow. Use it
      as normal-size TEXT only directly on --house-base.

   2. --house-mid-2 IS NOT A TEXT-BEARING SURFACE.
        --rws-white-50 on #2F4F6B  3.47:1   --rws-white-30 on #2F4F6B  3.33:1
      Both fail AA for normal text. #2F4F6B is for borders, dividers, hover states
      and hairlines only. Do not make it a card background.

   ⚠️ Changing any accent means re-running the §3b separation table (all six pairs),
      not just re-checking the one you touched. Bastion sits BETWEEN Foundry and
      MythrilWorks on the greyscale axis, so widening one pair narrows another.
      Bastion/Foundry are 6.4 greyscale points apart and MythrilWorks/Athenaeum 7.0
      — both under the spec's own 8-point floor, both carried by hue alone.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── THE FOUR RAMPS ─────────────────────────────────────────────────────────
   Declared for all four houses so this file is the one place the palette lives.
   ✅ 2026-08-15: all four now carry a legacy remap block. Athenaeum was the last
   and is the odd one — it is not a page but SEVEN pages sharing css/athenaeum.css,
   which has its own :root and its own 860px breakpoint. Its block is at the
   bottom of this file and is the longest, because it also re-tints the fixed
   nav/sub-nav chrome that athenaeum.css hardcodes as cold near-black.
   ── */


/* ── CROSS-HOUSE ACCENTS ────────────────────────────────────────────────────
   Added 2026-08-15 for the account page.

   THE PROBLEM THIS SOLVES. `--house-accent` is declared on `body.house-x`, so
   only ONE house's accent exists at a time — whichever the body is wearing.
   That is correct for a division page, which is only ever one house. The
   account page is not: it shows all four division cards at once, and a "you
   follow this" badge on the Bastion card must be Bastion's sapphire even while
   the body is wearing Athenaeum. Using `--house-accent` there painted every
   badge in the ACTIVE house's colour and repainted them all on every tab click.

   These four are always available, regardless of the body class.

   🚨 THEY DUPLICATE THE FOUR `--house-accent` VALUES BELOW AND MUST MATCH THEM.
   Duplication inside one file is the lesser evil — the alternative was a copy
   of the palette in account.css, in a different file, which is the drift
   contrast.py exists to catch. To stop THIS copy drifting, contrast.py now
   asserts the pairs are equal and exits 2 if they are not. It reads both sides
   out of this same file, so it cannot be lying about its own copy.
   Change an accent below and contrast.py will tell you to change it here too. */
:root {
  --house-accent-bastion:      #4F7BE8;
  --house-accent-foundry:      #FF6A00;
  --house-accent-mythrilworks: #22E0FF;
  --house-accent-athenaeum:    #E8B95C;
  --house-accent-cdr:          #C0392B;
}

body.house-bastion {
  --house-base:      #0A0F1C;   /* fortified navy — the ground                */
  --house-mid:       #162033;   /* cards, panels                              */
  --house-mid-2:     #2F4F6B;   /* borders + hover ONLY — see hard limit 2    */
  --house-accent:    #4F7BE8;   /* sapphire, 223°                             */
  --house-light:     #E6EEF5;   /* labels, headings                           */
  --house-accent-lit:#8FB3F5;   /* lit-outline button text — see §buttons     */
  --house-glow:      rgba(79,123,232,.35);
  --house-glow-soft: rgba(79,123,232,.14);
}

body.house-foundry {
  --house-base:      #140A08;   /* furnace shadow                             */
  --house-mid:       #4A1200;
  --house-mid-2:     #B83200;
  --house-accent:    #FF6A00;   /* molten orange, 25°                         */
  --house-light:     #FFD166;
  --house-accent-lit:#FFD166;   /* lit-outline button text — see §buttons     */
  --house-glow:      rgba(255,106,0,.35);
  --house-glow-soft: rgba(255,209,102,.25);
}

body.house-mythrilworks {
  --house-base:      #052A38;   /* abyssal steel                              */
  --house-mid:       #0B3E52;
  --house-mid-2:     #B8C7CE;   /* machined silver — a MATERIAL, not a neutral */
  --house-accent:    #22E0FF;   /* TRON cyan, 188°                            */
  --house-light:     #EAFBFF;
  /* ⚠️ #8AF2FF is --mw-cyan-lit from the MythrilWorks page, copied EXACTLY.
     Andrew called that button "perfect" on 2026-08-15 and it is the model the
     other houses were rolled out from — it must not shift by a shade. */
  --house-accent-lit:#8AF2FF;   /* lit-outline button text — see §buttons     */
  --house-glow:      rgba(34,224,255,.35);
  --house-glow-soft: rgba(34,224,255,.14);
}

body.house-athenaeum {
  --house-base:      #141014;   /* warm ink                                   */
  --house-mid:       #4A3720;
  --house-mid-2:     #F3E2B8;   /* parchment                                  */
  --house-accent:    #E8B95C;   /* gilt amber, 40°                            */
  --house-light:     #F7F1E3;
  --house-accent-lit:#F2D08A;   /* lit-outline button text — see §buttons     */
  --house-glow:      rgba(232,185,92,.35);
  --house-glow-soft: rgba(232,185,92,.16);
}


/* ═══════════════════════════════════════════════════════════════════════════
   🚨 THE SPEC'S "MID" IS NOT A TEXT SURFACE IN THREE OF THE FOUR HOUSES.
   Measured 2026-08-14 against the real ramps, with `--rws-white-30` (which is
   .48) — the alpha the cards actually use for body copy:

       card on spec-mid    Foundry #4A1200  4.42   FAIL AA
                      MythrilWorks #0B3E52  3.91   FAIL AA
                         Athenaeum #4A3720  3.93   FAIL AA
                           Bastion #162033  4.77   pass  ← the only one

   Bastion cleared it by luck of hue, which is why the problem did not surface
   in the first pass. If the other three had simply reused the spec's mid as the
   card colour, every card on three division pages would have shipped failing.

   **So the mid is demoted to borders, gradients and glow, and each house gets a
   purpose-built card tone instead.** Every ground token below is measured.

   ⚠️ MythrilWorks is the tightest house on the site: white-48 on its own base
   `#052A38` is **4.54**, barely over. There is no room to lighten anything. Its
   card therefore SINKS on hover (`#03202B` → `#021A23`) instead of lifting,
   which is the opposite of the other houses. That is a contrast requirement
   wearing a material metaphor, not a style choice — machined recess. Do not
   "fix" it to match the others.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── BASTION: legacy token remap = the actual ground swap ───────────────────
   The pattern every house below follows.
   ── */

body.house-bastion {
  /* The four ground tokens the page's inline rules already reference. Remapping
     these is what turns the page navy without touching the rules themselves. */
  --rws-void:      #070B14;   /* one step under base — .charge, .cta, .footer  */
  --rws-black:     #0A0F1C;   /* = --house-base — body ground                  */
  --rws-dark:      #162033;   /* = --house-mid  — .pcard                       */
  /* 🚨 WAS #1D2A42 UNTIL 2026-08-15 AND IT FAILED AA — 4.47:1.
     Session 13 measured the CARD and never measured the HOVER. `.pcard:hover`
     swaps in this token (division/bastion/index.html:90) while the card still
     contains --rws-white-30 text: `.pc-name .pron` (:97) and two inline
     `style="color:var(--rws-white-30)"` "In development" links (:312, :313).
     So the text stayed put and the ground moved out from under it. A hover
     state is not exempt from 1.4.3. #1B2740 is 4.58:1 and still reads as a
     LIFT (1.095x, vs Foundry's 1.074 and Athenaeum's 1.115) — the lift was
     never the problem, the last 3 points of lightness were.
     ⚠️ Ceiling is ~#1B2842 (4.52). Do not brighten this to taste. */
  --rws-dark-mid:  #1B2740;   /* card hover — 4.58:1 with white-48            */

  /* Borders pick up the house hue instead of flat white/crimson tints. */
  --rws-border:     rgba(79,123,232,.14);
  --rws-border-red: rgba(79,123,232,.30);

  /* 🚨 THE BUG THIS FILE ALSO FIXES. --rws-label is used FOUR times on
     division/bastion/index.html (.eyebrow, .hero-copy .eyebrow, .pc-link:hover,
     .b-live) and is DECLARED NOWHERE THAT PAGE CAN SEE — it lives at
     css/styles.css:43 and this page has never linked styles.css. Every one of
     those four rules was invalid at computed-value time and silently inherited
     its parent's colour. It looked almost right, which is why it survived.
     Declared here as the house light, NOT the accent — see hard limit 1. */
  --rws-label: #E6EEF5;
}

/* The division's own mark moves to the accent. Crimson stays as light source. */
body.house-bastion .hero-title .red { color: var(--house-accent); }
body.house-bastion .hero-rule       { background: var(--house-accent); }
body.house-bastion .pcard::before   { background: var(--house-accent); }
body.house-bastion .pc-glyph        { color: var(--house-accent);
                                      text-shadow: 0 0 40px var(--house-glow); }

/* Hero lighting: sapphire replaces the crimson bloom on the title and eyebrow.
   Crimson is retained on the emblem/logo mark (nav.css) and the primary CTA,
   which is where the anchor belongs. */
body.house-bastion .hero-copy .eyebrow {
  color: var(--house-light);
  text-shadow: 0 0 20px var(--house-glow), 0 0 44px var(--house-glow-soft),
               0 2px 10px rgba(0,0,0,.92);
}
body.house-bastion .hero-title {
  text-shadow: 0 0 60px var(--house-glow-soft), 0 2px 24px rgba(0,0,0,.95);
}
body.house-bastion .hero-scroll .thread {
  background: linear-gradient(to bottom, var(--house-accent), transparent);
}

/* Hero grade + charge glow: the gradients hardcode rgba(5,5,6,…) (the old void)
   and a crimson radial. Both are re-tinted to the house ground so the video
   vignette does not fade to a colour the page no longer contains. */
body.house-bastion .hero-grade {
  background:
    radial-gradient(ellipse 90% 70% at 50% 45%, transparent 30%, rgba(7,11,20,.5) 100%),
    linear-gradient(to bottom, rgba(7,11,20,.5) 0%, transparent 20%, transparent 58%, rgba(7,11,20,.92) 100%),
    linear-gradient(to right, rgba(7,11,20,.9) 0%, rgba(7,11,20,.55) 30%, rgba(7,11,20,.12) 55%, transparent 68%);
}
body.house-bastion .charge::before {
  background: radial-gradient(ellipse at 30% 50%, var(--house-glow-soft), transparent 60%);
}

/* Featured card: the inline gradient is hand-mixed near-black reds. Re-mixed on
   the navy ramp, keeping the same shape. */
body.house-bastion .pcard--f {
  background: linear-gradient(140deg, #12203A, #0C1526 55%, var(--house-mid));
  border-color: var(--rws-border-red);
}

/* Badges. b-live/b-beta were crimson-on-crimson-border; b-soon stays neutral
   because "coming soon" should read as absent, not as house-marked.
   🚨 BOTH TAKE THE LIGHT, NOT THE ACCENT — and this was caught on screen after
   being written wrong here first. b-beta is .75rem (normal size) and sits on
   the featured card, whose gradient lands on --house-mid #162033 under the
   badge. Sapphire there is 4.14:1 — hard limit 1, violated by the very file
   that documents it. The accent survives as the BORDER, which is not text. */
body.house-bastion .b-live { border-color: rgba(79,123,232,.45); color: var(--house-light); }
body.house-bastion .b-beta { border-color: rgba(79,123,232,.40); color: var(--house-light); }

/* Mobile hero grade — the 860px block re-declares .hero-grade, so it needs the
   same re-tint or the phone keeps fading to the old near-black. ⚠️ 860 is a REAL
   breakpoint in this codebase (styles.css uses 640, athenaeum.css 860). Do not
   invent one. */
@media (max-width: 860px) {
  body.house-bastion .hero-grade {
    background:
      linear-gradient(to right, rgba(7,11,20,.94) 0%, rgba(7,11,20,.72) 42%, rgba(7,11,20,.22) 72%, transparent 90%),
      linear-gradient(to bottom, rgba(7,11,20,.72) 0%, transparent 24%, transparent 52%, rgba(7,11,20,.96) 100%);
  }
  body.house-bastion .hero-copy .eyebrow {
    text-shadow: 0 0 18px var(--house-glow), 0 0 40px var(--house-glow-soft),
                 0 2px 10px rgba(0,0,0,.92);
  }
}


/* ── FOUNDRY ────────────────────────────────────────────────────────────────
   The hero plate needed NO re-grade: assets/foundry/foundry-hero-loop.mp4 is
   already a molten foundry line with orange flame jets. Checked a frame before
   assuming — unlike Bastion, whose crimson plate had to be re-baked.
   ── */

body.house-foundry {
  --rws-void:      #0C0604;   /* furnace shadow — deepest band                */
  --rws-black:     #140A08;   /* = --house-base                               */
  --rws-dark:      #2A0D04;   /* card. NOT the spec mid — that fails at 4.42   */
  --rws-dark-mid:  #371103;   /* card hover, lifts toward the crucible         */
  --rws-border:     rgba(255,106,0,.16);
  --rws-border-red: rgba(255,106,0,.34);
  --rws-label:      #FFD166;  /* the house light. 13.53:1 on base             */

  /* 🚨 --rws-steel #4FB0C6 IS RETIRED HERE, AND THE PAGE STILL ARGUES FOR IT.
     `division/foundry/index.html` carries a long comment calling the Foundry /
     MythrilWorks cyan collision "a deliberate, approved collision — Andrew's
     call, 2026-08-09". **That was superseded five days later.** NAV_AND_IDENTITY
     §3a, 2026-08-14: Foundry "abandons the steel-cyan entirely for molten
     orange… That kills the Foundry/MythrilWorks hue collision RATHER THAN
     MANAGING IT." Andrew: *"Foundry color is too close to MythrilWorks."*
     The older comment is now wrong; the newer decision wins. Steel is remapped
     rather than deleted so the page keeps working until that comment is fixed. */
  --rws-steel:        #FFD166;             /* was cyan — now the house light   */
  --rws-steel-glow:   rgba(255,106,0,.16);
  --rws-border-steel: rgba(255,209,102,.34);
}

body.house-foundry .hero-title .red  { color: var(--house-accent); }
body.house-foundry .hero-rule        { background: var(--house-accent); }
body.house-foundry .pcard::before    { background: var(--house-accent); }
body.house-foundry .pc-glyph         { color: var(--house-accent);
                                       text-shadow: 0 0 40px var(--house-glow); }
body.house-foundry .hero-scroll .thread {
  background: linear-gradient(to bottom, var(--house-accent), transparent);
}
/* Embers RISE here — per §3a that is Foundry's motion, and it is the one house
   where the existing plate's upward ember drift is correct rather than borrowed. */
body.house-foundry .charge::before {
  background: radial-gradient(ellipse at 30% 50%, var(--house-glow-soft), transparent 60%);
}


/* ── MYTHRILWORKS ───────────────────────────────────────────────────────────
   No hero video exists yet — the page says so itself ("WHEN THE VIDEO PLATE
   ARRIVES"), so this is a CSS-only hero and there is nothing to re-grade.
   The page ALREADY uses #22E0FF in its inline styles, so this block is mostly
   grounds; the accent was already right.
   ── */

body.house-mythrilworks {
  --rws-void:      #02161D;
  --rws-black:     #052A38;   /* = --house-base. white-48 here is 4.54 — the
                                 tightest ground on the site. Do not lighten.  */
  --rws-dark:      #03202B;   /* card RECESSED below the base                  */
  --rws-dark-mid:  #021A23;   /* hover sinks FURTHER — see the note above      */
  --rws-border:     rgba(184,199,206,.16);   /* machined silver, not white     */
  --rws-border-red: rgba(34,224,255,.34);
  --rws-label:      #EAFBFF;  /* 14.15:1 on base                              */
}

/* ⚠️ `.red` DOES NOT EXIST IN THIS PAGE'S MARKUP — MythrilWorks names its second
   line `.mythril` (the other houses use `.red`). This rule was therefore a
   silent no-op from the day it was written, which is exactly why the title was
   still silver when everyone believed the house layer owned it. Both selectors
   listed so the rule works whichever class the page uses; the page's own inline
   rule sets the same cyan, but THIS one wins on specificity (0,2,1 vs 0,1,0). */
body.house-mythrilworks .hero-title .red,
body.house-mythrilworks .hero-title .mythril { color: var(--house-accent); }
body.house-mythrilworks .hero-rule       { background: var(--house-accent); }
body.house-mythrilworks .pcard::before   { background: var(--house-accent); }
body.house-mythrilworks .pc-glyph        { color: var(--house-accent);
                                           text-shadow: 0 0 40px var(--house-glow); }
body.house-mythrilworks .hero-scroll .thread {
  background: linear-gradient(to bottom, var(--house-accent), transparent);
}
body.house-mythrilworks .charge::before {
  background: radial-gradient(ellipse at 30% 50%, var(--house-glow-soft), transparent 60%);
}


/* ═══════════════════════════════════════════════════════════════════════════
   ATHENAEUM — a REALM, not a page. Built 2026-08-15 (session 14).
   Andrew: "I love the athenaeum so much. The entire Realm/Division needs the
   new theme touch."

   ── WHY THIS BLOCK IS LONGER THAN THE OTHER THREE ──────────────────────────
   The other houses are one self-contained page each. The Athenaeum is SEVEN
   pages (hall + articles + books + lore + news + reading + reading/bestsellers)
   sharing css/athenaeum.css, and that file HARDCODES the fixed chrome as cold
   near-black: the nav at rgba(8,8,9,…), the sub-nav at rgba(10,10,12,…), the
   room-hero grade at rgba(5,5,6,…). Remapping the tokens alone would leave a
   warm ink page permanently under a blue-grey nav bar. So this block does the
   token swap AND re-tints the hardcoded chrome.

   Everything here is a `body.house-athenaeum …` descendant selector, which is
   at least (0,2,1) and therefore outranks both athenaeum.css's `:root` (0,1,0)
   and the pages' own inline rules (0,1,0) no matter what order they load in.
   That is what lets this file reach values that are physically written inside
   seven different HTML files without editing any of them. Do NOT "simplify"
   this by pasting the values back into the pages — that is the exact drift this
   file exists to prevent.

   ── MEASURED 2026-08-15 WITH Manifesto/_scripts/contrast.py (alpha-composited) ─
       white-80 on base #141014   12.13:1
       white-50 on base #141014    5.36:1   PASS AA
       white-30 on base #141014    5.01:1   PASS AA   [.48, not .30]
       white-30 on card #231A12    4.88:1   PASS AA
       white-30 on hover #2E2317   4.66:1   PASS AA
       amber    on base #141014   10.35:1
       amber    on card #231A12    9.39:1
   The Athenaeum is the ROOMIEST house on the site — every pair clears AA with
   margin, including the hover state that Bastion failed. Nothing here is tight.

   🚨 THE SPEC'S MID #4A3720 IS NOT THE CARD. It is 3.93:1 and fails. It stays
   declared above as --house-mid for borders and gradients only.

   ── THE LORE TERMINAL STAYS CYAN. ANDREW'S CALL, 2026-08-15. ────────────────
   division/athenaeum/lore/index.html carries ~30 hardcoded cyan values for the
   CRT inside the plate (#7FC4DE, rgba(127,196,222,…), #EAF7FF). None of them
   are --rws-* tokens, so none of them move when this block loads — that is by
   design, not an oversight. A monitor is a light source at its own colour
   temperature, the same exemption §3a grants crimson. Its three tuned states
   (idle / index / entry) are untouched. If you ever revisit this, amber
   monochrome is the alternative that was considered and deferred.
   ═══════════════════════════════════════════════════════════════════════════ */

body.house-athenaeum {
  --rws-void:      #0E0B0E;   /* .rooms, .footer, .lore-index, mobile intro   */
  --rws-black:     #141014;   /* = --house-base — body ground                 */
  --rws-dark:      #231A12;   /* card. NOT the spec mid — that is 3.93        */
  --rws-dark-mid:  #2E2317;   /* card hover, lifts toward lamplight            */

  --rws-border:     rgba(232,185,92,.14);   /* gilt hairline, not white tint  */
  --rws-border-red: rgba(232,185,92,.30);

  /* 🚨 THE SAME UNDECLARED-TOKEN BUG AS BASTION AND FOUNDRY, AND IT IS WORSE
     HERE. --rws-label is used twice in css/athenaeum.css — `.eyebrow` (:32) and
     the sub-nav back-arrow `.subnav-home::before` (:81) — and is DECLARED ONLY
     in css/styles.css:43, which not one of the seven Athenaeum pages has ever
     linked. `.eyebrow` renders 14 times across those seven pages and the
     sub-nav back-arrow on all six room pages, and every one of them has been
     invalid at computed-value time on the LIVE site — silently inheriting
     instead of erroring. It looked nearly right, which is why it survived
     three type passes.
     Declared here as the house LIGHT (16.74:1 on base, 15.18:1 on card).
     ⚠️ This fixes the ARROWS outright and only SOME of the eyebrows — read the
     next note before assuming the token was the whole story. */
  --rws-label: #F7F1E3;

  /* 🚨 AND THE TOKEN ALONE IS NOT ENOUGH — MEASURED IN THE BROWSER, 2026-08-15.
     Declaring --rws-label fixed the eyebrows on articles/ and books/ (both went
     from inheriting to #F7F1E3, confirmed via getComputedStyle). It did NOTHING
     for the hall's two, books' second, or lore's — because `.eyebrow` in this
     realm is a `<p class="eyebrow">`, and every container that holds one also
     styles its own paragraphs:
         .ath-intro p    (0,1,1)  beats  .eyebrow (0,1,0)   -> white-80
         .charge-inner p (0,1,1)  beats  .eyebrow (0,1,0)   -> white-50
     So those eyebrows were never reading --rws-label at all, undeclared or not,
     and the "undeclared token" diagnosis only explains half of them. An eyebrow
     rendering as body copy is the same bug wearing different clothes: it is a
     LABEL, and on every other page of this site labels are the house light.
     The rule below is (0,2,1) and outranks both. Do not lower it to `.eyebrow`.
     ⚠️ Reasoning about this from the files gives the wrong answer — the two
     rules live in different stylesheets and neither one mentions the other. */

  /* --rws-lume was #7FC4DE, a cold blue in a warm room. Six live uses, all
     OUTSIDE the terminal: the hall's room numerals, .book-series, .lore-card's
     era label AND its focus ring, and the bestsellers teaser's edge + link.
     ⚠️ TASKS/VERIFY both recorded "4 uses, 1 focus ring". Both undercount —
     reading/index.html:163 and :182 use it with a #7FC4DE FALLBACK, so a grep
     for the bare hex misses them and a grep for the token finds them. Amber is
     an improvement at every one of the six (base 9.74 -> 10.35). */
  --rws-lume: #E8B95C;
}

/* Every eyebrow in the realm is the house light — see the note in the block
   above for why the token on its own does not achieve this. */
body.house-athenaeum .eyebrow { color: var(--rws-label); }

/* ── the division's own mark takes the accent ──────────────────────────────── */
/* The TITLE. Andrew, 2026-08-15, from his phone: the Athenaeum was the only
   division whose h1 carried no house colour at all — neither fill nor glow, just
   #fff over a pure-black drop. Bastion gilds `.red` and MythrilWorks `.mythril`;
   this is the same rule for `.gilt`, added to the markup the same day because
   this h1 had no accent-coloured child span for a rule to hook onto.
   Amber on the warm-ink ground measures 10.35:1, so the fill carries itself and
   does not need the glow to be legible — which matters, because the portrait
   block at division/athenaeum/index.html:~342 strips text-shadow from this h1
   (the copy leaves the lit plate and sits on flat void down there). Fill only,
   deliberately: a glow-based treatment would have shown NOTHING on Andrew's
   phone, which is the exact screen the complaint came from. */
body.house-athenaeum .ath-intro h1 .gilt { color: var(--house-accent); }

/* The room you are standing in. Direct analogue of Bastion's .pcard::before. */
body.house-athenaeum .subnav a.room[aria-current="page"]::after {
  background: var(--house-accent);
}
/* The portrait-phone "five rooms below" chevron. It sits on a near-black scrim
   at the foot of the plate, not on the lit plate itself, so amber reads. */
body.house-athenaeum .ath-more .chev {
  border-right-color: var(--house-accent);
  border-bottom-color: var(--house-accent);
}
/* Below-the-plate lore chrome. NOT the terminal — this is the search field in
   the plain index that lives under the hero. */
body.house-athenaeum .lore-search:focus {
  border-color: rgba(232,185,92,.55);
}

/* ═══════════════════════════════════════════════════════════════════════════
   §buttons — THE LIT OUTLINE. THE HOUSE PRIMARY BUTTON, EVERYWHERE.

   Andrew, 2026-08-15, comparing all four division heroes side by side:
   "MythrilWorks is the only one that has it right and its perfect... Looks like
   that button should be the norm going forward. After all....we still have
   RedWardenCDR to build."

   ⭐ WHY AN OUTLINE AND NOT A FILL — the reason is already written on the
   MythrilWorks page and it generalises: "Cyan is a LIGHT, so the primary button
   is a lit outline rather than a fill — a solid #22E0FF block needs near-black
   text and stops reading as energy." Every house accent is a light: molten
   orange, sapphire, gilt, cyan. A solid block of any of them forces dark text
   and kills the glow. Low-alpha fill + lit border + inner and outer bloom keeps
   the accent reading as emission.

   🚨 WHAT WAS WRONG BEFORE: Bastion and Foundry both shipped a SOLID CRIMSON
   fill on a sapphire and a molten page — the company colour on a division's
   hero, ignoring the house entirely. The Athenaeum's .ath-cta was a crimson
   wash with a crimson border, which Andrew called "sloppy". Only MythrilWorks
   had been done properly, and it was done inline on its own page where no other
   division could inherit it.

   ⭐ THE SELECTOR IS `body[class*="house-"]` ON PURPOSE. This is the rule that
   answers "and the potential two other divisions" — RedWardenCDR and anything
   after it get the correct button the moment their `body.house-<name>` block
   exists above, with no new CSS here. Explicitly listing four houses would mean
   this comment gets read again in six months by someone wondering why the new
   division's button is crimson. (0,2,1) also out-specifies every page's inline
   `.btn-primary` (0,1,0) regardless of source order — which is the ONLY reason
   this works, because the division pages load their inline <style> first.

   ⚠️ MythrilWorks must not shift. --house-accent-lit for that house is
   #8AF2FF, copied exactly from --mw-cyan-lit, and the alphas below match its
   original .10/.22/.08 and .20/.42/.14. If you change these numbers, you are
   changing the one button Andrew signed off on.
   ⚠️ .ath-cta is included because the Athenaeum's hall CTA is a different class
   doing the same job. ⚠️ Re-run contrast.py after touching any of it.
   ═══════════════════════════════════════════════════════════════════════════ */
body[class*="house-"] .btn-primary,
body[class*="house-"] .ath-cta {
  background: color-mix(in srgb, var(--house-accent) 10%, transparent);
  color: var(--house-accent-lit);
  border: 1px solid var(--house-accent);
  box-shadow: 0 0 22px color-mix(in srgb, var(--house-accent) 22%, transparent),
              inset 0 0 22px color-mix(in srgb, var(--house-accent) 8%, transparent);
  text-shadow: none;
}
body[class*="house-"] .btn-primary:hover,
body[class*="house-"] .ath-cta:hover {
  background: color-mix(in srgb, var(--house-accent) 20%, transparent);
  color: #fff;
  border-color: var(--house-accent);
  box-shadow: 0 0 34px color-mix(in srgb, var(--house-accent) 42%, transparent),
              inset 0 0 26px color-mix(in srgb, var(--house-accent) 14%, transparent);
}
/* Fallback for engines without color-mix(). Chrome 111 / Safari 16.2 / FF 113
   all have it, so this is belt-and-braces rather than a real target — but a
   primary CTA is the last thing that should degrade to an invisible button. */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
  body[class*="house-"] .btn-primary,
  body[class*="house-"] .ath-cta {
    background: var(--house-glow-soft);
    box-shadow: 0 0 22px var(--house-glow);
  }
}

/* ── crimson deliberately KEPT ─────────────────────────────────────────────── */
/* .hot-dot:hover — NOT changed, and this one is a judgement call worth keeping.
   The hotspot dots sit ON the lit library plate, which is already warm and
   amber. Crimson is what makes a hovered door pop OFF that plate; amber would
   sink into it. §3a's "crimson as a light source" is exactly this case.
   (The two .ath-cta crimson pins that used to live here are gone — that button
   is now the house lit outline above, per Andrew 2026-08-15.) */

/* ── the fixed chrome athenaeum.css hardcodes as cold near-black ───────────── */
body.house-athenaeum .nav          { background: rgba(20,16,20,.55); }
body.house-athenaeum .nav.scrolled { background: rgba(20,16,20,.95); }
body.house-athenaeum .nav-mobile   { background: rgba(20,16,20,.98); }
body.house-athenaeum .subnav       { background: rgba(16,13,16,.94); }

/* Room hero: the placeholder band every room shows until its plate ships. The
   first stop was ALREADY #141014 — the ramp was derived from this gradient, so
   only the cold second stop needs moving. */
body.house-athenaeum .room-hero {
  background: linear-gradient(160deg, #1C1510, #141014 60%, var(--rws-void));
}
body.house-athenaeum .room-hero-grade {
  background: linear-gradient(to bottom, rgba(14,11,14,.55) 0%, transparent 35%,
              rgba(14,11,14,.55) 72%, rgba(14,11,14,.95) 100%);
}

/* Dashed placeholder boxes. A white dashed rule on warm ink reads grey-blue. */
body.house-athenaeum .empty,
body.house-athenaeum .lore-empty { border-color: rgba(232,185,92,.16); }
body.house-athenaeum .ad-slot    { border-color: rgba(232,185,92,.10); }

/* ── page-local hardcodes, reached from here rather than edited in place ───── */
/* HALL. The plate scrim and the band the intro drops into on a portrait phone
   must fade to the SAME colour --rws-void now is, or the seam shows. */
body.house-athenaeum .ath-hero { background: var(--rws-void); }
/* 🚨 THIS RULE IS THE ONE THAT WINS, AND THAT IS EASY TO MISS.
   `body.house-athenaeum .ath-grade` is (0,2,1); the hall page's own inline
   `.ath-grade` is (0,1,0). On 2026-08-15 the horizontal layer below was first
   written in the inline block, verified by reading the SERVED HTML, and shipped
   — where it was inert, because this rule overrode it. **Reading the bytes off
   the server is not verification. Read the COMPUTED STYLE.** The inline rule
   carries the full explanation of what the "shadowed box" actually is; this is
   where any change to it has to land.

   ⚠️ A LEFT-HAND WASH WAS TRIED AND REJECTED ONCE BEFORE — see the note under
   the title scrim below. That attempt needed .65 alpha because it was carrying
   TEXT CONTRAST on its own, and at .65 it dimmed the lit touch table and
   flattened the left bookcases. This one is not doing that job: the ellipse
   scrim still carries the text. This only has to bury the plate's own
   architectural step at 59% width inside a ramp, so it tops out at .58 and is
   fully transparent by 84% — the touch table (at 14%) sits under .55 rather
   than .65, and the lit end wall and archway are untouched.
   ⚠️ If this ever reads as "the plate got dull", back THIS layer out, not the
   ellipse. */
body.house-athenaeum .ath-grade {
  background:
    linear-gradient(to right, rgba(14,11,14,.55) 0%, rgba(14,11,14,.44) 24%,
                rgba(14,11,14,.28) 46%, rgba(14,11,14,.13) 66%, transparent 84%),
    linear-gradient(to bottom, rgba(14,11,14,.72) 0%, rgba(14,11,14,.10) 18%,
                transparent 40%, transparent 62%, rgba(14,11,14,.55) 100%);
}

/* ── the title block's own scrim ────────────────────────────────────────────
   🚨 ADDED 2026-08-15 BECAUSE MOVING .ath-intro TO THE TOP BROKE ITS CONTRAST,
   AND MEASUREMENT SAID SO WHEN THE SCREENSHOT DID NOT.
   Sampling the actual plate pixels under each element and compositing the grade
   over them: worst-case white-80 went from 3.13:1 (old bottom-left position) to
   1.65:1 at the top. The old spot was ALREADY failing — the h1 was 1.81:1 across
   the lit touch table — so this is not a regression the move introduced so much
   as one it exposed and made worse. There is a lit ceiling fixture at
   rgb(228,222,238) running straight through where the title now sits.

   ⚠️ WHY A LOCAL SCRIM AND NOT A BIGGER `.ath-grade` WASH. A left-hand wash was
   built and measured first, the way Bastion's hero does it. To clear AA it had
   to reach .65 alpha, and at that strength it visibly dimmed the lit touch table
   and flattened the left bookcases — it fixed the text by dulling the two things
   that make this plate worth having. This ellipse is anchored to the copy, so
   the rest of the room keeps its light.

   The flat centre runs to 57%, which is exactly where the block's own corner
   falls, so the whole text box sits on even ground and ALL of the falloff
   happens out in the padding. A shorter falloff left a visible arc on the wood.
   MEASURED at 2560x1351: eyebrow 10.40 · h1 7.03 · pron 5.15 · lede 5.13.
   ⚠️ Re-measure if the plate, the copy length, or --rws-void ever changes —
   the numbers come from photograph pixels, not from tokens, so nothing in the
   build will catch a regression here. */
body.house-athenaeum .ath-intro::before {
  content: '';
  position: absolute;
  left: -380px; right: -380px; top: -300px; bottom: -300px;
  /* 🚨 `farthest-side` IS LOad-BEARING. THIS IS THE "SHADOWED BOX".
     Andrew, 2026-08-15: "There is a giant shadowed box there that is noticeable
     lol." — then, after two failed attempts elsewhere: "why in the world can we
     not get rid of that shadow box in the athenaeum???"

     It was THIS rule the whole time. A `radial-gradient(ellipse ...)` with the
     DEFAULT sizing is `farthest-corner`: it reaches its last stop — alpha 0 —
     only at the box's CORNERS. At the middle of each SIDE it is still painting,
     and the element's rectangular edge then clips it stone dead. For this box
     (1280x856 at 2560 wide) the right edge midpoint sits at 83% of the ramp
     (alpha ~.26) and the BOTTOM edge midpoint at just 56% (alpha ~.55). A .55
     alpha wash ending in a straight horizontal line is not a scrim, it is a box.
     Measured on the live page: the visible edges land at x=964 and y~859, which
     is precisely left+520+380 and top+height+300.

     `farthest-side` makes the ellipse's radii the half-width and half-height, so
     it reaches alpha 0 exactly AT all four sides and there is nothing left to
     clip. The corners overshoot, but they are transparent, so nothing shows.

     ⭐ CONTRAST IS UNCHANGED. The text block's own corner sits at ~58% of the
     ramp either way, so it still lands just past the 57% flat stop at ~.55 —
     the same value the measurements below were taken at.
     ⚠️ Do NOT "simplify" this back to `ellipse at center`, and do not try to fix
     it by enlarging the insets: a bigger box moves the hard edge, it does not
     remove it. Two earlier attempts went after the plate and .ath-grade instead
     and both were wrong — the plate's own 59% luminance step is real but is the
     architecture, not this. */
  background: radial-gradient(ellipse farthest-side at center,
              rgba(14,11,14,.60) 0%, rgba(14,11,14,.55) 57%,
              rgba(14,11,14,.30) 80%, rgba(14,11,14,0) 100%);
  z-index: -1;
  pointer-events: none;
}
/* The block shrinks on short landscape viewports (see the height media queries
   in division/athenaeum/index.html), so the ellipse has to shrink with it or it
   starts washing the ladder and the lower shelves for no reason. */
@media (min-width: 601px) and (max-height: 780px) {
  body.house-athenaeum .ath-intro::before {
    left: -300px; right: -300px; top: -210px; bottom: -210px;
  }
}
/* On a portrait phone .ath-intro leaves the plate entirely and sits on a solid
   --rws-void band in normal flow, so the scrim is not only unnecessary there,
   it would darken a rectangle of that flat band and read as a smudge. */
@media (max-width: 600px) and (orientation: portrait) {
  body.house-athenaeum .ath-intro::before { display: none; }
}
/* BOOKS. Empty cover placeholders were cold slate. */
body.house-athenaeum .book-cover {
  background: linear-gradient(150deg, #2A2018, #141014);
}
/* READING. The bestsellers teaser's hover edge was a hardcoded pale blue that
   the token swap cannot reach. Lightened amber, matching the old blue's intent
   (the edge brightens on hover) rather than its hue. */
body.house-athenaeum .bs-teaser:hover { border-left-color: #F2D08A; }

/* ── mobile ────────────────────────────────────────────────────────────────
   ⚠️ 860 is athenaeum.css's OWN breakpoint (styles.css uses 640). The sub-nav
   scroll-fade is the only chrome that re-declares a colour below it, and it
   must match .subnav above or the fade ends in a cold band. */
@media (max-width: 860px) {
  body.house-athenaeum .subnav::after {
    background: linear-gradient(to right, rgba(16,13,16,0), rgba(16,13,16,.94) 65%);
  }
}
/* The hall's portrait band. .ath-intro leaves the plate here and takes
   --rws-void as a real background, so it is already correct via the token —
   listed only so the next reader does not go looking for it. */

/* ═══════════════════════════════════════════════════════════════════════════
   THE COMMANDER — body.house-cdr
   Added 2026-08-16. Andrew: "The Commander gets the Red Geranium that we have
   scoped from Vash the Stampede. He is the only one that gets the Red
   Geranium. The same color that is on the original shields."

   ⭐ THIS IS THE ANSWER TO CTA-CRIMSON, AND IT IS A HIERARCHY, NOT A PALETTE.
   The four divisions each went and took their own colour. The Commander keeps
   the ORIGINAL — the shield colour, the parent mark, the one the whole company
   was built on. So the rule is not "crimson owns the chrome"; it is *crimson is
   the Commander's*, and the chrome is his because the company is. Nobody else
   gets it, and that is what makes the head of the table mean something.

   🚨 REDWARDENCDR IS NOT A DIVISION AND THE PUBLIC COUNT STAYS FOUR.
   He is the head of the round table, not a business unit. The five-vs-six
   division inconsistency was a Creem payment-reviewer flag that a previous
   session deliberately closed — do not reopen it by adding him to any
   "N divisions" string, the JSON-LD, or RWS_DISCOVERABILITY_STANDARD. This
   block exists because he is FOLLOWABLE (Andrew's call, overriding
   THE_SORTING_SPEC's objection — for a streamer, following the person is the
   entire point), and because /redwardencdr/ needs a ground to paint on.
   ⚠️ The page lives at /redwardencdr/, deliberately OUTSIDE /division/.

   ⚠️ ADJACENCY, MEASURED: geranium is only 19.3° from Foundry's molten orange
   #FF6A00. The pair passes on the OTHER axis — 17.3 greyscale points — and on
   that alone. Andrew checked it on screen and can tell them apart. But if
   anyone ever lightens geranium or darkens Foundry, that separation is gone.
   Re-run contrast.py and the full six-pair table before touching either.
   (Every other pair clears comfortably: vs Bastion 142.9°, vs MythrilWorks
   177.2°, vs Athenaeum 34.2° AND 38.3pts — that one clears both axes.)

   ⚠️ Geranium is 3.72:1 on this ground — MARKS, BORDERS AND GLOW ONLY.
   It is under the 4.5 text floor, which is why --house-accent-lit exists,
   exactly as MythrilWorks needed a lit cyan and Bastion a lit sapphire.
   Measured before shipping: white-48 holds 4.93-5.00 on all four surfaces.
   ═══════════════════════════════════════════════════════════════════════════ */

body.house-cdr {
  --house-base:      #0A0506;   /* warm near-black — sampled from his studio  */
  --house-mid:       #180C0C;   /* cards, panels                              */
  --house-mid-2:     #5A2420;   /* borders + hover ONLY — see hard limit 2    */
  --house-accent:    #C0392B;   /* RED GERANIUM, 6° — the original shield     */
  --house-light:     #F5E9E7;   /* labels, headings — 17.06:1 on base         */
  --house-accent-lit:#E0574A;   /* lit-outline button text, 5.43:1            */
  --house-glow:      rgba(192,57,43,.35);
  --house-glow-soft: rgba(192,57,43,.14);
}

/* Ground remap. The pages paint with the legacy --rws-* names, so a house that
   only declares the ramp above inherits the SITE's near-neutral black and the
   warmth never arrives. Warmed toward the geranium rather than tinted with it:
   at this luminance a real red tint reads as a colour cast, not as a ground. */
body.house-cdr {
  --rws-void:      #070405;   /* one step under base — .charge, .cta, .footer  */
  --rws-black:     #0A0506;   /* = --house-base — body ground                  */
  --rws-dark:      #180C0C;   /* card — white-48 lands 5.00 here               */
  --rws-dark-mid:  #201011;   /* card hover, lifts toward the coat             */
  --rws-border:     rgba(192,57,43,.14);
  --rws-border-red: rgba(192,57,43,.30);
  /* ⚠️ MUST be declared per house — it lives in css/styles.css, which the
     division pages never link, so it silently inherits otherwise. And it takes
     the LIGHT, never the accent: geranium as a text colour is 3.72:1. */
  --rws-label:      #F5E9E7;
}

/* The division's own mark takes the accent. On every other house these rules
   RE-tint something that was crimson; here they are identity — the page was
   already going to be crimson, and that is the point. Listed in full anyway so
   the Commander's page is themed by the same machinery as everyone else's and
   nothing has to be special-cased later. */
body.house-cdr .hero-title .red { color: var(--house-accent); }
body.house-cdr .hero-rule       { background: var(--house-accent); }
body.house-cdr .pcard::before   { background: var(--house-accent); }
body.house-cdr .pc-glyph        { color: var(--house-accent);
                                  text-shadow: 0 0 40px var(--house-glow); }
body.house-cdr .hero-scroll .thread {
  background: linear-gradient(to bottom, var(--house-accent), transparent);
}
body.house-cdr .charge::before {
  background: radial-gradient(ellipse at 30% 50%, var(--house-glow-soft), transparent 60%);
}

/* ── THE VIOLET BLOOM IS DELETED. Andrew's call, 2026-08-16. ───────────────
   🚨 DO NOT REINSTATE IT. This rule used to add two radials over the hero —
   blue rgba(26,14,164,.16) and violet rgba(75,26,126,.14), sampled from the
   LED strips on his studio walls — under the reasoning "synthwave is light,
   never content." On the finished page with a real photograph underneath it,
   he read it exactly as the thing he had already rejected: "I had thrown out
   the idea of having synthwave blue/violet mix in and you did it, but now its
   like an overlay to the hero and its clouding things."

   ⚠️ AND IT COST MOST OF A SESSION TO FIND, FOR A REASON WORTH KEEPING.
   houses.css is linked LAST on every page, and `body.house-cdr .hero-grade`
   is (0,2,1) — it out-specifies the page's own inline `.hero-grade` (0,1,0)
   and `background` is a single property, so this did not blend with the
   page's grade, it REPLACED it wholesale. Two rounds of image regrading were
   spent chasing a cast that was never in the photograph, and the page's own
   seam feathers were silently discarded the entire time. He diagnosed it from
   memory — "this has to do with the color schema" — while I was measuring
   pixels that had nothing to do with it.

   THE HERO GRADE NOW LIVES ENTIRELY IN redwardencdr/index.html, which is the
   only file that knows where the plate's edges fall (it depends on
   --plate-zoom). One owner, not two fighting. The geranium bloom that used to
   lead this stack moved there with it. If a house-level hero rule is ever
   needed again, give it a comment saying what it replaces — a `background`
   shorthand from a later stylesheet is invisible sabotage, not an override
   anyone will look for. */
