/* ── VARIABLES ─────────────────────────────────────────────── */
:root {
  --navy:    #002855;
  --gold:    #ac926c;
  --gold-lt: #c8aa84;
  --white:   #ffffff;
  --gray-50: #f8f9fa;
  --gray-100:#f1f3f5;
  --gray-200:#e9ecef;
  --gray-300:#dee2e6;
  --gray-400:#ced4da;
  --gray-500:#adb5bd;
  --gray-600:#868e96;
  --gray-700:#495057;
  --gray-800:#343a40;
  --gray-900:#212529;
  --green:   #2f9e44;
  --yellow:  #f59f00;
  --red:     #e03131;
  --blue:    #1971c2;

  --sidebar-w: 220px;
  --topbar-h:  56px;
  --radius:    6px;
  --shadow:    0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.15);
}

/* ── RESET ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size: 14px; color: var(--gray-900); background: var(--gray-50); }
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }
ul { list-style: none; }
button { cursor: pointer; font-family: inherit; font-size: inherit; }
input, select, textarea { font-family: inherit; font-size: inherit; }

.hidden { display: none !important; }

/* ── LOGIN SCREEN ──────────────────────────────────────────── */
.login-screen {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh;
  background: linear-gradient(135deg, var(--navy) 0%, color-mix(in srgb, var(--navy) 62%, #ffffff) 100%);
}
.login-card {
  background: var(--white); border-radius: 12px; padding: 48px 40px;
  text-align: center; box-shadow: var(--shadow-md); width: 360px;
}
.login-logo-emblem {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--navy); margin: 0 auto 16px;
  position: relative;
}
.login-logo-emblem::after {
  content: 'AWHS'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--gold); font-size: 11px; font-weight: 700; letter-spacing: 0.5px;
}
.login-crest { width: 210px; height: auto; display: block; margin: 0 auto 14px; }
.login-logo h1 { font-size: 22px; font-weight: 700; color: var(--navy); margin-bottom: 4px; }
.login-logo p  { color: var(--gray-600); margin-bottom: 32px; }
.btn-google {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 12px 16px; border: 1px solid var(--gray-300);
  border-radius: var(--radius); background: var(--white); font-weight: 500;
  transition: background 0.15s, box-shadow 0.15s;
}
.btn-google:hover { background: var(--gray-50); box-shadow: var(--shadow); }
.login-note { margin-top: 16px; color: var(--gray-500); font-size: 12px; }

/* ── APP SHELL ─────────────────────────────────────────────── */
.app-shell { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.app-body { display: flex; flex: 1; overflow: hidden; min-height: 0; }

/* ── TOP BAR (product-area switcher) ───────────────────────── */
.topbar {
  height: var(--topbar-h); flex-shrink: 0; background: var(--navy); color: var(--white);
  display: flex; align-items: stretch; gap: 8px; padding: 0 16px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.25); z-index: 20;
}
.topbar-brand {
  display: flex; align-items: center; gap: 10px; color: var(--white);
  font-weight: 700; font-size: 15px; text-decoration: none; flex-shrink: 0;
}
.topbar-brand:hover { text-decoration: none; color: var(--white); }
.topbar-logo {
  width: 34px; height: 34px; border-radius: 7px; background: var(--white);
  flex-shrink: 0; display: flex; align-items: center; justify-content: center; padding: 3px;
}
.topbar-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.topbar-areas { display: flex; align-items: stretch; gap: 2px; margin-left: 12px; overflow-x: auto; flex: 1; }
.topbar-area {
  padding: 0 14px; background: none; border: none; cursor: pointer; white-space: nowrap;
  color: rgba(255,255,255,0.72); font-size: 14px; font-weight: 600;
  border-bottom: 3px solid transparent; transition: color 0.15s, border-color 0.15s;
}
.topbar-area:hover { color: var(--white); }
.topbar-area.active { color: var(--white); border-bottom-color: var(--gold); }
.topbar-right { display: flex; align-items: center; gap: 14px; margin-left: auto; flex-shrink: 0; }
.topbar-user { font-size: 12px; color: rgba(255,255,255,0.8); text-align: right; line-height: 1.3; }
.topbar-user strong { display: block; color: var(--white); font-size: 13px; }

/* ── SIDEBAR (contextual: the active area's pages) ─────────── */
.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  background: var(--navy); color: var(--white);
  display: flex; flex-direction: column; overflow-y: auto;
}
/* Single-page areas (Dashboard, Students, …) drop the sidebar entirely. */
.app-shell.no-sidebar .sidebar { display: none; }
/* …and so must the phone hamburger that opens it. Without this the button is
   still drawn on a no-sidebar screen and taps to nothing, because the drawer it
   toggles is display:none. Most visible on the roles that have NO nav at all
   (pending, noAccount): the one control on screen does nothing. */
.app-shell.no-sidebar .sidebar-toggle { display: none; }
.sidebar-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 20px 16px; border-bottom: 1px solid rgba(255,255,255,0.1);
  font-weight: 700; font-size: 15px;
}
.sidebar-logo {
  width: 40px; height: 40px; border-radius: 8px;
  background: var(--white); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; padding: 4px;
}
.sidebar-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.sidebar-nav { flex: 1; padding: 12px 0; }
.sidebar-nav li a {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; color: rgba(255,255,255,0.75);
  border-left: 3px solid transparent; transition: all 0.15s;
  font-size: 13.5px;
}
.sidebar-nav li a:hover { background: rgba(255,255,255,0.08); color: var(--white); text-decoration: none; }
.sidebar-nav li a.active { background: rgba(255,255,255,0.12); color: var(--white); border-left-color: var(--gold); }
.sidebar-nav li a .nav-icon { width: 18px; height: 18px; opacity: 0.8; flex-shrink: 0; }
.nav-section-label {
  padding: 16px 16px 6px; color: rgba(255,255,255,0.4);
  font-size: 10px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
}
.sidebar-footer { padding: 16px; border-top: 1px solid rgba(255,255,255,0.1); }
.sidebar-user { font-size: 13px; color: rgba(255,255,255,0.8); margin-bottom: 8px; }
.sidebar-user strong { display: block; color: var(--white); }
.btn-link { background: none; border: none; color: rgba(255,255,255,0.5); font-size: 13px; padding: 0; }
.btn-link:hover { color: var(--white); text-decoration: underline; }

/* ── MAIN CONTENT ──────────────────────────────────────────── */
.main-content { flex: 1; overflow-y: auto; display: flex; flex-direction: column; }

/* One of these per navigation, so a page that is still finishing an async
   render keeps its own detached subtree instead of querying a container that
   has been emptied underneath it (see navToken in app.js). `display: contents`
   makes the wrapper invisible to layout, so .page-header / .page-body remain
   flex children of .main-content exactly as before. */
.page-view { display: contents; }

/* ── PAGE HEADER ───────────────────────────────────────────── */
.page-header {
  background: var(--white); border-bottom: 1px solid var(--gray-200);
  padding: 20px 32px; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-shrink: 0;
}
.page-header h1 { font-size: 20px; font-weight: 700; color: var(--navy); }
.page-header .header-actions { display: flex; gap: 8px; align-items: center; }

/* ── PAGE BODY ─────────────────────────────────────────────── */
.page-body { padding: 24px 32px; flex: 1; }

/* ── CARDS ─────────────────────────────────────────────────── */
.card {
  background: var(--white); border: 1px solid var(--gray-200);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.card-header {
  padding: 16px 20px; border-bottom: 1px solid var(--gray-200);
  font-weight: 600; font-size: 14px; color: var(--navy);
  display: flex; align-items: center; justify-content: space-between;
}
.card-body { padding: 20px; }

/* ── STAT CARDS ────────────────────────────────────────────── */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin-bottom: 24px; }
.stat-card {
  background: var(--white); border: 1px solid var(--gray-200);
  border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow);
}
.stat-card .stat-label { color: var(--gray-600); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .stat-value { font-size: 32px; font-weight: 700; color: var(--navy); line-height: 1.2; margin: 4px 0; }
.stat-card .stat-sub   { color: var(--gray-500); font-size: 12px; }
.stat-card.danger .stat-value  { color: var(--red); }
.stat-card.warning .stat-value { color: var(--yellow); }
.stat-card.success .stat-value { color: var(--green); }

/* ── FILTER BAR ────────────────────────────────────────────── */
.filter-bar {
  background: var(--white); border: 1px solid var(--gray-200);
  border-radius: var(--radius); padding: 16px 20px;
  display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end;
  margin-bottom: 20px;
}
.filter-group { display: flex; flex-direction: column; gap: 4px; }
.filter-group label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-600); }
.filter-group select, .filter-group input {
  padding: 7px 10px; border: 1px solid var(--gray-300);
  border-radius: var(--radius); min-width: 140px;
  background: var(--white);
}
.filter-group select:focus, .filter-group input:focus {
  outline: none; border-color: var(--navy); box-shadow: 0 0 0 2px rgba(0,40,85,0.12);
}

/* ── BUTTONS ───────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: var(--radius); font-weight: 500;
  border: 1px solid transparent; transition: all 0.15s; white-space: nowrap;
}
.btn-primary   { background: var(--navy); color: var(--white); border-color: var(--navy); }
.btn-primary:hover { background: #003370; }
.btn-secondary { background: var(--white); color: var(--gray-700); border-color: var(--gray-300); }
.btn-secondary:hover { background: var(--gray-50); }
.btn-gold      { background: var(--gold); color: var(--white); border-color: var(--gold); }
.btn-gold:hover { background: var(--gold-lt); }
.btn-danger    { background: var(--red); color: var(--white); }
.btn-danger:hover { background: #c92a2a; }
.btn-sm { padding: 5px 10px; font-size: 12px; }
.btn-icon { padding: 6px; }

/* ── TABLES ────────────────────────────────────────────────── */
.table-wrapper { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead tr { background: var(--gray-50); border-bottom: 2px solid var(--gray-200); }
th { padding: 10px 12px; text-align: left; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-600); white-space: nowrap; }
td { padding: 10px 12px; border-bottom: 1px solid var(--gray-200); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--gray-50); }

/* ── FREE TEXT A PARENT WROTE ──────────────────────────────────
   A reason, or a reviewer's note. The server allows 1000 characters and a
   parent writing several sentences is entirely normal, but every screen that
   showed one had clipped it: Checkpoint Notes ellipsised at 200px with no
   `title`, and on the Approved/Rejected/Voided tabs there is no Details button
   either, so the rest of the sentence was unreachable anywhere in the app.

   Wrapping, not truncating, is the right default here. This is the text a
   decision is made ON — whether an absence is excused — so it must be readable
   without hovering, clicking through, or knowing a modal exists.

   `pre-wrap` keeps the line breaks the parent actually typed; the previous
   plain <div> collapsed a list of dates into one paragraph.
   `overflow-wrap: anywhere` stops one long pasted string widening the table.
   `vertical-align: top` keeps a multi-line cell aligned with its neighbours. */
td.reason-cell {
  max-width: 340px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  vertical-align: top;
}

/* ── HOVER STATES ──────────────────────────────────────────────
   These were written as inline onmouseover/onmouseout and never ran once: the
   Content Security Policy has no 'unsafe-inline' in script-src, so the browser
   refuses inline handlers. Same effects, expressed where they belong — CSS
   cannot be blocked by a script policy, and hover has no business in JS.

   The base border/background/colour for these three moved OUT of their inline
   style attributes and into the rules below. It had to: an inline style beats a
   stylesheet rule, so `:hover` could set the border all it liked and the inline
   grey would win. Verified by hovering one for real and watching the shadow
   change while the border did not. */
.viewas-role-btn       { border: 1px solid var(--gray-200); background: var(--white); }
.viewas-role-btn:hover { border-color: var(--navy); background: var(--gray-50); }
.add-dept-btn          { border: 1px solid var(--gray-300); background: var(--white); color: var(--gray-600); }
.add-dept-btn:hover    { border-color: var(--navy); color: var(--navy); }
.student-card          { border: 1px solid var(--gray-200); }
.student-card:hover    { box-shadow: 0 2px 12px rgba(0,0,0,0.1); border-color: var(--navy); }
.sh-result-item:hover,
.student-result-item:hover { background: var(--gray-50); }
.hover-lift:hover  { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
.hover-raise:hover { transform: translateY(-2px); }

/* ── TABLE TOOLS (sort + search) ───────────────────────────────
   Added by js/table-tools.js to every table in the app from one hook in the
   router. Nothing here is applied by the page modules themselves. */
.tt-bar {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px;
  padding: 0 0 10px;
}
.tt-search { max-width: 280px; }
.tt-count { font-size: 12px; color: var(--gray-500); white-space: nowrap; }
.tt-count-empty { color: var(--red); font-weight: 600; }

th.tt-sortable {
  cursor: pointer; user-select: none; position: relative;
  padding-right: 22px;
}
th.tt-sortable:hover, th.tt-sortable:focus-visible { color: var(--gray-800); background: var(--gray-100); }

/* A faint chevron on every sortable header, so the affordance is visible
   before anyone hovers — otherwise nobody discovers that columns sort at all. */
th.tt-sortable::after {
  content: "↕";
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-size: 10px; opacity: 0.35; font-weight: 400;
}
th.tt-asc::after  { content: "▲"; opacity: 1; }
th.tt-desc::after { content: "▼"; opacity: 1; }

/* ── BADGES ────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 600;
}
.badge-excellent { background: #d3f9d8; color: #2b8a3e; }
.badge-good      { background: #d0ebff; color: #1971c2; }
.badge-atRisk    { background: #fff3bf; color: #e67700; }
.badge-underperforming { background: #ffe8cc; color: #d9480f; }
.badge-failing   { background: #ffe3e3; color: #c92a2a; }
.badge-incomplete{ background: var(--gray-200); color: var(--gray-700); }
.badge-high   { background: #ffe3e3; color: #c92a2a; }
.badge-medium { background: #fff3bf; color: #e67700; }
.badge-low    { background: #d3f9d8; color: #2b8a3e; }

/* ── SEARCH INPUT ──────────────────────────────────────────── */
.search-input {
  position: relative; display: flex; align-items: center;
}
.search-input input {
  padding: 8px 12px 8px 36px; border: 1px solid var(--gray-300);
  border-radius: var(--radius); width: 260px;
}
.search-input::before {
  content: '🔍'; position: absolute; left: 10px; font-size: 14px;
  pointer-events: none;
}

/* ── MODAL ─────────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.45);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 20px;
}
.modal {
  background: var(--white); border-radius: 10px;
  box-shadow: var(--shadow-md); width: 100%; max-width: 720px;
  max-height: 90vh; display: flex; flex-direction: column;
}
.modal-header {
  padding: 20px 24px 16px; border-bottom: 1px solid var(--gray-200);
  display: flex; align-items: center; justify-content: space-between;
  flex-shrink: 0;
}
.modal-header h2 { font-size: 17px; font-weight: 700; color: var(--navy); }
.modal-close { background: none; border: none; font-size: 20px; color: var(--gray-500); }
.modal-close:hover { color: var(--gray-800); }
.modal-body { padding: 24px; overflow-y: auto; flex: 1; }
.modal-footer {
  padding: 16px 24px; border-top: 1px solid var(--gray-200);
  display: flex; justify-content: flex-end; gap: 8px; flex-shrink: 0;
}

/* ── MEETING MODE ──────────────────────────────────────────── */
.meeting-mode {
  position: fixed; inset: 0; z-index: 2000;
  background: var(--navy); color: var(--white);
  display: flex; flex-direction: column;
}
.meeting-mode-header {
  padding: 20px 40px; border-bottom: 1px solid rgba(255,255,255,0.1);
  display: flex; align-items: center; justify-content: space-between;
}
.meeting-mode-body { flex: 1; display: flex; align-items: center; padding: 40px; overflow-y: auto; }
.meeting-mode-nav {
  padding: 20px 40px; border-top: 1px solid rgba(255,255,255,0.1);
  display: flex; align-items: center; justify-content: center; gap: 20px;
}

/* ── TABS ──────────────────────────────────────────────────── */
.tabs { display: flex; border-bottom: 2px solid var(--gray-200); margin-bottom: 20px; gap: 0; }
.tab-btn {
  background: none; border: none; padding: 10px 18px;
  color: var(--gray-600); font-weight: 500; border-bottom: 2px solid transparent;
  margin-bottom: -2px; transition: all 0.15s;
}
.tab-btn:hover { color: var(--navy); }
.tab-btn.active { color: var(--navy); border-bottom-color: var(--navy); font-weight: 600; }
.tab-pane { display: none; }
.tab-pane.active { display: block; }

/* ── CHART CONTAINERS ──────────────────────────────────────── */
.chart-container { position: relative; }
.chart-md { height: 280px; }
.chart-sm { height: 200px; }

/* ── FORM ELEMENTS ─────────────────────────────────────────── */
.form-group { margin-bottom: 16px; }
.form-label { display: block; margin-bottom: 6px; font-weight: 500; }
.form-control {
  display: block; width: 100%; padding: 8px 12px;
  border: 1px solid var(--gray-300); border-radius: var(--radius);
}
.form-control:focus { outline: none; border-color: var(--navy); box-shadow: 0 0 0 2px rgba(0,40,85,0.12); }
textarea.form-control { min-height: 100px; resize: vertical; }

/* ── TOASTS ────────────────────────────────────────────────── */
.toast-container { position: fixed; bottom: 24px; right: 24px; z-index: 3000; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: var(--gray-900); color: var(--white);
  padding: 12px 18px; border-radius: var(--radius);
  box-shadow: var(--shadow-md); font-size: 13px; max-width: 320px;
  animation: slideIn 0.2s ease;
}
.toast.success { background: var(--green); }
.toast.error   { background: var(--red); }
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }

/* ── ACTION ITEMS PANEL ────────────────────────────────────── */
.action-items-panel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 360px;
  background: var(--white); border-left: 1px solid var(--gray-200);
  box-shadow: -4px 0 16px rgba(0,0,0,0.12); z-index: 500;
  display: flex; flex-direction: column;
}

/* ── EMPTY STATE ───────────────────────────────────────────── */
.empty-state { text-align: center; padding: 60px 20px; color: var(--gray-500); }
.empty-state .empty-icon { font-size: 48px; margin-bottom: 12px; }
.empty-state h3 { color: var(--gray-700); margin-bottom: 8px; }

/* ── LOADING ───────────────────────────────────────────────── */
.loading { display: flex; align-items: center; justify-content: center; padding: 60px; }
.spinner {
  width: 36px; height: 36px; border: 3px solid var(--gray-200);
  border-top-color: var(--navy); border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── REPORTS HUB ───────────────────────────────────────────── */
.reports-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.report-card {
  background: var(--white); border: 1px solid var(--gray-200);
  border-radius: var(--radius); padding: 20px;
  display: flex; flex-direction: column; gap: 8px;
  cursor: pointer; transition: all 0.15s;
}
.report-card:hover { border-color: var(--navy); box-shadow: var(--shadow); }
.report-card .report-icon { font-size: 28px; }
.report-card h3 { font-size: 14px; font-weight: 600; color: var(--navy); }
.report-card p  { font-size: 12px; color: var(--gray-600); }

/* ── ADMIN PANEL ───────────────────────────────────────────── */
.admin-tabs { display: flex; flex-direction: column; }
.role-badge {
  display: inline-block; padding: 2px 8px; border-radius: 12px;
  font-size: 11px; font-weight: 600; background: var(--gray-200); color: var(--gray-700);
}
.role-badge.schoolAdmin { background: #e7f5ff; color: #1971c2; }
.role-badge.tidalAdmin  { background: #ffe8cc; color: #d9480f; }
.role-badge.counselor   { background: #f3d9fa; color: #862e9c; }
.role-badge.teacher     { background: #d3f9d8; color: #2b8a3e; }
.role-badge.learningSpecialist { background: #fff3bf; color: #e67700; }

/* ── PERFORMANCE CATEGORY COLORS ─────────────────────────────  */
.perf-bar {
  height: 8px; border-radius: 4px; background: var(--gray-200); overflow: hidden;
}
.perf-bar-fill { height: 100%; border-radius: 4px; }
.perf-excellent { background: #2f9e44; }
.perf-good      { background: #1971c2; }
.perf-atRisk    { background: #f59f00; }
.perf-failing   { background: #e03131; }

/* ── LIVE BADGE ────────────────────────────────────────────── */
.live-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; color: var(--green);
  background: #d3f9d8; padding: 3px 8px; border-radius: 12px;
}

/* ── STATUS DOTS ───────────────────────────────────────────── */
.status-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.dot-green { background: var(--green); }
.dot-yellow { background: var(--yellow); }
.dot-red   { background: var(--red); }
.dot-gray  { background: var(--gray-400); }

/* ── DURATION PILLS ────────────────────────────────────────── */
.dur-pill {
  display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 600;
}
.dur-green  { background: #d3f9d8; color: #2b8a3e; }
.dur-yellow { background: #fff3bf; color: #e67700; }
.dur-red    { background: #ffe3e3; color: #c92a2a; }

/* ── PASS TYPE CHIPS ───────────────────────────────────────── */
.pass-type-chip {
  display: inline-block; padding: 2px 10px; border-radius: 10px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px;
  background: var(--gray-200); color: var(--gray-700);
}
.pass-nurse     { background: #e7f5ff; color: #1864ab; }
.pass-bathroom  { background: #d3f9d8; color: #2b8a3e; }
.pass-office    { background: #fff3bf; color: #e67700; }
.pass-library   { background: #f3d9fa; color: #862e9c; }
.pass-counselor { background: #ffe8cc; color: #d9480f; }
.pass-other     { background: var(--gray-200); color: var(--gray-700); }

/* ── STATS BAR (Today at a glance — AW port) ───────────────── */
.stats-bar {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch; margin-bottom: 16px;
}
.stats-bar-item {
  display: flex; align-items: center; gap: 8px;
  background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius);
  padding: 8px 14px; box-shadow: var(--shadow);
}
.stats-bar-icon  { font-size: 18px; line-height: 1; }
.stats-bar-count { font-size: 20px; font-weight: 700; color: var(--navy); }
.stats-bar-label { font-size: 12px; font-weight: 600; color: var(--gray-600); text-transform: uppercase; letter-spacing: 0.3px; }
.stats-bar-total { margin-left: auto; background: var(--navy); border-color: var(--navy); }
.stats-bar-total .stats-bar-count { color: var(--white); }
.stats-bar-total .stats-bar-label { color: var(--gold-lt); }

/* ── COMMAND CENTER GRID (AW StaffDashboard port) ──────────── */
.cc-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px; margin-bottom: 24px;
}
.cc-card {
  background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius);
  box-shadow: var(--shadow); display: flex; flex-direction: column; overflow: hidden;
  border-top: 3px solid var(--gray-300);
}
.cc-card.cc-accent-navy   { border-top-color: var(--navy); }
.cc-card.cc-accent-gold   { border-top-color: var(--gold); }
.cc-card.cc-accent-green  { border-top-color: var(--green); }
.cc-card.cc-accent-yellow { border-top-color: var(--yellow); }
.cc-card.cc-accent-red    { border-top-color: var(--red); }
.cc-card.cc-accent-blue   { border-top-color: var(--blue); }
.cc-card-head {
  display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border-bottom: 1px solid var(--gray-100);
}
.cc-card-icon  { font-size: 18px; line-height: 1; }
.cc-card-title { font-size: 13px; font-weight: 700; color: var(--gray-800); flex: 1; }
.cc-card-count {
  font-size: 15px; font-weight: 700; color: var(--white); background: var(--gray-500);
  min-width: 24px; text-align: center; padding: 1px 8px; border-radius: 10px;
}
.cc-card.cc-accent-navy   .cc-card-count { background: var(--navy); }
.cc-card.cc-accent-red    .cc-card-count { background: var(--red); }
.cc-card.cc-accent-yellow .cc-card-count { background: var(--yellow); }
.cc-card.cc-accent-green  .cc-card-count { background: var(--green); }
.cc-card.cc-accent-blue   .cc-card-count { background: var(--blue); }
.cc-card.cc-accent-gold   .cc-card-count { background: var(--gold); }
.cc-list { list-style: none; margin: 0; padding: 0; max-height: 280px; overflow-y: auto; }
.cc-row {
  display: flex; align-items: center; gap: 8px; padding: 8px 14px;
  border-bottom: 1px solid var(--gray-100); font-size: 13px;
}
.cc-row:last-child { border-bottom: none; }
.cc-row-clickable { cursor: pointer; }
.cc-row-clickable:hover { background: var(--gray-50); }
.cc-row-name { font-weight: 600; color: var(--gray-800); }
.cc-row-meta { color: var(--gray-500); font-size: 11px; }
.cc-row-actions { margin-left: auto; display: flex; gap: 4px; white-space: nowrap; }
.cc-empty { padding: 18px 14px; text-align: center; color: var(--gray-500); font-size: 12px; }

/* ── ATTENDANCE DRILL-DOWN SEGMENTED TABS ──────────────────── */
.att-segs { display: flex; gap: 8px; padding: 12px 16px; flex-wrap: wrap; }
.att-seg {
  border: 1px solid var(--gray-300); background: var(--white); border-radius: var(--radius);
  padding: 6px 12px; font-size: 13px; font-weight: 600; color: var(--gray-700); cursor: pointer;
}
.att-seg:hover { background: var(--gray-50); }
.att-seg-active { background: var(--navy); border-color: var(--navy); color: var(--white); }
.att-seg-count { font-weight: 700; margin-left: 4px; opacity: 0.85; }
.att-seg:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }

/* ── STUDENT PROFILE SECTION CARDS + LARGE MODAL ───────────── */
.sp-section-card { cursor: pointer; transition: box-shadow 0.15s ease, transform 0.05s ease; }
.sp-section-card:hover { box-shadow: var(--shadow-md); }
.sp-section-card:active { transform: translateY(1px); }
.sp-section-card:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.modal.sp-modal-lg { max-width: 940px; }

/* ── STUDENT PORTAL TOP ROW ─────────────────────────────────
   Current-pass + request-a-pass side by side on a laptop, stacked on a phone.
   Was a hard `1fr 1fr`, which clipped the request tiles off-screen on mobile —
   the surface most students actually use. */
.sp-top-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px; margin-bottom: 22px;
}

/* ── PASS-TYPE TILE PICKER (AW-Passes student request) ─────── */
.pass-tile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 12px; }
.pass-tile {
  background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius);
  padding: 14px; text-align: left; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s;
}
.pass-tile:hover { border-color: var(--gold); box-shadow: var(--shadow); }
.pass-tile.selected { border-color: var(--navy); background: rgba(0,40,85,0.04); box-shadow: inset 0 0 0 1px var(--navy); }
.pass-tile:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.pass-tile-icon  { font-size: 26px; display: block; margin-bottom: 6px; line-height: 1; }
.pass-tile-label { font-weight: 700; color: var(--gray-800); font-size: 14px; display: block; }
.pass-tile-limit { font-size: 12px; color: var(--gray-500); margin-top: 2px; }

/* ── GRADE HISTORY GRID (student profile) ──────────────────── */
.grade-grid { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13px; }
.grade-grid th, .grade-grid td {
  border-right: 1px solid var(--gray-200); border-bottom: 1px solid var(--gray-200);
  padding: 9px 12px; white-space: nowrap;
}
.grade-grid th:first-child, .grade-grid td:first-child { border-left: 1px solid var(--gray-200); }
.grade-grid thead th { border-top: 1px solid var(--gray-200); }
.grade-grid thead th {
  background: var(--gray-50); font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--gray-600); font-weight: 700; position: sticky; top: 0; z-index: 1;
}
/* Freeze the Course column while scanning snapshots horizontally. */
.grade-grid th:first-child, .grade-grid td:first-child {
  position: sticky; left: 0; background: var(--white); z-index: 2;
}
.grade-grid thead th:first-child { background: var(--gray-50); z-index: 3; }
.grade-grid tbody tr:nth-child(even) td { background: var(--gray-50); }
.grade-grid tbody tr:nth-child(even) td:first-child { background: #f4f6f8; }
.grade-grid tbody tr:hover td { background: #eef2f7; }
.grade-grid tbody tr:hover td:first-child { background: #e7edf4; }
.grade-grid .gg-snap { text-align: center; }
.grade-cols-bar { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--gray-500); font-weight: 400; }
.grade-cols-bar select { padding: 4px 8px; border: 1px solid var(--gray-300); border-radius: var(--radius); font-size: 12px; }

/* ── FREQUENT FLYERS ALERT (AW port) ───────────────────────── */
.ff-alert {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: #fff5f5; border: 1px solid #ffc9c9; border-left: 4px solid var(--red);
  border-radius: var(--radius); padding: 10px 14px; margin-bottom: 16px;
}
.ff-alert-icon  { font-size: 18px; }
.ff-alert-text  { font-size: 13px; font-weight: 600; color: #c92a2a; }
.ff-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--white); border: 1px solid #ffc9c9; border-radius: 12px;
  padding: 2px 10px; font-size: 12px; font-weight: 600; color: var(--gray-800);
}
.ff-chip-count { color: var(--red); font-weight: 700; }
.ff-alert-btn { margin-left: auto; }

/* ── KIOSK SCREEN UTILITY ──────────────────────────────────── */
.kiosk-screen { position: fixed; inset: 0; }

/* ── LOGIN DIVIDER ─────────────────────────────────────────── */
.login-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 16px 0; color: var(--gray-400); font-size: 12px;
}
.login-divider::before, .login-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--gray-200);
}

/* ── PRINT ─────────────────────────────────────────────────── */
@media print {
  .sidebar, .filter-bar, .btn, nav { display: none !important; }
  .main-content { overflow: visible; }
  .card { box-shadow: none; border: 1px solid #ddd; }
}

/* Student Support → Export: while a record prints, it is the ONLY thing on the
   page (support.js printRecord). Hidden on screen; the modal shows the preview. */
#record-print { display: none; }
@media print {
  body.printing-record > *:not(#record-print) { display: none !important; }
  body.printing-record #record-print { display: block !important; padding: 0 12px; }
}

/* ── SUB-NAV ITEMS ─────────────────────────────────────────── */
.sidebar-nav li a.nav-sub {
  padding-left: 36px;
  font-size: 13px;
  color: rgba(255,255,255,0.6);
}
.sidebar-nav li a.nav-sub:hover { color: var(--white); }
.sidebar-nav li a.nav-sub.active {
  color: var(--white);
  border-left-color: var(--gold);
  background: rgba(255,255,255,0.08);
}

/* ── VIEW AS BANNER ────────────────────────────────────────── */
.viewas-banner {
  background: #fff3bf;
  border-bottom: 2px solid #f59f00;
  padding: 10px 32px;
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; font-weight: 500; color: #7d4e00;
  flex-shrink: 0;
}
.viewas-banner strong { color: #5c3700; }
.viewas-banner .btn-exit-viewas {
  background: #f59f00; color: #fff; border: none;
  padding: 5px 14px; border-radius: var(--radius);
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.viewas-banner .btn-exit-viewas:hover { background: #e67700; }

/* ── VIEW AS FOOTER BUTTON ─────────────────────────────────── */
.btn-viewas {
  display: block; width: 100%;
  background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2);
  color: rgba(255,255,255,0.8); border-radius: var(--radius);
  padding: 7px 12px; font-size: 12px; font-weight: 500;
  cursor: pointer; text-align: center; margin-bottom: 8px;
  transition: background 0.15s;
}
.btn-viewas:hover { background: rgba(255,255,255,0.18); color: var(--white); }

/* ── DASHBOARD NOTE STAT CARDS (CLICKABLE) ─────────────────── */
.stat-card.clickable {
  cursor: pointer; transition: transform 0.1s, box-shadow 0.1s;
}
.stat-card.clickable:hover {
  transform: translateY(-2px); box-shadow: var(--shadow-md);
  border-color: var(--navy);
}
.stat-card.absent .stat-value  { color: var(--red); }
.stat-card.tardy .stat-value   { color: var(--yellow); }
.stat-card.dismissal .stat-value { color: var(--blue); }

/* ── PASS DURATION LIVE PILL ───────────────────────────────── */
.dur-live { background: #d3f9d8; color: #2b8a3e; }

/* ── ATTENDANCE IMPACT CORRELATION ────────────────────────── */
.impact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px; margin-bottom: 24px;
}
.impact-card {
  background: var(--white); border: 1px solid var(--gray-200);
  border-radius: var(--radius); padding: 16px 20px;
  border-left: 4px solid var(--gray-300);
}
.impact-card.absent-card  { border-left-color: var(--red); }
.impact-card.tardy-card   { border-left-color: var(--yellow); }
.impact-card.dismissal-card { border-left-color: var(--blue); }
.impact-card .impact-name  { font-weight: 600; color: var(--navy); margin-bottom: 4px; }
.impact-card .impact-count { font-size: 12px; color: var(--gray-600); margin-bottom: 8px; }
.impact-card .impact-grades { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── INSIGHTS SUB-PAGES ────────────────────────────────────── */
.page-tabs {
  display: flex; gap: 0;
  border-bottom: 2px solid var(--gray-200);
  margin-bottom: 24px; flex-wrap: wrap;
}
.page-tab-btn {
  background: none; border: none;
  padding: 10px 20px; font-size: 13.5px; font-weight: 500;
  color: var(--gray-600); border-bottom: 2px solid transparent;
  margin-bottom: -2px; cursor: pointer; transition: all 0.15s;
}
.page-tab-btn:hover { color: var(--navy); }
.page-tab-btn.active { color: var(--navy); border-bottom-color: var(--navy); font-weight: 600; }

/* ── ROAM HISTORY TABLE ────────────────────────────────────── */
.pass-status-active  { color: var(--green); font-weight: 600; }
.pass-status-closed  { color: var(--gray-500); }
.pass-status-overdue { color: var(--red); font-weight: 600; }

/* Accessibility (WCAG 2.4.7): visible keyboard-focus ring for interactive
   controls that lack one. :focus-visible shows it for keyboard users only,
   not on mouse click. Form controls already have their own :focus ring above. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
.tab-btn:focus-visible,
.page-tab-btn:focus-visible,
.numpad-btn:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--navy, #002855);
  outline-offset: 2px;
}

/* Accessibility (WCAG 2.4.1 Bypass Blocks): skip-to-content link, hidden
   until it receives keyboard focus. */
.skip-link {
  position: absolute;
  left: 8px;
  top: -48px;
  z-index: 1000;
  background: var(--navy, #002855);
  color: #fff;
  padding: 10px 16px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 8px; outline: 2px solid #fff; outline-offset: 2px; }

/* ── MOBILE / RESPONSIVE (≤ 768px) ─────────────────────────────
   The staff app + student portal shell is desktop-first (fixed 220px sidebar).
   Below 768px the hamburger + backdrop (in index.html) turn the rail into a
   slide-in drawer and the main content spans the full width. Layout only — no
   change to which nav items or data a role can see. Parent portal & kiosks have
   their own layouts and are unaffected. */
.sidebar-toggle { display: none; }
.sidebar-backdrop { display: none; }

@media (max-width: 768px) {
  /* Hamburger: fixed top-left, above the drawer so it can also close it. */
  .sidebar-toggle {
    display: flex; align-items: center; justify-content: center;
    position: fixed; top: 8px; left: 8px; z-index: 700;
    width: 40px; height: 40px; border-radius: 8px;
    background: var(--navy); color: var(--white);
    border: none; font-size: 20px; line-height: 1; box-shadow: var(--shadow);
  }

  /* Sidebar slides in from the left instead of holding a fixed column. */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 650;
    width: 260px; max-width: 84vw;
    transform: translateX(-100%); transition: transform 0.2s ease;
    box-shadow: 2px 0 16px rgba(0,0,0,0.25);
  }
  .sidebar.open { transform: translateX(0); }

  /* Dimmed backdrop while the drawer is open (the global .hidden !important
     keeps it invisible until JS removes that class). */
  .sidebar-backdrop { display: block; position: fixed; inset: 0; z-index: 640; background: rgba(0,0,0,0.45); }

  /* Content spans full width; clear the hamburger and tighten desktop padding. */
  .main-content { width: 100%; }
  .page-header { padding: 16px 16px 16px 56px; }
  .page-body { padding: 16px; }

  /* Wide fixed elements → fluid so nothing overflows a ~375px phone screen. */
  .search-input input { width: 100%; }
  .action-items-panel { width: 92vw; max-width: 360px; }
  .login-card { width: 100%; max-width: 360px; }
  .login-screen { padding: 20px; }

  /* Tab strips run off the side rather than wrapping into a stack that pushes
     the content down — several pages carry six or more tabs. */
  .tabs { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tab-btn { white-space: nowrap; flex: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   PHONE  (≤560px)
   ═══════════════════════════════════════════════════════════════════════
   The 768px block above handles the shell — drawer nav, full-width content.
   Everything below is about what happens INSIDE a page on a ~375px screen,
   which nothing previously accounted for: one media query covered all 36
   pages, and it stopped at the sidebar.

   Deliberately CSS-only. The alternative was editing three dozen page files
   that build their layouts with inline styles, which is more code, more
   risk, and leaves the next page someone writes with the same problems.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 560px) {

  /* ── Form fields ──────────────────────────────────────────────────────
     iOS Safari ZOOMS THE PAGE whenever a focused field is under 16px, and
     the base size here is 14px. Every text field on the site did it —
     including the one a parent types their email into to get a login code,
     which is the first thing any parent ever touches. The zoom does not
     undo itself, so they land on the code screen scrolled sideways. */
  .form-control,
  input[type="text"], input[type="email"], input[type="tel"],
  input[type="number"], input[type="search"], input[type="date"],
  select, textarea {
    font-size: 16px;
  }

  /* ── Tables ───────────────────────────────────────────────────────────
     84 tables across the pages; 12 of them are not inside a .table-wrapper
     (admin, caseloads, my-family, service-hours-settings, teacher-roster —
     my-family being the parent-facing one). Rather than chase the twelve and
     rely on everyone remembering the wrapper forever, every table scrolls
     itself on a phone. `width: max-content` keeps columns from crushing;
     `min-width: 100%` keeps a narrow table full-bleed instead of shrinking. */
  .page-body table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    width: max-content;
    min-width: 100%;
  }
  /* A scrolling table needs its cells to stop wrapping, or every column
     collapses to one word per line and the row becomes unreadable. */
  .page-body td { white-space: nowrap; }

  /* …except the one column that is a paragraph rather than a value. Left to
     the rule above, a parent's reason became a single nowrap line running off
     the side of a sideways-scrolling table — the worst of both. Needs
     `.page-body td` specificity to win here. */
  .page-body td.reason-cell { white-space: pre-wrap; max-width: 60vw; }

  /* ── Rigid grids ──────────────────────────────────────────────────────
     The pages set their columns inline — 15 use `1fr 1fr`, and there are
     `repeat(7,1fr)`, `repeat(6,1fr)`, `repeat(4,1fr)` and `repeat(3,1fr)`
     among them. A seven-column grid on a 375px screen gives 47px columns.
     Inline styles can only be beaten with !important, which is why it is
     here; grids already written as auto-fit/auto-fill collapse on their own
     and are excluded so their intended minimums still apply. */
  .page-body [style*="grid-template-columns"]:not([style*="auto-fit"]):not([style*="auto-fill"]) {
    grid-template-columns: 1fr !important;
  }

  /* ── Page header ──────────────────────────────────────────────────────
     h1 and the action buttons sit in one space-between row. With two or
     three buttons the title crushes to a couple of characters per line. */
  .page-header {
    flex-wrap: wrap;
    align-items: flex-start;
    padding: 14px 16px 14px 56px;
  }
  .page-header .header-actions { width: 100%; flex-wrap: wrap; }

  /* ── Touch targets ────────────────────────────────────────────────────
     .btn is ~34px tall and .btn-sm ~26px. Both are below the 44px that
     iOS and WCAG 2.5.5 ask for, and .btn-sm is what the row actions in
     every table use — the densest, most mis-tappable place on the site. */
  .btn { min-height: 44px; padding: 10px 16px; }
  .btn-sm { min-height: 38px; padding: 8px 12px; font-size: 13px; }
  .modal-close { min-width: 44px; min-height: 44px; }

  /* Buttons stacked in a table cell need room between them, or the gap
     between "Edit" and "Revoke" is smaller than a fingertip. */
  .page-body td .btn + .btn { margin-top: 6px; }

  /* ── Modals ───────────────────────────────────────────────────────────
     Already fluid, but the backdrop's 20px inset plus the header/body
     padding leaves little room on a narrow screen, and a tall modal needs
     to be scrollable rather than clipped. */
  .modal-backdrop { padding: 10px; align-items: flex-start; }
  .modal { max-height: calc(100vh - 20px); }
  .modal-header { padding: 16px 16px 12px; }
  .modal-body { padding: 16px; overflow-y: auto; }
  .modal-footer { padding: 12px 16px; flex-wrap: wrap; gap: 8px; }
  .modal-footer .btn { flex: 1 1 auto; justify-content: center; }

  /* ── Cards ────────────────────────────────────────────────────────────
     20px of padding on each side of a 375px screen is a tenth of the width. */
  .card-body { padding: 14px; }
  .page-body { padding: 14px; }
}

/* ── WHO DECIDES ATTENDANCE ─────────────────────────────────────
   Set on <body> by app.js (syncDecideClass) for anyone without the by-name
   "Approve and correct attendance" permission. The server refuses them anyway;
   this stops the buttons being offered. Every class here belongs to an
   attendance screen only (checkpoint-notes, attendance, awaitingCheckIns). */
.no-attendance-decide .approve-btn,
.no-attendance-decide .approve-note-btn,
.no-attendance-decide .reject-note-btn,
.no-attendance-decide .attach-btn,
.no-attendance-decide .reject-btn,
.no-attendance-decide #cn-bulk-bar,
.no-attendance-decide #cn-content input[type="checkbox"],
.no-attendance-decide .void-btn,
.no-attendance-decide .edit-note-btn,
.no-attendance-decide .edit-att-btn,
.no-attendance-decide .bb-match-btn,
.no-attendance-decide .void-att-btn,
.no-attendance-decide .void-checkin-btn,
.no-attendance-decide .assign-btn,
.no-attendance-decide .time-btn,
.no-attendance-decide .absent-btn,
.no-attendance-decide .void-this,
.no-attendance-decide .void-other,
.no-attendance-decide .send-anyway,
.no-attendance-decide .link-go { display: none !important; }
.decide-only-note { display: none; }
.no-attendance-decide .decide-only-note { display: block; }
