/* (c) 2026 Nodus. Original work. Reproduction without permission is prohibited. */
/* Nodus app (login + stubs). Same dark navy/blue/gold palette as the landing page. */

:root {
  --bg:         #0d1424;
  --surface:    #151f38;
  --raise:      #1b2743;   /* Calm Ledger: the lifted surface (active nav, insets) */
  --field:      #0b1120;
  --border:     #25324e;
  --text:       #f4f6fa;
  --text-muted: #9db0cf;
  --blue:       #2563c4;
  --blue-hover: #2f72de;
  --gold:       #c9a24a;
  --danger:     #e89393;  /* calm, desaturated red for error text */
  --sidebar-bg: #0c1322;
  --topbar-bg:  rgba(15, 23, 41, 0.92);

  /* calendar/timetable accents (theme-aware) */
  --off-bg:  rgba(224,107,107,0.18);  --off-fg: #f0a8a8;  --off-bd: rgba(224,107,107,0.5);
  --flag-bg: rgba(214,158,46,0.18);   --flag-fg: #e6bd5e; --flag-bd: rgba(214,158,46,0.5);
  --ok-bg:   rgba(63,160,103,0.18);   --ok-fg:  #69c08c;  --ok-bd: rgba(63,160,103,0.5);
  --info-bg: rgba(55,138,221,0.16);   --info-fg: #8fc0f5; --info-bd: rgba(55,138,221,0.5);
  /* BARE status tokens. These are referenced 44 times across the app (score
     chips, log pills, gate-pass tags, boundaries, fees, support, trajectory
     deltas) and were never defined - only the -bg/-fg/-bd trio existed. Every
     bare var(--ok) therefore resolved to NOTHING and left the element
     uncoloured, while every var(--ok, #hex) fell through to a dark-tuned
     literal that stayed dark on a white page. Defining them fixes both at once,
     in both themes, without touching a single call site. */
  --ok:     #69c08c;
  --flag:   #e6bd5e;
  --off:    #f0a8a8;
  --info:   #8fc0f5;
  --accent: #2f72de;
  --ok-soft:   rgba(63,160,103,0.18);
  --flag-soft: rgba(214,158,46,0.18);
  --off-soft:  rgba(224,107,107,0.18);
  --row-hover: rgba(255,255,255,0.04);

  --radius:    20px;       /* Calm Ledger: rounder, roomier cards */
  --radius-sm: 13px;
}

/* Light theme: flips the core palette; everything that references these variables
   adapts. Dark is the default (no attribute / data-theme="dark"). */
:root[data-theme="light"] {
  --bg:         #eef1f7;
  --surface:    #ffffff;
  --raise:      #f7f9fc;
  --field:      #f2f5fa;
  --border:     #dde4ef;
  --text:       #16203a;
  --text-muted: #5b6a85;
  --blue:       #1f5fc0;
  --blue-hover: #1a52a8;
  --gold:       #9a7a2c;
  --danger:     #b3392f;
  --sidebar-bg: #ffffff;
  --topbar-bg:  rgba(255, 255, 255, 0.9);
  --off-bg:  #fdebeb;  --off-fg: #b23b3b;  --off-bd: #f1c4c4;
  --flag-bg: #fbf1da;  --flag-fg: #8a6a1f; --flag-bd: #ecd49c;
  --ok-bg:   #e4f3ea;  --ok-fg:  #1f7a45; --ok-bd: #bfe3cd;
  --info-bg: #e3eefb;  --info-fg: #1f5fc0; --info-bd: #b8d3f3;
  --ok:     #1f7a45;
  --flag:   #8a6a1f;
  --off:    #b23b3b;
  --info:   #1f5fc0;
  --accent: #1f5fc0;
  --ok-soft:   #e4f3ea;
  --flag-soft: #fbf1da;
  --off-soft:  #fdebeb;
  --row-hover: rgba(0,0,0,0.045);
}
/* Tell the browser to render native controls (the <select> popup, scrollbars, date
   pickers) in the current theme, so option lists are legible in dark mode instead of
   defaulting to the OS light rendering. */
:root { color-scheme: dark; }
:root[data-theme="dark"]  { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

/* light-mode readability for the live-board period chip */
:root[data-theme="light"] .rn-period { background: #e3eefb; color: #1f5fc0; border-color: #b8d3f3; }

.theme-toggle { width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text-muted); cursor: pointer; flex: none; }
.theme-toggle:hover { color: var(--text); border-color: var(--gold); }
.theme-toggle svg { width: 18px; height: 18px; }

/* Score chips need readable colours on a light surface. */
:root[data-theme="light"] .chip-good { background-color: #e4f3ea; color: #1f7a45; border-color: #bfe3cd; }
:root[data-theme="light"] .chip-ok   { background-color: #f6edd4; color: #8a6a1f; border-color: #e7d3a0; }
:root[data-theme="light"] .chip-low  { background-color: #fdecec; color: #b23b3b; border-color: #f1c4c4; }
:root[data-theme="light"] .chip-mid  { background-color: #eef1f7; color: #5b6a85; border-color: var(--border); }
:root[data-theme="light"] .chip-none { color: #7c8aa3; }

* { box-sizing: border-box; }

/* Make the hidden attribute always win, even over elements that set a display
   value (e.g. .checking uses display:grid). Without this, toggling .hidden in
   JS would not actually hide such elements. */
[hidden] { display: none !important; }

/* ONE control style for the whole app. Until now there was no base rule for form
   controls at all: some modules styled their own (#staffInput, .gc-row) and the
   rest shipped bare browser widgets - the planner task field, the homework and
   calendar editors, the timetable cell editor - so fields drifted visibly from
   the cards holding them. Declared early and by element, so every module class
   that already styles its own controls still wins on specificity and order.
   Checkboxes, radios, ranges, files and button-inputs are widgets, not fields,
   and are excluded. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]),
select,
textarea {
  background-color: var(--field);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font: inherit;
  font-size: 0.9rem;
}
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]):focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--blue);
}
input::placeholder, textarea::placeholder { color: var(--text-muted); opacity: 1; }

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--text);
  font-family: "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.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;
}

/* ---------- Layout ---------- */
.auth-wrap {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px;
  position: relative;
  overflow: hidden;
}

/* restrained navy/blue glow behind the card */
.auth-wrap::before {
  content: "";
  position: absolute;
  top: -180px;
  left: 50%;
  transform: translateX(-50%);
  width: 680px;
  height: 480px;
  max-width: 120%;
  background: radial-gradient(closest-side, rgba(37, 99, 196, 0.20), rgba(37, 99, 196, 0) 70%);
  pointer-events: none;
}

.checking {
  display: grid;
  place-items: center;
  position: relative;
  z-index: 1;
}

/* ---------- Card ---------- */
.auth-card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 392px;
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 34px 30px 32px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
}

.auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  margin-bottom: 18px;
}

.logo-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  background-color: var(--field);
  border: 1px solid var(--gold);
  box-shadow: inset 0 0 0 1px rgba(201, 162, 74, 0.12);
}
.logo-icon { width: 22px; height: 22px; color: var(--gold); }

/* Chrome paints its OWN background on any field it holds autofill data for, and
   its dark-mode colour is a muddy olive that ignores every background we set.
   The UA rule can only be beaten by flooding the field with an inset shadow. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--field) inset;
  box-shadow: 0 0 0 1000px var(--field) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
  transition: background-color 5000s ease-in-out 0s;
}

/* Sign-in family pages only (.auth-brand lives on login + accept, never dashboards):
   one slow turn of the gold triangle around the blue centre node when the card
   becomes visible. The axis is pinned by translating to the node (64,70 in SVG
   user units) and back, NOT via transform-origin, which resolves inconsistently
   on scaled SVG viewBoxes. CSS (not SMIL) so the hidden card's animation starts
   when the card is shown, not at document load. */
.auth-brand .logo-icon .orbit {
  animation: nodus-orbit 1.8s cubic-bezier(0.25, 0.6, 0.3, 1) 1;
}
@keyframes nodus-orbit {
  from { transform: translate(64px, 70px) rotate(0deg)   translate(-64px, -70px); }
  to   { transform: translate(64px, 70px) rotate(360deg) translate(-64px, -70px); }
}
@media (prefers-reduced-motion: reduce) {
  .auth-brand .logo-icon .orbit { animation: none; }
}

.brand-name { font-size: 1.25rem; font-weight: 700; letter-spacing: 0.01em; }

.auth-title {
  margin: 0 0 22px;
  text-align: center;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* ---- Accept-invite / set-password page ---- */
.auth-sub { color: var(--text-muted); font-size: 0.9rem; text-align: center; margin: -14px 0 18px; line-height: 1.5; }
.pw-reqs { list-style: none; margin: 12px 0 0; padding: 0; font-size: 0.8rem; }
.pw-reqs li { display: flex; align-items: center; gap: 7px; margin: 4px 0; }
.pw-reqs li::before { content: "\2713"; font-weight: 700; }
.pw-reqs li.no { color: var(--text-muted); }
.pw-reqs li.ok { color: var(--ok-fg); }
.acc-warn { width: 46px; height: 46px; border-radius: 50%; background: var(--off-bg); color: var(--off-fg); display: flex; align-items: center; justify-content: center; margin: 0 auto 14px; }
.acc-link { display: block; text-align: center; margin-top: 16px; color: var(--gold); text-decoration: none; font-size: 0.9rem; }
.acc-link:hover { text-decoration: underline; }

/* ---- Two-door login (school-first) ---- */
.auth-school { text-align: center; margin: -8px 0 18px; }
.auth-school-name { display: block; font-size: 1.02rem; font-weight: 700; letter-spacing: -0.01em; }
.auth-school-sub { display: block; margin-top: 3px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--gold); }

.auth-toggle { display: flex; gap: 3px; padding: 3px; margin-bottom: 18px; background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.auth-toggle[hidden] { display: none; }
.auth-tab { flex: 1; padding: 9px 8px; font-size: 0.88rem; font-weight: 600; color: var(--text-muted); background: transparent; border: none; border-radius: calc(var(--radius-sm) - 3px); cursor: pointer; transition: background-color 0.15s ease, color 0.15s ease; }
.auth-tab:hover { color: var(--text); }
.auth-tab.is-on { background-color: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25); }
.auth-tab:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 196, 0.30); }

.code-input { letter-spacing: 0.32em; text-transform: uppercase; font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

.auth-link { display: block; width: 100%; margin-top: 14px; padding: 0; text-align: center; font-size: 0.85rem; color: var(--gold); background: none; border: none; cursor: pointer; }
.auth-link:hover { text-decoration: underline; }

.auth-hint { margin: 12px 0 0; font-size: 0.78rem; line-height: 1.5; color: var(--text-muted); text-align: center; }

.form-note { margin: 2px 0 14px; padding: 9px 11px; font-size: 0.85rem; line-height: 1.45; color: var(--text-muted); background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.form-ok { margin: 2px 0 14px; padding: 9px 11px; font-size: 0.85rem; line-height: 1.45; color: var(--ok-fg); background-color: var(--ok-bg); border: 1px solid var(--ok-bd); border-radius: var(--radius-sm); }

.auth-back { margin: 0 0 6px; padding: 0; font-size: 0.82rem; color: var(--text-muted); background: none; border: none; cursor: pointer; }
.auth-back:hover { color: var(--text); }
.auth-subtitle { margin: 4px 0 18px; font-size: 1.05rem; font-weight: 700; text-align: center; }

.auth-change { display: block; width: 100%; margin-top: 16px; padding: 0; text-align: center; font-size: 0.82rem; color: var(--text-muted); background: none; border: none; cursor: pointer; }
.auth-change:hover { color: var(--text); }
.auth-change[hidden] { display: none; }

/* ---- students status segment (Enrolled / Graduated / Left) ---- */
.mode-seg { display: inline-flex; gap: 3px; padding: 3px; background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.mode-btn { font: inherit; font-size: 0.84rem; font-weight: 600; color: var(--text-muted); background: transparent; border: none; border-radius: calc(var(--radius-sm) - 3px); padding: 7px 14px; cursor: pointer; }
.mode-btn:hover { color: var(--text); }
.mode-btn.is-on { background-color: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25); }

/* ---- year rollover wizard ---- */
.rw-steps { display: flex; gap: 7px; flex-wrap: wrap; margin: 4px 0 18px; }
.rw-pill { font-size: 0.76rem; font-weight: 600; color: var(--text-muted); background-color: var(--field); border: 1px solid var(--border); border-radius: 16px; padding: 4px 13px; }
.rw-pill.rw-done { color: var(--ok-fg); border-color: var(--ok-bd); background: var(--ok-bg); }
.rw-card { background-color: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; margin-bottom: 16px; }
.rw-card.rw-locked { opacity: 0.55; }
.rw-h { font-size: 0.98rem; font-weight: 700; margin: 0 0 5px; }
.rw-sub { font-size: 0.84rem; color: var(--text-muted); line-height: 1.55; margin: 0 0 10px; }
.rw-ok { font-size: 0.78rem; color: var(--ok-fg); font-weight: 600; margin-left: 8px; }
.rw-tbl th, .rw-tbl td { font-size: 0.84rem; padding: 8px 10px; }
.rw-sel { background-color: var(--field); border: 1px solid var(--border); border-radius: 6px; color: var(--text); font: inherit; font-size: 0.8rem; padding: 3px 8px; }
.rw-subrow > td { background-color: var(--field); }
.rw-checks { display: flex; flex-direction: column; gap: 5px; margin: 4px 0 12px; font-size: 0.85rem; font-weight: 500; }
.rw-chk-ok { color: var(--ok-fg); }
.rw-chk-warn { color: var(--flag-fg); }
.rw-chk-bad { color: var(--off-fg); }

/* ---- teacher My-profile card (read-only; identity/scope are admin-set) ---- */
.prof-card { background-color: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; margin-bottom: 18px; }
.prof-name { font-size: 1.1rem; font-weight: 700; }
.prof-role { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--gold); margin-top: 3px; }
.prof-row { display: flex; gap: 10px; margin-top: 12px; font-size: 0.86rem; line-height: 1.6; }
.prof-k { width: 84px; flex: none; color: var(--text-muted); font-weight: 600; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; padding-top: 3px; }
.prof-chip { display: inline-block; background-color: var(--field); border: 1px solid var(--border); border-radius: 14px; padding: 2px 11px; font-size: 0.8rem; margin: 0 6px 6px 0; }
.prof-chip-hr { background: var(--flag-bg); border-color: var(--flag-bd); color: var(--flag-fg); }
.prof-note { font-size: 0.76rem; color: var(--text-muted); margin-top: 10px; line-height: 1.5; }

/* signed-in user's name beside the avatar (initial-only circle stays the control) */
.topbar-user { font-size: 0.88rem; font-weight: 500; color: var(--text-muted); margin-right: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 280px; }
@media (max-width: 640px) { .topbar-user { display: none; } }
/* derived position tag after the name: Principal / Class Teacher / Teacher / Admin */
.topbar-role { color: var(--gold); font-size: 0.74rem; font-weight: 600; margin-left: 8px; letter-spacing: 0.02em; }

/* ---- self-service password-change dialog (staff; opened from the avatar) ---- */
.avatar-btn { cursor: pointer; }
.avatar-btn:hover { box-shadow: 0 0 0 2px var(--blue); }
.av-menu { position: fixed; z-index: 70; min-width: 190px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 6px; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.32); }
.av-menu-head { padding: 6px 10px 8px; font-size: 0.8rem; color: var(--text-dim); border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.av-mi { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: none; border: 0; border-radius: 7px; padding: 9px 10px; font: inherit; font-size: 0.9rem; color: var(--text); cursor: pointer; }
.av-mi:hover { background: var(--row-hover); }
.av-mi svg { width: 17px; height: 17px; flex: none; color: var(--text-dim); }
a.av-mi { text-decoration: none; box-sizing: border-box; }
.av-menu-div { height: 1px; background: var(--border); margin: 4px 2px; }
.pwd-overlay { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 20px; background: rgba(5, 9, 18, 0.62); }
.pwd-card { width: 100%; max-width: 360px; background-color: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 24px; box-shadow: 0 18px 50px rgba(0, 0, 0, 0.4); }
.pwd-title { margin: 0 0 6px; font-size: 1.05rem; font-weight: 700; }
.pwd-sub { margin: 0 0 14px; font-size: 0.82rem; line-height: 1.5; color: var(--text-muted); }
.pwd-lab { display: block; font-size: 0.82rem; font-weight: 600; color: var(--text-muted); margin: 10px 0 5px; }
.pwd-in { width: 100%; box-sizing: border-box; font-size: 0.95rem; color: var(--text); background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; }
.pwd-in:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(37, 99, 196, 0.25); }
.pwd-msg { margin: 12px 0 0; font-size: 0.85rem; font-weight: 500; }
.pwd-actions { display: flex; gap: 9px; margin-top: 16px; }

.school-picks { margin: 2px 0 16px; }
.school-picks[hidden] { display: none; }
.school-picks-head { margin: 0 0 8px; font-size: 0.85rem; color: var(--text-muted); }
.school-pick { display: block; width: 100%; text-align: left; margin-bottom: 8px; padding: 11px 14px; font-size: 0.95rem; font-weight: 600; color: var(--text); background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; transition: border-color 0.15s ease, background-color 0.15s ease; }
.school-pick:hover { border-color: var(--blue); }
.school-pick:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 196, 0.30); }

/* ---------- Fields ---------- */
.field { margin-bottom: 16px; }

.field label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 7px;
}

.field input {
  width: 100%;
  font-size: 1rem;
  color: var(--text);
  background-color: var(--field);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.field input::placeholder { color: #5d6c87; }
.field input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(37, 99, 196, 0.25);
}

/* ---------- Error ---------- */
.form-error {
  margin: 2px 0 16px;
  color: var(--danger);
  font-size: 0.92rem;
  font-weight: 500;
}

/* ---------- Button ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  padding: 13px 22px;
  /* Pill, app-wide. The family quick links proved the shape and it belongs
     everywhere: it is the same round language as the ring cards and the page
     banners, and a button that reads as a button on a phone is worth more than
     a corner radius that matches a card. */
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}
.btn-primary {
  background-color: var(--blue);
  color: #ffffff;
  border-color: var(--blue);
}
.btn-primary:hover { background-color: var(--blue-hover); border-color: var(--blue-hover); }
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(201, 162, 74, 0.45);
}
.btn:disabled { cursor: default; opacity: 0.75; }

.auth-submit { width: 100%; margin-top: 4px; }

/* ---------- Spinner ---------- */
.spinner {
  display: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: #ffffff;
  animation: nodus-spin 0.7s linear infinite;
}
.btn.is-loading .spinner { display: inline-block; }

.spinner-lg {
  display: inline-block;
  width: 26px;
  height: 26px;
  border-width: 3px;
  border-color: rgba(159, 176, 204, 0.35);
  border-top-color: var(--gold);
}

@keyframes nodus-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 1.4s; }
  .btn { transition: none; }
}

/* ---------- Minimal authenticated home stub ---------- */
.home-wrap {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.home-card {
  width: 100%;
  max-width: 460px;
  text-align: center;
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 36px 32px;
}
.home-card h1 { margin: 16px 0 6px; font-size: 1.4rem; }
.home-card p { margin: 0 0 22px; color: var(--text-muted); }
.home-user { color: var(--text); font-weight: 600; }
.btn-ghost {
  background-color: transparent;
  color: var(--text);
  border-color: var(--border);
}
.btn-ghost:hover { border-color: #2f3e5e; background-color: rgba(255,255,255,0.03); }

/* ============================================================
   Admin app shell (dashboard / class / student)
   ============================================================ */
.app-shell {
  display: grid;
  grid-template-columns: 210px 1fr;
  min-height: 100vh;
  min-height: 100dvh;
}

/* The backdrop is out of flow except on mobile. Without this it is an in-flow
   grid item on desktop and steals a column, breaking the whole layout. */
.sidebar-backdrop { display: none; }

/* ---- Sidebar ---- */
.sidebar {
  background-color: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 18px 12px;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 8px 18px;
}
.sidebar-brand .brand-name { font-size: 1.1rem; font-weight: 700; letter-spacing: 0.01em; }
.sidebar-brand .logo-tile { width: 40px; height: 40px; }
.sidebar-brand .logo-tile svg, .sidebar-brand .logo-icon { width: 24px; height: 24px; }

/* ---- Collapsible sidebar (desktop): icon-only rail, preference remembered ---- */
.sb-toggle {
  display: none; align-items: center; gap: 11px; width: 100%;
  background: none; border: 0; border-top: 1px solid var(--border);
  padding: 10px 12px; margin-top: 6px; border-radius: 0;
  color: var(--text-muted); font: inherit; font-size: 0.85rem; cursor: pointer;
}
.sb-toggle:hover { color: var(--text); }
.sb-toggle svg { width: 18px; height: 18px; flex: none; transition: transform 0.18s ease; }
@media (min-width: 901px) {
  .sb-toggle { display: flex; }
  .app-shell.sb-mini { grid-template-columns: 64px 1fr; }
  .sb-mini .sidebar { padding-left: 10px; padding-right: 10px; overflow-x: hidden; }
  .sb-mini .sidebar .brand-name,
  .sb-mini .sidebar .nav-badge,
  .sb-mini .sb-toggle .sb-toggle-label { display: none; }
  .sb-mini .sidebar .nav-item { justify-content: center; font-size: 0; gap: 0; padding: 11px 0; }
  .sb-mini .sidebar .nav-item svg { width: 19px; height: 19px; }
  .sb-mini .sb-toggle { justify-content: center; }
  .sb-mini .sb-toggle svg { transform: rotate(180deg); }
  .sb-mini .sidebar-brand { justify-content: center; padding-left: 0; padding-right: 0; }
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;   /* nav links are never underlined (mock A) */
  cursor: pointer;
}
.nav-item:hover { background-color: rgba(128,128,128,0.14); color: var(--text); }
.nav-item.active { background-color: var(--raise); color: var(--text); font-weight: 600; box-shadow: inset 2px 0 0 var(--gold); }
.nav-group {
  display: block; margin: 18px 12px 6px;
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted); opacity: 0.72;
}
.nav-item.is-disabled { opacity: 0.4; cursor: not-allowed; }
.nav-item.is-disabled:hover { background-color: transparent; color: var(--text-muted); }
.nav-item svg { width: 18px; height: 18px; flex: none; }
.nav-spacer { flex: 1; }

/* ---- Main + topbar ---- */
.main { display: flex; flex-direction: column; min-width: 0; }
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 28px;
  background-color: var(--topbar-bg);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.topbar-school { font-weight: 700; font-size: 1.02rem; white-space: nowrap; }
.topbar-lens { display: flex; align-items: center; gap: 10px; margin-left: 6px; flex-wrap: wrap; }
.lens-select {
  appearance: none;
  background-color: var(--field);
  color: var(--text);
  border-radius: 999px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 30px 8px 12px;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239fb0cc' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.lens-select:focus { outline: none; border-color: var(--blue); }
.topbar-spacer { flex: 1; }
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background-color: rgba(201,162,74,0.18); border: 1px solid var(--gold);
  color: var(--gold); font-weight: 700; font-size: 0.9rem;
}
.icon-btn {
  display: none; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  background: transparent; border: 1px solid var(--border); color: var(--text); cursor: pointer;
}
.icon-btn svg { width: 20px; height: 20px; }

/* ---- Content ---- */
.content { padding: 28px; max-width: 1180px; width: 100%; }
.page-title { font-size: 1.72rem; font-weight: 750; letter-spacing: -0.022em; margin: 0 0 3px; }
.page-sub { color: var(--text-muted); font-size: 0.94rem; margin: 0 0 26px; }

/* Performance bars: rounded, thicker, and on a visible track so a short bar
   still reads as a value rather than as an empty row. */
.chart-card { background-color: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.chart-title { font-size: 0.98rem; font-weight: 650; }

/* Homework status pills carry their meaning in colour as well as in the word,
   which is what makes "is anything missing" answerable at a glance. */
.sa-p, .hwm-done { background-color: var(--ok-bg); color: var(--ok-fg); }
.sa-l, .hwm-late { background-color: var(--flag-bg); color: var(--flag-fg); }
.sa-a, .hwm-missing { background-color: var(--off-bg); color: var(--off-fg); }

/* Family sections read as a stack of long grey lists otherwise. The heading
   carries the page accent (set by app.js) and a rule under it, so a parent can
   find "Exams" or "Attendance" by scanning rather than reading. */
.content > section > .section-head .section-title { font-size: 0.76rem; }
.content > section > .section-head {
  border-bottom: 2px solid var(--page-accent);
  padding-bottom: 6px;
  display: inline-flex;
  margin-bottom: 12px;
}

/* ---- Motion, sparingly ----
   Three places only, and each one earns it: a ring draws itself so the eye
   follows the value being filled in, a card lifts under the pointer so it reads
   as clickable, and the wordmark's centre node turns on hover as a small piece of
   life in the chrome. Nothing loops, nothing moves on its own, nothing delays
   reading: every value is already correct before its animation runs, so a reader
   who prefers no motion loses the movement and nothing else. */
.ring-arc { animation: nodus-arc 0.85s cubic-bezier(0.3, 0.8, 0.3, 1) 1 both; }
@keyframes nodus-arc {
  from { stroke-dashoffset: var(--arc, 400); }
  to   { stroke-dashoffset: 0; }
}
.rk-link, .tile { will-change: transform; }
.rk-link:hover { transform: translateY(-2px); }
.sidebar-brand .logo-icon circle:last-of-type { transition: transform 0.5s cubic-bezier(0.3, 0.8, 0.3, 1); }
.sidebar-brand:hover .logo-icon circle:last-of-type {
  transform: translate(64px, 70px) rotate(180deg) translate(-64px, -70px);
}
.page-banner { animation: nodus-rise 0.3s ease-out 1 both; }
@keyframes nodus-rise { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .ring-arc, .page-banner { animation: none; }
  .rk-link:hover, .tile:hover { transform: none; }
  .sidebar-brand:hover .logo-icon circle:last-of-type { transform: none; }
}

/* Bus stops: an ordered list, numbered, because the order IS the route. */
.bus-stops { list-style: none; padding: 0; margin: 0; }
.bus-stop { display: flex; gap: 11px; align-items: center; padding: 8px 11px;
  background-color: var(--field); border-radius: var(--radius-sm); margin-bottom: 6px; }
.bus-stop .no { flex: 0 0 26px; height: 26px; border-radius: 50%; background-color: var(--raise);
  display: flex; align-items: center; justify-content: center; font-size: .76rem; font-weight: 700; color: var(--text-muted); }
.bus-stop .nm { flex: 1; font-weight: 600; font-size: .9rem; min-width: 0; }

/* Console tiles. A console whose whole job is "go to the right screen" should
   be a grid you scan, not six identical paragraphs you scroll. */
.tile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 14px; margin-bottom: 26px; }
.tile {
  display: block; text-decoration: none; color: inherit;
  background-color: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px 18px;
  transition: border-color .12s ease, transform .12s ease;
}
.tile:hover { border-color: var(--page-accent); transform: translateY(-2px); }
.tile-k { display: block; font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--page-accent); }
.tile b { display: block; font-size: 1.02rem; font-weight: 650; margin: 5px 0 4px; }
.tile span:not(.tile-k) { display: block; color: var(--text-muted); font-size: 0.84rem; line-height: 1.45; }

/* Family quick links. The small ghost buttons were fine as a toolbar for staff,
   but this row is the main navigation a parent has - it deserves to be tappable
   on a phone and readable at a glance. */
.fam-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.fam-actions .btn {
  padding: 9px 16px;
  font-size: 0.9rem;
  font-weight: 600;
  background-color: var(--surface);
  border: 1px solid var(--border);
}
.fam-actions .btn:hover { border-color: var(--gold); }
.fam-actions .btn-primary { background-color: var(--blue); border-color: var(--blue); }
@media (max-width: 560px) { .fam-actions { width: 100%; } .fam-actions .btn { flex: 1 1 auto; text-align: center; } }

/* ---- Page banner + per-page colour identity ----
   Built at runtime by app.js from the .page-title / .page-sub every page already
   has, so every screen gets it including ones added later. The accent is one of
   the palette-validated ring hues, mapped fixedly per module. */
:root { --page-accent: var(--ring-marks); --page-wash: var(--wash-marks); }
.page-banner {
  background: var(--page-wash);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 24px 22px;
  margin-bottom: 24px;
}
.page-banner .page-title { margin-bottom: 4px; }
.page-banner .page-sub { margin-bottom: 0; }
/* The eyebrow on every section takes the page's colour, which is what turns a
   grey screen into a coloured one without repainting any content. */
.section-title { color: var(--page-accent); }
/* Cards on a page pick up a whisper of the same hue on their edge. */
.rk, .board-card { border-color: var(--border); }

/* ---- Ring KPI cards (Calm Ledger, mock A) ----
   Only ever used for part-of-whole metrics; see gauge.js for the rule. */
/* Flex, not grid, precisely because the card COUNT varies by tenant and seat:
   the fees ring is absent for a head kept out of the ledgers, wellbeing for a
   non-reader. A fixed grid leaves whatever is left over sitting alone in a
   quarter-width slot. With flex-grow the final row spreads to fill the width
   whatever the count, so no arrangement looks broken. */
.ring-row { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 22px; }
.ring-row > .rk { flex: 1 1 236px; min-width: 0; }
@media (max-width: 1080px) { .ring-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .ring-row { grid-template-columns: 1fr; } }
.rk {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 17px 19px 19px;
  display: block;
}
.rk { position: relative; }
.rk-link { text-decoration: none; color: inherit; }
.rk-tip {
  position: absolute; left: 14px; right: 14px; bottom: calc(100% - 6px);
  background-color: var(--raise); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 9px 11px; font-size: 0.78rem; line-height: 1.4; font-weight: 400;
  box-shadow: 0 10px 26px rgba(0,0,0,0.34);
  opacity: 0; pointer-events: none; transform: translateY(4px);
  transition: opacity .13s ease, transform .13s ease; z-index: 5;
}
.rk:hover .rk-tip, .rk:focus-visible .rk-tip { opacity: 1; transform: translateY(0); }
@media (hover: none) { .rk-tip { display: none; } }
.rk-link:hover { border-color: var(--gold); }
.rk-title { color: var(--text-muted); font-size: 0.8rem; font-weight: 500; margin: 0 0 11px; }
.rk-row { display: flex; align-items: center; gap: 16px; }
.rk-fig { min-width: 0; }
.rk-value { font-size: 1.95rem; font-weight: 750; line-height: 1.05; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.rk-value .rk-of { font-size: 0.95rem; font-weight: 500; color: var(--text-muted); letter-spacing: 0; }
.rk-muted { color: var(--text-muted); }
.rk-raw { color: var(--text-muted); font-size: 0.79rem; margin-top: 3px; line-height: 1.35; }
.ring { flex: none; display: block; }
/* Ring hues, chosen with the palette validator rather than by eye, and stepped
   per theme (the dark greens fell under 3:1 on white). Each hue is bound to a
   METRIC, never to a value. Both sets PASS every check with no warnings:
   lightness band, chroma floor, CVD separation, normal-vision floor, contrast.
   The -wash tokens are the same hue at low alpha, used to tint the card so the
   colour carries the layout instead of living only in a thin stroke. */
:root {
  --ring-track: rgba(255,255,255,0.09);
  --ring-attendance: #26a96b;  --wash-attendance: rgba(38,169,107,0.10);
  --ring-registers:  #c68619;  --wash-registers:  rgba(198,134,25,0.10);
  --ring-marks:      #4790e5;  --wash-marks:      rgba(71,144,229,0.10);
  --ring-fees:       #dd5b98;  --wash-fees:       rgba(221,91,152,0.10);
}
:root[data-theme="light"] {
  --ring-track: rgba(20,32,58,0.10);
  --ring-attendance: #12a463;  --wash-attendance: rgba(18,164,99,0.09);
  --ring-registers:  #c9700c;  --wash-registers:  rgba(201,112,12,0.09);
  --ring-marks:      #2472d6;  --wash-marks:      rgba(36,114,214,0.09);
  --ring-fees:       #d13a85;  --wash-fees:       rgba(209,58,133,0.09);
}
.rk-t-attendance { background-color: var(--wash-attendance); border-color: rgba(38,169,107,0.30); }
.rk-t-registers  { background-color: var(--wash-registers);  border-color: rgba(198,134,25,0.30); }
.rk-t-marks      { background-color: var(--wash-marks);      border-color: rgba(71,144,229,0.30); }
.rk-t-fees       { background-color: var(--wash-fees);       border-color: rgba(221,91,152,0.30); }

/* The three structural counts. They are totals, not parts, so they can never be
   rings - but they also do not deserve four big cards. One quiet line. */
.fact-strip { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 0 0 24px; color: var(--text-muted); font-size: 0.9rem; }
.fact-strip b { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; margin-right: 4px; }

/* Term switcher dot: marks a term that holds comments, so an empty term is
   visible without opening it. Decorative only - the tab label carries the name. */
.tc-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ring-marks); margin-left: 7px; vertical-align: middle; }

/* Right-now band (mock A): the live board in a card, with a companion card
   beside it. The aside carries the wellbeing trends - and on a school whose head
   is kept out of the ledgers (0134) that is what fills the space the mock gave
   to a fee donut. Collapses to one column before the board gets cramped. */
.rn-split { display: grid; grid-template-columns: minmax(0, 1.85fr) minmax(0, 1fr); gap: 18px; align-items: start; margin-bottom: 26px; }
@media (max-width: 1080px) { .rn-split { grid-template-columns: 1fr; } }
.board-card { background-color: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 17px 19px 19px; }
.rn-aside:empty { display: none; }
.rn-aside .wb-chart { background-color: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 15px 17px; margin-bottom: 14px; }
.rn-aside .section-label { display: none; }

/* ---- Summary cards ---- */
.cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 30px;
}
.stat {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
}
.stat-label { color: var(--text-muted); font-size: 0.8rem; font-weight: 500; margin: 0 0 8px; }
.stat-value { font-size: 1.75rem; font-weight: 750; line-height: 1.05; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.stat-accent .stat-value { color: var(--gold); }

/* ---- Section + class list ---- */
.section-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 26px 0 12px;
}
.section-title {
  font-size: 0.7rem; font-weight: 700; margin: 0;
  text-transform: uppercase; letter-spacing: 0.11em; color: var(--text-muted);
}
.class-list { display: flex; flex-direction: column; gap: 12px; }
.class-row {
  display: flex; align-items: center; gap: 16px;
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  text-decoration: none; color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.class-row:hover { border-color: #2f3e5e; transform: translateY(-2px); }
/* ---------------------------------------------------------------------------
   PERSON AVATAR (shared). Every profile reserves the same circular slot so a
   school that uploads photos later gets them everywhere without a redesign.
   Until then the slot renders the person's initials. Photos themselves are a
   separate build (private storage bucket + per-tenant rules); the demo schools
   stay on initials because their people are fictional.
   --------------------------------------------------------------------------- */
.n-av {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; flex: none; overflow: hidden; position: relative;
  background-color: var(--raise); border: 1px solid var(--border);
  color: var(--text-muted); font-weight: 700; letter-spacing: .01em;
  width: 40px; height: 40px; font-size: 0.95rem;
}
.n-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.n-av-sm { width: 30px; height: 30px; font-size: 0.78rem; }
.n-av-lg { width: 68px; height: 68px; font-size: 1.5rem; }
.n-av-xl { width: 92px; height: 92px; font-size: 2rem; }
/* the empty state is deliberately quiet, not a broken-image box */
.n-av-empty { border-style: dashed; }
.n-av-wrap { display: flex; align-items: center; gap: 12px; }

.class-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--radius-sm);
  background-color: #0c1322; border: 1px solid var(--gold); color: var(--gold);
  font-weight: 700; flex: none;
}
.class-meta { min-width: 0; }
.class-name { font-weight: 700; font-size: 1.05rem; }
.class-sub { color: var(--text-muted); font-size: 0.92rem; }
.class-cta { margin-left: auto; color: var(--text-muted); display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 0.95rem; }
.class-cta svg { width: 16px; height: 16px; }
.class-add {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px dashed var(--border); border-radius: var(--radius);
  padding: 14px; color: var(--text-muted); font-weight: 600; font-size: 0.95rem;
}

/* Class detail header */
.class-head { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.class-badge-lg { width: 56px; height: 56px; font-size: 1.15rem; }
.class-head-meta { min-width: 0; }
.class-head-meta .page-title { margin: 0; }
.class-head-meta .page-sub { margin: 4px 0 0; }
.class-head-action { margin-left: auto; flex: none; }
.class-head-actions { margin-left: auto; display: flex; gap: 10px; flex-wrap: wrap; }
.class-head-actions .btn { text-decoration: none; }

/* ---- Subjects card (per-class subject management) ---- */
.subjects-card { margin-top: 30px; }
.count-badge { background: var(--info-bg); color: var(--info-fg); font-size: 0.8rem; padding: 2px 9px; border-radius: 999px; margin-left: 8px; vertical-align: middle; font-weight: 700; }
.link-danger { background: none; border: 1px solid var(--border); color: var(--off-fg); border-radius: var(--radius-sm); padding: 5px 8px; cursor: pointer; display: inline-flex; }
.link-danger:hover { border-color: var(--off-bd); background-color: var(--off-bg); }
.subj-lock { color: var(--text-muted); display: inline-flex; padding: 5px 8px; }
.add-subject .add-label { display: block; margin-bottom: 8px; color: var(--text-muted); font-size: 0.85rem; font-weight: 700; }
.add-subject input { background: var(--field); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 9px 12px; font: inherit; font-size: 0.92rem; min-width: 0; }
.add-subject input::placeholder { color: #5d6c87; }
.add-subject input:focus { outline: none; border-color: var(--blue); }

/* ---- Performance trajectory line (shared NodusPerf component) ---- */
.perf-svg { width: 100%; max-width: 460px; height: auto; display: block; margin: 6px 0 4px; }
.perf-grid-line { stroke: var(--border); stroke-width: 1; }
.perf-axis { fill: var(--text-muted); font-size: 9px; }
.perf-val { fill: var(--text); font-size: 10px; font-weight: 700; }
.perf-line-stu { stroke: var(--gold); stroke-width: 2.5; fill: none; }
.perf-dot-stu { fill: var(--gold); }
.perf-line-class { stroke: var(--text-muted); stroke-width: 2; stroke-dasharray: 4 3; fill: none; }
.perf-dot-class { fill: var(--text-muted); }
.traj-list { margin-top: 8px; }

/* ---- Analysis ---- */
.scope-seg { margin-bottom: 16px; }
.an-two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 760px) { .an-two { grid-template-columns: 1fr; } }
.vbar-svg { width: 100%; height: auto; display: block; margin: 6px 0; }
.vgrid { stroke: var(--border); stroke-width: 1; }
.vaxis { fill: var(--text-muted); font-size: 9px; }
.vval { fill: var(--text); font-size: 10px; font-weight: 700; }
.vlabel { fill: var(--text-muted); font-size: 10px; }
.vhit { transition: fill 0.12s ease; }
.vhit:hover { fill: var(--row-hover); }

/* ---- Admin add/remove (classes + students) ---- */
.nc-input { background: var(--field); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 12px; font: inherit; font-size: 0.92rem; min-width: 0; }
.nc-input::placeholder { color: #5d6c87; }
.nc-input:focus { outline: none; border-color: var(--blue); }
.btn-danger-ghost { color: var(--off-fg); border-color: var(--off-bd); }
.btn-danger-ghost:hover { border-color: var(--off-fg); background-color: var(--off-bg); }

/* ---- Teacher dashboard: subject vs homeroom sections ---- */
.section-label { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 12px; }
.class-row-homeroom { border-color: var(--gold); }
.class-row-homeroom:hover { border-color: var(--gold); }
.hr-pill { font-size: 0.7rem; font-weight: 700; color: var(--gold); background: rgba(201,162,74,0.16); border: 1px solid rgba(201,162,74,0.4); padding: 1px 8px; border-radius: 999px; margin-left: 8px; vertical-align: 1px; white-space: nowrap; }

/* ---- Logs tab ---- */
.nav-badge { margin-left: auto; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; background: var(--off-bg); border: 1px solid var(--off-bd); color: var(--off-fg); font-size: 0.72rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.lt-pickbar { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.lt-pickbar select { flex: 0 0 220px; }
.lt-pickbar input { flex: 1; min-width: 200px; }
.lt-srow { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); text-decoration: none; color: inherit; margin-bottom: 8px; transition: border-color 0.15s ease; }
.lt-srow:hover { border-color: #2f3e5e; }
.lt-srow-main { font-weight: 600; }
.lt-srow-meta { color: var(--text-muted); font-size: 0.9rem; }
.lt-srow-cta { margin-left: auto; color: var(--text-muted); display: flex; align-items: center; gap: 5px; font-size: 0.9rem; }
.lt-srow-cta svg { width: 15px; height: 15px; }
.lt-thread-head { display: flex; justify-content: flex-end; margin-bottom: 12px; }
.lt-compose { border: 2px solid var(--gold); border-radius: var(--radius); background: var(--surface); padding: 16px; margin-bottom: 18px; }
.lt-compose-title { font-weight: 700; margin-bottom: 10px; }
.lt-compose-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.lt-compose-row select { flex: 0 0 170px; }
.lt-compose textarea, .lt-editbox { width: 100%; }
.lt-refpick { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.lt-refopt { font-size: 0.92rem; color: var(--text); display: inline-flex; align-items: center; gap: 6px; }
#teacherPickWrap { margin-top: 8px; }
#teacherPickWrap select { width: 100%; max-width: 360px; }
.lt-compose-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.lt-entry { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 14px 16px; margin-bottom: 12px; }
.lt-entry.lt-frozen { opacity: 0.62; background: var(--field); }
.lt-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.lt-meta { color: var(--text-muted); font-size: 0.86rem; }
.lt-frozen-tag { color: var(--gold); }
.lt-pill { font-size: 0.72rem; font-weight: 700; padding: 2px 9px; border-radius: 999px; }
.lt-pill-concern { color: var(--flag-fg); background: var(--flag-bg); border: 1px solid var(--flag-bd); }
.lt-pill-praise { color: var(--ok-fg); background: var(--ok-bg); border: 1px solid var(--ok-bd); }
.lt-pill-discipline { color: var(--off-fg); background: var(--off-bg); border: 1px solid var(--off-bd); }
.lt-pill-note, .lt-pill-other { color: var(--text-muted); background: rgba(120,130,150,0.15); border: 1px solid var(--border); }
.lt-body { font-size: 0.98rem; line-height: 1.5; white-space: pre-wrap; }
.lt-replies { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.lt-reply { border-left: 2px solid var(--gold); background: var(--field); border-radius: 0 8px 8px 0; padding: 8px 12px; }
.lt-reply-body { font-size: 0.92rem; margin-top: 2px; }
.lt-replybox { display: flex; gap: 8px; margin-top: 10px; align-items: flex-start; }
.lt-replybox textarea { flex: 1; }
.lt-ctls { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.lt-ctl { font-size: 0.85rem; border: 1px solid var(--border); background: transparent; color: var(--text-muted); border-radius: var(--radius-sm); padding: 5px 11px; cursor: pointer; }
.lt-ctl:hover { border-color: #2f3e5e; color: var(--text); }
.lt-ctl-danger { color: #e88f8f; border-color: rgba(224,107,107,0.35); }
.lt-ctl-danger:hover { border-color: #e88f8f; color: #f0b3b3; }

/* ---- Psychologist workspace ---- */
.pw-flag { display: block; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 13px 15px; margin-bottom: 10px; text-decoration: none; color: inherit; transition: border-color 0.15s ease; }
.pw-flag:hover { border-color: #2f3e5e; }
.pw-flag-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.pw-flag-name { font-weight: 700; }
.pw-flag-cta { margin-left: auto; color: var(--text-muted); display: flex; align-items: center; gap: 5px; font-size: 0.9rem; }
.pw-flag-cta svg { width: 15px; height: 15px; }
.pw-flag-snip { color: var(--text-muted); font-size: 0.92rem; }
.pw-perf { margin-top: 22px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 14px 16px; }
.pw-perf-head { display: flex; align-items: center; gap: 8px; font-weight: 700; margin-bottom: 12px; }
.pw-perf-head svg { width: 18px; height: 18px; color: var(--gold); }

/* ---- Homeroom overview ---- */
.hm-roster { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.hm-row { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--border); cursor: pointer; }
.hm-row:last-child { border-bottom: none; }
.hm-row:hover { background: var(--field); }
.hm-row.sel { background: rgba(55,138,221,0.12); box-shadow: inset 2px 0 0 var(--blue); }
.hm-av { width: 30px; height: 30px; border-radius: 50%; background: var(--field); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: 0.78rem; font-weight: 700; color: var(--text-muted); flex: none; }
.hm-row-main { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.hm-name { font-weight: 600; }
.hm-code { color: var(--text-muted); font-size: 0.84rem; font-variant-numeric: tabular-nums; }
.hm-logpill { font-size: 0.72rem; font-weight: 700; color: #e0b341; background: rgba(214,158,46,0.15); border: 1px solid rgba(214,158,46,0.4); padding: 1px 9px; border-radius: 999px; }
.hm-detail-empty { margin-top: 16px; padding: 28px; text-align: center; color: var(--text-muted); border: 1px dashed var(--border); border-radius: var(--radius); }
.hm-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 14px 16px; margin-top: 14px; }
.hm-h { display: flex; align-items: center; gap: 8px; font-weight: 700; margin-bottom: 12px; }
.hm-h svg { width: 18px; height: 18px; color: var(--gold); flex: none; }

/* ---- Timetable grid ---- */
.tt-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.tt-toolbar select { flex: 0 0 200px; }
.tt-toolbar-meta { font-size: 0.86rem; color: var(--text-muted); }
.tt-seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.tt-seg-btn { background: transparent; border: none; color: var(--text-muted); font: inherit; font-size: 0.85rem; padding: 6px 14px; cursor: pointer; }
.tt-seg-btn + .tt-seg-btn { border-left: 1px solid var(--border); }
.tt-seg-btn.active { background: var(--field); color: var(--text); font-weight: 600; }
.tt-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); }
.tt-grid { width: 100%; border-collapse: collapse; table-layout: fixed; min-width: 720px; }
.tt-grid th, .tt-grid td { border: 1px solid var(--border); padding: 5px 6px; vertical-align: top; }
.tt-grid thead th { background: var(--surface); font-weight: 600; text-align: center; font-size: 0.76rem; color: var(--text); }
.tt-corner { width: 38px; }
.tt-ph { font-size: 0.66rem; color: var(--text-muted); font-weight: 400; }
.tt-dayc { background: var(--surface); font-weight: 600; text-align: center; width: 38px; font-size: 0.8rem; }
.tt-c { background: var(--surface); }
.tt-s { font-weight: 600; font-size: 0.78rem; line-height: 1.3; }
.tt-m { font-size: 0.68rem; color: var(--text-muted); line-height: 1.25; }
.tt-c-empty { background: repeating-linear-gradient(135deg, transparent, transparent 5px, rgba(120,130,150,0.07) 5px, rgba(120,130,150,0.07) 6px); }
.tt-dash { display: block; text-align: center; color: var(--text-muted); font-size: 0.85rem; }
.tt-editing .tt-c-edit { cursor: pointer; }
.tt-editing .tt-c-edit:hover { outline: 2px solid var(--gold); outline-offset: -2px; }
.tt-legend { font-size: 0.78rem; color: var(--text-muted); margin: 8px 0 0; }
.tt-editor { border: 2px solid var(--gold); border-radius: var(--radius); background: var(--surface); padding: 16px; margin-top: 16px; max-width: 460px; }
.tt-editor-head { font-weight: 700; margin-bottom: 12px; }
.tt-lbl { display: block; font-size: 0.74rem; color: var(--text-muted); margin: 10px 0 3px; }
.tt-hint { font-weight: 400; text-transform: none; letter-spacing: 0; }
.tt-teachers { display: flex; flex-direction: column; gap: 5px; max-height: 160px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; background: var(--field); }
.tt-tk { font-size: 0.9rem; display: flex; align-items: center; gap: 7px; }
.tt-editor input, .tt-editor select { width: 100%; }
.tt-clash { display: flex; align-items: flex-start; gap: 9px; margin-top: 12px; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--flag-bg); border: 1px solid var(--flag-bd); color: var(--flag-fg); font-size: 0.82rem; line-height: 1.45; }
.tt-clash svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.tt-clash > div { display: flex; align-items: flex-start; gap: 9px; }
.tt-clash-block { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 8px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--off-bg); border: 1px solid var(--off-bd); color: var(--off-fg); }
.tt-clash-block svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.tt-editor-actions { display: flex; gap: 8px; align-items: center; margin-top: 14px; }

/* ---- timetable rework: view segments, class picker, today/now, summary, phone ---- */
.tt-actions { margin-left: auto; display: flex; gap: 8px; }
.tt-picker { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.tt-find { position: relative; display: inline-flex; align-items: center; }
.tt-find svg { position: absolute; left: 11px; width: 15px; height: 15px; stroke: var(--text-muted); fill: none; stroke-width: 1.9; pointer-events: none; }
/* An ID, deliberately. The base form-control rule is input:not(...) x6, which
   scores (0,6,1) - higher than any sensible class selector here - so a
   .tt-find input rule silently loses its padding and the search icon lands on
   top of the typed text. */
#classSearch { padding-left: 32px; border-radius: 999px; min-width: 210px; }
.tt-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.tt-chip { border: 1px solid var(--border); background: var(--surface); color: var(--text-muted);
  border-radius: 999px; padding: 5px 13px; font: inherit; font-size: 0.8rem; cursor: pointer; }
.tt-chip:hover { color: var(--text); border-color: var(--page-accent, var(--accent)); }
.tt-chip.on { background: var(--page-wash, var(--field)); border-color: var(--page-accent, var(--accent)); color: var(--text); font-weight: 600; }

/* Today reads as a tinted row; the live period gets the gold outline, the same
   signal the board uses for "right now". */
.tt-grid tr.tt-today td { background: var(--page-wash, var(--field)); }
.tt-grid tr.tt-today .tt-dayc { background: var(--page-accent, var(--accent)); color: #fff; }
.tt-grid th.tt-hnow { color: var(--gold); }
.tt-grid td.tt-now { outline: 2px solid var(--gold); outline-offset: -2px; }

.tt-sum { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.tt-sumchip { border: 1px solid var(--border); background: var(--surface); border-radius: 999px;
  padding: 5px 13px; font-size: 0.78rem; color: var(--text-muted); }
.tt-sumchip b { color: var(--text); font-weight: 600; }

/* The phone view. Both are rendered; CSS picks one, so rotating a device cannot
   leave a stale layout behind. */
.tt-days { display: none; }
.tt-daytabs { display: flex; gap: 6px; justify-content: center; margin-bottom: 6px; }
.tt-daytab { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--border);
  background: var(--surface); color: var(--text-muted); font: inherit; font-size: 0.8rem; cursor: pointer; }
.tt-daytab.is-today { border-color: var(--page-accent, var(--accent)); }
.tt-daytab.on { background: var(--page-accent, var(--accent)); border-color: transparent; color: #fff; font-weight: 600; }
.tt-dayname { text-align: center; font-size: 0.82rem; color: var(--text-muted); margin: 0 0 10px; }
.tt-dlist { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.tt-drow { display: flex; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--border); align-items: center; }
.tt-drow:last-child { border-bottom: 0; }
.tt-drow-now { background: var(--page-wash, var(--field)); box-shadow: inset 3px 0 0 var(--gold); }
.tt-dt { color: var(--text-muted); font-size: 0.72rem; width: 44px; flex: none; font-variant-numeric: tabular-nums; }
.tt-db { flex: 1; min-width: 0; }
.tt-db .tt-s { font-size: 0.9rem; }
.tt-dfree { color: var(--text-muted); font-weight: 500; }

@media (max-width: 700px) {
  .tt-scroll { display: none; }
  .tt-days { display: block; }
  #classSearch { min-width: 150px; }
}

/* ---- Live "right now" board ---- */
.rn-head { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.rn-now-lbl { font-size: 0.82rem; color: var(--text-muted); }
.rn-now-time { font-size: 1.4rem; font-weight: 600; line-height: 1.1; }
.rn-head-chips { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }
.rn-period { background: rgba(55,138,221,0.16); color: #8fc0f5; border: 1px solid rgba(55,138,221,0.4); font-size: 0.85rem; font-weight: 600; padding: 4px 13px; border-radius: 999px; }
.rn-period-idle { background: var(--field); color: var(--text-muted); border-color: var(--border); }
.rn-next { font-size: 0.8rem; color: var(--text-muted); }
.rn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 11px; }
.rn-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 11px 13px; }
.rn-cl { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); letter-spacing: 0.03em; margin-bottom: 4px; }
.rn-sub { font-size: 0.98rem; font-weight: 600; line-height: 1.2; }
.rn-m { font-size: 0.74rem; color: var(--text-muted); margin-top: 2px; }
.rn-free { font-size: 0.86rem; color: var(--text-muted); }
.rn-on { border-left: 3px solid var(--gold); }
.rn-out { color: var(--text-muted); }
.rn-cover { color: var(--ok); font-weight: 600; }
.rn-needs { color: var(--flag); font-weight: 600; }
.td-cover { color: var(--ok); font-weight: 600; text-transform: uppercase; font-size: 0.72rem; letter-spacing: 0.03em; }
.gc-row { display: flex; align-items: center; gap: 10px; margin: 6px 0; flex-wrap: wrap; }
.gc-row > label { min-width: 70px; color: var(--text-dim); font-size: 0.82rem; }
.gc-row > input[type="text"], .gc-row > input[type="email"] { flex: 1 1 200px; border: 1px solid var(--border); border-radius: 8px; background: transparent; color: var(--text); padding: 6px 10px; font: inherit; font-size: 0.9rem; }
.gc-row > span { display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; flex: 1 1 200px; }
.rn-pending { border-style: dashed; opacity: 0.85; }
.rn-section { margin: 4px 0 30px; }
.rn-empty { padding: 18px; border: 1px dashed var(--border); border-radius: var(--radius); color: var(--text-muted); font-size: 0.9rem; }

/* ---- Teacher day timeline (finished / now / next) ---- */
.td-wrap { margin-bottom: 28px; }
.td-h { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.td-title { font-size: 1.05rem; font-weight: 600; }
.td-hsub { font-size: 0.85rem; color: var(--text-muted); }
.td-grid { display: grid; grid-template-columns: 1fr 1.3fr 1fr; gap: 12px; }
@media (max-width: 720px) { .td-grid { grid-template-columns: 1fr; } }
.td-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 15px 16px; }
.td-now { border: 2px solid var(--gold); background: rgba(201,162,74,0.07); }
.td-lbl { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 10px; }
.td-now .td-lbl { color: var(--gold); }
.td-sub { font-size: 1rem; font-weight: 600; line-height: 1.2; }
.td-sub-lg { font-size: 1.4rem; font-weight: 600; line-height: 1.15; }
.td-meta { font-size: 0.78rem; color: var(--text-muted); margin-top: 3px; }
.td-accent { color: var(--gold); }
.td-done { display: flex; align-items: flex-start; gap: 8px; font-size: 0.85rem; padding: 4px 0; color: var(--text-muted); }
.td-done svg { width: 15px; height: 15px; color: #6bd08a; flex: none; margin-top: 1px; }
.td-time { min-width: 38px; color: var(--text-muted); }
.td-bar { height: 5px; border-radius: 999px; background: var(--field); overflow: hidden; margin: 12px 0 5px; }
.td-bar > div { height: 100%; background: var(--gold); border-radius: 999px; }
.td-mut { font-size: 0.78rem; color: var(--text-muted); }
.td-then { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 9px; }
.td-thenline { font-size: 0.78rem; color: var(--text-muted); margin-top: 3px; }
.td-empty { padding: 14px 16px; border: 1px dashed var(--border); border-radius: var(--radius); color: var(--text-muted); font-size: 0.9rem; }

/* ---- School calendar ---- */
.cal-top { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.cal-nav { border: 1px solid var(--border); background: transparent; color: var(--text); border-radius: var(--radius-sm); width: 32px; height: 32px; cursor: pointer; font-size: 1.1rem; line-height: 1; }
.cal-nav:hover { border-color: #2f3e5e; }
.cal-mon { font-size: 1.1rem; font-weight: 600; min-width: 150px; }
.cal-today-btn { margin-left: auto; border: 1px solid var(--border); background: transparent; color: var(--text-muted); border-radius: var(--radius-sm); padding: 5px 12px; font: inherit; font-size: 0.82rem; cursor: pointer; }
.cal-today-btn:hover { border-color: #2f3e5e; color: var(--text); }
.cal-dow { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 4px; }
.cal-dow span { text-align: center; font-size: 0.7rem; font-weight: 600; color: var(--text-muted); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-c { min-height: 60px; border: 1px solid var(--border); border-radius: 8px; padding: 5px 6px; background: var(--surface); }
.cal-c-edit { cursor: pointer; }
.cal-c-edit:hover { outline: 2px solid var(--gold); outline-offset: -2px; }
.cal-n { font-size: 0.78rem; color: var(--text-muted); }
.cal-dim { opacity: 0.4; }
.cal-today { outline: 2px solid var(--gold); outline-offset: -2px; }
.cal-off { background: var(--off-bg); border-color: var(--off-bd); }
.cal-off .cal-n, .cal-off .cal-lbl { color: var(--off-fg); }
.cal-flag { background: var(--flag-bg); border-color: var(--flag-bd); }
.cal-flag .cal-n, .cal-flag .cal-lbl { color: var(--flag-fg); }
/* Weekend cell (from weekend_days config; no per-date row needed). Muted, and
   visually distinct from a holiday/break so the grid reads "normal weekend". */
.cal-weekend { background: var(--row-hover); }
.cal-weekend .cal-n { color: var(--text-muted); }
.cal-sw-weekend { background: var(--row-hover); border-color: var(--border); }
.cal-lbl { font-size: 0.66rem; font-weight: 600; margin-top: 3px; line-height: 1.2; }
.cal-legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 0.76rem; color: var(--text-muted); margin-top: 12px; }
.cal-key { display: inline-flex; align-items: center; gap: 6px; }
.cal-sw { width: 13px; height: 13px; border-radius: 3px; border: 1px solid var(--border); background: var(--field); }
.cal-sw-off { background: var(--off-bd); border-color: var(--off-fg); }
.cal-sw-flag { background: var(--flag-bd); border-color: var(--flag-fg); }
.cal-hint { font-size: 0.78rem; color: var(--text-muted); margin: 8px 0 0; }
.cal-editor { border: 2px solid var(--gold); border-radius: var(--radius); background: var(--surface); padding: 16px; margin-top: 16px; max-width: 400px; }
.cal-editor-head { font-weight: 700; margin-bottom: 12px; }
.cal-lbl2 { display: block; font-size: 0.74rem; color: var(--text-muted); margin: 10px 0 3px; }
.cal-editor input, .cal-editor select { width: 100%; }
.cal-dates { display: flex; gap: 10px; }
.cal-dates > div { flex: 1; }
.cal-toggle { display: flex; align-items: flex-start; gap: 9px; margin-top: 14px; font-size: 0.9rem; }
.cal-toggle input { width: auto; margin-top: 2px; }
.cal-hint2 { color: var(--text-muted); font-size: 0.78rem; }
.cal-editor-actions { display: flex; gap: 8px; align-items: center; margin-top: 14px; }

/* ---- Attendance register ---- */
.at-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.at-top select { flex: 0 0 180px; }
.at-classname { font-weight: 600; }
.at-nav { border: 1px solid var(--border); background: transparent; color: var(--text); border-radius: var(--radius-sm); width: 32px; height: 32px; cursor: pointer; font-size: 1.1rem; line-height: 1; }
.at-nav:hover { border-color: var(--gold); }
.at-date { font-weight: 600; min-width: 180px; }
.at-actions { margin-left: auto; display: flex; gap: 8px; }
.at-sum { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.at-pill { font-size: 0.78rem; font-weight: 600; padding: 3px 11px; border-radius: 999px; border: 1px solid var(--border); }
.at-p { background: var(--ok-bg);   color: var(--ok-fg);   border-color: var(--ok-bd); }
.at-a { background: var(--off-bg);  color: var(--off-fg);  border-color: var(--off-bd); }
.at-l { background: var(--flag-bg); color: var(--flag-fg); border-color: var(--flag-bd); }
.at-e { background: var(--info-bg); color: var(--info-fg); border-color: var(--info-bd); }
.at-roster { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.at-row { display: flex; align-items: center; gap: 12px; padding: 9px 14px; border-bottom: 1px solid var(--border); }
.at-row:last-child { border-bottom: none; }
.at-name { flex: 1; min-width: 0; font-weight: 600; font-size: 0.95rem; }
.at-seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; flex: none; }
.at-seg button { border: none; background: transparent; color: var(--text-muted); font: inherit; font-size: 0.82rem; font-weight: 600; padding: 5px 12px; cursor: pointer; border-left: 1px solid var(--border); }
.at-seg button:first-child { border-left: none; }
.at-seg button:hover { color: var(--text); }
/* selected status button gets its colour (needs class+element to beat `.at-seg button`) */
.at-seg button.at-p { background: var(--ok-bg);   color: var(--ok-fg); }
.at-seg button.at-a { background: var(--off-bg);  color: var(--off-fg); }
.at-seg button.at-l { background: var(--flag-bg); color: var(--flag-fg); }
.at-seg button.at-e { background: var(--info-bg); color: var(--info-fg); }
.at-note { flex: 0 0 150px; }
.at-note input { width: 100%; font-size: 0.82rem; }
.at-noschool { padding: 18px; border: 1px dashed var(--border); border-radius: var(--radius); color: var(--text-muted); }

/* ---- Student/parent attendance summary ---- */
.sa-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 16px 18px; max-width: 580px; }
.sa-rate { display: flex; align-items: baseline; gap: 8px; margin-bottom: 14px; }
.sa-big { font-size: 2.1rem; font-weight: 600; line-height: 1; }
.sa-sub { color: var(--text-muted); font-size: 0.85rem; }
.sa-counts { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.sa-pill { font-size: 0.78rem; font-weight: 600; padding: 3px 11px; border-radius: 999px; border: 1px solid var(--border); }
.sa-p { background: var(--ok-bg);   color: var(--ok-fg);   border-color: var(--ok-bd); }
.sa-a { background: var(--off-bg);  color: var(--off-fg);  border-color: var(--off-bd); }
.sa-l { background: var(--flag-bg); color: var(--flag-fg); border-color: var(--flag-bd); }
.sa-e { background: var(--info-bg); color: var(--info-fg); border-color: var(--info-bd); }
.sa-awaylbl { font-size: 0.74rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 2px; }
.sa-row { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-top: 1px solid var(--border); font-size: 0.88rem; }
.sa-date { flex: 0 0 140px; color: var(--text-muted); }
.sa-tag { font-size: 0.72rem; font-weight: 600; padding: 1px 9px; border-radius: 999px; }
.sa-note { color: var(--text-muted); }

/* ---- Private planner: to-dos (pl-) + lesson notes (lp-) ---- */
.planner-row { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; margin: 18px 0 6px; }
.planner-main { flex: 1 1 380px; min-width: 0; }
.planner-side { flex: 1 1 300px; min-width: 0; max-width: 460px; }
#todoSection { margin-bottom: 18px; max-width: 640px; }

.pl-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 15px 16px; }
.pl-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.pl-title { font-size: 1rem; font-weight: 600; }
.pl-lock { display: inline-flex; align-items: center; gap: 4px; font-size: 0.7rem; color: var(--gold); border: 1px solid var(--border); padding: 2px 9px; border-radius: 999px; margin-left: auto; white-space: nowrap; }
.pl-add { display: flex; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.pl-in { flex: 1 1 160px; min-width: 0; }
.pl-date { flex: 0 0 auto; }
.pl-grp { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin: 12px 0 3px; }
.pl-grp-over { color: var(--off-fg); }
.pl-todo { display: flex; align-items: center; gap: 9px; padding: 7px 0; border-top: 1px solid var(--border); font-size: 0.9rem; }
.pl-box { width: 17px; height: 17px; border-radius: 5px; border: 1.5px solid var(--text-muted); background: transparent; flex: none; cursor: pointer; position: relative; padding: 0; }
.pl-box.on { background: var(--gold); border-color: var(--gold); }
.pl-box.on::after { content: "\2713"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 0.7rem; color: #15203a; font-weight: 700; }
.pl-body { flex: 1; min-width: 0; word-break: break-word; }
.pl-link { font-size: 0.68rem; color: var(--gold); border: 1px solid var(--border); padding: 1px 8px; border-radius: 999px; white-space: nowrap; }
.pl-due { font-size: 0.68rem; padding: 1px 8px; border-radius: 999px; color: var(--text-muted); border: 1px solid var(--border); white-space: nowrap; }
.pl-due.pl-over { background: var(--off-bg); color: var(--off-fg); border-color: var(--off-bd); }
.pl-due.pl-soon { background: var(--flag-bg); color: var(--flag-fg); border-color: var(--flag-bd); }
.pl-del { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 1.15rem; line-height: 1; opacity: 0; padding: 0 2px; flex: none; }
.pl-todo:hover .pl-del { opacity: 0.7; }
.pl-del:hover { color: var(--off-fg); opacity: 1; }
.pl-donerow { opacity: 0.5; }
.pl-donerow .pl-body { text-decoration: line-through; }
.pl-none { color: var(--text-muted); font-size: 0.88rem; padding: 6px 0; }

.lp-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 15px 16px; }
.lp-datebar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.lp-nav { border: 1px solid var(--border); background: transparent; color: var(--text); border-radius: var(--radius-sm); width: 28px; height: 28px; cursor: pointer; font-size: 1rem; line-height: 1; }
.lp-nav:hover { border-color: var(--gold); }
.lp-date { font-weight: 600; min-width: 150px; }
.lp-hint { font-size: 0.72rem; color: var(--text-muted); margin-left: auto; }
.lp-lesson { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 8px; }
.lp-lrow { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.lp-per { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); }
.lp-sub { font-weight: 600; }
.lp-meta { font-size: 0.82rem; color: var(--text-muted); }
.lp-body { margin-top: 7px; }
.lp-note { display: flex; gap: 8px; align-items: flex-start; font-size: 0.88rem; color: var(--text); background: var(--field); border-left: 2px solid var(--gold); border-radius: 0 6px 6px 0; padding: 6px 10px; }
.lp-note span { flex: 1; min-width: 0; word-break: break-word; }
.lp-edit { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 0; flex: none; }
.lp-edit:hover { color: var(--gold); }
.lp-addnote { background: none; border: none; color: var(--gold); cursor: pointer; font-size: 0.8rem; padding: 2px 0; }
.lp-todobtn { display: block; background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 0.78rem; padding: 2px 0; margin-top: 4px; }
.lp-todobtn:hover { color: var(--gold); }
.lp-editor { margin-top: 6px; }
.lp-ta, .lp-ti { width: 100%; font: inherit; }
.lp-ta { resize: vertical; }
.lp-ebtns { display: flex; gap: 6px; margin-top: 6px; }
.lp-todoadd { margin-top: 8px; }
.lp-empty { color: var(--text-muted); font-size: 0.88rem; padding: 8px 0; }

/* ---- Homework: teacher lesson set (hw-set/lp-hwbtn) + student assignments card ---- */
.hw-set { display: flex; align-items: flex-start; gap: 8px; font-size: 0.85rem; background: var(--info-bg); border-left: 2px solid var(--info-fg); border-radius: 0 6px 6px 0; padding: 6px 10px; margin-bottom: 6px; }
.hw-sethead { flex: 1; min-width: 0; word-break: break-word; }
.hw-setdue { color: var(--text-muted); font-size: 0.8rem; }
.hw-setlink { color: var(--info-fg); }
.hw-setact { display: inline-flex; gap: 4px; flex: none; }
.hw-del { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 1.05rem; line-height: 1; padding: 0 2px; }
.hw-del:hover { color: var(--off-fg); }
.lp-hwbtn { display: block; background: none; border: none; color: var(--info-fg); cursor: pointer; font-size: 0.8rem; padding: 2px 0; margin-top: 2px; }
.hw-ed-inline input, .hw-ed-inline textarea { width: 100%; font: inherit; box-sizing: border-box; margin-bottom: 6px; }
.hw-ed-inline textarea { resize: vertical; }
.hw-frow { display: flex; gap: 8px; }
.hw-frow input { flex: 1; min-width: 0; }
.hw-sharenote { font-size: 0.72rem; color: var(--info-fg); display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }

.hw-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 6px 16px 14px; max-width: 640px; }
.hw-grp { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin: 14px 0 4px; }
/* Assignment rows became separated tinted rows rather than a hairline list. A
   family reads this to answer "is anything outstanding", which is a scan, not a
   read - so each item needs an edge. */
.hw-item {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 11px 13px; margin-bottom: 7px;
  background-color: var(--field);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
}
.hw-item:hover { border-color: var(--border); }
.hw-tag {
  flex: 0 0 auto; font-size: 0.7rem; font-weight: 700; color: var(--ring-marks);
  background-color: var(--wash-marks); border-radius: 999px; padding: 3px 10px;
  word-break: break-word; text-transform: uppercase; letter-spacing: .04em;
}
.hw-itembody { flex: 1; min-width: 0; }
.hw-title { font-weight: 600; font-size: 0.95rem; word-break: break-word; }
.hw-desc { font-size: 0.82rem; color: var(--text-muted); margin-top: 1px; word-break: break-word; }
.hw-due { font-size: 0.72rem; color: var(--text-muted); white-space: nowrap; flex: none; }
.hw-due.hw-soon { color: var(--flag-fg); font-weight: 600; }

/* ---- Homework management page (/app/homework) ---- */
#hwForm select, #hwForm input, #hwForm textarea { width: 100%; box-sizing: border-box; font: inherit; }
#hwForm textarea { resize: vertical; }
.hm-flabel { display: block; font-size: 0.72rem; color: var(--text-muted); margin: 9px 0 3px; }
.hm-frow { display: flex; gap: 10px; }
.hm-frow > div { flex: 1; min-width: 0; }
.hm-fact { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.hm-share { margin-left: auto; font-size: 0.72rem; color: var(--info-fg); display: inline-flex; align-items: center; gap: 4px; }
.hm-list { max-width: 720px; }
.hm-grp { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin: 16px 0 4px; }
.hm-item { display: flex; gap: 12px; align-items: flex-start; padding: 11px 0; border-top: 1px solid var(--border); }
.hm-meta { flex: 0 0 130px; }
.hm-cls { font-size: 0.78rem; font-weight: 600; color: var(--info-fg); word-break: break-word; }
.hm-when { font-size: 0.72rem; color: var(--text-muted); margin-top: 2px; }
.hm-pin { font-size: 0.68rem; color: var(--text-muted); display: inline-flex; align-items: center; gap: 3px; margin-top: 3px; }
.hm-body { flex: 1; min-width: 0; }
.hm-title { font-weight: 600; font-size: 0.95rem; word-break: break-word; }
.hm-desc { font-size: 0.82rem; color: var(--text-muted); margin-top: 1px; word-break: break-word; }
.hm-due { font-size: 0.72rem; color: var(--text-muted); white-space: nowrap; flex: none; }
.hm-due.hm-soon { color: var(--flag-fg); font-weight: 600; }
.hm-iacts { display: flex; gap: 6px; flex: none; }
.hm-ib { background: none; border: 1px solid var(--border); border-radius: 8px; color: var(--text-muted); width: 30px; height: 28px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.hm-ib:hover { border-color: var(--gold); color: var(--text); }
.hm-ib.hm-danger:hover { border-color: var(--off-fg); color: var(--off-fg); }
.hm-past { opacity: 0.62; }
.hm-empty { color: var(--text-muted); padding: 8px 0; }

/* ---- Homework marking (teacher) + homework marks (student) ---- */
.hk-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.hk-title { font-weight: 600; font-size: 1.05rem; }
.hk-meta { font-size: 0.82rem; color: var(--text-muted); }
.hk-pts { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 3px; font-size: 0.85rem; }
.hk-pts input { width: 46px; }
.hk-max { color: var(--text-muted); }
.hwm-head { display: flex; align-items: baseline; gap: 8px; margin: 6px 0; }
.hwm-big { font-size: 1.9rem; font-weight: 600; line-height: 1; }
.hwm-sub { font-size: 0.8rem; color: var(--text-muted); }
.hwm-comp { font-size: 0.82rem; color: var(--text-muted); margin-bottom: 6px; }
.hwm-score { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; flex: none; }
.hg-cap { font-size: 0.82rem; color: var(--text-muted); margin-bottom: 8px; }
.hg-empty { color: var(--text-muted); padding: 8px 0; font-size: 0.9rem; }
.hg-hh { max-width: 110px; vertical-align: bottom; }
.hg-sub { font-size: 0.66rem; color: var(--text-muted); font-weight: 400; }
.hg-c { text-align: center; }
.hg-pill { display: inline-block; min-width: 22px; padding: 1px 6px; border-radius: 999px; font-size: 0.74rem; font-weight: 600; }
.hg-done { background: var(--ok-bg); color: var(--ok-fg); }
.hg-late { background: var(--flag-bg); color: var(--flag-fg); }
.hg-missing { background: var(--off-bg); color: var(--off-fg); }
.hg-due-inline { color: var(--text-muted); font-size: 0.85em; }

/* ---- Staff provisioning (/app/staff) ---- */
.sp-banner { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; background: var(--info-bg); color: var(--info-fg); border: 1px solid var(--info-bd); border-radius: var(--radius-sm); padding: 9px 13px; margin-bottom: 16px; }
.sp-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 16px 18px; max-width: 720px; }
#staffInput input, #staffInput select { background: var(--field); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; font: inherit; }
#staffInput input:focus, #staffInput select:focus { outline: none; border-color: var(--blue); }
.sp-in { width: 100%; box-sizing: border-box; }
.sp-row2 { display: flex; gap: 12px; flex-wrap: wrap; }
.sp-row2 > div { flex: 1 1 240px; min-width: 0; }
.sp-lab { display: block; font-size: 0.72rem; color: var(--text-muted); margin: 12px 0 4px; }
.sp-seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.sp-seg button { border: none; background: transparent; color: var(--text-muted); font: inherit; font-size: 0.88rem; padding: 7px 16px; cursor: pointer; border-left: 1px solid var(--border); }
.sp-seg button:first-child { border-left: none; }
.sp-seg button.on { background: var(--blue); color: #fff; }
.sp-checks { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.sp-check { font-size: 0.88rem; display: inline-flex; align-items: center; gap: 6px; }
.sp-pair { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.sp-pair select { flex: 1 1 160px; min-width: 0; }
.sp-chipwrap { margin-top: 8px; }
.sp-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 0.78rem; padding: 3px 4px 3px 11px; border-radius: 999px; background: var(--ok-bg); color: var(--ok-fg); border: 1px solid var(--ok-bd); margin: 0 6px 6px 0; }
.sp-chip.hr { background: var(--info-bg); color: var(--info-fg); border-color: var(--info-bd); }
.sp-chip .x { background: none; border: none; color: inherit; cursor: pointer; font-size: 0.95rem; line-height: 1; padding: 0 3px; opacity: 0.7; }
.sp-chip .x:hover { opacity: 1; }
.sp-warnline { color: var(--flag-fg); font-size: 0.8rem; margin-top: 4px; }
.sp-actions { display: flex; align-items: center; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.sp-mini { font-size: 0.78rem; color: var(--text-muted); }
.sp-tag { font-size: 0.72rem; padding: 1px 9px; border-radius: 999px; border: 1px solid var(--border); }
.sp-pend { background: var(--flag-bg); color: var(--flag-fg); border-color: var(--flag-bd); }
.sp-iact { background: none; border: 1px solid var(--border); border-radius: 7px; color: var(--text-muted); padding: 4px 10px; cursor: pointer; font-size: 0.82rem; }
.sp-iact:hover { border-color: var(--off-fg); color: var(--off-fg); }
.sp-empty { color: var(--text-muted); padding: 8px 0; }
#staffInput textarea { background: var(--field); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; }
#staffInput textarea:focus { outline: none; border-color: var(--blue); }
.mp-hint { font-size: 0.78rem; color: var(--text-muted); background: var(--field); border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 10px; line-height: 1.5; }
.mp-hint code { color: var(--gold); }
.mp-ta { width: 100%; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.78rem; min-height: 96px; resize: vertical; color: var(--text); background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; }
.mp-ta:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(37, 99, 196, 0.25); }
.mp-ta::placeholder { color: #5d6c87; }
.mp-ok { color: var(--ok-fg); }
.mp-bad { color: var(--off-fg); }
.mp-warn { color: var(--flag-fg); }
.mp-rowbad td { background: var(--off-bg); }
.mp-rep th, .mp-rep td { font-size: 0.82rem; padding: 8px 9px; white-space: normal; }
.sp-t-ok { background: var(--ok-bg); color: var(--ok-fg); border-color: var(--ok-bd); }
.sp-t-bad { background: var(--off-bg); color: var(--off-fg); border-color: var(--off-bd); }
.sp-t-warn { background: var(--flag-bg); color: var(--flag-fg); border-color: var(--flag-bd); }

/* student intake: monospace ID column, match-report summary line, single-add inline result */
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.3px; }
.mat-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.95rem; font-weight: 700; letter-spacing: 1.2px; color: var(--text); background: var(--field); border: 1px dashed var(--border); border-radius: 6px; padding: 2px 9px; display: inline-block; }
.mp-sumline { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.sp-result { margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-sm); font-size: 0.85rem; line-height: 1.5; }
.sp-r-ok { color: var(--ok-fg); background: var(--ok-bg); border: 1px solid var(--ok-bd); }
.sp-r-warn { color: var(--flag-fg); background: var(--flag-bg); border: 1px solid var(--flag-bd); }

/* ---- Staff activation panel ---- */
.av-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 16px 18px; }
.av-mini { font-size: 0.78rem; color: var(--text-muted); }
.av-sum { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 12px; }
.av-pill { font-size: 0.78rem; font-weight: 600; padding: 3px 11px; border-radius: 999px; border: 1px solid var(--border); color: var(--text-muted); }
.av-pill.av-inv { background: var(--info-bg); color: var(--info-fg); border-color: var(--info-bd); }
.av-pill.av-reuse { background: var(--ok-bg); color: var(--ok-fg); border-color: var(--ok-bd); }
.av-pill.av-fail { background: var(--off-bg); color: var(--off-fg); border-color: var(--off-bd); }
.av-pill.av-skip { background: var(--flag-bg); color: var(--flag-fg); border-color: var(--flag-bd); }
.av-tbl th, .av-tbl td { font-size: 0.82rem; padding: 8px 9px; white-space: normal; }
.av-tag { font-size: 0.72rem; font-weight: 600; padding: 1px 9px; border-radius: 999px; }
.av-t-inv { background: var(--info-bg); color: var(--info-fg); }
.av-t-reuse { background: var(--ok-bg); color: var(--ok-fg); }
.av-t-skip { background: rgba(120,130,150,0.15); color: var(--text-muted); }
.av-t-fail { background: var(--off-bg); color: var(--off-fg); }
.av-flag { font-size: 0.72rem; color: var(--flag-fg); }
.av-confirmbar { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; border-top: 1px solid var(--border); padding-top: 14px; }
.av-warn { font-size: 0.78rem; color: var(--flag-fg); }

/* Student detail header */
.student-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 22px; }
.student-actions { margin-left: auto; display: flex; gap: 10px; flex: none; align-items: center; }
.student-actions .btn { text-decoration: none; }

/* Summary | Summatives view switch */
.seg { display: inline-flex; background-color: var(--field); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 3px; gap: 3px; }
.seg-btn {
  background: transparent; border: none; color: var(--text-muted);
  font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer;
  padding: 6px 14px; border-radius: 999px;
}
.seg-btn:hover { color: var(--text); }
.seg-btn.active { background-color: var(--blue); color: #fff; }

/* Summatives table */
table.data.sums th.grp { text-align: center; color: var(--text-muted); border-left: 1px solid var(--border); }
table.data.sums .sum-cell { text-align: center; padding-left: 10px; padding-right: 10px; }
table.data.sums tbody td:first-child { position: sticky; left: 0; background-color: var(--surface); }
.sums-note { color: var(--text-muted); font-size: 0.85rem; margin: 10px 2px 0; }

/* Summatives chain table (the expanded summary) */
table.data.chain { font-size: 0.85rem; }
table.data.chain th, table.data.chain td { padding: 6px 8px; text-align: center; white-space: nowrap; }
table.data.chain th.grp { color: var(--text-muted); border-left: 1px solid var(--border); }
table.data.chain td.roll, table.data.chain th.roll { background-color: var(--row-hover); }
table.data.chain .roll-start { border-left: 2px solid var(--border); }
table.data.chain .roll-pct { font-weight: 700; }
table.data.chain td.col-subj, table.data.chain th.col-subj {
  position: sticky; left: 0; background-color: var(--surface);
  text-align: left; font-weight: 600; z-index: 1;
}

/* Performance charts */
.perf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.chart-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; min-width: 0; }
.chart-title { font-size: 0.98rem; font-weight: 700; margin: 0 0 14px; }
.chart .state { padding: 18px; }
.bar-row { display: grid; grid-template-columns: 124px 1fr 66px; align-items: center; gap: 10px; margin-bottom: 8px; font-size: 0.85rem; }
.bar-label { color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track { background: var(--ring-track); border-radius: 999px; height: 12px; overflow: hidden; }
/* display:block is LOAD-BEARING. bar-fill is a <span>, and an inline element
   ignores width and height entirely - so every bar in the app (Analysis
   distributions, subject snapshots, invigilation load) was drawing an empty
   track with no fill at all. The height:100% and width:N% were being computed
   and discarded. */
.bar-fill { display: block; height: 100%; border-radius: 999px; min-width: 3px; }
.bar-val { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.barc-5 { background: #3fa067; }
.barc-4 { background: var(--gold); }
.barc-3 { background: #5b6b86; }
.barc-low { background: #c0654f; }
.traj-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; font-size: 0.95rem; color: var(--text-muted); }
.traj-head b { color: var(--text); }
.traj-arrow { opacity: 0.55; }
.delta { font-weight: 700; font-variant-numeric: tabular-nums; }
.delta-up { color: var(--ok-fg); }
.delta-down { color: var(--off-fg); }
.delta-steady { color: var(--text-muted); }
.traj-row { display: grid; grid-template-columns: 124px 1fr 58px; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 0.85rem; }
.traj-bars { display: flex; flex-direction: column; gap: 4px; }
.tbar { height: 7px; border-radius: 4px; min-width: 2px; }
.tbar-s1 { background: #3a4a66; }
.tbar-s2 { background: var(--blue); }
.delta-mini { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; font-size: 0.8rem; }
@media (max-width: 760px) { .perf-grid { grid-template-columns: 1fr; } }

/* Teacher assignment sections */
.t-assignment { margin-bottom: 28px; }
.t-assignment .banner { margin-top: 4px; }

/* Student-vs-class comparison legend */
.cmp-legend { display: flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: 0.85rem; margin-bottom: 14px; }
.cmp-legend .sw { display: inline-block; width: 13px; height: 9px; border-radius: 3px; margin: 0 5px 0 12px; vertical-align: middle; }
.cmp-legend .sw:first-child { margin-left: 0; }
.cmp-legend .sw-student { background: var(--blue); }
.cmp-legend .sw-class { background: #3a4a66; }

/* Mark-entry editor */
.row-actions { display: flex; gap: 10px; align-items: center; justify-content: flex-end; margin-bottom: 14px; }
.edit-toolbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
.edit-term { color: var(--text-muted); font-size: 0.9rem; display: flex; align-items: center; gap: 8px; }
.edit-hint { color: var(--text-muted); font-size: 0.85rem; margin: 0 0 14px; }
table.edit-grid td { padding: 3px; }
table.edit-grid .cell-in {
  width: 58px; text-align: center; font: inherit; font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  color: var(--text); background-color: var(--field);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 4px;
}
table.edit-grid .cell-in:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 2px rgba(37,99,196,0.3); }
table.edit-grid .cell-in.cell-changed { border-color: var(--gold); background-color: rgba(201,162,74,0.12); }
/* collapsed range component: the derived monthly average (display-only) */
table.edit-grid td.me-derived { text-align: center; color: var(--text-muted); font-weight: 600; font-variant-numeric: tabular-nums; font-style: italic; }
/* Per-semester colour blocks + dividers in the editor grid (like the report card) */
table.edit-grid td.g-s1, table.edit-grid th.g-s1 { background-color: rgba(63,160,103,0.08); }
table.edit-grid td.g-s2, table.edit-grid th.g-s2 { background-color: rgba(201,162,74,0.08); }
table.edit-grid td.g-yr, table.edit-grid th.g-yr { background-color: rgba(37,99,196,0.10); }
table.edit-grid .gs-start { border-left: 3px solid var(--gold) !important; }

.review-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; margin-top: 16px; }
.banner.banner-bad { background-color: rgba(224,107,107,0.10); border-color: rgba(224,107,107,0.45); }
.banner.banner-bad svg, .banner.banner-bad strong { color: var(--off-fg); }

/* ---- Breadcrumb ---- */
.crumbs { display: flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: 0.92rem; margin-bottom: 14px; }
.crumbs a { color: var(--text-muted); }
.crumbs a:hover { color: var(--text); }
.crumbs .sep { opacity: 0.5; }

/* ---- Data-issue banner ---- */
.banner {
  display: flex; align-items: flex-start; gap: 12px;
  background-color: rgba(201,162,74,0.10);
  border: 1px solid rgba(201,162,74,0.45);
  border-radius: var(--radius);
  padding: 14px 16px; margin-bottom: 20px;
}
.banner svg { width: 20px; height: 20px; color: var(--gold); flex: none; margin-top: 1px; }
.banner-text { font-size: 0.95rem; }
.banner-text strong { color: var(--gold); }

/* ---- Tables ---- */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background-color: var(--surface); }
table.data { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
table.data th, table.data td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
table.data thead th { color: var(--text-muted); font-size: 0.82rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr.clickable { cursor: pointer; }
table.data tbody tr.clickable:hover { background-color: var(--row-hover); }
td.num, th.num { font-variant-numeric: tabular-nums; }
tr.row-flagged { background-color: rgba(201,162,74,0.06); }
.warn-dot { color: var(--gold); margin-left: 6px; }

/* ---- Score chips ---- */
.chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; padding: 3px 9px; border-radius: 999px;
  font-weight: 700; font-size: 0.85rem; font-variant-numeric: tabular-nums;
}
.chip-good { background-color: var(--ok-bg);   color: var(--ok-fg);   border: 1px solid var(--ok-bd); }
.chip-ok   { background-color: var(--flag-bg); color: var(--flag-fg); border: 1px solid var(--flag-bd); }
.chip-mid  { background-color: rgba(159,176,204,0.14); color: var(--text-muted); border: 1px solid var(--border); }
.chip-low  { background-color: var(--off-bg);  color: var(--off-fg);  border: 1px solid var(--off-bd); }
.chip-none { background-color: transparent; color: var(--text-muted); border: 1px solid var(--border); }

/* ---- Misc states ---- */
.state { padding: 40px; text-align: center; color: var(--text-muted); }
.state.error { color: var(--danger); }
.link-btn { color: var(--blue); font-weight: 600; }
.link-btn:hover { color: var(--blue-hover); }

/* ---- Responsive: collapse sidebar ---- */
@media (max-width: 900px) {
  .app-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0; width: 210px; z-index: 40;
    transform: translateX(-100%); transition: transform 0.2s ease;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-backdrop {
    display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 30;
  }
  .sidebar-backdrop.show { display: block; }
  .icon-btn { display: inline-flex; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .content { padding: 20px 16px; }
  .topbar { padding: 12px 16px; }
}
@media (max-width: 520px) {
  .cards { grid-template-columns: 1fr; }
  .topbar-school { display: none; }
}
/* Student page uses 3 summary cards; a responsive modifier (two classes = beats the
   inline override problem) so they stack on a phone instead of squeezing to 3-across. */
.cards.cards-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) { .cards.cards-3 { grid-template-columns: 1fr; } }

/* ---- Classes tab: grade groups ---- */
.grade-group { margin-bottom: 28px; }
.grade-group:last-child { margin-bottom: 0; }

/* ---- Students tab: search ---- */
.search-row { position: relative; max-width: 460px; margin: 0 0 18px; }
.search-row .search-icon {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--text-muted); pointer-events: none;
}
.search-input {
  width: 100%; background-color: var(--field); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px 14px 11px 40px; font: inherit; font-size: 0.95rem;
}
.search-input::placeholder { color: #5d6c87; }
.search-input:focus { outline: none; border-color: var(--blue); }
.list-controls { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 18px; }
.list-controls .search-row { margin: 0; flex: 1 1 320px; }
.sort-control { display: flex; flex-direction: column; gap: 6px; color: var(--text-muted); font-size: 0.85rem; font-weight: 700; }
.sort-control .lens-select { font-weight: 600; }

/* ---- Reports tab: generation card ---- */
.gen-card {
  background-color: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 22px;
  display: grid; grid-template-columns: 1fr 1fr auto; gap: 20px; align-items: end;
}
.gen-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.gen-field label { color: var(--text-muted); font-size: 0.85rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.gen-field .lens-select { width: 100%; }
.gen-hint { color: var(--text-muted); font-size: 0.82rem; margin: 2px 0 0; }
.gen-actions { display: flex; align-items: flex-end; }
@media (max-width: 760px) {
  .gen-card { grid-template-columns: 1fr; align-items: stretch; }
  .gen-actions .btn { width: 100%; }
}


/* Parent fee view (F3) */
.fees-table { width: 100%; border-collapse: collapse; }
.fees-table th, .fees-table td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border); font-size: 14px; }
.fees-table th { color: var(--text-dim); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; }
.fees-table .fees-num, .fees-table th.fees-num { text-align: right; font-variant-numeric: tabular-nums; }
.fees-conc { color: var(--text-dim); font-size: 12px; }
