/* ============================================================================
   panel.css — the product panels, ported from the live site (site/*.html).
   ----------------------------------------------------------------------------
   ⛔ THESE ARE THE COMPONENT THE NEXT-GENERATION SITE WAS MISSING, and their
   absence is why the prose kept being asked to build the interface in the
   reader's head. There are no screenshots on this site; a panel is a
   reconstruction of a real surface, drawn from the product's own labels, rules
   and thresholds, with a caption that says which parts are real and which are
   simulated.

   Every one of the eight was verified panel-by-panel in
   business/marketing/PUBLIC_SITE_MARKETING_AUDIT_2026-08-09.md against a stated
   verdict scale (VERBATIM / SUPPORTED / PARTIAL / DEFECT). Porting rather than
   rebuilding keeps that verification intact — a hand-rebuilt panel would
   re-open every fidelity question the audit already closed.

   WHAT CHANGED IN THE PORT: only the palette. The live site's tokens
   (--ink-3, --teal, --slate-l …) are remapped onto the next-generation
   set (--star-dim, --waterline, --panel-hd …) so the panels sit inside the
   canvas world instead of importing a second colour system. The live sheet
   themes with `body.dark`; here dark is the ground, so those wrappers are
   dropped rather than inverted.
   ========================================================================= */

:root {
  --panel-bg:   color-mix(in srgb, var(--sky) 82%, #000);
  --panel-hd:   color-mix(in srgb, var(--sky) 62%, #000);
  --hairline-c: color-mix(in srgb, var(--star) 16%, transparent);
  --ok:         #6FBF9B;
  --alert:      #E08878;

  /* 🪤 NINE TOKENS SURVIVED THE PORT UNMAPPED, and an undefined custom
     property voids the WHOLE declaration it appears in — so those panels would
     have rendered with no background, no border and no accent, silently.
     I built the rename map from the fourteen most FREQUENT tokens instead of
     censusing every one, which is the sampling error this project has a rule
     about. Found by listing every var() in the ported sheet and checking each
     against the palette, which is the check that should have come first.
     Defined here rather than renamed again: a second pass of blind renames is
     how the first nine got missed. */
  --font:     var(--f-text);
  --r:        var(--r-plate);
  --shadow:   0 1px 2px rgba(0,0,0,.5), 0 10px 26px rgba(0,0,0,.34);
  --slate:    color-mix(in srgb, var(--sky) 74%, #000);
  --slate-2:  color-mix(in srgb, var(--sky) 60%, #000);
  --teal-l:   color-mix(in srgb, var(--waterline) 26%, transparent);
  --green-l:  color-mix(in srgb, var(--ok) 22%, transparent);
  --red-l:    color-mix(in srgb, var(--alert) 22%, transparent);
  /* amber is the district-policy accent everywhere else on this site; the
     panels use it for the same thing, so it borrows --phosphor rather than
     introducing a second warning hue. */
  --amber:    var(--phosphor);
  --amber-l:  color-mix(in srgb, var(--phosphor) 22%, transparent);
}

/* ⛔ A PANEL IS PRODUCT UI, NOT PROSE. .canvas-panel-in sets text-align:center
   so a centred panel's copy centres — correct for a sentence, wrong for a
   screenshot. Panels inherited it, so the Mira transcript centred its chat
   bubbles and the eligibility rows centred their cells. I first patched that
   per component (text-align:left on three .sh-* rules); this is the class, and
   those patches come back out below. */
.shot{text-align:left}
.shot{
  border:1px solid var(--hairline-c);border-radius:var(--r);background:var(--panel-bg);
  box-shadow:var(--shadow);overflow:hidden;margin-top:18px;
}
.shot-hd{
  display:flex;align-items:center;gap:8px;padding:8px 13px;
  background:color-mix(in srgb,var(--panel-hd) 55%,var(--panel-bg));
  border-bottom:1px solid var(--hairline-c);
  font-family:var(--f-data);font-size:10.5px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--star-dim);
}
.shot-hd{background:#16304F;color:#94A3B8}
.shot-hd::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--waterline);flex:none}
.shot-body{padding:14px 15px;overflow-x:auto}
.shot-cap{
  padding:9px 15px 11px;border-top:1px solid var(--hairline-c);
  font-size:11.5px;line-height:1.5;color:var(--star-dim);
  background:color-mix(in srgb,var(--panel-hd) 30%,var(--panel-bg));
}
.shot-cap{background:#132A46}
.shot-cap b{color:var(--star);font-weight:600}

/* ── timeline / clock cells ─────────────────────────────────────────── */
.sh-tl{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:9px}
.sh-tlc{border-left:3px solid var(--slate);background:var(--panel-bg);border-radius:var(--r-interactive);padding:9px 11px}
.sh-tlc.warn{border-left-color:var(--amber)}
.sh-tlc.ok{border-left-color:var(--ok)}
.sh-tlc.risk{border-left-color:var(--alert)}
.sh-k{font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--star-dim)}
.sh-v{font-size:14.5px;font-weight:700;color:var(--star);margin-top:2px;font-family:var(--f-data)}
.sh-pill{
  display:inline-block;margin-top:6px;padding:2px 7px;border-radius:999px;
  font-size:10.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  background:var(--panel-hd);color:var(--slate-2);
}
.sh-pill.a{background:var(--amber-l);color:var(--amber)}
.sh-pill.g{background:var(--green-l);color:var(--ok)}
.sh-pill.r{background:var(--red-l);color:var(--alert)}
.sh-tlc{background:#132A46}

/* ── eligibility support rows ──────────────────────────────────────
   ⛔ THIS BLOCK WAS MISSED IN THE ORIGINAL PORT. The eligibility panel's markup
   came across and its stylesheet did not, so every row rendered as centred
   running text with no separator: "Specific Learning DisabilityStrong support",
   because .sh-nm and .sh-sup were both display:inline with nothing between them.

   ⛔ AND NO INSTRUMENT COULD SEE IT. plate-fit measures .plate and <table>;
   this panel has neither (it is .shot markup), so /programs contributed ZERO
   measurements to it. a11y checks contrast, which was fine — collapsed text is
   perfectly legible, it is just not a table. Both suites were green on a panel
   that had lost its entire layout. It took a screenshot.

   Ported from the live stylesheet with this file's token conventions:
   --ink → --star, --ink-2/-3 → --star-dim, --border → --hairline-c,
   --bg → --panel-bg, --green → --ok, --mono → --f-data. */
.sh-cat{
  border:1px solid var(--hairline-c);border-radius:6px;padding:9px 11px;
  background:var(--panel-bg);margin-bottom:7px;
}
.sh-cat:last-child{margin-bottom:0}
.sh-catr{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.sh-nm{font-weight:700;font-size:12.5px;color:var(--star)}
.sh-sup{
  padding:2px 8px;border-radius:999px;font-size:9.5px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;
  background:var(--green-l);color:var(--ok);white-space:nowrap;
}
.sh-sup.needs{background:var(--amber-l);color:var(--amber)}
.sh-ev{font-size:11.5px;color:var(--star-dim);margin-top:5px}
.sh-cite{font-family:var(--f-data);font-size:10px;color:var(--star-dim);margin-top:4px}

/* ══ R1 · A RULE-OUT IS NOT A CATEGORY, AND MUST NOT LOOK LIKE ONE ══════════
   The referral panel rendered an exclusionary rule-out in the same `.sh-cat`
   card as an SLD category row, and captioned the pair "Washington's eligibility
   categories, side by side". They are different kinds of thing: a categorical
   support row says a student MAY qualify under a category; an exclusionary
   rule-out says a competing explanation has or has not been eliminated. The
   panel presented the second as a third disability category.
   Measured in the running product (ledger §10): they live in different parents
   about 460px apart, rule-out ABOVE the category list. So the treatment now
   differs — a left-ruled strip with a status glyph, not a filled card — and the
   panel states the separation instead of implying adjacency. */
.sh-sect{
  font-family:var(--f-data);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--star-dim);margin:0 0 5px;display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;
}
.sh-sect-x{font-size:9px;opacity:.75;text-transform:none;letter-spacing:0}
.sh-rule{
  display:flex;gap:9px;align-items:flex-start;
  border-left:3px solid var(--amber);border-radius:0 6px 6px 0;
  padding:8px 11px;background:transparent;margin-bottom:7px;
}
.sh-rule-b{flex:1;min-width:0}
.sh-glyph{font-size:13px;line-height:1.2;color:var(--star-dim);flex:none}
.sh-glyph.needs{color:var(--amber)}
/* The visible break. It is not decoration — it is the panel declaring that it
   has compressed two distant subsections into one frame. */
.sh-break{
  font-size:10px;color:var(--star-dim);font-style:italic;
  margin:9px 0;padding-left:3px;opacity:.85;
}

/* ── kiosk scoring rail ─────────────────────────────────────────────── */
.sh-scorerow{display:flex;flex-wrap:wrap;gap:9px;align-items:stretch}
.sh-c{
  flex:1 1 74px;background:var(--panel-bg);border:1px solid var(--hairline-c);border-radius:var(--r-interactive);
  padding:8px 6px;text-align:center;
}
.sh-c b{display:block;font-family:var(--f-data);font-size:19px;font-weight:700;color:var(--star);line-height:1.1}
.sh-c i{display:block;font-style:normal;font-size:9.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--star-dim);margin-top:2px}
.sh-c.err b{color:var(--alert)}
.sh-c.score{background:var(--teal-l);border-color:var(--waterline)}
/* ══ K2 · THE SCORE TILE IS NOT A PEER OF THE COUNTERS ══════════════════════
   The panel showed four equal tiles: Errors / Words / WCPM / Accuracy.
   Rendered in the product (kiosk driven in-window, ledger §10): THREE live
   counters — Errors · Words · Score — plus a SEPARATE tall score tile whose
   unit line reads WCPM and whose accuracy is a sub-chip formatted by
   `_kioskRecalcLive` as `accuracy + '% · ' + score + '/' + denominator`.
   So "WCPM" was never a tile (it is the unit line) and "Accuracy" was never a
   tile (it is a chip, and absent until the first attempt). */
.sh-c.tile{
  background:var(--teal-l);border-color:var(--waterline);
  display:flex;flex-direction:column;justify-content:center;gap:1px;
}
.sh-c.tile b{font-size:26px;line-height:1}
.sh-c.tile u{display:block;text-decoration:none;font-family:var(--f-data);
  font-size:9px;color:var(--star-dim);margin-top:1px}
.sh-c.tile em{display:block;font-style:normal;font-family:var(--f-data);
  font-size:9px;color:var(--ok);margin-top:2px}
/* The save-armed state. Observed in the product: when the timer stops, the
   score tile's border goes from grey rgb(226,232,240) to teal rgb(15,118,110).
   That colour change IS the affordance — the examiner is never asked whether
   the score saved — so the sequence's third frame is this and nothing else. */
.sh-c.tile.armed{border-color:var(--phosphor);box-shadow:0 0 0 1px var(--phosphor) inset}
.sh-c.tile.armed b{color:var(--phosphor)}
.sh-c.score b{color:var(--waterline)}
.sh-c{background:#132A46}
.sh-c.score{background:#16394A;border-color:var(--waterline)}
.sh-c.score b{color:var(--waterline)}
.sh-etc{margin-top:11px}
.sh-etc-h{font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--star-dim);margin-bottom:6px}
.sh-etc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(84px,1fr));gap:6px}
.sh-etc-box{
  background:var(--panel-bg);border:1px solid var(--hairline-c);border-radius:var(--r-interactive);
  padding:6px 4px;text-align:center;
}
.sh-etc-box b{display:block;font-family:var(--f-data);font-size:14px;font-weight:700;color:var(--star-dim)}
.sh-etc-box i{display:block;font-style:normal;font-size:9px;color:var(--star-dim);margin-top:1px}
.sh-etc-box.hit{background:var(--red-l);border-color:var(--alert)}
.sh-etc-box.hit b,.sh-etc-box.hit i{color:var(--alert)}
.sh-etc-box{background:#132A46}

/* ── assistant panel ────────────────────────────────────────────────── */
.sh-mp{max-width:430px}
.sh-mphd{
  display:flex;align-items:center;gap:8px;padding-bottom:9px;margin-bottom:10px;
  border-bottom:1px solid var(--hairline-c);
}
.sh-mpnm{font-weight:700;font-size:13px;color:var(--star)}
.sh-mpsub{font-size:10.5px;color:var(--star-dim)}
.sh-msg{display:flex;margin-bottom:9px}
.sh-msg.user{justify-content:flex-end}
.sh-bub{
  max-width:88%;background:var(--panel-bg);border:1px solid var(--hairline-c);
  border-radius:12px;padding:9px 11px;font-size:12.5px;line-height:1.55;color:var(--star);
}
.sh-msg.user .sh-bub{background:var(--teal-l);border-color:var(--waterline);color:var(--waterline)}
.sh-bub{background:#132A46}
.sh-msg.user .sh-bub{background:#16394A;color:var(--waterline)}
.sh-bub p{margin:0 0 6px}
.sh-bub p:last-child{margin-bottom:0}
.sh-bub b{color:var(--star)}
.sh-bub b{color:#E2E8F0}
.sh-act{
  display:inline-block;margin-top:7px;padding:5px 10px;border-radius:var(--r-interactive);
  font-size:11.5px;font-weight:600;background:var(--waterline);color:#fff;
}
.sh-act.ghost{background:transparent;border:1px solid var(--waterline);color:var(--waterline)}
.sh-act.ghost{color:var(--waterline)}
.sh-chips{display:flex;flex-wrap:wrap;gap:5px;margin-top:9px}
.sh-chip{
  padding:3px 9px;border-radius:999px;border:1px solid var(--hairline-c);
  font-size:10.5px;color:var(--star-dim);background:var(--panel-bg);
}
.sh-chip{background:#132A46}

/* ── analytics table ────────────────────────────────────────────────── */
.sh-tbl{width:100%;border-collapse:collapse;font-size:12px;min-width:440px}
.sh-tbl th{
  text-align:left;padding:6px 8px;border-bottom:2px solid var(--hairline-c);
  font-size:9.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--star-dim);font-weight:700;
}
.sh-tbl td{padding:6px 8px;border-bottom:1px solid var(--hairline-c);color:var(--star);font-family:var(--f-data)}
.sh-tbl td:first-child{font-family:var(--font);color:var(--star);font-weight:600}
.sh-over{color:var(--alert);font-weight:700}
.sh-supp{color:var(--star-dim);font-style:italic;font-family:var(--font)}
.sh-foot{margin-top:9px;font-size:10.5px;color:var(--star-dim);line-height:1.5}

/* The Mira transcript is capped at 430px in the source — a phone-width chat,
   deliberately. In a deck panel that is 1,328px wide it was stranded against
   the left edge with 900px of empty navy beside it. Centring the column makes
   the proportion read as composition rather than as a layout that failed. */
/* The transcript panel sizes to the conversation rather than stretching the
   deck's full width: its header bar and caption were spanning 1,328px around a
   430px column. Scoped with :has() so the table panels, which genuinely want
   the width, are untouched. */
.shot:has(.sh-mp){max-width:660px;margin-inline:auto}
.sh-mp{margin-inline:auto}

/* ── THE CAPABILITY PLATE (/mira) ─────────────────────────────────────────
   Replaces a percentage bar chart of the knowledge file. A capability is a
   sentence, not a quantity, so this is a list of statements rather than a
   comparison of magnitudes — there is nothing here to compare. */
.cap-intro { color: var(--star-dim); margin: 0 0 1rem; max-width: 74ch; }
.cap-grid {
  list-style: none; margin: 0; padding: 0;
  /* min() so the track can collapse below 15rem instead of forcing the plate
     wider than the frame. Without it the fitter scaled the whole plate to its
     0.55 floor at 390px and the role label rendered at 6.9px — the type was
     never too small, the PLATE was too wide, and shrinking the label would
     have been treating the symptom. */
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: .1rem;
  border-top: 1px solid var(--hairline-c);
}
.cap-item {
  display: grid; gap: .18rem; align-content: start;
  padding: .7rem .85rem .8rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--hairline-c) 55%, transparent);
}
.cap-name { font-weight: 600; font-size: .95rem; color: var(--star); }
.cap-what { font-size: .84rem; line-height: 1.45; color: color-mix(in srgb, var(--star) 76%, transparent); }
/* ⚠ .68rem scaled to 6.1px at 390 once the plate fitter shrank the whole
   plate to fit — the fitter's floor applies to the PLATE, not to the type
   inside it, so a small label compounds with the scale. Caught by the
   9px minimum in _test-plate-fit. */
.cap-who  { font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--waterline); }
.cap-prov { margin: 1rem 0 0; color: var(--star-dim); max-width: 78ch; }

/* ── THE BROWSER FRAME ────────────────────────────────────────────────────
   The panel read as a floating card rather than a screen. A chrome bar is the
   cheapest signal that what follows is an application — and the URL carries a
   real claim: `local` beside the path is the product's actual posture, not a
   decorative padlock. */
.shot-browser { overflow: hidden; }
.br-bar {
  display: flex; align-items: center; gap: .42rem;
  padding: .5rem .7rem; background: var(--panel-hd);
  border-bottom: 1px solid var(--hairline-c);
}
.br-dot { width: 8px; height: 8px; border-radius: 50%; flex: none;
          background: color-mix(in srgb, var(--star) 22%, transparent); }
.br-url {
  flex: 1; margin-left: .35rem; padding: .18rem .6rem; border-radius: 999px;
  background: color-mix(in srgb, var(--star) 7%, transparent);
  font-family: var(--f-data); font-size: 10px; color: var(--star-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.br-path { color: color-mix(in srgb, var(--star) 55%, transparent); }
/* ⛔ .br-lock IS REMOVED, NOT COMMENTED OUT, AND THE STYLE GOES WITH IT (M7,
   2026-08-16). It rendered the word "local" in green, in the PADLOCK SLOT of a
   simulated browser chrome — a browser's connection-security affordance, which
   a reader trusts differently from prose.
   Three faults, and the middle one is the one I would have missed:
     1. UNQUALIFIED. "Local" is the shipped default of FOUR data tiers (local ·
        local+meta · custodial · zk-cloud). The app's own copy never says it
        bare: "IN THIS MODE all student data stays on this device … This is the
        shipped default; a district changes it by configuring a destination."
     2. THE EVIDENCE I INHERITED FOR IT WAS FALSE. The supporting claim was
        "zero fetch/XHR/WebSocket/sendBeacon in the Mira band". Re-derived over
        the band: THREE fetch call sites, all live-form dispatch, each gated on
        a configured relay URL + key + _egressAllowed(). Unreachable in the
        shipped default — which is a different sentence from zero, and the
        difference is the whole claim.
     3. IT WAS A DUPLICATE. /privacy already carries the hedged version, in the
        app's own form: "CetusEd can send data to a district destination. That
        path ships switched off, and the only people who can switch it on are
        you." Nothing was deleted by removing this.
   ⛔ THE STYLE IS DELETED SO THE SPAN CANNOT COME BACK PRE-DRESSED. A retained
   rule makes re-adding the badge a one-line change that looks finished. A
   product claim does not belong in a browser-chrome trust affordance inside a
   RECONSTRUCTION, at any wording. */

/* ── THE PLAYED CONVERSATION ──────────────────────────────────────────────
   ⛔ The hidden state hangs off .is-demo, which only mira-demo.js adds and only
   after its reduced-motion check. Script blocked or motion reduced: the whole
   transcript is present and readable, which is the same information. */
.is-demo [data-turn] { opacity: 0; transform: translateY(.35rem); }
.is-demo [data-turn].is-shown {
  opacity: 1; transform: none;
  transition: opacity 240ms var(--e-out, cubic-bezier(.16,1,.3,1)),
              transform 260ms var(--e-out, cubic-bezier(.16,1,.3,1));
}
/* ⛔ M9 · M10 · M11 — THREE DEFECTS IN THESE TWO RULES, AND THE FIRST ONE HID
   THE OTHER TWO. Fixed together 2026-08-16; fixing M9 alone would have made the
   panel WORSE than leaving it broken.

   M9  `background: var(--blue)`. --blue is defined ONLY in conductor.css:37,
       and conductor.css is loaded by exactly ONE page — conductor.html. On
       every page that renders this panel the declaration is invalid at
       computed-value time, so the background fell back to transparent: the
       strongest "someone is typing" cue on the site has never once rendered.
       ⭐ THE FIX IS NOT TO DEFINE --blue HERE. conductor.css's --blue is
       #7FB6E8 and the base already ships --current: #7FB6E8 — the SAME HEX,
       semantically named, in cetus-site.css where every page can see it.
       --blue was always a second home for a fact the token system owned.
   M10 the suppression selector ended `~ * [data-turn="ask"]`, which requires an
       ask turn that is a DESCENDANT of a later sibling. Every turn is a flat
       sibling, so it matched nothing and the caret would have blinked forever
       on a question answered two turns ago. Rewritten with :has(), which reads
       forward across flat siblings — the pattern canvas.css already relies on,
       including its note that :has() contributes its argument's specificity
       (that is what makes this rule beat the one above it: 0,5,2 over 0,3,2).
   M11 the caret matched [data-turn="ask"] exactly while mira-demo.js:41 tests
       /^ask/ — so the SECOND question typed with no caret at all. Both rules
       now use ^="ask", so the selector and the script agree on what a question
       is.
   🪤 The reduced-motion block below already kills ::after on every [data-turn],
   so none of this animates for a reader who asked it not to. */
.is-demo [data-turn^="ask"].is-shown::after {
  content: ''; display: inline-block; width: 1.5px; height: .95em;
  margin-left: 2px; vertical-align: -2px; background: var(--current);
  animation: br-caret 1.05s steps(2) infinite;
}
/* …and it goes out the moment that question has been answered. */
.is-demo [data-turn^="ask"].is-shown:has(~ [data-turn^="say"].is-shown)::after { display: none; }
@keyframes br-caret { 0%,49% { opacity: 1 } 50%,100% { opacity: 0 } }

@media (prefers-reduced-motion: reduce) {
  .is-demo [data-turn] { opacity: 1 !important; transform: none !important; }
  .is-demo [data-turn]::after { display: none !important; }
}

/* ⛔ THE PLATE HAS TO FIT, SO THE PHONE GETS THE SHORT FORM.
   Ten items each carrying a sentence is 1,425px on a 390px screen, in a 315px
   panel — the fitter clamps to its 0.55 floor and the role label renders at
   6.9px. That is not a type-size problem; the plate is four times too tall.
   Below the breakpoint the explanation is dropped and the ten capability NAMES
   run in two columns, which is ~300px and fits without any scaling. A reader on
   a phone gets the scannable list; a reader on a laptop gets the sentences.
   ⚠ The names alone still carry the claim — nothing load-bearing is hidden. */
@media (max-width: 700px) {
  .cap-grid { grid-template-columns: 1fr 1fr; gap: 0 .8rem; }
  .cap-item { padding: .42rem .4rem .45rem 0; }
  .cap-what { display: none; }
  .cap-name { font-size: .82rem; }
  .cap-who  { font-size: .66rem; }
}

/* ══ THE FLAG-REFERRAL WIZARD (refer) ═══════════════════════════════════════
   Step rail, prompt and concern chips, all read off the running wizard. The
   rail is the load-bearing part: it carries "there are five steps" without the
   panel claiming to know what is on the four it could not reach. */
.sh-wizrail{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:10px;
  font-family:var(--f-data);font-size:9.5px;letter-spacing:.05em;text-transform:uppercase}
.sh-wizrail span{color:var(--star-dim);opacity:.6}
.sh-wizrail span.on{color:var(--star);opacity:1;border-bottom:2px solid var(--waterline);padding-bottom:2px}
.sh-wizq{font-size:13px;font-weight:700;color:var(--star);margin:0 0 9px}
.sh-chips.wrap{display:flex;flex-wrap:wrap;gap:6px}
.sh-chip.add{border-style:dashed;opacity:.75}
.sh-chip.on{background:color-mix(in srgb, var(--waterline) 22%, transparent);
  border-color:var(--waterline);color:var(--star)}

/* ══ FRAME 2 · THE KIOSK ADMINISTRATION ARC ═════════════════════════════════
   Five authored frames of one workflow. Every control below mirrors a surface
   read off the running product; only the passage text is invented, and the
   frame says so. */
.sh-purpose{display:flex;flex-direction:column;gap:7px}
.sh-p{border:1px solid var(--hairline-c);border-radius:6px;padding:9px 11px;background:var(--panel-bg)}
.sh-p b{display:block;font-size:12.5px;color:var(--star);font-weight:700}
.sh-p i{display:block;font-style:normal;font-size:10.5px;color:var(--star-dim);margin-top:3px}
.sh-p.on{border-color:var(--waterline);background:color-mix(in srgb,var(--waterline) 12%,transparent)}
/* the disabled purpose: dimmed, and its reason stays legible */
.sh-p.off{opacity:.55}
.sh-p.off b{color:var(--star-dim)}
.sh-p.off i{color:var(--amber);opacity:1}
/* the pre-start refusal */
.sh-block{display:flex;gap:9px;align-items:flex-start;border-left:3px solid var(--amber);
  border-radius:0 6px 6px 0;padding:9px 11px;background:color-mix(in srgb,var(--amber) 8%,transparent)}
.sh-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:8px;margin-bottom:10px}
.sh-fields label{display:block;font-family:var(--f-data);font-size:9px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--star-dim)}
.sh-sel{display:block;margin-top:3px;padding:6px 9px;border:1px solid var(--hairline-c);
  border-radius:var(--r-sm);background:var(--panel-bg);color:var(--star);
  font-family:var(--font);font-size:11.5px;text-transform:none;letter-spacing:0}
.sh-launch{display:inline-block;padding:6px 14px;border-radius:var(--r-sm);
  background:var(--waterline);color:#14181C;font-weight:700;font-size:11.5px}
/* the administration surface wrapper. It had NO rule when first shipped and
   _test-plate-fit caught it — the same shape as the caret's undefined token:
   a class that exists in markup and nowhere in CSS. */
.sh-admin{display:block}
.sh-admin-hd{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:7px}
.sh-admin-hd b{font-size:12.5px;color:var(--star)}
.sh-admin-hd span{font-family:var(--f-data);font-size:10px;color:var(--star-dim)}
.sh-toggle{display:inline-flex;border:1px solid var(--hairline-c);border-radius:var(--r-sm);
  overflow:hidden;margin-bottom:9px}
.sh-toggle span{padding:3px 11px;font-size:10px;color:var(--star-dim);font-family:var(--f-data)}
.sh-toggle span.on{background:var(--panel-hd);color:var(--star)}
.sh-passage{font-size:12.5px;line-height:1.75;color:var(--star);margin:0 0 11px}
.sh-passage em{font-style:normal;font-weight:700;display:block;margin-bottom:4px}
/* a marked miscue, as the examiner taps it */
.sh-passage u.mk{text-decoration:none;background:color-mix(in srgb,var(--alert) 26%,transparent);
  border-bottom:2px solid var(--alert);border-radius:2px;padding:0 2px}

/* ══ THE PLATFORM CARD ══════════════════════════════════════════════════════
   Measured from the founder's captures, docs/PANEL_UI_PARITY_2026-08-17.md.
   The old chrome (.shot / .shot-hd with a teal dot and uppercase mono) was a
   component the product does not have. This is the one it does. */
:root{
  /* the product's ground is near-black and its cards a desaturated slate —
     markedly darker and less blue than the panels had drifted to. */
  --pc-bg:      #151C2B;
  --pc-hair:    color-mix(in srgb, var(--star) 11%, transparent);
  --pc-label:   color-mix(in srgb, var(--star) 46%, transparent);
  /* accent per surface, as the product assigns them */
  --pc-refer:     #C86BA6;
  --pc-decide:    #8A8CE8;
  --pc-assess:    var(--waterline);
  --pc-analytics: var(--phosphor);
  --pc-record:    #6E8BB5;
  --pc-assist:    var(--mira);
}
.pcard{margin-top:18px}
.pcard-label{
  font-family:var(--f-data);font-size:9px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--pc-label);margin:0 0 5px 2px;
}
.pcard-in{
  position:relative;border:1px solid var(--pc-hair);border-radius:var(--r-plate);
  background:var(--pc-bg);overflow:hidden;
}
/* the left accent bar — the signature this chrome was missing entirely */
.pcard-in::before{
  content:"";position:absolute;inset:0 auto 0 0;width:3px;background:var(--pc-accent,var(--pc-record));
}
.pcard-record   .pcard-in{--pc-accent:var(--pc-record)}
.pcard-refer    .pcard-in{--pc-accent:var(--pc-refer)}
.pcard-decide   .pcard-in{--pc-accent:var(--pc-decide)}
.pcard-assess   .pcard-in{--pc-accent:var(--pc-assess)}
.pcard-analytics .pcard-in{--pc-accent:var(--pc-analytics)}
.pcard-assist   .pcard-in{--pc-accent:var(--pc-assist)}
.pcard-hd{display:grid;grid-template-columns:auto 1fr;gap:2px 9px;padding:11px 14px 9px 16px}
.pcard-ic{
  grid-row:1/3;align-self:start;width:16px;height:16px;margin-top:2px;border-radius:3px;
  border:1.5px solid var(--pc-accent,var(--pc-record));opacity:.85;
}
.pcard-t{font-size:13.5px;font-weight:700;color:var(--pc-accent,var(--star));line-height:1.25}
.pcard-s{font-size:11px;color:var(--star-dim);line-height:1.35}
.pcard-body{padding:2px 14px 13px 16px;overflow-x:auto}
.pcard-cap{
  padding:9px 14px 11px 16px;border-top:1px solid var(--pc-hair);
  font-size:11.5px;line-height:1.5;color:var(--star-dim);
  background:color-mix(in srgb,#000 14%,transparent);
}
.pcard-cap b{color:var(--star);font-weight:600}

/* ⭐ DISABLED-WITH-REASON, the platform's signature, as one shape.
   A dimmed row whose reason stays legible underneath — the product does this on
   at least three surfaces and it is the clearest thing it does. */
.pdecl{padding:8px 0}
.pdecl b{display:block;font-size:12.5px;font-weight:700;color:var(--star-dim);opacity:.7}
.pdecl i{display:block;font-style:normal;font-size:11px;color:var(--amber);margin-top:2px}

/* ── the browser frame every card now carries ─────────────────────────────
   The Mira panel had this and nothing else did, which is why the others read
   flat. Same shape, promoted into card(). */
.pc-bar{
  display:flex;align-items:center;gap:6px;padding:6px 11px;
  background:color-mix(in srgb,#000 26%,var(--pc-bg));
  border-bottom:1px solid var(--pc-hair);
}
.pc-dot{width:7px;height:7px;border-radius:50%;flex:none;
  background:color-mix(in srgb,var(--star) 20%,transparent)}
.pc-url{
  flex:1;margin-left:5px;padding:2px 8px;border-radius:999px;
  background:color-mix(in srgb,#000 22%,transparent);
  font-family:var(--f-data);font-size:9.5px;color:var(--star-dim);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.pc-path{color:color-mix(in srgb,var(--star) 34%,transparent)}

/* ── the acted scene: pointer, marked words, ticking tallies ──────────────── */
.plate-fit-in{position:relative}
.seq-cursor{
  position:absolute;left:0;top:0;width:13px;height:13px;margin:-2px 0 0 -2px;
  pointer-events:none;z-index:5;
  border:2px solid var(--star);border-radius:50% 50% 50% 2px;
  background:color-mix(in srgb,var(--star) 22%,transparent);
  transition:transform 700ms cubic-bezier(.4,.1,.2,1);
}
.seq-cursor.is-press{transform-origin:center;box-shadow:0 0 0 7px color-mix(in srgb,var(--star) 16%,transparent)}
.kw{
  padding:0 2px;border-radius:2px;cursor:default;
  transition:background 180ms ease,box-shadow 180ms ease;
}
.kw.is-acted{
  background:color-mix(in srgb,var(--alert) 30%,transparent);
  box-shadow:inset 0 -2px 0 var(--alert);
}
[data-tally]{transition:color 180ms ease}
.is-acting [data-tally]{color:var(--alert)}
[data-act-final].is-armed{border-color:var(--phosphor)}
@media (prefers-reduced-motion: reduce){ .seq-cursor{display:none} }

/* ══ THE SETUP DRAWER ═══════════════════════════════════════════════════════
   Founder, 2026-08-17: "see how it opens anchored to the bottom of the page
   like a pull up drawer." The setup is not a card on a page — it rises from the
   bottom over the dimmed application, which stays visible above it. Drawing it
   as a standalone card lost the fact that the examiner never leaves the screen
   they were on. */
.kv-app{
  position:absolute;inset:0 0 auto 0;height:17%;overflow:hidden;
  opacity:.30;filter:saturate(.5);pointer-events:none;
}
.kv-apphd{display:flex;align-items:center;gap:7px;padding:7px 11px;border-bottom:1px solid var(--pc-hair)}
.kv-apphd span{width:9px;height:9px;border-radius:2px;background:var(--pc-decide)}
.kv-apphd b{font-size:11px;color:var(--star)}
.kv-appbody{display:grid;grid-template-columns:1fr 1fr;gap:5px;padding:5px 11px}
.kv-appcard{height:22px;border:1px solid var(--pc-hair);border-radius:5px;background:color-mix(in srgb,#000 18%,transparent)}
.kv-approw{grid-column:1/-1;height:22px;border:1px solid var(--pc-hair);border-radius:5px}
/* the drawer itself */
.kv-draw{
  position:absolute;inset:auto 0 0 0;height:83%;
  background:var(--pc-bg);border-top:1px solid var(--pc-hair);
  box-shadow:0 -18px 40px rgba(0,0,0,.45);
  display:flex;flex-direction:column;
}
.kv-drawhd{
  display:flex;align-items:center;justify-content:space-between;
  padding:7px 14px;border-bottom:1px solid var(--pc-hair);
  background:color-mix(in srgb,#000 16%,var(--pc-bg));
}
.kv-drawhd b{font-size:13px;color:var(--star)}
.kv-drawhd span{color:var(--star-dim);font-size:14px}
.kv-drawbody{flex:1;min-height:0;overflow:auto;padding:9px 0 11px;
  display:flex;flex-direction:column;gap:4px;align-items:stretch}
/* ⛔ align-self, NOT margin-inline:auto. Founder, 2026-08-17: "text is
   misaligned". The step line rendered flush to the drawer edge while the
   options sat in a centred column, because `.kv-step{margin:0 0 2px}` is a
   SHORTHAND and it reset the auto inline margins this rule had just set. Every
   child with a margin shorthand had the same silent defeat. Flex alignment
   cannot be undone by a margin, so the centring survives whatever a child
   declares later. */
.kv-drawbody>*{inline-size:min(560px,86%);align-self:center}
.kv-step{font-size:11.5px;color:var(--star-dim);margin:0 0 2px}
.kv-step span{margin-right:7px}
/* an option row: bold name, grey note, teal ground when chosen */
.kv-opt{padding:5px 12px;border-radius:5px;background:transparent;text-align:left}
.kv-opt b{display:block;font-size:12px;color:var(--star);font-weight:700}
.kv-opt i{display:block;font-style:normal;font-size:11px;color:var(--star-dim);margin-top:1px}
.kv-opt.on{background:color-mix(in srgb,var(--phosphor) 20%,transparent)}
.kv-opt.off{opacity:.45}
.kv-opt.off i{color:var(--amber);opacity:1}
.kv-opt.is-acted{outline:1px solid var(--phosphor)}
.kv-check{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--star-dim)}
/* ⚠ 9px floors measured after the zoom, not authored sizes. The adversarial
   sweep put three elements under a 9px rendered floor: the error-type badge
   at 8.2px and two step-4 sub-labels at 8.9px. Everything else cleared it
   once the zoom landed (16.7 / 11.3 / 10.6px). These are the last three. */
.ac-item .kv-check{font-size:10.5px}
.kv-check span{width:13px;height:13px;border:1px solid var(--star-dim);border-radius:3px;flex:none}
.kv-block{display:flex;gap:9px;padding:10px 12px;border-radius:5px;
  background:color-mix(in srgb,var(--amber) 12%,transparent);border-left:3px solid var(--amber)}
.kv-block b{display:block;font-size:12.5px;color:var(--star)}
.kv-block i{display:block;font-style:normal;font-size:11px;color:var(--amber);margin-top:2px}
.kv-empty{padding:14px 12px;font-size:12px;color:var(--star-dim);font-style:italic;
  border:1px dashed var(--pc-hair);border-radius:5px;text-align:center}
.kv-aside{font-size:11px;color:var(--star-dim);margin:0}
.kv-lbl{font-family:var(--f-data);font-size:9px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--star-dim);margin:4px 0 0}
.kv-chips{display:flex;gap:6px;flex-wrap:wrap}
.kv-chips span{padding:3px 10px;border-radius:999px;font-size:11px;color:var(--star-dim);
  border:1px solid var(--pc-hair)}
.kv-chips span.on{background:color-mix(in srgb,var(--phosphor) 22%,transparent);
  border-color:var(--phosphor);color:var(--star)}
.kv-chips span.is-acted{outline:1px solid var(--phosphor)}
/* the stacked review */
.kv-rev{margin:0;display:flex;flex-direction:column;border:1px solid var(--pc-hair);border-radius:5px;overflow:hidden}
/* ⚠ Sized to FIT, not to taste. The monitor is fixed (see canvas.css), so a
   review that needs scrolling shows the viewer 4 of its 8 rows and calls it
   the whole configuration — measured 2026-08-17, exactly that. Content that
   cannot fit a fixed screen is a content problem, not a screen problem. */
.kv-rev>div{display:grid;grid-template-columns:104px 1fr auto;align-items:center;gap:8px;
  padding:3px 10px;border-bottom:1px solid var(--pc-hair)}
.kv-rev>div:nth-child(odd){background:color-mix(in srgb,#000 12%,transparent)}
.kv-rev>div:last-child{border-bottom:0}
.kv-rev dt{font-size:10px;color:var(--star-dim);margin:0}
.kv-rev dd{margin:0;font-size:11.5px;font-weight:700;color:var(--star)}
.kv-rev span{padding:1px 8px;border-radius:4px;font-size:10px;color:var(--star-dim);
  background:color-mix(in srgb,var(--star) 12%,transparent)}
.kv-rev span.is-acted{outline:1px solid var(--phosphor);color:var(--star)}
.kv-note{font-size:10.5px;color:var(--star-dim);margin:0}
/* the full-width primary the drawer always ends on */
.kv-cta{
  padding:9px 14px;border-radius:5px;text-align:center;font-weight:700;font-size:12.5px;
  background:var(--phosphor);color:#0C1512;
}
.kv-cta.is-acted{filter:brightness(1.12)}

/* ══ THE ORF ADMINISTRATION SCREEN ══════════════════════════════════════════
   Founder, 2026-08-17: "the orf probe also has a timer to start, a button to
   mark the last word read, and the overview of the probe information is in a
   row wrapping but it all stacks in the real platform."

   Two grounds, and the split is the point: the passage sits on WHITE because a
   child reads it, and the examiner's controls sit on the dark chrome because
   the examiner is operating software. The first build had one ground for both,
   which is why it did not read as an administration.
   ⚠ The passage is invented. Real probe content is never published — see
   build/lint-no-probe-content.js. */
/* ⚠ Sized to the fixed monitor. Measured 2026-08-17 by
   _test-monitor-stability check 3: these two frames overflowed by 25 and 27 px,
   and in an autoplaying sequence the reader cannot scroll to reach it. */
.orf{display:grid;grid-template-columns:1fr 196px;gap:9px;align-items:stretch;
  block-size:100%;min-block-size:0}
/* the reading ground */
.orf-read{background:#F7F5EF;border-radius:6px;padding:9px 12px;color:#16211E;
  overflow:hidden;min-block-size:0}
.orf-guide{display:flex;align-items:center;gap:6px;margin-bottom:7px}
.orf-guide b{font-family:var(--f-data);font-size:8.5px;letter-spacing:.08em;
  text-transform:uppercase;color:#6A7370;font-weight:600}
.orf-guide span{padding:2px 8px;border-radius:999px;font-size:10px;color:#6A7370;
  border:1px solid #D7D2C6}
.orf-guide span.on{background:#16211E;border-color:#16211E;color:#F7F5EF}
.orf-title{margin:0 0 5px;font-size:13px;font-weight:700;color:#16211E}
.orf-text{margin:0;font-size:12.5px;line-height:1.7;color:#16211E;text-align:left}
.orf-text sup{font-family:var(--f-data);font-size:8px;color:#9AA29E;
  vertical-align:super;margin-right:2px;font-weight:600}
/* a word the examiner has marked as a miscue */
.orf-text .kw{padding:0 1px;border-radius:2px;transition:background .18s,color .18s}
.orf-text .kw.is-acted{background:#C4442E;color:#FFF;text-decoration:line-through}
/* the examiner's rail — everything STACKS, one control per row */
.orf-rail{display:flex;flex-direction:column;gap:5px;min-block-size:0}
.orf-steps{display:flex;gap:4px}
.orf-steps span{flex:1;text-align:center;padding:3px 0;border-radius:4px;
  font-family:var(--f-data);font-size:8.5px;color:var(--star-dim);
  border:1px solid var(--pc-hair)}
.orf-steps span.on{background:color-mix(in srgb,var(--phosphor) 22%,transparent);
  border-color:var(--phosphor);color:var(--star)}
.orf-script{margin:0;padding:6px 9px;border-left:3px solid var(--phosphor);
  border-radius:0 4px 4px 0;background:color-mix(in srgb,#000 18%,transparent);
  font-size:11px;line-height:1.5;color:var(--star);font-style:italic}
.orf-timer{text-align:center;padding:3px 0;border:1px solid var(--pc-hair);border-radius:5px}
.orf-timer b{font-family:var(--f-data);font-size:20px;font-weight:600;
  color:var(--star);font-variant-numeric:tabular-nums;letter-spacing:.02em}
.orf-start{padding:6px 10px;border-radius:5px;text-align:center;font-weight:700;
  font-size:12px;background:var(--phosphor);color:#0C1512}
.orf-start.is-acted{filter:brightness(1.14)}
/* once the timer has run, the same slot becomes the stop control the founder
   named — "a button to mark the last word read" */
.orf-start.done{background:transparent;border:1px solid var(--phosphor);color:var(--phosphor)}
.orf-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:5px}
.orf-stats span{text-align:center;padding:3px 0;border-radius:5px;
  background:color-mix(in srgb,#000 18%,transparent);border:1px solid var(--pc-hair)}
.orf-stats b{display:block;font-family:var(--f-data);font-size:15px;font-weight:600;
  color:var(--star);font-variant-numeric:tabular-nums}
.orf-stats i{display:block;font-style:normal;font-size:8.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--star-dim);margin-top:1px}
.orf-stats .e b{color:var(--amber)}
.orf-stats .s b{color:var(--phosphor)}
.orf-score{padding:6px 10px;border-radius:5px;border:1px solid var(--pc-hair);text-align:center}
.orf-score i{display:block;font-style:normal;font-family:var(--f-data);font-size:8.5px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--star-dim)}
.orf-score b{display:block;font-family:var(--f-data);font-size:22px;font-weight:600;
  color:var(--star-dim);line-height:1.1;font-variant-numeric:tabular-nums}
.orf-score span{display:block;font-size:10px;color:var(--star-dim)}
.orf-score em{display:block;font-style:normal;font-size:10px;color:var(--star-dim);margin-top:3px}
.orf-score.armed{border-color:var(--phosphor);
  background:color-mix(in srgb,var(--phosphor) 10%,transparent)}
.orf-score.armed b{color:var(--phosphor)}
.orf-score.armed span{color:var(--star)}
@media (max-width:760px){ .orf{grid-template-columns:1fr} }

/* Found by build/lint-unstyled-element.js on its first run — the three wrappers
   below carried a class that read as deliberate and resolved to nothing, so each
   was taking a default UA margin instead of the spacing its name implies.
   `.w` is the same defect one hour old: its two siblings in .orf-stats declare a
   colour and it did not, so the Words box was the only one inheriting. */
.shot-prov{margin:6px 0 0;font-size:11px;line-height:1.5;color:var(--star-dim)}
.doc-go{margin:10px 0 0}
.smc-body{display:flex;flex-direction:column;gap:6px;min-inline-size:0}
.orf-stats .w b{color:var(--star)}

/* ── the monitor tab: where the cycle starts and where it lands ─────────────
   Founder, 2026-08-17: "no step for handoff to view as data point in monitor
   chart." The sequence ended at the score, which is half a claim — the page
   says a probe scored on the tablet reaches the chart without re-entry, and
   nothing showed the chart. First and last frame are the same surface, one
   point apart, which is the whole argument made visually. */
.mon-wrap{display:flex;flex-direction:column;gap:9px;height:100%}
.mon{border:1px solid var(--pc-hair);border-radius:6px;padding:10px 12px;flex:1;
  display:flex;flex-direction:column;gap:7px;min-block-size:0}
.mon-hd{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap}
.mon-hd b{font-size:12.5px;color:var(--star)}
.mon-hd span{font-size:10.5px;color:var(--star-dim)}
.mon-chart{width:100%;flex:1;min-block-size:0}
.mon-aim{stroke:var(--star-dim);stroke-width:1;stroke-dasharray:4 4;opacity:.55}
.mon-line{stroke:var(--phosphor);stroke-width:1.6;opacity:.85}
.mon-dot{fill:var(--phosphor);opacity:.85}
.mon-new{fill:var(--amber);opacity:1}
.mon-tag{fill:var(--amber);font-family:var(--f-data);font-size:9px;font-weight:600}
.mon-foot{display:flex;justify-content:space-between;font-size:10.5px;color:var(--star-dim)}
.mon-act{display:flex;align-items:center;justify-content:space-between;gap:12px}
.mon-act>span{font-size:11.5px;color:var(--star-dim)}
.kv-cta-sm{padding:6px 18px;flex:none}
.kv-cta-quiet{background:transparent;border:1px solid var(--phosphor);color:var(--phosphor)}
/* ⚠ the drawer's own text direction, set once. The "Cannot start" block came
   out centre-aligned in the founder's capture because nothing here declared it
   and the card ground centres by default. */
.kv-drawbody{text-align:left}
.orf-steps span.done{color:var(--phosphor);border-color:color-mix(in srgb,var(--phosphor) 40%,transparent)}

/* ── the Action Center row, and the tab it lands on ─────────────────────────
   Validated against the product before it was drawn (MTSS2RTI.html): the alert
   is real (`_gatherCalendarEvents` type:'probes', deadline:true) and its label
   text is quoted verbatim. What is deliberately NOT drawn is a kiosk launcher
   on the alert — `_alertNavigate` routes probes to {tab:3, openPMModal('data')}
   and no due signal reaches any of the 14 `openProbeKiosk(` call sites. */
.ac{border:1px solid var(--pc-hair);border-radius:6px;overflow:hidden;height:100%;
  display:flex;flex-direction:column}
.ac-top{display:flex;align-items:center;gap:8px;padding:8px 12px;
  border-bottom:1px solid var(--pc-hair);background:color-mix(in srgb,#000 16%,transparent)}
.ac-top b{font-size:12.5px;color:var(--star)}
.ac-n{font-family:var(--f-data);font-size:9.5px;padding:1px 7px;border-radius:999px;
  background:color-mix(in srgb,var(--phosphor) 24%,transparent);color:var(--star)}
.ac-list{display:flex;flex-direction:column}
.ac-row{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:10px;
  padding:9px 12px;border-bottom:1px solid var(--pc-hair)}
.ac-row:last-child{border-bottom:0}
.ac-row b{display:block;font-size:11.5px;font-weight:700;color:var(--star)}
.ac-row i{display:block;font-style:normal;font-size:10.5px;color:var(--star-dim);margin-top:1px}
.ac-dot{width:7px;height:7px;border-radius:50%;background:var(--phosphor)}
.ac-late{background:var(--alert)}
.ac-go{font-size:10.5px;color:var(--star-dim);white-space:nowrap}
.ac-due{background:color-mix(in srgb,var(--phosphor) 10%,transparent)}
.ac-due .ac-go{color:var(--phosphor)}
.ac-row.is-acted{outline:1px solid var(--phosphor);outline-offset:-1px}
.pm{display:flex;flex-direction:column;gap:8px;height:100%}
.pm-tabs{display:flex;gap:3px;border-bottom:1px solid var(--pc-hair);padding-bottom:5px}
.pm-tabs span{padding:3px 10px;border-radius:4px 4px 0 0;font-size:11px;color:var(--star-dim)}
.pm-tabs span.on{color:var(--star);background:color-mix(in srgb,var(--phosphor) 16%,transparent)}
.pm-bar{display:flex;align-items:center;justify-content:space-between;gap:12px}
.pm-bar b{font-size:12.5px;color:var(--star)}
.pm-ic{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:5px;
  border:1px solid var(--pc-hair);font-size:12px;color:var(--star-dim)}
.pm-ic i{font-style:normal;font-size:10.5px}
.pm-ic.is-acted{border-color:var(--phosphor);color:var(--star);
  background:color-mix(in srgb,var(--phosphor) 16%,transparent)}
.pm-goal{padding:7px 11px;border-radius:5px;font-size:11.5px;color:var(--star-dim);
  border-left:3px solid var(--phosphor);background:color-mix(in srgb,#000 16%,transparent)}
.pm-goal b{color:var(--star)}
.pm-cad{font-family:var(--f-data);font-size:9.5px;padding:1px 7px;border-radius:999px;
  border:1px solid var(--pc-hair);margin-left:6px}
.pm-chartbox{flex:1;min-block-size:0;border:1px solid var(--pc-hair);border-radius:6px;padding:8px}
.pm-chartbox svg{width:100%;height:100%}

/* ══ THE WORKSPACE MONITOR TAB ══════════════════════════════════════════════
   Rebuilt 2026-08-17 from MTSS2RTI.html rather than from memory, after the
   founder listed what was missing: legend, goal container, the four-point
   decision rule, the tab bar, the student pill and the header icon buttons.
   ⚠ The read corrected me on two things worth keeping written down:
     · there is ONE decision card, not four — the "four" is the four dots and
       the four ROI stat blocks inside it (#fourPointCard, 4315)
     · the student pill shows a TIER BADGE and TWO-LETTER INITIALS; the name and
       grade are the tooltip (updateDomainPill, 65300-65312). Drawing the name
       as text would have been a fabricated component. */
.ws-nav{display:flex;align-items:center;gap:3px;padding-bottom:4px;
  border-bottom:1px solid var(--pc-hair)}
.ws-tab{padding:2px 10px;border-radius:4px;font-size:11px;color:var(--star-dim)}
.ws-tab.on{color:var(--star);background:color-mix(in srgb,var(--phosphor) 18%,transparent)}
.ws-div{width:1px;height:14px;background:var(--pc-hair);margin:0 5px}
.ws-pill{margin-left:auto;display:inline-flex;align-items:center;gap:5px;
  padding:2px 7px;border-radius:999px;border:1px solid var(--pc-hair)}
.ws-pill b{font-family:var(--f-data);font-size:9px;padding:0 5px;border-radius:999px;
  background:#D97706;color:#16211E;font-weight:700}
.ws-pill i{font-style:normal;font-size:10.5px;font-weight:700;color:var(--star)}
.ws-pill svg{width:8px;height:5px;fill:none;stroke:var(--star-dim);stroke-width:1.4}
.ws-bar{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin:4px 0 5px}
.ws-bar b{display:block;font-size:12.5px;color:var(--star)}
.ws-bar i{display:block;font-style:normal;font-size:9.5px;color:var(--star-dim);margin-top:0}
.ws-ics{display:flex;gap:5px;flex:none}
.ws-ic{width:24px;height:24px;display:grid;place-items:center;border-radius:5px;
  border:1px solid var(--pc-hair)}
.ws-ic svg{width:14px;height:14px;fill:none;stroke:var(--star-dim);stroke-width:1.5;
  stroke-linecap:round}
.ws-ic.is-acted{border-color:var(--phosphor);background:color-mix(in srgb,var(--phosphor) 18%,transparent)}
.ws-ic.is-acted svg{stroke:var(--star)}
/* ⚠ text-align:left is declared, not assumed. The card ground centres by
   default, so every reproduction inherits centred body text and reads as a
   poster rather than an application. Third time on this page. */
/* ⚠ 196px, not 172px, and the reason is measured: at 172 the cadence line
   wrapped to a third line and drove the LEFT column past the fixed monitor by
   6 px. Trimming the right column could not have fixed it — the taller column
   sets the height, and it was not the one being trimmed. */
.ws-cols{display:grid;grid-template-columns:196px 1fr;gap:7px;align-items:stretch;
  text-align:left;flex:1;min-block-size:0}
/* the goal card, left rail, teal edge as the product draws it */
.ws-goal{align-self:start;border-left:3px solid var(--phosphor);border-radius:0 5px 5px 0;padding:5px 9px;
  background:color-mix(in srgb,#000 16%,transparent);display:flex;flex-direction:column;gap:2px}
/* ⚠ NOT `eyebrow`, and the rename is a distinction rather than a dodge.
   lint-copy-budget bans class names `kicker`/`eyebrow` at budget 0 because
   the base audit deletes letterspaced kickers from OUR editorial voice. This
   is not our voice: it is the product's own card label (#pmGoalSummaryCard,
   MTSS2RTI.html:4276, 9px uppercase letterspaced) inside a reconstruction of
   its screen, and `.pcard-label` — the same thing one level up — already sets
   that precedent and passes. Renaming a site kicker to slip this rule would
   be the evasion the rule exists to catch; reproducing a product label is a
   different object. */
.ws-cardlabel{margin:0 0 3px;font-family:var(--f-data);font-size:8px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--phosphor);font-weight:700}
.ws-goal p{margin:0;font-size:10px;color:var(--star-dim)}
.ws-goal b{color:var(--star)}
.ws-pills{display:flex;gap:4px;margin-bottom:3px}
.ws-pills span{font-size:9px;padding:1px 6px;border-radius:999px}
.gp-d{background:color-mix(in srgb,#34D399 22%,transparent);color:var(--star)}
.gp-s{background:color-mix(in srgb,var(--phosphor) 22%,transparent);color:var(--star)}
.ws-win{opacity:.85}
.ws-cad{margin-top:2px;padding-top:3px;border-top:1px solid var(--pc-hair);font-size:9px}
.ws-cad .due b{color:#D97706}
.ws-cad .next b{color:var(--phosphor)}
.ws-cad .cadn{opacity:.8}
/* the chart card and its nine-item key */
/* ⚠ min-block-size:0 is what lets the chart give way. A grid item's automatic
   minimum is its content size, so .ws-main refused to compress and the chart
   inside it never used its flex:1 — the frame overflowed by 3px and four
   rounds of trimming other elements moved nothing, because none of them was
   the constraint. Measure the box before shrinking its neighbours. */
.ws-main{display:flex;flex-direction:column;gap:5px;min-inline-size:0;min-block-size:0}
/* the screen grew on the founder's read; the chart takes the room rather than
   leaving a void under the decision card */
.ws-chart{border:1px solid var(--pc-hair);border-radius:5px;padding:5px 8px;
  flex:1;min-block-size:0;display:flex;flex-direction:column}
.ws-ch-hd b{font-size:10.5px;color:var(--star)}
.ws-ch{width:100%;flex:1;min-block-size:30px;margin:1px 0 2px}
.c-aim{stroke:#34D399;stroke-width:1;stroke-dasharray:4 3}
.c-line{stroke:#60A5FA;stroke-width:1.5}
.c-dot{fill:#34D399}
.c-new{fill:#F472B6}
.c-tag{fill:#F472B6;font-family:var(--f-data);font-size:8px;font-weight:600}
/* five columns, so nine items are two rows rather than three — the legend is
   the product's nine, kept whole, at the density the fixed monitor allows */
.ws-key{display:grid;grid-template-columns:repeat(5,auto);gap:1px 10px;justify-content:start}
.ck{display:flex;align-items:center;gap:4px;font-size:8px;color:var(--star-dim);white-space:nowrap}
.ck-dot{width:7px;height:7px;border-radius:50%;background:var(--c);flex:none}
.ck-dash{width:12px;height:0;border-top:2px dashed var(--c);flex:none}
.ck-bar{width:12px;height:2px;background:var(--c);flex:none}
.ck-dia{width:7px;height:7px;background:var(--c);transform:rotate(45deg);flex:none}
.ck-star{width:8px;height:8px;background:var(--c);flex:none;
  clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
/* the ONE decision card */
.ws-4pt{border:1px solid var(--pc-hair);border-radius:5px;padding:5px 8px;
  display:flex;flex-direction:column;gap:3px}
.ws-4hd{display:flex;align-items:center;justify-content:space-between;gap:10px}
.ws-4hd b{font-size:10.5px;color:var(--star)}
.ws-badge{font-family:var(--f-data);font-size:8.5px;padding:1px 7px;border-radius:999px;
  background:color-mix(in srgb,#60A5FA 22%,transparent);color:var(--star)}
.ws-4dots{display:flex;align-items:center;gap:3px}
.ws-4dots em{font-style:normal;font-size:8px;color:var(--star-dim)}
.pt-dot{width:15px;height:15px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--f-data);font-size:9px;font-weight:600}
.pt-dot.above{background:#34D399;color:#0C1512}
.pt-dot.below{background:#F87171;color:#0C1512}
.pt-dot.empty{border:1px dashed var(--pc-hair);color:var(--star-dim)}
.ws-4stats{display:grid;grid-template-columns:repeat(4,1fr);gap:3px}
.sb{text-align:center;padding:1px 0;border-radius:4px;
  background:color-mix(in srgb,#000 18%,transparent)}
.sb b{display:block;font-family:var(--f-data);font-size:10px;font-weight:600}
.sb i{display:block;font-style:normal;font-size:8px;color:var(--star-dim);margin-top:1px}
.sb-good b{color:#34D399}
.sb-warn b{color:#D97706}
.sb-bad b{color:#F87171}
.sb-info b{color:#60A5FA}
.ws-verdict{padding:3px 8px;border-radius:4px;
  background:color-mix(in srgb,#34D399 12%,transparent);border-left:3px solid #34D399}
.ws-verdict b{display:block;font-size:10.5px;color:var(--star)}
.ws-verdict span{display:block;font-size:9px;color:var(--star-dim);margin-top:0}
.ws-verdict.is-acted{outline:1px solid var(--phosphor)}

/* ══ THE WORKSPACE NAV BAR ══════════════════════════════════════════════════
   MTSS2RTI.html:3466-3562, CSS 237-257, visual order 309-317.
   ⭐ THE BEHAVIOUR I HAD MOST WRONG: inactive tabs are ICON-ONLY. `.tab-lbl` is
   max-width:0/opacity:0 and only the active tab slides its word out (255). Five
   worded tabs was a redrawing of the product's most visible habit. */
.tn{display:flex;align-items:center;gap:2px;padding-bottom:4px;text-align:left;
  border-bottom:1px solid var(--pc-hair)}
.tn-env{width:22px;height:20px;display:grid;place-items:center;color:var(--phosphor)}
.tn-env svg{width:14px;height:14px}
.tn-mode{display:inline-flex;align-items:stretch;height:17px;border-radius:999px;
  overflow:hidden;margin:0 5px 0 1px;font-size:8px;letter-spacing:.04em}
.tn-mode b{display:inline-flex;align-items:center;padding:0 6px;background:var(--phosphor);
  color:#0C1512;font-weight:800}
.tn-mode i{display:inline-flex;align-items:center;padding:0 6px;font-style:normal;
  font-weight:700;color:var(--star-dim);background:color-mix(in srgb,#000 22%,transparent)}
.tn-div{width:1px;height:14px;background:var(--pc-hair);margin:0 5px}
.tn-tab{display:inline-flex;align-items:center;padding:2px 7px;border-radius:4px;
  color:var(--star-dim);border-bottom:2px solid transparent}
.tn-tab svg{width:15px;height:15px;flex:none}
/* ⛔ ONLY THE ACTIVE TAB EMITS A LABEL, and that is an accessibility fix rather
   than a styling one. The product collapses inactive labels with
   max-width:0/opacity:0 (MTSS2RTI.html:254) — fine in a live app where the
   button carries an aria-label and hover reveals the word. Copying the CSS into
   a static reconstruction left four real words at opacity:0 on every frame:
   invisible to a sighted reader, still reachable by a screen reader, and caught
   by _test-a11y as 12 invisible elements. The icons carry `title` instead. */
.tn-tab .tab-lbl{font-size:10.5px;font-weight:600;line-height:1;
  margin-inline-start:6px;white-space:nowrap}
.tn-tab.on{color:var(--phosphor);border-bottom-color:var(--phosphor)}
.tn-pill{margin-inline-start:auto;display:inline-flex;align-items:center;gap:5px;
  padding:1px 7px;border-radius:999px;border:1px solid var(--pc-hair);flex:none}
.tn-pill b{font-family:var(--f-data);font-size:8.5px;padding:0 5px;border-radius:999px;
  background:#D97706;color:#16211E;font-weight:700}
.tn-pill i{font-style:normal;font-size:10px;font-weight:700;color:var(--star);
  font-family:var(--f-data)}

/* ══ THE STUDENT IDENTITY STRIP ═════════════════════════════════════════════
   _applyGateState 202872, content 203030-203125. Injected into EVERY workspace
   panel, so its absence from the Monitor view was a missing component rather
   than a styling choice. Not #headerPill — that is the tiny pill in the nav. */
.sid{display:flex;align-items:center;gap:8px;margin:4px 0 5px;padding:4px 8px;
  border:1px solid var(--pc-hair);border-radius:5px;
  background:color-mix(in srgb,#000 16%,transparent)}
.sid-ic{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;flex:none;
  background:color-mix(in srgb,var(--star) 10%,transparent);color:var(--star-dim)}
.sid-ic svg{width:15px;height:15px}
.sid-tx{flex:1;min-inline-size:0;text-align:left}
.sid-tx b{display:block;font-size:11px;color:var(--star);line-height:1.15}
.sid-sub{display:block;font-size:9.5px;color:var(--star-dim);margin-top:1px}
.sid-chips{display:flex;gap:4px;flex-wrap:wrap;margin-top:3px}
.ch{font-size:8px;padding:1px 7px;border-radius:9px;color:var(--star-dim);
  background:color-mix(in srgb,#000 20%,transparent);white-space:nowrap}
.ch em{font-style:normal;font-weight:700;color:var(--star-dim);opacity:.75;margin-right:3px}
.ch-504{background:color-mix(in srgb,var(--phosphor) 22%,transparent);color:var(--star);font-weight:700}
.ch-con{border:1px solid #F87171;color:#F87171;background:transparent}
.ch-fam{border:1px solid var(--pc-hair);background:transparent}
.sid-kb{width:22px;height:22px;display:grid;place-items:center;flex:none;color:var(--star-dim)}
.sid-kb svg{width:13px;height:13px}

/* ══ THE ACTION CENTER PANEL ════════════════════════════════════════════════
   _renderAlertsDropdown 289855, CSS 2640-2655. 340px, anchored under the bell,
   header + count pill + four filter chips + grouped rows, each row four
   controls wide. The earlier frame was a bare list on a blank card. */
.ad-stage{display:flex;justify-content:flex-end;padding:8px 0 0}
.ad{inline-size:340px;max-inline-size:100%;border:1px solid var(--pc-hair);border-radius:8px;
  background:var(--pc-bg);box-shadow:0 8px 24px rgba(0,0,0,.45);overflow:hidden}
.ad-hd{display:flex;align-items:center;gap:8px;padding:8px 12px;
  border-bottom:1px solid var(--pc-hair)}
.ad-title{font-size:9.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--star)}
.ad-count{font-size:8.5px;font-weight:700;padding:1px 8px;border-radius:10px;
  background:color-mix(in srgb,#F87171 20%,transparent);color:#F87171}
.ad-tabs{display:flex;gap:2px;flex-wrap:wrap;margin:4px 8px 6px}
.ad-tabs span{font-size:8px;padding:2px 8px;border-radius:8px;color:var(--star-dim);
  background:color-mix(in srgb,#000 22%,transparent)}
.ad-tabs span.on{background:#6366F1;color:#fff;font-weight:700}
.ad-grp{margin:0;padding:5px 12px 2px;font-size:8px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--star-dim)}
.ad-grp-red{color:#F87171}
.ad-row{display:flex;align-items:stretch;border-bottom:1px solid var(--pc-hair)}
.ad-row.over{background:color-mix(in srgb,#F87171 10%,transparent)}
.ad-item{flex:1;min-inline-size:0;display:flex;align-items:center;gap:8px;padding:6px 12px}
.ad-dot{width:6px;height:6px;border-radius:50%;flex:none}
.ad-label{flex:1;min-inline-size:0;font-size:10px;color:var(--star);line-height:1.3;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ad-date{font-size:8.5px;font-weight:600;white-space:nowrap;color:var(--star-dim)}
.ad-ctl{display:grid;place-items:center;padding:0 8px;border-left:1px solid var(--pc-hair);
  color:var(--star-dim)}
.ad-ctl svg{width:12px;height:12px}
.ad-go{color:var(--phosphor)}
.ad-x{padding:0 11px;font-size:13px}
.ad-row.is-acted{outline:1px solid var(--phosphor);outline-offset:-1px}

/* ══ ERROR-TYPE MARKING ═════════════════════════════════════════════════════
   PROBE_ERROR_TYPES.orf (MTSS2RTI.html:42614-42618) and the picker at
   81942-81996: a flex row of numbered buttons under the word, red-bordered,
   with a Clear. Founder: "the error type marking is not being used in the
   administration type" — it was not, and the setting naming it was in step 5
   under a label I had invented ("Detailed"; the product says "Each error
   marked by type"). */
.kwrap{position:relative;display:inline-block}
/* ⛔ display:none, NOT opacity:0 — the second instance of the same defect in one
   session. A type label on an unmarked word is text that does not exist yet;
   hiding it with opacity leaves it in the accessibility tree and reachable by a
   screen reader, which _test-a11y counts and is right to. The tab labels were
   the first instance; this rule is why the lesson is written twice. */
.kw-t{display:none;font-style:normal;font-size:8.5px;font-weight:700;
  margin-left:3px;padding:0 3px;border-radius:2px;vertical-align:super;
  background:#C4442E;color:#fff}
.kw.is-acted .kw-t{display:inline-block}
.etp{position:absolute;left:-14px;top:calc(100% + 3px);z-index:6;display:flex;gap:2px;
  padding:2px;border:1.5px solid #C4442E;border-radius:4px;background:#12201C;
  white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,.45)}
.etp-b{font-family:var(--f-data);font-size:7.5px;padding:2px 5px;border-radius:3px;
  color:var(--star-dim);background:color-mix(in srgb,#fff 8%,transparent)}
.etp-b.on{background:#C4442E;color:#fff;font-weight:700}
.etp-clr{background:transparent;color:var(--star-dim)}
/* the live per-type tally beside the score (80689-80710) */
.orf-tally{display:grid;grid-template-columns:repeat(5,1fr);gap:3px}
.orf-tally span{text-align:center;padding:2px 0;border-radius:3px;font-size:7px;
  color:var(--star-dim);background:color-mix(in srgb,#000 18%,transparent)}
.orf-tally b{display:block;font-family:var(--f-data);font-size:10px;color:var(--star)}

/* ══ THE ACCOMMODATIONS BANNER ══════════════════════════════════════════════
   _kioskAccommodationBannerHtml, 83100-83195, rendered at 79832 above the body.
   ⚠ Its chips are FLAG-derived (IEP / 504 / Autism / Trauma …), NOT the plan
   accommodation labels the wizard just listed — two pipelines the product keeps
   apart, and joining them here would be the same category error as merging a
   district configuration badge with a record provenance marker. */
.acb{display:flex;align-items:center;gap:7px;flex-wrap:wrap;padding:4px 9px;
  margin-bottom:6px;border-radius:4px;
  background:color-mix(in srgb,#D97706 10%,transparent);border-bottom:1px solid #D97706}
.acb b{font-size:9.5px;color:#D97706;font-weight:700}
.acb-c{font-size:8px;padding:1px 7px;border-radius:9px;color:var(--star);
  background:color-mix(in srgb,#D97706 22%,transparent)}
.acb i{font-style:normal;font-size:8px;color:var(--star-dim);margin-left:auto}

/* step 4's affirmative case (75600-75606) */
.ac-item{padding:4px 12px;border-radius:5px;
  background:color-mix(in srgb,#000 16%,transparent);margin-bottom:3px}
.ac-l b{font-size:11px;color:var(--star);font-weight:700}
.ac-l span{font-size:10.5px;color:var(--star-dim);margin-left:4px}
.ac-item .kv-check{margin-top:2px;font-size:9.5px}
.kv-check.on span{background:var(--phosphor);border-color:var(--phosphor);color:#0C1512;
  display:grid;place-items:center;font-size:9px;line-height:1}

/* The dropdown opens OVER the workspace, which is where the bell lives — the
   first version floated a panel on an empty card and read as a component sheet
   rather than a screen. The app behind it is dimmed rather than removed,
   because what the reader needs to see is that the alert arrives while you are
   already looking at the student. */
.ad-host{position:relative;flex:1;min-block-size:0}
/* ⛔ THE SCREEN DIMS WHEN THE PANEL OPENS, NOT BEFORE.
   Founder, 2026-08-17: "the screen starts blurred but nothing is open yet from
   alert." It did — the backdrop was dimmed from the first frame, so the reader
   saw a greyed-out application with no dialogue on it and then a click that
   appeared to do nothing. A backdrop is a consequence of an overlay; it cannot
   precede one. */
/* ⛔ THE SCREEN IS LIVE; ONLY THE REGION BEHIND AN OPEN PANEL DIMS.
   The alert frame had its whole screen wrapped in .ad-behind, so the bell the
   user presses was scenery — the backdrop lint stripped its behaviour, correctly,
   and the pointer then had nowhere legitimate to go. Dimming is a STATE of the
   screen, not a different element. */
.ws-live{position:absolute;inset:0;display:flex;flex-direction:column;
  transition:opacity .28s ease,filter .28s ease}
[data-frame]:has(.ah-bell.is-acted) .ws-live>*:not(.ah){opacity:.3;filter:saturate(.5)}
.ad-behind{position:absolute;inset:0;opacity:1;filter:none;
  transition:opacity .28s ease,filter .28s ease;
  pointer-events:none;overflow:hidden;display:flex;flex-direction:column}
[data-frame]:has(.ah-bell.is-acted) .ad-behind{opacity:.28;filter:saturate(.55)}
[data-frame]:has(.pk) .ad-behind{opacity:.28;filter:saturate(.55)}
.ad-host>.ad-stage{position:relative;z-index:2}
.ad-label{text-align:left}
.ad-item{text-align:left}

/* ⛔ THE REFUSAL IS A STATE OF STEP 1, NOT A SCENE OF ITS OWN.
   It shipped as a separate frame first and the founder read the sequence as
   "duplicate administrations" — correctly, because two frames both said
   "Step 1 of 5". A pre-start check is something that happens TO a step. So the
   frame opens with the refusal showing, and the choice clears it, which is also
   the true order of events: the examiner pressed Continue and was stopped.
   :has() rather than a sibling combinator because the block precedes the
   options; where :has() is unsupported the refusal simply stays visible, which
   is the honest degradation. */
.kv-drawbody:has(.kv-opt.is-acted) .kv-block{display:none}
.kv-block{transition:opacity .2s}

/* ── the "Probe Kiosk" modal, the screen between the icon and the wizard ─────
   _openUnifiedProbeKiosk (MTSS2RTI.html:73991) opens the pmModal overlay as its
   own surface; for a baselined student the canRunPM branch (74096) renders the
   active measure, "Baseline locked", and a button labelled exactly `Run`. The
   practice checkbox beside it is read by _kioskRunOrPractice (74144).
   ⚠ The label is `Run`, not "Run probe" — "Run probe" is the SPED IEP-goal
   variant at 74088 and belongs to a different track. */
.pk-stage{position:absolute;inset:0;display:grid;place-items:center;z-index:2}
.pk{inline-size:min(420px,86%);border:1px solid var(--pc-hair);border-radius:8px;
  background:var(--pc-bg);box-shadow:0 14px 34px rgba(0,0,0,.5);overflow:hidden;text-align:left}
.pk-hd{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;
  border-bottom:1px solid var(--pc-hair);background:color-mix(in srgb,#000 16%,transparent)}
.pk-hd b{font-size:12px;color:var(--star)}
.pk-hd span{color:var(--star-dim);font-size:13px}
.pk-body{padding:9px 12px 11px;display:flex;flex-direction:column;gap:7px}
.pk-sec{margin:0;font-family:var(--f-data);font-size:8px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--star-dim)}
.pk-row{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:5px;
  border:1px solid var(--pc-hair);background:color-mix(in srgb,#000 14%,transparent)}
.pk-row>div{flex:1;min-inline-size:0}
.pk-row b{display:block;font-size:11px;color:var(--star)}
.pk-row i{display:block;font-style:normal;font-size:9.5px;color:var(--star-dim);margin-top:1px}
.pk-run{flex:none;padding:4px 14px;border-radius:5px;font-size:10.5px;font-weight:700;
  background:var(--phosphor);color:#0C1512}
.pk-run.is-acted{filter:brightness(1.14)}

/* ══ THE GLOBAL APP HEADER ══════════════════════════════════════════════════
   MTSS2RTI.html:3222-3296. Founder audit: "universal header missing making
   alert bell location and related header icons missing". Every frame was
   drawing the TAB NAV as though it were the top of the application, so the
   alerts dropdown had no bell to hang from and read as a floating component
   sheet. The bell lives here, above the nav, and that is why the panel is
   anchored right.
   ⛔ #hdrImpersonationBadge and #backupAlertBtn are display:none by default and
   are deliberately not drawn — reproducing hidden chrome is its own invention. */
.ah{display:flex;align-items:center;gap:8px;padding:0 2px 4px;
  border-bottom:1px solid var(--pc-hair);margin-bottom:4px}
.ah-logo{width:15px;height:15px;border-radius:3px;flex:none;
  background:linear-gradient(135deg,#5EEAD4,var(--phosphor))}
.ah-title{font-size:11.5px;font-weight:700;color:var(--star);letter-spacing:.01em}
.ah-title b{color:#5EEAD4;font-weight:700}
.ah-r{margin-inline-start:auto;display:flex;align-items:center;gap:7px}
.ah-year{font-family:var(--f-data);font-size:8.5px;padding:1px 7px;border-radius:999px;
  border:1px solid var(--pc-hair);color:var(--star-dim)}
.ah-save{font-size:10px;color:var(--star-dim)}
.ah-bell{position:relative;width:20px;height:20px;display:grid;place-items:center;
  border-radius:5px;color:var(--star-dim)}
.ah-bell svg{width:13px;height:13px;fill:currentColor}
.ah-bell.is-acted{background:color-mix(in srgb,var(--phosphor) 20%,transparent);color:var(--star)}
.ah-badge{position:absolute;top:-3px;right:-3px;min-width:11px;height:11px;border-radius:6px;
  font-style:normal;font-size:7px;font-weight:800;color:#fff;background:#F87171;
  display:grid;place-items:center;padding:0 2px;line-height:1}
.ah-menu{width:18px;height:18px;display:grid;place-items:center;color:var(--star-dim)}
.ah-menu svg{width:12px;height:12px;fill:currentColor}

/* ⛔ THE PANEL WAITS FOR THE BELL. Founder: "show alert bell clicked to open
   alerts before click." A dropdown that is simply present was never opened by
   anyone; the gesture is the point. */
/* ⛔ display, NOT opacity — THE THIRD INSTANCE OF THIS IN ONE SESSION.
   `opacity:0` left the whole Action Center panel — its title, its filter chips,
   three alert rows — in the accessibility tree while invisible on screen, and
   _test-a11y counts exactly that. It also stalled the sequence: the row the
   cursor has to press had no reachable box.
   The tab labels were the first instance, the error-type labels the second.
   Same rule each time: text that does not exist yet must not be RENDERED yet. */
[data-frame] .ad-stage{display:none}
[data-frame]:has(.ah-bell.is-acted) .ad-stage{display:flex}

/* ══ THE REAL SCREEN BEHIND THE DRAWER ══════════════════════════════════════
   Founder: "fabricated surface behind setup". It was — an invented grey
   placeholder standing in for the application. The drawer opens over the
   Monitor tab, so the Monitor tab is what is behind it. */
.kv-behind{position:absolute;inset:0;overflow:hidden;opacity:.26;filter:saturate(.5);
  pointer-events:none;display:flex;flex-direction:column}

/* ══ THE MONITOR STACK — one column, goal on top ════════════════════════════
   Founder: "should be banner strip across top of chart, not side panel, refer
   to code." The product says it in its own comment (MTSS2RTI.html:4269-4272):
   goal = full row across the top · chart = full width and 50% shorter ·
   four-point rule = a full-width row BELOW the chart. No `order` involved —
   plain source order in one flex column. The two-column rail was mine. */
.ws-stack{display:flex;flex-direction:column;gap:6px;flex:1;min-block-size:0;text-align:left}
.ws-grow{display:flex;align-items:baseline;gap:4px 12px;flex-wrap:wrap;margin-top:2px}
.ws-grow span{font-size:10px;color:var(--star-dim)}
.ws-grow b{color:var(--star)}
/* ⛔ the section heading is NOT reproduced: .section-title and .section-sub are
   display:none on a panel's direct-child title row (CSS 263-264), so "Monitor /
   Track weekly probes…" is never on screen. The row keeps its icons and nothing
   else, which is what a user sees. Founder's one-word verdict: "fabricated". */
.ws-bar{display:flex;justify-content:flex-end;margin:3px 0 4px}
/* the axes the product draws and this page did not */
.c-grid{stroke:var(--pc-hair);stroke-width:.6}
.c-tick{fill:var(--star-dim);font-family:var(--f-data);font-size:6.5px}
.c-ax{fill:var(--star-dim);font-size:7px;font-weight:600}
.c-above{fill:#34D399}
.c-below{fill:#F87171}
.c-new{stroke:var(--pc-bg);stroke-width:1.2}

/* the not-responding verdict and its actions (MTSS2RTI.html:93579-93590) */
.ws-verdict-change{background:color-mix(in srgb,#F87171 12%,transparent);
  border-left-color:#F87171}
.ws-verdict-change b{color:#F87171}
.fp-btns{display:flex;gap:4px;flex-wrap:wrap;margin-top:4px}
.fp-btn{font-size:8.5px;padding:2px 8px;border-radius:4px;color:var(--star);
  border:1px solid var(--pc-hair);background:color-mix(in srgb,#000 18%,transparent)}

/* ⚠ preserveAspectRatio:none with a viewBox cut to the container's real shape.
   The chart was authored 330x92 and rendered in a box nearer 8:1, so it
   letterboxed into the right half with a third of the card empty — visible in
   the founder's capture as a chart floating away from its own axis labels. */
.ws-ch{width:100%;height:100%;flex:1;min-block-size:44px;display:block}
/* the verdict's action buttons are a ROW, not a stack. As flex children of a
   column they were stretching to full width and reading as four menu items. */
.fp-btns{display:flex;gap:4px;flex-wrap:wrap;margin-top:4px;align-items:flex-start}
.fp-btn{flex:none;white-space:nowrap}
.ws-verdict{display:flex;flex-direction:column;align-items:flex-start}

/* the pointer does not exist until it has somewhere to be (see seq-act.js) */
.seq-cursor.is-parked{opacity:0}
.seq-cursor{opacity:1;transition:transform 700ms cubic-bezier(.4,.1,.2,1),opacity 240ms ease}
/* the zoom layer. transform-origin and the transform itself are set in JS from
   the focus region's measured rect; this only supplies the paint hint. */
.plate-fit[data-frames].is-seq-on .pcard-body{will-change:transform}

/* ══ A CONTROL REACTS TO BEING PRESSED ══════════════════════════════════════
   Founder, 2026-08-17: "hovering over continues doesnt highlight the button and
   clicking doesnt depress it like a button would typically do."
   Only the cursor carried state, so the pointer landed on inert controls and
   read as a drawing floating over a picture. Arrival highlights, the press
   depresses, and both come off before the acted state lands. Applied by
   structural role — anything the choreography can target — so a control added
   later inherits it rather than needing to be remembered. */
[data-act-step]{transition:filter .12s ease,transform .09s ease,box-shadow .12s ease,
  background-color .14s ease,border-color .14s ease}
[data-act-step].is-hovering{filter:brightness(1.13)}
.kv-cta.is-hovering,.pk-run.is-hovering,.orf-start.is-hovering{
  box-shadow:0 0 0 3px color-mix(in srgb,var(--phosphor) 26%,transparent)}
.kv-opt.is-hovering,.ad-row.is-hovering,.ws-ic.is-hovering,.ah-bell.is-hovering,
.kv-chips span.is-hovering,.kv-rev span.is-hovering,.ws-verdict.is-hovering{
  background:color-mix(in srgb,var(--star) 10%,transparent)}
[data-act-step].is-pressing{transform:translateY(1px) scale(.985);filter:brightness(.92)}
.kv-cta.is-pressing,.pk-run.is-pressing,.orf-start.is-pressing{
  box-shadow:inset 0 2px 5px rgba(0,0,0,.35),0 0 0 3px color-mix(in srgb,var(--phosphor) 20%,transparent)}
/* the word being marked gets the same treatment on the reading ground */
.kw.is-hovering{background:color-mix(in srgb,#C4442E 18%,transparent);border-radius:2px}
.kw.is-pressing{background:#C4442E;color:#fff}

/* ── step 3: three forms and the passage preview ─────────────────────────── */
.kv-forms{display:flex;gap:6px}
.kv-form{flex:1;text-align:center;padding:6px 0;border-radius:5px;font-weight:700;
  font-size:12px;color:var(--star-dim);border:1px solid var(--pc-hair)}
.kv-form.on{background:color-mix(in srgb,var(--phosphor) 22%,transparent);
  border-color:var(--phosphor);color:var(--star)}
.kv-sample{font-family:var(--f-data);font-size:10px;line-height:1.7;padding:8px 10px;
  border:1px solid var(--pc-hair);border-radius:5px;color:var(--star-dim);
  background:color-mix(in srgb,#000 16%,transparent);max-block-size:96px;overflow:hidden}

/* ── step 4: an opt-out, not a menu ──────────────────────────────────────────
   Founder: "accommodations auto generated, not optional, why do these have
   checks verify the code surface." The checkbox is real, but it is the ONLY
   interaction and it records an omission that cannot pass without a written
   reason. Read as a plain checkbox it looks like a choice; the required marker
   and the muted, warning-coloured opt-out say what it actually is. */
.ac-req{display:inline-block;font-style:normal;font-size:8px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;margin-left:6px;padding:1px 6px;
  border-radius:999px;background:color-mix(in srgb,var(--phosphor) 20%,transparent);
  color:var(--star)}
.ac-omit{color:#D9A05B;opacity:.9}
.ac-omit span{border-color:#D9A05B}

/* ── the bell carries the alert's colour ─────────────────────────────────────
   Founder: "the alert bell not having the correct color of amber when it has an
   active alert." The product tints the count pill red when anything is overdue
   and amber otherwise (_renderAlertsDropdown 289882); the bell itself should
   read as active rather than as ordinary chrome. */
.ah-bell{color:#D9A05B}
.ah-bell .ah-badge{background:#D9A05B;color:#16211E}
