/* ══════════════════════════════════════════════════════════════════════
   JLEARN ADMIN — RESPONSIVE + DESIGN LAYER  (v2.2.0)

   Linked LAST in admin.html, after styles.css, flawless-design.css,
   dusk-theme.css and light-theme.css, so it wins the cascade by order and
   is the single place where admin layout responds to the viewport.

   Breakpoints (content-driven, not device-driven):
     ≥1920  wide desktop      ≥1440  desktop
     ≥1181  laptop            ≤1180  small laptop
     ≤1024  tablet landscape  ≤860   small tablet / large phone landscape
     ≤768   phone             ≤560   small phone        ≤400 extra small

   Rules of the layer:
     • layout, spacing and type live here — colours stay with the themes
     • nothing gets a fixed px width unless it is a rail or a touch target
     • every scroller is touch-scrollable and never traps the page
   ══════════════════════════════════════════════════════════════════════ */

/* ── 0. TOKENS ─────────────────────────────────────────────────────── */
:root {
  /* measured by admin.html on load + resize; fallback keeps the sticky nav sane */
  --admin-appbar-h: 58px;

  --admin-touch: 44px;
  --admin-touch-sm: 38px;

  --admin-pad: clamp(0.8rem, 0.55rem + 0.8vw, 1.5rem);
  --admin-card-pad: clamp(0.9rem, 0.7rem + 0.55vw, 1.5rem);
  --admin-gap: clamp(0.7rem, 0.5rem + 0.55vw, 1.15rem);

  --admin-radius: 16px;
  --admin-radius-sm: 12px;

  /* opaque backing for sticky table chrome (card bg is translucent) */
  --admin-sticky-bg: #10141d;
  --admin-sheet-bg: #0e1119;
  --admin-edge-fade: rgba(2, 6, 23, 0.55);
}

html[data-theme="light"] {
  --admin-sticky-bg: #f7f8fc;
  --admin-sheet-bg: #ffffff;
  --admin-edge-fade: rgba(248, 250, 252, 0.85);
}

/* The site-wide aurora decoration is injected on every page by
   advanced-ui-2.0.js. Behind a data dashboard it is noise and paint cost —
   same guard the teacher dashboard and landing page already use. */
.site-aurora-bg { display: none !important; }

/* ── 1. APP SHELL ──────────────────────────────────────────────────── */
/* Tablet + desktop: one fixed viewport, the rail and the content scroll
   independently. Replaces the old calc(100vh - 65px) magic number, which
   left a dead strip whenever the appbar wrapped or grew. */
@media (min-width: 769px) {
  #dashboard {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }
  #dashboard > .appbar { flex: 0 0 auto; position: relative; top: auto; }
  #dashboard > .admin-layout { flex: 1 1 auto; min-height: 0; height: auto; }
  .admin-main {
    overflow-y: auto;
    overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
  }
}

/* Phone: the document scrolls, the appbar and the section rail stick. */
@media (max-width: 768px) {
  #dashboard { display: block; height: auto; overflow: visible; }
  .admin-layout { display: block; height: auto; overflow: visible; }
  .admin-main { overflow: visible; }
  .admin-section { scroll-margin-top: calc(var(--admin-appbar-h) + 16px); }
}

/* ── 2. APPBAR ─────────────────────────────────────────────────────── */
.appbar {
  gap: 0.5rem 0.75rem;
  padding: calc(0.55rem + env(safe-area-inset-top, 0px)) var(--admin-pad) 0.55rem;
}
.appbar h1 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1 1 auto;
  font-size: clamp(0.92rem, 0.78rem + 0.45vw, 1.18rem);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.appbar h1 i { flex: 0 0 auto; }
.appbar .right { gap: 0.4rem; }
.appbar .right .btn-sm { white-space: nowrap; min-height: var(--admin-touch-sm); }
/* Shown only when a read had to fall back to the legacy D1 bundle. */
.source-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
  padding: 0.3rem 0.55rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  color: #fbbf24;
  background: rgba(234, 179, 8, 0.14);
  border: 1px solid rgba(234, 179, 8, 0.35);
}
.source-badge[hidden] { display: none; }
html[data-theme="light"] .source-badge { color: #b45309; background: rgba(217, 119, 6, 0.12); border-color: rgba(217, 119, 6, 0.3); }

/* Phones: icon-only appbar actions — the labels are wrapped in <span> so
   they can be dropped without touching the button's accessible name. */
@media (max-width: 620px) {
  .appbar { padding-inline: max(0.75rem, env(safe-area-inset-left, 0px)) max(0.75rem, env(safe-area-inset-right, 0px)); flex-wrap: nowrap; }
  .appbar h1 { font-size: 0.9rem; }
  .appbar .right .btn-sm span { display: none; }
  .appbar .right .btn-sm { padding-inline: 0.7rem; }
  .source-badge { padding-inline: 0.45rem; }
  .source-badge span { display: none; }
}
@media (max-width: 400px) {
  .appbar h1 { font-size: 0.88rem; }
  /* Keep a readable (truncated) title rather than a bare logo. */
  .appbar h1 span.appbar-title-text {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* ── 3. NAVIGATION: SIDE TABS (desktop/tablet) + HAMBURGER DRAWER (phone) */
.nav-toggle { display: none; }
.admin-nav-head, .admin-nav-label, .admin-nav-foot, .admin-nav-scrim { display: none; }

/* ≥769px: permanent side tabs, flat against the content pane. */
@media (min-width: 769px) {
  .admin-sidebar {
    width: clamp(206px, 17vw, 264px);
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    padding: 0.9rem 0.7rem;
    gap: 0.15rem;
  }
  .admin-nav-label {
    display: block;
    padding: 0.15rem 0.9rem 0.45rem;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .sidebar-nav { display: flex; flex-direction: column; gap: 0.15rem; }
  .admin-sidebar .sidebar-link {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    min-height: var(--admin-touch);
    padding: 0.55rem 0.85rem;
    border: 0;
    border-left: 3px solid transparent;
    border-radius: 0 0.7rem 0.7rem 0;
    font-weight: 600;
    white-space: nowrap;
  }
  .admin-sidebar .sidebar-link i { width: 18px; text-align: center; flex: 0 0 auto; }
  .admin-sidebar .sidebar-link.active {
    border-left-color: #818cf8;
    background: rgba(99, 102, 241, 0.16);
    box-shadow: inset 0 0 0 1px rgba(99, 102, 241, 0.22);
  }
  .admin-sidebar .sidebar-link.danger-link.active {
    border-left-color: #f87171;
    background: rgba(239, 68, 68, 0.14);
    box-shadow: inset 0 0 0 1px rgba(239, 68, 68, 0.22);
  }
}
/* Tablet: same side tabs, tighter metrics. */
@media (min-width: 769px) and (max-width: 1024px) {
  .admin-sidebar { width: 188px; padding: 0.7rem 0.5rem; }
  .admin-nav-label { padding-inline: 0.7rem; }
  .admin-sidebar .sidebar-link { padding: 0.5rem 0.6rem; font-size: 0.83rem; gap: 0.55rem; }
  .admin-sidebar .sidebar-link i { width: 16px; font-size: 0.95rem; }
}

/* ≤768px: off-canvas hamburger drawer, scrim behind it. */
@media (max-width: 768px) {
  .nav-toggle {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: var(--admin-touch);
    min-width: var(--admin-touch);
    padding-inline: 0;
  }
  /* the hamburger takes over the logo's job in the appbar */
  .appbar h1 i.fa-graduation-cap { display: none; }

  .admin-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(84vw, 320px);
    max-width: 320px;
    z-index: 10001; /* above the cookie-consent banner (9990) */
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: calc(0.85rem + env(safe-area-inset-top, 0px)) 0.8rem calc(0.85rem + env(safe-area-inset-bottom, 0px));
    background: var(--admin-sheet-bg);
    border-right: 1px solid var(--border);
    box-shadow: 24px 0 60px rgba(2, 6, 23, 0.45);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    transform: translateX(-102%);
    visibility: hidden;
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear 0.22s;
  }
  .admin-sidebar.open {
    transform: none;
    visibility: visible;
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
  }
  .admin-nav-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.1rem 0.15rem 0.7rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.5rem;
  }
  .admin-nav-brand { display: flex; align-items: center; gap: 0.5rem; font-weight: 800; font-size: 0.95rem; }
  .admin-nav-brand i { color: var(--accent, #818cf8); }
  .admin-nav-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 0.6rem;
    background: transparent;
    color: var(--muted);
    font-size: 1.05rem;
    cursor: pointer;
  }
  .admin-nav-close:hover { background: var(--surface-soft, rgba(148, 163, 184, 0.14)); color: var(--text); }
  .admin-nav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgba(2, 6, 23, 0.6);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
  }
  .admin-nav-scrim.show {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.2s ease, visibility 0s;
  }
  body.admin-nav-open { overflow: hidden !important; }

  .sidebar-nav { display: flex; flex-direction: column; gap: 0.15rem; }
  .admin-sidebar .sidebar-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 46px;
    padding: 0.6rem 0.85rem;
    border: 0;
    border-left: 3px solid transparent;
    border-radius: 0.6rem;
    font-size: 0.92rem;
    font-weight: 600;
    white-space: nowrap;
  }
  .admin-sidebar .sidebar-link i { width: 18px; text-align: center; flex: 0 0 auto; }
  .admin-sidebar .sidebar-link.active,
  .admin-sidebar .sidebar-link.active:hover {
    border-left-color: #818cf8;
    background: rgba(99, 102, 241, 0.16);
    color: #f8fafc;
  }
  html[data-theme="light"] .admin-sidebar .sidebar-link.active { color: var(--text); }
  .admin-sidebar .sidebar-link.danger-link.active { border-left-color: #f87171; background: rgba(239, 68, 68, 0.14); }
  #sidebar-credits-badge { flex: 0 0 auto; }
  .admin-nav-foot {
    display: flex;
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border);
  }
  .admin-nav-foot .btn { width: 100%; justify-content: center; min-height: var(--admin-touch); }
}
@media (max-width: 400px) {
  .admin-sidebar .sidebar-link { font-size: 0.86rem; padding: 0.55rem 0.7rem; }
}

/* ── 4. CONTAINER, SECTIONS, CARDS ─────────────────────────────────── */
.container {
  max-width: 1300px;
  padding: var(--admin-pad);
}
@media (min-width: 1440px) { .container { max-width: 1420px; } }
@media (min-width: 1920px) { .container { max-width: 1680px; } }

.section { margin-top: clamp(1.25rem, 1rem + 1vw, 2.25rem); }
.section > h2,
.section h2 {
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.22rem);
  margin-bottom: 0.7rem;
}
.section > p { max-width: 78ch; }

.card {
  padding: var(--admin-card-pad) !important; /* beats mobile-responsive.css 16px !important */
  border-radius: var(--admin-radius);
}
.card h3 { font-size: clamp(0.72rem, 0.68rem + 0.15vw, 0.82rem); }
.card .big {
  font-size: clamp(1.3rem, 1.05rem + 1vw, 2.05rem);
  overflow-wrap: anywhere;
}

/* KPI + mini grids: intrinsic columns, never narrower than the viewport. */
.grid { gap: var(--admin-gap); margin: var(--admin-gap) 0; }
.grid-kpi { grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); }
.grid-mini { grid-template-columns: repeat(auto-fit, minmax(min(100%, 148px), 1fr)); }
.grid-duo { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
/* Six-up stat clusters split 4+2 in a wide-ish tablet pane; 3×2 reads
   as a deliberate grid instead of a row with a hole. */
@media (min-width: 561px) and (max-width: 1100px) {
  .grid-mini:has(> :nth-child(6):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .grid-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-mini { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 360px) {
  .grid-kpi, .grid-mini { grid-template-columns: minmax(0, 1fr); }
}

.mini {
  border-radius: var(--admin-radius-sm);
  padding: 0.65rem 0.7rem;
  min-width: 0;
}
.mini small { overflow-wrap: anywhere; }
.mini strong {
  font-size: clamp(1.05rem, 0.92rem + 0.55vw, 1.4rem);
  overflow-wrap: anywhere;
}

/* ── 5. TOOLBARS + FILTERS ─────────────────────────────────────────── */
.admin-toolbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.admin-toolbar > div { min-width: 0; }
.admin-toolbar strong { font-size: clamp(0.88rem, 0.82rem + 0.25vw, 0.98rem); }
.admin-toolbar small { max-width: 70ch; }
.admin-toolbar-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.filters { gap: 0.5rem; }
.filters input, .filters select {
  flex: 1 1 190px;
  width: auto;
  min-width: 0;
}
@media (max-width: 768px) {
  .admin-toolbar { align-items: stretch; gap: 0.6rem; }
  .admin-toolbar-controls { width: 100%; }
  .admin-toolbar-controls select,
  .admin-toolbar-controls input[type="text"] { flex: 1 1 130px; min-width: 0; }
  .filters input, .filters select { flex: 1 1 100%; }
}

/* ── 6. TAB STRIPS ─────────────────────────────────────────────────── */
.ai-tabbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1rem;
}
.ai-tab-btn { min-height: 40px; border-radius: 0.5rem 0.5rem 0 0; }

/* Narrow viewports: one row that scrolls sideways instead of a 4-deck
   stack of wrapped tabs eating half the screen. Bleeds to the card edges
   so the strip reads as a native control. */
@media (max-width: 900px) {
  .ai-tabbar {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin-inline: calc(var(--admin-card-pad) * -1);
    padding: 0.15rem var(--admin-card-pad) 0;
    scroll-padding-inline: var(--admin-card-pad);
  }
  .ai-tabbar::-webkit-scrollbar { display: none; width: 0; height: 0; }
  .ai-tab-btn {
    flex: 0 0 auto;
    min-height: 42px;
    padding: 0.5rem 0.75rem;
    font-size: 0.8rem;
    white-space: nowrap;
  }
}

/* ── 7. TABLES ─────────────────────────────────────────────────────── */
.table-wrap {
  border-radius: var(--admin-radius-sm);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table-wrap table { width: 100%; min-width: 100%; border-collapse: collapse; }
/* mobile-enhancements.js injects .table-responsive around every table it
   finds on load. Inside the admin's own .table-wrap that leaves a second,
   outer-sized scroll container: the inner one swallows horizontal scrolling,
   the sticky header anchors to the wrong scrollport, and the wrapper draws
   a second border. Dissolving the injected box restores one scroller. */
.table-wrap > .table-responsive { display: contents; }
.table-wrap .table-responsive > table { min-width: 100%; }
.table-wrap th, .table-wrap td { padding: 0.7rem 0.75rem; vertical-align: middle; }
.table-wrap th {
  white-space: nowrap;
  font-size: 0.78rem;
  letter-spacing: 0.01em;
}
.table-wrap td { font-size: clamp(0.76rem, 0.72rem + 0.15vw, 0.87rem); }
.table-wrap td small { overflow-wrap: anywhere; }
.table-wrap .tag { white-space: nowrap; }

/* Opaque, sticky column headers. Only the LAST thead row sticks, so the
   colspan title banners ("Recent VIP charges") scroll away cleanly. */
.table-wrap thead tr:last-child th {
  position: sticky;
  top: 0;
  z-index: 3;
  background-color: var(--admin-sticky-bg);
  background-image: linear-gradient(180deg, rgba(99, 102, 241, 0.20), rgba(99, 102, 241, 0.08));
}
.table-wrap thead tr:not(:last-child) th { position: static; }

/* Phones: cap tall tables so the header stays visible while rows scroll. */
@media (max-width: 768px) {
  .table-wrap { max-height: min(68vh, 540px); overflow-y: auto; }
  .table-wrap th, .table-wrap td { padding: 0.55rem 0.6rem; }
  .table-wrap .btn-sm { min-height: var(--admin-touch-sm); padding: 0.35rem 0.6rem; }
}
@media (max-width: 480px) {
  .table-wrap th, .table-wrap td { padding: 0.5rem 0.5rem; }
}

/* Sticky identity column — opt-in per table, only when it can scroll. */
@media (max-width: 900px) {
  .tbl-sticky-id thead tr:last-child th:first-child,
  .tbl-sticky-id tbody td:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background-color: var(--admin-sticky-bg);
    box-shadow: 1px 0 0 var(--border);
  }
  .tbl-sticky-id thead tr:last-child th:first-child { z-index: 4; }
  .tbl-sticky-id tbody tr:hover td:first-child { background-color: var(--admin-sticky-bg); }
}

/* Scroll affordance: JS marks wraps that actually overflow (.is-scrollable)
   and clears the hint once the reader reaches the end (.at-end). */
.table-wrap { position: relative; }
.table-wrap.is-scrollable::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 26px;
  pointer-events: none;
  background: linear-gradient(270deg, var(--admin-edge-fade), transparent);
  opacity: 1;
  transition: opacity 0.25s ease;
}
.table-wrap.is-scrollable.at-end::after { opacity: 0; }

/* ── 7b. PER-TABLE MIN WIDTHS + COLUMN DIET ──────────────────────────
   Wide tables keep a floor so cells never crush; low-value columns drop
   out on phones so most tables fit without sideways scrolling at all. */
#vip-teacher-table, #vip-tool-table, #vip-recent-table,
#credits-requests-table, #credits-balances-table, #bug-reports-table { min-width: 640px; }
#paid-transactions-table { min-width: 760px; }
#neural-engines-table, #byteacher-table, #teachers-table, #feature-locks-table { min-width: 560px; }
#assistant-logs-table, #imports-table, #errors-table { min-width: 460px; }

/* ≤1024 — drop the redundant / derivable columns */
@media (max-width: 1024px) {
  #teachers-table thead tr:last-child th:nth-child(6),
  #teachers-table tbody td:nth-child(6),                       /* Joined */
  #credits-balances-table thead tr:last-child th:nth-child(6),
  #credits-balances-table tbody td:nth-child(6),                /* Total purchased */
  #credits-requests-table thead tr:last-child th:nth-child(7),
  #credits-requests-table tbody td:nth-child(7),                /* Teacher note */
  #vip-teacher-table thead tr:last-child th:nth-child(6),
  #vip-teacher-table tbody td:nth-child(6),                     /* Cost (PHP) — USD column already shows it */
  #vip-recent-table thead tr:last-child th:nth-child(7),
  #vip-recent-table tbody td:nth-child(7),                      /* Revenue — totals card covers it */
  #assistant-logs-table thead tr:last-child th:nth-child(6),
  #assistant-logs-table tbody td:nth-child(6),                  /* Status — always success */
  #neural-engines-table thead tr:last-child th:nth-child(5),
  #neural-engines-table tbody td:nth-child(5),                  /* Reset */
  #byteacher-table thead tr:last-child th:nth-child(5),
  #byteacher-table tbody td:nth-child(5),                       /* Engines */
  #feature-locks-table thead tr:last-child th:nth-child(4),
  #feature-locks-table tbody td:nth-child(4),                   /* Locked by */
  #feature-locks-table thead tr:last-child th:nth-child(5),
  #feature-locks-table tbody td:nth-child(5),                   /* Locked at */
  #tm-students thead tr:last-child th:nth-child(4),
  #tm-students tbody td:nth-child(4),                           /* Student email */
  #tm-students thead tr:last-child th:nth-child(5),
  #tm-students tbody td:nth-child(5),                             /* Student joined */
  #paid-transactions-table thead tr:last-child th:nth-child(8),
  #paid-transactions-table tbody td:nth-child(8) { display: none; } /* Payment reference */
}

/* ≤640 — second course */
@media (max-width: 640px) {
  #teachers-table thead tr:last-child th:nth-child(2),
  #teachers-table tbody td:nth-child(2),                        /* School (shown in the profile modal) */
  #credits-balances-table thead tr:last-child th:nth-child(5),
  #credits-balances-table tbody td:nth-child(5),                /* PHP value */
  #credits-requests-table thead tr:last-child th:nth-child(5),
  #credits-requests-table tbody td:nth-child(5),                /* Pass / VIP credits */
  #vip-teacher-table thead tr:last-child th:nth-child(8),
  #vip-teacher-table tbody td:nth-child(8),                     /* Margin */
  #vip-tool-table thead tr:last-child th:nth-child(7),
  #vip-tool-table tbody td:nth-child(7),                        /* Margin */
  #vip-recent-table thead tr:last-child th:nth-child(4),
  #vip-recent-table tbody td:nth-child(4),                      /* Model */
  #assistant-logs-table thead tr:last-child th:nth-child(3),
  #assistant-logs-table tbody td:nth-child(3),                  /* Input tokens */
  #assistant-logs-table thead tr:last-child th:nth-child(4),
  #assistant-logs-table tbody td:nth-child(4),                  /* Output tokens */
  #neural-engines-table thead tr:last-child th:nth-child(2),
  #neural-engines-table tbody td:nth-child(2),                  /* Provider */
  #byteacher-table thead tr:last-child th:nth-child(6),
  #byteacher-table tbody td:nth-child(6),                       /* Last used */
  #bug-reports-table thead tr:last-child th:nth-child(1),
  #bug-reports-table tbody td:nth-child(1),                     /* ID */
  #tm-results thead tr:last-child th:nth-child(4),
  #tm-results tbody td:nth-child(4),                            /* Result status */
  #tm-results thead tr:last-child th:nth-child(5),
  #tm-results tbody td:nth-child(5),                            /* Submitted */
  #tm-txn thead tr:last-child th:nth-child(4),
  #tm-txn tbody td:nth-child(4),                                /* Balance after */
  #admin-ledger-table thead tr:last-child th:nth-child(4),
  #admin-ledger-table tbody td:nth-child(4),                     /* Balance after */
  #paid-transactions-table thead tr:last-child th:nth-child(7),
  #paid-transactions-table tbody td:nth-child(7) { display: none; } /* Channel (icon in ref) */
}

/* ≤440 — keep the decision columns only */
@media (max-width: 440px) {
  #teachers-table thead tr:last-child th:nth-child(3),
  #teachers-table tbody td:nth-child(3),                        /* Students */
  #credits-balances-table thead tr:last-child th:nth-child(2),
  #credits-balances-table tbody td:nth-child(2),                /* Email */
  #vip-teacher-table thead tr:last-child th:nth-child(2),
  #vip-teacher-table tbody td:nth-child(2),                     /* VIP calls */
  #tm-lessons thead tr:last-child th:nth-child(2),
  #tm-lessons tbody td:nth-child(2),                            /* Subject */
  #paid-transactions-table thead tr:last-child th:nth-child(4),
  #paid-transactions-table tbody td:nth-child(4) { display: none; } /* Type badge */
}

/* ── 8. MODALS ─────────────────────────────────────────────────────── */
/* mobile-responsive.css forces `overflow-y:auto !important` on body, so a
   plain inline lock loses; the class carries the !important that wins. */
body.admin-modal-open { overflow: hidden !important; }
.admin-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 10010; /* above the cookie-consent banner, whose actions must not block a dialog */
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(2, 6, 23, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.admin-modal-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  max-height: min(92vh, 92dvh);
  overflow: hidden;
  background: var(--admin-sheet-bg);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
  animation: adminSheetIn 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes adminSheetIn { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: none; } }

.admin-modal--wide .admin-modal-card { max-width: 1100px; }
.admin-modal--mid .admin-modal-card { max-width: 860px; }
.admin-modal--grant .admin-modal-card { max-width: 560px; }

.admin-modal-head {
  flex: 0 0 auto;
  padding: 0.9rem var(--admin-card-pad);
  border-bottom: 1px solid var(--border);
  background: var(--admin-sheet-bg);
}
.admin-modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: var(--admin-card-pad);
}
.admin-modal-foot {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.8rem var(--admin-card-pad) calc(0.8rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border);
  background: var(--admin-sheet-bg);
}
.admin-modal-close {
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.4rem 0.55rem;
  min-width: var(--admin-touch-sm);
  min-height: var(--admin-touch-sm);
  border-radius: 0.6rem;
}
.admin-modal-close:hover { background: rgba(148, 163, 184, 0.14); color: var(--text); }

/* Head that carries a title block plus a close button */
.admin-modal-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.admin-modal-head-row > div:first-child { min-width: 0; }
.admin-modal-head-row h3 {
  margin: 0;
  font-size: clamp(0.98rem, 0.9rem + 0.4vw, 1.15rem);
  overflow-wrap: anywhere;
}
.admin-modal-head-row small { color: var(--muted); font-size: 0.82rem; overflow-wrap: anywhere; }

/* Teacher profile header inside the sticky modal head */
.tm-id { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.tm-id-main { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
.tm-avatar {
  width: 46px; height: 46px;
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  border-radius: 14px;
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  font-size: 1.2rem;
}
.tm-id-text { min-width: 0; }
.tm-id-text h3 {
  margin: 0;
  font-size: clamp(1rem, 0.92rem + 0.4vw, 1.2rem);
  overflow-wrap: anywhere;
}
.tm-id-text .tm-sub {
  font-size: 0.8rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.tm-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.35rem; }
.tm-side { display: flex; align-items: center; gap: 0.45rem; flex: 0 0 auto; }
.tm-live { color: var(--muted); font-size: 0.68rem; white-space: nowrap; }
.tm-tabs { margin: 0.75rem 0 -0.9rem; border-bottom: 0; }

/* Screenshot viewer (built at runtime by viewBugScreenshot) */
.admin-modal--viewer { padding: 1rem; background: rgba(0, 0, 0, 0.92); z-index: 10015; }
.admin-modal--viewer img {
  max-width: 100%;
  max-height: min(86vh, 86dvh);
  object-fit: contain;
  border-radius: 10px;
}
.admin-modal--viewer .admin-modal-close {
  position: absolute;
  top: 0.5rem; right: 0.5rem;
  background: rgba(239, 68, 68, 0.92);
  color: #fff;
  border-radius: 999px;
  min-width: var(--admin-touch);
  min-height: var(--admin-touch);
}

/* Phone: the modal becomes a full-bleed sheet — no floating card to
   squint at, header and action bar pinned, safe-area aware. */
@media (max-width: 768px) {
  .admin-modal { padding: 0; align-items: stretch; justify-content: stretch; }
  .admin-modal-card {
    max-width: none;
    width: 100%;
    height: 100%;
    height: 100dvh;
    max-height: none;
    border: 0;
    border-radius: 0;
    animation: adminSheetUp 0.24s cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  .admin-modal-head {
    padding-top: calc(0.75rem + env(safe-area-inset-top, 0px));
  }
  /* Two rows of two, so a 4-action footer never crowds the sheet's bottom edge. */
  .admin-modal-foot .btn { flex: 1 1 calc(50% - 0.25rem); justify-content: center; min-height: var(--admin-touch); }
  .tm-avatar { width: 40px; height: 40px; border-radius: 12px; font-size: 1.05rem; }
  .tm-live { display: none; }
  /* Keep the pinned head shallow: one scrollable tag row instead of a
     wrapped block that can eat a quarter of a phone screen. */
  .tm-id { gap: 0.5rem; }
  .tm-id-main { gap: 0.55rem; }
  .tm-tags {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 2px;
  }
  .tm-tags::-webkit-scrollbar { display: none; }
  .tm-tags .tag { flex: 0 0 auto; }
  .tm-tabs { margin: 0.55rem 0 -0.9rem; }
  .admin-modal--viewer { padding: 0.5rem; }
}
@keyframes adminSheetUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }

/* Short landscape phones: don't let the sheet clip the action bar */
@media (max-height: 520px) and (orientation: landscape) {
  .admin-modal-card { max-height: 100dvh; }
  .admin-modal--viewer img { max-height: 92dvh; }
}

/* ── 9. TOAST ──────────────────────────────────────────────────────── */
.toast {
  z-index: 10020; /* above every modal — it reports modal actions */
  bottom: calc(1.1rem + env(safe-area-inset-bottom, 0px));
  right: 1.1rem;
  max-width: min(90vw, 420px);
}
@media (max-width: 768px) {
  .toast {
    left: 0.75rem;
    right: 0.75rem;
    max-width: none;
    text-align: center;
    /* clears the fixed STAGING badge env-config.js pins bottom-left */
    bottom: calc(2.9rem + env(safe-area-inset-bottom, 0px));
  }
}

/* ── 10. CHARTS ────────────────────────────────────────────────────── */
.bar-chart {
  height: clamp(150px, 24vh, 260px);
  gap: clamp(2px, 0.4vw, 0.4rem);
  padding: 1rem 0.5rem 0.4rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.bar-group { min-width: clamp(7px, 0.9vw, 18px); }
.bar-legend { gap: 0.6rem 1rem; font-size: 0.78rem; }
.usage-list li { gap: 0.75rem; font-size: 0.85rem; }
.usage-list li > :last-child { text-align: right; }

/* ── 11. FORMS, BUTTONS, TOUCH ─────────────────────────────────────── */
.btn { border-radius: 0.7rem; }
.btn-sm { border-radius: 0.55rem; }
input[type="text"], input[type="number"], input[type="email"], input[type="password"], select, textarea {
  border-radius: 0.6rem;
}
@media (max-width: 768px) {
  .btn { min-height: var(--admin-touch); }
  .btn-sm { min-height: 40px; }
  /* 16px keeps iOS from auto-zooming the page on focus */
  .admin-modal input, .admin-modal select, .filters input, .filters select { font-size: 16px; }
  #quick-grant-modal .qg-pick { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  #quick-grant-modal .qg-pick .btn { min-height: 46px; font-size: 0.76rem; }
}
@media (max-width: 400px) {
  #quick-grant-modal .qg-pick { grid-template-columns: minmax(0, 1fr) !important; }
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid #818cf8;
  outline-offset: 2px;
}
html[data-theme="light"] :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline-color: #4f46e5;
}

/* Hover-only affordances must not fire on touch */
@media (hover: none) and (pointer: coarse) {
  .card:hover { transform: none; box-shadow: var(--shadow); }
  .btn:hover { transform: none; }
  tbody tr:hover { background: transparent; }
  .sidebar-link:hover { background: transparent; color: var(--muted); }
  .sidebar-link.active:hover { background: rgba(99, 102, 241, 0.16); color: #f8fafc; }
  .ai-tab-btn:hover { background: transparent; color: var(--muted); }
  .ai-tab-btn.active:hover { color: #a855f7; background: rgba(168, 85, 247, 0.08); }
}

/* ── 12. LOGIN ─────────────────────────────────────────────────────── */
.login-page { padding: 1rem; min-height: 100vh; min-height: 100dvh; }
.login-box { width: 100%; max-width: 400px; padding: clamp(1.25rem, 1rem + 1.5vw, 2.25rem); }
.login-box .btn { width: 100%; min-height: var(--admin-touch); }
@media (max-width: 400px) {
  .login-box h1 { font-size: 1.25rem; }
}

/* ── 12b. THEME-ACCURATE TEXT COLOURS ───────────────────────────────
   The admin still carries many dark-first inline colours. On white cards in
   light mode they fall under WCAG AA, so map every pastel accent to its
   AA-safe -800 equivalent. Dark mode keeps its original palette untouched. */
/* One token fix covers every `color:var(--muted)` label, small and caption.
   Both html and body carry data-theme, and body is the closer ancestor. */
html[data-theme="light"],
html[data-theme="light"] body { --muted: #475569; --text-muted: #475569; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar, .login-page) [style*="color:#f8fafc"] { color: var(--text) !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar, .login-page) [style*="color:#cbd5e1"] { color: #475569 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar, .login-page) [style*="color:#94a3b8"] { color: #475569 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar, .login-page) [style*="color:#9ca3af"] { color: #4b5563 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar, .login-page) [style*="color:#e5e7eb"] { color: #374151 !important; }
/* amber / gold */
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#facc15"] { color: #854d0e !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#eab308"] { color: #854d0e !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#fbbf24"] { color: #9a3412 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#f59e0b"] { color: #9a3412 !important; }
/* sky / cyan */
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#38bdf8"] { color: #075985 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#22d3ee"] { color: #155e75 !important; }
/* green / emerald */
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#4ade80"] { color: #166534 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#22c55e"] { color: #166534 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#34d399"] { color: #065f46 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#a7f3d0"] { color: #065f46 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#6ee7b7"] { color: #065f46 !important; }
/* indigo / violet / purple */
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#818cf8"] { color: #3730a3 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#a5b4fc"] { color: #3730a3 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#c7d2fe"] { color: #312e81 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#6366f1"] { color: #3730a3 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#c084fc"] { color: #6b21a8 !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#a855f7"] { color: #6b21a8 !important; }
/* red */
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#ef4444"] { color: #991b1b !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#f87171"] { color: #991b1b !important; }
html[data-theme="light"] :is(.admin-main, .admin-modal, .appbar, .admin-sidebar) [style*="color:#fca5a5"] { color: #991b1b !important; }
/* dark slabs used as inline backgrounds */
html[data-theme="light"] .admin-main [style*="rgba(15, 23, 42"],
html[data-theme="light"] .admin-main [style*="rgba(14, 17, 26"],
html[data-theme="light"] .admin-main [style*="rgba(30,41,59"],
html[data-theme="light"] .admin-main [style*="rgba(30, 41, 59"],
html[data-theme="light"] .admin-modal [style*="rgba(30,41,59"],
html[data-theme="light"] .admin-modal [style*="rgba(15, 23, 42"] { background: var(--card-bg, #fff) !important; }
html[data-theme="light"] #admin-theme-toggle { background: var(--surface, #fff) !important; color: var(--text); }
/* Login title is gradient-clipped text; the dark pair (#e0e7ff/#f5d0fe) is
   invisible on the white login card. */
html[data-theme="light"] .login-box h1 {
  background: linear-gradient(90deg, #312e81, #6b21a8);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* Solid success/danger buttons: white on #10b981 / #ef4444 is 2.5:1 and 3.8:1. */
html[data-theme="light"] .btn-success { background: #047857 !important; border-color: #047857 !important; color: #fff !important; }
html[data-theme="light"] .btn-danger { background: #b91c1c !important; border-color: #b91c1c !important; color: #fff !important; }
/* Active side tab: #4f46e5 on the tinted active pill measured 4.48:1. */
html[data-theme="light"] .admin-sidebar .sidebar-link.active { color: #3730a3; }
/* Credits KPI: the "total in circulation" value is long, so let its row wrap
   instead of colliding with the trailing hint. */
div:has(> #sec-credits-total-issued) { flex-wrap: wrap; gap: 0.2rem 0.6rem; }
#sec-credits-total-issued { font-size: clamp(1.2rem, 0.95rem + 0.9vw, 1.55rem); line-height: 1.15; }
/* Primary buttons: the shared violet ramp ends at #8b5cf6, where a white
   label is only 3.6:1 (both themes). Keep the violet identity, deepen the ramp.
   Buttons that carry their own background/colour (chip-style actions) are left
   to the accent map above. */
:is(.admin-main, .admin-modal, .admin-sidebar, .appbar, .login-page) .btn:not([style*="background"]):not([style*="color:"]):not(.btn-success):not(.btn-danger),
:is(.admin-main, .admin-modal, .appbar) .btn[style*="linear-gradient(135deg,#6366f1"] {
  background: linear-gradient(135deg, #4f46e5, #4338ca) !important;
  color: #fff !important;
}
/* Credit pickers: the shared .btn gradient is violet, so dark inherited text
   disappears. Render them as light chips with AA text instead. */
html[data-theme="light"] #quick-grant-modal .qg-pick .btn {
  background: #fff !important;
  border: 1px solid rgba(99, 102, 241, 0.45) !important;
  color: #0f172a !important;
  box-shadow: none;
}
html[data-theme="light"] #quick-grant-modal .qg-pick .btn strong { color: #0f172a !important; }
html[data-theme="light"] #quick-grant-modal .qg-pick .btn small { color: #475569 !important; opacity: 1; }
html[data-theme="light"] #quick-grant-modal .qg-pick .btn[style*="rgba(16,185,129"] { background: #f0fdf4 !important; border-color: rgba(22, 163, 74, 0.5) !important; color: #166534 !important; }
html[data-theme="light"] #quick-grant-modal .qg-pick .btn[style*="rgba(99,102,241"] { background: #eef2ff !important; border-color: rgba(79, 70, 229, 0.45) !important; color: #3730a3 !important; }
html[data-theme="light"] #quick-grant-modal .qg-pick .btn[style*="rgba(239,68,68"] { background: #fef2f2 !important; border-color: rgba(220, 38, 38, 0.45) !important; color: #991b1b !important; }
/* Small print inside coloured buttons/badges must inherit the control's own
   colour: the global `small { color: var(--muted) }` made the credit-picker
   captions unreadable on the violet buttons in both themes. */
.qg-pick small, .btn small, .tag small, .badge small { color: inherit; opacity: 0.82; }
/* Active tab: #a855f7 measured 4.42:1 on the dark modal surface and 3.6:1 on
   the light one. */
html:not([data-theme="light"]) .ai-tab-btn.active { color: #c084fc; }
html[data-theme="light"] .ai-tab-btn.active { color: #7e22ce; }
/* VIP profit figure — coloured by class so each theme can pick an AA tone. */
#vip-profit.is-profit-pos { color: #4ade80; }
#vip-profit.is-profit-neg { color: #f87171; }
html[data-theme="light"] #vip-profit.is-profit-pos { color: #166534; }
html[data-theme="light"] #vip-profit.is-profit-neg { color: #b91c1c; }

/* ── 13. MOTION + PRINT ────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  .appbar, .admin-sidebar, .toast, .admin-modal, .btn { display: none !important; }
  #dashboard { display: block !important; height: auto !important; overflow: visible !important; }
  .admin-main { overflow: visible !important; }
  .table-wrap { max-height: none !important; overflow: visible !important; }
  .card { break-inside: avoid; box-shadow: none; }
}
