/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ---------------------------------------------------------------------------
 * Themes. The app is written dark-first with Tailwind classes; Tailwind v4
 * compiles utilities to var(--color-*), so the light theme just redefines
 * those variables. Palette for light: Bauhaus poster — cream paper, ink,
 * red, deep blue, mustard. html[data-theme] is set by an inline head script
 * (no flash) and the theme Stimulus controller (auto follows the OS).
 * ------------------------------------------------------------------------ */
:root { color-scheme: dark; }

/* Edge-to-edge (viewport-fit=cover): keep content clear of the system
 * gesture bar / notches; insets are 0 on desktop. */
body {
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

:root[data-theme="light"] {
  color-scheme: light;

  /* paper + ink (slate scale flipped onto cream) */
  --color-slate-950: #f6f1e4;
  --color-slate-900: #e9e1cc;
  --color-slate-800: #d8cdb0;
  --color-slate-700: #b5a987;
  --color-slate-600: #8d8266;
  --color-slate-500: #756b54;
  --color-slate-400: #58503f;
  --color-slate-300: #423c2f;
  --color-slate-200: #2e2a20;
  --color-slate-100: #211e16;
  --color-white: #191711;

  /* links & primary accent: poster blue */
  --color-sky-200: #0e2a68;
  --color-sky-300: #142f80;
  --color-sky-400: #1f44ad;
  --color-sky-500: #2148b1;
  --color-sky-600: #1c3da0;
  --color-sky-700: #5a74c8;
  --color-sky-900: #ccd8f5;
  --color-sky-950: #dde5f8;
  --color-blue-400: #1f44ad;
  --color-indigo-300: #312e81;
  --color-indigo-400: #3b3fae;
  --color-violet-300: #5b21b6;
  --color-violet-900: #ddd2f2;
  --color-violet-950: #eae1f8;
  --color-teal-400: #0f766e;

  /* grades & marks */
  --color-emerald-300: #1b5e3f;
  --color-emerald-400: #20764d;
  --color-emerald-500: #259058;
  --color-emerald-700: #5fae85;
  --color-emerald-900: #cfe8d8;
  --color-emerald-950: #ddf0e4;
  --color-rose-300: #a81d14;
  --color-rose-400: #c9251a;
  --color-rose-500: #d22b1f;
  --color-rose-700: #e0695e;
  --color-rose-900: #f4cfc9;
  --color-rose-950: #f9ded9;
  --color-amber-200: #5c4a04;
  --color-amber-300: #8a6d05;
  --color-amber-400: #9a7a08;
  --color-amber-700: #d3b75a;
  --color-amber-900: #ecdca4;
  --color-amber-950: #f4e9c8;
}

/* On solid accent surfaces (primary buttons) "white" stays paper-white.
 * Every accent background that carries text-white must be listed here —
 * otherwise the label inherits the remapped --color-white (dark ink) and
 * renders near-invisible on the deep-blue/green button. */
:root[data-theme="light"] :is(
  .bg-sky-400, .bg-sky-500, .bg-sky-600,
  .bg-emerald-500, .bg-emerald-600,
  .bg-rose-500, .bg-rose-600,
  .bg-violet-500, .bg-violet-600
) {
  --color-white: #fffdf6;
}

/* ---------------------------------------------------------------------------
 * Teacher export/summary sheet. This is a TRUE light "paper" sheet regardless
 * of the app theme: it must stay white with dark ink in BOTH the dark app and
 * the cream light theme. It deliberately uses explicit colours instead of
 * Tailwind semantic utilities (bg-white / text-slate-*) because those compile
 * to var(--color-*), and the light theme remaps --color-white to dark ink —
 * which is exactly what made the summary render dark-on-dark. Nothing here may
 * reference a theme token.
 * ------------------------------------------------------------------------ */
.export-sheet {
  margin-top: 2rem;
  border-radius: 1rem;
  background: #ffffff;
  color: #0f172a;
  padding: 1.5rem;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.25), 0 8px 10px -6px rgba(0, 0, 0, 0.2);
  border: 1px solid #cbd5e1;
}

/* The off-screen node used to rasterise a single exercise into a PNG
 * (exercise_image.js). Same light paper; sized to its content so nothing is
 * clipped when html2canvas captures it. */
.export-image-stage {
  width: fit-content;
  max-width: none;
  box-shadow: none;
}

/* Print: emit ONLY the teacher summary. exercises_page_controller mounts a
 * copy of the summary as a direct child of <body> (#exercise-print-root) and
 * flags <html> with .exporting-summary for the duration of the print; we then
 * display:none everything else so no invisible interactive UI occupies page
 * boxes (visibility:hidden left the old export with trailing blank pages). The
 * flag scopes this to the export flow so an ordinary Cmd+P elsewhere in the
 * app is untouched. */
#exercise-print-root { display: none; }
@media print {
  html.exporting-summary, html.exporting-summary body { background: #fff !important; }
  html.exporting-summary body > *:not(#exercise-print-root) { display: none !important; }
  html.exporting-summary #exercise-print-root {
    display: block !important;
    margin: 0 !important;
  }
  html.exporting-summary #exercise-print-root .export-sheet {
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
  }
}

/* ---------------------------------------------------------------------------
 * Ordinary Cmd+P / "Save as PDF" of an interactive-exercises page (lesson
 * homework or book practice) — how Roman hands finished work to his teacher.
 * This is DISTINCT from the teacher-export flow above (.exporting-summary),
 * which rasterises a separate summary sheet; here we print the live worksheet
 * itself. Three things must hold that don't by default:
 *   1. The crossword grid draws its cell boxes with BACKGROUND colour — a
 *      tinted container (bg-slate-800) showing through 1px gaps, plus a
 *      per-cell fill (bg-slate-950). Browsers strip backgrounds when printing,
 *      so the boxes vanish and only the dark letters/numbers remain floating.
 *      We replace the gap-and-fill trick with a real per-cell border and force
 *      print-color-adjust: exact so the boxes actually render on paper.
 *   2. Interactive-only controls (Check / Show answers / Clear / image export)
 *      must not leak onto the printout.
 *   3. The sticky app header + min-h-screen flex body otherwise emit a
 *      near-blank leading page; we drop the chrome and collapse the height.
 * Everything is scoped with :has(.exercises-root) so every OTHER page in the
 * app prints exactly as before, and gated on html:not(.exporting-summary) so
 * the teacher-export flow stays in sole control when it runs.
 * ------------------------------------------------------------------------ */
@media print {
  html:not(.exporting-summary) body:has(.exercises-root) {
    background: #fff !important;
    min-height: 0 !important;
    /* undo the min-h-screen flex column that reserves a full first page */
    display: block !important;
  }
  html:not(.exporting-summary) body:has(.exercises-root) > header { display: none !important; }
  html:not(.exporting-summary) body:has(.exercises-root) main {
    display: block !important;
    flex: none !important;
  }

  /* Interactive-only controls never belong on the printout. The per-exercise
     score (X/Y) stays — it prints next to the work. */
  .exercises-root .exercise-actions button,
  .exercises-root .exercise-page-actions { display: none !important; }

  /* The reading stopwatch is interactive chrome, and it is sticky — left in,
     it stamps itself onto every printed page. */
  html:not(.exporting-summary) body:has(.exercises-root) [data-drill-timer-target="chip"] {
    display: none !important;
  }

  /* Never split a crossword grid across a page break. */
  .exercises-root .crossword-grid { break-inside: avoid; }

  /* --- Core fix: make the crossword cell boxes render on paper. The on-screen
     grid draws its lines with a tinted container behind 1px gaps and fills each
     cell with a background — both are stripped in print. Swap in real borders
     and opt the fills back in with print-color-adjust: exact. --- */
  .exercises-root .crossword-grid {
    gap: 0 !important;
    background: transparent !important;
    border: 0 !important;
    padding: 0 !important;
  }
  /* Letter cells (they contain the <input>): a solid box with white fill. */
  .exercises-root .crossword-grid > div:has(input) {
    border: 1px solid #0f172a !important;
    background: #ffffff !important;
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
  /* Blocked/empty cells: leave blank (no box) so the grid shape reads. */
  .exercises-root .crossword-grid > div:not(:has(input)) {
    border: 0 !important;
    background: transparent !important;
  }
  /* The typed letter must be dark ink on white (the grader may have tinted it
     green/red inline — override for legibility, matching the PNG export). */
  .exercises-root .crossword-grid input {
    color: #0f172a !important;
    -webkit-text-fill-color: #0f172a !important;
    background: transparent !important;
  }
  /* The little clue number in the cell corner. */
  .exercises-root .crossword-grid > div > span { color: #1d4ed8 !important; }
}

/* Practice exercises: chosen option (set by the exercise controller). Kept
 * here instead of utility classes so it can't be purged from the build. */
[data-exercise-target="option"][data-selected="1"] {
  border-color: #38bdf8;
  color: #e0f2fe;
  background: rgba(56, 189, 248, 0.15);
  font-weight: 700;
}
:root[data-theme="light"] [data-exercise-target="option"][data-selected="1"] {
  border-color: #1f44ad;
  color: #15306e;
  background: rgba(31, 68, 173, 0.12);
}

/* Markdown content (homework, theory) rendered by render_simple_markdown */
.md-content p { margin-bottom: 0.6rem; }
.md-content p:last-child { margin-bottom: 0; }
.md-content strong, .md-content b { color: #f1f5f9; font-weight: 700; }
.md-content a { color: #38bdf8; text-decoration: underline; }
.md-content a:hover { color: #7dd3fc; }
.md-content ul, .md-content ol { margin: 0.4rem 0 0.8rem; padding-left: 1.4rem; }
.md-content ul { list-style: disc; }
.md-content ol { list-style: decimal; }
.md-content li { margin-bottom: 0.25rem; }
.md-content h1, .md-content h2, .md-content h3, .md-content h4 {
  color: #f1f5f9; font-weight: 700; margin: 0.9rem 0 0.4rem; font-size: 1rem;
}
.md-content h1 { font-size: 1.15rem; }
.md-content code {
  background: rgba(15, 23, 42, 0.8); border: 1px solid #1e293b;
  border-radius: 0.3rem; padding: 0.1rem 0.35rem; font-size: 0.85em;
}
.md-content blockquote {
  border-left: 3px solid #334155; padding-left: 0.8rem; color: #94a3b8; margin: 0.6rem 0;
}
.md-content table { width: 100%; border-collapse: collapse; margin: 0.6rem 0; }
.md-content th, .md-content td { border: 1px solid #1e293b; padding: 0.35rem 0.6rem; text-align: left; }
.md-content hr { border-color: #1e293b; margin: 0.8rem 0; }

/* Book chapter reader rendered by render_book_content */
.book-content { font-family: ui-serif, Georgia, "Times New Roman", serif; letter-spacing: 0.01em; }
.book-content p { margin-bottom: 0.9rem; line-height: 1.75; }
.book-content p:last-child { margin-bottom: 0; }
.book-content strong, .book-content b { color: #e2e8f0; font-weight: 600; }
.book-content ul, .book-content ol { margin: 0.5rem 0 1rem; padding-left: 1.5rem; list-style: disc; }
.book-content ol { list-style: decimal; }
.book-content li { margin-bottom: 0.3rem; line-height: 1.7; }
.book-content h2 {
  display: inline-block; font-family: ui-sans-serif, system-ui, sans-serif;
  color: #38bdf8; background: rgba(12, 74, 110, 0.25); border: 1px solid rgba(12, 74, 110, 0.6);
  border-radius: 9999px; font-weight: 700; font-size: 0.8rem; letter-spacing: 0.08em;
  padding: 0.2rem 0.8rem; margin: 1.6rem 0 0.8rem;
}
.book-content h2:first-child { margin-top: 0; }
.book-content h3 {
  font-family: ui-sans-serif, system-ui, sans-serif; color: #f1f5f9;
  font-weight: 700; font-size: 1.05rem; margin: 1.4rem 0 0.6rem;
}
.book-content h3:first-child { margin-top: 0; }
.book-content blockquote {
  font-family: ui-sans-serif, system-ui, sans-serif;
  border-left: 3px solid #1e293b; background: rgba(15, 23, 42, 0.4);
  border-radius: 0 0.5rem 0.5rem 0; padding: 0.6rem 0.9rem; margin: 0.8rem 0;
  color: #94a3b8; font-size: 0.85em; line-height: 1.9;
}
.book-content blockquote p { margin: 0; line-height: 1.9; }

/* Light-theme counterparts for the hardcoded prose colors above. */
:root[data-theme="light"] .md-content strong, :root[data-theme="light"] .md-content b,
:root[data-theme="light"] .md-content h1, :root[data-theme="light"] .md-content h2,
:root[data-theme="light"] .md-content h3, :root[data-theme="light"] .md-content h4 { color: #211e16; }
:root[data-theme="light"] .md-content a { color: #1f44ad; }
:root[data-theme="light"] .md-content a:hover { color: #142f80; }
:root[data-theme="light"] .md-content code { background: rgba(233, 225, 204, 0.7); border-color: #d8cdb0; }
:root[data-theme="light"] .md-content blockquote { border-left-color: #b5a987; color: #58503f; }
:root[data-theme="light"] .md-content th, :root[data-theme="light"] .md-content td { border-color: #d8cdb0; }
:root[data-theme="light"] .md-content hr { border-color: #d8cdb0; }
:root[data-theme="light"] .book-content strong, :root[data-theme="light"] .book-content b { color: #211e16; }
:root[data-theme="light"] .book-content h3 { color: #191711; }
:root[data-theme="light"] .book-content h2 {
  color: #1f44ad; background: rgba(31, 68, 173, 0.08); border-color: rgba(31, 68, 173, 0.35);
}
:root[data-theme="light"] .book-content blockquote {
  border-left-color: #d8cdb0; background: rgba(233, 225, 204, 0.5); color: #58503f;
}

/* Luistertoets exam mode: the shared exercise renderer's Check / Show answers /
   export rows stay hidden until the one-shot round is over (exam_player), and
   so does the "Opdracht N / instruction" header — during the round the sticky
   HUD carries the state and the question itself should be the first thing in
   the card, not the third. */
.exam-mode .exercise-actions,
.exam-mode .exercise-page-actions,
.exam-mode .exercise-head {
  display: none;
}

.exam-mode .exercise-body {
  margin-top: 0;
}
