/* Shared page chrome: top bar, back button, mastery bar, review badges,
   the text-size widget, and the lesson content type scale.

   Extracted from base.html's inline <style>. Every page was re-sending
   these ~18KB and re-parsing them on each navigation, because CSS inside
   HTML cannot be cached. The thirteen Django tags that used to pin it
   there are now body classes (.vs-tier-bar, .vs-has-back) and one custom
   property (--vs-banner), all set by base.html. */

    body {
        margin: 0;
        background-color: var(--bg);
    }

    /* ── Accessibility: skip link, focus, reduced motion ──────────────── */
    .skip-link {
        position: absolute; left: 8px; top: -48px; z-index: 1000;
        background: var(--brand-strong, #15803d); color: #fff;
        padding: 10px 16px; border-radius: 8px; font-weight: 800;
        text-decoration: none; transition: top .15s;
    }
    .skip-link:focus { top: 8px; }
    #main:focus { outline: none; }   /* programmatic focus target, no ring */

    /* A clear, consistent keyboard focus indicator for every control that
       doesn't define its own (the brain nav keeps its bespoke one). */
    a:focus-visible,
    button:focus-visible,
    input:focus-visible,
    select:focus-visible,
    textarea:focus-visible,
    [role="button"]:focus-visible,
    [tabindex]:focus-visible {
        outline: 3px solid var(--focus-ring);
        outline-offset: 2px;
        box-shadow: 0 0 0 2px var(--focus-ring-halo);
        border-radius: 4px;
    }
    @media (forced-colors: active) {
        a:focus-visible, button:focus-visible, input:focus-visible,
        select:focus-visible, textarea:focus-visible,
        [role="button"]:focus-visible, [tabindex]:focus-visible {
            outline-color: Highlight; box-shadow: none;
        }
    }

    @media (prefers-reduced-motion: reduce) {
        *, *::before, *::after {
            animation-duration: 0.001ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: 0.001ms !important;
            scroll-behavior: auto !important;
        }
    }

    #site-footer {
        text-align: center;
        padding: 24px 20px;
        font-size: 13px;
        font-weight: 700;
    }
    #site-footer a { color: var(--muted); text-decoration: none; }
    #site-footer a:hover { text-decoration: underline; }

    #top-bar {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 60px;
        background-color: var(--topbar-bg);
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0 20px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        z-index: 10;
    }
    /* Carry the node's subject colour onto the banner (the graph pages do
       the same). Only the banner is tinted — the page background stays
       neutral. --vs-banner is set inline on <html> by base.html when the
       page has a subject; with no subject it falls back to the default. */
    #top-bar { background-color: var(--vs-banner, var(--topbar-bg)); }

    #top-bar #title {
        color: var(--topbar-text);
        font-size: 24px;
        font-weight: bold;
    }

    #top-bar #title a {
        color: var(--topbar-text);
        text-decoration: none;
    }

    #top-bar #title a:hover {
        text-decoration: underline;
    }

    #back-btn {
        position: fixed;
        top: 80px;
        left: 32px;
        background: var(--surface);
        border: 2px solid var(--border);
        color: var(--text);
        font-family: var(--font);
        font-size: 15px;
        font-weight: 700;
        padding: 10px 20px;
        border-radius: var(--radius-pill);
        text-decoration: none;
        z-index: 10;
        box-shadow: var(--shadow-sm);
        transition: all 0.15s;
    }

    #back-btn:hover {
        background: #f1f5f9;
    }

    /* ── Mastery tier progress bar (top of review node pages) ─────────── */
    #tier-bar {
        position: fixed; top: 60px; left: 0; width: 100%; z-index: 9;
        display: flex; align-items: center; gap: 12px;
        padding: 5px 18px; box-sizing: border-box;
        background: rgba(248,248,248,0.92); box-shadow: 0 1px 5px rgba(0,0,0,0.07);
    }
    .tier-bar-track {
        flex: 1 1 auto; height: 12px; min-width: 0;
        background: #e2e8f0; border: 1.5px solid #cbd5e1;
        border-radius: 999px; overflow: hidden;
    }
    .tier-bar-fill {
        height: 100%; width: 0; border-radius: 999px;
        transition: width 0.9s cubic-bezier(.34,1.3,.64,1);
    }
    .tier-bar-fill.tb-wood   { background: linear-gradient(90deg,#c89b6a,#8B5E3C,#5c3a1e); }
    .tier-bar-fill.tb-bronze { background: linear-gradient(90deg,#fde68a,#d97706,#92400e); }
    .tier-bar-fill.tb-silver { background: linear-gradient(90deg,#f1f5f9,#cbd5e1,#64748b); }
    .tier-bar-fill.tb-gold   { background: linear-gradient(90deg,#fef9c3,#fde047,#ca8a04); }
    .tier-bar-fill.tier-up   { width: 100% !important; animation: tierUpPulse .9s ease; }
    @keyframes tierUpPulse { 0%,100%{filter:brightness(1);} 50%{filter:brightness(1.55);} }
    .tier-bar-label {
        flex: 0 0 auto; font-family: var(--font); font-size: 12px; font-weight: 800;
        color: #475569; white-space: nowrap;
    }
    /* ── Review-session chip ──────────────────────────────────────────
       Inside a run through the review queue, the session was previously
       invisible until the learner reached the Next button at the foot of
       the page. This says where they are and, just as importantly, offers
       the way out — a queue you cannot leave is a trap, not a flow. */
    .vs-review-session {
        max-width: 900px; margin: 0 auto 18px;
        display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
        background: var(--danger-tint); color: #991b1b;
        border: 1.5px solid #fca5a5; border-radius: var(--radius);
        padding: 9px 16px;
        font-family: var(--font); font-size: 14px; font-weight: 400;
    }
    .vs-review-session .vs-rs-title { font-weight: 900; }
    .vs-review-session .vs-rs-count {
        background: var(--danger-strong); color: #fff;
        border-radius: var(--radius-pill); padding: 2px 11px;
        font-weight: 900; font-size: 13px; font-variant-numeric: tabular-nums;
    }
    .vs-review-session .vs-rs-exit {
        margin-left: auto; color: #991b1b; font-weight: 800; font-size: 13px;
        /* The way out of a flow should not be the smallest control in it; this
           was 74x18. Padding + min-height rather than a fixed box, so the chip's
           row stays compact when it wraps on a phone. */
        display: inline-flex; align-items: center; min-height: 44px;
        padding: 0 10px; border-radius: var(--radius-sm);
    }
    .vs-review-session .vs-rs-exit:hover { background: rgba(153, 27, 27, .09); }
    @media (max-width: 640px) {
        .vs-review-session { font-size: 13px; padding: 8px 12px; gap: 8px; }
        .vs-review-session .vs-rs-exit { margin-left: 0; }
    }

    /* Teacher previewing a lesson as a student (?preview=1). Deliberately
       loud — it must never be mistaken for the real thing. */
    .vs-preview-bar {
        max-width: 900px; margin: 0 auto 18px;
        background: #fef3c7; color: #92400e; border: 2px solid #fde68a;
        border-radius: var(--radius); padding: 11px 16px;
        font-family: var(--font); font-size: 14px; font-weight: 700;
        line-height: 1.45; text-align: center;
    }
    #tier-up-toast {
        position: fixed; top: 92px; left: 50%; transform: translateX(-50%) translateY(-8px);
        z-index: 30; background: #1e293b; color: #fff; font-family: var(--font);
        font-weight: 900; font-size: 14px; padding: 9px 18px; border-radius: 999px;
        box-shadow: 0 6px 20px rgba(0,0,0,.3); opacity: 0; pointer-events: none;
        transition: opacity .3s, transform .3s;
    }
    #tier-up-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
    @media (max-width: 640px) { .tier-bar-label { display: none; } }

    /* ── Progress dots squeezed past the point of being dots ───────────
       A quiz with a hundred-plus questions on a phone leaves each of them
       about a pixel of the row (see the fitter near the end of this file).
       A border can't be drawn that thin — under border-box a border wider
       than the box wins, and the dots quietly grow back until the row
       overflows again — and the near-white unanswered fill is invisible
       anyway. So at that size the strip stops being circles and becomes a
       segmented bar: flat grey, filling in with green and red. The extra
       class in each selector is what outranks the per-page .dot colours. */
    .dots.vs-dots-hairline .dot            { border-width: 0; border-radius: 1px; background: #cbd5e1; }
    .dots.vs-dots-hairline .dot.correct    { background: #22c55e; }
    .dots.vs-dots-hairline .dot.wrong      { background: #ef4444; }
    .dots.vs-dots-hairline .dot.current    { background: #6366f1; box-shadow: none; }

    /* ── Review badges (countdown / "review needed") ───────────────────
       Pinned to the top-right of a lesson. Styled here rather than inline
       so the phone rules further down can reposition them — an inline
       style outranks any stylesheet rule. */
    .vs-review-badge {
        position: fixed; top: 70px; right: 20px; z-index: 15;
        display: flex; align-items: center; gap: 7px;
        background: rgba(255,255,255,0.95); border: 2px solid #cbd5e1;
        border-radius: 12px; padding: 6px 14px;
        font-family: var(--font); font-size: 13px; font-weight: 700;
        color: #475569; box-shadow: 0 2px 8px rgba(0,0,0,0.10);
    }
    .vs-review-badge .vs-rb-icon { font-size: 15px; }
    .vs-review-badge .vs-rb-note { font-size: 11px; font-weight: 600; color: #64748b; }
    .vs-review-badge.due {
        background: #fef2f2; border-color: #fca5a5; color: #dc2626;
        box-shadow: 0 2px 8px rgba(239,68,68,0.15);
    }
    /* "Completed" marker. A review node already advertises its state through
       the mastery bar and the countdown badge; a NON-review node had nothing
       at all, so finishing one — and re-opening it later — looked identical
       to never having done it. */
    .vs-review-badge.done {
        background: #f0fdf4; border-color: #86efac; color: #15803d;
        box-shadow: 0 2px 8px rgba(34,197,94,0.15);
    }
    /* The mastery bar takes the 22px under the banner, so everything pinned
       below it starts lower and the content needs the extra room. Keyed on
       a body class (these three rules used to sit inside a template
       conditional) so the whole stylesheet can be a cached file.

       DESKTOP ONLY, and the media query is what makes that true rather than a
       comment: at phone size Back and the badge ride ON the banner (the block
       below), and `body.vs-tier-bar #back-btn` outranks a bare `#back-btn`
       whatever the source order, so without this guard the tier bar dragged
       both of them back down to 90px — under the banner, on top of the first
       lines of the lesson — on every review node. This query is the exact
       complement of the phone one: neither narrow nor short. */
    @media (min-width: 641px) and (min-height: 521px) {
        body.vs-tier-bar #back-btn { top: 90px; }
        body.vs-tier-bar .vs-review-badge { top: 90px; }
        body.vs-tier-bar #main.page-content { padding-top: 46px; }
    }

    /* ── Phone: Back and the review timer ride IN the banner ───────────
       Both are pinned controls, and at phone size they hovered over the
       first 40-odd pixels of every lesson and quiz — exactly where a map,
       a title or a first paragraph wants to be. The banner is already
       there and mostly empty, so they move up onto it and the content
       starts directly under it.

       "Phone size" is narrow OR short, because those are the same phone
       held two ways. Nothing changes parent: both keep a z-index above the
       banner and are simply repositioned, so no stacking order shifts. */
    @media (max-width: 640px), (max-height: 520px) {
        /* Only where there is a Back button to make room for: a chrome page
           keeps its title left and its actions right. */
        body.vs-has-back #top-bar { justify-content: center; gap: 6px; padding: 0 8px; }
        body.vs-has-back #top-bar #title {
            font-size: 20px;
            /* Never grow into the two controls overlapping the bar's ends. */
            max-width: calc(100vw - 190px);
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        }
        #back-btn {
            top: 12px; left: 8px; z-index: 11;
            padding: 6px 12px; font-size: 13px; border-width: 1.5px;
        }
        .vs-review-badge {
            top: 14px; right: 8px; z-index: 11;
            padding: 4px 9px; font-size: 11.5px; gap: 5px; border-width: 1.5px;
        }
        .vs-review-badge .vs-rb-icon { font-size: 13px; }
        .vs-review-badge .vs-rb-note { display: none; }   /* "until review" — no room */
        #main.page-content { padding-top: 12px; }
        /* Only the mastery bar is still under the banner here, so the content
           clears 22px of it rather than the desktop 46px. */
        body.vs-tier-bar #main.page-content { padding-top: 34px; }
    }

    /* ── Text-size widget (lesson pages only) ────────────────────────── */
    /* Bottom-right so it never collides with the top-right review badge /
       countdown / supervisor force-review controls. */
    #text-size {
        position: fixed;
        bottom: 20px;
        right: 20px;
        z-index: 16;
        display: flex;
        align-items: center;
        gap: 6px;
        background: var(--surface);
        border: 2px solid var(--border);
        border-radius: var(--radius-pill);
        padding: 5px 8px;
        box-shadow: var(--shadow);
        font-family: var(--font);
    }
    #text-size button {
        border: none;
        background: var(--brand-tint);
        color: var(--brand-strong);
        font-family: var(--font);
        font-weight: 900;
        border-radius: var(--radius-pill);
        cursor: pointer;
        line-height: 1;
        padding: 0;
        /* 44px: this control exists for readers who need larger text, so it is
           the last one that should be hard to hit. */
        width: 44px;
        height: 44px;
        transition: background .12s;
    }
    #text-size button:hover { background: #dcfce7; }
    #text-size button.ts-minus { font-size: 15px; }
    #text-size button.ts-reset { font-size: 15px; }
    #text-size button.ts-plus  { font-size: 20px; }

    .page-content {
        margin-top: 60px;
        padding: 20px;
    }

    /* ── Lesson content type scale (generous for young readers, with a
          clear hierarchy and comfortable line-height for everyone).
          Sizes multiply by --content-scale so the A−/A/A+ widget can grow
          or shrink the whole lesson per learner.
          Selectors are scoped to .page-content so this shared scale also
          overrides the per-page font sizes older lesson templates still
          declare — unifying typography and making them scale too. ─────── */
    .page-content .Title p,
    .page-content .Title h1 {
        text-align: center;
        font-weight: 900;
        font-size: calc(44px * var(--content-scale));
        line-height: 1.2;
        color: var(--text);
        /* The <p> this replaced carried the UA default 1em top margin;
           <h1>'s is 0.67em, so declare it to keep the spacing identical. */
        margin-top: 1em;
        margin-bottom: 40px;
        font-family: var(--font);
    }

    .page-content .Goal p {
        text-align: center;
        font-size: calc(26px * var(--content-scale));
        line-height: 1.45;
        color: var(--muted);
        max-width: 900px;
        margin: 0 auto 30px;
        font-family: var(--font);
    }

    .page-content .Header p,
    .page-content .Header h2 {
        text-align: left;
        font-size: calc(30px * var(--content-scale));
        font-weight: 900;
        color: var(--text);
        max-width: 900px;
        margin: 0 auto 16px;
        font-family: var(--font);
    }

    .page-content .Content p {
        text-align: left;
        font-size: calc(22px * var(--content-scale));
        line-height: 1.6;
        color: var(--text);
        max-width: 900px;
        margin: 0 auto 32px;
        font-family: var(--font);
    }

    /* Equation block — always centered, rendered in a system math/serif
       face so glyphs (∑ ∫ √ α…) and sup/sub read like real notation.
       No web-font dependency: relies on the OS math font, falling back to
       a serif, in keeping with the project's zero-external-asset rule. */
    .page-content .Equation p {
        text-align: center;
        font-size: calc(30px * var(--content-scale));
        line-height: 1.6;
        color: var(--text);
        max-width: 900px;
        margin: 0 auto 32px;
        font-family: "Cambria Math", "STIX Two Math", "Latin Modern Math", Georgia, serif;
    }
    .page-content .Equation sup,
    .page-content .Equation sub { font-size: .72em; }

    /* Layout spans emitted by the content-block editor's inline toolbar —
       unscoped (not under .page-content) so they render identically in
       the editor's live contenteditable preview and on the lesson page. */
    .center-run {
        display: block;
        text-align: center;
    }

    /* Stacked fraction: numerator, a horizontal rule, denominator — built
       from three spans rather than <table>/MathML to stay inline with
       surrounding text (see cbAddEquationBlock's Fraction button). */
    .frac {
        display: inline-flex;
        flex-direction: column;
        align-items: center;
        vertical-align: middle;
        margin: 0 .18em;
        line-height: 1.15;
    }
    .frac-num, .frac-den {
        display: block;
        padding: 0 .2em;
    }
    .frac-line {
        display: block;
        width: 100%;
        height: 0;
        border-top: 1.5px solid currentColor;
        margin: .12em 0;
    }

    /* Equation highlighter — a yellow-marker run, wrapped/unwrapped by the
       Equation block's 🖍 toolbar button (see _eqToggleHighlight). Unscoped
       like .frac so it renders identically in the editor preview and on
       the lesson page. */
    .highlight {
        background: #fef08a;
        border-radius: 3px;
        padding: 0 .15em;
        box-decoration-break: clone;
        -webkit-box-decoration-break: clone;
    }

    .Table {
        max-width: 900px;
        margin: 0 auto;
        margin-bottom: 40px;
    }

    .page-content .Table td, .page-content .Table th {
        font-family: var(--font);
        font-size: calc(22px * var(--content-scale));
        line-height: 1.5;
    }

    .Image {
        max-width: 1000px;
        margin: 0 auto;
        margin-bottom: 40px;
        text-align: center;
    }

    .Image img {
        max-width: 100%;
        border-radius: 8px;
    }

    /* ── Drawing block ────────────────────────────────────────────────────
       A supervisor-authored diagram, stored as a scene of shapes and rendered
       to inline SVG server-side (see core/drawing.py). data-drawing-width is
       the percentage of the column it should occupy; the SVG itself carries a
       viewBox so it scales cleanly to any size. */
    .Drawing {
        max-width: 1000px;
        margin: 0 auto 40px;
        text-align: center;
    }

    /* ── Graph block ──────────────────────────────────────────────────────
       An interactive plotter (core/frontend_assets/graph_runtime.js). The
       author fixes the view; a learner gets the sliders and a hover readout. */
    .GraphBlock {
        max-width: 1000px;
        margin: 0 auto 40px;
        display: flex;
        justify-content: center;
    }
    .graph-host { max-width: 100%; }
    .GraphBlock svg.graph-svg {
        width: 100%;
        height: auto;
        max-width: 100%;
        border-radius: 8px;
        display: block;
    }
    .graph-sliders {
        display: flex;
        flex-direction: column;
        gap: 6px;
        margin: 10px auto 0;
        padding: 10px 12px;
        border: 1.5px solid var(--border, #cbd5e1);
        border-radius: 10px;
        background: var(--surface, #fff);
        font-family: var(--font);
    }
    .graph-slider {
        display: flex;
        align-items: center;
        gap: 10px;
        font-size: 14px;
        font-weight: 700;
        color: var(--text, #1e293b);
    }
    .graph-slider-name { min-width: 92px; }
    .graph-slider input[type="range"] { flex: 1; cursor: pointer; min-width: 110px; }
    .graph-slider-val {
        min-width: 56px;
        text-align: right;
        font-variant-numeric: tabular-nums;
        color: var(--muted, #64748b);
    }
    .graph-readout {
        min-height: 20px;
        margin-top: 6px;
        text-align: center;
        font-family: var(--font);
        font-size: 13px;
        font-weight: 700;
        color: var(--muted, #64748b);
        font-variant-numeric: tabular-nums;
    }
    .graph-reset {
        align-self: flex-start;
        margin-top: 4px;
        padding: 4px 12px;
        font-size: 12px;
        font-weight: 700;
        font-family: var(--font);
        color: var(--muted, #64748b);
        background: none;
        border: 1.5px solid var(--border, #cbd5e1);
        border-radius: 7px;
        cursor: pointer;
    }
    @media (max-width: 640px) {
        .graph-slider { flex-wrap: wrap; gap: 6px; }
        .graph-slider-name { min-width: 0; }
    }

    /* The width percentage is written inline on the <svg> by the renderer
       (same approach as .Image's img), so the block stays centred in the prose
       column at whatever size the author picked. */
    .Drawing svg.drawing-svg {
        height: auto;
        max-width: 100%;
        border-radius: 8px;
    }

    /* Basic-quiz card styling now ships as its own cached stylesheet
       (static/core/css/quiz-page.css), linked by base.html alongside
       this file and by the supervisor's question-preview page. */
    /* ── Narrow screens (phones) ──────────────────────────────────────────
       Tame the large display type so lessons read well on small devices.
       (Back and the review badge are handled by the banner rules above —
       they sit ON the banner here, not under it, so the content no longer
       needs to start below them.) */
    @media (max-width: 640px) {
        .page-content .Title p,
        .page-content .Title h1  { font-size: calc(30px * var(--content-scale)); margin-bottom: 24px; }
        .page-content .Goal p    { font-size: calc(20px * var(--content-scale)); }
        .page-content .Header p,
        .page-content .Header h2 { font-size: calc(24px * var(--content-scale)); }
        .page-content .Content p { font-size: calc(19px * var(--content-scale)); }
        .page-content .Equation p { font-size: calc(24px * var(--content-scale)); }
    }
