/* ===========================================================================
   edu.css - the Education base ("Boardroom"), 2026-10-04. Docs/UI/EDUCATION_BASE.md.

   The look of /Education/ProductLifeCycle, taken out of its own stylesheet so every /Education activity
   shares one copy: tokens, banner + stepper + menus, stage + parts, buttons, cards, KPIs, forms, switches,
   tables, chart tabs, pills, notices, windows, toasts, the About window, Tabulator restyle, focus rings.

   Two ways in, by a class on the activity's root element next to its own root class:
   - "edu-app"   (<div class="plc edu-app" id="plcApp">): the whole Boardroom system, component names included
                 (.btn, .card, .row, .kpi ...: Bootstrap's names, safe because every rule is scoped under .edu-app,
                 one class more specific than Bootstrap, and this file loads after Bootstrap). For activities BUILT
                 on these names: ProductLifeCycle, GatewayThreat, DRCC, RRT, and every new one. Add "edu-hosted"
                 when it runs inside SIOP (the frame is a fixed-height box, so the root scrolls inside it).
   - "edu-theme" (<div class="oil-rig edu-theme">): for an older activity that uses those generic names for its own
                 things. It gets the tokens and the root font and color, every edu-* component (banner, brand,
                 stepper, menus, stage, parts, windows), and edu-* ALIASES of the generic ones (.edu-btn,
                 .edu-btn-primary, .edu-card, .edu-kpis / .edu-kpi, .edu-pill, table.edu-tbl, .edu-notice, .edu-tabs /
                 .edu-tab, .edu-chart, .edu-toggle, .edu-fld, .edu-input, .edu-info-i, .edu-x-close, .edu-muted ...),
                 styled exactly like the originals. The aliases work under .edu-app too.
   Pages that opt in to neither are untouched. The activity's own stylesheet (scoped under its root class, loaded
   after this file) adds or overrides; it re-tints by overriding tokens on its root class. The selector lists are
   generated by Docs/UI/edu_base/theme_aliases.py (re-run it after adding a rule).

   Loaded by Views/Shared/_LayoutEdu.cshtml (bundle ~/Content/edu-ui/css) on every Education page, before any view
   stylesheet: a rule that must beat a LIBRARY stylesheet linked in a view (tabulator.min.css) needs more classes
   than the library's rule. Shared behavior: Scripts/app/edu-ui/edu.ui.js (EduUI). The standalone builds
   (Docs/Education/<name>/build/assemble.py) inline this file ahead of their own CSS.

   Light only. Tokens are the single source of truth: no hex outside the token block.
   =========================================================================== */
.edu-app, .edu-theme {
  /* ---- Palette ---- */
  --bg:          #ffffff;
  --surface:     #f7f8fa;
  --surface-alt: #eef0f4;
  --border:      #d8dce3;
  --text:        #101820;
  --text-muted:  #5c636e;
  --accent:      #0e3a5c;   /* deep navy */
  --accent-soft: #1b5480;
  --accent-hover:#0b2f4a;
  --accent-2:    #c08a2d;   /* bronze */
  --accent-2-soft:#d9a441;
  --accent-2-hover:#a9781f;
  --accent-2-ink:#241a06;   /* text on bronze */
  --positive:    #2e7d5b;
  --negative:    #b2452f;
  --warn:        #b8860b;
  --info:        #4e6e8e;
  --white:       #ffffff;
  --positive-ink:#1e5a41;   /* text on a green / red / amber notice */
  --negative-ink:#7d2f1f;
  --warn-ink:    #7a5a06;
  --series-violet:#7a4fa8;
  --series-steel: #3a6ea5;
  --series-teal:  #17706e;
  --series-orange:#ef7d1a;
  /* ---- Banner (navy gradient) ---- */
  --banner-top:  #0e3a5c;
  --banner-bot:  #0b2f4a;
  --banner-ink:  #eaf1f7;
  --banner-sub:  #9db9cf;
  --banner-tagline: #8fa8bd; /* about 4.7:1 on the navy; one step quieter than --banner-sub */
  --banner-shadow: rgba(14,58,92,.22);
  --step-ink:    #b7cadb;
  --step-ring:   #6d8aa4;
  --step-sep:    #47617c;
  --step-active-ring: rgba(217,164,65,.6);
  /* ---- Chart palette + phase colors (read by each activity's ECharts theme through getComputedStyle) ---- */
  --chart-1: var(--accent);       /* navy   */
  --chart-2: var(--accent-2);     /* bronze */
  --chart-3: var(--positive);     /* green  */
  --chart-4: var(--series-violet);/* violet */
  --chart-5: var(--negative);     /* red    */
  --chart-6: var(--info);         /* steel-muted */
  --chart-7: var(--accent-2-soft);/* light bronze */
  --chart-8: var(--series-steel); /* steel  */
  --phase-intro:   var(--series-steel);
  --phase-launch:  var(--positive);
  --phase-mature:  #a9781f;
  --phase-decline: var(--negative);
  --phase-intro-bg:   #eef3f8;
  --phase-launch-bg:  #eaf5ef;
  --phase-mature-bg:  #f6efe1;
  --phase-decline-bg: #f7ece9;
  /* ---- Type (self-hosted: Content/fonts/edu-fonts.css) ---- */
  --font-display: "Libre Franklin", "Segoe UI", system-ui, sans-serif;
  --font-body:    "Libre Franklin", "Segoe UI", system-ui, sans-serif;
  --font-data:    "Spline Sans Mono", "Cascadia Mono", ui-monospace, monospace;
  /* ---- Geometry ---- */
  --radius: 8px;
  --radius-sm: 5px;
  --density: 10px 16px;
  --gap: 22px;
  --gap-sm: 12px;

  font-family: var(--font-body);
  color: var(--text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
/* the page box: .edu-app only (an .edu-theme activity keeps its own) */
.edu-app {
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.edu-app *, .edu-app *::before, .edu-app *::after { box-sizing: border-box; }
/* Hosted in SIOP: the frame (_LayoutEdu) gives the activity a fixed-height overflow:hidden box, so the root
   fills it and scrolls inside instead of growing past 100vh. Added by the SIOP view only (never standalone). */
.edu-app.edu-hosted { height: 100%; min-height: 0; overflow-y: auto; overflow-x: hidden; }

/* ===== Banner (signature element): brand | stepper | menus ===== */
.edu-app .edu-banner,
.edu-theme .edu-banner {
  background: linear-gradient(180deg, var(--banner-top) 0%, var(--banner-bot) 100%);
  color: var(--banner-ink);
  padding: 10px 22px;
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
  box-shadow: 0 2px 10px var(--banner-shadow);
  position: sticky; top: 0; z-index: 40;
}
/* The brand is a baseline-aligned flex row (wordmark + sub-title share one line) that wraps, so the tagline
   takes a full line under them. A wrapping flex row sizes itself as if its items sat on one line, so it is
   capped; the tagline wraps inside the cap if it must. */
/* Selectors here stay at two classes (.edu-app + the component) wherever they can, so an activity overrides one
   with ".<root> .<component>" and wins by load order alone. */
.edu-app .edu-brand,
.edu-theme .edu-brand { display: flex; align-items: baseline; gap: 10px; white-space: nowrap; flex-wrap: wrap; max-width: 380px; }
.edu-app .edu-logo,
.edu-theme .edu-logo {
  font-family: var(--font-display); font-weight: 800; font-size: 20px; letter-spacing: -.4px;
  color: var(--white);
}
.edu-app .edu-logo .tm,
.edu-theme .edu-logo .tm { font-size: 11px; vertical-align: super; color: var(--accent-2-soft); }
.edu-app .edu-sub,
.edu-theme .edu-sub { font-size: 12px; color: var(--banner-sub); font-family: var(--font-data); }
.edu-app .edu-tagline,
.edu-theme .edu-tagline {
  flex: 0 0 100%;            /* own line, under the wordmark + sub-title */
  white-space: normal;
  font-size: 11px; line-height: 1.25;
  color: var(--banner-tagline);
  margin: 2px 0 0;
}
/* The .edu-theme activities' banners (no stepper: brand + a few controls): the brand is a two-row grid, wordmark and
   sub-title side by side, the tagline under both, as wide as the longer of the two rows. The 380px cap above exists for
   a banner that also holds a stepper (.edu-app: ProductLifeCycle, GatewayThreat); under it a long name pushed the
   sub-title onto a line of its own and the banner grew a third line (James, 2026-10-05: the Stochastic Assembly and
   M/M/s banners "too thick", OilRig's "the correct height"). */
.edu-theme .edu-brand {
  display: grid; grid-template-columns: auto auto; justify-content: start; align-items: baseline;
  column-gap: 10px; row-gap: 10px; max-width: none;
}
.edu-theme .edu-brand .edu-tagline { grid-column: 1 / -1; }

/* stepper: the exercise parts. It never shrinks below its content: when the banner is too narrow the menus
   wrap to a second line (right-aligned) instead of being covered. */
.edu-app .edu-stepper,
.edu-theme .edu-stepper { display: flex; align-items: center; gap: 4px; flex: 1; min-width: max-content; }
.edu-app .edu-step,
.edu-theme .edu-step {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: var(--radius);
  color: var(--step-ink); cursor: pointer; border: 1px solid transparent; white-space: nowrap;
  font-size: 13px; transition: background .15s, color .15s;
  background: none; font-family: var(--font-body);   /* a step may be a <button> */
}
.edu-app .edu-step:hover,
.edu-theme .edu-step:hover { background: rgba(255,255,255,.08); color: var(--banner-ink); }
.edu-app .edu-step.active,
.edu-theme .edu-step.active { background: rgba(255,255,255,.14); color: var(--white); border-color: var(--step-active-ring); }
.edu-app .edu-step.done .edu-step-num,
.edu-theme .edu-step.done .edu-step-num { background: var(--accent-2); border-color: var(--accent-2); color: var(--accent-2-ink); }
.edu-app .edu-step .edu-step-num,
.edu-theme .edu-step .edu-step-num {
  width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--step-ring);
  display: grid; place-items: center; font-family: var(--font-data); font-size: 12px; font-weight: 600;
}
.edu-app .edu-step.active .edu-step-num,
.edu-theme .edu-step.active .edu-step-num { background: var(--white); color: var(--accent); border-color: var(--white); }
.edu-app .edu-step-sep,
.edu-theme .edu-step-sep { color: var(--step-sep); }
@media (max-width: 1800px) {
  .edu-app .edu-step,
  .edu-theme .edu-step { padding: 6px 8px; gap: 6px; font-size: 12.5px; }
}

.edu-app .edu-banner-right,
.edu-theme .edu-banner-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* ===== Buttons ===== */
.edu-app .btn,
.edu-app .edu-btn,
.edu-theme .edu-btn {
  font-family: var(--font-body); font-weight: 600; font-size: 13px;
  padding: 8px 15px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text); cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, box-shadow .15s;
}
.edu-app .btn:hover,
.edu-app .edu-btn:hover,
.edu-theme .edu-btn:hover { background: var(--surface-alt); }
.edu-app .btn:focus-visible,
.edu-app .edu-btn:focus-visible,
.edu-theme .edu-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.edu-app .btn:focus,
.edu-app .edu-btn:focus,
.edu-theme .edu-btn:focus { box-shadow: none; }  /* no Bootstrap focus halo (the outline above is the focus ring) */
.edu-app .btn-primary,
.edu-app .edu-btn-primary,
.edu-theme .edu-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--white); }
.edu-app .btn-primary:hover,
.edu-app .edu-btn-primary:hover,
.edu-theme .edu-btn-primary:hover { background: var(--accent-hover); }
.edu-app .btn-accent,
.edu-app .edu-btn-accent,
.edu-theme .edu-btn-accent { background: var(--accent-2); border-color: var(--accent-2); color: var(--accent-2-ink); }
.edu-app .btn-accent:hover,
.edu-app .edu-btn-accent:hover,
.edu-theme .edu-btn-accent:hover { background: var(--accent-2-hover); color: var(--white); }
.edu-app .btn-ghost,
.edu-app .edu-btn-ghost,
.edu-theme .edu-btn-ghost { background: transparent; border-color: rgba(255,255,255,.35); color: var(--banner-ink); }
.edu-app .btn-ghost:hover,
.edu-app .edu-btn-ghost:hover,
.edu-theme .edu-btn-ghost:hover { background: rgba(255,255,255,.1); }
.edu-app .btn-sm,
.edu-app .edu-btn-sm,
.edu-theme .edu-btn-sm { padding: 5px 10px; font-size: 12px; }
.edu-app .btn-xs,
.edu-app .edu-btn-xs,
.edu-theme .edu-btn-xs { padding: 3px 7px; font-size: 11px; }
.edu-app .btn:disabled,
.edu-app .edu-btn:disabled,
.edu-theme .edu-btn:disabled { opacity: .45; cursor: not-allowed; }
.edu-app .btn-danger,
.edu-app .edu-btn-danger,
.edu-theme .edu-btn-danger { background: var(--negative); border-color: var(--negative); color: var(--white); }

/* ===== Banner menus (Scenario / Domain / Actions): button + .edu-menu, one open at a time ===== */
.edu-app .edu-menu-wrap,
.edu-theme .edu-menu-wrap { position: relative; }
.edu-app .edu-menu,
.edu-theme .edu-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  background: var(--white); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius);
  min-width: 250px; box-shadow: 0 12px 34px rgba(16,24,32,.22); padding: 6px;
  /* opens just under the banner, so 72vh always fits; scroll rather than clip a long list */
  max-height: 72vh; overflow-y: auto; overflow-x: hidden;
  /* shrink-to-fit on its content: capped so one long option does not stretch the menu */
  max-width: min(420px, 92vw);
}
.edu-app .edu-menu.open,
.edu-theme .edu-menu.open { display: block; }
.edu-app .edu-menu-field,
.edu-theme .edu-menu-field { padding: 2px 10px 6px; }
.edu-app select.edu-menu-select { width: 100%; max-width: 100%; text-overflow: ellipsis; }
.edu-app .edu-menu-item,
.edu-theme .edu-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 8px 10px; border: none; background: none; border-radius: var(--radius-sm);
  font-size: 13px; color: var(--text); cursor: pointer;
}
.edu-app .edu-menu-item:hover,
.edu-theme .edu-menu-item:hover { background: var(--surface-alt); }
.edu-app .edu-menu-item.active,
.edu-theme .edu-menu-item.active { background: rgba(14,58,92,.08); font-weight: 600; }
.edu-app .edu-menu-sep,
.edu-theme .edu-menu-sep { height: 1px; background: var(--border); margin: 5px 4px; }
.edu-app .edu-menu-head,
.edu-theme .edu-menu-head { font-size: 11px; text-transform: uppercase; letter-spacing: .6px; color: var(--text-muted); padding: 6px 10px 2px; }
/* a two-line item (label + small note): .edu-menu-item is a centered flex row, so the pair is a nested column */
.edu-app .edu-menu-2l,
.edu-theme .edu-menu-2l { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; }
.edu-app .edu-menu-note,
.edu-theme .edu-menu-note { font-size: 10.5px; line-height: 1.25; color: var(--text-muted); font-family: var(--font-data); }

/* ===== Stage + parts ===== */
.edu-app .edu-stage,
.edu-theme .edu-stage { flex: 1; padding: var(--gap); max-width: 1500px; width: 100%; margin: 0 auto; }
.edu-app .edu-part,
.edu-theme .edu-part { display: none; }
.edu-app .edu-part.active,
.edu-theme .edu-part.active { display: block; animation: edu-fade .25s ease; }
@keyframes edu-fade { from { opacity: 0; transform: translateY(4px);} to {opacity:1; transform:none;} }

.edu-app .edu-part-head,
.edu-theme .edu-part-head { margin-bottom: calc(var(--gap) / 2); }
.edu-app .edu-part-head .kicker,
.edu-theme .edu-part-head .kicker { font-family: var(--font-data); font-size: 12px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--accent-2); }
/* the active student email, right-justified on the kicker line (hosted only) */
.edu-app .edu-part-head > .kicker,
.edu-theme .edu-part-head > .kicker { display: flex; align-items: baseline; }
.edu-app .part-email { margin-left: auto; text-transform: none; letter-spacing: normal;
  color: var(--text-muted); font-weight: 400; white-space: nowrap; }
.edu-app .edu-part-head h1,
.edu-theme .edu-part-head h1 { font-family: var(--font-display); font-weight: 800; font-size: 27px; margin: 2px 0 4px; letter-spacing: -.5px; }
.edu-app .edu-part-head p.lead,
.edu-theme .edu-part-head p.lead { color: var(--text-muted); max-width: 74ch; margin: 0; font-size: 13px; }

/* ===== Cards + layout ===== */
.edu-app .card,
.edu-app .edu-card,
.edu-theme .edu-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px 18px 9px;
}
.edu-app .card.tight,
.edu-app .edu-card.tight,
.edu-theme .edu-card.tight { padding: 12px; }
.edu-app .card h3,
.edu-app .edu-card h3,
.edu-theme .edu-card h3 { font-family: var(--font-display); font-weight: 700; font-size: 15px; margin: 0 0 10px; }
.edu-app .card h3 .h3-note,
.edu-app .edu-card h3 .h3-note,
.edu-theme .edu-card h3 .h3-note { font-weight: 400; font-size: 12px; color: var(--text-muted); font-family: var(--font-body); }
.edu-app .grid,
.edu-app .edu-grid,
.edu-theme .edu-grid { display: grid; gap: var(--gap); }
.edu-app .grid-2,
.edu-app .edu-grid-2,
.edu-theme .edu-grid-2 { grid-template-columns: 1fr 1fr; }
.edu-app .grid-3,
.edu-app .edu-grid-3,
.edu-theme .edu-grid-3 { grid-template-columns: repeat(3, 1fr); }
/* margin:0 neutralizes Bootstrap's .row negative margins */
.edu-app .row,
.edu-app .edu-row,
.edu-theme .edu-row { display: flex; gap: var(--gap-sm); flex-wrap: wrap; align-items: flex-start; margin: 0; }
.edu-app .spread,
.edu-app .edu-spread,
.edu-theme .edu-spread { display: flex; justify-content: space-between; align-items: center; gap: 12px; }

/* ===== Reading layout (case pages): prose + sticky "At a glance" aside ===== */
.edu-app .edu-read,
.edu-theme .edu-read { display: grid; grid-template-columns: minmax(0,1.7fr) minmax(260px,1fr); gap: var(--gap); }
.edu-app .edu-read-main,
.edu-theme .edu-read-main { min-width: 0; }
.edu-app .edu-read .prose,
.edu-theme .edu-read .prose { font-size: 15px; }
.edu-app .edu-read .prose h2,
.edu-theme .edu-read .prose h2 { font-family: var(--font-display); font-weight: 800; font-size: 19px; margin: 22px 0 8px; }
.edu-app .edu-read .prose h2:first-child,
.edu-theme .edu-read .prose h2:first-child { margin-top: 0; }
.edu-app .edu-read .prose p,
.edu-theme .edu-read .prose p { margin: 0 0 12px; }
.edu-app .edu-read .prose .drop::first-letter,
.edu-theme .edu-read .prose .drop::first-letter { font-family: var(--font-display); font-weight:800; font-size:52px;
  float:left; line-height:.8; padding: 4px 8px 0 0; color: var(--accent); }
.edu-app .edu-aside,
.edu-theme .edu-aside { position: sticky; top: 78px; align-self: start; }
.edu-app .fact,
.edu-app .edu-fact,
.edu-theme .edu-fact { border-left: 3px solid var(--accent-2); padding: 3px 0 3px 10px; margin-bottom: 7px; display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.edu-app .fact .k,
.edu-app .edu-fact .k,
.edu-theme .edu-fact .k { font-family: var(--font-data); font-size: 11px; text-transform: uppercase; letter-spacing:.5px; color: var(--text-muted); white-space: nowrap; flex-shrink: 0; }
.edu-app .fact .v,
.edu-app .edu-fact .v,
.edu-theme .edu-fact .v { font-family: var(--font-display); font-weight: 700; font-size: 13px; text-align: right; }

/* ===== KPI tiles ===== */
.edu-app .kpis,
.edu-app .edu-kpis,
.edu-theme .edu-kpis { display: grid; grid-template-columns: repeat(auto-fit,minmax(140px,1fr)); gap: var(--gap-sm); }
.edu-app .kpi,
.edu-app .edu-kpi,
.edu-theme .edu-kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 6px 14px; }
.edu-app .kpi .kpi-label,
.edu-app .edu-kpi .kpi-label,
.edu-theme .edu-kpi .kpi-label { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-muted); }
.edu-app .kpi .kpi-val,
.edu-app .edu-kpi .kpi-val,
.edu-theme .edu-kpi .kpi-val { font-family: var(--font-data); font-weight: 600; font-size: 22px; line-height: 1.15; margin-top: 3px;
  font-variant-numeric: tabular-nums; }
.edu-app .kpi .kpi-sub,
.edu-app .edu-kpi .kpi-sub,
.edu-theme .edu-kpi .kpi-sub { font-size: 11px; color: var(--text-muted); font-family: var(--font-data); margin-top: 2px; }
.edu-app .kpi.good .kpi-val,
.edu-app .edu-kpi.good .kpi-val,
.edu-theme .edu-kpi.good .kpi-val { color: var(--positive); }
.edu-app .kpi.bad .kpi-val,
.edu-app .edu-kpi.bad .kpi-val,
.edu-theme .edu-kpi.bad .kpi-val { color: var(--negative); }
.edu-app .kpi.accent,
.edu-app .edu-kpi.accent,
.edu-theme .edu-kpi.accent { border-color: var(--accent-2); }

/* ===== Forms ===== */
.edu-app label.fld,
.edu-theme label.edu-fld { display: block; font-size: 12px; color: var(--text-muted); margin-bottom: 3px; }
.edu-app input[type=number],
.edu-app input[type=text],
.edu-app select,
.edu-app .edu-input,
.edu-theme .edu-input {
  font-family: var(--font-data); font-size: 13px; padding: 7px 9px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--white); color: var(--text); width: 100%;
  font-variant-numeric: tabular-nums;
}
.edu-app input:focus,
.edu-app select:focus,
.edu-app .edu-input:focus,
.edu-theme .edu-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(14,58,92,.12); }
/* compact select (inline pickers) */
.edu-app select.edu-select { width: auto; padding: 5px 8px; font-size: 12px; }
.edu-app input[type=range],
.edu-theme input[type=range].edu-input { width: 100%; accent-color: var(--accent); }
.edu-app .fld-grid,
.edu-app .edu-fld-grid,
.edu-theme .edu-fld-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(120px,1fr)); gap: 10px; }

/* switches: <label class="toggle" role="switch" tabindex="0"><span class="sw"></span> text</label>, .on = checked */
.edu-app .toggle,
.edu-app .edu-toggle,
.edu-theme .edu-toggle { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; }
.edu-app .toggle .sw,
.edu-app .edu-toggle .sw,
.edu-theme .edu-toggle .sw { width: 36px; height: 20px; border-radius: 999px; background: var(--border); position: relative; transition: background .15s; flex: none; }
.edu-app .toggle .sw::after,
.edu-app .edu-toggle .sw::after,
.edu-theme .edu-toggle .sw::after { content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background: var(--white); transition:transform .15s; box-shadow:0 1px 2px rgba(0,0,0,.25); }
.edu-app .toggle.on .sw,
.edu-app .edu-toggle.on .sw,
.edu-theme .edu-toggle.on .sw { background: var(--accent); }
.edu-app .toggle.on .sw::after,
.edu-app .edu-toggle.on .sw::after,
.edu-theme .edu-toggle.on .sw::after { transform: translateX(16px); }

/* ===== Plain tables (Tabulator for real grids) ===== */
.edu-app table.tbl,
.edu-theme table.edu-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.edu-app table.tbl th,
.edu-app table.tbl td,
.edu-theme table.edu-tbl th,
.edu-theme table.edu-tbl td { padding: 7px 10px; border-bottom: 1px solid var(--border); text-align: left; }
.edu-app table.tbl.compact th,
.edu-app table.tbl.compact td,
.edu-theme table.edu-tbl.compact th,
.edu-theme table.edu-tbl.compact td { padding: 2px 8px; }
.edu-app table.tbl.compact,
.edu-theme table.edu-tbl.compact { font-size: 12px; }
.edu-app table.tbl th,
.edu-theme table.edu-tbl th { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-muted); font-weight: 600; }
.edu-app table.tbl td.num,
.edu-app table.tbl th.num,
.edu-theme table.edu-tbl td.edu-num,
.edu-theme table.edu-tbl th.edu-num { text-align: right; font-family: var(--font-data); font-variant-numeric: tabular-nums; }
/* centered variant: every column but the left-aligned label column is centered */
.edu-app table.tbl.tbl-center td.num,
.edu-app table.tbl.tbl-center th.num,
.edu-theme table.edu-tbl.tbl-center td.edu-num,
.edu-theme table.edu-tbl.tbl-center th.edu-num { text-align: center; }
.edu-app table.tbl.tbl-center td.num input,
.edu-theme table.edu-tbl.tbl-center td.edu-num input { text-align: center; }
.edu-app table.tbl tr:hover td,
.edu-theme table.edu-tbl tr:hover td { background: var(--surface-alt); }

/* ===== Chart tabs + chart areas ===== */
.edu-app .chart-tabs,
.edu-app .edu-tabs,
.edu-theme .edu-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 10px; flex-wrap: wrap; align-items: center; }
.edu-app .chart-tab,
.edu-app .edu-tab,
.edu-theme .edu-tab { padding: 7px 9px; font-size: 12.5px; white-space: nowrap; color: var(--text-muted); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.edu-app .chart-tab.active,
.edu-app .edu-tab.active,
.edu-theme .edu-tab.active { color: var(--accent); border-bottom-color: var(--accent-2); font-weight: 600; }
.edu-app .chart-box,
.edu-app .edu-chart,
.edu-theme .edu-chart { width: 100%; height: 320px; }
.edu-app .chart-box.tall,
.edu-app .edu-chart.tall,
.edu-theme .edu-chart.tall { height: 380px; }
.edu-app .chart-box.short,
.edu-app .edu-chart.short,
.edu-theme .edu-chart.short { height: 220px; }

/* ===== Multi-select checklist ===== */
.edu-app .checklist { display: grid; grid-template-columns: repeat(auto-fit,minmax(150px,1fr)); gap: 6px; }
.edu-app .chk {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; font-size: 13px; background: var(--white);
}
.edu-app .chk:hover { background: var(--surface-alt); }
.edu-app .chk input { width: auto; accent-color: var(--accent); }
.edu-app .chk .swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.edu-app .chk.sel { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

/* ===== Pills / badges ===== */
.edu-app .pill,
.edu-app .edu-pill,
.edu-theme .edu-pill { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-family: var(--font-data);
  background: var(--surface-alt); color: var(--text-muted); border: 1px solid var(--border); }
.edu-app .pill.good,
.edu-app .edu-pill.good,
.edu-theme .edu-pill.good { color: var(--positive); border-color: var(--positive); background: rgba(46,125,91,.08); }
.edu-app .pill.bad,
.edu-app .edu-pill.bad,
.edu-theme .edu-pill.bad { color: var(--negative); border-color: var(--negative); background: rgba(178,69,47,.08); }
.edu-app .pill.phase-intro,
.edu-app .edu-pill.phase-intro,
.edu-theme .edu-pill.phase-intro { background: var(--phase-intro-bg); color: var(--phase-intro); }
.edu-app .pill.phase-launch,
.edu-app .edu-pill.phase-launch,
.edu-theme .edu-pill.phase-launch { background: var(--phase-launch-bg); color: var(--phase-launch); }
.edu-app .pill.phase-mature,
.edu-app .edu-pill.phase-mature,
.edu-theme .edu-pill.phase-mature { background: var(--phase-mature-bg); color: var(--phase-mature); }
.edu-app .pill.phase-decline,
.edu-app .edu-pill.phase-decline,
.edu-theme .edu-pill.phase-decline { background: var(--phase-decline-bg); color: var(--phase-decline); }

/* ===== Notices ===== */
.edu-app .banner-msg,
.edu-app .edu-notice,
.edu-theme .edu-notice { border-radius: var(--radius); padding: 10px 14px; font-size: 13px; line-height: 1.5; }
.edu-app .banner-msg.warn,
.edu-app .edu-notice.warn,
.edu-theme .edu-notice.warn { background: rgba(184,134,11,.1); border: 1px solid var(--warn); color: var(--warn-ink); }
.edu-app .banner-msg.ok,
.edu-app .edu-notice.ok,
.edu-theme .edu-notice.ok { background: rgba(46,125,91,.1); border: 1px solid var(--positive); color: var(--positive-ink); }
.edu-app .banner-msg.bad,
.edu-app .edu-notice.bad,
.edu-theme .edu-notice.bad { background: rgba(178,69,47,.1); border: 1px solid var(--negative); color: var(--negative-ink); }

/* ===== Windows =====
   edu-modal*, never Bootstrap's .modal: Bootstrap's .modal { display:none; position:fixed } would collapse the
   box while the overlay still darkens the page. */
.edu-app .edu-modal-overlay,
.edu-theme .edu-modal-overlay { display: none; position: fixed; inset: 0; background: rgba(16,24,32,.5); z-index: 100; align-items: center; justify-content: center; padding: 20px; }
.edu-app .edu-modal-overlay.open,
.edu-theme .edu-modal-overlay.open { display: flex; }
.edu-app .edu-modal,
.edu-theme .edu-modal { display: block; position: static; background: var(--white); border-radius: var(--radius); max-width: 620px; width: 100%; max-height: 86vh; overflow: auto; box-shadow: 0 24px 60px rgba(0,0,0,.3); }
.edu-app .edu-modal-head,
.edu-theme .edu-modal-head { padding: 16px 20px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; cursor: move; user-select: none; }
/* see-through mode: transparent, click-through backdrop so a chart behind the window stays visible and usable */
.edu-app .edu-modal-overlay.see-through,
.edu-theme .edu-modal-overlay.see-through { background: transparent; pointer-events: none; }
.edu-app .edu-modal-overlay.see-through .edu-modal,
.edu-theme .edu-modal-overlay.see-through .edu-modal { pointer-events: auto; box-shadow: 0 10px 40px rgba(0,0,0,.45); }
.edu-app .edu-modal-head h3,
.edu-theme .edu-modal-head h3 { margin: 0; font-family: var(--font-display); font-weight: 800; font-size: 17px; }
.edu-app .edu-modal-body,
.edu-theme .edu-modal-body { padding: 20px; }
.edu-app .edu-modal-foot,
.edu-theme .edu-modal-foot { padding: 14px 20px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 10px; }
.edu-app .x-close,
.edu-app .edu-x-close,
.edu-theme .edu-x-close { background: none; border: none; font-size: 20px; line-height: 1; cursor: pointer; color: var(--text-muted); }

/* small round "i" that opens an explanation window */
.edu-app a.info-i,
.edu-theme a.edu-info-i { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border-radius: 50%; border: 1.5px solid var(--accent); color: var(--accent); font-family: "Libre Franklin", serif; font-style: italic; font-weight: 700; font-size: 10px; line-height: 1; text-decoration: none; vertical-align: middle; cursor: pointer; }
.edu-app a.info-i:hover,
.edu-theme a.edu-info-i:hover { background: var(--accent); color: var(--white); }
.edu-app .info-i,
.edu-app .edu-info-i,
.edu-theme .edu-info-i { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border-radius: 50%; border: 1.5px solid var(--accent); color: var(--accent); font-family: "Libre Franklin", serif; font-style: italic; font-weight: 700; font-size: 10px; line-height: 1; vertical-align: middle; }

/* ===== About & credits window (Actions > About & credits) ===== */
.edu-app .about-modal { text-align:center; padding:2px 4px 4px; }
.edu-app .about-emblem svg { display:block; margin:0 auto 12px; filter: drop-shadow(0 4px 10px rgba(11,47,76,.22)); }
.edu-app .about-name { font-family:var(--font-display); font-weight:800; font-size:30px; letter-spacing:.4px; color:var(--accent); line-height:1; }
.edu-app .about-name .tm { font-size:12px; vertical-align:super; font-weight:600; margin-left:1px; }
.edu-app .about-tagline { font-family:var(--font-display); font-weight:600; font-size:14px; color:var(--accent-2); letter-spacing:.6px; margin-top:4px; text-transform:uppercase; }
.edu-app .about-desc { font-size:13px; color:var(--text-muted); max-width:460px; margin:12px auto 0; line-height:1.55; }
.edu-app .about-rule { height:1px; background:linear-gradient(90deg,transparent,var(--border),transparent); margin:18px auto 16px; max-width:340px; }
.edu-app .about-credits-head { font-size:10.5px; text-transform:uppercase; letter-spacing:1.4px; color:var(--text-muted); margin-bottom:12px; }
.edu-app .about-people { display:flex; flex-direction:row; justify-content:center; gap:46px; flex-wrap:wrap; }
.edu-app .about-person { min-width:188px; }
.edu-app .about-person .about-pn { font-family:var(--font-display); font-weight:700; font-size:15.5px; color:var(--text); }
.edu-app .about-person .about-inst { font-size:11.5px; color:var(--text-muted); font-style:italic; margin-top:1px; }
.edu-app .about-person .about-pc { font-size:13px; margin-top:3px; font-family:var(--font-data); color:var(--text-muted); }
.edu-app .about-person .about-pc a { color:var(--accent); text-decoration:none; font-weight:500; }
.edu-app .about-person .about-pc a:hover { text-decoration:underline; }
.edu-app .about-dot { color:var(--border); margin:0 3px; }
.edu-app .about-star { color:var(--accent-2); font-weight:700; }
.edu-app .about-note { font-size:11.5px; color:var(--text-muted); font-style:italic; margin:16px auto 2px; max-width:410px; line-height:1.5; }

/* ===== Small helpers ===== */
.edu-app .muted,
.edu-app .edu-muted,
.edu-theme .edu-muted { color: var(--text-muted); }
.edu-app .mono,
.edu-app .edu-mono,
.edu-theme .edu-mono { font-family: var(--font-data); font-variant-numeric: tabular-nums; }
.edu-app .num,
.edu-app .edu-num,
.edu-theme .edu-num { font-family: var(--font-data); font-variant-numeric: tabular-nums; text-align: right; }
.edu-app .good,
.edu-app .edu-good,
.edu-theme .edu-good { color: var(--positive); }
.edu-app .bad,
.edu-app .edu-bad,
.edu-theme .edu-bad { color: var(--negative); }
.edu-app .sec-gap,
.edu-app .edu-sec-gap,
.edu-theme .edu-sec-gap { margin-top: var(--gap); }
.edu-app hr.sep { border: none; border-top: 1px solid var(--border); margin: var(--gap) 0; }
.edu-app .legend-dot,
.edu-app .edu-legend-dot,
.edu-theme .edu-legend-dot { display:inline-block; width:10px; height:10px; border-radius:2px; margin-right:5px; vertical-align:middle; }

/* ===== Tabulator restyle =====
   This file loads in the page head, BEFORE tabulator.min.css (which an activity links in its view), so on a tie the
   library wins: every rule below must be MORE specific than Tabulator's rule for the same property (its header
   column rule is ".tabulator .tabulator-header .tabulator-col", three classes). */
.edu-app .tabulator { border: 1px solid var(--border); border-radius: var(--radius); font-family: var(--font-body); font-size: 13px; background: var(--white); }
.edu-app .tabulator .tabulator-header { background: var(--surface-alt); border-bottom: 1px solid var(--border); }
.edu-app .tabulator .tabulator-header .tabulator-col { background: var(--surface-alt); border-right: 1px solid var(--border); }
.edu-app .tabulator .tabulator-col-title { font-size: 11px; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); font-weight: 600; }
.edu-app .tabulator-row { border-bottom: 1px solid var(--border); }
.edu-app .tabulator-row.tabulator-row-even { background: var(--surface); }
.edu-app .tabulator-row:hover { background: var(--surface-alt) !important; }
.edu-app .tabulator .tabulator-cell { border-right: 1px solid var(--border); }
.edu-app .tabulator .tabulator-cell.num { font-family: var(--font-data); font-variant-numeric: tabular-nums; }

/* ===== Narrow screens ===== */
@media (max-width: 1024px) {
  .edu-app .grid-2,
  .edu-app .grid-3,
  .edu-app .edu-grid-2,
  .edu-theme .edu-grid-2,
  .edu-app .edu-grid-3,
  .edu-theme .edu-grid-3 { grid-template-columns: 1fr; }
  .edu-app .edu-read,
  .edu-theme .edu-read { grid-template-columns: 1fr; }
  .edu-app .edu-aside,
  .edu-theme .edu-aside { position: static; }
}
/* ===== Accessibility: keyboard focus + reduced motion ===== */
.edu-app .edu-step:focus-visible,
.edu-app .edu-menu-item:focus-visible,
.edu-app .chart-tab:focus-visible,
.edu-app .toggle:focus-visible,
.edu-app .chk:focus-visible,
.edu-app .x-close:focus-visible,
.edu-app [role="switch"]:focus-visible,
.edu-app a:focus-visible,
.edu-theme .edu-step:focus-visible,
.edu-theme .edu-menu-item:focus-visible,
.edu-app .edu-tab:focus-visible,
.edu-theme .edu-tab:focus-visible,
.edu-app .edu-toggle:focus-visible,
.edu-theme .edu-toggle:focus-visible,
.edu-app .edu-x-close:focus-visible,
.edu-theme .edu-x-close:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.edu-app input:focus-visible,
.edu-app select:focus-visible,
.edu-app .edu-input:focus-visible,
.edu-theme .edu-input:focus-visible {
  outline: 2px solid var(--accent-2); outline-offset: 1px;
}
.edu-app .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@media (prefers-reduced-motion: reduce) {
  .edu-app .edu-part.active,
  .edu-theme .edu-part.active { animation: none; }
  .edu-app .toast,
  .edu-app .edu-toast,
  .edu-theme .edu-toast { animation: none; }
  .edu-app *, .edu-app *::before, .edu-app *::after { transition: none !important; animation-duration: .001ms !important; }
}

/* ===== Toasts (bottom center, aria-live) ===== */
.edu-app .toast-wrap,
.edu-app .edu-toast-wrap,
.edu-theme .edu-toast-wrap { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 200; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.edu-app .toast,
.edu-app .edu-toast,
.edu-theme .edu-toast { background: var(--accent); color: var(--white); padding: 10px 18px; border-radius: var(--radius); font-size: 13px; box-shadow: 0 8px 24px rgba(0,0,0,.25); animation: edu-fade .2s ease; }
.edu-app .toast.accent,
.edu-app .edu-toast.accent,
.edu-theme .edu-toast.accent { background: var(--accent-2); color: var(--accent-2-ink); }
.edu-app .toast.bad,
.edu-app .edu-toast.bad,
.edu-theme .edu-toast.bad { background: var(--negative); }

/* ===== Session: the student email prompt (Actions > Enter your email...) ===== */
.edu-app input[type=email],
.edu-app input[type=datetime-local],
.edu-app .edu-input,
.edu-theme .edu-input {
  font-family: var(--font-data); font-size: 13px; padding: 7px 9px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--white); color: var(--text);
}
.edu-app .edu-email-prompt .pep-lead,
.edu-theme .edu-email-prompt .pep-lead { font-size: 14px; line-height: 1.55; margin: 0 0 14px; }
.edu-app .edu-email-prompt .pep-label,
.edu-theme .edu-email-prompt .pep-label { display: block; font-size: 12px; color: var(--text-muted); margin-bottom: 4px; }
.edu-app .edu-email-prompt .pep-input,
.edu-theme .edu-email-prompt .pep-input { width: 100%; font-size: 15px; padding: 10px 12px; }
.edu-app .edu-email-prompt .pep-err,
.edu-theme .edu-email-prompt .pep-err { display: none; margin-top: 8px; font-size: 12.5px; color: var(--negative); }
