/* ============================================================================
   Tutor mode + house-style lesson chrome — static/css/components/tutor-mode.css

   Implements the finalized Tutor UI direction (2026-07-04 design pass,
   docs/superpowers/specs/2026-07-04-ai-course-structure-question-audit-design.md,
   mockup 2026-07-04-tutor-ui-mockups.html):
     - sidebar dot-progress trail (shared by the panel-deck walkthrough AND
       the Tutor) — teal-done / tangerine-current, never a full takeover
     - "Tutor mode" signalled via a badge + a subtle tangerine wash on the
       stage-top strip — NOT a colour-scheme flip, no dark background
       anywhere, and (2026-07-04 owner review) no card border/frame around
       the video/graphic pixel-area itself (that read as boxed/embedded)
     - the Tutor entry sequence (launching -> objective+unit-map intro ->
       guided steps -> chapter-complete recap)
     - the consolidated print/export kebab flyout
     - the gold 5-star self-rating reskin
     - the Questions page difficulty ladder (1-4, teal->cyan->gold->tangerine)

   All colours reference theme.css tokens. No inline styles, no raw hex.
   =========================================================================== */

/* ============================================================ MODE BADGE */

.jm-mode-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-family: var(--jm-font-mono);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    white-space: nowrap;
    color: #fff;
}
.jm-mode-badge.tutor { background: var(--tangerine); }
.jm-mode-badge.walkthrough { background: var(--gold); color: var(--teal-ink); }
.jm-mode-badge .ic { width: 9px; height: 9px; }

/* ============================================================ SIDEBAR: DOT-PROGRESS TRAIL
   Same idiom used inside BOTH an older panel-deck walkthrough and the Tutor —
   the sidebar never disappears, only its content swaps from the free
   jump-list to this locked vertical trail. */

.page-container .slide-sidebar.dot-mode {
    /* Independent of the free jump-list's 188px (page-detail.css) — this is
       a pure dot-trail, no labels, so it only needs to fit the widest thing
       in it (the "TUTOR" mode badge, ~65px) plus the row's own padding.
       Distinct from .compact (52px, a separately-toggled manual state). */
    width: 84px;
    align-items: center;
    padding-top: 0.75rem;
}

.page-container .slide-sidebar.dot-mode .sidebar-slides {
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: visible;
    padding: 0;
}

.jm-dot-badge-row {
    padding: 0 0.5rem 0.75rem;
    width: 100%;
    display: flex;
    justify-content: center;
}

.jm-dot-head {
    font-family: var(--jm-font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.6rem;
    text-align: center;
}

.jm-dot-trail {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.jm-dstep { display: flex; flex-direction: column; align-items: center; }

.jm-dknob {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 3px solid var(--line);
    background: var(--paper);
    flex: none;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.jm-dstep.done .jm-dknob { background: var(--teal); border-color: var(--teal); }
.jm-dstep.now .jm-dknob {
    border-color: var(--tangerine);
    box-shadow: 0 0 0 5px rgba(255, 107, 74, 0.16);
}
.jm-dstep.locked .jm-dknob { opacity: 0.6; }

.jm-dconn { width: 2px; height: 28px; background: var(--line); }
.jm-dconn.done { background: var(--teal); }

.jm-dot-foot {
    margin-top: auto;
    padding: 0.75rem 0 0.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
}

.jm-dfoot-exit {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--mint2);
    color: var(--tangerine);
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    cursor: pointer;
    transition: background 0.15s;
}
.jm-dfoot-exit:hover { background: var(--mint); }

/* ============================================================ SIDEBAR: TUTOR "COMING SOON" SLOT
   Shown in the free jump-list sidebar when a lesson has no walkthrough-type
   LessonContentBlock yet (almost every lesson, 2026-07-04 audit) — an
   intentional placeholder in the slot the Tutor entry would occupy, instead
   of the entry point simply being absent. Not a link, no functional CTA. */

.page-container .sidebar-slide.sidebar-slide-soon {
    /* Own border-radius: page-detail.css's base .sidebar-slide rule no
       longer carries one unconditionally (2026-07-05 fix — radius now only
       applies where a fill/border is actually visible), and this row always
       has a visible dashed border, so it needs to state its own. */
    border-radius: 8px;
    cursor: default;
    color: var(--muted);
    border: 1px dashed var(--tangerine);
    background: var(--mint);
    opacity: 0.8;
}
.page-container .sidebar-slide.sidebar-slide-soon:hover {
    color: var(--muted);
    background: var(--mint);
}
.page-container .sidebar-slide.sidebar-slide-soon .slide-icon {
    background: transparent;
    color: var(--tangerine);
}

.jm-soon-tag {
    font-family: var(--jm-font-mono);
    font-size: 0.55rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--tangerine);
    flex-shrink: 0;
}

.page-container .slide-sidebar.compact .jm-soon-tag {
    display: none;
}

@media (max-width: 768px) {
    .page-container .jm-soon-tag {
        display: none;
    }
}

/* ============================================================ SIDEBAR MOTION
   Direction B — "Motion & micro-interactions"
   (docs/superpowers/mockups/2026-07-04-tutor-ui-mockups.html#sidebar-makeover).
   Owner picked B: keep the calmer cream/mint base (no colour-blocking, no
   gradient rail) — the "poppy" read comes entirely from movement:
     - hover rotates + scales the row icon and slides the row sideways
       (see page-detail.css .sidebar-slide / .slide-icon)
     - the active/"now" icon breathes with a soft continuous pulse
     - a short connecting trail grows in between rows/dots on first render
     - the row list itself has a light staggered fade+slide entrance
   Applied consistently across all three sidebar states: the free jump-list
   (.sidebar-slide, page-detail.css), the panel-deck walkthrough dot-trail,
   and the Tutor dot-trail (.jm-dstep/.jm-dconn, both above) — same motion
   language throughout, not just one state.
   All of it is gated behind prefers-reduced-motion: no-preference; hover
   transform motion is neutralised under prefers-reduced-motion: reduce. */

.jm-dconn { transform-origin: top; }

@media (prefers-reduced-motion: no-preference) {
    /* --- active/now icon: soft continuous pulse --- */
    @keyframes jm-sidebar-icon-pulse {
        0%, 100% { box-shadow: 0 0 0 0 rgba(18, 181, 166, 0.45); }
        50% { box-shadow: 0 0 0 6px rgba(18, 181, 166, 0); }
    }
    .page-container .sidebar-slide.active .slide-icon {
        animation: jm-sidebar-icon-pulse 2.2s ease-in-out infinite;
    }

    @keyframes jm-dot-now-pulse {
        0%, 100% { box-shadow: 0 0 0 4px rgba(255, 107, 74, 0.16); }
        50% { box-shadow: 0 0 0 7px rgba(255, 107, 74, 0.04); }
    }
    .jm-dstep.now .jm-dknob {
        animation: jm-dot-now-pulse 2.2s ease-in-out infinite;
    }

    /* --- connecting trail: grows in between rows/dots on first render --- */
    @keyframes jm-sidebar-trail-grow {
        from { transform: scaleY(0); }
        to { transform: scaleY(1); }
    }
    .page-container .sidebar-slide:not(:first-child)::before,
    .jm-dconn {
        animation: jm-sidebar-trail-grow 0.3s ease-out 150ms both;
    }

    /* --- staggered entrance: rows unfold open from the top, one after
       another. Previous version (opacity + 6px translateY) was too subtle
       to read as motion at all — this is a real "grow open" reveal:
       scaleY from a collapsed sliver up to full height, transform-origin
       pinned to the top edge so each row visibly unfolds downward. */
    @keyframes jm-row-in {
        from { opacity: 0; transform: translateY(-10px) scaleY(0.4); }
        60%  { opacity: 1; }
        to   { opacity: 1; transform: translateY(0) scaleY(1); }
    }
    .page-container .sidebar-slides > .sidebar-slide,
    .page-container .sidebar-slides > .add-slide,
    .jm-dot-trail > .jm-dstep {
        transform-origin: top;
        animation-name: jm-row-in;
        animation-duration: 0.42s;
        animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
        animation-fill-mode: both;
    }
    /* ~35-40ms stagger per row, capped so a long list doesn't take forever */
    .page-container .sidebar-slides > *:nth-child(1) { animation-delay: 0ms; }
    .page-container .sidebar-slides > *:nth-child(2) { animation-delay: 40ms; }
    .page-container .sidebar-slides > *:nth-child(3) { animation-delay: 80ms; }
    .page-container .sidebar-slides > *:nth-child(4) { animation-delay: 120ms; }
    .page-container .sidebar-slides > *:nth-child(5) { animation-delay: 160ms; }
    .page-container .sidebar-slides > *:nth-child(6) { animation-delay: 200ms; }
    .page-container .sidebar-slides > *:nth-child(7) { animation-delay: 240ms; }
    .page-container .sidebar-slides > *:nth-child(8) { animation-delay: 280ms; }
    .page-container .sidebar-slides > *:nth-child(9) { animation-delay: 320ms; }
    .page-container .sidebar-slides > *:nth-child(10) { animation-delay: 360ms; }
    .page-container .sidebar-slides > *:nth-child(n+11) { animation-delay: 400ms; }

    .jm-dot-trail > .jm-dstep:nth-child(1) { animation-delay: 0ms; }
    .jm-dot-trail > .jm-dstep:nth-child(3) { animation-delay: 40ms; }
    .jm-dot-trail > .jm-dstep:nth-child(5) { animation-delay: 80ms; }
    .jm-dot-trail > .jm-dstep:nth-child(7) { animation-delay: 120ms; }
    .jm-dot-trail > .jm-dstep:nth-child(9) { animation-delay: 160ms; }
    .jm-dot-trail > .jm-dstep:nth-child(11) { animation-delay: 200ms; }
    .jm-dot-trail > .jm-dstep:nth-child(13) { animation-delay: 240ms; }
    .jm-dot-trail > .jm-dstep:nth-child(15) { animation-delay: 280ms; }
    .jm-dot-trail > .jm-dstep:nth-child(17) { animation-delay: 320ms; }
    .jm-dot-trail > .jm-dstep:nth-child(19) { animation-delay: 360ms; }
    .jm-dot-trail > .jm-dstep:nth-child(n+21) { animation-delay: 400ms; }

    /* --- main content entrance: the page body had no load animation at
       all (unlike the sidebar above) — cards used to just appear. A
       slower, clearly-visible fade+slide-up on the worked-example/theory
       panel(s) and, for the Questions page, a per-card stagger so the
       list visibly builds in rather than popping in all at once. */
    @keyframes jm-card-in {
        from { opacity: 0; transform: translateY(18px); }
        to   { opacity: 1; transform: translateY(0); }
    }
    .page-container .split-panel > .panel,
    .page-container .single-panel > .panel {
        animation: jm-card-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
    }
    .page-container .split-panel > .panel:nth-child(2) {
        animation-delay: 90ms;
    }
    .q-card {
        animation: jm-card-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
    }
    .q-card:nth-child(1) { animation-delay: 0ms; }
    .q-card:nth-child(2) { animation-delay: 70ms; }
    .q-card:nth-child(3) { animation-delay: 140ms; }
    .q-card:nth-child(4) { animation-delay: 210ms; }
    .q-card:nth-child(5) { animation-delay: 280ms; }
    .q-card:nth-child(n+6) { animation-delay: 350ms; }
}

@media (prefers-reduced-motion: reduce) {
    .page-container a.sidebar-slide:hover,
    .page-container .sidebar-slide:hover,
    .page-container a.sidebar-slide:hover .slide-icon,
    .page-container .sidebar-slide:hover .slide-icon {
        transform: none;
    }
}

/* connecting trail line itself — a subtle 2px filament in the icon gutter
   linking consecutive rows, growing in on first render (keyframe above).
   Neutral --line colour: the normal jump-list is free browsing, not a
   locked sequence, so this is a decorative "journey" cue, not a done/now
   progress read (that meaning stays reserved for .jm-dconn below). */
.page-container .sidebar-slide:not(:first-child)::before {
    content: "";
    position: absolute;
    left: 22px;
    top: -4px;
    width: 2px;
    height: 6px;
    background: var(--line);
    z-index: 0;
    pointer-events: none;
}

/* the "Coming Soon" slot (above) is deliberately non-interactive
   (aria-disabled, cursor: default, no colour shift on hover) — don't let
   the new generic hover motion make it read as clickable. */
.page-container .sidebar-slide.sidebar-slide-soon:hover,
.page-container .sidebar-slide.sidebar-slide-soon:hover .slide-icon {
    transform: none;
}

/* ============================================================ TUTOR STAGE
   "Tutor mode" = a small mode badge + a subtle tangerine wash on the stage-top
   strip only — never a colour-scheme flip, never a dark background, and
   (2026-07-04 owner review) never a card border/frame around the video
   itself. A hard border + card background wrapping the whole stage read as
   a boxed/embedded video rather than something native to the page, so the
   signal now lives entirely in the chrome above the video, not around it. */

.jm-tutor-stagewrap {
    /* Containing block for the absolutely-positioned launching spinner and
       exit-confirmation popover (both position:absolute; inset:0 below) —
       without this they escape to the viewport instead of covering just the
       Tutor stage. Doesn't affect the cine-bar controls: those already have
       their own nearer positioned ancestor, .wt-cine-stage. */
    position: relative;
    padding: 0.75rem;
}

/* Tutor Mode breaks out of the shared 10px-inset rounded-card frame
   (page-detail.css .page-body — deliberate for every OTHER block type,
   see its comment) so the stage runs edge-to-edge like the header, same
   idea as the teal top bar: launching Tutor should feel like entering a
   separate, immersive experience, not another bordered card on the page. */
.page-container .page-body.tutor-mode-body {
    margin: 0;
    border: none;
    border-radius: 0;
    box-shadow: none;
}

/* "Tutor mode" + step count both live in the top bar's .header-center now —
   no stage-top strip. */
.jm-header-tutor-label {
    /* Was --tangerine (orange) on the teal header gradient — the two have
       almost no luminance difference, so it read as low-contrast/hard to
       read. Every other header label on this bar uses plain white. */
    font-family: var(--jm-font-mono);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #fff;
    white-space: nowrap;
}

.jm-tutor-step-count {
    font-family: var(--jm-font-mono);
    font-size: 0.68rem;
    color: var(--muted);
    white-space: nowrap;
}

/* The video/graphic pixel-area itself is transparent — it shows the page's
   own background straight through, so there is no seam/rectangle around the
   rendered clip or SVG (see manim/jmaths_brand.py CINEMA_BG, which matches
   the page background the clip is composited onto). Never dark, even inside
   "Tutor mode". */
.jm-tutor-stagewrap .wt-graphic-panel,
.jm-tutor-stagewrap .wt-cine-stage {
    background: transparent;
    border-radius: 10px;
}

/* ============================================================ TUTOR ENTRY SEQUENCE */

.jm-tutor-launching {
    position: absolute;
    inset: 0;
    background: rgba(251, 250, 245, 0.92);
    backdrop-filter: blur(1.5px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    z-index: 20;
}
.jm-tutor-launching .jm-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--teal), var(--teal-deep));
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--jm-font-display);
    font-weight: 800;
    font-size: 1.1rem;
}
.jm-tutor-launching b {
    font-family: var(--jm-font-display);
    font-size: 0.95rem;
    color: var(--ink);
}
.jm-tutor-launching span {
    font-family: var(--jm-font-mono);
    font-size: 0.68rem;
    color: var(--teal-deep);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.jm-spin {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 3px solid var(--mint2);
    border-top-color: var(--teal);
}
@media (prefers-reduced-motion: no-preference) {
    .jm-spin { animation: jm-spin 0.9s linear infinite; }
}
@keyframes jm-spin { to { transform: rotate(360deg); } }

/* Same "signal via chrome, not a box" principle as .jm-tutor-stagewrap above
   (2026-07-04 owner review) — this screen is content sitting on the page,
   not a modal dialog, so no card background/border/shadow wrapping it. */
.jm-tutor-intro {
    /* .single-panel (page-detail.css) is display:flex on this element's
       parent, so as a flex item it defaults to shrink-to-fit content width
       (flex-basis:auto) instead of filling the row — max-width/margin:auto
       alone center a box that never reaches that max-width. width:100%
       makes it claim the row first, then the cap centers it correctly. */
    width: 100%;
    padding: 1.5rem 0;
    max-width: 640px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.jm-tutor-intro h2 {
    font-family: var(--jm-font-display);
    font-size: 1.35rem;
    color: var(--ink);
    margin: 0;
}
.jm-tutor-intro .jm-intro-eyebrow {
    font-family: var(--jm-font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--teal-deep);
    background: var(--mint);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 0.2rem 0.6rem;
    width: fit-content;
}

/* White + hairline-divider rows, matching the real Learning Objectives
   page's flat-list treatment (page-detail-blocks.css .objective-item) —
   was a solid mint-filled box with no code chip, which read as a
   different design language for the same content. */
.jm-objcard {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 0.75rem 0.9rem;
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
}
.jm-objcard .ic-badge {
    width: 26px;
    height: 26px;
    flex: none;
    border-radius: 7px;
    background: var(--mint2);
    color: var(--teal-deep);
    display: flex;
    align-items: center;
    justify-content: center;
}
.jm-objcard-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--color-border-light);
}
.jm-objcard-row:last-child { border-bottom: none; }
.jm-objcard b { font-family: var(--jm-font-display); font-size: 0.9rem; color: var(--ink); font-weight: 600; flex: 1; }
.jm-objcard span.jm-mini-stars { flex: none; }

.jm-unit-row {
    display: flex;
    gap: 0.9rem;
    overflow-x: auto;
    padding: 0.4rem 0.1rem 0.6rem;
}
.jm-unit-node {
    flex: 0 0 68px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    text-align: center;
}
.jm-unit-node .jm-und {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--paper);
    border: 2px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--jm-font-mono);
    font-weight: 700;
    font-size: 0.7rem;
    color: var(--muted);
}
.jm-unit-node.done .jm-und { background: var(--teal); border-color: var(--teal); color: #fff; }
.jm-unit-node.now .jm-und {
    border-color: var(--tangerine);
    color: var(--tangerine);
    box-shadow: 0 0 0 4px rgba(255, 107, 74, 0.15);
}
.jm-unit-node small { font-size: 0.65rem; color: var(--muted); line-height: 1.25; }
.jm-unit-node.now small { color: var(--ink); font-weight: 700; }

.jm-tutor-begin-row { display: flex; justify-content: flex-end; gap: 0.6rem; }
.jm-tutor-begin {
    background: var(--teal);
    color: #fff;
    border: none;
    font-weight: 700;
    font-size: 0.9rem;
    padding: 0.65rem 1.3rem;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    box-shadow: var(--shadow);
}
.jm-tutor-begin:hover { filter: brightness(1.05); }

/* ============================================================ CHAPTER COMPLETE RECAP */

.jm-tutor-complete {
    /* Same flex-item shrink-to-fit issue as .jm-tutor-intro above (both are
       siblings under .single-panel's display:flex) — width:100% lets this
       actually reach max-width and center, instead of hugging its content. */
    width: 100%;
    background: linear-gradient(180deg, var(--mint2), var(--mint) 60%, var(--cream));
    border: 2px solid var(--teal);
    border-radius: 14px;
    padding: 2rem 1.5rem;
    max-width: 560px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.7rem;
}
.jm-tutor-complete .jm-ring {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: 2px solid var(--teal);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--teal-deep);
    box-shadow: 0 0 0 8px rgba(18, 181, 166, 0.12);
}
.jm-tutor-complete .jm-sub {
    font-family: var(--jm-font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--teal-deep);
}
.jm-tutor-complete h3 { font-family: var(--jm-font-display); font-size: 1.25rem; color: var(--ink); margin: 0; }
.jm-tutor-complete p { font-size: 0.9rem; color: var(--muted); max-width: 40ch; }
.jm-recap-chips { display: flex; gap: 0.4rem; flex-wrap: wrap; justify-content: center; margin: 0.2rem 0; }
.jm-recap-chip {
    font-family: var(--jm-font-mono);
    font-size: 0.68rem;
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    background: var(--paper);
    border: 1px solid var(--line);
    color: var(--teal-deep);
}
.jm-complete-doors { display: flex; gap: 0.6rem; margin-top: 0.4rem; }
.jm-door-go, .jm-door-alt {
    font-size: 0.85rem;
    font-weight: 700;
    padding: 0.6rem 1.1rem;
    border-radius: 9px;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.jm-door-go { background: var(--teal); color: #fff; }
.jm-door-go:hover { color: #fff; filter: brightness(1.05); }
.jm-door-alt { background: transparent; border: 1px solid var(--line); color: var(--muted); }
.jm-door-alt:hover { color: var(--ink); border-color: var(--teal-deep); }

/* ============================================================ EXIT CONFIRMATION (light) */

.jm-exit-popover {
    position: absolute;
    inset: 0;
    background: rgba(251, 250, 245, 0.88);
    backdrop-filter: blur(1.5px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 30;
}
.jm-exit-card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 1.25rem 1.4rem;
    max-width: 320px;
    text-align: center;
    box-shadow: var(--shadow);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
}
.jm-exit-card .ic-badge {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--mint);
    color: var(--teal-deep);
    display: flex;
    align-items: center;
    justify-content: center;
}
.jm-exit-card b { font-family: var(--jm-font-display); font-size: 1rem; color: var(--ink); }
.jm-exit-card p { font-size: 0.85rem; color: var(--muted); }
.jm-exit-actions { display: flex; gap: 0.5rem; margin-top: 0.2rem; }
.jm-exit-stay {
    font-size: 0.8rem; font-weight: 700; padding: 0.5rem 0.9rem; border-radius: 8px;
    border: 1px solid var(--teal); color: var(--teal-deep); background: var(--paper); cursor: pointer;
}
.jm-exit-leave {
    font-size: 0.8rem; font-weight: 700; padding: 0.5rem 0.9rem; border-radius: 8px;
    border: none; background: var(--tangerine); color: #fff; cursor: pointer;
}

/* ============================================================ GOLD 5-STAR SELF-RATING
   Reskinned in house-style gold, echoed as a compact readout on the Tutor's
   objective + unit-map intro screen. */

.page-container .star-btn.filled,
.page-container .star-btn:hover,
.page-container .star-rating:hover .star-btn:hover,
.page-container .star-rating:hover .star-btn:hover ~ .star-btn {
    color: var(--gold);
}

.jm-mini-stars { display: inline-flex; align-items: center; gap: 0.15rem; }
.jm-mini-stars .fa-star { font-size: 0.7rem; color: var(--line); }
.jm-mini-stars .fa-star.on { color: var(--gold); }

/* ============================================================ PRINT/EXPORT KEBAB
   Consolidates the toolbar into one icon + flyout: an unchanged "Print"
   section and a new "Export" section marked "Optional" — PDF/PNG rows
   grey out to an "unavailable" state pointing back at Print when the
   (unbuilt) backend isn't available. */

.page-container .export-kebab { position: relative; }

.page-container .export-flyout {
    position: absolute;
    top: 34px;
    right: 0;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--shadow);
    padding: 0.4rem;
    min-width: 190px;
    z-index: 60;
    text-align: left;
    display: none;
}
.page-container .export-kebab.open .export-flyout { display: block; }
[data-sidebar-position="right"] .page-container .export-flyout,
.page-container .export-flyout.align-left { right: auto; left: 0; }

.page-container .export-flyout .fly-sec {
    font-family: var(--jm-font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    padding: 0.35rem 0.45rem 0.15rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.page-container .export-flyout .fly-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.45rem;
    border-radius: 7px;
    font-size: 0.8rem;
    color: var(--ink);
    cursor: pointer;
    background: none;
    border: none;
    width: 100%;
    text-align: left;
}
.page-container .export-flyout .fly-item:hover { background: var(--mint); }
.page-container .export-flyout .fly-item .ic-badge {
    width: 20px;
    height: 20px;
    border-radius: 5px;
    background: var(--mint2);
    color: var(--teal-deep);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    font-size: 0.7rem;
}
.page-container .export-flyout hr { border: none; border-top: 1px solid var(--line); margin: 0.3rem 0; }

.page-container .export-flyout .opt-tag {
    background: var(--mint2);
    color: var(--teal-deep);
    font-family: var(--jm-font-mono);
    font-size: 0.58rem;
    font-weight: 700;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

.page-container .export-flyout .fly-item.disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

.page-container .export-flyout .fly-warn {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    background: var(--mint);
    border: 1px solid var(--line);
    color: var(--muted);
    border-radius: 7px;
    padding: 0.45rem 0.5rem;
    margin-top: 0.3rem;
    font-size: 0.68rem;
    line-height: 1.4;
}
.page-container .export-flyout .fly-warn i { margin-top: 0.1rem; flex: none; color: var(--gold); }

/* ============================================================ QUESTIONS PAGE
   Static-course surface, NOT gated behind the Tutor. A 1-4 difficulty
   ladder doubles as a filter; answers reveal via the same shade-overlay
   pattern already used for worked examples. */

.q-page-head { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 0.75rem; }
.q-page-meta { font-family: var(--jm-font-mono); font-size: 0.7rem; color: var(--muted); }

.q-ladder { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.5rem 0 1rem; }
.q-lchip {
    font-family: var(--jm-font-mono);
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.35rem 0.75rem;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--paper);
    color: var(--muted);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    cursor: pointer;
    text-decoration: none;
}
.q-lchip:hover { border-color: var(--teal); color: var(--ink); }
.q-lchip .ldot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.q-lchip.active { background: var(--teal-deep); color: #fff; border-color: var(--teal-deep); }

/* Never red — colourblind-safe teal -> cyan -> gold -> tangerine ladder */
.q-level-1 { background: var(--teal); }
.q-level-2 { background: var(--cyan); }
.q-level-3 { background: var(--gold); color: var(--teal-ink); }
.q-level-4 { background: var(--tangerine); }

/* Flat rows, not per-card boxes — matches the objectives list: the page
   already has one shared frame (.page-body) around sidebar+content, so
   individual bordered/radiused cards on top of that read as nested
   boxes. A hairline divider does the same separation job. */
.q-card {
    padding: 0.9rem 0.25rem;
    border-bottom: 1px solid var(--color-border-light);
}
#q-all .q-card:last-child,
[id^="q-level-"] .q-card:last-child {
    border-bottom: none;
}
.q-card-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.4rem; }
.q-level-badge {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--jm-font-mono);
    font-size: 0.75rem;
    font-weight: 800;
    color: #fff;
    flex: none;
}
.q-card-label { font-family: var(--jm-font-display); font-weight: 700; font-size: 0.9rem; color: var(--ink); }
.q-card-marks { font-family: var(--jm-font-mono); font-size: 0.68rem; color: var(--muted); margin-left: auto; }

/* The stem (.panel-content above this) is always visible — only the answer,
   scoped to this wrapper, sits behind the shade. .shade-overlay is
   position:absolute against its nearest positioned ancestor (normally
   .panel-body, shared across a whole panel) — each card needs its OWN
   positioned wrapper so the shade covers just this card's answer, not the
   entire Questions list. */
.q-answer-wrap { position: relative; }
.q-answer-wrap .panel-content { padding: 0.75rem 0; }
/* Collapsed until revealed: the hidden solution's full height must not
   reserve a big blank block under short questions — the card tracks its
   visible content and only expands when the answer is opened. */
.q-answer-wrap.q-collapsed { height: 96px; overflow: hidden; }
.q-answer-wrap.q-collapsed .shade-overlay { padding-top: 1.25rem; }
.q-card-empty {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--muted);
    background: var(--mint);
    border: 1px dashed var(--line);
    border-radius: 12px;
}
