:root {
  color-scheme: light;
  /* Insights donut palette: blue = main value, cyan = new sections,
     amber = needs attention, track = unfilled. */
  --donut-blue: #1f6fe0;
  --donut-cyan: #1596a6;
  --donut-amber: #d98a0b;
  --donut-track: #dbe6f4;
  /* Shared ring (tis-ring.css) palette, round 4: violet = further category,
     slate = "other"; the extended tones only serve partitions with more than
     five categories and carry no meaning. */
  --donut-violet: #6d5bd6;
  --donut-slate: #5f7595;
  --donut-green: #0d8a56;
  --donut-rose: #c0436e;
  --donut-teal: #0f7f7a;
  --donut-gold: #9a7b12;
  --donut-halo: 14%;
  --donut-drop: rgba(15, 35, 70, 0.22);
  /* Premium surface tokens (tis-surface.css consumes them). */
  --tis-elev-1: 0 1px 2px rgba(27, 69, 110, 0.12);
  --tis-elev-2: 0 8px 22px rgba(27, 69, 110, 0.12);
  --tis-elev-3: 0 20px 44px rgba(27, 69, 110, 0.2), 0 0 0 1px color-mix(in srgb, #1f6fe0 30%, transparent);
  --tis-radius-sm: 10px;
  --tis-radius-md: 14px;
  --tis-radius-lg: 18px;
  --tis-radius-xl: 20px;
  --tis-accent: #1f6fe0;
  --tis-accent-ink: #1f6fe0;
  --tis-ok: #0d8a56;
  --tis-warn: #b26b00;
  --tis-btn-primary: linear-gradient(180deg, #2f80f2, #1f6fe0);
  --tis-focus-ring: #1f6fe0;
  --tis-motion-fast: 150ms;
  --tis-motion-chart: 1200ms;
}
html,
body {
  overflow-x: clip;
}
[data-theme="dark"] {
  color-scheme: dark;
  --donut-blue: #3b8cff;
  --donut-cyan: #2cc1cf;
  --donut-amber: #f0b44c;
  --donut-track: #1c3f66;
  --donut-violet: #8b7cf6;
  --donut-slate: #7d93b3;
  --donut-green: #4fd39a;
  --donut-rose: #f27aa0;
  --donut-teal: #3fc6bd;
  --donut-gold: #d9c25a;
  --donut-halo: 28%;
  --donut-drop: rgba(0, 4, 14, 0.55);
  --tis-elev-1: 0 1px 2px rgba(0, 6, 20, 0.25);
  --tis-elev-2: 0 10px 28px rgba(0, 6, 20, 0.38);
  --tis-elev-3: 0 22px 50px rgba(0, 6, 20, 0.5), 0 0 0 1px color-mix(in srgb, #3b8cff 30%, transparent);
  --tis-accent: #3b8cff;
  --tis-accent-ink: #7ab6ff;
  --tis-ok: #4fd39a;
  --tis-warn: #f0b44c;
  --tis-btn-primary: linear-gradient(180deg, #3d8dff, #2a6fd8);
  --tis-focus-ring: #7ab6ff;
  --app-bg: #06172d;
  --app-bg-strong: #020f22;
  --app-surface: #0b213d;
  --app-surface-strong: #0e2949;
  --app-surface-muted: #102b4c;
  --app-line: #21476f;
  --app-line-strong: #32618f;
  --app-ink: #f3f7ff;
  --app-muted: #a9bfdb;
  --app-brand: #54a8ff;
  --app-brand-deep: #d7eaff;
  --app-brand-soft: #123c6b;
  --app-shadow: 0 18px 44px rgba(0, 4, 14, 0.38);
  --app-shadow-sm: 0 8px 22px rgba(0, 4, 14, 0.28);
  --app-shadow-md: 0 14px 32px rgba(0, 4, 14, 0.34);
  --app-focus-ring: 0 0 0 3px rgba(65, 157, 255, 0.32);
  --bg: #06172d;
  --bg-1: #06172d;
  --bg-2: #020f22;
  --card: #0b213d;
  --line: var(--app-line);
  --ink: var(--app-ink);
  --muted: var(--app-muted);
  --brand: var(--app-brand);
  --brand-dark: #8fc7ff;
  --brand-deep: #d7eaff;
  --app-icon-default: #8fc7ff;
  --app-icon-shell: #8fc7ff;
  --app-icon-shell-active: #d8ecff;
}
[data-theme="dark"] body {
  background:
    radial-gradient(
      circle at 82% 10%,
      rgba(18, 78, 139, 0.22),
      transparent 28%
    ),
    linear-gradient(145deg, #06172d, #020f22);
  color: var(--app-ink);
}
[data-theme="dark"] .app-sidebar {
  border-color: #173c63;
  background: linear-gradient(180deg, #071b34, #04142a);
  color: var(--app-ink);
  box-shadow: 0 18px 44px rgba(0, 4, 14, 0.42);
}
[data-theme="dark"] .sidebar-section-title,
[data-theme="dark"] .sidebar-tree-link {
  color: #a9c5e7;
}
[data-theme="dark"] .sidebar-section,
[data-theme="dark"] .sidebar-tree {
  border-color: #22486f;
}
[data-theme="dark"] .sidebar-link {
  color: #dceaff;
}
[data-theme="dark"] .sidebar-link:hover {
  border-color: #285888;
  background: #0d3158;
}
[data-theme="dark"] .sidebar-link.is-active {
  border-color: #245d99;
  background: linear-gradient(90deg, #10437a, #0b2e57);
  color: #fff;
}
[data-theme="dark"] .sidebar-tree-link:hover,
[data-theme="dark"] .sidebar-tree-link.is-active {
  background: #0d3158;
  color: #e9f4ff;
}
[data-theme="dark"] .sidebar-config-card,
[data-theme="dark"] .sidebar-account {
  border-color: #20476f;
  background: #0a203b;
  color: var(--app-ink);
}
[data-theme="dark"] .sidebar-config-card p,
[data-theme="dark"] .sidebar-config-card label,
[data-theme="dark"] .sidebar-account-copy span,
[data-theme="dark"] .sidebar-photo-help {
  color: var(--app-muted);
}
[data-theme="dark"] .sidebar-config-card select,
[data-theme="dark"] .sidebar-config-card input,
[data-theme="dark"] .sidebar-config-btn,
[data-theme="dark"] .sidebar-config-link,
[data-theme="dark"] .sidebar-logout {
  border-color: #28527d;
  background: #081b33;
  color: var(--app-ink);
}
[data-theme="dark"] .app-header,
[data-theme="dark"] .page-panel,
[data-theme="dark"] .configuration-sections,
[data-theme="dark"] .config-tree {
  border-color: var(--app-line);
  background: rgba(8, 29, 54, 0.94);
  box-shadow: var(--app-shadow);
}
[data-theme="dark"] .header-chip,
[data-theme="dark"] .header-user-chip {
  border-color: #244d77;
  background: #0d2745;
  color: var(--app-ink);
}
/* Logos sit directly on the header in both themes (no plate or box). Dark uses
   the organization's "light" logo in place of the primary when one is uploaded
   (see .header-logo-for-dark in app-shell.css). */
[data-theme="dark"] .header-tenant-logo-slot {
  border: 0;
  background: transparent;
}
[data-theme="dark"] .header-chip span,
[data-theme="dark"] .header-user-copy small,
[data-theme="dark"] .header-logo-placeholder span {
  color: var(--app-muted);
}
[data-theme="dark"] .header-logo-placeholder {
  border-color: #28527d;
  background: #091d36;
}
[data-theme="dark"] .header-logo-placeholder strong {
  color: #d7eaff;
}
[data-theme="dark"] .page-title,
[data-theme="dark"] .config-hero h2,
[data-theme="dark"] .config-copy strong,
[data-theme="dark"] .configuration-sections h2 {
  color: var(--app-ink);
}
[data-theme="dark"] .config-hero p,
[data-theme="dark"] .config-copy span {
  color: var(--app-muted);
}
[data-theme="dark"] .config-search,
[data-theme="dark"] input,
[data-theme="dark"] select,
[data-theme="dark"] textarea {
  border-color: #28527d !important;
  background: #091d36 !important;
  color: var(--app-ink) !important;
}
/* The generic input/select/textarea rule above sets `background` as a
   shorthand, which resets every unspecified sub-property (including
   background-image) to its initial value. .search inputs (Planning,
   Subjects, Teachers, Users toolbars) paint their magnifier glyph via a
   light-mode-tuned inline SVG background-image, so the shorthand silently
   deleted the icon in dark mode. Restore it here with a light-stroke
   variant instead of relying on the light-mode declaration. */
[data-theme="dark"] .page-stage .search {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fc7ff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: 10px center !important;
  background-size: 14px 14px !important;
}
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
  color: #7894b5;
}
[data-theme="dark"] .config-node,
[data-theme="dark"] .config-child {
  border-color: #244d77;
  background: #0a203b;
  color: var(--app-ink);
}
[data-theme="dark"] .config-node[open] {
  border-color: #3b8ee7;
  background: linear-gradient(100deg, #0c2b4f, #0a213e);
}
[data-theme="dark"] .config-row:hover {
  background: #102d50;
}
[data-theme="dark"] .config-children {
  border-color: #315e8b;
}
[data-theme="dark"] .configuration-section-link {
  color: #c9dcf3;
}
[data-theme="dark"] .configuration-section-link:hover {
  border-color: #28527d;
  background: #102b4c;
}
[data-theme="dark"] .configuration-section-link.is-active {
  border-color: #2589ff;
  background: linear-gradient(90deg, #0d4d91, #103a69);
  color: #fff;
  box-shadow: 0 0 18px rgba(26, 132, 255, 0.24);
}
[data-theme="dark"]
  :is(
    .school-list,
    .school-main,
    .section-card,
    .role-panel,
    .permission-card,
    .year-card,
    .qualification-card,
    .settings-card,
    .calendar-card,
    .logo-panel,
    .design-panel,
    .top,
    .card
  ) {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
  box-shadow: var(--app-shadow-sm) !important;
}
[data-theme="dark"]
  :is(
    .school-list,
    .school-main,
    .section-card,
    .role-panel,
    .permission-card,
    .year-card,
    .qualification-card,
    .settings-card,
    .calendar-card,
    .logo-panel,
    .design-panel,
    .top,
    .card
  )
  :is(h1, h2, h3, h4, strong) {
  color: var(--app-ink) !important;
}
[data-theme="dark"]
  :is(
    .school-list,
    .school-main,
    .section-card,
    .role-panel,
    .permission-card,
    .year-card,
    .qualification-card,
    .settings-card,
    .calendar-card,
    .logo-panel,
    .design-panel,
    .top,
    .card
  )
  :is(p, small, label, span) {
  border-color: var(--app-line);
  color: var(--app-muted);
}
[data-theme="dark"]
  :is(
    .school-link,
    .school-tab,
    .role-tab,
    .role-mode-tab,
    .action-btn-secondary,
    .branch-filter-bar,
    .table-wrap,
    .usage-chip,
    .capacity-notice,
    .logo-strip
  ) {
  border-color: var(--app-line) !important;
  background: #0d2745 !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"]
  :is(.school-link, .school-tab, .role-tab, .role-mode-tab).is-active {
  border-color: #328df0 !important;
  background: #103b69 !important;
  color: #fff !important;
}
[data-theme="dark"] table {
  color: var(--app-ink);
}
[data-theme="dark"] :is(th, td) {
  border-color: #21476f !important;
}
[data-theme="dark"] th {
  color: #a9bfdb !important;
  background: #102b4c !important;
}
[data-theme="dark"] dialog,
[data-theme="dark"] .modal,
[data-theme="dark"] [role="dialog"] {
  border-color: var(--app-line) !important;
  background: var(--app-surface-strong) !important;
  color: var(--app-ink) !important;
}

/* Application-wide dark component layer. Page templates keep their approved
   layouts; shared semantic surfaces absorb the theme instead of being inverted. */
[data-theme="dark"] {
  --app-text: var(--app-ink);
  --app-text-muted: var(--app-muted);
  --app-border: var(--app-line);
  --surface: var(--app-surface);
  --surface-2: var(--app-surface-strong);
  --panel: var(--app-surface);
  --border: var(--app-line);
  --text: var(--app-ink);
  --text-muted: var(--app-muted);
  --primary: #218cff;
}
[data-theme="dark"] :is(.app-shell, .app-main, .page-stage, .page-content) {
  color: var(--app-ink);
}
[data-theme="dark"] .page-stage
  :is(
    .panel,
    .workspace,
    .surface,
    .content-card,
    .metric-card,
    .stat-card,
    .summary-card,
    .form-card,
    .filter-card,
    .table-card,
    .list-card,
    .detail-card,
    .info-card,
    .profile-card,
    .settings-panel,
    .modal-card,
    .dropdown-menu,
    .empty-state,
    .empty,
    .filters,
    .filter-bar,
    .toolbar,
    .tabs,
    .pagination,
    .tp-card,
    .tp-program-card,
    .tp-table-wrap
  ) {
  border-color: var(--app-line) !important;
  background-color: var(--app-surface) !important;
  color: var(--app-ink) !important;
}
/* Round 3 systemic-gap correction (2026-09-27): the suffix contract only
   ever covered -card/-panel/-workspace, but a repository-wide audit of every
   template's inline <style> block found the same "flat surface, never
   themed" pattern repeated under a dozen other component-name suffixes
   (buttons, rows, sections/groups, list items, headers, close controls,
   detail blocks, notes, menus/popups, search boxes, option rows) across
   academic_calendar, dashboard (Subject Sufficiency/hiring), edit_teacher/
   teachers (assignment suggestions, qualification dropdowns), notifications,
   observation_detail/observation_form, platform_console/knowledge_center,
   and timetable. Extending the shared suffix contract instead of adding a
   one-off rule per page/component closes every current and future consumer
   of these names at once, exactly like the original -card/-panel/-workspace
   contract. Deliberately excluded from this suffix list: -icon, -stat,
   -metric, -count, -status, -link -- these are more often small inline text/
   glyph elements or already-colored semantic tiles (e.g. the KPI gradient
   icons), where a blanket flat-navy override risks erasing an intentional
   semantic color rather than fixing a real defect; those are reviewed
   individually instead. */
[data-theme="dark"] .page-stage
  :is(
    [class$="-card"],
    [class*="-card "],
    [class$="-panel"],
    [class*="-panel "],
    [class$="-workspace"],
    [class*="-workspace "],
    [class$="-btn"],
    [class*="-btn "],
    [class$="-button"],
    [class*="-button "],
    [class$="-row"],
    [class*="-row "],
    [class$="-section"],
    [class*="-section "],
    [class$="-group"],
    [class*="-group "],
    [class$="-item"],
    [class*="-item "],
    [class$="-head"],
    [class*="-head "],
    [class$="-close"],
    [class*="-close "],
    [class$="-detail"],
    [class*="-detail "],
    [class$="-note"],
    [class*="-note "],
    [class$="-menu"],
    [class*="-menu "],
    [class$="-popup"],
    [class*="-popup "],
    [class$="-search"],
    [class*="-search "],
    [class$="-option"],
    [class*="-option "]
  ) {
  border-color: var(--app-line) !important;
  color: var(--app-ink);
}
/* Several module-local -card/-panel classes (e.g. .report-card,
   .assignment-suggestion-panel, .manual-plan-panel, .calendar-summary-card)
   paint a light background-image gradient via the `background` shorthand.
   The rule above only ever reset background-color, so that gradient image
   layer kept painting a white/pale surface on top of the dark app-surface
   color underneath -- the same shorthand-vs-longhand gap already found for
   the login .form-area and Timetable's .panel-current-assignment. Explicitly
   clearing background-image here fixes every current and future -card/
   -panel/-workspace consumer of this pattern at once instead of patching
   each page-local gradient individually. */
[data-theme="dark"] .page-stage
  :is(
    [class$="-card"],
    [class*="-card "],
    [class$="-panel"],
    [class*="-panel "],
    [class$="-workspace"],
    [class*="-workspace "],
    [class$="-btn"],
    [class*="-btn "],
    [class$="-button"],
    [class*="-button "],
    [class$="-row"],
    [class*="-row "],
    [class$="-section"],
    [class*="-section "],
    [class$="-group"],
    [class*="-group "],
    [class$="-item"],
    [class*="-item "],
    [class$="-head"],
    [class*="-head "],
    [class$="-close"],
    [class*="-close "],
    [class$="-detail"],
    [class*="-detail "],
    [class$="-note"],
    [class*="-note "],
    [class$="-menu"],
    [class*="-menu "],
    [class$="-popup"],
    [class*="-popup "],
    [class$="-search"],
    [class*="-search "],
    [class$="-option"],
    [class*="-option "]
  ):not(.icon-card):not(.status-card):not(.sidebar-config-card) {
  background-color: var(--app-surface) !important;
  background-image: none !important;
}
/* Generic suffix contract for module-specific chip/pill/badge/tag component
   classes (e.g. .subject-chip, .capacity-chip, .teacher-status-badge,
   .status-tag, .report-card-tag) that never adopted the shared
   .chip/.pill/.badge names. Matches by class-name suffix only, so layout/
   action sub-parts such as *-chip-actions or *-chip-label are intentionally
   excluded.
   Colors are CONSUMED from the subject/status pill custom-property contract
   (--subject-pill-*, falling back to --subject-color-*) when the element
   carries or inherits it, instead of being hardcoded to one flat navy. This
   is the fix for the semantic-color-flattening bug: previously every
   subject-colored chip/pill (e.g. .subject-color-chip, .subject-theme-pill)
   was forced to identical navy regardless of the subject's own hue, because
   this rule's !important literal colors always outrank the non-important
   `background: var(--subject-color-soft, ...)` declared on the component's
   own class. Elements with no subject/status contract still fall back to the
   original flat navy chip surface via the var() fallback argument. */
[data-theme="dark"] .page-stage
  :is(
    [class$="-chip"],
    [class*="-chip "],
    [class$="-pill"],
    [class*="-pill "],
    [class$="-badge"],
    [class*="-badge "],
    [class$="-tag"],
    [class*="-tag "]
  ) {
  border-color: var(--subject-pill-border, var(--subject-color-border, #315e8b)) !important;
  background-color: var(--subject-pill-bg, var(--subject-color-soft, #142b43)) !important;
  color: var(--subject-pill-fg, var(--subject-color-text, #b9d6f4)) !important;
}
/* Inline per-row accent contract: several server-rendered rows (subject
   chips, subject-theme pills, timetable lesson cells, the dashboard Subject
   Sufficiency status pill) set custom properties inline that are blended
   toward white on the server for light mode. The raw hue custom property
   (--subject-color for per-subject identity, --subject-accent for the
   coverage-status donut color) is never itself overridden by theme.css, so
   dark mode re-derives the soft/border/text/pill tints from that same hue
   with color-mix() instead of replacing it outright -- this keeps distinct
   per-subject/per-entity color-coding (e.g. Arabic green, Art magenta,
   Biology teal, Chemistry orange) and distinct coverage-status coloring
   (good/partial/critical) visible under dark mode instead of flattening
   every consumer to one generic navy. */
[data-theme="dark"] .page-stage [style*="--subject-color-soft"],
[data-theme="dark"] .page-stage [style*="--subject-accent-surface"] {
  --subject-color-soft: color-mix(in srgb, var(--subject-color, var(--subject-accent, #218cff)) 30%, var(--app-surface)) !important;
  --subject-color-border: color-mix(in srgb, var(--subject-color, var(--subject-accent, #218cff)) 55%, var(--app-line)) !important;
  --subject-color-text: color-mix(in srgb, var(--subject-color, var(--subject-accent, #218cff)) 62%, var(--app-ink)) !important;
  --subject-accent-surface: color-mix(in srgb, var(--subject-accent, var(--subject-color, #218cff)) 24%, var(--app-surface-strong)) !important;
  --subject-pill-bg: color-mix(in srgb, var(--subject-accent, var(--subject-color, #218cff)) 30%, var(--app-surface)) !important;
  --subject-pill-fg: color-mix(in srgb, var(--subject-accent, var(--subject-color, #218cff)) 68%, var(--app-ink)) !important;
  --subject-pill-border: color-mix(in srgb, var(--subject-accent, var(--subject-color, #218cff)) 55%, var(--app-line)) !important;
}
[data-theme="dark"] .page-stage [style*="--cell-soft"] {
  --cell-soft: #142b43 !important;
  --cell-surface: #142b43 !important;
  --cell-border: #315e8b !important;
  --cell-text: #dceaff !important;
}
[data-theme="dark"] .page-stage :is(.report-subject-item, .teacher-load-subject-row, .subject-theme-item, .assigned-item) {
  background: linear-gradient(155deg, var(--app-surface), var(--app-surface-strong)) !important;
  border-color: var(--app-line) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage :is(.error, .success) {
  background-color: #0d2745 !important;
  border-left-color: var(--app-line-strong) !important;
}
[data-theme="dark"] .page-stage .error {
  color: #ffb6c2 !important;
}
[data-theme="dark"] .page-stage .success {
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage :is(h1, h2, h3, h4, h5, h6, legend, strong) {
  color: var(--app-ink);
}
[data-theme="dark"] .page-stage :is(p, small, .muted, .help, .hint, .subtitle, .description, .meta) {
  color: var(--app-muted);
}
[data-theme="dark"] .page-stage a:not(.btn):not(.button):not([class*="primary"]):not(.tis-action) {
  color: #83c1ff;
}
[data-theme="dark"] :is(input, select, textarea, button) {
  color-scheme: dark;
}
[data-theme="dark"] :is(input, select, textarea):disabled {
  border-color: #1b3b5e !important;
  background: #07182d !important;
  color: #6f89a8 !important;
  opacity: 1;
}
[data-theme="dark"] :is(input, select, textarea, button, a):focus-visible {
  outline: 0;
  box-shadow: var(--app-focus-ring) !important;
}
[data-theme="dark"] :is(input[type="checkbox"], input[type="radio"]) {
  accent-color: #258fff;
}
[data-theme="dark"] select option {
  background: #091d36;
  color: var(--app-ink);
}
[data-theme="dark"] :is(.table-wrap, .table-container, .data-table, table) {
  border-color: var(--app-line) !important;
  background-color: #0a203b !important;
}
[data-theme="dark"] :is(thead, thead tr) {
  background: #102b4c !important;
}
[data-theme="dark"] tbody tr {
  background: #0a203b;
  color: #dceaff;
}
[data-theme="dark"] tbody tr:nth-child(even) {
  background: #0b2442;
}
[data-theme="dark"] tbody tr:hover {
  background: #103257 !important;
}
[data-theme="dark"] td {
  color: #dceaff;
}
[data-theme="dark"] :is(.badge, .chip, .pill, .tag, .status-badge) {
  border-color: #315e8b;
  background-color: #142b43 !important;
  color: #b9d6f4 !important;
}
[data-theme="dark"] :is(.alert, .banner, .notice, .callout, .message) {
  border-color: #315e8b;
  color: var(--app-ink);
}
[data-theme="dark"] :is(.pagination button, .pagination a, .page-link) {
  border-color: #28527d !important;
  background: #0d2745 !important;
  color: #bcd5f1 !important;
}
[data-theme="dark"] :is(.pagination .active, .page-link.is-active, .page-link[aria-current="page"]) {
  border-color: #258fff !important;
  background: #1677db !important;
  color: #fff !important;
}
[data-theme="dark"] ::selection {
  background: #196dc0;
  color: #fff;
}

/* Focused legacy-family completion discovered by route-by-route visual audit. */
[data-theme="dark"] .page-stage
  :is(
    .tab,
    .subject-view-btn,
    .add-teacher-trigger-cta,
    .add-teacher-close,
    .qualification-dropdown-trigger,
    .qualification-option,
    .auto-empty,
    .auto-summary-pill,
    .tp-executive-kpi,
    .tp-page-head,
    .tp-empty,
    .timetable-shell,
    .version-bar,
    .lifecycle-context,
    .readiness-shell,
    .readiness-metric,
    .hero-kicker,
    .hero-btn.is-secondary,
    .obs-kpi,
    .obs-panel,
    .msg-filter,
    .msg-empty,
    .save-all-toolbar,
    .summary-row,
    .permission-check,
    .create-row,
    .event-type-row,
    .branch-overrides,
    .weekday-cell,
    .day-cell,
    .role-permission-preview
    ,.max-hours-rule
    ,.assignment-suggestion-badge
    ,.assignment-suggestion-action
    ,.assignment-suggestion-progress-track
    ,.allocation-status-badge
    ,.allocation-hours-total
    ,.allocation-progress-track
    ,.allocation-breakdown-item
    ,.toolbar-shell
    ,.view-chip
    ,.legend-pill
    ,.warning-pill
    ,.month-events-head
    ,.permission-status
    ,.day-pill
    ,.advanced-conditions
    ,.timeline-row
    ,.timeline-day-chip
    ,.performance-guide
    ,.performance-guide-item
    ,.condition-option
    ,.lane-shell
    ,.board-shell
    ,.board-grid-wrap
    ,.inspector-shell
    ,.hero-shell
    ,.tp-band
    ,.tp-executive-hero
    ,.subject-grade-row
    ,.subject-grade-toggle
    ,.auto-panel
    ,.aligned-item
    ,.aligned-item-hours
    ,.subject-pool-focus
    ,.subject-pool-focus-metric
    ,.subject-pool-focus-subject
    ,.subject-pool-focus-note
    ,.subject-pool-summary-item
    ,.subject-pool-stat
    ,.dashboard-subject-grade-icon
    ,.dashboard-subject-grade-count
    ,.dashboard-subject-grade-hours
    ,.report-card-icon
    ,.report-mini-stat
    ,.report-section-block
    ,.report-teacher-column
    ,.report-hiring-profile
    ,.hiring-studio
    ,.hiring-chip-dropzone
    ,.assignment-suggestion-stat
    ,.major-guidance-stat
    ,.region-group-count
    ,.history-icon
    ,.result-band
    ,.self-tool
  ) {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
  box-shadow: none;
}
[data-theme="dark"] .page-stage .subject-grade-row td {
  background: var(--app-surface) !important;
  border-color: var(--app-line) !important;
}
/* Academic Planning > Insights > Subjects grade rows. The page-local rule
   `.dashboard-subject-grade-row td { background: #edf4ff }` in
   templates/dashboard.html is declared after this stylesheet and outranks the
   ambient dark `td`/`tbody tr` rules, so the rendered grade cells (not only
   the table wrapper) need their own dark contract. */
[data-theme="dark"] .page-stage .dashboard-subject-grade-row td {
  background: var(--app-surface-muted) !important;
  border-color: var(--app-line) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-grade-row:hover td,
[data-theme="dark"] .page-stage .dashboard-subject-grade-row:focus-within td {
  background: var(--app-surface-strong) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-grade-toggle {
  background: transparent !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-grade-toggle:focus-visible {
  outline-color: #54a8ff;
}
[data-theme="dark"] .page-stage .dashboard-subject-grade-label {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-grade-hint {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-grade-toggle[aria-expanded="true"] .dashboard-subject-grade-icon {
  border-color: var(--app-line-strong) !important;
  background: var(--app-brand-soft) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-row td {
  background: var(--app-surface) !important;
  border-color: var(--app-line) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .dashboard-subject-row:hover td {
  background: var(--app-surface-strong) !important;
}
[data-theme="dark"] .page-stage .subject-row,
[data-theme="dark"] .page-stage .subject-row td {
  background: var(--app-surface-muted) !important;
  border-color: var(--app-line) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .subject-row:hover,
[data-theme="dark"] .page-stage .subject-row:hover td {
  background: var(--app-surface-strong) !important;
}
[data-theme="dark"] .page-stage .aligned-item-state {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage :is(.tab.active, .msg-filter.is-active, .subject-view-btn.is-active) {
  border-color: #258fff !important;
  background: #176dcc !important;
  color: #fff !important;
}
[data-theme="dark"] .page-stage :is(.view-chip.is-active, .day-pill.is-active) {
  border-color: #258fff !important;
  background: #154f87 !important;
  color: #e9f4ff !important;
}
[data-theme="dark"] .page-stage :is(.tp-chart-legend li) {
  border-color: var(--app-line) !important;
  background: #0d2745 !important;
  color: #c9dcf3 !important;
}
[data-theme="dark"] .page-stage .tp-chart li {
  border-color: var(--app-line) !important;
  background: #0d2745 !important;
  color: #c9dcf3 !important;
}
[data-theme="dark"] .tp-active-filters li {
  border-color: #315e8b !important;
  background: #0d2745 !important;
  color: #b9d6f4 !important;
}
[data-theme="dark"] :is(.access-denied-eyebrow, .access-denied-btn) {
  border-color: #315e8b !important;
  background: #0d2745 !important;
  color: #d7eaff !important;
}
[data-theme="dark"] .page-stage details > summary {
  border-color: var(--app-line) !important;
  background: #102b4c !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage :is(.banner.is-warning, .notice-banner) {
  border-color: #8b6727 !important;
  background: #2b2519 !important;
  color: #f3d28b !important;
}
[data-theme="dark"] .page-stage :is(.status-pill.is-warning, .readiness-status) {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}
[data-theme="dark"] .page-stage :is(.status-pill.is-muted, .usage-pill) {
  border-color: #315574 !important;
  background: #142b43 !important;
  color: #a9bfdb !important;
}
[data-theme="dark"] .page-stage :is(.status-pill.is-success) {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage :is(.action-btn-danger, .btn-danger) {
  border-color: #8c4250 !important;
  background: #351b26 !important;
  color: #ffb6c2 !important;
}
[data-theme="dark"] .page-stage :is(.obs-kpi span, .obs-kpi strong, .summary-row strong, .summary-row span) {
  color: inherit !important;
}
[data-theme="dark"] .page-stage :is(.day-cell.is-muted) {
  background: #07182d !important;
  color: #7894b5 !important;
}
[data-theme="dark"] .page-stage :is(.tp-page-head, .tp-executive-hero, .timetable-shell, .hero-shell) {
  background-image: linear-gradient(145deg, #0b213d, #081a31) !important;
}
[data-theme="dark"] .page-stage :is(.tp-empty, .auto-empty, .msg-empty) {
  background-image: none !important;
}
[data-theme="dark"] .page-stage :is(.wizard-head, .step-chip, .scope-option, .calendar-header-link, .observation-form-head, .observation-toolbar, .domain, .criterion-rubric, .criterion-tool, .rating-wrap, .evidence-box) {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage :is(.back-link, .step-chip.active) {
  border-color: var(--app-line-strong) !important;
  background: var(--app-active) !important;
  color: #dceeff !important;
}
[data-theme="dark"] .page-stage :is(.progress-track) {
  background: #173c61 !important;
}
[data-theme="dark"] .page-stage :is(.criterion-tool-evidence, .evidence-box) {
  border-color: #745b2f !important;
  background: #2e260f !important;
}
[data-theme="dark"] .page-stage :is(.tp-executive-kpi) .tp-stat-value {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage :is(.permission-check.is-inherited, .permission-check.has-override, .permission-check.is-developer-only) {
  background: #0d2745 !important;
}

/* Wide data workspaces scroll internally instead of widening the application. */
.page-stage,
.configuration-workspace,
.configuration-workspace-content,
[data-theme="dark"] .page-stage > * {
  min-width: 0;
  max-width: 100%;
}
[data-theme="dark"] .page-stage :is(.table-wrap, .table-container, .tp-table-wrap, .calendar-grid, .schedule-grid) {
  max-width: 100%;
  overflow-x: auto;
}
[data-theme="dark"] .page-stage :is(.timetable-shell, .calendar-shell, .grid, .workspace) {
  min-width: 0 !important;
  max-width: 100% !important;
}
.configuration-workspace-content > .grid {
  min-width: 0 !important;
  max-width: 100% !important;
  grid-template-columns: minmax(0, 1fr) !important;
}
.configuration-workspace-content :is(.card, .toolbar, .table-wrap, .module-head, .event-type-list, .create-row, .event-type-row) {
  min-width: 0 !important;
  max-width: 100% !important;
}
.configuration-workspace-content .table-wrap {
  overflow-x: auto !important;
  contain: inline-size;
}
[data-theme="dark"] body[data-page-key="users"] .configuration-workspace-content table {
  width: 100% !important;
  min-width: min(720px, 100%) !important;
  table-layout: fixed;
}
[data-theme="dark"] body[data-page-key="users"] .configuration-workspace-content :is(th, td) {
  width: auto !important;
  min-width: 0 !important;
  overflow-wrap: anywhere;
}
[data-theme="dark"] .compact-description-tooltip {
  max-width: min(320px, calc(100vw - 24px)) !important;
}
html[data-theme="dark"],
[data-theme="dark"] body {
  overflow-x: clip;
}
.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 5px 8px;
  border: 1px solid var(--app-line);
  border-radius: 999px;
  background: var(--app-surface-muted);
  color: var(--app-ink);
  font: inherit;
  font-size: var(--tis-fs-xs, 12px);
  font-weight: 750;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
}
.theme-toggle:hover {
  border-color: var(--app-line-strong);
}
.theme-toggle:focus-visible {
  outline: 0;
  box-shadow: var(--app-focus-ring);
}
.theme-toggle-track {
  position: relative;
  width: 36px;
  height: 20px;
  flex: 0 0 36px;
  border: 1px solid #9ab5d1;
  border-radius: 999px;
  background: #d8e6f5;
  box-shadow: inset 0 1px 3px rgba(22, 61, 101, 0.18);
}
.theme-toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #176bd8;
  box-shadow: 0 2px 6px rgba(14, 67, 133, 0.32);
  transform: translateX(0);
  transition: transform 180ms ease, background-color 180ms ease, box-shadow 180ms ease;
}
.theme-toggle-light {
  color: var(--app-brand-deep);
}
[data-theme="dark"] .theme-toggle {
  border-color: #28527d;
  background: #081e39;
  color: #9eb9d8;
}
[data-theme="dark"] .theme-toggle-track {
  border-color: #2969a8;
  background: #0a315b;
  box-shadow: inset 0 1px 4px rgba(0, 5, 18, 0.55), 0 0 10px rgba(38, 139, 255, 0.12);
}
[data-theme="dark"] .theme-toggle-thumb {
  background: #2d9cff;
  box-shadow: 0 0 10px rgba(45, 156, 255, 0.65);
  transform: translateX(16px);
}
[data-theme="dark"] .theme-toggle-light {
  color: #7898bb;
}
[data-theme="dark"] .theme-toggle-dark {
  color: #e9f4ff;
}
@media (prefers-reduced-motion: reduce) {
  * {
    scroll-behavior: auto !important;
  }
  .theme-toggle {
    transition: none !important;
  }
  .theme-toggle-thumb {
    transition: none !important;
  }
}

/* SaaS account, onboarding, and platform-administration shell. */
body.saas-page {
  --app-ink: var(--ink);
  --app-brand-deep: var(--brand-dark);
  --app-line: var(--line);
  --app-line-strong: #9bb9d8;
  --app-surface-muted: var(--panel-soft);
  --app-focus-ring: 0 0 0 3px rgba(23, 107, 216, .2);
}
[data-theme="dark"] body.saas-page {
  --app-ink: #edf6ff;
  --app-brand-deep: #8bc8ff;
  --app-line: #244b70;
  --app-line-strong: #3476b5;
  --app-surface-muted: #0a2949;
  --app-focus-ring: 0 0 0 3px rgba(45, 156, 255, .32);
  --bg: #041426;
  --panel: #08213c;
  --panel-soft: #0a2949;
  --ink: #edf6ff;
  --muted: #9db6d1;
  --line: #244b70;
  --brand: #55adff;
  --brand-dark: #8bc8ff;
  --warn: #ffd383;
  --warn-bg: #35260e;
  --error: #ff9aab;
  --error-bg: #351521;
  --ok: #74e3b8;
  --ok-bg: #0b302a;
  --shadow: 0 24px 70px rgba(0, 5, 18, .42);
  color-scheme: dark;
  background:
    radial-gradient(680px 460px at 4% -8%, rgba(42, 139, 238, .18), transparent 70%),
    radial-gradient(620px 420px at 100% 0%, rgba(32, 111, 176, .12), transparent 72%),
    linear-gradient(155deg, #041426, #061a31 48%, #031224);
}
[data-theme="dark"] body.saas-page :is(.hero, .card, .panel, .summary-card, .plan-card, .setup-console, .setup-title-panel, .setup-journey, .setup-workspace-brand) {
  border-color: rgba(42, 83, 122, .92);
  background: rgba(8, 33, 60, .94);
  color: var(--ink);
  box-shadow: var(--shadow);
}
[data-theme="dark"] body.saas-page :is(.auth-kpi, .wizard-section, .payment-launcher, .review-card) {
  border-color: #28527d !important;
  background: #0a2949 !important;
  color: #edf6ff !important;
}
[data-theme="dark"] body.saas-page :is(.page-header, .section, .row, .list-item, .table-wrap, table, th, td) {
  border-color: var(--line);
}
[data-theme="dark"] body.saas-page :is(.page-eyebrow, code, .pill, .step-pill, .setup-edit-step, .setup-timeline-step) {
  border-color: #28577f;
  background: #0a3158;
  color: #a9d6ff;
}
[data-theme="dark"] body.saas-page :is(input, select, textarea) {
  border-color: #2a557d;
  background: #061a31;
  color: #edf6ff;
}
[data-theme="dark"] body.saas-page :is(input, textarea)::placeholder {
  color: #7898ba;
}
[data-theme="dark"] body.saas-page :is(.btn.secondary, button.secondary) {
  border-color: #2c5b86;
  background: #0a2949;
  color: #c9e5ff;
}
[data-theme="dark"] body.saas-page :is(.notice, .warning, .error, .success) {
  border-color: var(--line);
}
[data-theme="dark"] body.saas-page :is(thead, thead tr, th) {
  background: #0a2949;
  color: #bddcff;
}
[data-theme="dark"] body.saas-page tbody tr:nth-child(even) {
  background: rgba(12, 43, 75, .52);
}
[data-theme="dark"] body.saas-page tbody tr:hover {
  background: #0d365f;
}
[data-theme="dark"] body.saas-page :is(.muted, .page-subtitle, small, .help, .hint) {
  color: var(--muted);
}
/* Dark mode swaps to the canonical transparent white/light-orange TIS asset
   (templates/saas/base.html .brand-symbol-dark); the frame itself must stay
   transparent so the logo never sits on a baked dark rectangle. */
[data-theme="dark"] body.saas-page .brand-symbol-frame {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}

body.standalone-theme-page {
  --app-ink: #10233f;
  --app-brand-deep: #093b7b;
  --app-line: #c8d8ea;
  --app-line-strong: #91b1d2;
  --app-surface-muted: #f1f6fc;
  --app-focus-ring: 0 0 0 3px rgba(23, 107, 216, .2);
}
.standalone-theme-toggle {
  position: fixed;
  z-index: 20;
  top: 16px;
  right: 16px;
}
[data-theme="dark"] body.standalone-theme-page {
  --app-ink: #edf6ff;
  --app-brand-deep: #8bc8ff;
  --app-line: #244b70;
  --app-line-strong: #3476b5;
  --app-surface-muted: #0a2949;
  --app-focus-ring: 0 0 0 3px rgba(45, 156, 255, .32);
  /* templates/index.html (TIS operational login) defines its own local
     --ink/--muted/--brand/--line/--danger-* tokens in a page :root block
     that loads before theme.css. Redefining them here on body overrides
     the inherited light values for every descendant (labels, heading,
     hint text, error banner) without editing the page's light-mode CSS. */
  --ink: #edf6ff;
  --muted: #9db6d1;
  --brand: #55adff;
  --brand-dark: #2d9cff;
  --line: #244b70;
  --danger-bg: #351521;
  --danger-border: #ff8fa3;
  color: #edf6ff;
  color-scheme: dark;
  background: radial-gradient(680px 480px at 8% -8%, rgba(42, 139, 238, .2), transparent 70%), #041426;
}
[data-theme="dark"] body.standalone-theme-page :is(main, .shell, .form-area, .demo-access) {
  border-color: #28527d;
  background-color: #08213c;
  color: #edf6ff;
  box-shadow: 0 24px 70px rgba(0, 5, 18, .45);
}
/* .form-area also paints its own light background-image (gradients) on top
   of background-color, so background-color alone never showed through. */
[data-theme="dark"] body.standalone-theme-page .form-area {
  background-image: none !important;
}
[data-theme="dark"] body.standalone-theme-page .login-panel::before {
  border-color: rgba(52, 118, 181, 0.45);
  background: linear-gradient(145deg, rgba(10, 41, 73, 0.55), rgba(8, 33, 60, 0.25));
  box-shadow: 0 20px 48px rgba(0, 5, 18, 0.35);
}
[data-theme="dark"] body.standalone-theme-page .modal-card {
  background: #08213c !important;
  border-color: #28527d !important;
  color: #edf6ff;
}
[data-theme="dark"] body.standalone-theme-page .modal-notice.is-success {
  background: #0d392f !important;
  border-color: #20795f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] body.standalone-theme-page :is(p, small, .muted, .brand-copy span) {
  color: #9db6d1;
}
[data-theme="dark"] body.standalone-theme-page :is(input, select, textarea) {
  border-color: #2a557d;
  background: #061a31;
  color: #edf6ff;
}
[data-theme="dark"] body.standalone-theme-page :is(.demo-access__notice, .notice) {
  border-color: #9c6e2d;
  background: #35260e;
  color: #f3d9a6;
}
[data-theme="dark"] body.standalone-theme-page :is(.demo-access__button.secondary, .btn.secondary) {
  border-color: #3476b5;
  background: #0a2949;
  color: #b9dcff;
}
/* Compact placement for the TIS operational login page only: the toggle
   moves from a viewport-fixed corner control into the login card itself so
   it reads as part of the composition. Other standalone pages that reuse
   .standalone-theme-toggle (commercial_access_ended, demo_access_blocked)
   keep their existing fixed top-right placement untouched. */
.login-theme-toggle {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 5;
}
@media (max-width: 640px) {
  .login-theme-toggle {
    top: 10px;
    right: 10px;
  }
}

body.landing-page {
  --app-ink: var(--landing-ink);
  --app-brand-deep: var(--landing-navy);
  --app-line: var(--landing-line);
  --app-line-strong: #9bb9d8;
  --app-surface-muted: var(--landing-ice);
  --app-focus-ring: 0 0 0 3px rgba(22, 138, 136, .22);
}
[data-theme="dark"] body.landing-page {
  --landing-ink: #edf6ff;
  --landing-navy: #d8ebff;
  --landing-navy-soft: #0a2949;
  --landing-sky: #0a2949;
  --landing-ice: #071c34;
  --landing-line: #28527d;
  --landing-slate: #9db6d1;
  --landing-white: #08213c;
  --app-ink: #edf6ff;
  --app-brand-deep: #8bc8ff;
  --app-line: #28527d;
  --app-line-strong: #3476b5;
  --app-surface-muted: #0a2949;
  --app-focus-ring: 0 0 0 3px rgba(45, 156, 255, .32);
  color-scheme: dark;
  background: radial-gradient(circle at top, rgba(27, 105, 181, .18), transparent 34%), #041426;
}
[data-theme="dark"] body.landing-page :is(.site-header, .feature-card, .problem-card, .product-card, .pricing-card, .proof-card, .faq-card, .cta-panel) {
  border-color: #28527d;
  background-color: #08213c;
  color: #edf6ff;
}
[data-theme="dark"] body.landing-page :is(section, footer) {
  border-color: #244b70;
}
[data-theme="dark"] body.landing-page :is(p, .section-lede, .hero-lede, .card-copy, .footer-copy) {
  color: #9db6d1;
}
[data-theme="dark"] .calendar-header-link {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
}

/* Timetable workspace (templates/timetable.html) keeps its own local
   --tt-* token namespace defined in a page :root block that loads before
   theme.css. Redefining the same custom properties here (later in the
   cascade, on the .timetable-page root) fixes headings, labels, shells,
   and version/lifecycle copy without touching the page's light-mode values. */
[data-theme="dark"] .timetable-page {
  --tt-ink: var(--app-ink);
  --tt-subtle: var(--app-muted);
  --tt-border: var(--app-line);
  --tt-border-strong: var(--app-line-strong);
  --tt-surface: var(--app-surface);
  --tt-surface-soft: var(--app-surface-muted);
  --tt-surface-tint: linear-gradient(180deg, var(--app-surface), var(--app-surface-strong));
  --tt-accent: var(--app-brand);
  --tt-accent-soft: #142b43;
  --tt-shadow: var(--app-shadow-sm);
}
/* Critical timetable grid: day headers, period column, empty/assigned/
   blocked/stale cell states. These set literal light colors instead of
   consuming --tt-* tokens, so they need explicit dark values. */
[data-theme="dark"] .timetable-page :is(.board-grid thead th) {
  background: var(--app-surface-muted) !important;
  color: var(--app-muted) !important;
}
[data-theme="dark"] .timetable-page .board-grid td {
  border-bottom-color: var(--app-line) !important;
}
[data-theme="dark"] .timetable-page .period-cell {
  background: var(--app-surface-muted) !important;
}
[data-theme="dark"] .timetable-page .period-cell.is-non-teaching-row {
  background: #2b2519 !important;
  border-left-color: #c77d19 !important;
}
[data-theme="dark"] .timetable-page .grid-cell {
  background: var(--app-surface) !important;
}
[data-theme="dark"] .timetable-page .grid-button {
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .timetable-page .grid-button:hover {
  border-color: var(--app-line-strong) !important;
  background: var(--app-surface-strong) !important;
}
[data-theme="dark"] .timetable-page .grid-button.is-selected {
  border-color: #3b8ee7 !important;
  background: #123c6b !important;
  box-shadow: 0 12px 24px rgba(0, 4, 14, 0.4);
}
[data-theme="dark"] .timetable-page .grid-button.is-empty {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
}
[data-theme="dark"] .timetable-page .grid-button.is-blocked,
[data-theme="dark"] .timetable-page .grid-button.is-assigned {
  background: var(--cell-soft, #142b43) !important;
  border-color: var(--cell-border, #315e8b) !important;
  color: var(--cell-text, #dceaff) !important;
}
[data-theme="dark"] .timetable-page .grid-button.is-stale {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}
[data-theme="dark"] .timetable-page .grid-button.is-non-teaching-row.is-empty {
  background: var(--app-surface-muted) !important;
  border-color: var(--app-line) !important;
  color: var(--app-muted) !important;
}
[data-theme="dark"] .timetable-page :is(.banner.is-warning, .lifecycle-context.is-stale) {
  border-color: #8b6727 !important;
  background: #2b2519 !important;
  color: #f3d28b !important;
}
[data-theme="dark"] .timetable-page .banner.is-info {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .timetable-page :is(.version-badge, .version-select, .history-version-card, .lifecycle-fact, .lifecycle-step) {
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
  border-color: var(--app-line) !important;
}
[data-theme="dark"] .timetable-page .version-badge.is-warning {
  background: #332515 !important;
  color: #ffd38a !important;
}
[data-theme="dark"] .timetable-page .version-badge.is-active {
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .timetable-page .version-notice.is-stale {
  background: #351521 !important;
  color: #ffb6c2 !important;
}
[data-theme="dark"] .timetable-page .lifecycle-step.is-complete {
  background: #0d392f !important;
  border-color: #20795f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .timetable-page .lifecycle-step.is-current {
  background: #123c6b !important;
  border-color: #3b8ee7 !important;
  color: #d7eaff !important;
}
/* Assignment dialog/panel: these gradients bake a literal #ffffff first
   stop, so overriding only the --cell-* custom properties (handled above)
   is not enough; the shorthand background itself needs a dark value. */
[data-theme="dark"] .timetable-page .panel-current-assignment {
  background: linear-gradient(180deg, var(--app-surface), var(--cell-surface, var(--app-surface-strong))) !important;
}
[data-theme="dark"] .timetable-page .assignment-option-card {
  background: var(--cell-soft, #142b43) !important;
  color: var(--cell-text, #dceaff) !important;
}
[data-theme="dark"] .timetable-page .assignment-option-card:hover {
  background: var(--cell-surface, #17365d) !important;
}

/* Round 2 systemic-gap correction (2026-09-27): named pills/badges/wrappers
   that neither adopted the shared -chip/-pill/-badge/-tag/-card/-panel
   suffix contract nor appeared in the earlier explicit legacy-family list,
   found by tracing exact class names used in teachers.html, planning.html,
   dashboard.html, subjects.html, and the shared system_configuration_*
   .module-shell wrapper. Each rule below is written with
   `[data-theme="dark"] .page-stage .exact-class` specificity so it reliably
   outranks the generic suffix rules above when a specific semantic state
   (success/warning/danger) must be preserved instead of falling back to
   flat navy. */

/* Teachers: "SUBJECTS" / "TEACHING LOAD" / "HOMEROOM" section labels. */
[data-theme="dark"] .page-stage .coverage-label {
  background: #142b43 !important;
  color: #b9d6f4 !important;
}

/* Teachers: evaluator performance band, including "NO EVALUATOR SCORE".
   Class name ends in "-band", so it never matched the chip/pill/badge/tag
   suffix contract; states mirror the existing .status-pill success/warning/
   danger token pattern used elsewhere in this file. */
[data-theme="dark"] .page-stage .performance-band {
  border-color: #315e8b !important;
  background: #142b43 !important;
  color: #b9d6f4 !important;
}
[data-theme="dark"] .page-stage .performance-band.is-strong,
[data-theme="dark"] .page-stage .performance-band.is-meets {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage .performance-band.is-warning {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}
[data-theme="dark"] .page-stage .performance-band.is-danger {
  border-color: #8c4250 !important;
  background: #351b26 !important;
  color: #ffb6c2 !important;
}

/* Teachers: capacity/status chip and badge state variants. The generic
   -chip/-badge suffix rule already darkens the base surface; these restore
   the good/danger and ready/balanced/over semantic differentiation that
   would otherwise be flattened to identical navy. */
[data-theme="dark"] .page-stage .hours-status-chip.is-good {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage .hours-status-chip.is-danger {
  border-color: #8c4250 !important;
  background: #351b26 !important;
  color: #ffb6c2 !important;
}
[data-theme="dark"] .page-stage .allocation-dashboard[data-state="ready"] .allocation-status-badge {
  border-color: #1f6f86 !important;
  background: #0d2f39 !important;
  color: #8fd8ec !important;
}
[data-theme="dark"] .page-stage .allocation-dashboard[data-state="balanced"] .allocation-status-badge {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage .allocation-dashboard[data-state="over"] .allocation-status-badge {
  border-color: #8c4250 !important;
  background: #351b26 !important;
  color: #ffb6c2 !important;
}

/* Planning: "Current" / "New" section-status tags. Class name ends in
   "-tag", so the generic -tag suffix rule above now dark-ifies the base
   surface; these two restore the green/orange semantic differentiation the
   plain fallback would otherwise flatten to identical navy. */
[data-theme="dark"] .page-stage .status-tag-current {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage .status-tag-new {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}

/* Dashboard Subject Sufficiency: the expand/collapse arrow circle painted a
   literal white background regardless of theme. */
[data-theme="dark"] .page-stage .report-subject-toggle-arrow {
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
  border-color: var(--app-line) !important;
}
/* Dashboard Subject Sufficiency: filter/search controls. The text input and
   <select> already pick up the generic dark input/select rule; the "Clear
   Filter" <button> and its result count did not, since neither matches any
   existing suffix or tag rule. */
[data-theme="dark"] .page-stage .report-subject-filter-clear {
  border-color: #28527d !important;
  background: #0d2745 !important;
  color: #bcd5f1 !important;
}
[data-theme="dark"] .page-stage .report-subject-filter-count {
  color: var(--app-muted) !important;
}
/* Subjects: per-grade subject-count chip inside an otherwise dark-ified
   grade row. Class name ends in "-count", so it never matched the chip/
   pill/badge/tag suffix contract. */
[data-theme="dark"] .page-stage .subject-grade-count {
  border-color: #315e8b !important;
  background: #142b43 !important;
  color: #b9d6f4 !important;
}

/* System Configuration: shared module wrapper and section-nav pill used
   across every system_configuration_*.html page (Degrees/Specializations,
   Academic Calendar Event Types, Schools, Branches, Years, Logos, Design,
   Role Permissions, Timetable settings). Fixing it once here removes the
   still-white outer content wrapper reported on both Degrees and Academic
   Calendar Event Types instead of patching each page's local .module-shell
   rule individually. */
[data-theme="dark"] .page-stage .module-shell {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
}
/* .config-nav / .config-nav-link are declared in several
   system_configuration_*.html <style> blocks but are dead CSS: the actual
   section navigation is rendered by the shared configuration_sections()
   macro using .configuration-section-link, which theme.css already
   dark-ifies above. No rule is added for the unused .config-nav-link name. */
/* System Configuration > Degrees/Specializations: the degree/specialization
   name text carries its own literal dark-navy color (#17365d) tuned for the
   light table background. That color survives the table's dark-ify because
   a single-class rule always outranks the ambient `td` element selector, so
   without this it renders as low-contrast dark-on-dark text. */
[data-theme="dark"] .page-stage .qualification-label {
  color: var(--app-ink) !important;
}

/* Round 3 systemic-gap correction (2026-09-27), continued: named surfaces
   found by a repository-wide inventory of every template's inline <style>
   block, grouped by fix pattern rather than fixed one page at a time. */

/* Messages/Notifications quick-action button (the owner's own contrast
   benchmark page): background:#fff with color:var(--app-brand-deep) is
   near-white text (#d7eaff) on a still-white surface once --app-brand-deep
   resolves to its dark value -- the exact "blue text disappearing" defect
   class, on the page meant to be the good example. */
[data-theme="dark"] .page-stage .msg-action {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-brand) !important;
}

/* Observation self-assessment / peer rating scale (Observations, both the
   live form and the read-only detail view): the unchecked <label> state was
   a flat white pill with slate-blue text; the checked state already paints
   a solid saturated color (blue/gray/red/orange/amber) with white text and
   needs no change in either theme. */
[data-theme="dark"] .page-stage .self-rating-grid label,
[data-theme="dark"] .page-stage .rating-grid label {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-muted) !important;
}
/* .self-tool-evidence / .subject-chip-override reuse the shared amber
   "evidence/override" warning tint (same token pair as .status-pill.is-warning
   elsewhere in this file) instead of the flat navy every other .self-tool /
   generic surface gets, since their light-mode color is a deliberate amber
   semantic, not an accident. */
[data-theme="dark"] .page-stage .self-tool-evidence,
[data-theme="dark"] .page-stage .subject-chip-override {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}

/* Operations Dashboard "Alert" metric tile (e.g. an understaffed/at-risk
   count): light mode washes a translucent white over a semantic red/green
   tinted border. Both the .is-clear (green) and default (red) states need
   their own dark surface + text pairing, not the generic flat navy, or the
   semantic urgency signal is lost. */
[data-theme="dark"] .page-stage .report-alert-metric {
  border-color: #8c4250 !important;
  background: #351b26 !important;
}
[data-theme="dark"] .page-stage .report-alert-metric strong {
  color: #ffb6c2 !important;
}
[data-theme="dark"] .page-stage .report-alert-metric span {
  color: #e59aa8 !important;
}
[data-theme="dark"] .page-stage .report-visual-card-alert.is-clear .report-alert-metric {
  border-color: #20795f !important;
  background: #0d392f !important;
}
[data-theme="dark"] .page-stage .report-visual-card-alert.is-clear .report-alert-metric strong,
[data-theme="dark"] .page-stage .report-visual-card-alert.is-clear .report-alert-metric span {
  color: #8ae2c2 !important;
}

/* Dashboard Subject Sufficiency "focus" circle and Observation History /
   .history-icon small round icon buttons: flat white circles regardless of
   theme; .history-icon.is-danger keeps its own red icon color (Delete),
   matched to the shared danger token used throughout this file. */
[data-theme="dark"] .page-stage .subject-pool-focus-ring span {
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .history-icon.is-danger {
  color: #ffb6c2 !important;
}

/* Academic Calendar month-view status chip/picker: the [data-status] color
   variants carry real semantic meaning (Planned/Confirmed = blue, In
   Progress = amber, Completed = green, Cancelled = red) that must be
   preserved, not flattened -- these apply whether the chip renders as a
   <details><summary> quick-status trigger (already dark-ified generically
   via the shared `.page-stage details > summary` rule, but that rule only
   sets one flat color, overriding the per-status one below it in the
   light-mode cascade) or, when the actor cannot edit, a plain read-only
   <span> that the generic details/summary rule never reaches at all. */
[data-theme="dark"] .page-stage .month-event-status {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .month-event-status[data-status="Planned"],
[data-theme="dark"] .page-stage .month-event-status[data-status="Confirmed"] {
  border-color: #2f6fb0 !important;
  background: #123c6b !important;
  color: #d7eaff !important;
}
[data-theme="dark"] .page-stage .month-event-status[data-status="In Progress"] {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}
[data-theme="dark"] .page-stage .month-event-status[data-status="Completed"] {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage .month-event-status[data-status="Cancelled"] {
  border-color: #8c4250 !important;
  background: #351b26 !important;
  color: #ffb6c2 !important;
}
/* The quick-status picker buttons (.event-status-button) share the same
   five states via .is-active; the idle/default state is covered by the
   shared -button suffix contract, only the per-status active colors need
   restating here. */
[data-theme="dark"] .page-stage .event-status-button[data-status="In Progress"].is-active {
  border-color: #9a6a24 !important;
  background: #332515 !important;
  color: #ffd38a !important;
}
[data-theme="dark"] .page-stage .event-status-button[data-status="Confirmed"].is-active {
  border-color: #2f6fb0 !important;
  background: #123c6b !important;
  color: #d7eaff !important;
}
[data-theme="dark"] .page-stage .event-status-button[data-status="Completed"].is-active {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}
[data-theme="dark"] .page-stage .event-status-button[data-status="Cancelled"].is-active {
  border-color: #8c4250 !important;
  background: #351b26 !important;
  color: #ffb6c2 !important;
}

/* Timetable lesson-cell overlay icons/badges (.lesson-icon-wrap, .cell-code,
   .subject-tile-icon): these render on top of a per-subject colored cell and
   were painted with a literal translucent/opaque white regardless of theme,
   unlike the rest of the cell which already consumes the --cell-* custom
   properties this file redefines for dark mode (see the .page-stage
   [style*="--cell-soft"] rule above). Switching them to the same --cell-*
   tokens keeps them visually attached to their cell's color in both themes
   instead of floating as a separate white patch. */
[data-theme="dark"] .page-stage .lesson-icon-wrap,
[data-theme="dark"] .page-stage .cell-code {
  background: var(--cell-surface, var(--app-surface-muted)) !important;
  border-color: var(--cell-border, var(--app-line)) !important;
}
[data-theme="dark"] .page-stage .subject-tile-icon {
  background: var(--cell-surface, var(--app-surface-muted)) !important;
}

/* Observation signature block: .signature-pad (the live drawing canvas) and
   .signature-preview / .signature-result img (the captured ink image) are
   the one intentional, isolated light exception in this file -- dark-ink on
   a light/paper surface is the recorded content, not a theme choice, so
   they are deliberately NOT touched here. Everything else around them
   (action buttons, the result wrapper card, the "locked" status pill) is
   ordinary UI chrome and gets the normal dark treatment. */
[data-theme="dark"] .page-stage .signature-button-secondary,
[data-theme="dark"] .page-stage .clear-signature {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .signature-result {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
}
[data-theme="dark"] .page-stage .signature-result span {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .lock-pill {
  border-color: #20795f !important;
  background: #0d392f !important;
  color: #8ae2c2 !important;
}

/* Dashboard report compositions use -brief/-plan and pseudo-element
   centers, so neither the shared card/panel suffix contract nor inherited
   surface tokens can reach their literal light gradients. */
[data-theme="dark"] .page-stage .report-coverage-brief,
[data-theme="dark"] .page-stage .report-coverage-brief.is-alert,
[data-theme="dark"] .page-stage .report-coverage-brief.is-clear,
[data-theme="dark"] .page-stage .report-hiring-plan {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
  box-shadow: var(--app-shadow-sm) !important;
}
[data-theme="dark"] .page-stage .report-coverage-copy h4,
[data-theme="dark"] .page-stage .report-hiring-plan-head p {
  color: var(--app-ink) !important;
}
/* Donut card titles: the page-local pill is light, while the shared dark
   heading rules make its text near-white. */
[data-theme="dark"] .page-stage .report-donut-card h5 {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}

/* KPI focus cards keep their semantic state with dark-safe values. */
[data-theme="dark"] .page-stage .report-focus-card {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  box-shadow: var(--app-shadow-sm) !important;
}
[data-theme="dark"] .page-stage .report-focus-card.is-alert {
  border-color: rgba(248, 113, 113, 0.45) !important;
  background: color-mix(in srgb, #ef4444 14%, var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .report-focus-card.is-clear {
  border-color: rgba(74, 222, 128, 0.4) !important;
  background: color-mix(in srgb, #22c55e 13%, var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .report-focus-label {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .report-focus-value {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .report-focus-card.is-alert .report-focus-value {
  color: #ff9b91 !important;
}
[data-theme="dark"] .page-stage .report-focus-card.is-clear .report-focus-value {
  color: #6ee7a8 !important;
}
[data-theme="dark"] .page-stage .report-focus-card p {
  color: var(--app-muted) !important;
}

/* Alert eyebrow: red by default, green for the clear states (including the
   Coverage brief, whose clear state is declared in dashboard.html). */
[data-theme="dark"] .page-stage .report-alert-eyebrow {
  border-color: rgba(248, 113, 113, 0.45) !important;
  background: rgba(239, 68, 68, 0.16) !important;
  color: #ffb4ac !important;
}
[data-theme="dark"] .page-stage .report-visual-card-alert.is-clear .report-alert-eyebrow,
[data-theme="dark"] .page-stage .report-coverage-brief.is-clear .report-alert-eyebrow {
  border-color: rgba(74, 222, 128, 0.4) !important;
  background: rgba(34, 197, 94, 0.16) !important;
  color: #8ae2c2 !important;
}

/* Subject Sufficiency rows: summary line, flag, KPI chips and progress track. */
[data-theme="dark"] .page-stage .report-subject-summary-line {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  box-shadow: none !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .report-subject-summary-segment-label {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .report-subject-summary-segment-value {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .report-subject-summary-separator {
  color: var(--app-line-strong) !important;
}
[data-theme="dark"] .page-stage .report-subject-flag {
  border-color: rgba(248, 113, 113, 0.4) !important;
  background: rgba(239, 68, 68, 0.16) !important;
  color: #ffb4ac !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip span {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip strong {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip.is-clear {
  border-color: rgba(74, 222, 128, 0.4) !important;
  background: color-mix(in srgb, #22c55e 13%, var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip.is-clear strong {
  color: #6ee7a8 !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip.is-gap {
  border-color: rgba(248, 113, 113, 0.45) !important;
  background: color-mix(in srgb, #ef4444 14%, var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .report-subject-kpi-chip.is-gap strong {
  color: #ff9b91 !important;
}
[data-theme="dark"] .page-stage .report-subject-summary-progress {
  background: var(--donut-track) !important;
  box-shadow: inset 0 1px 2px rgba(0, 5, 18, 0.5) !important;
}

/* Remaining page-local light literals on the Insights Summary and Subjects
   panels (progress tracks, hiring plan stats, KPI tiles, filter controls).
   Fill colours inside the tracks stay as the page supplies them. */
[data-theme="dark"] .page-stage :is(
  .report-chart-track,
  .report-coverage-stack-track,
  .report-contributor-track,
  .report-hiring-progress-track
) {
  background: var(--donut-track) !important;
  box-shadow: inset 0 1px 2px rgba(0, 5, 18, 0.5) !important;
}
[data-theme="dark"] .page-stage .report-kpi {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  box-shadow: var(--app-shadow-sm) !important;
}
[data-theme="dark"] .page-stage .report-kpi::after {
  background: var(--app-line-strong) !important;
}
[data-theme="dark"] .page-stage .report-kpi span,
[data-theme="dark"] .page-stage .report-kpi p {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .report-kpi strong {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage :is(.report-hiring-stat, .report-hiring-reason, .report-subject-empty) {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .report-hiring-stat span {
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .report-hiring-stat strong {
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .report-contributor-section-chip {
  border-color: var(--app-line-strong) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage :is(.hiring-profile-name, .report-subject-filter-select) {
  border-color: var(--app-line-strong) !important;
  background: var(--app-surface-strong) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .hiring-card-remove {
  border-color: rgba(248, 113, 113, 0.45) !important;
  background: rgba(239, 68, 68, 0.16) !important;
  color: #ffb4ac !important;
}

/* Primary workflow links such as Adjust Curriculum use .btn-save rather
   than a -button/-btn suffix and previously retained a washed-out label. */
[data-theme="dark"] .page-stage .btn-save {
  border-color: #258fff !important;
  background: #176dcc !important;
  color: #ffffff !important;
}
[data-theme="dark"] .page-stage .btn-save:hover {
  border-color: #55adff !important;
  background: #258fff !important;
}
[data-theme="dark"] .page-stage :is(button, .btn, [class$="-btn"], [class$="-button"]):disabled {
  border-color: #244b70 !important;
  background: #102a45 !important;
  color: #7898ba !important;
  opacity: 1 !important;
}

/* Small remaining flat-white KPI/stat tiles found across Dashboard,
   Observation History, and the platform owner console, following the same
   pattern already fixed above for their sibling components. */
[data-theme="dark"] .page-stage .subject-level-kpi,
[data-theme="dark"] .page-stage .lead-stat,
[data-theme="dark"] .page-stage .owner-stat,
[data-theme="dark"] .page-stage .history-kpi,
[data-theme="dark"] .page-stage .knowledge-clear {
  border-color: var(--app-line) !important;
  background: var(--app-surface) !important;
  color: var(--app-ink) !important;
}
/* Insights > Subjects level summary wrapper (page-local light gradient). */
[data-theme="dark"] .page-stage .subject-level-dashboard {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
}

/* Theme-aware canonical TIS logo (templates/_tis_logo.html tis_theme_logo):
   Light = full-color asset, Dark = transparent white/light-orange asset.
   The wrappers use display: contents so both variants keep the exact same
   logo box; only one is ever rendered, so there is no double logo. */
.tis-theme-logo--light { display: contents; }
.tis-theme-logo--dark { display: none; }
[data-theme="dark"] .tis-theme-logo--light { display: none; }
[data-theme="dark"] .tis-theme-logo--dark { display: contents; }

/* Round 4 Phase A: dark-mode stragglers.
   The html canvas had no dark background, so a white band could show above
   the app header wherever the body gradient did not reach the viewport top. */
html[data-theme="dark"] {
  background: #020f22;
}
/* Teachers > Add Teacher workflow card: page-local light gradient and literal
   navy/grey copy with no dark counterpart (the note also inherited the pale
   ink from the -note suffix rule, rendering pale-on-light). */
[data-theme="dark"] .page-stage .add-teacher-trigger {
  border-color: var(--app-line);
  background: linear-gradient(135deg, var(--app-surface-muted), var(--app-surface));
  color: var(--app-ink);
}
[data-theme="dark"] .page-stage .add-teacher-trigger:hover {
  border-color: var(--app-line-strong);
  box-shadow: 0 16px 34px rgba(0, 4, 14, 0.38);
}
/* Mirrors the :not() chain of the generic suffix surface rule (0,6,0) so the
   note does not paint a surface box inside the card. */
[data-theme="dark"] .page-stage .add-teacher-trigger :is(.add-teacher-trigger-copy, .add-teacher-trigger-note):not(.icon-card):not(.status-card):not(.sidebar-config-card) {
  background: transparent !important;
}
[data-theme="dark"] .page-stage .add-teacher-trigger-eyebrow {
  color: var(--app-muted);
}
[data-theme="dark"] .page-stage .add-teacher-trigger-title {
  color: var(--app-ink);
}
[data-theme="dark"] .page-stage .add-teacher-trigger-note {
  color: var(--app-muted);
}
/* Two classes: the legacy-family :is() list above resolves to 0,4,0. */
[data-theme="dark"] .page-stage .add-teacher-trigger .add-teacher-trigger-cta {
  border-color: #2a72d0 !important;
  background: linear-gradient(180deg, #2a72d0, #1f5fbf) !important;
  color: #ffffff !important;
  box-shadow: 0 6px 16px rgba(59, 140, 255, 0.3);
}
[data-theme="dark"] .page-stage .add-teacher-trigger[aria-expanded="true"] .add-teacher-trigger-cta {
  border-color: #1f5fbf !important;
  background: #1b55ad !important;
  color: #ffffff !important;
}
/* Bounded sweep: page-local light surfaces whose text inherits the dark ink
   token (white-on-light). Neutral surfaces take the shared muted surface;
   semantic surfaces keep their hue via color-mix instead of being flattened. */
[data-theme="dark"] .page-stage
  :is(
    .edit-dialog,
    .month-event-empty,
    .confirm-box,
    .period-box,
    .section-check,
    .teacher-box,
    .planning-kpi,
    .tile,
    .assignment-step,
    .subject-picker,
    .subject-grade-group.is-open .subject-grade-summary,
    .notification-field,
    .notification-popup-body,
    .feedback-box,
    .self-rating,
    .obs-modal-frame,
    .workspace-metadata,
    .knowledge-filters,
    .design-field,
    .block-shell,
    .preview-shell,
    .session-control,
    .assignment-panel-body,
    .tpc-tree-row-competency,
    .tp-result-headline,
    .stu-roster-row-nochange,
    .major-guidance,
    .major-guidance[data-state="no-match"]
  ) {
  border-color: var(--app-line) !important;
  background: var(--app-surface-muted) !important;
  color: var(--app-ink);
}
[data-theme="dark"] .page-stage .qualification-dropdown-clear:hover {
  background: var(--app-brand-soft) !important;
}
[data-theme="dark"] .page-stage .tp-op-form .tp-assessment-levels .tp-level-option:has(input:checked) .tp-rubric-tile {
  background: var(--app-brand-soft);
}
[data-theme="dark"] .page-stage .major-guidance[data-state="aligned"] {
  border-color: color-mix(in srgb, #22c55e 45%, var(--app-line)) !important;
  background: color-mix(in srgb, #22c55e 12%, var(--app-surface-muted)) !important;
}
[data-theme="dark"] .page-stage :is(.major-guidance[data-state="override"], .major-guidance[data-state="review"], .self-evidence) {
  border-color: color-mix(in srgb, #f0b44c 45%, var(--app-line)) !important;
  background: color-mix(in srgb, #f0b44c 12%, var(--app-surface-muted)) !important;
  color: var(--app-ink);
}
[data-theme="dark"] .page-stage :is(.danger-zone, .has-save-all-error, .stu-roster-row-error) {
  border-color: color-mix(in srgb, #ff8a80 45%, var(--app-line)) !important;
  background: color-mix(in srgb, #ff8a80 12%, var(--app-surface-muted)) !important;
  color: var(--app-ink);
}
/* Students roster import preview: the page-local dark-red / slate status text
   in the last cell stayed dark-on-dark once the row turned dark. */
[data-theme="dark"] .page-stage .stu-roster-row-error :is(th, td:last-child) {
  color: #ffb6c2;
}
[data-theme="dark"] .page-stage .stu-roster-row-nochange td:last-child {
  color: var(--app-muted);
}

/* Round 4 Phase C: shared surfaces that also carry a legacy -card/-group class
   (e.g. .tp-result-card, .tp-evaluation-group) keep the premium gradient,
   accent outline and hover border in Dark. The :not() chain mirrors the
   generic suffix contracts above so these rules outrank them. */
[data-theme="dark"] .page-stage .tis-surface:not(.icon-card):not(.status-card):not(.sidebar-config-card) {
  background-color: var(--app-surface) !important;
  background-image: linear-gradient(165deg, var(--app-surface-muted), var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .tp-timeline > .tp-timeline-node:not(.icon-card):not(.status-card):not(.sidebar-config-card) {
  background-color: var(--app-surface) !important;
  background-image: linear-gradient(165deg, var(--app-surface-muted), var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .tp-timeline > .tp-timeline-node.is-selected {
  border-color: var(--tis-accent) !important;
}
[data-theme="dark"] .page-stage .tp-timeline .tp-evaluation-program-card:not(.is-disabled):is(:hover, :focus-visible),
[data-theme="dark"] .page-stage .tp-timeline .tp-evaluation-program-card.is-selected {
  border-color: var(--tis-accent) !important;
}
[data-theme="dark"] .page-stage .tp-timeline-node.is-planned .tp-timeline-dot {
  background: var(--app-bg);
}

/* Round 4 Phase D: Notification Center. The legacy flat-surface rules above
   (.msg-filter/.msg-empty list, the -card suffix contract and .msg-action)
   would erase the segmented control, the unread tint and the hover outline. */
[data-theme="dark"] .page-stage .msg-filters .msg-filter {
  border-color: transparent !important;
  background: transparent !important;
  color: var(--app-muted) !important;
}
[data-theme="dark"] .page-stage .msg-filters a.msg-filter:hover {
  background: var(--app-surface-muted) !important;
  color: var(--app-ink) !important;
}
[data-theme="dark"] .page-stage .msg-filters .msg-filter.is-active {
  background: var(--tis-btn-primary) !important;
  color: #fff !important;
}
[data-theme="dark"] .page-stage .msg-filters .msg-filter.msg-timezone {
  border-color: var(--app-line) !important;
}
[data-theme="dark"] .page-stage .msg-list .msg-card:not(.icon-card):not(.status-card):not(.sidebar-config-card) {
  background-color: var(--app-surface) !important;
}
[data-theme="dark"] .page-stage .msg-list .msg-card.is-new:not(.icon-card):not(.status-card):not(.sidebar-config-card) {
  border-color: color-mix(in srgb, var(--tis-accent) 35%, var(--app-line)) !important;
  background-image: linear-gradient(90deg, color-mix(in srgb, var(--tis-accent) 12%, var(--app-surface)), var(--app-surface)) !important;
}
[data-theme="dark"] .page-stage .msg-list .msg-card:is(:hover, :focus-within) {
  border-color: var(--tis-accent) !important;
}
[data-theme="dark"] .page-stage .msg-list .msg-action.msg-action-primary {
  border-color: color-mix(in srgb, var(--tis-accent) 70%, transparent) !important;
  background: var(--tis-btn-primary) !important;
  color: #fff !important;
}
[data-theme="dark"] .page-stage .msg-list .msg-action.msg-quick:hover {
  border-color: var(--tis-accent) !important;
  color: var(--tis-accent-ink) !important;
}
[data-theme="dark"] .page-stage .msg-list .msg-empty {
  border-color: var(--app-line-strong) !important;
  background: color-mix(in srgb, var(--app-surface) 70%, transparent) !important;
}
[data-theme="dark"] .page-stage .msg-summary .msg-stat {
  border-color: var(--app-line);
  background: linear-gradient(165deg, var(--app-surface-muted), var(--app-surface));
}
[data-theme="dark"] .page-stage .notification-popup .notification-action {
  color: #fff !important;
}

/* System Configuration logo slot: stored row whose file is missing on the server. */
[data-theme="dark"] .page-stage .logo-missing {
  border-color: rgba(248, 113, 113, 0.45) !important;
  background: rgba(239, 68, 68, 0.16) !important;
  color: #ffb4ac !important;
}
