/* ============================================================
   hoh-case.css  ·  The House of Hygiene
   The shared case-experience layer (Vol. 01).

   WHY THIS FILE EXISTS
   Every interactive case shipped with ~31KB of its own inline CSS and
   its own private :root palette. Six copies had drifted 66-90 lines
   apart, and the alias names had stopped matching their values:
   --sun was forest teal, --moss was purple, --cherry was lavender.
   Electric Iris, the signature brand color, appeared zero times in
   any case. Correct answers were teal in the scene and purple in the
   quiz; wrong answers were lavender; warnings were an off-palette
   mustard. A learner could not read right from wrong by color.

   WHAT IT DOES
   Redefines the legacy alias names on top of the hoh-system.css
   tokens, then repairs the state language, the type roles, the radius
   scale and the contrast floor. Existing case markup and JS are
   untouched: the aliases keep resolving, they just resolve to the
   house system now.

   LOAD ORDER (all three, in this order):
     hoh-brand.css  ->  hoh-system.css  ->  hoh-case.css
   and delete the page's local :root palette block, or it wins.
   ============================================================ */


/* ------------------------------------------------------------
   1 · ALIAS REMAP  ·  legacy names -> system tokens
   The names stay so the markup keeps working. The values are now
   the real palette. Anything that had drifted off-palette is gone.
   ------------------------------------------------------------ */
:root{
  /* grounds */
  --sand:var(--p-lavender);        /* #EFEBF5 */
  --sand-mid:rgba(28,25,41,.14);   /* was #D8D1EA - now the system hairline */
  --sand-dark:var(--p-slate-lt);   /* was #9D93BE at 3.1:1 - now 5.27:1 */
  --deep:var(--p-purple);
  --deep-mid:var(--p-purple-mid);
  --white:var(--p-card);
  --mid:var(--p-slate-lt);

  /* the four case states. One color per meaning, no overlap. */
  --st-pick:var(--p-iris);         /* YOUR CHOICE  - the signature color, */
  --st-pick-dk:var(--p-iris-dk);   /*   finally present in the cases      */
  --st-pick-lt:#E8E5FE;
  --st-good:var(--p-teal);         /* CORRECT / GAINED - 5.71:1 on light  */
  --st-good-lt:#E0EDEA;
  --st-bad:#8E5446;                /* WRONG / COST - brand rose-dk, 6.3:1 */
  --st-bad-lt:#F7EAE6;
  --st-mixed:var(--p-slate);       /* PARTIAL - neutral, carries no valence */
  --st-mixed-lt:var(--p-sand);

  /* legacy aliases folded onto the four states above, so any rule
     this file has not restyled still lands somewhere coherent. */
  --terra:var(--st-pick);      --terra-lt:var(--st-pick-lt);
  --sky:var(--p-teal-soft);    --sky-lt:var(--st-good-lt);  --sky-dk:var(--st-good);
  --sun:var(--st-good);        --sun-lt:var(--st-good-lt);
  --moss:var(--st-good);       --moss-lt:var(--st-good-lt);
  --cherry:var(--st-bad);      --cherry-dk:var(--st-bad);
  --wine:var(--st-bad);
}

/* Case screens sit on purple, so the on-purple context tokens apply:
   accent becomes periwinkle-light (9.05:1), never iris on a dark field. */
.screen{ color-scheme:light; }
#s-intro,#s-brief,#s-info,.hud,.scene-panel,#s-out,.fquiz-hud,.quiz-hud,.learn-hud{
  --accent:var(--p-periwinkle-lt);
  --fg:#FFFDFB;
  --fg-mid:rgba(255,253,251,.78);
  --fg-soft:rgba(255,253,251,.60);
  --hairline:rgba(255,253,251,.16);
  --hairline-strong:rgba(255,253,251,.30);
}


/* ------------------------------------------------------------
   2 · TYPE ROLES
   Vol. 01: every eyebrow, label and data readout is IBM Plex Mono.
   The cases had 14 label classes all set in Outfit 800 uppercase,
   so only the one literally named .eyebrow picked up the house rule.
   ------------------------------------------------------------ */
.badge-txt,.badge-pill,.brief-eyebrow,.pf-k,.pf-role,.sc-loc,.rapport-lbl,
.hud-prog,.choices-dock-lbl,.pearl-lbl,.cq-lbl,.db-ey,.out-ey,.qf-lbl,
.quiz-q-eyebrow,.quiz-hud-prog,.learn-badge-txt,.lcard-eyebrow,.cert-lbl,
.cert-score-sub,.cert-pass-lbl,.score-tally-lbl,.fcard-lbl,.say-col-lbl,
.judgment-tag,.ftag,.chip,.cc-tag,.learn-card-prog,.conseq .cq-lbl{
  font-family:var(--font-mono)!important;
  font-weight:500;
  letter-spacing:var(--track-label);
}
/* Outfit 800 at .54-.6rem was unreadable small caps. Mono holds up. */
.rapport-lbl,.hud-prog,.sc-loc,.pf-k,.choices-dock-lbl,.pearl-lbl,
.badge-txt,.cert-lbl,.score-tally-lbl,.say-col-lbl{ font-size:var(--fs-100); }

/* The wordmark is Lumierepolis. It was rendering in Fraunces, so the
   one place the case says "House of Hygiene" was in the wrong face. */
.hud-logo{ font-family:var(--font-display); letter-spacing:.01em; }
.hud-logo span{ color:var(--p-periwinkle-lt); }

/* Editorial serif for headings and narrative pull-quotes. */
.intro-h,.intro-sub,.pf-name,.out-h,.db-h,.lcard-title,.cert-card-title,
.score-headline,.stat-num,.dbox p,.brief-note,.cert-score-big{
  font-family:var(--font-serif);
}


/* ------------------------------------------------------------
   3 · CONTRAST FLOOR
   White at .28-.45 on #3E3166 measures 1.6-2.6:1. These are the
   readouts a learner actually needs mid-case: scene counter, chart
   labels, location. Raised to the system's dark-surface ramp.
   ------------------------------------------------------------ */
.hud-prog,.rapport-lbl,.pf-k,.sc-loc,.badge-txt,.chip,
.intro-resume,.back-link,.back-c{ color:var(--fg-soft); }
.pf-v,.pf-role,.stat-desc,.pearl p,.narr,.brief-note{ color:var(--fg-mid); }
.back-link:hover,.back-c:hover,.intro-resume:hover{ color:var(--fg); }


/* ------------------------------------------------------------
   4 · RADIUS
   hoh-system.css: "23 radius values existed across the site. There
   are now three." The cases were still running six of their own
   (50px pills, 20, 16, 14, 13, 12).
   ------------------------------------------------------------ */
.btn-terra,.btn-sky,.btn-primary,.retry-btn,.cert-submit-btn,.quiz-submit,
.quiz-continue,.quiz-retry,.learn-prev,.learn-next,.out-cta,.ci-eval-btn,
.chip,.badge-pill,.ftag,.cc-tag,.judgment-tag,.cert-inp,.qopt-letter,.cl{
  border-radius:var(--r-sm);
}
.pf,.obj-box,.dbox,.cb,.qopt,.conseq,.pearl,.stat-block,.fcard,.cert-card,
.lcard,.scene-panel,.cc,.debrief,.deb-inner,.cert-success,.dtable,.say-table{
  border-radius:var(--r-md);
}
.pip,.mood-dot,.pf-av,.p-av,.fq-progress-bar,.fq-progress-fill,.out-icon,
.cert-pass-dot,.score-icon,.cert-success-icon{ border-radius:var(--r-pill); }
/* Letter chips stay circular - they read as tokens, not buttons. */
.cl,.qopt-letter{ border-radius:var(--r-pill); }


/* ------------------------------------------------------------
   5 · THE STATE LANGUAGE  ·  the substantive fix
   Before: correct was teal in the scene and purple in the quiz,
   wrong was lavender in both, partial was mustard #9a6207, and the
   selected card turned deep purple - the brand's own primary used
   to mark a mistake. Now: iris = your pick, teal = right,
   brick-rose = wrong, slate = partial. Applied identically to the
   scene choices and the quiz options.
   ------------------------------------------------------------ */

/* -- scene choice cards -- */
.cb{ background:var(--p-card); border:1.5px solid var(--hairline-strong,rgba(28,25,41,.24)); }
.cb:hover{
  background:var(--st-pick-lt); border-color:var(--st-pick);
  transform:translateY(-1px);
}
.cb:hover .cl{ background:var(--st-pick); border-color:var(--st-pick); color:#FFFDFB; }
.cb:hover .ct{ color:var(--p-ink); }
.cb:hover .cs{ color:var(--p-slate); }

/* `.cb.sel` keeps the ink slab already shipped in the hoh-brand.css
   "Case-engine polish (Vol.01)" block, which sets it !important. That
   block and this file agree on the distinction, so it is stated here
   rather than left to be rediscovered:
     ink slab + iris chip  = COMMITTED. The scene choice is locked, the
                             alternatives have faded, the consequence is in.
     iris tint + iris border = SELECTED, not yet submitted. The quiz option
                             is still changeable until you press Submit.
   Only the label colors are set here, because the shipped block sets the
   ink fill without inverting the text, which left ink-on-ink. */
.cb.sel .ct{ color:#FFFDFB; }
.cb.sel .cs{ color:rgba(255,253,251,.62); }

.cb.g,.cb.ok{ background:var(--st-good-lt); border-color:var(--st-good); }
.cb.g .ct,.cb.ok .ct{ color:var(--p-ink); }
.cb.g .cl,.cb.ok .cl{ background:var(--st-good); border-color:var(--st-good); color:#FFFDFB; }

.cb.ms{ background:var(--st-bad-lt); border-color:var(--st-bad); }
.cb.ms .ct{ color:var(--p-ink); }
.cb.ms .cl{ background:var(--st-bad); border-color:var(--st-bad); color:#FFFDFB; }

.cb.fade{ opacity:.45; }
.cb:focus-visible,.qopt:focus-visible{
  outline:2px solid var(--st-pick); outline-offset:2px;
}

/* -- quiz options: same four states, same colors -- */
.qopt{ border:1.5px solid var(--hairline-strong,rgba(28,25,41,.24)); }
.qopt:hover{ border-color:var(--st-pick); background:var(--st-pick-lt); }
.qopt.selected{ border-color:var(--st-pick); background:var(--st-pick-lt); }
.qopt.selected .qopt-letter{ background:var(--st-pick); border-color:var(--st-pick); color:#FFFDFB; }
.qopt.correct,.qopt.reveal-correct{ border-color:var(--st-good); background:var(--st-good-lt); }
.qopt.correct .qopt-letter,.qopt.reveal-correct .qopt-letter{
  background:var(--st-good); border-color:var(--st-good); color:#FFFDFB;
}
.qopt.wrong{ border-color:var(--st-bad); background:var(--st-bad-lt); }
.qopt.wrong .qopt-letter{ background:var(--st-bad); border-color:var(--st-bad); color:#FFFDFB; }

/* -- consequence panel -- */
.conseq{ border-radius:var(--r-md); border-width:1.5px; border-style:solid; }
.conseq.up{ background:var(--st-good-lt); border-color:var(--st-good); }
.conseq.up .cq-lbl{ color:var(--st-good); }
.conseq.down{ background:var(--st-bad-lt); border-color:var(--st-bad); }
.conseq.down .cq-lbl{ color:var(--st-bad); }
.conseq.mix{ background:var(--st-mixed-lt); border-color:var(--hairline-strong,rgba(28,25,41,.24)); }
.conseq.mix .cq-lbl{ color:var(--st-mixed); }   /* was hardcoded #9a6207 */
.conseq p,.conseq{ color:var(--p-ink); }

/* -- meters: one color, distinguished by label, not by hue.
      Kills the off-palette gold #C8A24B on the credibility row. -- */
.pip{ background:rgba(255,253,251,.14); border:1.5px solid rgba(255,253,251,.24); }
.pip.lit,.pips.cred .pip.lit{
  background:var(--p-periwinkle); border-color:var(--p-periwinkle);
}
.pips.cred .pip.lit{ box-shadow:inset 0 0 0 2px var(--p-purple); }


/* ------------------------------------------------------------
   6 · BUTTON HIERARCHY
   The forward action changed color screen to screen: "Begin Case"
   was iris, "Enter the Operatory" and "Next" were teal, "Continue"
   was bare purple - and "Try Again" was the loudest thing on the
   results screen. One primary per screen, retry demoted.
   ------------------------------------------------------------ */
.btn-terra,.btn-sky,.cert-submit-btn,.quiz-submit,.quiz-continue,
.learn-next,.out-cta,.ci-eval-btn{
  font-family:var(--font-mono);
  font-size:var(--fs-100);
  font-weight:600;
  letter-spacing:.1em;
  text-transform:uppercase;
  min-height:44px;
  border:1.5px solid transparent;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
/* On the purple/dark case field the system inverts primary to paper. */
.btn-terra,.btn-sky,.cert-submit-btn,.quiz-submit,.quiz-continue,.learn-next{
  background:#FFFDFB!important; color:var(--p-ink)!important; border-color:#FFFDFB;
}
.btn-terra:hover,.btn-sky:hover,.cert-submit-btn:hover,.quiz-submit:hover,
.quiz-continue:hover,.learn-next:hover{
  background:var(--p-periwinkle-lt)!important; border-color:var(--p-periwinkle-lt);
  color:var(--p-ink)!important; transform:none;
}
/* Buttons sitting on the light choices dock / quiz body take iris. */
.choices-dock .btn-terra,.choices-dock .btn-sky,.quiz-body .quiz-submit,
.quiz-body .quiz-continue,.quiz-actions .quiz-submit,.quiz-actions .quiz-continue{
  background:var(--st-pick)!important; color:#FFFDFB!important; border-color:var(--st-pick);
}
.choices-dock .btn-terra:hover,.choices-dock .btn-sky:hover,
.quiz-body .quiz-submit:hover,.quiz-actions .quiz-submit:hover{
  background:var(--st-pick-dk)!important; border-color:var(--st-pick-dk);
}
/* Retry and back are secondary. They were reading as the main action. */
.retry-btn,.quiz-retry,.learn-prev,.cert-skip{
  background:transparent!important;
  color:var(--fg)!important;
  border:1.5px solid var(--hairline-strong,rgba(255,253,251,.30))!important;
  font-family:var(--font-mono);
  font-size:var(--fs-100);
  font-weight:600;
  letter-spacing:.1em;
  text-transform:uppercase;
  border-radius:var(--r-sm);
}
.retry-btn:hover,.quiz-retry:hover,.learn-prev:hover,.cert-skip:hover{
  background:transparent!important; border-color:var(--fg)!important; transform:none;
}


/* ------------------------------------------------------------
   7 · SURFACES & CHROME
   The blob motif (border-radius:60% 40% 55% 45% + a 12s float) exists
   nowhere else on the site. The editorial-clinical system rules bands
   with hairlines instead. Blobs retired; the scene panel reclaims the
   ~165px of empty purple that was pushing the decision below the fold.
   ------------------------------------------------------------ */
.intro-blob,.scene-panel .sb,.scene-panel .sb1,.scene-panel .sb2{ display:none!important; }
.scene-panel{
  height:auto; min-height:112px; padding:var(--sp-5) 4% var(--sp-4);
  border-bottom:1px solid var(--hairline);
  border-radius:0;
}
.hud{ border-bottom:1px solid var(--hairline); }
.dbox{
  border-left:3px solid var(--st-pick);
  background:var(--p-card);
}
.dbox::before{ font-family:var(--font-mono); color:var(--st-pick); font-weight:500; }
.dbox p{ color:var(--p-ink); }
.pearl{
  background:rgba(255,253,251,.06);
  border:1px solid var(--hairline);
}
.pearl-lbl{ color:var(--p-periwinkle-lt); }
.stat-block{ background:rgba(255,253,251,.06); border:1px solid var(--hairline); }
.stat-num{ color:var(--p-periwinkle-lt); }
.pf{ background:rgba(255,253,251,.06); border:1px solid var(--hairline); }
.pf-av,.p-av{ background:linear-gradient(135deg,var(--st-pick),var(--p-purple-mid)); border:2px solid var(--hairline-strong); }
.chip{ border:1px solid var(--hairline); }
.badge-pill{ background:var(--st-pick); color:#FFFDFB; }
.choices-dock{ border-top:1px solid rgba(28,25,41,.14); }
.choices-dock-lbl{ color:var(--p-slate-lt); }

/* Reduced motion: the case leans on transitions for state feedback,
   so keep color changes and drop movement only. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.01ms!important; animation-iteration-count:1!important; }
  .cb:hover,.btn-terra:hover,.btn-sky:hover{ transform:none!important; }
}


/* ------------------------------------------------------------
   8 · POST-RENDER CORRECTIONS  ·  2026-09-02
   Found by rendering the rebuilt Case 01, not by reading the CSS.
   ------------------------------------------------------------ */

/* 8a · Iris eyebrows on the purple field.
   hoh-brand.css carries `.eyebrow{color:var(--hoh-iris)!important}`, which
   paints iris onto deep purple at about 2.4:1. hoh-system.css already fixes
   this for `.on-dark` / `.on-purple`, but the case screens carry neither
   class. Scope the same correction to the screens themselves. */
#s-intro .eyebrow,#s-brief .eyebrow,#s-info .eyebrow,#s-out .eyebrow,
#s-learn .eyebrow,#s-game .eyebrow,#s-cert .eyebrow,
#s-intro .loc-strip,#s-brief .loc-strip,#s-game .loc-strip,
.scene-panel .eyebrow,.hud .eyebrow{
  color:var(--p-periwinkle-lt)!important;   /* 9.05:1 on purple */
}
/* The choices dock and quiz body are light surfaces, so iris is correct
   there and must not be caught by the rule above. */
.choices-dock .eyebrow,.quiz-body .eyebrow,.fquiz-body .eyebrow{
  color:var(--p-iris)!important;
}

/* 8b · The hero emphasis word.
   `.intro-h em` was forest teal on deep purple: roughly 2.2:1, on the single
   most prominent word in the case. The subtitle had the same problem. */
.intro-h em{ color:var(--p-periwinkle-lt); font-style:italic; }
.intro-sub{ color:var(--p-periwinkle-lt); }

/* 8c · `.badge` collision.
   The case intro wraps its case-number row in `.badge`, which is also a
   hoh-system.css component with an ink fill. Loading the system put a dark
   slab behind the row. The case usage is a layout wrapper, not a badge. */
#s-intro .badge{
  background:transparent; color:inherit; padding:0;
  border-radius:0; gap:var(--sp-2);
}

/* 8d · Objective numerals read as ordinals, not as a "correct" state.
   Teal is now reserved for correct answers, so the 01-05 markers move to
   the label color. */
.obj-num{ color:var(--p-periwinkle-lt); font-family:var(--font-mono); font-weight:500; }

/* 8e · The last two off-palette holdouts.
   `.judgment-tag` and the quiz "near miss" label were both hardcoded
   #9a6207, a mustard that appears nowhere else in the company, and the
   judgment tag sat on a teal tint that now means "correct". Both are
   partial-credit signals, so both take the neutral. Overridden here in
   one place rather than in six page copies. */
.judgment-tag{
  color:var(--st-mixed)!important;
  background:var(--st-mixed-lt)!important;
  border:1px solid var(--hairline-strong,rgba(28,25,41,.24))!important;
  border-radius:var(--r-sm)!important;
  font-family:var(--font-mono);
  font-weight:500;
}
.quiz-feedback.near .qf-lbl{ color:var(--st-mixed)!important; }


/* ------------------------------------------------------------
   9 · SECOND-PASS COVERAGE  ·  2026-09-02
   Found while extending the sweep to the 7 NBDHE case pages. The
   first pass audited the CSS but not the JS, and missed two state
   variants plus the scene atmosphere gradients (those are set from
   JS and were remapped at the source, in the page files).
   ------------------------------------------------------------ */

/* 9a · The "near miss" quiz state.
   `.qopt.near` is partial credit, so it takes the neutral, matching
   `.conseq.mix`. It was amber text on a teal chip, which read as a
   third valence and collided with teal-means-correct. */
.qopt.near{ border-color:var(--hairline-strong,rgba(28,25,41,.24)); background:var(--st-mixed-lt); }
.qopt.near .qopt-letter{
  background:var(--st-mixed); border-color:var(--st-mixed); color:#FFFDFB;
}

/* 9b · The third meter.
   Case 02 runs a STABILITY row alongside Trust, on its own olive-bordered
   green. Every meter in the product now reads in one language and is told
   apart by its label. */
.pips.stab .pip.lit{
  background:var(--p-periwinkle); border-color:var(--p-periwinkle);
  box-shadow:inset 0 0 0 2px var(--p-purple);
}

/* 9c · The course-information screen.
   `#s-info` is the one light screen in the case shell and sets its own
   near-black on white with `!important`. Kept light, moved onto tokens. */
.screen#s-info{ background:var(--p-paper)!important; color:var(--p-ink)!important; }
#s-info .ci-box{ border-radius:var(--r-md); }
#s-info .eyebrow{ color:var(--p-iris)!important; }

/* 9d · `.cc-tag.ok` is a correct/complete tag, so it takes the correct color. */
.cc-tag.ok{ background:var(--st-good-lt)!important; color:var(--st-good)!important;
  border:1px solid var(--st-good)!important; border-radius:var(--r-sm)!important; }
