/* Classroom-projector-friendly: high contrast, large type, single column.
   Exam-paper register: serif for headings/question text, sans for UI
   chrome and anything tabular. See docs/ui.md for the design rationale. */

:root {
  --paper: #ffffff;
  --paper-raised: #fbfbfa;
  --ink: #14181f;
  --slate: #57626f;
  --slate-soft: #8992a0;
  --hairline: #dfe4ea;
  --academy: #1b4c87;
  --academy-soft: #eaf1fa;
  --verified: #2f7d5b;
  --verified-soft: #e7f3ed;
  --generated: #b8791a;
  --generated-soft: #fbf0df;
  --danger: #b0392c;
  --danger-soft: #fbe9e6;

  --serif: Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
  --sans: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* Theme is explicit, not system-inferred: an inline script in every
   page's <head> sets data-theme from localStorage (defaulting to
   "light") before first paint, and the toggle in the nav dropdown
   flips it. See docs/ui.md. */

:root[data-theme="dark"] {
  --paper: #10151c;
  --paper-raised: #151b23;
  --ink: #e8ecf1;
  --slate: #93a0ad;
  --slate-soft: #647080;
  --hairline: #253040;
  --academy: #6fa0dc;
  --academy-soft: #1b2a3c;
  --verified: #59c793;
  --verified-soft: #16301f;
  --generated: #e3a63d;
  --generated-soft: #3a2a12;
  --danger: #e0685a;
  --danger-soft: #3a1a16;
}

:root[data-theme="light"] {
  --paper: #ffffff;
  --paper-raised: #fbfbfa;
  --ink: #14181f;
  --slate: #57626f;
  --slate-soft: #8992a0;
  --hairline: #dfe4ea;
  --academy: #1b4c87;
  --academy-soft: #eaf1fa;
  --verified: #2f7d5b;
  --verified-soft: #e7f3ed;
  --generated: #b8791a;
  --generated-soft: #fbf0df;
  --danger: #b0392c;
  --danger-soft: #fbe9e6;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 19px;
  line-height: 1.55;
}

h1, h2, h3 {
  font-family: var(--serif);
  text-wrap: balance;
  font-weight: 400;
}

a {
  color: var(--academy);
}

.site-header {
  padding: 1.1rem 1.5rem;
  border-bottom: 3px solid var(--academy);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.site-header h1 {
  margin: 0;
  font-size: 1.5rem;
  color: var(--academy);
}

.tagline {
  color: var(--slate);
  font-size: 1rem;
  margin: 0;
}

/* Persistent left icon rail (Home / Notebooks / Profile) -- present on
   every signed-in student page except admin-*.html (its own separate
   nav) and index.html (nothing to navigate to before signing in).
   position: fixed rather than a flex sibling of body's own column
   layout so it works identically whether or not the page also opts
   into body.dashboard-body's fixed-height shell -- .icon-rail doesn't
   care about that at all, it just floats over the left edge of the
   viewport. body.has-icon-rail pushes everything else right by the
   rail's width so nothing renders underneath it. */
.icon-rail {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 76px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 1.25rem 0.5rem;
  background: var(--paper-raised);
  border-right: 1px solid var(--hairline);
  z-index: 30;
  overflow-y: auto;
}

.icon-rail-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  width: 100%;
  padding: 0.6rem 0.2rem;
  border-radius: 8px;
  color: var(--slate);
  text-decoration: none;
  font-family: var(--sans);
  font-size: 0.7rem;
  text-align: center;
}

.icon-rail-item:hover {
  background: var(--academy-soft);
  color: var(--academy);
}

.icon-rail-item.active {
  background: var(--academy-soft);
  color: var(--academy);
  font-weight: 600;
}

.icon-rail-icon {
  font-size: 1.4rem;
  line-height: 1;
}

body.has-icon-rail {
  padding-left: 76px;
}

@media (max-width: 760px) {
  .icon-rail {
    width: 56px;
  }

  .icon-rail-icon {
    font-size: 1.2rem;
  }

  .icon-rail-item {
    font-size: 0.6rem;
  }

  body.has-icon-rail {
    padding-left: 56px;
  }
}

main {
  max-width: 700px;
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
}

/* Pages that show a left sidebar (subjects.html/chapter.html/admin-*.html
   always; doubt-books.html only when a ?subject= filter is active) need
   more width for the extra column -- see .dashboard-layout below, which
   is single-column by default and opts into the two-column flex layout
   via the .has-sidebar modifier class (added statically in markup, or by
   JS exactly when the sidebar is actually populated).

   width: 100% is needed alongside max-width because body.dashboard-body
   is a flex column and the base `main` rule (above) carries `margin: 0
   auto` -- a flex item with an auto cross-axis margin and an auto width
   doesn't stretch to fill its container the way plain block layout would
   (the auto margin absorbs the space instead), so without an explicit
   width main would just shrink-wrap to its own content instead of
   actually using the extra room up to max-width. */
main.dashboard-main {
  width: 100%;
  max-width: 1320px;
}

/* Pages that additionally cap at the viewport height instead of growing
   with content -- subjects.html, chapter.html, and the three admin-*.html
   pages, all of which always show a sidebar. Opt in via this class on
   <body> (set in each page's markup) rather than :has(main.dashboard-main)
   -- this project has already been bitten once by Safari not reliably
   re-evaluating :has() against content that changes after initial paint
   (see the .dashboard-layout fix in git history); an explicit class has
   no such risk and makes the opt-in list explicit and grep-able.
   doubt-books.html deliberately does NOT get this class even though it
   reuses the same sidebar/panel CSS classes -- its sidebar is optional
   (?subject= only), and the .dashboard-layout/.dashboard-panel/
   .subject-sidebar height+scroll rules below are all scoped under
   body.dashboard-body, so nothing here affects it.

   max-height here, not height -- a short page (one question, a handful
   of chapters) should just be as tall as its content and let the footer
   sit right after it, not get stretched to fill the full viewport with a
   big empty gap above a footer stranded at the bottom (most visible in
   landscape, where there's height to spare beyond what the content
   needs). max-height only kicks in as a ceiling once content actually
   would exceed the viewport, at which point it caps the page there and
   the flex:1/min-height:0 chain below gives dashboard-layout a definite,
   capped height to stretch its sidebar/panel into -- same scrolling
   behavior as before for long content, just without forcing short
   content to pretend it's a full screen tall. */
body.dashboard-body {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
}

body.dashboard-body .site-header,
body.dashboard-body .site-footer {
  flex-shrink: 0;
}

body.dashboard-body main.dashboard-main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

body.dashboard-body main.dashboard-main > .user-bar,
body.dashboard-body main.dashboard-main > nav.crumbs {
  flex-shrink: 0;
}

body.dashboard-body .dashboard-layout {
  flex: 1;
  min-height: 0;
}

.card {
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem 2rem;
  background: var(--paper-raised);
}

.card h2 {
  margin-top: 0;
  color: var(--academy);
}

.site-footer {
  text-align: center;
  color: var(--slate);
  padding: 1.5rem;
  font-size: 1rem;
}

.button {
  display: inline-block;
  font-family: var(--sans);
  font-size: 1.05rem;
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  border: none;
  background: var(--academy);
  color: #ffffff;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}

.button-secondary {
  background: transparent;
  color: var(--academy);
  border: 1px solid var(--academy);
}

.button:focus-visible,
a:focus-visible,
.row:focus-visible,
.crumb:focus-visible {
  outline: 2px solid var(--academy);
  outline-offset: 2px;
}

#auth-section form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1.5rem;
  max-width: 320px;
}

#auth-section label {
  font-size: 1rem;
  color: var(--slate);
}

#auth-section input[type="email"] {
  font-size: 1.1rem;
  padding: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}

#auth-status {
  color: var(--slate);
  min-height: 1.5em;
}

.user-bar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
  font-size: 0.95rem;
  color: var(--slate);
}

.user-bar a {
  color: var(--academy);
}

.user-menu-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

/* Nav: "Edit profile" / email / "Sign out" always collapse behind a
   hamburger toggle, on every screen size, so "Doubt Books" keeps room
   to stay a prominent, always-visible full-size button. */
.user-menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  line-height: 1;
  padding: 0.4rem 0.7rem;
  border-radius: 6px;
  border: 1px solid var(--hairline);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
}

.user-menu {
  display: none;
  position: absolute;
  top: calc(100% + 0.6rem);
  right: 0;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.85rem;
  background: var(--paper-raised);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  z-index: 20;
  min-width: 200px;
}

.user-menu.open {
  display: flex;
}

.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--hairline);
  font-size: 1rem;
  color: var(--ink);
  cursor: pointer;
}

.theme-toggle input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.theme-toggle .switch {
  position: relative;
  flex-shrink: 0;
  width: 2.6rem;
  height: 1.5rem;
  border-radius: 999px;
  background: var(--hairline);
  border: 1px solid var(--slate-soft);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.theme-toggle .switch::before {
  content: "";
  position: absolute;
  top: 1px;
  left: 1px;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  background: var(--paper);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s ease;
}

.theme-toggle input:checked + .switch {
  background: var(--academy);
  border-color: var(--academy);
}

.theme-toggle input:checked + .switch::before {
  transform: translateX(1.1rem);
}

.theme-toggle input:focus-visible + .switch {
  outline: 2px solid var(--academy);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .theme-toggle .switch,
  .theme-toggle .switch::before {
    transition: none;
  }
}

/* Profile setup / edit form */

#profile-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  max-width: 420px;
}

#profile-form label {
  font-size: 1.05rem;
}

#profile-form input[type="text"] {
  font-size: 1.1rem;
  padding: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  width: 100%;
}

#profile-form fieldset {
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.75rem 1rem 1rem;
}

#profile-form legend {
  padding: 0 0.4rem;
  color: var(--slate);
  font-size: 0.9rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

#profile-form fieldset label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0;
}

#profile-form fieldset label:has(input:disabled) {
  color: var(--slate-soft);
}

#profile-status {
  color: var(--slate);
  min-height: 1.5em;
}

/* Breadcrumb navigation */

nav.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.95rem;
  color: var(--slate);
  margin-bottom: 1.75rem;
}

nav.crumbs a.crumb {
  color: var(--academy);
  text-decoration: underline;
  text-underline-offset: 3px;
}

nav.crumbs .sep {
  color: var(--slate-soft);
}

nav.crumbs .current {
  color: var(--ink);
  font-weight: 600;
}

/* Level header (eyebrow + heading + subtitle) */

.eyebrow {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--academy);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--hairline);
}

.level-header {
  margin-bottom: 1.75rem;
}

.level-header h1 {
  font-size: 2rem;
  margin: 0.35rem 0 0.3rem;
}

.level-header .sub {
  color: var(--slate);
  font-size: 1rem;
}

/* Drill-down list (chapters, sections) */

.list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--hairline);
}

.row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 0.25rem;
  border-bottom: 1px solid var(--hairline);
  background: none;
  border-left: none;
  border-right: none;
  border-top: none;
  width: 100%;
  font-size: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  color: inherit;
}

.row:hover {
  background: var(--academy-soft);
}

.row .idx {
  font-variant-numeric: tabular-nums;
  color: var(--slate-soft);
  font-size: 0.95rem;
  width: 1.6rem;
  flex-shrink: 0;
}

.row .idx.letter {
  font-family: var(--serif);
  color: var(--academy);
  font-size: 1.35rem;
  width: 2rem;
}

.row .title {
  flex: 1;
  font-size: 1.08rem;
}

.row .meta {
  color: var(--slate);
  font-size: 0.9rem;
  white-space: nowrap;
}

.row .chevron {
  color: var(--slate-soft);
  font-size: 1.1rem;
  flex-shrink: 0;
}

.empty-state {
  color: var(--slate);
  padding: 1.5rem 0.25rem;
  font-size: 1rem;
}

/* Year filter (chapter.html) */

.year-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.year-chip {
  font-family: var(--sans);
  font-size: 0.9rem;
  padding: 0.35rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--paper);
  color: var(--slate);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}

.year-chip:hover {
  border-color: var(--academy);
  color: var(--academy);
}

.year-chip.active {
  background: var(--academy);
  border-color: var(--academy);
  color: #ffffff;
}

.year-chip-disabled {
  border-style: dashed;
  border-color: var(--hairline);
  background: transparent;
  color: var(--slate-soft);
  cursor: default;
}

.year-chip-disabled:hover {
  border-color: var(--hairline);
  color: var(--slate-soft);
}

/* Subject dashboard: sidebar (subjects.html always; doubt-books.html only
   when subject-filtered) + chapter-list panel. */

/* Single column by default -- doubt-books.html starts (and stays) this way
   when it has no ?subject= to show a sidebar for. Was previously driven by
   `.dashboard-layout:has(> #subject-sidebar-slot:empty)`, but Safari
   doesn't reliably re-run :has() the moment JS appends the sidebar into a
   previously-empty slot -- it would sit in single-column layout until some
   unrelated reflow (e.g. switching tabs and back) nudged it to
   re-evaluate. Explicit JS-driven class instead: whoever populates
   #subject-sidebar-slot adds .has-sidebar alongside it. subjects.html's
   sidebar is always populated, so its markup has the class baked in
   directly rather than needing JS to add it. */
.dashboard-layout {
  display: block;
}

.dashboard-layout.has-sidebar {
  display: flex;
  align-items: stretch;
  gap: 2rem;
}

.dashboard-panel {
  flex: 1;
  min-width: 0;
  padding-right: 0.5rem;
  padding-bottom: 1.5rem;
}

/* On body.dashboard-body pages, .dashboard-layout's own height is now
   content-bounded-or-capped (see body.dashboard-body above), so
   stretching the sidebar and panel to match it is safe -- for short
   content that height is small (no more forced full-viewport stretch
   into empty space), and for long content it's capped at the viewport,
   with overflow-y:auto below letting each box scroll independently
   instead of the whole page growing. Elsewhere (doubt-books.html's
   optional sidebar) these same rules are harmless: height/overflow only
   matter once a height is actually constrained by an ancestor, which
   only body.dashboard-body provides. */
.dashboard-panel,
.subject-sidebar,
.section-sidebar {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

.subject-sidebar {
  flex-shrink: 0;
  width: 220px;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.subject-sidebar-list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  padding: 0.5rem;
  background: var(--paper-raised);
}

.subject-sidebar-item {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.65rem 0.75rem;
  border-radius: 7px;
  color: var(--ink);
  text-decoration: none;
  font-size: 1rem;
}

.subject-sidebar-item:hover {
  background: var(--academy-soft);
}

.subject-sidebar-item.active {
  background: var(--academy);
  color: #ffffff;
}

.subject-sidebar-icon {
  font-size: 1.15rem;
  flex-shrink: 0;
  width: 1.5rem;
  text-align: center;
}

.subject-sidebar-name {
  font-family: var(--sans);
  white-space: nowrap;
}

.subject-sidebar-doubtbook {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.65rem 0.75rem;
  border-radius: 7px;
  border: 1px solid var(--hairline);
  color: var(--academy);
  text-decoration: none;
  font-size: 1rem;
}

.subject-sidebar-doubtbook:hover {
  background: var(--academy-soft);
}

/* Section sidebar (chapter.html): same look and pattern as the subject
   sidebar above, just a narrower compact tab strip -- letter + short
   label (MCQ/VSA/SA/LA/Case Study) instead of icon + full name, since
   there are only ever 5 of these and they're identical across every
   chapter. */
.section-sidebar {
  flex-shrink: 0;
  width: 150px;
  display: flex;
  flex-direction: column;
}

.section-sidebar-list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  padding: 0.5rem;
  background: var(--paper-raised);
}

.section-sidebar-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.65rem;
  border-radius: 7px;
  color: var(--ink);
  text-decoration: none;
  font-size: 0.95rem;
}

.section-sidebar-item:hover {
  background: var(--academy-soft);
}

.section-sidebar-item.active {
  background: var(--academy);
  color: #ffffff;
}

.section-sidebar-letter {
  font-family: var(--serif);
  font-size: 1.1rem;
  font-weight: 700;
  flex-shrink: 0;
  width: 1.3rem;
  text-align: center;
}

.section-sidebar-label {
  font-family: var(--sans);
  font-size: 0.85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Narrow widths: sidebars become horizontal scrollable chip strips pinned
   above the panel instead of hiding behind a menu -- every subject/section
   stays one tap away regardless of screen width. */
@media (max-width: 760px) {
  .dashboard-layout {
    flex-direction: column;
    gap: 1.25rem;
  }

  .subject-sidebar,
  .section-sidebar {
    /* overflow-y stays auto (inherited) rather than visible -- CSS
       requires overflow-x/overflow-y to agree on visible-vs-not, and
       overflow-x is hidden here, so a mismatched visible would just get
       silently resolved back to auto by the browser anyway. Harmless
       either way: height:auto means there's nothing to scroll once
       stacked, so auto never actually shows a scrollbar. */
    width: 100%;
    flex-shrink: 0;
    height: auto;
  }

  .subject-sidebar-list,
  .section-sidebar-list {
    flex-direction: row;
    overflow-x: auto;
    gap: 0.5rem;
    -webkit-overflow-scrolling: touch;
  }

  .subject-sidebar-item,
  .section-sidebar-item {
    flex-shrink: 0;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.6rem 0.9rem;
    font-size: 0.85rem;
    text-align: center;
  }

  .subject-sidebar-name,
  .section-sidebar-label {
    white-space: nowrap;
  }

  .subject-sidebar-doubtbook {
    justify-content: center;
  }
}

.chapter-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.chapter-filter-chip {
  font-family: var(--sans);
  font-size: 0.9rem;
  padding: 0.35rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--paper);
  color: var(--slate);
  cursor: pointer;
}

.chapter-filter-chip:hover {
  border-color: var(--academy);
  color: var(--academy);
}

.chapter-filter-chip.active {
  background: var(--academy);
  border-color: var(--academy);
  color: #ffffff;
}

.continue-solving-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  border: 1px solid var(--academy);
  border-radius: 10px;
  background: var(--academy-soft);
  color: var(--ink);
  text-decoration: none;
}

.continue-solving-card:hover {
  background: var(--academy);
  color: #ffffff;
}

.continue-solving-card:hover .continue-solving-label {
  color: #ffffff;
}

.continue-solving-label {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--academy);
  flex-shrink: 0;
}

.continue-solving-chapter {
  flex: 1;
  font-family: var(--serif);
  font-size: 1.1rem;
}

.chapter-row .weak-badge {
  display: inline-block;
  margin-left: 0.6rem;
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  background: var(--danger-soft);
  color: var(--danger);
  vertical-align: middle;
}

.subject-filter-notice {
  font-size: 0.9rem;
  color: var(--slate);
  padding: 0.65rem 0;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--hairline);
}

/* Question list (rows link out to a dedicated question page) */

.qlist {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.qcard-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--paper-raised);
  padding-right: 0.75rem;
}

.qrow-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
  padding: 0.9rem 1.1rem;
  text-decoration: none;
  color: inherit;
}

.qrow-link:hover {
  background: var(--academy-soft);
}

.qrow-link .qnum {
  font-family: var(--serif);
  font-size: 1.15rem;
  color: var(--academy);
  width: 2.2rem;
  flex-shrink: 0;
}

.tag {
  font-size: 0.8rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--academy-soft);
  color: var(--academy);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.spacer {
  flex: 1;
}

.qrow-link .chevron {
  color: var(--slate-soft);
  flex-shrink: 0;
}

.qrow-actions {
  flex-shrink: 0;
}

/* Dedicated single-question page */

.qfocus-back {
  display: inline-block;
  margin-bottom: 1.25rem;
  color: var(--academy);
  font-family: var(--sans);
  font-size: 0.95rem;
  text-decoration: none;
}

.qfocus-back:hover {
  text-decoration: underline;
}

/* Capped independently of .dashboard-panel's own (now much wider) width
   -- list rows benefit from the extra room (bigger, easier-to-read rows
   on a wide/landscape screen), but a single question's prose and MCQ
   options don't: stretched edge-to-edge across a wide panel, the options
   would look thin and sparse and the question text would run wider than
   is comfortable to read (see .qtext's own 62ch cap, sized for this). */
.qfocus-card {
  max-width: 760px;
  margin: 0 auto;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--paper-raised);
  /* Generous bottom padding -- Check Answer/Previous/Next no longer
     live inside this card (moved into the fixed .qfocus-actions-slot,
     see below), so without this the revealed solution's last lines
     would scroll to sit right underneath that fixed bar. */
  padding: 1.25rem 1.1rem 7rem;
}

.qfocus-meta {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}

.qfocus-meta .qnum {
  font-family: var(--serif);
  font-size: 1.05rem;
  color: var(--academy);
  font-variant-numeric: tabular-nums;
}

.qtext {
  font-family: var(--serif);
  font-size: 1.15rem;
  line-height: 1.6;
  margin: 1rem 0 1.25rem;
  max-width: 62ch;
}

.mcq-options {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0 0 1.25rem;
}

.mcq-option {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--paper-raised);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.mcq-option:hover:not(.correct):not(.incorrect) {
  border-color: var(--academy);
}

.mcq-option.selected {
  border-color: var(--academy);
  background: var(--academy-soft);
}

.mcq-option.correct {
  border-color: var(--verified);
  background: var(--verified-soft);
  cursor: default;
}

.mcq-option.incorrect {
  border-color: var(--danger);
  background: var(--danger-soft);
  cursor: default;
}

.mcq-option.correct .mcq-label,
.mcq-option.incorrect .mcq-label {
  color: var(--ink);
}

.mcq-option .mcq-label {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--academy);
  flex-shrink: 0;
  width: 1.3rem;
}

.mcq-option .mcq-text {
  font-family: var(--serif);
  font-size: 1.05rem;
  line-height: 1.5;
}

/* Page-level anchor for the fixed Check Answer/Previous/Next bar --
   present (empty, zero footprint) on every page that includes it, even
   outside focused-question view; .qfocus-actions (below) carries all
   the actual visible styling, so an empty slot renders nothing. left
   accounts for the icon rail's width so the bar starts right after it
   instead of underneath it -- position: fixed is relative to the
   viewport, not to body's own padding-left, so this can't just inherit
   body.has-icon-rail's offset. */
#qfocus-actions-slot {
  position: fixed;
  left: 76px;
  right: 0;
  bottom: 0;
  z-index: 25;
}

@media (max-width: 760px) {
  #qfocus-actions-slot {
    left: 56px;
  }
}

/* True position: fixed (via the slot above), not sticky -- sticky
   inside this nested flex/scroll layout was overlapping content on
   real devices instead of cleanly pinning to the bottom. Fixed escapes
   .dashboard-panel's scrolling entirely, so it stays put regardless of
   how the content above scrolls. max-width + margin: auto keeps it
   aligned with .qfocus-card above it rather than stretching edge to
   edge; .qfocus-card gets matching bottom padding (see below) so the
   solution text never renders underneath this bar. */
.qfocus-actions {
  max-width: 760px;
  margin: 0 auto;
  padding: 0.85rem 1.1rem calc(0.85rem + env(safe-area-inset-bottom, 0px));
  background: var(--paper-raised);
  border-top: 1px solid var(--hairline);
  box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.1);
}

.check-answer-btn {
  display: block;
  width: 100%;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  padding: 0.85rem 1rem;
  margin-bottom: 1.25rem;
  border-radius: 8px;
  border: 1px solid var(--academy);
  background: var(--academy-soft);
  color: var(--academy);
  cursor: pointer;
}

.check-answer-btn:hover {
  background: var(--academy);
  color: var(--paper);
}

.solution {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1rem 1.1rem;
}

.qnav {
  display: flex;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.qnav-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 0.7rem 1rem;
  border-radius: 8px;
  border: 1px solid var(--hairline);
  background: var(--paper);
  color: var(--slate);
  text-decoration: none;
  cursor: pointer;
}

.qnav-btn:hover:not(.qnav-btn-disabled) {
  border-color: var(--academy);
  color: var(--academy);
}

.qnav-btn-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.solution-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.6rem;
}

.solution-head .label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--slate);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.pill {
  font-size: 0.78rem;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  font-weight: 600;
}

.pill.verified {
  background: var(--verified-soft);
  color: var(--verified);
}

.pill.generated {
  background: var(--generated-soft);
  color: var(--generated);
}

.solution-text {
  font-size: 1rem;
  color: var(--ink);
}


/* Doubt Book */

.doubt-book-btn {
  font-family: var(--sans);
  font-size: 0.85rem;
  padding: 0.25rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--hairline);
  background: var(--paper);
  color: var(--slate);
  cursor: pointer;
  white-space: nowrap;
}

.doubt-book-btn:hover {
  border-color: var(--academy);
  color: var(--academy);
}

.doubt-book-btn.saved {
  background: var(--academy-soft);
  border-color: var(--academy);
  color: var(--academy);
}

dialog#doubt-book-dialog {
  border: 1px solid var(--hairline);
  border-radius: 10px;
  padding: 1.5rem;
  max-width: 360px;
  width: 90%;
  background: var(--paper);
  color: var(--ink);
}

dialog#doubt-book-dialog::backdrop {
  background: rgba(0, 0, 0, 0.4);
}

dialog#doubt-book-dialog h2 {
  margin: 0 0 1rem;
  font-size: 1.3rem;
}

.doubt-book-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 1rem;
}

#new-doubt-book-form {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 1rem 0;
}

#new-doubt-book-form label {
  font-size: 0.85rem;
  color: var(--slate);
}

#new-doubt-book-form input[type="text"] {
  font-size: 1rem;
  padding: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}

/* Admin review (admin-review.html) */

.review-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.review-bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  border: 1px solid var(--academy);
  border-radius: 8px;
  background: var(--academy-soft);
}

.review-select-all {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.95rem;
  color: var(--ink);
  cursor: pointer;
}

.review-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.review-row {
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--paper-raised);
  overflow: hidden;
}

.review-row-header {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.9rem 1.1rem;
}

.review-select {
  margin-top: 0.3rem;
  flex-shrink: 0;
}

.review-quick-publish-btn {
  flex-shrink: 0;
}

.review-summary {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.review-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}

.review-qtext {
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.review-row-header .chevron {
  color: var(--slate-soft);
  flex-shrink: 0;
  margin-top: 0.3rem;
  transition: transform 0.15s ease;
}

.review-row.open .chevron {
  transform: rotate(90deg);
}

.review-body {
  padding: 0 1.1rem 1.25rem;
  border-top: 1px solid var(--hairline);
}

.review-solution-text {
  margin-bottom: 0.75rem;
}

.review-meta-line {
  font-size: 0.9rem;
  color: var(--slate);
  margin-bottom: 0.5rem;
}

.review-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1rem;
}

.review-actions .review-reject-btn {
  background: var(--danger);
}

.review-status {
  color: var(--slate);
  font-size: 0.9rem;
  min-height: 1.4em;
  margin: 0.5rem 0 0;
}

.review-edit-form {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding-top: 1rem;
}

.review-edit-form label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: var(--slate);
}

.review-edit-form textarea,
.review-edit-form select {
  font-family: var(--sans);
  font-size: 1rem;
  padding: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}

.review-edit-form textarea {
  font-family: var(--serif);
  resize: vertical;
}

.review-edit-taxonomy {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.review-edit-taxonomy label {
  flex: 1;
  min-width: 160px;
}

/* Admin students (admin-students.html) */

.students-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.students-filter-row input[type="search"] {
  flex: 1;
  min-width: 220px;
  font-family: var(--sans);
  font-size: 1rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}

.students-filter-row select {
  font-family: var(--sans);
  font-size: 1rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
}

.students-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--hairline);
  border-radius: 8px;
}

.students-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.students-table th,
.students-table td {
  padding: 0.75rem 1rem;
  text-align: left;
  white-space: nowrap;
}

.students-table th {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--slate);
  background: var(--paper-raised);
  border-bottom: 1px solid var(--hairline);
}

.students-table tbody tr:not(:last-child) td {
  border-bottom: 1px solid var(--hairline);
}

.students-table tbody tr:hover td {
  background: var(--academy-soft);
}

.students-table td.empty-state {
  white-space: normal;
}
