/* ==========================================================================
   ThePYQs.com design system
   ==========================================================================
   Restyled 2026-09-29 to the "EvalHub" teal palette (design-tokens pass,
   evalhub-theme branch) - visual tokens only, no markup/class/JS changes.
   Plain CSS on purpose - no build step, no Tailwind CDN - so the whole app
   stays "clone it and run it" simple. Organized in the order a page uses it:
   reset/base -> layout shell (nav, page header) -> primitives (card, btn,
   badge, table, form) -> feature-specific blocks (paper annotations, review
   workspace, skills graph, etc). */

/* ---- Reset & base ---- */
*, *::before, *::after { box-sizing: border-box; }

:root {
  /* ---- EvalHub design tokens (the one central place - Step 2) ---- */
  --primary: #1E3A8A;      /* buttons, links, titles, active nav, toggles - dark navy blue */
  --primary-50: #EFF6FF;   /* active sidebar bg, hover tint */
  --primary-200: #BFDBFE;  /* highlight borders, focus rings */
  --primary-400: #60A5FA;  /* gradients / soft accents (between primary and primary-200) */
  --primary-500: #3B82F6;  /* brighter mid accent - focus outlines */
  --primary-700: #172554;  /* hover / pressed */
  --accent: #F59E0B;       /* badges, notification dots */
  --success: #16A34A;      /* trends, sparklines, positive status */
  --text: #0F172A;         /* headings, big numbers */
  --body: #334155;         /* labels, body text */
  --muted: #64748B;        /* subtitles, timestamps */
  --bg: #F8FAFC;           /* page background */
  --surface: #FFFFFF;      /* cards, sidebar, header */
  --border: #E2E8F0;       /* borders, dividers */
  --radius-sm: 8px; --radius-md: 12px;
  --font: 'Inter', system-ui, sans-serif;

  --accent-violet: #7c3aed; --accent-violet-bg: #f3e8ff;
  --accent-blue: #2563eb; --accent-blue-bg: #dbeafe;
  --accent-amber: #d97706; --accent-amber-bg: #fef3c7;
  --accent-emerald: #059669; --accent-emerald-bg: #d1fae5;
  --accent-rose: #e11d48; --accent-rose-bg: #ffe4e6;
  --accent-cyan: #0891b2; --accent-cyan-bg: #cffafe;

  /* Per-institute brand color (app/routers/admin_settings.py's Branding
     card writes Institute.primary_color; app/templating.py's
     brand_css_vars() derives shades from that ONE hex the same way this
     block derives them from --primary below, and base.html injects the
     result as a <style> override in <head> - so any institute/reseller
     that already picked its own color is completely unaffected by this
     token change; only those still on the default inherit the new navy.
     The --brand-* names themselves are kept exactly as-is (every other
     CSS file in this project, and brand_css_vars()'s generated overrides,
     reference them by this name) - only their DEFAULT values change here. */
  --brand: var(--primary); --brand-dark: var(--primary-700); --brand-mid: var(--primary-500);
  --brand-soft: var(--primary-400); --brand-light: var(--primary-50);
  --brand-rgb: 30, 58, 138; --brand-mid-rgb: 59, 130, 246;
}

html { overflow-x: hidden; }
body {
  margin: 0;
  background: #ffffff;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  color: #0f172a;
  overflow-x: hidden;
  max-width: 100vw;
}

a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-dark); }

/* ---- App shell: left sidebar nav + top header ---- */
.app-shell { display: flex; min-height: 100vh; }
/* position: fixed (not sticky) is deliberate - a sticky sidebar's
   containing block is .app-shell, whose height grows with the page's
   tallest content; once a page (e.g. the long Settings form) is much
   taller than the viewport, a sticky sidebar runs out of that container
   near the bottom and detaches, scrolling away with the page instead of
   staying put. Fixed pins it to the actual viewport regardless of page
   length - .main-area's margin-left below reserves the space a normal
   in-flow sidebar would have taken. */
.sidebar {
  width: 232px; flex-shrink: 0;
  background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: fixed; top: 0; left: 0; bottom: 0; overflow-y: auto; z-index: 20;
}
.navbrand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; padding: 22px 20px 18px; }
.navlogo {
  width: 34px; height: 34px; border-radius: 9px;
  background: linear-gradient(135deg, var(--brand-soft), var(--brand));
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  overflow: hidden;
}
.navlogo-img { width: 100%; height: 100%; object-fit: cover; }
.navtitle { color: var(--text); font-weight: 700; font-size: 18px; letter-spacing: -0.01em; white-space: nowrap; }
.navbrand-text { display: flex; flex-direction: column; line-height: 1.3; }
.navsubtitle { color: var(--muted); font-size: 11px; font-weight: 500; white-space: nowrap; }
.sidenav { display: flex; flex-direction: column; gap: 3px; padding: 8px 12px; flex: 1; overflow-y: auto; }
.navlink, .nav-cat-btn {
  display: flex; align-items: flex-start; gap: 11px; color: var(--body); font-size: 13.5px; font-weight: 600;
  padding: 12px 16px; border-radius: var(--radius-sm); min-height: 40px;
  width: 100%; border: none; background: none; font-family: inherit; text-align: left;
}
.navlink, .nav-cat-btn { cursor: pointer; }
.navicon {
  width: 26px; height: 26px; flex-shrink: 0; border-radius: 8px; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  background: #f1f5f9; color: var(--muted);
}
/* Labels wrap rather than truncate - a long label like "Upload Answer
   Sheets" must stay fully readable at every sidebar/drawer width. */
.navlabel { overflow: visible; text-overflow: clip; white-space: normal; line-height: 1.3; padding-top: 2px; flex: 1; }
.navlink:hover, .nav-cat-btn:hover { color: var(--text); background: #f1f5f9; }
.navlink:hover .navicon, .nav-cat-btn:hover .navicon { color: var(--text); }
/* Active state is a light brand-tinted shade, not a solid block - just
   enough to mark the current page without the sidebar itself feeling
   like a colored surface. */
.navlink.active, .nav-cat-btn.active {
  color: var(--primary); font-weight: 600;
  background: var(--primary-50);
}
.navlink.active .navicon, .nav-cat-btn.active .navicon { background: var(--surface); color: var(--primary); }
.navlink:focus-visible, .nav-cat-btn:focus-visible, .nav-child-link:focus-visible {
  outline: 2px solid var(--brand-mid); outline-offset: 2px;
}

/* ---- Category dropdown (one open at a time) ---- */
.nav-category { display: flex; flex-direction: column; }
.nav-chevron { margin-left: auto; flex-shrink: 0; margin-top: 9px; color: #94a3b8; transition: transform 0.18s ease; }
.nav-cat-btn[aria-expanded="true"] .nav-chevron { transform: rotate(90deg); color: inherit; }
.nav-children {
  list-style: none; margin: 0; padding: 0 0 0 14px;
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.2s ease;
}
.nav-children.open { max-height: 320px; opacity: 1; }
.nav-child-link {
  display: flex; align-items: flex-start; gap: 9px; color: var(--body); font-size: 13px; font-weight: 600;
  padding: 9px 10px; border-radius: 9px; min-height: 38px;
  border-left: 2px solid var(--border); margin: 2px 0 2px 7px; padding-left: 11px;
}
.nav-child-link .navicon { width: 22px; height: 22px; background: transparent; }
.nav-child-link:hover { color: var(--text); background: #f1f5f9; }
.nav-child-link.active {
  color: var(--primary); font-weight: 600; background: var(--primary-50); border-left-color: var(--primary);
}
.sidefoot { padding: 16px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 12px; }
.sidefoot-user { display: flex; align-items: center; gap: 10px; }
.navuser { display: flex; flex-direction: column; line-height: 1.3; overflow: hidden; }
.navuser .name { color: var(--text); font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.navuser .role { color: var(--muted); font-size: 12px; text-transform: capitalize; }
.avatar {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13px; font-weight: 700; background: var(--brand-mid);
}
.avatar-sm { width: 30px; height: 30px; font-size: 11.5px; }
.cell-user { display: flex; align-items: center; gap: 10px; }
.cell-user .avatar-sm { font-weight: 700; }
.logout-btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; color: var(--body); background: #f1f5f9;
  border: 1px solid var(--border); border-radius: 7px; padding: 8px 14px; cursor: pointer;
}
.logout-btn:hover { background: #e2e8f0; color: var(--text); }
.logout-form { display: contents; }
button.logout-btn { font-family: inherit; }

/* margin-left reserves the space the now position:fixed .sidebar would
   have taken up in normal flow - must stay in sync with .sidebar's width
   at every breakpoint below (232px desktop, 208px tablet/laptop, 0 once
   the sidebar becomes an off-canvas drawer under 768px). */
.main-area { flex: 1; min-width: 0; display: flex; flex-direction: column; margin-left: 232px; }
.topbar {
  height: 64px; flex-shrink: 0; background: var(--surface); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: flex-end;
  padding: 0 32px; gap: 16px;
}
.topbar-greet { display: flex; align-items: baseline; gap: 6px; margin-right: auto; overflow: hidden; }
.topbar-hi { font-size: 14px; color: var(--muted); white-space: nowrap; }
.topbar-name { font-size: 15px; color: var(--text); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-right { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.menu-btn {
  display: none; background: none; border: none; padding: 6px; margin-right: 4px;
  cursor: pointer; border-radius: 6px;
}
.sidebar-backdrop { display: none; }

/* ---- Page shell ---- */
/* width: 100% + min-width: 0, rather than relying on flex cross-axis
   stretch alone, is deliberate - a flex item's default min-width is
   "auto" (its content's own intrinsic width, e.g. a row of stat cards
   that doesn't wrap), which can otherwise win over stretch and force
   this - and everything inside it - to render at its natural desktop
   width on a narrow/mobile viewport instead of reflowing to fit. */
.page { padding: 28px 40px 60px 40px; max-width: 1280px; margin: 0 auto; width: 100%; min-width: 0; box-sizing: border-box; }
.page.narrow { max-width: 820px; }
.crumb { font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.crumb b { color: var(--text); font-weight: 600; }
.pagehead { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; margin-bottom: 24px; flex-wrap: wrap; }
h1.title { font-size: 28px; font-weight: 700; margin: 0 0 6px 0; color: var(--text); letter-spacing: -0.01em; }
p.subtitle { font-size: 14px; color: var(--muted); margin: 0 0 20px 0; }

/* ---- Flash / alert banners ---- */
.flash, .banner {
  display: flex; align-items: center; gap: 10px;
  background: #fffbeb; border: 1px solid #fde68a; color: #92400e;
  font-size: 14px; padding: 14px 18px; border-radius: 10px; margin-bottom: 22px; line-height: 1.6;
}
.flash.error, .banner.error { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
.flash.success, .banner.success { background: #f0fdf4; border-color: #bbf7d0; color: #166534; }
.flash a, .banner a { color: inherit; font-weight: 600; text-decoration: underline; }

/* ---- Card ---- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  /* Near-flat elevation (a single hairline shadow, not a diffused drop
     shadow) - a deliberately quieter "modern SaaS" look, matched to the
     ExamLens design system this was benchmarked against. */
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.card + .card { margin-top: 20px; }
.cardpad { padding: 24px; }
.sectiontitle { font-size: 15px; font-weight: 700; margin: 0 0 14px 0; }

/* ---- Buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 14px; font-weight: 600; border-radius: var(--radius-sm); padding: 10px 18px;
  min-height: 44px;
  cursor: pointer; border: 1px solid transparent; white-space: nowrap;
  font-family: inherit; line-height: 1.2;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--primary-700); color: #fff; }
.btn-outline { background: var(--surface); color: var(--body); border-color: var(--border); }
.btn-outline:hover:not(:disabled) { background: var(--bg); color: var(--body); }
.btn-ghost { background: transparent; color: var(--muted); }
.btn-ghost:hover:not(:disabled) { color: var(--body); }
.btn-success { background: var(--success); color: #fff; }
.btn-success:hover:not(:disabled) { background: #15803d; color: #fff; }
.btn-danger { background: #dc2626; color: #fff; }
.btn-sm { padding: 7px 14px; font-size: 13px; min-height: 36px; }
.btn-link {
  background: none; border: none; padding: 0; font: inherit; font-weight: 600;
  color: var(--primary); cursor: pointer;
}

/* ---- Badges ---- */
.badge {
  display: inline-flex; align-items: center; padding: 3px 10px;
  border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.badge-green { background: #dcfce7; color: #166534; }
.badge-amber { background: #fef3c7; color: #92400e; }
.badge-red { background: #fee2e2; color: #991b1b; }
.badge-blue { background: #dbeafe; color: #1e40af; }
.badge-gray { background: #f1f5f9; color: #475569; }

/* ---- Stat cards ----
   Graphy-style KPI tiles: a colored rounded icon chip, a big number, and
   a label - each tile takes an accent color (violet/blue/amber/emerald/
   rose/cyan, defined once as CSS vars at :root) so a KPI row reads as a
   set of distinct signals instead of one flat color repeated. */
/* Grid, not flex - flex's equal-width distribution (flex: 1 1 0%) only
   holds until a sibling's content forces a larger minimum (a longer
   label like "Pending Review", a wider value like "3 (2 open)"), at
   which point that one card wins extra width at the others' expense and
   the row visibly stops looking even. Grid columns are all sized from
   the same track width by definition, so every card in a row is exactly
   as wide as its siblings regardless of what each one's content needs -
   auto-fit/minmax also collapses to fewer, still-equal columns instead
   of overflowing when the row is narrower than N * the minimum width. */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 16px; margin-bottom: 24px; }
.stat-card { min-width: 0; padding: 18px 22px; }
.stat-card.with-icon {
  min-width: 0; padding: 20px 22px;
  display: flex; align-items: flex-start; gap: 14px;
}
.stat-icon {
  width: 44px; height: 44px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.stat-card.violet .stat-icon { background: var(--accent-violet-bg); color: var(--accent-violet); }
.stat-card.blue .stat-icon { background: var(--accent-blue-bg); color: var(--accent-blue); }
.stat-card.amber .stat-icon { background: var(--accent-amber-bg); color: var(--accent-amber); }
.stat-card.emerald .stat-icon { background: var(--accent-emerald-bg); color: var(--accent-emerald); }
.stat-card.rose .stat-icon { background: var(--accent-rose-bg); color: var(--accent-rose); }
.stat-card.cyan .stat-icon { background: var(--accent-cyan-bg); color: var(--accent-cyan); }
.stat-body { min-width: 0; }
.stat-label {
  font-size: 11px; color: #94a3b8; margin-bottom: 5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.stat-value { font-size: 24px; font-weight: 800; color: #0f172a; letter-spacing: -0.01em; }
.stat-value .of { font-size: 14px; color: #94a3b8; font-weight: 500; }
.stat-sub { font-size: 12px; color: #94a3b8; margin-top: 3px; }

/* ---- Tables ---- */
/* overflow-x lets a wide table scroll inside its own card on a narrow
   screen instead of forcing the whole page to scroll sideways. */
.table-card { overflow-x: auto; overflow-y: hidden; }
table.evh { width: 100%; border-collapse: collapse; min-width: 480px; }
table.evh th {
  text-align: left; font-size: 12px; color: #64748b; font-weight: 600;
  padding: 12px 20px; background: #f8fafc; border-bottom: 1px solid #e2e8f0;
  white-space: nowrap;
}
table.evh td { font-size: 14px; color: #334155; padding: 13px 20px; border-bottom: 1px solid #f1f5f9; }
table.evh tbody tr:last-child td { border-bottom: none; }
table.evh .empty-row td { text-align: center; color: #94a3b8; padding: 32px 20px; }
/* An inline "Edit" toggle row hidden under a table row until clicked -
   shared by any editable list (rubric criteria, question bank, ...). */
.edit-row { display: none; }
.edit-row.open { display: table-row; }
.rankcell { font-weight: 700; }
.muted { color: #94a3b8; }

/* ---- Forms ---- */
.form-card { padding: 24px; max-width: 640px; }
.form-card.wide { max-width: 880px; }
.form-row { margin-bottom: 14px; }
.form-grid { display: grid; gap: 14px; }
.form-grid.cols-2 { grid-template-columns: 1fr 1fr; }
.form-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.form-grid.cols-4 { grid-template-columns: 1fr 1fr 1fr 1fr; }
.form-label { display: block; font-size: 13px; font-weight: 600; color: #475569; margin-bottom: 5px; }
.form-hint { font-size: 12px; color: #94a3b8; margin-top: 4px; }

input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="file"], input:not([type]), select, textarea {
  width: 100%;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 9px 12px;
  font-size: 14px;
  color: #0f172a;
  font-family: inherit;
  background: #fff;
}
textarea { resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand-mid); box-shadow: 0 0 0 3px rgba(var(--brand-mid-rgb), 0.15);
}
.select-inline {
  display: inline-flex; align-items: center; gap: 10px; border: 1px solid #e2e8f0;
  border-radius: 8px; padding: 9px 14px; font-size: 14px; color: #0f172a; background: #fff;
}
.select-inline select {
  border: none; padding: 0; font-size: 14px; color: #0f172a; background: transparent;
}
hr.divider { border: none; border-top: 1px solid #f1f5f9; margin: 18px 0; }

/* Grade-boundary / dynamic add-remove rows (release checklist) */
.boundrow { display: grid; grid-template-columns: 100px 1fr 32px; gap: 12px; align-items: center; margin-bottom: 10px; }
.addrow {
  display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600;
  color: var(--brand); margin-top: 4px; cursor: pointer; background: none; border: none; padding: 0; font-family: inherit;
}
.rm-row { color: #94a3b8; font-size: 16px; text-align: center; cursor: pointer; background: none; border: none; }
.rm-row:hover { color: #dc2626; }

/* Pre-release checklist */
.checkrow { display: flex; align-items: center; gap: 10px; font-size: 14px; color: #334155; padding: 8px 0; }
.checkicon {
  width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; flex-shrink: 0;
}
.checkicon.done { background: #dcfce7; }
.checkicon.pending { background: #fee2e2; }

/* ---- Login page ---- */
.login-wrap { max-width: 400px; margin: 80px auto 0; padding: 0 16px; }
.login-card { padding: 32px; }
.login-logo { display: flex; align-items: center; gap: 10px; margin-bottom: 22px; justify-content: center; }
.login-brand { font-weight: 700; font-size: 20px; color: #0f172a; }
.login-hint { font-size: 12.5px; color: #94a3b8; margin-top: 18px; line-height: 1.6; text-align: center; }

/* ---- Two/three column result & review layouts ---- */
.body-grid { display: grid; grid-template-columns: 1.55fr 1fr; gap: 20px; align-items: start; }
.grid2 { display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px; align-items: start; }
.three-col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 1000px) {
  .body-grid, .grid2, .three-col { grid-template-columns: 1fr; }
}

/* ---- Tablet ---- */
@media (max-width: 860px) {
  .form-grid.cols-3, .form-grid.cols-4 { grid-template-columns: 1fr 1fr; }
  .page { padding: 24px 24px 60px; }
}

/* ---- Mobile: sidebar becomes an off-canvas panel behind a menu button ---- */
/* ---- Laptop / tablet landscape: keep the persistent sidebar, just
   narrower - content never sits underneath it, flex layout does that
   for free at every width in this tier. ---- */
@media (max-width: 1199px) and (min-width: 768px) {
  .sidebar { width: 208px; }
  .main-area { margin-left: 208px; }
  .navbrand { padding: 18px 14px 14px; }
  .navtitle { font-size: 16px; }
  .navsubtitle { white-space: normal; line-height: 1.3; }
  .navlink, .nav-cat-btn, .nav-child-link { font-size: 13px; }
}

/* ---- Tablet portrait, mobile, small mobile: sidebar becomes an
   off-canvas drawer behind a menu button. One breakpoint covers every
   width down to the smallest phones (320px) - the drawer's own width is
   a percentage with a cap, so it scales down safely rather than needing
   a separate rule per device. ---- */
@media (max-width: 767px) {
  .sidebar {
    left: -100%; top: 0; bottom: 0; z-index: 40;
    width: 84%; max-width: 300px; transition: left 0.22s ease;
    box-shadow: 2px 0 24px rgba(15, 23, 42, 0.25);
    border-right: none;
  }
  .sidebar.open { left: 0; }
  /* The sidebar is an overlay drawer at this width, not a pushed-aside
     column - it shouldn't reserve any space in the main content's flow. */
  .main-area { margin-left: 0; }
  .sidebar-backdrop {
    display: block; position: fixed; inset: 0; background: rgba(15, 23, 42, 0.45);
    z-index: 35; opacity: 0; pointer-events: none; transition: opacity 0.22s ease;
  }
  .sidebar-backdrop.open { opacity: 1; pointer-events: auto; }
  .menu-btn { display: flex; align-items: center; }
  .page { padding: 20px 16px 60px; }
  .form-grid.cols-2, .form-grid.cols-3, .form-grid.cols-4 { grid-template-columns: 1fr; }
  .stat-row { grid-template-columns: 1fr; }
  h1.title { font-size: 22px; }
  /* Comfortable touch targets once the sidebar is a tap-driven drawer. */
  .navlink, .nav-cat-btn, .nav-child-link { min-height: 46px; padding-top: 12px; padding-bottom: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ---- Installed-app bottom tab bar ----
   Hidden by default (and while just browsing the site in a normal mobile
   browser tab, where the drawer + menu button already cover navigation) -
   only shown once the app is actually running standalone, i.e. launched
   from a home-screen icon, which is when a native-feeling tab bar earns
   its screen space. See the <nav class="bottom-nav"> block in base.html. */
.bottom-nav {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: #fff; border-top: 1px solid #ececf3;
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -4px 16px rgba(15, 23, 42, 0.07);
}
.bottom-nav-tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 6px 4px 5px; border-radius: 12px; color: #94a3b8;
  font-size: 11px; font-weight: 700; letter-spacing: 0.01em;
}
.bottom-nav-tab.active { color: var(--brand); background: var(--brand-light); }
.bottom-nav-tab svg { flex-shrink: 0; }

@media (max-width: 767px) and (display-mode: standalone),
       (max-width: 767px) and (display-mode: fullscreen),
       (max-width: 767px) and (display-mode: minimal-ui) {
  .bottom-nav { display: flex; }
  /* Room for the bar so the last bit of real content isn't hidden behind it. */
  .page { padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
}

/* ---- Install prompt banner ----
   No `display` set here on purpose - the [hidden] attribute's user-agent
   default (display:none) is what keeps this off-screen until the script
   in base.html finds a real install opportunity and sets style.display
   itself; a class-based `display` here would out-specificity [hidden]
   and show the banner on every load. */
.install-banner {
  position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 45;
  align-items: center; gap: 12px; padding: 12px 14px; max-width: 420px; margin: 0 auto;
  background: #0f172a; color: #fff; border-radius: 14px;
  box-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.45);
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
}
.install-banner-icon {
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
  background: linear-gradient(135deg, var(--brand-soft), var(--brand));
  display: flex; align-items: center; justify-content: center;
}
.install-banner-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.install-banner-text b { font-size: 13.5px; }
.install-banner-text span { color: #cbd5e1; font-size: 12px; line-height: 1.4; }
#evh-install-dismiss {
  background: none; border: none; color: #94a3b8; font-size: 20px; line-height: 1;
  padding: 4px 6px; cursor: pointer; flex-shrink: 0;
}
#evh-install-dismiss:hover { color: #e2e8f0; }

/* ---- Annotated paper / annotation boxes ---- */
.paper-toolbar { display: flex; justify-content: space-between; align-items: center; padding: 14px 18px; border-bottom: 1px solid #e2e8f0; }
.paper-frame {
  position: relative;
  background: repeating-linear-gradient(#ffffff 0px, #ffffff 27px, var(--brand-light) 28px);
  overflow: hidden;
}
.paper-frame img { display: block; width: 100%; }
.ann-box { position: absolute; border-radius: 3px 14px 4px 12px / 12px 4px 14px 3px; border-width: 2px; border-style: solid; pointer-events: none; }
.ann-qmark {
  position: absolute; top: -10px; left: 6px; font-family: 'Caveat', cursive;
  font-weight: 700; font-size: 22px; color: #1d4ed8; transform: rotate(-5deg);
}
.ann-tag {
  position: absolute; top: -11px; left: -2px; font-size: 11px; font-weight: 700;
  color: #fff; border-radius: 4px; padding: 1px 6px;
}
.pagechip {
  position: absolute; top: 8px; left: 8px; background: rgba(15, 23, 42, 0.65); color: #fff;
  font-size: 11px; padding: 2px 8px; border-radius: 5px; font-weight: 600;
}
.thumbstrip { display: flex; gap: 10px; padding: 14px 18px; flex-wrap: wrap; }
.thumb { width: 64px; height: 84px; border-radius: 6px; background: repeating-linear-gradient(#fff 0, #fff 6px, var(--brand-light) 7px); border: 2px solid #e2e8f0; overflow: hidden; }
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb.active { border-color: var(--brand-mid); }

/* "Hand-graded" red-pen marks - simulates a teacher's own pen on the
   scanned paper, layered on top of the AI-detected highlight boxes.
   Caveat is a handwriting-style Google Font; everything here uses the
   same "red ink" color (#b91c1c) and small rotations so marks read as
   drawn by a person rather than machine-perfect shapes. */
.pen-mark { position: absolute; display: flex; flex-direction: column; align-items: center; gap: 3px; transform: translateY(-50%); }
.pen-circle {
  width: 44px; height: 44px; border: 2.5px solid #b91c1c;
  border-radius: 52% 48% 47% 53% / 48% 55% 45% 52%;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Caveat', cursive; font-size: 21px; font-weight: 700; color: #b91c1c;
  transform: rotate(-6deg); position: relative; flex-shrink: 0; background: #fff;
}
.pen-icon { position: absolute; top: -9px; right: -11px; }
.pen-comment { font-family: 'Caveat', cursive; font-size: 17px; font-weight: 700; color: #b91c1c; transform: rotate(-3deg); white-space: nowrap; line-height: 1; }
.pen-underline { position: absolute; stroke: #b91c1c; fill: none; stroke-linecap: round; }
.scribble { stroke-linecap: round; fill: none; }

/* ---- Score / question cards (student result detail) ---- */
.qcard { padding: 16px 18px; border-bottom: 1px solid #f1f5f9; }
.qcard:last-child { border-bottom: none; }
.qhead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; gap: 12px; }
.qtag-left { display: flex; align-items: center; gap: 8px; }
.qlabel { font-size: 13px; color: #475569; }
.qscore { font-weight: 700; font-size: 15px; color: #0f172a; white-space: nowrap; }
.qbar-track { height: 5px; background: #f1f5f9; border-radius: 3px; overflow: hidden; margin-bottom: 10px; }
.qbar-fill { height: 100%; border-radius: 3px; }
.qremark { font-size: 13px; color: #64748b; font-style: italic; margin: 0 0 10px 0; line-height: 1.5; }
.verified { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.verified span { font-size: 12px; color: #166534; font-weight: 600; }
.dispute-link { font-size: 12px; font-weight: 600; cursor: pointer; }
.dispute-box { margin-top: 10px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; padding: 12px; }
.dispute-box textarea { margin-bottom: 8px; }

/* ---- Review workspace (3-pane grading) ---- */
.paneh { padding: 14px 18px; border-bottom: 1px solid #e2e8f0; font-weight: 600; font-size: 14px; }
.paneh .hint { font-weight: 400; color: #94a3b8; font-size: 12px; }
.panebody { padding: 16px 18px; max-height: 640px; overflow-y: auto; }
.aiblock { padding-bottom: 18px; margin-bottom: 18px; border-bottom: 1px solid #f1f5f9; }
.aiblock:last-child { border: none; margin: 0; padding: 0; }
.aihead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; gap: 8px; }
.qtitle { font-size: 13px; font-weight: 700; color: #0f172a; }
.transcript { background: #f8fafc; border: 1px solid #f1f5f9; border-radius: 6px; padding: 10px 12px; font-size: 13px; color: #334155; margin-bottom: 10px; line-height: 1.5; white-space: pre-wrap; }
.airow { display: flex; justify-content: space-between; align-items: center; font-size: 13px; margin-bottom: 6px; }
.airemark { font-size: 12.5px; color: #64748b; font-style: italic; margin: 6px 0 0 0; }
.field-label { font-size: 12px; font-weight: 600; color: #475569; margin: 0 0 5px 0; }
input.markinput { width: 90px; font-size: 14px; font-weight: 600; }
textarea.remarkinput { font-size: 13px; }
.reason-field { border: 1.5px solid #f59e0b; background: #fffbeb; border-radius: 6px; padding: 8px 10px; }
.reason-field input { border: none; background: transparent; padding: 0; box-shadow: none; }
.reason-field input:focus { box-shadow: none; }
.reason-label { font-size: 11px; font-weight: 700; color: #92400e; margin-bottom: 4px; display: block; }
.footer-bar { position: sticky; bottom: 0; display: flex; justify-content: space-between; align-items: center; padding: 16px 22px; margin-top: 18px; flex-wrap: wrap; gap: 10px; }

/* ---- Skills graph ---- */
.skillrow { display: flex; align-items: center; gap: 16px; padding: 16px 0; border-bottom: 1px solid #f1f5f9; }
.skillrow:last-child { border-bottom: none; }
.skillname { width: 170px; flex-shrink: 0; font-size: 14px; font-weight: 600; color: #0f172a; }
.skilltrack { flex: 1; height: 10px; background: #f1f5f9; border-radius: 5px; overflow: hidden; }
.skillfill { height: 100%; border-radius: 5px; }
.skillpct { width: 90px; text-align: right; font-size: 13.5px; font-weight: 700; color: #334155; flex-shrink: 0; }
.skillrow.compact { padding: 8px 0; gap: 12px; }
.skillrow.compact .skillname { width: 110px; font-size: 13px; }
.skillrow.compact .skilltrack { height: 8px; }
.skillrow.compact .skillpct { width: 60px; font-size: 12.5px; }

/* ---- Parent dashboard: child switcher ---- */
.switcher { display: flex; gap: 8px; margin-bottom: 22px; flex-wrap: wrap; }
.chip {
  padding: 8px 16px; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer;
  display: inline-block;
}
.chip.active { background: #0f172a; color: #fff; }
.chip.inactive { background: #fff; border: 1px solid #e2e8f0; color: #334155; }
.chip.inactive:hover { border-color: #c7d2fe; color: #0f172a; }
.childhead { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; }
.childavatar { width: 52px; height: 52px; border-radius: 50%; background: var(--brand-mid); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 17px; flex-shrink: 0; }
.childname { font-size: 18px; font-weight: 700; color: #0f172a; }
.childmeta { font-size: 13px; color: #64748b; }
.planitem { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; color: #334155; padding: 8px 0; border-bottom: 1px solid #f1f5f9; }
.planitem:last-child { border: none; }
.plandot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); margin-top: 7px; flex-shrink: 0; }

/* ---- Course card grid (Graphy-style media tile) ---- */
.course-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 20px; }
.course-card {
  padding: 0; overflow: visible; position: relative; display: flex; flex-direction: column;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.course-card:hover { box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 16px 32px -14px rgba(var(--brand-rgb), 0.28); transform: translateY(-3px); }
.course-hero {
  position: relative; height: 108px; border-radius: var(--radius-md) var(--radius-md) 0 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 32px; font-weight: 800; letter-spacing: -0.02em;
}
.course-hero::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 140% at 15% -10%, rgba(255, 255, 255, 0.28), transparent 55%);
}
.course-body { display: block; padding: 16px 18px 18px; color: inherit; text-decoration: none; flex: 1; }
.course-name { display: block; font-size: 15.5px; font-weight: 700; color: #0f172a; line-height: 1.35; }
.course-subject { font-size: 12.5px; color: #94a3b8; }
.course-subject-badge {
  display: inline-flex; margin-top: 6px; padding: 2px 10px; border-radius: 999px;
  background: var(--brand-light); color: var(--brand-dark); font-size: 11.5px; font-weight: 700;
  letter-spacing: .01em;
}
.course-stats {
  display: flex; justify-content: space-between; font-size: 12px; color: #94a3b8; text-align: center;
  border-top: 1px solid #f1f5f9; margin-top: 14px; padding-top: 12px;
}
.course-stats > span { flex: 1; min-width: 0; }
.course-stats b { display: block; font-size: 16px; font-weight: 800; color: #0f172a; letter-spacing: -0.01em; margin-bottom: 1px; }

.course-menu { position: absolute; top: 10px; right: 10px; z-index: 5; }
.course-menu-btn {
  width: 28px; height: 28px; border-radius: 8px; border: none; cursor: pointer;
  background: rgba(255, 255, 255, 0.22); color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.course-menu-btn:hover { background: rgba(255, 255, 255, 0.36); }
.course-menu-dropdown {
  display: none; position: absolute; top: 34px; right: 0; min-width: 168px;
  background: #fff; border: 1px solid #ececf3; border-radius: 10px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 16px 32px -10px rgba(15, 23, 42, 0.25);
  padding: 6px; text-align: left;
}
.course-menu.open .course-menu-dropdown { display: block; }
.course-menu-dropdown a, .course-menu-dropdown button {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: 7px;
  font-size: 13px; font-weight: 600; color: #334155; background: none; border: none;
  cursor: pointer; font-family: inherit; white-space: nowrap;
}
.course-menu-dropdown a:hover, .course-menu-dropdown button:hover { background: #f8fafc; }
.course-menu-dropdown .danger { color: #dc2626; }
.course-menu-dropdown .danger:hover { background: #fef2f2; }

/* ---- Utility ---- */
.mb-0 { margin-bottom: 0 !important; }
.mt-16 { margin-top: 16px; }
.flex { display: flex; }
.flex-between { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.flex-gap { display: flex; gap: 10px; flex-wrap: wrap; }
.text-right { text-align: right; }

@media print {
  .no-print { display: none !important; }
  .app-shell { display: block; }
  .main-area { display: block; margin-left: 0; }
  body { background: #fff; }
}
