/* File preview / viewer modal styles (used by js/review-layer.js). */
    /* =====================================================================
       PENDING-FILE VIEWER + MERGER FILTERS (additive, CSS only). Tokens only,
       so Midnight + Matinee both work. Matches the selector / loader layers.
       ===================================================================== */

    /* ---- "View file" button inside each pending row ---- */
    html[data-theme] #pendingQueueList > div > div:last-child { flex-wrap: wrap; }
    html[data-theme] .pv-view-btn {
      box-sizing: border-box; display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
      padding: 6px 14px; border-radius: 12px; font-size: 12px; font-weight: 600;
      font-family: var(--font-display); letter-spacing: 0.03em;
      background-color: var(--surface-2); color: var(--thumb-ink);
      border: var(--border-w) solid var(--thumb-line);
    }
    html[data-theme] .pv-view-btn > span { font-family: var(--font-mono); font-size: 11px; color: var(--accent-4); }
    html[data-theme="midnight"] .pv-view-btn { background-color: var(--thumb); box-shadow: var(--chip-shadow); }
    html[data-theme="matinee"] .pv-view-btn { background-color: #FFFFFF; color: #111315; border-color: #111315; box-shadow: 2px 2px 0 #111315; }
    html[data-theme="matinee"] .pv-view-btn > span { color: var(--accent-1); }
    html[data-theme] .pv-view-btn:hover { transform: translateY(-1px); filter: none; }
    html[data-theme="matinee"] .pv-view-btn:hover { transform: translate(1px, 1px); box-shadow: 1px 1px 0 #111315; }

    /* ---- viewer ---- */
    html.pv-lock { overflow: hidden; }
    #pvScrim { position: fixed; inset: 0; z-index: 1000; background: var(--overlay); display: none; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
    #pvScrim.on { display: block; animation: pvFade 220ms var(--ease) both; }
    #pvModal {
      position: fixed; z-index: 1001; inset: 0; margin: auto; display: none; flex-direction: column;
      width: min(940px, calc(100vw - 24px)); height: min(calc(100vh - 24px), 860px); height: min(calc(100dvh - 24px), 860px);
      background-color: var(--surface-solid); color: var(--text);
      border: var(--border); border-radius: 22px; overflow: hidden; box-shadow: var(--shadow-hover);
    }
    html[data-theme="matinee"] #pvModal { box-shadow: 6px 6px 0 #111315; }
    #pvModal.on { display: flex; animation: pvIn 280ms var(--ease) both; }
    @keyframes pvFade { from { opacity: 0; } to { opacity: 1; } }
    @keyframes pvIn { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: none; } }

    #pvModal .pv-head {
      display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex: none;
      padding: 14px 14px 12px 18px; border-bottom: var(--border); background-color: var(--surface-2);
    }
    #pvModal .pv-eyebrow { display: block; font: 600 10px/1 var(--font-mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--eyebrow); margin-bottom: 7px; }
    #pvModal .pv-title { font-family: var(--font-mono); font-weight: 700; font-size: 1.1rem; line-height: 1.2; word-break: break-word; margin: 0; }
    #pvModal .pv-path { margin: 6px 0 0; font: 500 10.5px/1.5 var(--font-mono); letter-spacing: 0.03em; color: var(--text-dim); word-break: break-word; }
    #pvModal .pv-x {
      flex: none; width: 38px; height: 38px; border-radius: 12px; cursor: pointer;
      background: var(--surface-2); color: var(--text-dim); border: 1px solid var(--border-color); font-size: 13px;
    }
    html[data-theme="matinee"] #pvModal .pv-x { border: 2px solid #111315; background: #fff; color: #111315; box-shadow: 2px 2px 0 #111315; }

    #pvModal .pv-stage { position: relative; flex: 1 1 auto; min-height: 220px; background-color: var(--code-bg); }
    #pvModal .pv-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #fff; }
    #pvModal .pv-stage.pv-empty .pv-frame { display: none; }
    #pvModal .pv-state {
      position: absolute; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
      padding: 24px; text-align: center; color: #E6EAF2; pointer-events: none;
      font: 600 11px/1.5 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase;
    }
    #pvModal .pv-state.on { display: flex; }
    #pvModal .pv-state.pv-msg { pointer-events: auto; letter-spacing: 0.04em; text-transform: none; font-weight: 500; font-size: 13px; max-width: 440px; margin: 0 auto; }
    #pvModal .pv-needle {
      width: 22px; height: 22px; border-radius: 50%; border: 2px solid rgba(230, 234, 242, 0.55);
      background: linear-gradient(45deg, transparent 44%, #10B981 44% 56%, transparent 56%);
      animation: needleSpin 1.1s linear infinite;
    }

    #pvModal .pv-meta { flex: none; padding: 12px 18px 4px; display: flex; flex-direction: column; gap: 8px; max-height: 28vh; overflow-y: auto; }
    #pvModal .pv-chips { display: flex; flex-wrap: wrap; gap: 6px; }
    #pvModal .pv-chip {
      padding: 4px 9px; border-radius: 999px; border: 1px solid var(--border-color); background: var(--surface-2);
      font: 600 10px/1.2 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim);
    }
    #pvModal .pv-chip.pv-type { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn-text); }
    #pvModal .pv-topics { margin: 0; font-size: 13px; line-height: 1.45; color: var(--text); }
    #pvModal .pv-topics b { font: 600 10px/1 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase; color: var(--eyebrow); margin-right: 6px; }
    #pvModal .pv-note { margin: 0; font-size: 12px; font-weight: 600; color: var(--bad-text); }
    #pvModal .pv-hint { margin: 0; font: 500 10.5px/1.5 var(--font-mono); letter-spacing: 0.03em; color: var(--text-faint); }

    #pvModal .pv-actions {
      flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px;
      padding: 12px 18px calc(14px + env(safe-area-inset-bottom, 0px)); border-top: var(--border);
    }
    #pvModal .pv-btn {
      box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 42px; padding: 8px 16px;
      border-radius: 14px; cursor: pointer; text-decoration: none; white-space: nowrap;
      font-family: var(--font-display); font-weight: 600; font-size: 13px; letter-spacing: 0.03em;
      border: var(--border-w) solid var(--border-color); background: var(--surface-2); color: var(--text);
    }
    #pvModal .pv-btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
    #pvModal .pv-open { margin-right: auto; border-color: var(--thumb-line); color: var(--thumb-ink); background-color: var(--thumb); }
    html[data-theme="matinee"] #pvModal .pv-open { background-color: #FFFFFF; color: #111315; border-color: #111315; box-shadow: 3px 3px 0 #111315; }
    #pvModal .pv-ok { background-color: #F0FDF4; color: #047857; border-color: #10B981; box-shadow: var(--btn-shadow); }
    html[data-theme="midnight"] #pvModal .pv-ok { box-shadow: 0 0 18px -6px rgba(16, 185, 129, 0.7); }
    #pvModal .pv-no { background-color: var(--bad); color: var(--bad-fg); border-color: var(--bad-line); box-shadow: var(--btn-shadow); }
    html[data-theme="midnight"] #pvModal .pv-no { box-shadow: 0 0 18px -6px rgba(244, 63, 94, 0.7); }
    #pvModal .pv-btn:hover { transform: translateY(-1px); }
    #pvModal .pv-ok:active, #pvModal .pv-no:active { transform: scale(0.94) skewX(-5deg); transition-duration: 70ms; }
    #pvModal .pv-btn[hidden] { display: none; }

    /* Full screen: the viewer fills the whole screen (real Fullscreen API where the browser allows it,
       this class everywhere, so phones that block it - iPhone - still get the same full-screen view). */
    #pvModal.pv-max, #pvModal:fullscreen {
      inset: 0; width: 100vw; height: 100vh; height: 100dvh; max-width: none; margin: 0;
      border: 0; border-radius: 0; box-shadow: none;
    }
    #pvModal.pv-max .pv-meta { display: none; }
    #pvModal.pv-max .pv-head { padding-top: calc(10px + env(safe-area-inset-top, 0px)); padding-bottom: 10px; }
    #pvModal.pv-max .pv-eyebrow, #pvModal.pv-max .pv-path { display: none; }
    #pvModal.pv-max .pv-actions { padding-top: 8px; padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }

    @media (max-width: 639px) {
      #pvModal { inset: auto 0 0 0; width: 100%; height: 94vh; height: 94dvh; border-radius: 22px 22px 0 0; margin: 0; }
      #pvModal.on { animation-name: pvSheet; }
      #pvModal .pv-actions .pv-btn { flex: 1 1 calc(50% - 10px); }
      #pvModal .pv-actions .pv-open { flex-basis: 100%; margin-right: 0; order: -1; }
      #pvModal.pv-max .pv-actions .pv-open { display: none; }   /* full screen: just Download + Exit, more room for the file */
      #pvModal.pv-max { border-radius: 0; }
    }
    @keyframes pvSheet { from { opacity: 0; transform: translateY(32px); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) {
      #pvModal.on, #pvScrim.on { animation: none; }
      #pvModal .pv-needle { animation: none; }
    }

    /* ---- merger: Subject + Course filter ---- */
    .mg-hide { display: none !important; }

    /* ---- Reusable motion helpers (Course Structure editor, modals, anything new) ----
       anim-in   : fades + slides a card/row in when it's added
       anim-pop  : a small scale-in for chips
       anim-out  : played by animateOut(el) right before an element is removed */
    @keyframes dnIn  { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
    @keyframes dnPop { from { opacity: 0; transform: scale(0.85); } to { opacity: 1; transform: none; } }
    @keyframes dnOut { to { opacity: 0; transform: scale(0.92); } }
    .anim-in  { animation: dnIn 240ms var(--ease) both; }
    .anim-pop { animation: dnPop 200ms var(--ease) both; }
    .anim-out { animation: dnOut 160ms ease-in forwards; pointer-events: none; }
    #batchModal.flex > div, #fileModal.flex > div { animation: dnIn 240ms var(--ease) both; }
    @media (prefers-reduced-motion: reduce) {
      .anim-in, .anim-pop, .anim-out, #batchModal.flex > div, #fileModal.flex > div { animation: none !important; }
    }
    #mergeFilterBar { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 10px; }
    @media (max-width: 459px) { #mergeFilterBar { grid-template-columns: 1fr; } }
    html[data-theme] #mergeFilterBar > div {
      background-color: var(--surface-2); border: 1px solid var(--border-color);
      border-radius: var(--r-tile); padding: 10px 12px 12px; min-width: 0;
    }
    html[data-theme] #mergeFilterBar > div:focus-within {
      border-color: var(--focus); box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 18%, transparent);
    }
    html[data-theme] #mergeFilterBar > div > .tsel-label { margin-bottom: 6px; }
    html[data-theme] #mergeGroupNote {
      margin: 0 0 12px; font: 500 10.5px/1.55 var(--font-mono); letter-spacing: 0.05em; color: var(--text-dim);
    }
    html[data-theme] #mergeGroupNote b { color: var(--eyebrow); font-weight: 700; }

    /* ---- leftover colours from newer panels, mapped onto the tokens ---- */
    html[data-theme] .border-rose-200 { border-color: var(--bad-line); }
    html[data-theme] .text-rose-500 { color: var(--bad-text); }
    html[data-theme] .bg-white\/70 { background-color: var(--surface-2); }
    html[data-theme] .border-indigo-200\/60 { border-color: var(--primary-line); }
    html[data-theme] .bg-purple-600 { background-color: var(--accent-3); }
    html[data-theme] :is(.hover\:text-rose-600, .hover\:text-rose-700):hover { color: var(--bad-text); }
    html[data-theme] :is(.hover\:text-indigo-600, .hover\:text-indigo-700):hover { color: var(--link); }

    /* ---- Course Structure editor: dropdown row + course chips ---- */
    html[data-theme] #structSemSelect ~ .tsel, html[data-theme] #structCopyFromSelect ~ .tsel { flex: 0 1 auto; }
    html[data-theme] #structOverrideBadge { font-family: var(--font-mono); letter-spacing: 0.06em; border-radius: var(--r-pill); }
    html[data-theme] #structSubjectRows > div { border-radius: var(--r-tile); }
    html[data-theme] #structSubjectRows :is([data-rm-course], [data-add-course], input[data-new-course]) {
      font-family: var(--font-mono); letter-spacing: 0.05em; min-height: 32px;
    }
    html[data-theme] #structSubjectRows [data-add-course] { border-color: var(--text-faint); color: var(--text-dim); }
    html[data-theme="matinee"] #structSubjectRows :is([data-rm-course], [data-add-course]) { box-shadow: 2px 2px 0 #111315; }

    /* ---- Join Class: known batch codes as chips ---- */
    html[data-theme] #batchKnownList > button {
      min-height: 36px; padding: 6px 12px; border-radius: 12px;
      background-color: var(--field); color: var(--text); border: var(--border-w) solid var(--border-color);
      font: 600 11.5px/1.15 var(--font-mono); letter-spacing: 0.05em;
    }
    html[data-theme] #batchKnownList > button:hover { border-color: var(--primary-line); filter: none; }
    html[data-theme="matinee"] #batchKnownList > button { box-shadow: 2px 2px 0 #111315; }
