/* appshell.css — 1:1 port of the App_Shell handoff token contract + global shell
 * primitives (App_Shell/handoff/src/Lysia App.dc.html <style>). This file is the
 * foundation for the full shell port: it scopes everything under #lysia-root so
 * it cannot leak into the current (pre-port) markup, and stays inert until PR1
 * introduces the #lysia-root frame. Verbatim from the handoff — do not redesign;
 * tokens are the single source of truth for the ported surfaces.
 *
 * Faces: Newsreader / Inter / JetBrains Mono (loaded in index.html <head>).
 * Terracotta (--accent) stays semantic: readiness + danger only.
 */

/* ===== Lysia — token contract. Light default paints instantly; dark overrides. =====
 * The token blocks ALSO match :root[data-mode] so they resolve from the
 * authoritative data-mode on <html> (set pre-paint by theme-init.js) — the whole
 * /app reskins to this handoff palette. :root[data-mode] has higher specificity
 * (0,2,0) than themes.css's [data-mode] (0,1,0) and appshell.css is linked last,
 * so the handoff tokens win deterministically. #lysia-root stays in the list so
 * the mirrored copy on the wrapper resolves too. Everything BELOW the token
 * blocks stays scoped to #lysia-root and cannot leak into pre-port markup. */
:root[data-mode="light"], #lysia-root, #lysia-root[data-mode="light"]{
  --bg:#faf9f5; --bg-deep:#f3f0e7; --surface:#fffdf8; --surface-raised:#fffefb;
  --ink:#222f37; --ink-muted:#4a5a61; --ink-subtle:#7c8884;
  --border:#e7dfd0; --border-strong:#d4cab6;
  --slate:#7d9aa0; --slate-2:#8fa9ae; --em:#3c545a;
  --accent:#a8623a; --accent-soft:rgba(168,98,58,.10);
  --trunk:#e7d8c4; --grove-bg-op:.5; --bg-grove-op:.2; --ready-green:#4f8a64; --lamp:transparent;
  --ease:cubic-bezier(.16,1,.3,1); --ease-spring:cubic-bezier(.32,.72,0,1);
  --dur-1:.55s; --dur-2:.8s; --dur-3:1.1s;
  --shadow-1:0 1px 2px rgba(60,42,28,.08);
  --shadow-2:0 1px 2px rgba(60,42,28,.05), 0 10px 30px rgba(60,42,28,.08);
  --shadow-3:0 2px 8px rgba(50,38,26,.07), 0 26px 64px rgba(50,38,26,.13);
  /* Shared terracotta (was loader-local in loader.css) — drives the generate
     loader's step marks/bar. --ed-paper is the exam-editor live-recompile pane. */
  --bl-terra:#c0664a; --ed-paper:#fbf8ef;
  color-scheme:light;
}
:root[data-mode="dark"], :root[data-mode="dark"] #lysia-root, #lysia-root[data-mode="dark"]{
  --bg:#1a1e1c; --bg-deep:#151816; --surface:#232825; --surface-raised:#2b302c;
  --ink:#ece3d3; --ink-muted:#b4b3a4; --ink-subtle:#868a7d;
  --border:#343a33; --border-strong:#4c5249;
  --slate:#9fb7ba; --slate-2:#aec4c6; --em:#c3d4d2;
  --accent:#c87d52; --accent-soft:rgba(200,125,82,.16);
  --trunk:#d9c7ac; --grove-bg-op:.34; --bg-grove-op:.12; --ready-green:#79b389;
  --lamp:radial-gradient(120% 90% at 50% -8%, rgba(210,150,86,.16), transparent 58%);
  --shadow-1:0 1px 2px rgba(0,0,0,.5);
  --shadow-2:0 1px 2px rgba(0,0,0,.5), 0 12px 32px rgba(0,0,0,.55);
  --shadow-3:0 2px 10px rgba(0,0,0,.55), 0 30px 70px rgba(0,0,0,.66);
  --bl-terra:#d2785c; --ed-paper:#20251f;
  color-scheme:dark;
}
#lysia-root *{ box-sizing:border-box; }
#lysia-root{ position:relative; isolation:isolate; min-height:100vh; background:var(--bg); color:var(--ink);
  font-family:'Inter',system-ui,sans-serif; -webkit-font-smoothing:antialiased;
  overflow-x:hidden; transition:background .5s var(--ease), color .5s var(--ease); }
#lysia-root a{ color:inherit; text-decoration:none; }
#lysia-root ::selection{ background:var(--accent-soft); color:var(--ink); }
/* paper fiber grain — fixed, inert */
#lysia-root::after{ content:""; position:fixed; inset:0; pointer-events:none; z-index:80; opacity:.04;
  background-image:radial-gradient(currentColor .6px,transparent .6px),radial-gradient(currentColor .5px,transparent .5px);
  background-size:7px 7px,11px 11px; background-position:0 0,3px 5px; color:var(--ink); }
@keyframes lyRise{ from{opacity:0; transform:translateY(20px)} to{opacity:1; transform:none} }
@keyframes lyRiseSm{ from{opacity:0; transform:translateY(11px)} to{opacity:1; transform:none} }
@keyframes lyDraw{ from{transform:scaleX(0); opacity:0} to{transform:scaleX(1); opacity:.5} }
@keyframes lyBloom{ from{opacity:0; filter:blur(9px)} to{opacity:1; filter:blur(0)} }
@keyframes lyBreathe{ 0%,100%{transform:translateY(0) rotate(0deg)} 50%{transform:translateY(-7px) rotate(.5deg)} }
@keyframes lyBreatheB{ 0%,100%{transform:translateY(0) rotate(0deg)} 50%{transform:translateY(-11px) rotate(-.45deg)} }
.scrub-range{ -webkit-appearance:none; appearance:none; width:100%; height:24px; margin:0;
  background:linear-gradient(90deg,var(--slate),var(--accent)) center/100% 2px no-repeat; border-radius:2px; cursor:ew-resize; touch-action:none; }
.scrub-range::-webkit-slider-thumb{ -webkit-appearance:none; appearance:none; width:18px; height:18px; border-radius:50%;
  background:var(--surface-raised); border:2px solid var(--accent); box-shadow:var(--shadow-1); cursor:ew-resize; }
.scrub-range::-moz-range-thumb{ width:18px; height:18px; border-radius:50%; background:var(--surface-raised); border:2px solid var(--accent); cursor:ew-resize; }
.scrub-range:focus-visible{ outline:2px solid var(--accent); outline-offset:4px; }
#lysia-root :focus-visible{ outline:2px solid var(--accent); outline-offset:3px; }
@media (prefers-reduced-motion: reduce){
  #lysia-root *, #lysia-root *::before, #lysia-root *::after{
    animation-duration:.001ms!important; animation-iteration-count:1!important; transition-duration:.001ms!important; }
}

/* ===========================================================================
 * App_Shell PR1 — shell frame layout (sidebar + sticky top bar).
 * Ported 1:1 from the handoff <aside> + sticky top bar, but expressed against
 * the existing class hooks (.sidebar / .nav-item / .topstrip …) so the markup
 * stays as-is and the routing/ARIA wiring is untouched. Scoped under #lysia-root
 * and linked last → these win over style.css on conflict. Surface internals
 * (everything inside .main) are NOT touched here — that's later PRs.
 * ======================================================================== */

/* Skip link — off-screen until focused (CSS only; strict script-src forbids the
 * handoff's inline onfocus/onblur). */
#lysia-root .skip-link{
  /* z-index above the sticky sidebar/topstrip (--z-sticky:1100), below modals,
     so a focused skip link is never painted under the rail (WCAG 2.4.7). */
  position:absolute; left:-9999px; top:0; z-index:var(--z-backdrop);
  background:var(--ink); color:var(--bg); padding:10px 16px; border-radius:6px;
  font:600 13px 'Inter',sans-serif;
}
#lysia-root .skip-link:focus{ left:12px; top:12px; }

/* ----- Sidebar (frosted left rail, handoff aside) ----- */
#lysia-root .sidebar{
  gap:6px; padding:22px 16px;
  background:color-mix(in oklch, var(--surface) 70%, transparent);
  -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
  border-right:1px solid var(--border); box-shadow:none;
}
/* desktop geometry only — leave style.css's <=720px stacking rules in charge */
@media (min-width: 721px){
  #lysia-root .sidebar{ width:clamp(220px,20vw,264px); }
  /* Change-log #14: the rail extends to fit every course instead of clipping the
     course list into a tiny internal scroll. height:auto + align-self:stretch
     (from style.css) lets the sticky rail grow with the page; the course list
     flows in full rather than scrolling within .sb-courses. */
  #lysia-root .sidebar{ height:auto; min-height:100vh; }
  #lysia-root .sb-courses{ overflow-y:visible; }
}

/* Change-log #13: "Import Materials" in the relabel hint is a real navigation
   control. Rendered as a <button> (keyboard-focusable, activates on Enter/Space
   via the delegated [data-goto] handler) but styled as inline link text. */
#lysia-root .mat-relabel-link{
  background:none; border:0; padding:0; margin:0;
  font:inherit; color:var(--accent); cursor:pointer;
  text-decoration:underline; text-underline-offset:2px;
}
#lysia-root .mat-relabel-link:hover{ text-decoration-thickness:2px; }

/* brand row: sapling mark + Newsreader wordmark (handoff) */
#lysia-root .sb-brand{ gap:11px; padding:4px 8px 16px; margin-bottom:0; border-bottom:0; align-items:flex-end; }
#lysia-root .brand-name{ font:500 21px 'Newsreader',Georgia,serif; color:var(--ink); letter-spacing:normal; }

/* nav items — pill rows, muted until active. Refined 2026-07-02: resting rows
   are quiet (small neutral dots), the active row earns the terracotta dot +
   a hairline-inset tinted pill — hierarchy from restraint, not seven bullets. */
#lysia-root .sb-nav{ gap:2px; }
#lysia-root .nav-item{
  gap:11px; padding:9px 12px; border-radius:9px;
  font:500 13.5px 'Inter',sans-serif; color:var(--ink-muted);
  position:relative;
}
#lysia-root .nav-item .nav-dot{
  width:5px; height:5px; flex:none; border-radius:50%;
  background:var(--border-strong);
  transition:background var(--dur-fast,.15s) ease, transform var(--dur-fast,.15s) ease, box-shadow var(--dur-fast,.15s) ease;
}
#lysia-root .nav-item:hover{ background:color-mix(in oklch, var(--ink) 5%, transparent); color:var(--ink); }
#lysia-root .nav-item:hover .nav-dot{ background:var(--slate); }
#lysia-root .nav-item[aria-selected="true"]{
  background:var(--accent-soft); color:var(--ink); font-weight:600; box-shadow:inset 0 0 0 1px color-mix(in oklch, var(--accent) 22%, transparent);
}
#lysia-root .nav-item[aria-selected="true"] .nav-dot{
  background:var(--accent); transform:scale(1.25);
  box-shadow:0 0 0 3px var(--accent-soft);
}
#lysia-root .nav-dot{ width:5px; height:5px; }
#lysia-root .nav-dot-empty{ background:var(--border-strong); }

/* sidebar group labels — mono dividers above the gated Teaching / Institution
   tab groups. Hidden by default; CSS :has() reveals each label the moment its
   group's first tab un-gates (inst_teacher.js / inst_admin.js remove the
   *-gated class), so label + tabs appear together with no JS changes. */
#lysia-root .sb-group-label{
  display:none; pointer-events:none; cursor:default;
  margin:14px 4px 2px; padding:6px 8px 4px; border-top:1px solid var(--border);
  font:600 9px 'JetBrains Mono',monospace; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-subtle); background:none;
}
#lysia-root .sb-nav:has(.tab[data-surface="teach"]:not(.teacher-gated)) .sb-group-label--teach{ display:block; }
#lysia-root .sb-nav:has(.tab[data-surface="inst-overview"]:not(.admin-gated)) .sb-group-label--inst{ display:block; }

/* "Your courses" group + account row (handoff footer block) */
#lysia-root .sb-courses-group{ border-top:1px solid var(--border); padding-top:14px; }
#lysia-root .sb-courses-label{
  font:600 9px 'JetBrains Mono',monospace; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-subtle); margin-bottom:6px;
}
#lysia-root .sb-account{ border-top:1px solid var(--border); padding:14px 6px 2px; }
#lysia-root .sb-email{ font:500 11px 'JetBrains Mono',monospace; color:var(--ink-subtle); }

/* ----- Sticky top bar (handoff: crumb · countdown · Feedback · "?") -----
 * Frosted bar; horizontal padding kept at the existing 30px so it stays aligned
 * with the not-yet-ported .main gutter (the handoff's 0.5in lands in a later PR
 * alongside the ported surfaces). */
#lysia-root .topstrip{
  gap:16px; padding:14px 30px;
  background:color-mix(in oklch, var(--surface) 72%, transparent);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  border-bottom:1px solid var(--border);
}
#lysia-root .topstrip .crumb{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-subtle);
  /* one-line crumb: a long course slug must never wrap the sticky bar to two rows */
  flex:0 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
#lysia-root .topstrip .days-to-final{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.12em; text-transform:uppercase;
  color:var(--accent); white-space:nowrap;
}
/* Feedback pill + "?" circle */
#lysia-root .topstrip-btn{
  flex:none; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-muted); background:none; border:1px solid var(--border-strong);
  border-radius:999px; padding:7px 13px; cursor:pointer; transition:.25s var(--ease);
}
#lysia-root .topstrip-btn:hover{ background:var(--accent-soft); color:var(--ink); border-color:var(--accent); }
#lysia-root .topstrip-help{
  flex:none; width:30px; height:30px; display:inline-flex; align-items:center; justify-content:center;
  border-radius:999px; border:1px solid var(--border-strong); background:transparent;
  color:var(--ink-muted); font:600 14px 'Newsreader',Georgia,serif; cursor:pointer; transition:.25s var(--ease);
}
#lysia-root .topstrip-help:hover{ background:var(--accent-soft); color:var(--ink); border-color:var(--accent); }

/* ----- Overview (checkin) ----- */
/* The stat row carries an inline display:flex, which would otherwise beat the
   [hidden] UA rule and leave the "—" cards showing next to the empty state for
   new accounts. !important restores hidden semantics (checkin.js toggles it). */
#lysia-root #checkin-stats[hidden]{ display:none !important; }

/* ===========================================================================
 * App_Shell PR2b — Courses (Exam Generation) surface.
 * The course-cards header + grid, ported 1:1 from the handoff (Lysia App.dc.html
 * data-surface-panel="courses", lines 137–186) onto the EXISTING readiness card
 * machinery (readiness.js #readiness-list .rd-card). The per-course detail
 * (#courses-detail + #exam-list) is untouched here — exam-list → Practice Exams
 * is PR2e. Scoped under #lysia-root #surface-courses; linked last → wins.
 * ======================================================================== */

/* editorial header — mono eyebrow, Newsreader title, pill actions */
#lysia-root #surface-courses .readiness-head .dv{
  font:600 11px 'JetBrains Mono',monospace; letter-spacing:.24em; text-transform:uppercase; color:var(--slate);
}
#lysia-root #surface-courses .readiness-h1{
  font:500 clamp(2rem,1.4rem+2.5vw,3.2rem)/1.04 'Newsreader',Georgia,serif;
  letter-spacing:-.02em; color:var(--ink); margin-top:6px;
}
#lysia-root #surface-courses #course-add-btn{
  font:600 13px 'Inter',sans-serif; color:var(--ink); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:10px 18px; cursor:pointer;
  transition:.3s var(--ease);
}
#lysia-root #surface-courses #course-add-btn:hover{ border-color:var(--ink); background:none; }
#lysia-root #surface-courses #readiness-generate-btn{
  display:inline-flex; align-items:center; gap:10px;
  font:600 14px 'Inter',sans-serif; color:var(--bg); background:var(--ink);
  border:none; border-radius:999px; padding:11px 20px; cursor:pointer;
  box-shadow:var(--shadow-2);
  transition:transform .4s var(--ease-spring), box-shadow .4s var(--ease);
}
#lysia-root #surface-courses #readiness-generate-btn:hover{
  transform:translateY(-2px); box-shadow:var(--shadow-3); background:var(--ink);
}

/* course cards — surface bg, soft border, rounded, hover lift (handoff) */
#lysia-root #surface-courses .rd-card{
  background:var(--surface); border:1px solid var(--border); border-radius:18px;
  box-shadow:var(--shadow-1); padding:22px 24px;
  transition:transform .35s var(--ease), box-shadow .35s var(--ease), border-color .25s var(--ease);
}
#lysia-root #surface-courses .rd-card:hover{ transform:translateY(-2px); box-shadow:var(--shadow-2); }
#lysia-root #surface-courses .rd-card[data-active="true"]{
  border-color:var(--accent); box-shadow:0 0 0 1px var(--accent), var(--shadow-2);
}
#lysia-root #surface-courses .rd-code{ font:500 1.4rem 'Newsreader',Georgia,serif; color:var(--ink); }
#lysia-root #surface-courses .rd-card-id:hover .rd-code{ color:var(--accent); }
#lysia-root #surface-courses .rd-bigpct{ font:500 2.4rem/1 'Newsreader',Georgia,serif; letter-spacing:normal; }

/* card footer action row — View materials (ghost) + Generate exam (solid) */
#lysia-root #surface-courses .rd-card-actions{
  margin-top:6px; padding-top:16px; border-top:1px solid var(--border);
  display:flex; gap:10px; flex-wrap:wrap; align-items:center;
}
#lysia-root #surface-courses .rd-act{
  font:600 12.5px 'Inter',sans-serif; border-radius:999px; padding:9px 16px; cursor:pointer;
  transition:transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
#lysia-root #surface-courses .rd-act-ghost{ color:var(--ink); background:none; border:1px solid var(--border-strong); }
#lysia-root #surface-courses .rd-act-ghost:hover{ border-color:var(--ink); }
#lysia-root #surface-courses .rd-act-solid{
  display:inline-flex; align-items:center; gap:8px; color:var(--bg); background:var(--ink);
  border:none; box-shadow:var(--shadow-1);
}
#lysia-root #surface-courses .rd-act-solid:hover{ transform:translateY(-1px); box-shadow:var(--shadow-2); }
/* the quiet Delete control trails the row, right-aligned. Refined 2026-07-02:
   text-only until hover — a rust-tinted pill on every resting card made delete
   compete with Generate. Hover restores the rust warning tint. */
#lysia-root #surface-courses .rd-card-actions .rd-card-del{
  margin-left:auto; align-self:center;
  background:none; border:1px solid transparent; border-radius:999px;
  padding:7px 10px; font:500 11.5px 'Inter',sans-serif; letter-spacing:0;
  color:var(--ink-subtle); opacity:1;
}
#lysia-root #surface-courses .rd-card-actions .rd-card-del:hover{
  color:var(--accent); background:var(--accent-soft);
  border-color:color-mix(in oklch, var(--accent) 35%, transparent);
}

/* empty state — no courses yet */
#lysia-root #surface-courses .rd-empty{
  border:1px dashed var(--border-strong); border-radius:18px; padding:40px 28px; text-align:center;
  color:var(--ink-muted); font:400 15px/1.55 'Inter',sans-serif; background:var(--surface);
}
#lysia-root #surface-courses .rd-empty b{
  display:block; margin-bottom:6px; color:var(--ink); font:500 1.2rem 'Newsreader',Georgia,serif;
}

/* ===========================================================================
 * App_Shell PR2c — Generate (generate) sub-surface.
 * The configure→draft screen, ported 1:1 from the handoff
 * (data-surface-panel="generate", Lysia App.dc.html ~186–247): back link → three
 * segmented config steps (01 Course · 02 Focus · 03 Format) → live summary card
 * + credit line → Generate button. No length/difficulty inputs — by design.
 * generate.js fills 01/02 from real data; the Generate button reuses the
 * existing pipeline. Scoped under #lysia-root #surface-generate; linked last.
 * ======================================================================== */
#lysia-root #surface-generate{ max-width:1000px; }

/* editorial header — mono back link, Newsreader title, muted subhead */
#lysia-root #surface-generate .gen-head{ margin-bottom:0.2in; }
#lysia-root #surface-generate .gen-back{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-subtle); background:none; border:none; cursor:pointer; padding:0;
  transition:.25s var(--ease);
}
#lysia-root #surface-generate .gen-back:hover{ color:var(--ink); }
#lysia-root #surface-generate .gen-h1{
  margin:12px 0 0; font:500 clamp(2rem,1.4rem+2.5vw,3.2rem)/1.04 'Newsreader',Georgia,serif;
  letter-spacing:-.02em; color:var(--ink);
}
#lysia-root #surface-generate .gen-sub{
  margin:11px 0 0; max-width:54ch; font:400 15px/1.55 'Inter',sans-serif; color:var(--ink-muted);
}

/* D30=A offgate panel — shown when a student's instructor turned off self-gen. */
#lysia-root #surface-generate .gen-offgate{
  margin:22px 0 0; padding:24px 26px; border:1px solid var(--border);
  border-radius:14px; background:var(--accent-soft);
}
#lysia-root #surface-generate .gen-offgate-h{
  margin:0; font:500 1.35rem 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-generate .gen-offgate-sub{
  margin:8px 0 0; max-width:48ch; font:400 14px/1.55 'Inter',sans-serif; color:var(--ink-muted);
}

/* two-column body: steps · sticky summary card */
#lysia-root #surface-generate .gen-grid{
  display:grid; grid-template-columns:minmax(0,1fr) clamp(260px,30%,348px);
  gap:34px; align-items:start;
}

/* each config step: label column · control column, divided by a top rule */
#lysia-root #surface-generate .gen-step{
  border-top:1px solid var(--border); padding:22px 0;
  display:grid; grid-template-columns:minmax(120px,168px) 1fr; gap:24px; align-items:start;
}
#lysia-root #surface-generate .gen-step-num{
  display:block; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase;
  color:var(--slate);
}
#lysia-root #surface-generate .gen-step-hint{
  display:block; margin-top:7px; font:400 12.5px/1.45 'Inter',sans-serif; color:var(--ink-subtle);
}
#lysia-root #surface-generate .gen-seg,
#lysia-root #surface-generate .gen-topics{ display:flex; flex-wrap:wrap; gap:8px; }

/* segmented pills (course / format / topic) — muted until active (accent) */
#lysia-root #surface-generate .gen-chip{
  font:600 12.5px 'Inter',sans-serif; color:var(--ink-muted); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:9px 16px; cursor:pointer;
  transition:background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
#lysia-root #surface-generate .gen-chip-sm{ font-weight:500; font-size:12px; padding:8px 14px; }
#lysia-root #surface-generate .gen-chip:hover{ border-color:var(--ink); color:var(--ink); }
#lysia-root #surface-generate .gen-chip.is-active{
  background:var(--accent-soft); color:var(--ink); border-color:var(--accent);
}
/* topic preview pills are reference-only — no pointer affordance, no hover shift */
#lysia-root #surface-generate .gen-chip-static{ cursor:default; }
#lysia-root #surface-generate .gen-chip-static:hover{ border-color:var(--border-strong); color:var(--ink-muted); }
#lysia-root #surface-generate .gen-empty{
  margin:0; font:400 13px/1.5 'Inter',sans-serif; color:var(--ink-subtle);
}

/* sticky summary card — mirrors the selections + per-cycle credit line */
#lysia-root #surface-generate .gen-aside{
  position:sticky; top:88px; padding:7px; border-radius:20px;
  background:color-mix(in oklch, var(--ink) 4%, var(--bg));
  border:1px solid var(--border); box-shadow:var(--shadow-1);
}
#lysia-root #surface-generate .gen-card{
  background:var(--surface); border:1px solid var(--border); border-radius:15px; padding:22px;
}
#lysia-root #surface-generate .gen-card-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase; color:var(--slate);
}
#lysia-root #surface-generate .gen-card-course{
  margin-top:10px; font:500 1.3rem/1.15 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-generate .gen-card-rule{ margin:16px 0; height:1px; background:var(--border); }
#lysia-root #surface-generate .gen-card-dl{ margin:0; display:flex; flex-direction:column; gap:11px; }
#lysia-root #surface-generate .gen-card-row{
  display:flex; justify-content:space-between; align-items:baseline; gap:12px;
}
#lysia-root #surface-generate .gen-card-row dt{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-subtle);
}
#lysia-root #surface-generate .gen-card-row dd{
  margin:0; text-align:right; font:500 13px 'Inter',sans-serif; color:var(--ink);
}
#lysia-root #surface-generate .gen-source{
  display:flex; align-items:center; gap:8px; font:500 12px 'Inter',sans-serif; color:var(--ink-muted);
}
#lysia-root #surface-generate .gen-source-dot{
  flex:none; width:6px; height:6px; border-radius:99px; background:var(--ready-green);
}
#lysia-root #surface-generate .gen-go{
  margin-top:18px; width:100%; display:inline-flex; align-items:center; justify-content:center; gap:10px;
  font:600 14px 'Inter',sans-serif; color:var(--bg); background:var(--ink);
  border:none; border-radius:999px; padding:13px 20px; cursor:pointer; box-shadow:var(--shadow-2);
  transition:transform .4s var(--ease-spring), box-shadow .4s var(--ease);
}
#lysia-root #surface-generate .gen-go:hover{ transform:translateY(-2px); box-shadow:var(--shadow-3); }
#lysia-root #surface-generate .gen-cost{
  margin-top:11px; text-align:center; min-height:13px;
  font:500 10px 'JetBrains Mono',monospace; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-subtle);
}

/* stack on narrow viewports: single column, label above control, card unsticks */
@media (max-width: 720px){
  #lysia-root #surface-generate .gen-grid{ grid-template-columns:1fr; gap:20px; }
  #lysia-root #surface-generate .gen-step{ grid-template-columns:1fr; gap:12px; }
  #lysia-root #surface-generate .gen-aside{ position:static; }
}

/* ========================================================================
 * MATERIALS sub-surface (#surface-materials) — the per-course materials
 * browser ported 1:1 from the App_Shell handoff (data-surface-panel=
 * "materials"). Read-only; materials.js fills it from real data. Scoped under
 * #lysia-root #surface-materials (the import surface uses reskin-materials.css
 * scoped to #surface-import — kept separate, untouched).
 * ======================================================================== */
#lysia-root #surface-materials{ max-width:1000px; }

/* editorial header — mono back link, Newsreader title */
#lysia-root #surface-materials .mat-head{ margin-bottom:0.2in; }
#lysia-root #surface-materials .mat-back{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-subtle); background:none; border:none; cursor:pointer; padding:0;
  transition:.25s var(--ease);
}
#lysia-root #surface-materials .mat-back:hover{ color:var(--ink); }
#lysia-root #surface-materials .mat-h1{
  margin:12px 0 0; font:500 clamp(2rem,1.4rem+2.5vw,3.2rem)/1.04 'Newsreader',Georgia,serif;
  letter-spacing:-.02em; color:var(--ink);
}

/* course switcher — segmented pills, muted until active (accent) */
#lysia-root #surface-materials .mat-seg{
  display:flex; flex-wrap:wrap; gap:8px; margin-bottom:0.24in;
}
#lysia-root #surface-materials .mat-chip{
  font:600 12.5px 'Inter',sans-serif; color:var(--ink-muted); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:9px 16px; cursor:pointer;
  transition:background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
#lysia-root #surface-materials .mat-chip:hover{ border-color:var(--ink); color:var(--ink); }
#lysia-root #surface-materials .mat-chip.is-active{
  background:var(--accent-soft); color:var(--ink); border-color:var(--accent);
}

/* per-course view — stacked groups */
#lysia-root #surface-materials .mat-view{
  max-width:880px; display:flex; flex-direction:column; gap:0.26in;
}
#lysia-root #surface-materials .mat-group-label{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase;
  color:var(--slate); margin-bottom:11px;
}

/* a group's rows live in one rounded surface, divided by hairlines */
#lysia-root #surface-materials .mat-card{
  background:var(--surface); border:1px solid var(--border); border-radius:14px; overflow:hidden;
}
#lysia-root #surface-materials .mat-row{
  display:flex; align-items:center; gap:14px; padding:14px 18px;
}
#lysia-root #surface-materials .mat-row + .mat-row{ border-top:1px solid var(--border); }
#lysia-root #surface-materials .mat-badge{
  flex:none; font:600 9px 'JetBrains Mono',monospace; letter-spacing:.1em; text-transform:uppercase;
  color:var(--slate); border:1px solid var(--border-strong); border-radius:6px; padding:4px 7px;
}
#lysia-root #surface-materials .mat-name{
  flex:1; min-width:0; font:500 14px 'Inter',sans-serif; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
#lysia-root #surface-materials .mat-meta{
  flex:none; font:500 11px 'JetBrains Mono',monospace; color:var(--ink-subtle);
}
#lysia-root #surface-materials .mat-open{
  flex:none; font:600 12px 'Inter',sans-serif; color:var(--ink-muted);
  background:none; border:none; cursor:pointer; padding:0; transition:color .25s var(--ease);
}
#lysia-root #surface-materials .mat-open:hover{ color:var(--ink); }

/* empty states — per group + the whole page */
#lysia-root #surface-materials .mat-empty{
  margin:0; font:400 13px/1.5 'Inter',sans-serif; color:var(--ink-subtle);
}
#lysia-root #surface-materials .mat-empty-page{ margin-bottom:0.2in; }

/* add-materials button — ghost pill */
#lysia-root #surface-materials .mat-add{
  align-self:flex-start; font:600 12.5px 'Inter',sans-serif; color:var(--ink);
  background:none; border:1px solid var(--border-strong); border-radius:999px; padding:10px 18px;
  cursor:pointer; transition:border-color .25s var(--ease);
}
#lysia-root #surface-materials .mat-add:hover{ border-color:var(--ink); }

/* ========================================================================
 * IMPORT surface (#surface-import) — PR2f port. The dashed dropzone + the
 * auto-sorted file-list card from the App_Shell handoff (lines 329–342).
 * The real stage→classify→commit pipeline (import.js) is untouched — only the
 * look moves here. Supersedes the #surface-import rules formerly in
 * reskin-materials.css (whose #surface-courses block stays put). Deviates from
 * the static handoff mock where the real flow differs: a folder is staged (not a
 * single Browse pick), so the file rows carry a staging status until the Classify
 * step fills in Course · Type, and steps 2/3 (Classify, Review & commit) have no
 * handoff analog and render in a quiet register below the card.
 * ======================================================================== */
#lysia-root #surface-import .wrap.rk-mat{ max-width:880px; }

/* panel eyebrow — mono uppercase slate, like every ported panel */
#lysia-root #surface-import .rk-mat-eyebrow{
  margin:0 0 0.125in; font:600 11px 'JetBrains Mono',monospace;
  letter-spacing:.24em; text-transform:uppercase; color:var(--slate);
}

/* dashed dropzone — Newsreader title, Inter sub, ink "Browse files" pill */
#lysia-root #surface-import .rk-mat-dropzone{
  border:1.5px dashed var(--border-strong); border-radius:18px;
  padding:clamp(28px,4vw,44px); text-align:center;
  /* warm recessed paper (--bg-deep), not an ink mix — mixing the slate ink into
     the warm paper cooled the panel toward blue against the cream shell */
  background:var(--bg-deep);
}
#lysia-root #surface-import .rk-mat-dropzone-title{
  margin:0; font:500 1.25rem 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-import .rk-mat-dropzone-sub{
  margin:8px auto 18px; max-width:48ch;
  font:400 14px/1.55 'Inter',sans-serif; color:var(--ink-muted);
}
/* label IS the visible control; #ingest-folder stays sr-only but focusable, so
   the webkitdirectory staging hook survives. */
#lysia-root #surface-import .rk-mat-choose{
  display:inline-block; font:600 13px 'Inter',sans-serif; color:var(--bg);
  background:var(--ink); border:1px solid var(--ink); border-radius:999px;
  padding:11px 20px; cursor:pointer; transition:.25s var(--ease);
}
#lysia-root #surface-import .rk-mat-choose:hover{
  background:var(--accent); border-color:var(--accent); color:var(--bg);
}
#lysia-root #surface-import #ingest-folder:focus-visible + .rk-mat-choose{
  outline:2px solid var(--accent); outline-offset:2px;
}

/* stage bar — status + clear */
#lysia-root #surface-import .rk-mat-stage-bar{
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; margin-top:16px; min-height:24px;
}
#lysia-root #surface-import .rk-mat-status{
  margin:0; font:400 13px 'Inter',sans-serif; color:var(--ink-muted);
}
#lysia-root #surface-import .rk-mat-status.err{ color:var(--accent); }
#lysia-root #surface-import .rk-mat-clear{
  flex:none; font:600 11px 'JetBrains Mono',monospace; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-subtle); background:none; border:1px solid transparent; border-radius:6px;
  padding:6px 10px; cursor:pointer; transition:.2s var(--ease);
}
#lysia-root #surface-import .rk-mat-clear:hover{ color:var(--ink); border-color:var(--border-strong); }

/* auto-sorted file-list card — hidden whole when nothing is staged */
#lysia-root #surface-import .rk-mat-files{
  margin-top:16px; background:var(--surface); border:1px solid var(--border);
  border-radius:18px; overflow:hidden;
}
#lysia-root #surface-import .rk-mat-files[hidden]{ display:none; }
#lysia-root #surface-import .rk-mat-files-head{
  display:flex; justify-content:space-between; padding:16px 18px;
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-subtle);
}
#lysia-root #surface-import .rk-mat-staged{ list-style:none; margin:0; padding:0; }
#lysia-root #surface-import .rk-mat-staged-row{
  display:flex; align-items:center; gap:14px; padding:13px 16px; border-top:1px solid var(--border);
}
#lysia-root #surface-import .rk-mat-staged-row:hover{ background:color-mix(in oklch,var(--ink) 2%,transparent); }
#lysia-root #surface-import .rk-mat-badge{
  flex:none; font:600 9px 'JetBrains Mono',monospace; letter-spacing:.1em; text-transform:uppercase;
  color:var(--slate); border:1px solid var(--border-strong); border-radius:6px; padding:4px 7px;
}
#lysia-root #surface-import .rk-mat-staged-name{
  flex:1; min-width:0; font:400 14px 'Inter',sans-serif; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
#lysia-root #surface-import .rk-mat-staged-meta{
  flex:none; font:500 11px 'JetBrains Mono',monospace; color:var(--ink-subtle);
}
#lysia-root #surface-import .rk-mat-staged-remove{
  flex:none; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-subtle); background:none; border:1px solid transparent; border-radius:5px;
  padding:4px 7px; cursor:pointer; transition:.2s var(--ease);
}
#lysia-root #surface-import .rk-mat-staged-remove:hover{
  color:var(--accent); border-color:color-mix(in oklch,var(--accent) 40%,var(--border));
}

/* steps 2 + 3 (Classify · Review & commit) — quiet register, kept usable */
#lysia-root #surface-import .rk-mat-step{
  margin-top:22px; padding-top:22px; border-top:1px solid var(--border);
}
#lysia-root #surface-import .rk-mat-step[hidden]{ display:none; }
#lysia-root #surface-import .rk-mat-step-label{
  margin:0 0 6px; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase; color:var(--slate);
}
#lysia-root #surface-import .rk-mat-step-note{
  margin:0 0 14px; max-width:60ch; font:400 13.5px/1.5 'Inter',sans-serif; color:var(--ink-muted);
}
#lysia-root #surface-import .rk-mat-btn{
  font:600 13px 'Inter',sans-serif; color:var(--bg); background:var(--ink);
  border:1px solid var(--ink); border-radius:999px; padding:11px 20px; cursor:pointer; transition:.25s var(--ease);
}
#lysia-root #surface-import .rk-mat-btn:hover:not(:disabled){ background:var(--accent); border-color:var(--accent); }
#lysia-root #surface-import .rk-mat-btn:disabled{ opacity:.5; cursor:default; }
#lysia-root #surface-import .rk-mat-row{ margin-top:14px; }
#lysia-root #surface-import .rk-mat-step .rk-mat-status{ margin-top:10px; }

/* review table — quiet, matches the shell form vocabulary */
#lysia-root #surface-import .rk-mat-table-scroll{
  overflow-x:auto; border:1px solid var(--border); border-radius:14px; background:var(--surface);
}
#lysia-root #surface-import .rk-mat-table{ width:100%; border-collapse:collapse; font:400 13.5px 'Inter',sans-serif; }
#lysia-root #surface-import .rk-mat-table th{
  text-align:left; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-subtle); padding:11px 14px; border-bottom:1px solid var(--border);
}
#lysia-root #surface-import .rk-mat-table td{
  padding:11px 14px; border-bottom:1px solid var(--border); color:var(--ink); vertical-align:top;
}
#lysia-root #surface-import .rk-mat-table tr:last-child td{ border-bottom:0; }
#lysia-root #surface-import .rk-mat-table tr.needs-review td{ background:color-mix(in oklch,var(--accent) 10%,var(--surface)); }
#lysia-root #surface-import .rk-mat-table .muted{ color:var(--ink-subtle); font-size:12px; margin-top:4px; }
#lysia-root #surface-import .rk-mat-table select,
#lysia-root #surface-import .rk-mat-table input[type="text"]{
  font:400 13px 'Inter',sans-serif; color:var(--ink); background:var(--surface-raised);
  border:1px solid var(--border-strong); border-radius:6px; padding:5px 8px; max-width:100%;
}
#lysia-root #surface-import .rk-mat-table .ingest-new-name{ margin-top:6px; }

@media (max-width:720px){
  #lysia-root #surface-import .rk-mat-staged-meta{ display:none; }
}

/* ===========================================================================
 * Practice Exams (#surface-exam) — PR2e three-group port. Faithful to the
 * handoff card structure (App_Shell handoff lines 307–328): To take · Completed
 * · Needs your feedback. The editorial header (.rk-prac-*) + amber gap band stay
 * in reskin-practice.css; the group + card chrome lives here. practice-queue.js
 * buckets GET /api/practice/exams into these lists.
 * ======================================================================== */
#lysia-root #surface-exam .pe-group{ margin-bottom:30px; }
#lysia-root #surface-exam .pe-group[hidden]{ display:none; }
#lysia-root #surface-exam .pe-group-head{
  display:flex; align-items:center; gap:9px; margin-bottom:11px;
}
#lysia-root #surface-exam .pe-group-label{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-muted);
}
#lysia-root #surface-exam .pe-group-count{
  font:600 9px 'JetBrains Mono',monospace; color:var(--ink-subtle);
  background:color-mix(in oklch, var(--ink) 7%, transparent);
  border-radius:999px; padding:2px 8px;
}
#lysia-root #surface-exam .pe-group-count.pe-count-accent{
  color:var(--accent); background:var(--accent-soft);
}
#lysia-root #surface-exam .pe-list{ display:flex; flex-direction:column; gap:12px; }

/* card */
#lysia-root #surface-exam .pe-card{
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  background:var(--surface); border:1px solid var(--border);
  border-radius:14px; padding:16px 20px;
}
#lysia-root #surface-exam .pe-card-main{ flex:1; min-width:0; }
#lysia-root #surface-exam .pe-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-subtle);
}
#lysia-root #surface-exam .pe-title{
  margin-top:3px; font:500 1.1rem 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-exam .pe-sub{
  margin-top:4px; font:400 12.5px 'Inter',sans-serif; color:var(--ink-muted);
}

/* "X% ready" tag (To take) — green when ready, terracotta when low */
#lysia-root #surface-exam .pe-ready{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.06em;
  text-transform:uppercase; white-space:nowrap; color:var(--ink-subtle);
}
#lysia-root #surface-exam .pe-ready.is-ready{ color:var(--ready-green); }
#lysia-root #surface-exam .pe-ready.is-low{ color:var(--accent); }

/* difficulty display (Completed) — 5-segment bar + word */
#lysia-root #surface-exam .pe-diff{
  display:flex; flex-direction:column; align-items:flex-end; gap:5px;
}
#lysia-root #surface-exam .pe-diff-label{
  font:600 9px 'JetBrains Mono',monospace; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-subtle);
}
#lysia-root #surface-exam .pe-diff-bar{ display:flex; gap:3px; }
#lysia-root #surface-exam .pe-diff-seg{
  width:15px; height:7px; border-radius:2px; border:1px solid var(--border-strong);
}
#lysia-root #surface-exam .pe-diff-seg.is-on{
  background:var(--accent); border-color:var(--accent);
}

/* buttons */
#lysia-root #surface-exam .pe-btn{
  font:600 13px 'Inter',sans-serif; color:var(--ink); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:8px 16px;
  cursor:pointer; transition:border-color .25s var(--ease), opacity .25s var(--ease);
}
#lysia-root #surface-exam .pe-btn:hover{ border-color:var(--ink); }
#lysia-root #surface-exam .pe-btn-primary{
  color:var(--bg); background:var(--ink); border-color:var(--ink); padding:8px 18px;
}
#lysia-root #surface-exam .pe-btn-primary:hover{ border-color:var(--ink); opacity:.9; }
#lysia-root #surface-exam .pe-btn-accent{
  color:var(--bg); background:var(--accent); border-color:var(--accent); padding:8px 18px;
}
#lysia-root #surface-exam .pe-btn-accent:hover{ border-color:var(--accent); opacity:.92; }

/* feedback card — accent glow */
#lysia-root #surface-exam .pe-card-feedback{
  border-color:color-mix(in oklch, var(--accent) 32%, var(--border));
  box-shadow:0 0 18px -8px color-mix(in oklch, var(--accent) 55%, transparent);
}

/* whole-surface empty / error state — a quiet ghost sapling gives the empty
   queue the same botanical warmth as the org-shell empty states */
#lysia-root #surface-exam .pe-empty{
  padding:6px 2px 2px; min-height:190px;
  background:url("assets/g/sapling-01-ghost.webp") no-repeat right clamp(12px,6%,64px) bottom / auto 170px;
}
#lysia-root #surface-exam .pe-empty[hidden]{ display:none; }
#lysia-root #surface-exam .pe-empty-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.18em;
  text-transform:uppercase; color:var(--ink-subtle); margin-bottom:8px;
}
#lysia-root #surface-exam .pe-empty-body{
  margin:0; font:400 15px/1.55 'Inter',sans-serif; color:var(--ink-muted); max-width:48ch;
}

/* ===========================================================================
 * Settings surface (App_Shell PR2g) — the handoff's clean 6-row account layout.
 * A max-760px column of label / description / action rows, hairline-separated.
 * Scoped under #lysia-root #surface-settings; this sheet loads after
 * reskin-settings.css, so it supersedes the old reskin shell where they overlap.
 * The live JS hooks (#billing-*, #pw-*, #users-block, the mode controller) keep
 * their IDs; only the chrome around them changes.
 * ======================================================================== */
#lysia-root #surface-settings .rk-set-wrap{ max-width:760px; }
#lysia-root #surface-settings .rk-set-eyebrow{
  font:600 11px 'JetBrains Mono',monospace; letter-spacing:.24em;
  text-transform:uppercase; color:var(--slate); margin-bottom:6px;
}

#lysia-root #surface-settings .rk-set-row{
  display:grid; grid-template-columns:minmax(150px,220px) 1fr auto;
  gap:20px; align-items:center; padding:20px 0; border-top:1px solid var(--border);
}
#lysia-root #surface-settings .rk-set-label{
  font:500 1.05rem 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-settings .rk-set-desc{
  font:400 14px 'Inter',sans-serif; color:var(--ink-muted); min-width:0;
}

/* Pill action buttons (Change / Toggle / Download / Manage / Delete). */
#lysia-root #surface-settings .rk-set-act{
  display:inline-flex; align-items:center; justify-content:center;
  font:600 12px 'Inter',sans-serif; color:var(--ink); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:8px 14px;
  cursor:pointer; text-decoration:none; white-space:nowrap;
  transition:border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
#lysia-root #surface-settings .rk-set-act:hover{ border-color:var(--ink); }
#lysia-root #surface-settings .rk-set-act-group{ display:flex; gap:8px; }
/* Semantic terracotta for the destructive Delete action. */
#lysia-root #surface-settings .rk-set-act-danger{
  color:var(--accent);
  border-color:color-mix(in oklch, var(--accent) 40%, var(--border));
}
#lysia-root #surface-settings .rk-set-act-danger:hover{
  border-color:var(--accent); background:var(--accent-soft);
}

/* Plan row is itself the grid (#billing-block); the billing hint, when present,
 * drops to its own full-width line under the row. */
#lysia-root #surface-settings #billing-block .hint{ grid-column:1 / -1; margin:0; }

/* Inline password form revealed by the Password row button. The input/submit
 * styling still comes from reskin-settings.css; here we only own the open/closed
 * toggle + a touch of spacing under the row. */
#lysia-root #surface-settings .rk-set-pw{ padding:0 0 20px; margin:0; }
#lysia-root #surface-settings .rk-set-pw[hidden]{ display:none; }

/* ===================================================================
   #surface-billing — the "Manage Plan" sub-surface (App_Shell PR2h).
   Ported 1:1 from the handoff (data-surface-panel="billing"): a back link
   to Settings, a current-plan headline, a 4-up plan-card grid with the
   active tier accent-ringed, and a terracotta Cancel row. Both modes
   resolve from the shared tokens. =================================== */
#lysia-root #surface-billing .rk-bill-wrap{ max-width:880px; }

#lysia-root #surface-billing .rk-bill-head{
  display:flex; align-items:center; gap:12px; margin-bottom:0.125in;
}
#lysia-root #surface-billing .rk-bill-back{
  display:inline-flex; align-items:center; gap:6px;
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-subtle); background:none; border:none; cursor:pointer; padding:4px 0;
  transition:color .2s var(--ease);
}
#lysia-root #surface-billing .rk-bill-back:hover{ color:var(--ink); }
#lysia-root #surface-billing .rk-bill-eyebrow{
  font:600 11px 'JetBrains Mono',monospace; letter-spacing:.24em; text-transform:uppercase;
  color:var(--slate);
}

#lysia-root #surface-billing .rk-bill-top{
  display:flex; align-items:baseline; justify-content:space-between; gap:16px;
  flex-wrap:wrap; margin-bottom:22px;
}
#lysia-root #surface-billing .rk-bill-h1{
  margin:0; font:500 clamp(1.8rem,1.3rem+1.6vw,2.4rem)/1.05 'Newsreader',Georgia,serif;
  letter-spacing:-.015em; color:var(--ink);
}
#lysia-root #surface-billing .rk-bill-meta{
  margin:9px 0 0; font:400 15px/1.55 'Inter',sans-serif; color:var(--ink-muted);
}
#lysia-root #surface-billing .rk-bill-portal{
  font:600 12px 'Inter',sans-serif; color:var(--ink); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:8px 14px;
  cursor:pointer; white-space:nowrap; transition:border-color .2s var(--ease);
}
#lysia-root #surface-billing .rk-bill-portal:hover{ border-color:var(--ink); }
#lysia-root #surface-billing .rk-bill-portal:disabled{ opacity:.55; cursor:default; }

#lysia-root #surface-billing .rk-bill-grid{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(206px,1fr));
  gap:16px; margin-bottom:18px;
}
#lysia-root #surface-billing .rk-bill-card{
  background:var(--surface); border:1px solid var(--border); border-radius:16px;
  padding:22px; display:flex; flex-direction:column; gap:14px;
  transition:border-color .2s var(--ease), box-shadow .2s var(--ease);
}
/* Active tier — accent ring + soft glow, mirroring the handoff's "Current" card. */
#lysia-root #surface-billing .rk-bill-card.is-current{
  border:1.5px solid var(--accent);
  box-shadow:0 0 0 1px var(--accent),
             0 14px 30px -18px color-mix(in oklch,var(--accent) 60%,transparent);
}
#lysia-root #surface-billing .rk-bill-tier{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-subtle);
}
#lysia-root #surface-billing .rk-bill-card.is-current .rk-bill-tier{ color:var(--accent); }
#lysia-root #surface-billing .rk-bill-badge{
  font:600 9px 'JetBrains Mono',monospace; letter-spacing:.1em; text-transform:uppercase;
  color:var(--accent); background:var(--accent-soft); border-radius:999px; padding:3px 8px;
}
#lysia-root #surface-billing .rk-bill-price{
  margin-top:10px; font:500 1.8rem 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-billing .rk-bill-cycle{
  font:400 13px 'Inter',sans-serif; color:var(--ink-subtle);
}
#lysia-root #surface-billing .rk-bill-feats{
  list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px;
  font:400 13.5px/1.4 'Inter',sans-serif; color:var(--ink-muted);
}
#lysia-root #surface-billing .rk-bill-switch{
  margin-top:auto; font:600 12px 'Inter',sans-serif; color:var(--ink);
  background:none; border:1px solid var(--border-strong); border-radius:999px;
  padding:10px 16px; cursor:pointer;
  transition:border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
#lysia-root #surface-billing .rk-bill-switch:hover{ border-color:var(--ink); }
/* The top tier reads as the loudest CTA (filled ink), like the handoff's "Go all in". */
#lysia-root #surface-billing .rk-bill-switch--primary{
  color:var(--accent-ink); background:var(--ink); border-color:var(--ink);
}
#lysia-root #surface-billing .rk-bill-switch--primary:hover{ background:var(--ink-muted); }
/* The active tier's button is the soft "Your plan" chip (disabled). */
#lysia-root #surface-billing .rk-bill-card.is-current .rk-bill-switch{
  color:var(--ink-subtle); background:var(--accent-soft); border-color:transparent;
}
#lysia-root #surface-billing .rk-bill-switch:disabled{ cursor:default; }
#lysia-root #surface-billing .rk-bill-switch:disabled:hover{ border-color:transparent; }

#lysia-root #surface-billing .rk-bill-note{ display:block; margin:0 0 6px; }

#lysia-root #surface-billing .rk-bill-cancel{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  flex-wrap:wrap; padding:20px 0; border-top:1px solid var(--border);
}
#lysia-root #surface-billing .rk-bill-cancel-label{
  font:500 1.05rem 'Newsreader',Georgia,serif; color:var(--ink);
}
#lysia-root #surface-billing .rk-bill-cancel-desc{
  margin-top:3px; font:400 13.5px 'Inter',sans-serif; color:var(--ink-muted);
}
/* Terracotta semantic for the destructive cancel action. */
#lysia-root #surface-billing .rk-bill-cancel-btn{
  font:600 12px 'Inter',sans-serif; color:var(--accent); background:none;
  border:1px solid color-mix(in oklch,var(--accent) 40%,var(--border));
  border-radius:999px; padding:9px 16px; cursor:pointer; white-space:nowrap;
  transition:border-color .2s var(--ease), background .2s var(--ease);
}
#lysia-root #surface-billing .rk-bill-cancel-btn:hover{
  border-color:var(--accent); background:var(--accent-soft);
}

/* ===========================================================================
   App feedback modal (PR3b) — the ported handoff `data-fb` card. Lives as a
   SIBLING of #lysia-root, so selectors are unscoped (.fb-*); design tokens
   still resolve because :root[data-mode] carries the full palette. Terracotta
   (--accent) accents the rating/tag selection. display:none until .is-open so
   it stays out of the tab order while closed.
   =========================================================================== */
.fb-modal{
  position:fixed; inset:0; z-index:95; display:none;
  align-items:center; justify-content:center; padding:24px;
}
.fb-modal.is-open{ display:flex; }
.fb-veil{
  position:absolute; inset:0; background:rgba(16,22,18,.62);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
.fb-card{
  position:relative; width:min(440px,100%); max-height:calc(100vh - 48px);
  overflow:auto; background:var(--surface); color:var(--ink);
  border:1px solid var(--border); border-radius:22px; padding:30px;
  box-shadow:var(--shadow-3);
}
.fb-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent); margin-bottom:12px;
}
.fb-title{ margin:0; font:500 1.6rem/1.12 'Newsreader',Georgia,serif; color:var(--ink); }
.fb-lead{ margin:8px 0 0; font:400 14px/1.6 'Inter',sans-serif; color:var(--ink-muted); }
.fb-label{
  margin-top:24px; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-subtle);
}
.fb-label-opt{ text-transform:none; letter-spacing:0; }
.fb-scale{ display:flex; gap:8px; margin-top:11px; }
.fb-rate{
  flex:1; font:600 15px 'Newsreader',Georgia,serif; color:var(--ink);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:12px; padding:13px 0; cursor:pointer;
  transition:border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
.fb-rate:hover{ border-color:var(--accent); }
.fb-rate.is-active{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
.fb-scale-ends{
  display:flex; justify-content:space-between; margin-top:7px;
  font:500 11px 'Inter',sans-serif; color:var(--ink-subtle);
}
.fb-tags{ display:flex; flex-wrap:wrap; gap:8px; margin-top:11px; }
.fb-tag{
  font:600 12.5px 'Inter',sans-serif; color:var(--ink-muted); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:8px 14px;
  cursor:pointer; transition:border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
.fb-tag:hover{ border-color:var(--accent); color:var(--ink); }
.fb-tag.is-active{
  background:var(--accent-soft); border-color:var(--accent); color:var(--accent);
}
.fb-text{
  margin-top:18px; width:100%; box-sizing:border-box; min-height:84px;
  resize:vertical; font:400 14px/1.5 'Inter',sans-serif; color:var(--ink);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:12px; padding:12px 14px;
}
.fb-actions{ display:flex; align-items:center; gap:10px; margin-top:20px; }
.fb-skip{
  font:600 12px 'Inter',sans-serif; color:var(--ink-subtle); background:none;
  border:none; cursor:pointer; padding:8px 6px;
}
.fb-skip:hover{ color:var(--ink-muted); }
.fb-spacer{ flex:1; }
.fb-send, .fb-close{
  font:600 13px 'Inter',sans-serif; color:var(--bg); background:var(--ink);
  border:none; border-radius:999px; padding:12px 24px; cursor:pointer;
  transition:transform .25s var(--ease-spring), box-shadow .25s var(--ease);
}
.fb-send:hover, .fb-close:hover{ transform:translateY(-1px); box-shadow:var(--shadow-2); }
.fb-send:disabled{ opacity:.5; cursor:not-allowed; transform:none; box-shadow:none; }
.fb-thanks{ text-align:center; padding:14px 0; }
.fb-check{
  margin:0 auto; width:46px; height:46px; border-radius:99px;
  background:var(--accent-soft); color:var(--accent);
  display:flex; align-items:center; justify-content:center; font-size:22px;
}
.fb-thanks-title{ margin:16px 0 0; font:500 1.5rem 'Newsreader',Georgia,serif; color:var(--ink); }
.fb-thanks-body{ margin:8px 0 0; font:400 14px/1.6 'Inter',sans-serif; color:var(--ink-muted); }
.fb-close{ margin-top:22px; padding:11px 26px; }

@media (prefers-reduced-motion: reduce){
  .fb-rate, .fb-tag, .fb-text, .fb-send, .fb-close{ transition:none; }
  .fb-send:hover, .fb-close:hover{ transform:none; }
}

/* ===========================================================================
   Settings handoff modal (App_Shell PR3c, `data-sx`) — ported from the handoff
   card. SIBLING of #lysia-root, so selectors are unscoped (.sx-*); design tokens
   resolve because :root[data-mode] carries the full palette (both themes).
   Terracotta (--accent) accents the danger panel. display:none until .is-open so
   it stays out of the tab order while closed.
   =========================================================================== */
.sx-modal{
  position:fixed; inset:0; z-index:96; display:none;
  align-items:center; justify-content:center; padding:24px;
}
.sx-modal.is-open{ display:flex; }
.sx-veil{
  position:absolute; inset:0; background:rgba(16,22,18,.62);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
.sx-card{
  position:relative; width:min(420px,100%); max-height:calc(100vh - 48px);
  overflow:auto; background:var(--surface); color:var(--ink);
  border:1px solid var(--border); border-radius:22px; padding:30px;
  box-shadow:var(--shadow-3);
}
.sx-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-subtle);
}
.sx-eyebrow-danger{ color:var(--accent); }
.sx-title{ margin:10px 0 0; font:500 1.5rem 'Newsreader',Georgia,serif; color:var(--ink); }
.sx-lead{ margin:8px 0 0; font:400 13.5px/1.55 'Inter',sans-serif; color:var(--ink-muted); }
.sx-lead strong{ color:var(--ink); }
.sx-field-label{
  display:block; margin-top:16px; font:600 11px 'Inter',sans-serif; color:var(--ink-muted);
}
.sx-current{ margin-top:6px; font:400 14px 'Inter',sans-serif; color:var(--ink); }
.sx-input{
  margin-top:6px; width:100%; box-sizing:border-box;
  font:400 14px 'Inter',sans-serif; color:var(--ink);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:11px; padding:12px 14px;
}
.sx-input:focus-visible{ outline:2px solid var(--focus-ring); outline-offset:1px; }
.sx-confirm{ font-weight:600; }
.sx-err{
  margin:12px 0 0; font:500 12.5px/1.45 'Inter',sans-serif; color:var(--missed);
}
.sx-ok{
  margin:12px 0 0; font:500 12.5px/1.45 'Inter',sans-serif; color:var(--ink-muted);
}
.sx-sub{
  margin-top:20px; font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-subtle);
}
.sx-reasons{ margin-top:11px; display:flex; flex-wrap:wrap; gap:8px; }
.sx-reason{
  font:600 12px 'Inter',sans-serif; color:var(--ink-muted);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:999px; padding:8px 14px; cursor:pointer;
  transition:border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease);
}
.sx-reason:hover{ border-color:var(--accent); color:var(--ink); }
.sx-reason.is-active{ background:var(--ink); border-color:var(--ink); color:var(--bg); }
.sx-note{
  margin-top:11px; width:100%; box-sizing:border-box; resize:none;
  font:400 13px/1.5 'Inter',sans-serif; color:var(--ink);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:11px; padding:11px 13px;
}
.sx-actions{ display:flex; align-items:center; gap:10px; margin-top:22px; }
.sx-spacer{ flex:1; }
.sx-btn{
  font:600 12px 'Inter',sans-serif; color:var(--ink-muted); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:10px 18px;
  cursor:pointer; transition:transform .25s var(--ease-spring), box-shadow .25s var(--ease), border-color .2s var(--ease);
}
.sx-btn:hover{ border-color:var(--accent); color:var(--ink); }
.sx-btn-primary{
  color:var(--bg); background:var(--ink); border-color:var(--ink); padding:10px 20px;
}
.sx-btn-primary:hover{ transform:translateY(-1px); box-shadow:var(--shadow-2); color:var(--bg); }
.sx-btn-danger{
  color:var(--accent-ink); background:var(--accent); border-color:var(--accent); padding:10px 20px;
}
.sx-btn-danger:hover{ transform:translateY(-1px); box-shadow:var(--shadow-2); }
.sx-btn:disabled,
.sx-btn-danger:disabled{ opacity:.5; cursor:not-allowed; transform:none; box-shadow:none; }

@media (prefers-reduced-motion: reduce){
  .sx-reason, .sx-btn{ transition:none; }
  .sx-btn-primary:hover, .sx-btn-danger:hover{ transform:none; }
}

/* ===========================================================================
   Cancel-subscription modal (App_Shell PR3d, `data-cancel`) — ported from the
   handoff card. SIBLING of #lysia-root, unscoped (.cancel-*); tokens resolve in
   both modes. Terracotta (--accent) is the semantic cancel accent; selected
   reasons glow terracotta while their text stays legible (--ink). display:none
   until .is-open so the closed modal stays out of the tab order.
   =========================================================================== */
.cancel-modal{
  position:fixed; inset:0; z-index:96; display:none;
  align-items:center; justify-content:center; padding:24px;
}
.cancel-modal.is-open{ display:flex; }
.cancel-veil{
  position:absolute; inset:0; background:rgba(16,22,18,.62);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
.cancel-card{
  position:relative; width:min(480px,100%); max-height:calc(100vh - 48px);
  overflow:auto; background:var(--surface); color:var(--ink);
  border:1px solid var(--border); border-radius:22px; padding:30px;
  box-shadow:var(--shadow-3);
}
.cancel-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent);
}
.cancel-title{ margin:10px 0 0; font:500 1.6rem/1.12 'Newsreader',Georgia,serif; color:var(--ink); }
.cancel-lead{ margin:8px 0 0; font:400 13.5px/1.55 'Inter',sans-serif; color:var(--ink-muted); }
.cancel-reasons{ display:flex; flex-direction:column; gap:8px; margin-top:20px; }
.cancel-reason{
  text-align:left; font:500 13.5px 'Inter',sans-serif; color:var(--ink-muted);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:11px; padding:12px 15px; cursor:pointer;
  transition:border-color .18s var(--ease), background .18s var(--ease),
    color .18s var(--ease), box-shadow .18s var(--ease);
}
.cancel-reason:hover{ border-color:var(--accent); color:var(--ink); }
.cancel-reason.is-active{
  border-color:var(--accent); color:var(--ink);
  background:color-mix(in oklch, var(--accent) 14%, var(--surface-raised));
  box-shadow:0 0 0 1px var(--accent) inset, 0 4px 16px -6px var(--accent);
}
.cancel-note{
  margin-top:16px; width:100%; box-sizing:border-box; min-height:76px; resize:vertical;
  font:400 14px/1.5 'Inter',sans-serif; color:var(--ink);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:12px; padding:12px 14px;
}
.cancel-note:focus-visible{ outline:2px solid var(--focus-ring); outline-offset:1px; }
.cancel-actions{ display:flex; align-items:center; gap:10px; margin-top:20px; }
.cancel-spacer{ flex:1; }
.cancel-btn{
  font:600 13px 'Inter',sans-serif; color:var(--ink-muted); background:none;
  border:1px solid var(--border-strong); border-radius:999px; padding:12px 22px;
  cursor:pointer; transition:transform .25s var(--ease-spring), box-shadow .25s var(--ease), border-color .2s var(--ease);
}
.cancel-btn:hover{ border-color:var(--accent); color:var(--ink); }
.cancel-btn-primary{ color:var(--bg); background:var(--ink); border-color:var(--ink); }
.cancel-btn-primary:hover{ transform:translateY(-1px); box-shadow:var(--shadow-2); color:var(--bg); }
.cancel-btn-accent{
  color:var(--accent);
  border-color:color-mix(in oklch, var(--accent) 40%, var(--border-strong));
}
.cancel-btn-accent:hover{ border-color:var(--accent); color:var(--accent); transform:translateY(-1px); box-shadow:var(--shadow-2); }
.cancel-btn:disabled{ opacity:.5; cursor:not-allowed; transform:none; box-shadow:none; }
.cancel-thanks{ text-align:center; padding:14px 0; }
.cancel-thanks-icon{
  margin:0 auto; width:46px; height:46px; border-radius:99px;
  background:color-mix(in oklch, var(--done) 18%, transparent); color:var(--done);
  display:flex; align-items:center; justify-content:center; font-size:22px;
}
.cancel-thanks .cancel-title{ margin-top:16px; }

@media (prefers-reduced-motion: reduce){
  .cancel-reason, .cancel-btn{ transition:none; }
  .cancel-btn-primary:hover, .cancel-btn-accent:hover{ transform:none; }
}

/* ===========================================================================
   Generate-loader step list (Institution P2, D55/D56). Promoted out of the
   runtime <style id="igl-styles"> inject in inst_generate_loader.js so the rules
   live in the design system and re-ink with the theme. Unscoped (like loader.css)
   because the loader mounts on the full-screen brand overlay, outside #lysia-root.
   References the shared --bl-terra token defined in :root above.
   =========================================================================== */
.igl-steps{ list-style:none; margin:18px 0 0; padding:0; display:flex;
  flex-direction:column; gap:8px; width:min(320px,80vw); text-align:left;
  font-family:var(--font-data,ui-monospace,monospace); font-size:12px;
  letter-spacing:.04em; color:var(--ink); }
.igl-step{ display:flex; align-items:center; gap:10px; opacity:.42;
  transition:opacity var(--duration-normal,300ms) ease; }
.igl-step.is-active,.igl-step.is-done,.igl-step.is-failed{ opacity:1; }
.igl-step-mark{ flex:0 0 auto; width:14px; height:14px; border-radius:50%;
  border:1.5px solid color-mix(in oklch,var(--ink) 35%,transparent);
  position:relative; display:inline-block; }
.igl-step.is-done .igl-step-mark{ background:var(--bl-terra); border-color:var(--bl-terra); }
.igl-step.is-active .igl-step-mark{ border-color:var(--bl-terra); }
.igl-step.is-active .igl-step-mark::after{ content:""; position:absolute;
  inset:3px; border-radius:50%; background:var(--bl-terra); }
.igl-step.is-failed .igl-step-mark::after{ content:"\00d7"; position:absolute;
  inset:0; display:flex; align-items:center; justify-content:center;
  font-size:12px; line-height:1; color:var(--bl-terra); }
.igl-step-label{ flex:1 1 auto; }
.igl-sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
.igl-bar-failed{ background:color-mix(in oklch,var(--bl-terra) 55%,var(--ink))!important; }
@media (prefers-reduced-motion:no-preference){
  .igl-step.is-active .igl-step-mark::after{ animation:igl-pulse 1.4s ease-in-out infinite; }
}
@keyframes igl-pulse{ 0%,100%{ opacity:1; transform:scale(1); }
  50%{ opacity:.4; transform:scale(.65); } }

/* ===========================================================================
   LMS connect card (P3, D62=B / D63=A) — the instructor "Connect your LMS"
   surface in the Classroom panel (#lms-block, built by lms.js). Net-new tokens
   for the provider grid (.lms-grid / .lms-tile / .lms-mark) + the toggle (.tgl);
   neutral monospace marks only, no third-party logos. Reuses the shared palette.
   =========================================================================== */
#lysia-root #lms-block{
  background:var(--surface); border:1px solid var(--border); border-radius:14px;
  padding:18px 20px; margin-top:20px; box-shadow:var(--shadow-1);
}
#lysia-root #lms-block .lms-head{ display:flex; align-items:baseline; gap:10px; }
#lysia-root #lms-block .lms-title{
  font:600 17px 'Newsreader',Georgia,serif; color:var(--ink); margin:0;
}
#lysia-root #lms-block .lms-tag{
  font:600 9px 'JetBrains Mono',monospace; letter-spacing:.1em; text-transform:uppercase;
  color:var(--slate); border:1px solid var(--border-strong); border-radius:6px; padding:3px 7px;
}
#lysia-root #lms-block .lms-sub{
  font:400 13px/1.5 'Inter',sans-serif; color:var(--ink-muted); margin:6px 0 14px;
}
#lysia-root #lms-block .lms-cta-lead{
  font:500 13px 'Inter',sans-serif; color:var(--ink-muted); margin:0 0 10px;
}
/* provider grid — responsive, gapless-ish bento of equal tiles */
#lysia-root #lms-block .lms-grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:10px;
}
#lysia-root #lms-block .lms-tile{
  display:flex; flex-direction:column; align-items:center; gap:8px;
  padding:16px 10px; background:var(--surface-raised);
  border:1px solid var(--border); border-radius:12px; cursor:pointer;
  transition:border-color .2s var(--ease), transform .2s var(--ease);
}
#lysia-root #lms-block .lms-tile:hover{ border-color:var(--accent); transform:translateY(-2px); }
#lysia-root #lms-block .lms-tile:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
#lysia-root #lms-block .lms-tile-label{ font:500 12px 'Inter',sans-serif; color:var(--ink); text-align:center; }
/* neutral monospace mark — initials, never a logo */
#lysia-root #lms-block .lms-mark{
  display:flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:9px;
  background:var(--accent-soft); color:var(--accent);
  font:600 14px 'JetBrains Mono',monospace; letter-spacing:.02em;
}
/* syncing spinner */
#lysia-root #lms-block .lms-syncing-label{ font:500 14px 'Inter',sans-serif; color:var(--ink-muted); }
#lysia-root #lms-block #lms-syncing{ display:flex; align-items:center; gap:12px; }
#lysia-root #lms-block .lms-spinner{
  width:18px; height:18px; border-radius:50%;
  border:2px solid var(--border-strong); border-top-color:var(--accent);
}
@media (prefers-reduced-motion:no-preference){
  #lysia-root #lms-block .lms-spinner{ animation:lms-spin .8s linear infinite; }
}
@keyframes lms-spin{ to{ transform:rotate(360deg); } }
/* connected state */
#lysia-root #lms-block .lms-conn-head{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
}
#lysia-root #lms-block .lms-conn-id{ display:flex; align-items:center; gap:10px; }
#lysia-root #lms-block .lms-prov-name{ font:600 15px 'Inter',sans-serif; color:var(--ink); }
#lysia-root #lms-block .lms-chip{
  font:600 11px 'JetBrains Mono',monospace; color:var(--em);
  background:var(--accent-soft); border-radius:999px; padding:4px 10px;
}
#lysia-root #lms-block .lms-conn-actions{ display:flex; gap:8px; }
#lysia-root #lms-block .lms-quizzes{ margin-top:14px; }
#lysia-root #lms-block .lms-quizzes .mat-row{
  display:flex; align-items:center; gap:14px; padding:12px 0;
}
#lysia-root #lms-block .lms-quizzes .mat-row + .mat-row{ border-top:1px solid var(--border); }
#lysia-root #lms-block .mat-row-title{ flex:1; min-width:0; font:500 14px 'Inter',sans-serif; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
#lysia-root #lms-block .mat-row-meta{ font:400 12px 'Inter',sans-serif; color:var(--ink-subtle); }
#lysia-root #lms-block .lms-state-msg{ font:400 13px 'Inter',sans-serif; color:var(--ink-subtle); margin:8px 0 0; }
/* live Canvas OAuth connect form (BUG-040) */
#lysia-root #lms-block .lms-canvas-form{ display:flex; flex-direction:column; gap:12px; margin-top:12px; }
#lysia-root #lms-block .lms-field{ display:flex; flex-direction:column; gap:4px; }
#lysia-root #lms-block .lms-field-label{ font:500 12px 'Inter',sans-serif; color:var(--ink-subtle); }
#lysia-root #lms-block .lms-input{
  font:400 14px 'Inter',sans-serif; color:var(--ink);
  background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:9px 11px;
}
#lysia-root #lms-block .lms-input:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent); }
/* toggle switch (.tgl) — per-class student self-gen / release controls */
#lysia-root .tgl{
  position:relative; display:inline-flex; align-items:center; width:38px; height:22px;
  border-radius:999px; background:var(--border-strong); cursor:pointer;
  transition:background .2s var(--ease); border:none; padding:0;
}
#lysia-root .tgl::after{
  content:""; position:absolute; left:3px; width:16px; height:16px; border-radius:50%;
  background:var(--surface-raised); box-shadow:var(--shadow-1); transition:transform .2s var(--ease);
}
#lysia-root .tgl[aria-checked="true"]{ background:var(--accent); }
#lysia-root .tgl[aria-checked="true"]::after{ transform:translateX(16px); }
#lysia-root .tgl:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* ============================================================================
 * P6 institution surfaces — Support (D16=B), Audit log (D38=A), and the
 * Accessible-output affordance (D44=A). Styling only: every owning module builds
 * its DOM with textContent and degrades gracefully, so these rules are presentation
 * (the surfaces function unstyled). Tokens reuse the existing palette/spacing vars.
 * ========================================================================== */
#lysia-root .sup-wrap,
#lysia-root .aud-wrap{ max-width:880px; padding:8px 4px 32px; }
#lysia-root .sup-h1,
#lysia-root .aud-wrap .sup-h1{ font:600 26px 'Newsreader',Georgia,serif; color:var(--ink); margin:0 0 6px; }
#lysia-root .sup-h2{ font:600 17px 'Newsreader',Georgia,serif; color:var(--ink); margin:0; }
#lysia-root .sup-section{ margin-top:22px; padding-top:18px; border-top:1px solid var(--border); }
#lysia-root .sup-section-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
#lysia-root .sup-msg{ color:var(--ink-muted); font:400 14px 'Inter',sans-serif; margin:8px 0; }
#lysia-root .sup-back{ background:none; border:0; color:var(--accent); font:500 13px 'Inter',sans-serif;
  cursor:pointer; padding:4px 0; margin-bottom:8px; }
#lysia-root .sup-back:hover{ text-decoration:underline; }

/* Status board */
#lysia-root .status-banner{ display:flex; align-items:center; gap:10px; padding:12px 14px;
  border:1px solid var(--border); border-radius:10px; background:var(--surface-raised); margin-bottom:12px; }
#lysia-root .status-orb{ width:12px; height:12px; border-radius:50%; background:var(--ready-green); flex:0 0 auto; }
#lysia-root .status-banner-label{ font:600 14px 'Inter',sans-serif; color:var(--ink); }
#lysia-root .status-banner.svc-deg .status-orb{ background:var(--slate); }
#lysia-root .status-banner.svc-out .status-orb{ background:var(--bl-terra); }
#lysia-root .svc-list{ display:flex; flex-direction:column; gap:8px; }
#lysia-root .svc-row{ display:grid; grid-template-columns:1fr auto auto; align-items:center; gap:12px;
  padding:10px 12px; border:1px solid var(--border); border-radius:8px; background:var(--surface); }
#lysia-root .svc-name{ font:500 14px 'Inter',sans-serif; color:var(--ink); }
#lysia-root .svc-pill{ font:600 11px 'JetBrains Mono',monospace; letter-spacing:.12em; text-transform:uppercase;
  padding:3px 8px; border-radius:999px; }
#lysia-root .svc-pill.svc-up{ color:var(--ready-green); background:color-mix(in oklch,var(--ready-green) 16%,transparent); }
#lysia-root .svc-pill.svc-deg{ color:var(--slate); background:color-mix(in oklch,var(--slate) 18%,transparent); }
#lysia-root .svc-pill.svc-out{ color:var(--bl-terra); background:color-mix(in oklch,var(--bl-terra) 16%,transparent); }
#lysia-root .svc-pct{ font:500 12px 'JetBrains Mono',monospace; color:var(--ink-subtle); }
#lysia-root .uptime{ display:flex; gap:2px; align-items:flex-end; margin-top:6px; }
#lysia-root .uptime i{ width:3px; height:14px; background:var(--ready-green); border-radius:1px; opacity:.85; }
#lysia-root .uptime i.deg{ background:var(--slate); }
#lysia-root .uptime i.out{ background:var(--bl-terra); }

/* Ticket queue + detail */
#lysia-root .tkt-row{ display:grid; grid-template-columns:auto 1fr auto auto; align-items:center; gap:12px;
  padding:11px 12px; border:1px solid var(--border); border-radius:8px; background:var(--surface);
  cursor:pointer; transition:border-color .2s var(--ease), transform .2s var(--ease); width:100%; text-align:left; }
#lysia-root .tkt-row:hover{ border-color:var(--border-strong); transform:translateX(2px); }
#lysia-root .tkt-id{ font:500 12px 'JetBrains Mono',monospace; color:var(--ink-subtle); }
#lysia-root .tkt-subject{ font:500 14px 'Inter',sans-serif; color:var(--ink); }
#lysia-root .tkt-meta{ font:400 12px 'Inter',sans-serif; color:var(--ink-muted); }
#lysia-root .tkt-arrow{ color:var(--ink-subtle); }
#lysia-root .tag-open,
#lysia-root .tag-prog,
#lysia-root .tag-resolved{ font:600 11px 'JetBrains Mono',monospace; letter-spacing:.1em; text-transform:uppercase;
  padding:3px 8px; border-radius:999px; white-space:nowrap; }
#lysia-root .tag-open{ color:var(--accent); background:var(--accent-soft); }
#lysia-root .tag-prog{ color:var(--slate); background:color-mix(in oklch,var(--slate) 18%,transparent); }
#lysia-root .tag-resolved{ color:var(--ready-green); background:color-mix(in oklch,var(--ready-green) 16%,transparent); }

/* Conversation bubbles */
#lysia-root .sup-conv{ display:flex; flex-direction:column; gap:10px; margin:14px 0; }
#lysia-root .bubble{ max-width:78%; padding:10px 12px; border-radius:12px; border:1px solid var(--border); }
#lysia-root .bubble-me{ align-self:flex-end; background:var(--accent-soft); border-color:transparent; }
#lysia-root .bubble-them{ align-self:flex-start; background:var(--surface-raised); }
#lysia-root .bubble-who{ font:600 11px 'Inter',sans-serif; color:var(--ink-subtle); margin-bottom:3px; }
#lysia-root .bubble-body{ font:400 14px 'Inter',sans-serif; color:var(--ink); white-space:pre-wrap; }
#lysia-root .bubble-when{ font:400 11px 'JetBrains Mono',monospace; color:var(--ink-subtle); margin-top:4px; }

/* New-ticket + reply forms */
#lysia-root .sup-form,
#lysia-root .sup-reply-box{ display:flex; flex-direction:column; gap:10px; margin-top:12px; }
#lysia-root .sup-field{ display:flex; flex-direction:column; gap:4px; }
#lysia-root .sup-label{ font:600 12px 'Inter',sans-serif; color:var(--ink-muted); }
#lysia-root .sup-input,
#lysia-root .sup-select,
#lysia-root .sup-textarea{ font:400 14px 'Inter',sans-serif; color:var(--ink); background:var(--surface);
  border:1px solid var(--border-strong); border-radius:8px; padding:8px 10px; }
#lysia-root .sup-textarea{ min-height:96px; resize:vertical; }
#lysia-root .sup-input:focus,
#lysia-root .sup-select:focus,
#lysia-root .sup-textarea:focus{ outline:2px solid var(--accent); outline-offset:1px; }
#lysia-root .sup-form-note{ font:400 12px 'Inter',sans-serif; color:var(--ink-subtle); }
#lysia-root .sup-reply-actions{ display:flex; gap:8px; justify-content:flex-end; }
#lysia-root .sup-detail-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
#lysia-root .sup-detail-row{ display:flex; gap:10px; align-items:center; color:var(--ink-muted);
  font:400 13px 'Inter',sans-serif; margin:4px 0 10px; }

/* Help resources */
#lysia-root .res-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:12px; margin-top:10px; }
#lysia-root .res-card{ padding:12px 14px; border:1px solid var(--border); border-radius:10px;
  background:var(--surface); text-decoration:none; transition:border-color .2s var(--ease); }
#lysia-root .res-card:hover{ border-color:var(--border-strong); }
#lysia-root .res-title{ display:block; font:600 14px 'Inter',sans-serif; color:var(--ink); }
#lysia-root .res-sub{ display:block; font:400 12px 'Inter',sans-serif; color:var(--ink-muted); margin-top:3px; }

/* ---- mode-dependent artwork (2026-07-02) --------------------------------
   · brand marks: slate tile in light, cream tile in dark (the slate tile
     disappeared into dark chrome)
   · ambient grove: raw watercolor in light; in dark, the SAME light asset is
     desaturated + inverted to a faint pale "bones" x-ray (option 3) rather than
     a recolored twin (the -dusk recolors were dropped; only the ghost-dusk
     empty-state swap survives). */
/* Original brand mark restored: slate tile in light, cream tile in dark. */
.brand-mark-light{ display:block; }
.brand-mark-dark{ display:none; }
:root[data-mode="dark"] .brand-mark-light, #lysia-root[data-mode="dark"] .brand-mark-light{ display:none; }
:root[data-mode="dark"] .brand-mark-dark, #lysia-root[data-mode="dark"] .brand-mark-dark{ display:block; }
:root[data-mode="dark"] .grove-light, #lysia-root[data-mode="dark"] .grove-light{
  display:block !important;
  filter:grayscale(1) invert(.9);
  opacity:.07 !important;
}
:root[data-mode="dark"] #lysia-root #surface-exam .pe-empty{ background-image:url("assets/g/sapling-01-ghost-dusk.webp"); }

/* Audit log table */
#lysia-root .aud-controls{ display:flex; align-items:center; gap:10px; margin:14px 0 10px; flex-wrap:wrap; }
#lysia-root .aud-table-box{ overflow-x:auto; }
#lysia-root .aud-table{ width:100%; border-collapse:collapse; font:400 13px 'Inter',sans-serif; }
#lysia-root .aud-table th{ text-align:left; font:600 11px 'JetBrains Mono',monospace; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-subtle); padding:8px 10px; border-bottom:1px solid var(--border-strong); }
#lysia-root .aud-table td{ padding:8px 10px; border-bottom:1px solid var(--border); color:var(--ink);
  vertical-align:top; }

/* ===========================================================================
   D41 consent-acceptance modal (consent.js) — SIBLING of #lysia-root, unscoped
   (.consent-*) like .cancel-modal, so the tokens above resolve on every shell
   (/app, /owner, /teach, /learn all load this file). Built entirely in JS
   (no static markup) since it must work identically across four separate HTML
   shells without duplicating markup in each. z-index sits above the shared
   --z-modal token (falls back to 1300 on shells that don't load themes.css) so
   it always wins over in-shell content; MANDATORY — no veil-click / Esc close.
   =========================================================================== */
.consent-modal{
  position:fixed; inset:0; z-index:var(--z-modal, 1300); display:none;
  align-items:center; justify-content:center; padding:24px;
}
.consent-modal.is-open{ display:flex; }
.consent-veil{
  position:absolute; inset:0; background:rgba(16,22,18,.62);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
.consent-card{
  position:relative; width:min(480px,100%); max-height:calc(100vh - 48px);
  overflow:auto; background:var(--surface); color:var(--ink);
  border:1px solid var(--border); border-radius:22px; padding:30px;
  box-shadow:var(--shadow-3);
}
.consent-eyebrow{
  font:600 10px 'JetBrains Mono',monospace; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent); margin:0;
}
.consent-title{ margin:10px 0 0; font:500 1.6rem/1.12 'Newsreader',Georgia,serif; color:var(--ink); }
.consent-lead{ margin:8px 0 0; font:400 13.5px/1.55 'Inter',sans-serif; color:var(--ink-muted); }
.consent-docs{ list-style:none; margin:18px 0 0; padding:0; display:flex; flex-direction:column; gap:8px; }
.consent-doc-link{
  display:block; font:500 13.5px 'Inter',sans-serif; color:var(--ink-muted);
  background:var(--surface-raised); border:1px solid var(--border-strong);
  border-radius:11px; padding:12px 15px; text-decoration:none;
  transition:border-color .18s var(--ease), color .18s var(--ease);
}
.consent-doc-link:hover, .consent-doc-link:focus-visible{ border-color:var(--accent); color:var(--ink); }
.consent-doc-link:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.consent-checkbox-row{
  display:flex; align-items:flex-start; gap:10px; margin-top:20px; cursor:pointer;
  font:400 13.5px/1.5 'Inter',sans-serif; color:var(--ink);
}
.consent-checkbox{ margin-top:2px; width:16px; height:16px; accent-color:var(--accent); cursor:pointer; }
.consent-err{
  margin:14px 0 0; font:500 13px/1.5 'Inter',sans-serif; color:var(--accent);
}
.consent-actions{ display:flex; align-items:center; justify-content:flex-end; gap:10px; margin-top:22px; }
.consent-btn{
  font:600 13px 'Inter',sans-serif; border-radius:999px; padding:12px 22px; cursor:pointer;
  transition:transform .25s var(--ease-spring), box-shadow .25s var(--ease), border-color .2s var(--ease);
}
.consent-btn-primary{
  color:var(--bg); background:var(--ink); border:1px solid var(--ink);
}
.consent-btn-primary:hover{ transform:translateY(-1px); box-shadow:var(--shadow-2); color:var(--bg); }
.consent-btn-primary:disabled{ opacity:.5; cursor:not-allowed; transform:none; box-shadow:none; }

@media (prefers-reduced-motion: reduce){
  .consent-doc-link, .consent-btn{ transition:none; }
  .consent-btn-primary:hover{ transform:none; }
}
#lysia-root .aud-table tbody tr:hover{ background:var(--surface-raised); }
