/* ═══════════════════════════════════════════════════════════════════════════
   account.css — the account area's type scale and its house theming.
   Added 2026-08-15 (session 15). Andrew: "Its so boring in here."

   ── WHY THIS IS A FILE AND NOT MORE INLINE CSS IN lib/page.php ─────────────
   page.php is deliberately self-contained: it links no external stylesheet so
   that a stale or broken styles.css can never produce a broken LOGIN screen.
   That rule is right and it stays — everything page.php inlines is still the
   full fallback, and the account area renders correctly, if plainly, with this
   file and houses.css both missing.

   What this file adds is an ENHANCEMENT layer, and it is a separate file for
   one reason: it consumes `--house-*`, which is declared in css/houses.css and
   nowhere else. Inlining a second copy of the four ramps into page.php would
   be the exact drift contrast.py exists to catch — a checker with its own copy
   of the thing it checks (see SOLUTIONS 2026-08-15, contrast.py's first draft).
   So: houses.css owns the palette, this file spends it, page.php survives
   without either.

   ⚠️ LOAD ORDER: page.php's inline <style> comes FIRST, this file after, so
   equal-specificity rules here win. Where that is not enough the selector is
   scoped with `body.house-x`, which outranks anything page.php declares.

   ── THE TWO HARD LIMITS FROM houses.css, OBEYED HERE ──────────────────────
   1. --house-accent is normal-size TEXT only directly on --house-base.
      Bastion is the tight one: sapphire is 4.86:1 on base and 4.14:1 on mid.
      So `.saved__following` (crimson-equivalent text) sits on the panel, and
      THE PANEL IS --house-base, not --house-mid. Headings use --house-light.
   2. --house-mid-2 IS NOT A TEXT-BEARING SURFACE and is not used as one here.
      Athenaeum's mid-2 is parchment #F3E2B8 — as a divider it would paint a
      bright hairline across a dark page. Dividers use --house-glow-soft, which
      is an alpha of the accent and lands at the same weight in all four houses.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ─── 1. THE STEP UP ────────────────────────────────────────────────────────
   Andrew, 2026-08-15: "Things need to be sized up a bit."  One clear step, not
   a redesign. Nothing here goes below 0.72rem, which is the project's hard type
   floor (CHECKPOINT / NAV_AND_IDENTITY_SPEC §4).

   These are unscoped on purpose: the account area should be this size whether
   or not a house is active, so the sizing survives even if houses.css fails. */

/* 1200px is --container-max from styles.css — the measure every other page's
   BODY content uses. It was 960 (a page-local override in index.php), then 1040
   earlier today, and both were numbers invented here. On a 2560px monitor an
   arbitrary ribbon between a full-bleed topbar and a full-bleed footer reads as
   an accident rather than a choice; the site's own measure does not.
   ⚠️ Not --nav-max (min(1800px,100%)). That is deliberately the CHROME width —
   styles.css says so — and prose set to 1800px is a bad line length. */
main.wrap { max-width: 1200px; padding: 64px 24px 88px; }

/* 🚨 CRIMSON AS TEXT, AGAIN. MEASURED, NOT ASSUMED.
   page.php sets `.eyebrow{color:var(--rws-crimson)}`. #C0392B measures:
       3.68:1 on the old neutral ground #050506
       3.62 Bastion · 3.70 Foundry · 3.40 MythrilWorks
   All four fail AA for normal text, and the eyebrow is 11px — normal text.
   ⚠️ IT WAS ALREADY FAILING BEFORE THIS SESSION. Theming did not cause it; it
   only added three more grounds to fail on. This is A11Y-CRIMSON (2026-08-14),
   which replaced crimson labels with `--rws-label` across 49 declarations and
   never reached lib/page.php, because page.php is self-contained and no
   stylesheet sweep touches it.

   Same resolution as that fix, deliberately: the ratio was never the objection,
   the COLOUR was — so this goes to the label light rather than to a brightened
   red. houses.css sets --rws-label per house (#E6EEF5 / #FFD166 / #EAFBFF /
   parchment); the fallback covers login.php and verify.php, which wear no
   house and were failing at 3.68 too. */
.eyebrow { color: var(--rws-label, #F5F5F5); }

/* The Beacon link is admin-only and it is an ACTION, so it should not flatten
   into the same white as everything else. --house-accent directly on the body
   ground is a pair contrast.py already verifies: 5.00 Bastion · 7.01 Foundry ·
   11.61 MythrilWorks · 10.74 Athenaeum. All pass, all four are the house's own
   colour, and none of them is 3.4.
   ⚠️ Its `style="color:..."` attribute had to be removed from index.php for
   this to apply — an inline style beats any stylesheet rule. */
.beacon-link { color: var(--house-accent, #F5F5F5); }

.lede        { font-size: 1.06rem; margin-bottom: 38px; }
.account-h2,
.panel h2    { font-size: 1.35rem; margin-bottom: 6px; letter-spacing: .02em; }
.sub         { font-size: .78rem; letter-spacing: .18em; }
.note        { font-size: .92rem; line-height: 1.7; }

/* ─── THE DIVISION TABS ─────────────────────────────────────────────────────
   Andrew, 2026-08-15: "why cant we have these decorated buttons inside of the
   account page as well? can the buttons get big enough to sit along this
   section?" — the buttons being the nav's Divisions dropdown items.

   So this is that component's anatomy, deliberately: 28px emblem, name in
   Cinzel caps, grey descriptor. Same emblem files the dropdown ships
   (/assets/emblems/web/{slug}.webp?v=3, written by build_nav.py) and the same
   descriptor words, which are approved copy — "the name alone does not say what
   Bastion *is*". Two components that mean "pick a division" should not look
   like two different ideas.

   GRID, NOT FLEX. `repeat(4, minmax(0,1fr))` makes all four the same width and
   fills the row, which is what "sit along this section" asks for. Flex would
   size each to its own content and leave the row ragged — the four names are
   very different lengths (Bastion vs MythrilWorks). minmax(0,1fr) rather than
   plain 1fr so a long name cannot push a column past its share.

   ⚠️ The grid goes on `.tabs` (the <ul>) and the <li> are the grid items. The
   button is a GRANDCHILD — see the mobile note below, where putting a layout
   rule on the button instead was inert and shipped a ragged row. */
.tabs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 12px; margin-bottom: 34px; }
.tabs > li          { display: flex; }
.tabs > li > button { width: 100%; }

.divtab {
  display: flex;
  align-items: center;
  gap: .9rem;
  text-align: left;
  padding: 15px 17px;
  min-height: 72px;          /* well past the 44px touch floor */
  border-radius: 4px;
  transition: border-color .18s, color .18s, background .18s;
}
/* 30px, not the dropdown's 28. These sit on a much wider button with more air
   around them; at 28 they read as small on a 1200px row. Still the same file —
   the emblems are dark, detailed art and below ~24 they resolve as smudges
   (nav.css), so this is the safe direction to move. */
.divtab img { width: 30px; height: 30px; object-fit: contain; flex: 0 0 auto; }

.divtab__text { min-width: 0; flex: 1 1 auto; }

/* ─── THE FOLLOW BADGE ──────────────────────────────────────────────────────
   Andrew's idea, 2026-08-15: a division you follow should say so ON ITS CARD,
   not as a row inside it that repeats the division's own name back at you.
   "You would also know right off if you are or are not following a division."

   It reuses --rws-shield-mask — the same traced heater shield the saved rows
   use — so "shielded" looks like one thing everywhere on the page rather than
   two. The mark is machine-traced (js/shield.js); do not redraw it by eye.

   ⚠️ The mask variable is declared in account/index.php's page-local block, not
   here. That is deliberate: it ships with the PHP, so if THIS file ever fails
   to load the saved rows keep their marks. Custom properties resolve at use
   time, so a declaration later in the document still reaches this rule.

   🚨 THE BADGE USES THE DIVISION'S OWN ACCENT, NOT --house-accent.
   --house-accent is whichever house the BODY is wearing, so using it here
   painted all four badges in the active house's colour and repainted every one
   of them on each tab click — Bastion's badge went amber while you looked at
   the Athenaeum. --house-accent-<slug> is declared on :root in houses.css
   precisely so all four are reachable at once; contrast.py asserts those four
   match the per-house values. */
.divtab__follow {
  flex: 0 0 auto;
  align-self: flex-start;
  width: 13px; height: 20px;
  background: var(--rws-crimson, #C0392B);
  -webkit-mask: var(--rws-shield-mask) center/contain no-repeat;
          mask: var(--rws-shield-mask) center/contain no-repeat;
}
.divtab[data-panel="bastion"]      .divtab__follow { background: var(--house-accent-bastion,      #4F7BE8); }
.divtab[data-panel="foundry"]      .divtab__follow { background: var(--house-accent-foundry,      #FF6A00); }
.divtab[data-panel="mythrilworks"] .divtab__follow { background: var(--house-accent-mythrilworks, #22E0FF); }
.divtab[data-panel="athenaeum"]    .divtab__follow { background: var(--house-accent-athenaeum,    #E8B95C); }

/* Visually hidden, still read aloud. The badge is a coloured shape and says
   nothing to a screen reader; "Following this division" is the whole point. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Space between grouped sections inside a panel. The first heading sits tight
   under the blurb; every one after it needs to read as a new group. */
.sub--spaced { margin-top: 30px; }
.divtab__name {
  display: block;
  font-family: 'Cinzel', Georgia, serif;
  font-size: .88rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.25;
}
.divtab__desc {
  display: block;
  font-size: .78rem;         /* above the 0.72rem floor */
  letter-spacing: .02em;
  line-height: 1.35;
  margin-top: 3px;
  color: var(--rws-white-30);
}

/* Rows. The list is the page's substance, so it gets the most of the increase. */
.saved__row      { padding: 18px 4px; gap: 15px; align-items: flex-start; }
.saved__mark     { width: 14px; height: 22px; margin-top: 2px; }
.saved__text     { font-size: 1.05rem; line-height: 1.5; }
.saved__meta     { font-size: .82rem; margin-top: 6px; }

.empty           { padding: 44px 28px; font-size: 1rem; }

/* Section rhythm. `Your details` was colliding with the list above it. */
.panel           { margin-bottom: 8px; }
.account-section { margin-top: 52px; }


/* ─── 2. THE PANEL ──────────────────────────────────────────────────────────
   The tab content sits on its own ground so that "which division am I looking
   at" is answered by a SURFACE, not just by which button has a border. Unthemed
   it is a near-black card; themed it becomes the house's own base colour.

   Radius/padding match .card in page.php so the two read as the same family. */
.panel:not([hidden]) {
  display: block;
  background: var(--rws-black);
  border: 1px solid var(--rws-line);
  border-radius: 6px;
  padding: 30px 30px 34px;
}
.panel .saved { border-top-color: var(--rws-line); }


/* ─── 3. HOUSE THEMING ──────────────────────────────────────────────────────
   One block per house would be four copies of the same eight rules, so the
   shared shape is written once against `--house-*` and the four `body.house-*`
   classes in houses.css supply the values. Adding a fifth division means adding
   a ramp THERE and nothing here.

   The guard is `body[class*="house-"]`: without an active house none of this
   applies and the page keeps page.php's crimson chrome. That matters on
   login.php and verify.php, which have no division context at all. */

/* 🚨 THE WHOLE PAGE REPAINTS, AND THAT IS DELIBERATE — Andrew, 2026-08-15:
   "the entire page changing is fine."

   Note that NO RULE HERE DOES THAT. houses.css does not only declare --house-*;
   each block also carries a LEGACY REMAP that rewrites --rws-void / --rws-black
   / --rws-dark to the house ramp, so the division pages' existing component CSS
   re-themes without being rewritten. page.php's `body{background:var(--rws-void)}`
   reads that same token, so adding the house class repaints the ground, the
   footer and the topbar on its own.

   ⚠️ THIS IS WHY THE GROUND IS SAFE WITHOUT NEW CONTRAST WORK. The body now
   sits on each house's --rws-void and the panel on its --house-base, and
   "white-80 / white-50 / white-30(.48) / house light / house accent on void"
   and "...on base" are EXACTLY the pairs contrast.py already checks — the same
   96 that pass today. Had I pinned the ground to a neutral near-black instead,
   the page would have been a set of combinations nothing verifies.

   To go back to a neutral ground, override `body[class*="house-"]{background}`
   here — do NOT edit houses.css, which ten other pages depend on. */
body[class*="house-"] .panel:not([hidden]) {
  background: var(--house-base);
  border-color: var(--house-glow-soft);
}

/* Headings take the house LIGHT, never the accent — hard limit 1. */
body[class*="house-"] .panel h2,
body[class*="house-"] .panel .sub { color: var(--house-light); }

/* The shield mark is a glyph, not text, so the accent is correct here and this
   is the single strongest per-house signal in the list. */
body[class*="house-"] .saved__mark     { background: var(--house-accent); }

/* Accent AS TEXT, and it is legal because the panel ground is --house-base:
   4.86:1 on Bastion, the tightest of the four. Do not move this onto a card. */
body[class*="house-"] .saved__following { color: var(--house-accent); }

/* Dividers: an alpha of the accent, not --house-mid-2. See the header note. */
body[class*="house-"] .saved,
body[class*="house-"] .saved__row      { border-color: var(--house-glow-soft); }

body[class*="house-"] .saved__text a         { border-bottom-color: var(--house-glow); }
body[class*="house-"] .saved__text a:hover   { border-bottom-color: var(--house-accent);
                                               color: var(--house-light); }

body[class*="house-"] .empty {
  border-color: var(--house-glow-soft);
  background: var(--house-glow-soft);
}

/* The active tab. Border + light text + a wash of the house's own glow, so the
   selected division is legible as a colour and not only as a rectangle. */
body[class*="house-"] .tabs button[aria-selected="true"] {
  border-color: var(--house-accent);
  color: var(--house-light);
  background: var(--house-glow-soft);
}
body[class*="house-"] .tabs button[aria-selected="true"] .divtab__name { color: var(--house-light); }
/* The descriptor on the SELECTED button sits on --house-glow-soft, which is an
   ALPHA of the accent over the page ground — a composited colour, not a token.
   It is measured by compositing, not by eye: white-30(.48) over that stack was
   checked in all four houses. Anything dimmer than .48 here is unverified. */
body[class*="house-"] .tabs button[aria-selected="true"] .divtab__desc { color: var(--rws-white-30); }

body[class*="house-"] .tabs button:hover { border-color: var(--house-glow); }
body[class*="house-"] .tabs button:focus-visible {
  outline: 2px solid var(--house-accent);
  outline-offset: 2px;
}


/* ─── 3b. THE COMMANDER CARD ────────────────────────────────────────────────
   Andrew, 2026-08-16: *"there is no place for RedWardenCDR. You can follow the
   commander but he does not appear in your account. Well...he kind of does, but
   not really."* He was landing in "Also saved" — see account/index.php.

   🚨 IT MUST NOT READ AS A FIFTH DIVISION. The public division count stays FOUR
   and the four-column grid below is what would say otherwise, so this is
   deliberately a DIFFERENT SHAPE from .divtab: full width, not a grid cell; a
   left accent edge instead of a full border; an eyebrow line no tab has. Head of
   the round table sits above the table, not in a seat.
   ⚠️ Do not "tidy" this by making it look like the tabs. Looking like them is
   the failure mode, not the goal.

   🚨 IT USES --house-accent-cdr, NEVER --house-accent. Same trap the follow
   badges hit: --house-accent is whichever house the BODY is wearing, so this
   card would turn amber the moment you clicked the Athenaeum tab, and the
   Commander's colour is not a function of which tab is open. houses.css declares
   the suffixed token at :root so all of them are reachable at once.

   The accent is Red Geranium and it is used for EDGES AND THE EYEBROW ONLY.
   ⚠️ It can never be body text here: crimson measures 3.40–3.70:1 on these
   grounds, a straight AA failure (the same measurement that moved .beacon-link
   out of an inline style). --rws-white-60 and above for anything that is read. */
.cdr-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 16px 20px;
  margin: 0 0 20px;
  border: 1px solid var(--rws-line);
  border-left: 2px solid var(--house-accent-cdr, #C0392B);
  border-radius: 4px;
  background:
    linear-gradient(90deg, rgba(192, 57, 43, .07), rgba(192, 57, 43, 0) 42%);
}
.cdr-card__emblem { width: 44px; height: 44px; object-fit: contain; flex: 0 0 auto; }
.cdr-card__text   { min-width: 0; flex: 1 1 auto; }

.cdr-card__eyebrow {
  margin: 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: .72rem;              /* ON the floor, and it is a label, not prose */
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--house-accent-cdr, #C0392B);
}
.cdr-card__name {
  margin: 3px 0 0;
  font-family: 'Cinzel', Georgia, serif;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.2;
}
.cdr-card__name a {
  color: var(--rws-white);
  text-decoration: none;
  border-bottom: 1px solid var(--rws-white-30);
}
.cdr-card__name a:hover { border-bottom-color: var(--house-accent-cdr, #C0392B); }

.cdr-card__state {
  margin: 5px 0 0;
  font-size: .82rem;              /* above the 0.72rem floor — this is read */
  line-height: 1.45;
  color: var(--rws-white-60);
}
/* Followed reads a shade brighter than not-followed. The difference is state,
   so it should be legible without reading the sentence. */
.cdr-card.is-followed .cdr-card__state { color: var(--rws-white-60); }

/* The shield's own geometry, ring and fill all come from css/shield.css. Only
   its position in this card belongs here — restyling the control locally is how
   two shields on one site start disagreeing. */
.cdr-card__shield { flex: 0 0 auto; align-self: center; }

/* ─── 4. MOBILE ─────────────────────────────────────────────────────────────
   🚨 THIS IS THE FIRST RESPONSIVE CSS THE ACCOUNT AREA HAS EVER HAD.
   Verified on the LIVE page 2026-08-15: `[...document.styleSheets]` counted
   ZERO media queries. It was not a squeezed mobile design — there was no mobile
   design. TASKS ACCT-MOBILE, opened after Andrew reported it from his S25.

   ⚠️ Test at 390 x 690, not 390 x 844. 844 is the phone's screen; ~690 is the
   browser's content area once Chrome's URL bar and the Android nav bar are
   subtracted. Testing at 844 is what shipped the mobile nav sheet that ran 83px
   off the bottom (SOLUTIONS 2026-08-14). */
@media (max-width: 640px) {
  main.wrap { padding: 36px 16px 56px; }

  .lede { font-size: 1rem; margin-bottom: 28px; }
  .panel h2 { font-size: 1.2rem; }

  /* The Commander card keeps its emblem and its shield on one row and lets the
     text wrap between them. It does NOT stack: the shield dropping under the
     name would put a 44px control at the bottom of a card whose own height is
     already the tap target, and "Following" would stop reading as a state of
     the thing beside it. */
  .cdr-card { padding: 14px 15px; gap: .8rem; margin-bottom: 18px; }
  .cdr-card__emblem { width: 36px; height: 36px; }
  .cdr-card__eyebrow { font-size: .72rem; letter-spacing: .16em; }
  .cdr-card__name { font-size: .95rem; }
  .cdr-card__state { font-size: .8rem; }

  /* The four tabs wrap to two rows rather than scrolling sideways. A horizontal
     scroller here would need its own fade affordance to not read as clipped
     text (the sub-nav problem in athenaeum.css) and there are only four of
     them — two rows of two is honest and needs no affordance at all.

     🚨 THE FLEX GOES ON THE <li>, NOT THE <button>. `.tabs` is the flex
     container and its children are `<li role="presentation">` wrappers — the
     button is a GRANDCHILD and `flex` on it is inert. The first version of this
     rule put it on the button and the tabs silently sized to their own text
     (75 / 103 / 118 / 81 px against 358px of room, ragged and unaligned). It
     looked deliberate enough to ship. Measure the rendered widths, do not
     assume the rule landed. */
  .tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-bottom: 26px; }
  .divtab { padding: 13px 12px; gap: .7rem; min-height: 66px; }
  .divtab img    { width: 26px; height: 26px; }
  .divtab__name  { font-size: .8rem; letter-spacing: .08em; }
  .divtab__desc  { font-size: .74rem; margin-top: 2px; }

  .panel:not([hidden]) { padding: 22px 18px 26px; border-radius: 5px; }

  /* Rows stay comfortable but give back some of the desktop increase — at
     390px the title is what matters and the padding is what costs. */
  .saved__row  { padding: 16px 2px; gap: 12px; }
  .saved__text { font-size: 1rem; }

  .empty { padding: 32px 18px; font-size: .95rem; }
  .account-section { margin-top: 40px; }
}

/* Very narrow. Stacking the tabs one per row beats letting a label wrap inside
   a button, which makes the four buttons different heights. */
/* Very narrow. One card per row: at ~350px of content, two columns leaves
   "MYTHRILWORKS" about 130px to live in and the name wraps mid-word. */
@media (max-width: 380px) {
  .tabs { grid-template-columns: minmax(0, 1fr); }
}


/* ─── 5. MOTION ─────────────────────────────────────────────────────────────
   Project rule: every transition respects prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  .tabs button { transition: none; }
}
