  /* ============================================================
     CASE FILE — detective evidence-desk theme
     Warm paper, typewriter + serif type, stamp-red accents.
     Every selector matches the DOM built by game-*.js; visual
     retheme only — layout mechanics (zoom/pan clipping, metrics
     rail flex, touch-action) are behavior and must not change.
     ============================================================ */

  *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

  /* --- Self-hosted fonts (game/fonts/) — no CDN; prod may run offline --- */
  @font-face {
    font-family: 'Special Elite';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/special-elite-v20-latin-regular.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Lora';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/lora-v37-latin-regular.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Lora';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/lora-v37-latin-italic.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Lora';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/lora-v37-latin-700.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Courier Prime';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/courier-prime-v11-latin-regular.woff2') format('woff2');
  }
  @font-face {
    font-family: 'Courier Prime';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/courier-prime-v11-latin-700.woff2') format('woff2');
  }

  :root {
    /* Admin controls still reference these palette tokens inline. */
    --bg: #f3eee0;             /* desk paper */
    --card: #fcf9f0;           /* file-folder paper */
    --paper-bright: #fffefa;   /* photo mat / inputs */
    --text: #2b2115;           /* iron-gall ink */
    --text-muted: #756a57;     /* faded pencil — REQ-1474: was #857863, which computed 4.10:1 on
                                  --card and failed AA at the 10-13px sizes it is used at
                                  (.stat-label, .level-name, #admin-timing-summary). This is the
                                  lightest step down the same hue that clears 4.5:1 on ALL THREE
                                  papers — --card 5.04, --bg 4.58, --paper-bright 5.26 — so the
                                  token stays safe wherever it lands, and still reads as a faded
                                  second voice against --text (14.99:1). */
    --border: #ddd3ba;         /* ruled line */
    --accent: #b23a25;         /* stamp red */
    --accent-light: #d0684f;   /* worn stamp red */
    --success: #33714e;        /* fountain-pen green */
    --error: #b23a25;          /* grease-pencil red */
    --amber: #a2790d;          /* pencil amber reference; gold sparks and streak ticks */
    --plum: #6d4a80;           /* plum ink — reconstruct action in the metrics rail */
    --steel: #3a5f8a;          /* steel-blue ink — the toolbar's "view swap" family (REQ-1473) */
    --teal: #23697a;           /* metrics teal ink */
    /* Hard offset shadows: stacked-paper look, no blur */
    --shadow: 3px 3px 0 rgba(43, 33, 21, 0.14);
    --shadow-lg: 6px 6px 0 rgba(43, 33, 21, 0.16);
    --radius: 3px;
    --font: 'Lora', Georgia, 'Times New Roman', serif;
    --font-display: 'Special Elite', 'Courier New', monospace;
    --font-mono: 'Courier Prime', 'Courier New', monospace;
  }

  /* REQ-1165: page-level only — stop pull-to-refresh / overscroll glow from wiping an
     in-progress run. Scoped to html/body so it never touches the REQ-850 canvas
     touch-action rules (.zoom-layer / .image-panel canvas keep pan-x pan-y). This only
     affects scroll-chaining at the page boundary; one-finger scroll of a tall layout
     still works. Double-tap/pinch page-zoom stays suppressed by the viewport meta. */
  html, body {
    overscroll-behavior: none;
  }

  /* Public frames hand ordinary scrolling to their article. The existing navigation control
     identifies a resolved public player; standalone, editorial and native fullscreen keep their
     page-boundary protection. Photo zoom/pan and the album's own scroll rules stay independent. */
  html:has([data-game-open-full-page]):not(:has(:fullscreen)),
  body:has([data-game-open-full-page]):not(:has(:fullscreen)) {
    overscroll-behavior: auto;
  }

  body:has([data-game-open-full-page]):not(:has(:fullscreen)) .daily-core-loop-puzzle .image-panel:not(.is-zoomed),
  body:has([data-game-open-full-page]):not(:has(:fullscreen)) .daily-core-loop-puzzle .image-panel:not(.is-zoomed) .zoom-layer,
  body:has([data-game-open-full-page]):not(:has(:fullscreen)) .daily-core-loop-puzzle .image-panel:not(.is-zoomed) canvas {
    touch-action: pan-x pan-y;
  }

  body {
    font-family: var(--font);
    /* Bright paper with a visible top-center spotlight and a faint edge vignette */
    background:
      radial-gradient(110% 80% at 50% 0%, #ffffff 0%, rgba(255, 255, 255, 0.55) 35%, rgba(255,255,255,0) 65%),
      radial-gradient(140% 120% at 50% 115%, rgba(94, 75, 45, 0.08), rgba(0,0,0,0) 50%),
      var(--bg);
    background-attachment: fixed;
    color: var(--text);
    min-height: 100vh;
    overflow-x: hidden;
  }

  /* Film-grain overlay across the whole desk — sits above everything at very
     low opacity; pointer-events:none so it never intercepts clicks. */
  body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 3000;
    pointer-events: none;
    opacity: 0.035;
    mix-blend-mode: multiply;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  .detective-game {
    margin: 0 auto;
    padding: 20px;
    position: relative;
  }

  .game-audio-settings { position: relative; }
  .game-audio-settings summary { list-style: none; }
  .game-audio-settings summary::-webkit-details-marker { display: none; }
  .game-audio-settings-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 30;
    width: min(260px, calc(100vw - 32px));
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--paper-bright);
    box-shadow: var(--shadow);
    color: var(--text);
    font: 14px/1.4 var(--font);
  }
  .game-audio-settings-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 4px 8px;
    margin-bottom: 10px;
  }
  .game-audio-settings-row:last-child { margin-bottom: 0; }
  .game-audio-settings-row input { grid-column: 1 / -1; width: 100%; }
  .game-audio-settings-row input:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
  }

  .admin-timing-summary {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
  }

  .panel-note-muted {
    color: var(--text-muted);
    font-size: 13px;
  }

  .pipeline-log-timestamp {
    font-size: 11px;
    color: var(--text-muted);
  }

  .hidden-file-input {
    display: none;
  }

  .detective-images {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    flex: 1;
    min-width: 0;
  }

  /* Evidence prints: a bright photo-paper mat (border survives the
     overflow:hidden clip, which stops at the padding box) with a hard
     paper shadow and a thin ink outline. */
  .image-panel {
    position: relative;
    background: var(--paper-bright);
    border: 10px solid var(--paper-bright);
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(43, 33, 21, 0.55), var(--shadow-lg);
    overflow: hidden;
    cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><circle cx="12" cy="12" r="9.5" fill="%23fff9ee" fill-opacity=".22" stroke="%23fff9ee" stroke-width="5"/><line x1="19" y1="19" x2="28" y2="28" stroke="%23fff9ee" stroke-width="7" stroke-linecap="round"/><circle cx="12" cy="12" r="9.5" fill="none" stroke="%232b2115" stroke-width="2.5"/><line x1="19" y1="19" x2="28" y2="28" stroke="%232b2115" stroke-width="3.5" stroke-linecap="round"/></svg>') 12 12, crosshair;
    transition: box-shadow 0.3s ease;
  }

  .image-panel:hover {
    box-shadow: 0 0 0 1px rgba(43, 33, 21, 0.75), 8px 8px 0 rgba(43, 33, 21, 0.18);
  }

  /* Each photo and its exhibit label stack as one grid cell. */
  .image-figure {
    margin: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  /* Stamped exhibit label — a caption below the print, not overlaying it. */
  .image-figure .label {
    align-self: flex-start;
    background: rgba(253, 249, 238, 0.88);
    padding: 4px 11px;
    border: 2px solid var(--accent);
    border-radius: 3px;
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 400;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    transform: rotate(-2deg);
    box-shadow: 1px 1px 0 rgba(43, 33, 21, 0.25);
  }

  /* REQ-850: the zoom-layer wraps both canvases and carries the shared zoom/pan
     transform; .image-panel keeps overflow:hidden so the zoomed photo is clipped
     to the frame and the chrome (label) outside the layer never moves. */
  .zoom-layer {
    position: relative;
    width: 100%;
    transform-origin: 0 0;
    will-change: transform;
    touch-action: pan-x pan-y;
  }

  .image-panel canvas {
    display: block;
    width: 100%;
    height: auto;
    /* At fit, allow one-finger page scroll past a tall layout; pinch is still
       captured (browser pinch-zoom is disabled by this + the viewport meta). */
    touch-action: pan-x pan-y;
  }

  /* Zoomed in: the panel owns one-finger drags (pan) — disable native scrolling. */
  .image-panel.is-zoomed .zoom-layer,
  .image-panel.is-zoomed canvas {
    touch-action: none;
  }

  /* The designer's photo-space SVG lives above the overlay canvas. */
  .found-ring-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
    z-index: 8;
  }
  .found-ring { overflow: visible; pointer-events: none; }
  .found-ring .rim { fill: none; stroke: #151b3d; stroke-linecap: round; stroke-linejoin: round; }
  .found-ring .band { fill: none; stroke-linecap: round; stroke-linejoin: round; }
  .found-ring .pencil .halo * { fill: #fff9ee; stroke: #fff9ee; stroke-width: 3.4; stroke-linejoin: round; stroke-linecap: round; }
  .found-ring .pencil .body * { stroke: #3B3495; stroke-width: .95; stroke-linejoin: round; stroke-linecap: round; }
  .found-ring .pencil .p-body { fill: #FEFFB5; }
  .found-ring .pencil .p-wood { fill: #FFFBF7; }
  .found-ring .pencil .p-lead { fill: #3B3495; }
  .found-ring .pencil .p-band { fill: #E5E4EC; }
  .found-ring .pencil .p-eraser { fill: #FFE6D4; }
  .found-ring .pencil .p-facet { fill: none; stroke-opacity: .45; }
  .found-ring .fleck-out { stroke: #151b3d; stroke-linecap: round; }
  .found-ring .fleck-in { stroke-linecap: round; }
  .hint-mark { pointer-events: none; }
  .hint-mark .sketch-under { fill: none; stroke: #151b3d; stroke-linecap: round; stroke-linejoin: round; }
  .hint-mark .sketch { fill: none; stroke: #a2790d; stroke-linecap: round; stroke-linejoin: round; }

  /* --- Level select: index tabs along the top of the file --- */
  .detective-level-select {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 20px;
    flex-wrap: wrap;
  }

  .level-btn {
    padding: 6px 14px;
    min-height: 44px;
    min-width: 44px;
    border: 1.5px solid var(--border);
    background: var(--card);
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    cursor: pointer;
    box-shadow: 2px 2px 0 rgba(43, 33, 21, 0.12);
    transition: all 0.15s;
  }

  .level-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
    transform: translate(-1px, -1px);
    box-shadow: 3px 3px 0 rgba(43, 33, 21, 0.16);
  }
  .level-btn.active {
    background: var(--text);
    color: var(--paper-bright);
    border-color: var(--text);
  }
  .generator-link { border-style: dashed; text-decoration: none; font-size: 12px; color: var(--text-muted); }
  .generator-link:hover { border-color: var(--accent); color: var(--accent); }

  /* Toolbar buttons: paper tags in typewriter caps.

     REQ-1473 — the toolbar control colour system, in one place. A control declares its FAMILY
     through two custom properties and the shared rules below do the rest:

       --toolbar-family-ink        the family's ink; draws the border and the label at rest,
                                   and becomes the fill once the control is latched on
       --toolbar-family-hover-ink  the same ink, one step deeper, for hover

     Three families, and each one answers "what will this control do?":
       ink  var(--text)     inert  — runs an action or opens a panel (Metrics, Pipeline Log,
                                     Generator, ?, zoom/Fit)
       ink  var(--steel)    view swap — replaces what the two panels show; a mutually exclusive
                                     family (Diff Map, Color Blind Diff, Admin View)
       ink  var(--accent)   arming — puts the surface into a mode where a click on a panel
                                     CHANGES the level (Admin, and only Admin)

     And the fill answers "is it doing it right now?": every control is an outline chip at rest
     and inverts to a filled chip while latched, reusing the .level-btn.active inversion already
     in this sheet. That replaced five unrelated `!important` accent fills (red / plum / steel /
     teal / burnt) which encoded neither destructiveness nor gating tier, and which painted a
     solid block whether the control was on or off — Diff Map looked identical in both states. */
  .hint-btn {
    --toolbar-family-ink: var(--text);
    /* REQ-1474: was var(--amber) (#a2790d), which computed 3.94:1 on the chip paper and failed AA
       in TEN states at once — the eight inert-family unlatched hovers, plus (REQ-1473's two new
       ones) the Metrics and Pipeline Log latched hovers, where the same ink becomes the fill under
       --paper-bright text. #8f6a0b is the same amber one step deeper and measures 4.91:1 in both
       directions. It is a literal here, exactly like the steel (#2e4c70) and arming (#8c2318)
       families below, rather than a re-pointed --amber: that token paints the gold hit sparkle
       and streak tick over photographs; the SVG sketch hint uses the same fixed amber color. */
    --toolbar-family-hover-ink: #8f6a0b;
    padding: 8px 16px;
    min-height: 44px;
    min-width: 44px;
    border: 1.5px solid var(--toolbar-family-ink);
    background: var(--paper-bright);
    border-radius: 3px;
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--toolbar-family-ink);
    cursor: pointer;
    box-shadow: 2px 2px 0 rgba(43, 33, 21, 0.22);
    transition: all 0.15s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
  }

  .hint-btn:hover {
    border-color: var(--toolbar-family-hover-ink);
    color: var(--toolbar-family-hover-ink);
    transform: translate(-1px, -1px);
    box-shadow: 3px 3px 0 rgba(43, 33, 21, 0.26);
  }
  .hint-btn:active { transform: translate(1px, 1px); box-shadow: 1px 1px 0 rgba(43, 33, 21, 0.2); }
  .hint-btn:disabled { opacity: 0.4; cursor: not-allowed; }

  /* REQ-1474: until now NO toolbar control had an authored focus style, so all of them fell back to
     the UA ring — drawn directly on a chip that already carries a 1.5px family-ink border and a hard
     offset shadow, which REQ-1473's outline-at-rest chips made even harder to tell apart from a
     resting border. This is the same focus language the surface already speaks
     (.image-panel:focus-visible): a 3px stamp-red ring at 5.90:1 on
     the chip paper, held 2px off the control so the paper gap keeps it readable even on the Admin
     chip, whose own border is that same stamp red. .level-btn is included because the level-select
     tabs and the "+ New" link are the rest of the header's keyboard path — one language, no
     control left on the UA default. */
  .hint-btn:focus-visible,
  .level-btn:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
  }

  /* Family: view swap. Diff Map and Color Blind Diff are mutually exclusive overlays that
     repaint the evidence panels, and the editorTools Admin View toggle is the same act one
     level up (it swaps the whole surface between designer and admin). One ink for the family;
     the labels tell the members apart. */
  .diffmap-btn,
  .colorblind-diff-btn,
  .editor-admin-view-toggle {
    --toolbar-family-ink: var(--steel);
    --toolbar-family-hover-ink: #2e4c70;
  }

  /* Family: arming. Admin is the only control that puts the surface into a mode where a click
     on a panel edits the level, so it is the only one wearing the stamp red. */
  .admin-btn {
    --toolbar-family-ink: var(--accent);
    --toolbar-family-hover-ink: #8c2318;
  }

  /* Latched. Every toggle in the toolbar inverts to its own family ink while it is on, so the
     fill now carries the state instead of carrying nothing. Same inversion as .level-btn.active.
     These selectors are the toggle classes set by game-admin-core.js / game-admin-metrics.js /
     game-admin-pipeline.js / game-editor-tools.js. */
  .admin-btn.admin-on,
  .diffmap-btn.diffmap-on,
  .colorblind-diff-btn.colorblind-diff-on,
  .metrics-btn.metrics-on,
  .pipeline-log-btn.pipeline-log-on,
  .editor-admin-view-toggle.admin-view-on {
    background: var(--toolbar-family-ink);
    border-color: var(--toolbar-family-ink);
    color: var(--paper-bright);
  }

  .admin-btn.admin-on:hover,
  .diffmap-btn.diffmap-on:hover,
  .colorblind-diff-btn.colorblind-diff-on:hover,
  .metrics-btn.metrics-on:hover,
  .pipeline-log-btn.pipeline-log-on:hover,
  .editor-admin-view-toggle.admin-view-on:hover {
    background: var(--toolbar-family-hover-ink);
    border-color: var(--toolbar-family-hover-ink);
    color: var(--paper-bright);
  }

  /* REQ-893: shared hover/focus tooltip card for the toolbar controls — a dark card with the
     control name, a one-sentence explanation, and (admin only) a "Learn more in the admin
     guide →" deep-link into /admin-guide. Positioned via fixed coords in JS. */
  .toolbar-tooltip {
    position: fixed;
    z-index: 1000;
    max-width: 280px;
    padding: 12px 14px;
    background: #241d12;
    color: #f4ecd9;
    border: 1px solid rgba(244, 236, 217, 0.25);
    border-radius: 4px;
    box-shadow: var(--shadow-lg);
    font-size: 12.5px;
    line-height: 1.45;
    pointer-events: auto;
  }
  .toolbar-tooltip[hidden] { display: none; }
  .toolbar-tooltip-name {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 4px;
  }
  .toolbar-tooltip-desc { color: rgba(244, 236, 217, 0.82); }
  .toolbar-tooltip-link {
    display: inline-block;
    margin-top: 8px;
    color: #e0a05e;
    font-weight: 600;
    text-decoration: none;
  }
  .toolbar-tooltip-link:hover,
  .toolbar-tooltip-link:focus { text-decoration: underline; }

  /* REQ-1164: "Beat 0:42?" banner shown during play when the level was opened from a challenge link */
  .challenge-banner {
    margin: 0 auto 12px;
    max-width: 640px;
    padding: 8px 16px;
    text-align: center;
    background: var(--card);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: 3px;
    font-family: var(--font-display);
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
  }

  .challenge-banner[hidden] { display: none; }

  /* REQ-1164: player-vs-challenger comparison inside the win card */
  .challenge-comparison {
    margin-bottom: 20px;
    padding: 12px 16px;
    border: 1px dashed var(--border);
    border-radius: 3px;
    background: rgba(0, 0, 0, 0.03);
  }

  .challenge-comparison[hidden] { display: none; }

  .challenge-verdict {
    font-family: var(--font-display);
    font-size: 15px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 8px;
  }

  .challenge-verdict.challenge-won { color: var(--accent); }
  .challenge-verdict.challenge-lost { color: var(--text-muted); }
  .challenge-verdict.challenge-tie { color: var(--text); }

  .challenge-compare-line {
    font-family: var(--font-mono);
    font-size: 14px;
    color: var(--text);
  }

  .detective-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 20px;
    color: var(--text-muted);
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: 13px;
    gap: 16px;
  }

  .spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
  }

  @keyframes spin { to { transform: rotate(360deg); } }

  /* REQ-1496: cursor fill follows its ink token; light/dark backing survives mixed photo tones. */
  .ghost-cursor {
    --cursor-ink: var(--text-muted);
    position: absolute;
    pointer-events: none;
    z-index: 9;
    border: 2px dashed var(--cursor-ink);
    border-radius: 50%;
    background: color-mix(in srgb, var(--cursor-ink) 16%, transparent);
    width: 36px;
    height: 36px;
    transform: translate(-50%, -50%);
    transition: opacity 0.15s ease;
    opacity: 0;
    box-shadow: inset 0 0 0 1px rgb(255 249 238 / 80%),
      0 0 0 2px rgb(255 249 238 / 95%), 0 0 0 4px rgb(43 33 21 / 55%);
  }

  .ghost-cursor.visible {
    opacity: 1;
  }

  .detective-empty {
    text-align: center;
    padding: 80px 20px;
    color: var(--text-muted);
  }

  .detective-empty h2 {
    font-family: var(--font-display);
    font-size: 20px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text);
    margin-bottom: 8px;
  }

  .detective-empty code {
    display: inline-block;
    background: var(--paper-bright);
    border: 1px solid var(--border);
    padding: 8px 16px;
    border-radius: 3px;
    margin-top: 12px;
    font-family: var(--font-mono);
    font-size: 14px;
  }

  .timer-penalty {
    animation: penaltyFlash 0.5s ease;
  }

  @keyframes penaltyFlash {
    0%, 100% { color: var(--accent); }
    50% { color: var(--error); transform: scale(1.15); }
  }

  /* --- Color-blind mode --- */
  .color-blind-mode .ghost-cursor,
  .color-blind-mode .keyboard-cursor {
    --cursor-ink: #2563eb;
  }

  /* --- Reduced motion --- */
  @media (prefers-reduced-motion: reduce) {
    .ghost-cursor, .keyboard-cursor, .spinner, .timer-penalty {
      animation: none !important;
      transition: none !important;
    }
  }

  /* --- Achievement toast --- */
  .achievement-toast {
    position: fixed;
    bottom: 20px;
    right: 20px;
    background: var(--card);
    border: 2px solid var(--success);
    border-radius: 4px;
    padding: 14px 20px;
    box-shadow: var(--shadow-lg);
    z-index: 200;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    font-weight: 500;
    animation: toastSlideIn 0.4s ease, toastFadeOut 0.4s ease 3s forwards;
  }

  @keyframes toastSlideIn {
    from { transform: translateY(40px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }

  @keyframes toastFadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
  }

  .image-panel:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
  }

  .keyboard-cursor {
    --cursor-ink: var(--accent);
    position: absolute;
    width: 24px;
    height: 24px;
    border: 2px solid var(--cursor-ink);
    border-radius: 50%;
    background: color-mix(in srgb, var(--cursor-ink) 16%, transparent);
    pointer-events: none;
    z-index: 12;
    transform: translate(-50%, -50%);
    box-shadow: inset 0 0 0 1px rgb(255 249 238 / 80%),
      0 0 0 2px rgb(255 249 238 / 95%), 0 0 0 4px rgb(43 33 21 / 55%);
    display: none;
  }

  .image-panel:focus-visible .keyboard-cursor {
    display: block;
  }

  /* --- Overlay canvas (REQ-217, REQ-218) --- */
  .overlay-canvas {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    z-index: 7;
  }

  /* --- Admin mode (REQ-219) ---
     The Admin / Diff Map / Color Blind Diff button skins that used to sit here were folded
     into the one toolbar colour system beside .hint-btn (REQ-1473). */
  .image-panel.admin-active {
    cursor: crosshair;
  }

  .admin-popover {
    position: absolute;
    z-index: 20;
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 16px;
    min-width: 280px;
    border: 2px solid var(--accent);
  }

  .admin-popover h3 {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 8px;
  }

  .admin-popover .admin-diff-desc {
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 12px;
  }

  .admin-popover input {
    width: 100%;
    padding: 8px 12px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 13px;
    font-family: var(--font);
    margin-bottom: 12px;
  }

  .admin-popover input:focus {
    outline: none;
    border-color: var(--accent);
  }

  .admin-popover .admin-actions {
    display: flex;
    gap: 8px;
  }

  .admin-popover button {
    flex: 1;
    padding: 8px 12px;
    border: none;
    border-radius: 3px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    font-family: var(--font);
  }

  .admin-popover .admin-inpaint-btn {
    background: var(--accent);
    color: var(--paper-bright);
  }

  .admin-popover .admin-cancel-btn {
    background: var(--bg);
    color: var(--text);
  }

  .admin-popover .admin-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255,255,255,0.3);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    vertical-align: middle;
    margin-right: 6px;
  }

  /* --- REQ-1152: editorTools toolbar extras (zoom buttons + admin-view toggle) ---
     The toggle's skin lives in the toolbar colour system beside .hint-btn (REQ-1473); only the
     zoom buttons' narrower footprint is local to them. */
  .editor-zoom-in-btn,
  .editor-zoom-out-btn {
    min-width: 34px;
  }

  /* --- Admin popover metrics table --- */
  .admin-metrics-summary {
    margin: 8px 0 12px;
    font-size: 11px;
    border: 1px solid var(--border);
    border-radius: 3px;
    overflow: hidden;
  }
  .admin-metrics-summary table {
    width: 100%;
    border-collapse: collapse;
  }
  .admin-metrics-summary th {
    background: var(--bg);
    padding: 4px 8px;
    text-align: left;
    font-family: var(--font-display);
    font-weight: 400;
    color: var(--text-muted);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }
  .admin-metrics-summary td {
    padding: 3px 8px;
    border-top: 1px solid var(--border);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
  }
  .admin-metrics-summary td:first-child {
    color: var(--text-muted);
  }

  /* --- Collapsible metrics panel --- */
  .metrics-panel {
    display: none;
    margin: 0;
    padding: 0;
    flex: 0 0 380px;
    max-height: calc(100vh - 110px);
    overflow-y: auto;
    position: sticky;
    top: 20px;
    min-width: 0;
  }
  .metrics-panel.visible {
    display: block;
  }

  .metrics-panel-content {
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 20px;
    border: 1px solid var(--border);
  }
  .metrics-panel-title {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 12px;
    color: var(--text);
  }
  .metrics-card .metric-id {
    font-family: var(--font-mono);
    font-weight: 700;
    color: var(--accent);
    font-size: 13px;
  }
  .metrics-card .metric-desc {
    white-space: normal;
    word-break: break-word;
    line-height: 1.45;
    font-size: 13px;
    color: var(--text);
    margin-top: 6px;
  }
  /* REQ-238: overlap detection badges */
  .metrics-card .metric-overlaps {
    white-space: normal;
    line-height: 1.6;
    margin-top: 6px;
  }
  .metric-overlap-badge {
    display: inline-block;
    margin: 2px 4px 2px 0;
    padding: 1px 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
  }
  .metric-overlap-paired {
    color: var(--teal);
    background: rgba(35, 105, 122, 0.12);
  }
  .metric-overlap-entangled {
    color: #8a4a12;
    background: rgba(168, 84, 19, 0.14);
  }
  .metric-overlap-warning {
    color: #7d5f0a;
    background: rgba(162, 121, 13, 0.16);
  }
  .metric-overlap-conflict {
    color: #8c2318;
    background: rgba(178, 58, 37, 0.14);
  }
  .metrics-legend {
    margin-top: 16px;
    padding: 12px;
    background: var(--bg);
    border-radius: 3px;
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.6;
  }
  .metrics-legend dt {
    font-weight: 600;
    color: var(--text);
    display: inline;
  }
  .metrics-legend dd {
    display: inline;
    margin: 0 0 0 4px;
  }
  .metrics-legend dd::after {
    content: '';
    display: block;
    margin-bottom: 4px;
  }
  /* REQ-895: collapse the glossary behind a "What do these numbers mean?" disclosure,
     collapsed by default, so the difference cards and action toolbars sit together. */
  .metrics-legend-disclosure {
    margin-top: 16px;
  }
  .metrics-legend-summary {
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
    padding: 6px 10px;
    border-radius: 3px;
    background: var(--bg);
    list-style: none;
    user-select: none;
  }
  .metrics-legend-summary::-webkit-details-marker {
    display: none;
  }
  .metrics-legend-summary::before {
    content: '\25B8'; /* ▸ collapsed */
    display: inline-block;
    margin-right: 6px;
  }
  .metrics-legend-disclosure[open] .metrics-legend-summary::before {
    content: '\25BE'; /* ▾ expanded */
  }
  /* Tighter gap between the summary and the revealed glossary than the standalone
     legend's default top margin. */
  .metrics-legend-disclosure .metrics-legend {
    margin-top: 8px;
  }
  /* --- Difference cards (replaces the old metrics table) --- */
  .metrics-card-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 4px;
  }
  .metrics-card {
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 10px 12px;
    background: var(--paper-bright);
    cursor: pointer;
    transition: background 0.15s, box-shadow 0.15s;
  }
  .metrics-card:hover {
    background: #f7f2e2;
  }
  .metrics-card.metrics-row-active {
    background: #f3ecd6;
    box-shadow: inset 3px 0 0 var(--accent);
  }
  /* REQ-224: disabled difference card styling */
  .metrics-card.metrics-row-disabled {
    opacity: 0.45;
  }
  .metrics-card.metrics-row-disabled .metric-desc {
    text-decoration: line-through;
  }
  .metrics-card.metrics-row-disabled:hover {
    opacity: 0.65;
  }
  .metrics-card.metrics-row-conflict {
    box-shadow: inset 3px 0 0 #8c2318;
  }
  .metrics-card-header {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .metrics-card-checkbox {
    cursor: pointer;
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    margin: 0;
    accent-color: var(--accent);
  }
  .metrics-card-actions {
    margin-left: auto;
    display: flex;
    gap: 4px;
    flex-shrink: 0;
  }
  .metrics-card-actions .metrics-edit-btn,
  .metrics-card-actions .metrics-move-btn,
  .metrics-card-actions .metrics-remove-btn {
    margin-left: 0;
  }

  /* Compact metric chips inside each card (the legend below explains each term) */
  .metrics-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 6px;
    margin-top: 8px;
  }
  .metric-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 2px 7px;
    border-radius: 3px;
    background: var(--bg);
    border: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    color: var(--text);
    white-space: nowrap;
  }
  .metric-chip-label {
    font-family: var(--font-display);
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    font-weight: 400;
  }
  /* REQ-1495: this fill used to be rgba(178, 58, 37, 0.1) — translucent, which quietly overrode the
     OPAQUE var(--bg) every other chip paints, so the notice chip took whichever row paper sat behind
     it. That made it lighter than its neighbours on a resting row and browner than them on an active
     one, and dragged the 9px .metric-chip-label (var(--text-muted)) down with it: 4.53 resting, 4.10
     hovered, 3.90 active — under the 4.5 floor, with no large-text exemption at 9px. The same wash
     flattened to one opaque tint keeps the pink notice read on every row and holds the label at 4.67
     and the 11px bold value ink (var(--accent)) at 5.24 wherever the chip lands. Fixed here rather
     than on --text-muted, which REQ-1474 already set to the lightest value that clears the darkest
     paper. */
  .metric-chip-notice {
    background: #f9eee9;
    border-color: rgba(178, 58, 37, 0.35);
    color: var(--accent);
    font-weight: 700;
  }
  .metrics-chip-row-empty {
    color: var(--text-muted);
    font-size: 11px;
  }

  /* --- REQ-253: Inline edit button + row in metrics panel --- */
  .metrics-edit-btn {
    margin-left: 8px;
    padding: 2px 8px;
    font-size: 10px;
    font-weight: 600;
    border: 1.5px solid var(--accent);
    border-radius: 3px;
    background: transparent;
    color: var(--accent);
    cursor: pointer;
    font-family: var(--font);
    transition: background 0.15s, color 0.15s;
    vertical-align: middle;
  }
  .metrics-edit-btn:hover {
    background: var(--accent);
    color: var(--paper-bright);
  }

  /* REQ-848: Move detected segment button in metrics panel */
  .metrics-move-btn {
    margin-left: 4px;
    padding: 2px 8px;
    font-size: 10px;
    font-weight: 600;
    border: 1.5px solid var(--teal);
    border-radius: 3px;
    background: transparent;
    color: var(--teal);
    cursor: pointer;
    font-family: var(--font);
    transition: background 0.15s, color 0.15s;
    vertical-align: middle;
  }
  .metrics-move-btn:hover {
    background: var(--teal);
    color: var(--paper-bright);
  }
  .metrics-move-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  /* REQ-848: inline move editor — appended after the card it relocates */
  .metrics-inline-move-row {
    background: rgba(35, 105, 122, 0.07);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 10px 12px;
  }
  .metrics-inline-move-wrapper {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
  .metrics-inline-move-offset-x,
  .metrics-inline-move-offset-y {
    width: 88px;
    padding: 7px 10px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font-mono);
  }
  .metrics-inline-move-background {
    flex: 1;
    min-width: 160px;
    padding: 7px 12px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
  }
  .metrics-inline-move-offset-x:focus,
  .metrics-inline-move-offset-y:focus,
  .metrics-inline-move-background:focus {
    outline: none;
    border-color: var(--teal);
  }
  .metrics-inline-move-submit,
  .metrics-inline-move-cancel {
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font);
    white-space: nowrap;
  }
  .metrics-inline-move-submit {
    background: var(--teal);
    color: var(--paper-bright);
  }
  .metrics-inline-move-submit:hover {
    background: #1a5361;
  }
  .metrics-inline-move-submit:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  .metrics-inline-move-cancel {
    background: var(--bg);
    color: var(--text);
  }
  .metrics-inline-move-cancel:hover {
    background: #eae2cc;
  }

  /* REQ-294: Remove from image button in metrics panel */
  .metrics-remove-btn {
    margin-left: 4px;
    padding: 2px 8px;
    font-size: 10px;
    font-weight: 600;
    border: 1.5px solid #8c2318;
    border-radius: 3px;
    background: transparent;
    color: #8c2318;
    cursor: pointer;
    font-family: var(--font);
    transition: background 0.15s, color 0.15s;
    vertical-align: middle;
  }
  .metrics-remove-btn:hover {
    background: #8c2318;
    color: var(--paper-bright);
  }
  .metrics-remove-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  /* Inline editor — now a block appended after the card it edits (was a table row) */
  .metrics-inline-edit-row {
    background: rgba(178, 58, 37, 0.06);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 10px 12px;
  }
  .metrics-inline-edit-wrapper {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
  .metrics-inline-edit-input {
    flex: 1;
    padding: 7px 12px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
  }
  .metrics-inline-edit-input:focus {
    outline: none;
    border-color: var(--accent);
  }
  .metrics-inline-edit-model {
    padding: 7px 8px;
    border: 1.5px solid var(--border);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
    background: var(--paper-bright);
    cursor: pointer;
  }
  .metrics-inline-edit-model:focus {
    outline: none;
    border-color: var(--accent);
  }
  .metrics-inline-edit-negative {
    flex: 0.6;
    padding: 7px 12px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
  }
  .metrics-inline-edit-negative:focus {
    outline: none;
    border-color: var(--accent);
  }
  .metrics-inline-edit-submit,
  .metrics-inline-edit-cancel {
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font);
    white-space: nowrap;
  }
  .metrics-inline-edit-submit {
    background: var(--accent);
    color: var(--paper-bright);
  }
  .metrics-inline-edit-submit:hover {
    background: #96311f;
  }
  .metrics-inline-edit-submit:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  .metrics-inline-edit-cancel {
    background: var(--bg);
    color: var(--text);
  }
  .metrics-inline-edit-cancel:hover {
    background: #eae2cc;
  }

  /* --- REQ-250: Reconstruct button in metrics panel --- */
  .reconstruct-toolbar {
    margin-top: 14px;
    display: flex;
    align-items: center;
    gap: 12px;
  }
  .reconstruct-btn {
    padding: 7px 16px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    background: var(--plum);
    color: var(--paper-bright);
    transition: background 0.15s, box-shadow 0.15s;
  }
  .reconstruct-btn:hover {
    background: #57386a;
  }
  .reconstruct-btn.reconstruct-active {
    background: var(--success);
    box-shadow: 0 0 0 2px rgba(51, 113, 78, 0.4);
  }
  .reconstruct-btn.reconstruct-active:hover {
    background: #275c3e;
  }
  .reconstruct-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
  .reconstruct-status {
    font-size: 12px;
    color: var(--text-muted);
  }

  /* --- Import difference from upload (REQ-849) --- */
  .import-difference-toolbar {
    margin-top: 10px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
  }
  .import-difference-btn {
    padding: 7px 16px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    background: var(--teal);
    color: var(--paper-bright);
    transition: background 0.15s, box-shadow 0.15s;
  }
  .import-difference-btn:hover {
    background: #1a5361;
  }
  .import-difference-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
  .import-difference-status {
    font-size: 12px;
    color: var(--text-muted);
  }

  /* REQ-892: the level-store export packages toolbar (REQ-876) first moved to
     the "Level store export" card on /generator. REQ-932 later moved that card;
     its current styles live in apps/admin/import-export/import-export.css. */

  /* --- "Add difference by click" (REQ-881) --- */
  .segment-point-toolbar {
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .segment-point-toggle-btn {
    align-self: flex-start;
    padding: 7px 16px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    background: var(--teal);
    color: var(--paper-bright);
    transition: background 0.15s, box-shadow 0.15s;
  }
  .segment-point-toggle-btn:hover {
    background: #1a5361;
  }
  .segment-point-toggle-btn.segment-point-toggle-active {
    background: #7fc9d6;
    color: #0c2a30;
    box-shadow: 0 0 0 2px rgba(127, 201, 214, 0.5);
  }
  .segment-point-status {
    font-size: 12px;
    color: var(--text-muted);
  }
  /* The shared .admin-spinner rule is scoped to .admin-popover; the segment toolbar sits outside a
     popover, so give the toggle button its own copy of the same spinner (reusing @keyframes spin). */
  .segment-point-toggle-btn .admin-spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    vertical-align: middle;
    margin-right: 6px;
  }
  /* On the active (light teal) button the white spinner washes out — darken it to match the text. */
  .segment-point-toggle-btn.segment-point-toggle-active .admin-spinner {
    border-color: rgba(12, 42, 48, 0.3);
    border-top-color: #0c2a30;
  }
  .segment-point-confirm-wrapper {
    background: rgba(35, 105, 122, 0.07);
    border: 1px solid rgba(35, 105, 122, 0.3);
    border-radius: 3px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .segment-point-summary {
    font-size: 12px;
    color: var(--text);
  }
  .segment-point-controls-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
  .segment-point-prompt {
    flex: 1;
    min-width: 200px;
    padding: 7px 12px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
  }
  .segment-point-prompt:focus {
    outline: none;
    border-color: var(--accent);
  }
  .segment-point-model {
    padding: 7px 8px;
    border: 1.5px solid var(--border);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
    background: var(--paper-bright);
    cursor: pointer;
  }
  .segment-point-negative {
    flex: 0.6;
    min-width: 120px;
    padding: 7px 12px;
    border: 1.5px solid var(--border);
    background: var(--paper-bright);
    border-radius: 3px;
    font-size: 12px;
    font-family: var(--font);
  }
  .segment-point-sliders-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
  }
  .segment-point-slider-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--text-muted);
  }
  .segment-point-spread,
  .segment-point-feather {
    width: 100px;
    accent-color: var(--teal);
  }
  .segment-point-slider-value {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 700;
    color: var(--text);
    min-width: 1.5em;
  }
  .segment-point-actions {
    display: flex;
    gap: 8px;
  }
  .segment-point-confirm-btn,
  .segment-point-clear-btn {
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font);
    white-space: nowrap;
  }
  .segment-point-confirm-btn {
    background: var(--teal);
    color: var(--paper-bright);
  }
  .segment-point-confirm-btn:hover {
    background: #1a5361;
  }
  .segment-point-confirm-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  .segment-point-clear-btn {
    background: var(--bg);
    color: var(--text);
  }
  .segment-point-clear-btn:hover {
    background: #eae2cc;
  }

  /* Crosshair cursor + highlight ring on the ORIGINAL panel while click-to-add is active —
     this is the only valid click target for the feature (segmentation runs on original.png). */
  body.add-diff-by-click-active #panel-original {
    cursor: crosshair;
    box-shadow: 0 0 0 3px rgba(127, 201, 214, 0.8), var(--shadow-lg);
  }

  /* --- Pipeline Log panel (REQ-239) ---
     The Pipeline Log button's skin moved into the toolbar colour system beside .hint-btn
     (REQ-1473); it is an inert panel-opener, so it wears the neutral ink. */
  .pipeline-log-panel {
    display: none;
    margin: 0;
    padding: 0 24px 24px;
  }
  .pipeline-log-panel.visible {
    display: block;
  }
  .pipeline-log-panel-content {
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 20px;
    border: 1px solid var(--border);
  }
  .pipeline-log-panel-title {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 12px;
    color: var(--text);
  }
  .pipeline-log-timing-bar {
    display: flex;
    gap: 24px;
    padding: 10px 14px;
    background: var(--bg);
    border-radius: 3px;
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 16px;
  }
  .pipeline-log-timing-bar strong {
    color: var(--text);
    font-weight: 600;
  }
  .pipeline-log-card {
    border: 1px solid var(--border);
    border-radius: 3px;
    margin-bottom: 8px;
    overflow: hidden;
  }
  .pipeline-log-card-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--bg);
    cursor: pointer;
    font-size: 12px;
    user-select: none;
  }
  /* REQ-1495 (REQ-1474's Discovered Task 1): the hover used to DARKEN this header to #eae2cc, which
     took its var(--text-muted) chevron and model name to 4.11:1. Darkening cannot be rescued here —
     the header's resting var(--bg) already measures only 4.58 against that ink, so any perceptible
     step down lands under the floor. Hovering to var(--paper-bright) lifts the header off the panel
     instead, which is a bigger visible step than the old tint AND takes the muted ink to 5.26:1. */
  .pipeline-log-card-header:hover {
    background: var(--paper-bright);
  }
  .pipeline-log-card-chevron {
    font-size: 10px;
    color: var(--text-muted);
    transition: transform 0.15s;
  }
  .pipeline-log-card.expanded .pipeline-log-card-chevron {
    transform: rotate(90deg);
  }
  .pipeline-log-card-step {
    font-weight: 700;
    color: var(--text);
  }
  .pipeline-log-card-api {
    color: var(--accent);
    font-weight: 600;
  }
  .pipeline-log-card-model {
    color: var(--text-muted);
  }
  .pipeline-log-card-duration {
    margin-left: auto;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    font-weight: 600;
  }
  .pipeline-log-card-body {
    display: none;
    padding: 14px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    line-height: 1.5;
  }
  .pipeline-log-card.expanded .pipeline-log-card-body {
    display: block;
  }
  .pipeline-log-section-label {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin-top: 10px;
    margin-bottom: 4px;
  }
  .pipeline-log-section-label:first-child {
    margin-top: 0;
  }
  .pipeline-log-pre {
    background: #241d12;
    color: #e8dcc2;
    padding: 10px 12px;
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 11px;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-all;
    max-height: 300px;
    overflow-y: auto;
  }
  .pipeline-log-copy-curl-btn {
    display: inline-block;
    margin-top: 8px;
    padding: 4px 12px;
    background: var(--accent);
    color: var(--paper-bright);
    border: none;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
  }
  .pipeline-log-copy-curl-btn:hover {
    background: #96311f;
  }
  .pipeline-log-params-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11px;
    margin-top: 4px;
  }
  .pipeline-log-params-table td {
    padding: 2px 8px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
  }
  .pipeline-log-params-table td:first-child {
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
    width: 140px;
  }

  /* On a narrower viewport, the metrics panel becomes part of the page flow. */
  @media (max-width: 1100px) {
    .metrics-panel.visible {
      flex: none;
      min-width: 0;
      max-height: none;
      position: static;
    }
  }

  @media (max-width: 768px) {
    .detective-images { grid-template-columns: 1fr; }
  }

  /* Current timed player and untimed editing board share this canvas host. */
  .detective-game.daily-core-loop-game {
    width: 100%;
    height: 100%;
    min-height: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
  }

  .daily-core-loop-puzzle { position: absolute; inset: 0; pointer-events: none; }

  .daily-core-loop-game .challenge-banner {
    position: absolute;
    top: calc(var(--daily-core-loop-pair-top) - 42px);
    left: 50%;
    z-index: 8;
    width: max-content;
    max-width: calc(100% - 24px);
    margin: 0;
    transform: translateX(-50%);
    background: #010b23;
    border-color: #fbff81;
    color: #fff;
    pointer-events: none;
  }

  /* The comparison lives in the Card footer. Wide boards lift it beside the Card's top edge;
     compact boards keep it in the footer column, so the measured footer (and the Card fit) includes it. */
  [data-daily-core-loop-card-host] .challenge-comparison {
    position: absolute;
    top: calc(var(--daily-core-loop-completed-card-width) * -518 / 366);
    left: calc(50% + var(--daily-core-loop-completed-card-width) / 2 + 16px);
    width: 264px;
    margin: 0;
    background: #010b23;
    border: 1px solid #fbff81;
    color: #fff;
    box-shadow: 0 8px 24px rgb(0 0 0 / 30%);
    pointer-events: none;
  }

  [data-daily-core-loop-card-host] .challenge-compare-line,
  [data-daily-core-loop-card-host] .challenge-verdict.challenge-tie {
    color: #fff;
  }

  [data-daily-core-loop-card-host] .challenge-verdict.challenge-won { color: #fbff81; }
  [data-daily-core-loop-card-host] .challenge-verdict.challenge-lost { color: #f8b9af; }

  @media (max-width: 925px) {
    [data-daily-core-loop-card-host] .challenge-comparison {
      position: static;
      width: min(300px, 100%);
      padding: 2px 10px;
    }
    [data-daily-core-loop-card-host] .challenge-verdict {
      margin-bottom: 2px;
      font-size: 12px;
      line-height: 1.2;
      white-space: nowrap;
    }
    [data-daily-core-loop-card-host] .challenge-compare-line { font-size: 11px; }
  }

  .daily-core-loop-puzzle .detective-images {
    position: absolute;
    left: var(--daily-core-loop-pair-left);
    top: var(--daily-core-loop-pair-top);
    display: grid;
    grid-template-columns: var(--daily-core-loop-photo-width) var(--daily-core-loop-photo-width);
    gap: 8px;
    width: calc(var(--daily-core-loop-photo-width) * 2 + 8px);
    height: var(--daily-core-loop-photo-height);
    pointer-events: auto;
  }

  .daily-core-loop-puzzle .image-figure {
    width: var(--daily-core-loop-photo-width);
    height: var(--daily-core-loop-photo-height);
    min-width: 0;
    margin: 0;
    gap: 0;
  }

  .daily-core-loop-puzzle .image-panel {
    width: 100%;
    height: 100%;
    border: 4px solid #fff;
    border-radius: 3px;
    background: #fff;
    box-shadow: 0 10px 30px -12px rgb(0 0 0 / 55%);
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
  }

  .daily-core-loop-puzzle .image-panel:hover { box-shadow: 0 10px 30px -12px rgb(0 0 0 / 55%); }

  .daily-core-loop-puzzle .zoom-layer,
  .daily-core-loop-puzzle .image-panel canvas {
    width: 100%;
    height: 100%;
    touch-action: none;
  }

  .daily-core-loop-puzzle .image-panel canvas {
    width: 100% !important;
    height: 100% !important;
    -webkit-user-drag: none;
  }

  .daily-core-loop-puzzle .image-panel.is-zoomed { cursor: grab; }
  .daily-core-loop-puzzle .image-panel.is-dragging { cursor: grabbing; }

  /* Both arrangements share one bounded live scroller. Absolute figures retain the flight's
     board-space coordinates; clipping contains zoomed descendants without enlarging its range. */
  [data-daily-core-loop-picture-layout] .daily-core-loop-puzzle .detective-images,
  :is(.daily-core-loop-phone-layout, .daily-core-loop-touch-play) .daily-core-loop-puzzle .detective-images {
    left: 0;
    top: var(--daily-core-loop-pair-top);
    display: block;
    width: 100%;
    height: var(--daily-core-loop-live-pair-height, calc(100% - var(--daily-core-loop-pair-top)));
    overflow-x: hidden;
    overflow-y: auto;
    scrollbar-width: none;
  }

  /* REQ-2324: the panel's clip-path hides the zoomed canvases but still lets them extend the pair's
     scroll range. Clipping the figure contains that overflow; its padding box is the panel's border
     box, so the painted frame stroke inside the border survives (overflow-clip-margin is not in Safari). */
  [data-daily-core-loop-picture-layout] .daily-core-loop-puzzle .image-figure,
  :is(.daily-core-loop-phone-layout, .daily-core-loop-touch-play) .daily-core-loop-puzzle .image-figure {
    position: absolute;
    left: var(--daily-core-loop-photo-original-left);
    top: calc(var(--daily-core-loop-photo-original-top) - var(--daily-core-loop-pair-top));
    overflow: clip;
    pointer-events: auto;
  }

  [data-daily-core-loop-picture-layout] .daily-core-loop-puzzle #figure-modified,
  :is(.daily-core-loop-phone-layout, .daily-core-loop-touch-play) .daily-core-loop-puzzle #figure-modified {
    left: var(--daily-core-loop-photo-modified-left);
    top: calc(var(--daily-core-loop-photo-modified-top) - var(--daily-core-loop-pair-top));
  }

  /* Layout owns this resting offset; the engine retains its inline pan/zoom transform. */
  :is(.daily-core-loop-phone-layout, .daily-core-loop-touch-play) .daily-core-loop-puzzle .zoom-layer {
    position: absolute;
    left: var(--daily-core-loop-photo-rest-left);
    width: var(--daily-core-loop-whole-photo-width);
    top: var(--daily-core-loop-photo-rest-top);
    height: var(--daily-core-loop-whole-photo-height);
    z-index: 1;
  }

  :is(.daily-core-loop-phone-layout, .daily-core-loop-touch-play) .daily-core-loop-puzzle .image-panel canvas {
    height: auto !important;
  }

  /* REQ-2305: the play sheet behind the stacked pictures in resting play, in the card's paper and 1px
     stroke and spanning the board less its margins: the round band stays put (and takes the touches the
     card's band did), the part behind the pictures scrolls with them. The deal and replay show the card. */
  .daily-core-loop-phone-layout[data-daily-core-loop-phone-play-column] .daily-core-loop-player-hud::before,
  .daily-core-loop-phone-layout[data-daily-core-loop-phone-play-column] .daily-core-loop-puzzle .detective-images::before {
    content: '';
    position: absolute;
    left: var(--daily-core-loop-phone-sheet-left);
    width: var(--daily-core-loop-phone-sheet-width);
    box-sizing: border-box;
    border: 1px solid #000;
    background: repeating-linear-gradient(135deg, #fff3e5 0 1.111px, #fffbf7 1.111px 3.704px);
  }
  .daily-core-loop-phone-layout[data-daily-core-loop-phone-play-column] .daily-core-loop-player-hud::before {
    top: var(--daily-core-loop-phone-sheet-top);
    height: calc(var(--daily-core-loop-pair-top) - var(--daily-core-loop-phone-sheet-top));
    border-bottom-width: 0;
    border-radius: 0 10px 0 0;
    pointer-events: auto;
  }
  .daily-core-loop-phone-layout[data-daily-core-loop-phone-play-column] .daily-core-loop-puzzle .detective-images::before {
    top: 0;
    height: calc(var(--daily-core-loop-phone-sheet-top) + var(--daily-core-loop-phone-sheet-height) - var(--daily-core-loop-pair-top));
    border-top-width: 0;
    box-shadow: 0 18px 48px -18px rgb(0 0 0 / 70%);
  }

  /* REQ-2305: a whole picture has nothing to pan at fit, so one finger scrolls the stacked pair. */
  .daily-core-loop-phone-layout[data-daily-core-loop-phone-play-column] .daily-core-loop-puzzle .image-panel:not(.is-zoomed),
  .daily-core-loop-phone-layout[data-daily-core-loop-phone-play-column] .daily-core-loop-puzzle .image-panel:not(.is-zoomed) :is(.zoom-layer, canvas) {
    touch-action: pan-y;
  }

  .daily-core-loop-player-hud {
    position: absolute;
    inset: 0;
    z-index: 7;
    color: #fff;
    pointer-events: none;
  }

  .daily-core-loop-tool-row {
    position: absolute;
    left: var(--daily-core-loop-tool-left, var(--daily-core-loop-pair-left));
    top: calc(var(--daily-core-loop-round-controls-top, calc(var(--daily-core-loop-pair-top) + var(--daily-core-loop-photo-height))) + 22px);
    display: flex;
    gap: 12px;
    pointer-events: auto;
  }

  .daily-core-loop-tool-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid rgb(0 0 0 / 35%);
    border-radius: 50%;
    background: #fbfaf6;
    color: #0f0f0f;
    cursor: pointer;
    transition: background 150ms ease;
  }

  .daily-core-loop-tool-button svg { width: 21px; height: 21px; }
  .daily-core-loop-tool-button:hover { background: #fff; }
  .daily-core-loop-tool-button:active { transform: translateY(1px); }
  .daily-core-loop-tool-button:focus-visible { outline: 2px solid #fbff81; outline-offset: 3px; }
  .daily-core-loop-tool-button:disabled { opacity: .38; cursor: default; }
  .daily-core-loop-tool-button:disabled:active { transform: none; }

  /* REQ-2406: the once-per-player "drag the photo" note. Out of the row's flow, so the buttons,
     count and clock never move; it fades by opacity only. */
  /* REQ-2406 D-06: above the zoom buttons, over the pair's lower-left corner. REQ-2405's whole-board pair
     leaves no room below the tool row (a 1400x720 board clipped the hint by 6px there). */
  .daily-core-loop-drag-hint {
    position: absolute;
    left: 0;
    bottom: calc(100% + 10px);
    margin: 0;
    padding: 6px 12px;
    border-radius: 6px;
    background: rgb(15 15 15 / 82%);
    color: #fff;
    font: 400 15px/20px 'ET Sans', sans-serif;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity 400ms ease;
  }
  .daily-core-loop-drag-hint:empty { visibility: hidden; }
  .daily-core-loop-drag-hint.is-visible { opacity: 1; }
  @media (prefers-reduced-motion: reduce) {
    .daily-core-loop-drag-hint { transition: none; }
  }

  /* TOUCH PLAY: the lesson's hand over the first picture, on every fill until Skip (REQ-2445). Its fingertip (22, 8 in
     the 48-unit drawing) sits on the point it drags; the engine moves it, and hides it while a finger is down. */
  .daily-core-loop-move-hint {
    position: absolute;
    z-index: 9;
    width: 72px;
    height: 72px;
    margin: -12px 0 0 -33px;
    transform-origin: 33px 12px;
    pointer-events: none;
    opacity: 0;
    filter: drop-shadow(0 3px 6px rgb(0 0 0 / 40%));
  }
  .daily-core-loop-move-hint svg { display: block; width: 100%; height: 100%; overflow: visible; }
  .daily-core-loop-move-hint path { fill: #fff9ee; stroke: #151b3d; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
  .daily-core-loop-move-hint-press {
    fill: rgb(255 249 238 / 45%);
    stroke: #fff9ee;
    stroke-width: 1.4;
    opacity: var(--daily-core-loop-move-hint-pressed, 0);
  }

  .daily-core-loop-score {
    position: absolute;
    top: calc(var(--daily-core-loop-round-controls-top, calc(var(--daily-core-loop-pair-top) + var(--daily-core-loop-photo-height))) + 26px);
    left: 0;
    right: 0;
    color: #fff;
    font: 400 30px/40px 'ET Title Slab', Georgia, serif;
    text-align: center;
    pointer-events: none;
  }

  .daily-core-loop-clock {
    position: absolute;
    top: calc(var(--daily-core-loop-round-controls-top, calc(var(--daily-core-loop-pair-top) + var(--daily-core-loop-photo-height))) + 24px);
    right: var(--daily-core-loop-pair-left);
    display: flex;
    align-items: center;
    gap: 9px;
    color: #fff;
    font: 400 30px/40px 'ET Title Slab', Georgia, serif;
    font-variant-numeric: tabular-nums;
    letter-spacing: 1px;
    pointer-events: none;
  }

  [data-daily-core-loop-live-pair]:focus-visible { outline: 2px solid #fbff81; outline-offset: -2px; }
  [data-daily-core-loop-picture-layout] .daily-core-loop-puzzle .image-panel:not(.is-zoomed),
  [data-daily-core-loop-picture-layout] .daily-core-loop-puzzle .image-panel:not(.is-zoomed) * { touch-action: pan-y; }
  [data-daily-core-loop-picture-scroll] {
    position: sticky;
    top: calc(100% - 44px);
    z-index: 9;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    border-top: 1px solid #fff;
    background: #132334;
    color: #fff;
    font: 600 14px/1.2 system-ui, sans-serif;
    touch-action: pan-y;
    pointer-events: auto;
  }
  [data-daily-core-loop-picture-layout] .daily-core-loop-puzzle .detective-images::after {
    content: '';
    position: absolute;
    top: calc(max(var(--daily-core-loop-photo-original-top), var(--daily-core-loop-photo-modified-top)) - var(--daily-core-loop-pair-top) + var(--daily-core-loop-photo-height));
    width: 1px;
    height: calc(44px + var(--daily-core-loop-hint-clearance, 0px));
    pointer-events: none;
  }

  /* A retained notice can leave less than one photo-and-controls viewport. Keep the same
     scroll owner, with controls before the width-first photos and a reachable trailing lesson. */
  .daily-core-loop-sequential-controls .daily-core-loop-puzzle .detective-images { top: 0; }
  .daily-core-loop-sequential-controls .daily-core-loop-puzzle .image-figure {
    top: calc(var(--daily-core-loop-photo-original-top) + 44px);
  }
  .daily-core-loop-sequential-controls .daily-core-loop-puzzle #figure-modified {
    top: calc(var(--daily-core-loop-photo-modified-top) + 44px);
  }
  .daily-core-loop-sequential-controls .daily-core-loop-puzzle .detective-images::after {
    top: calc(max(var(--daily-core-loop-photo-original-top), var(--daily-core-loop-photo-modified-top)) + 44px + var(--daily-core-loop-photo-height));
  }
  .daily-core-loop-sequential-controls [data-daily-core-loop-picture-scroll] { top: 0; }

  .daily-core-loop-clock svg { width: 24px; height: 24px; }
  .daily-core-loop-clock #timer-display { min-width: 5.5ch; color: inherit; }
  .daily-core-loop-clock #timer-display.timer-penalty { animation: daily-core-loop-clock-oops 500ms ease; }
  .daily-core-loop-clock #timer-display.timer-capped { color: #e86b60; animation: none; }

  /* The CMS editor uses the current photo board in ordinary document flow. Its iframe can be
     resized independently of the Home scene, so the pair scales with the available width. */
  .detective-game.daily-core-loop-game.designer-board-game {
    min-height: 100vh;
    height: auto;
    padding: 18px;
    overflow: visible;
    background: #010b23;
  }

  .designer-board-game .designer-board-puzzle {
    position: relative;
    inset: auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
    pointer-events: auto;
  }

  .designer-board-admin-context {
    display: grid;
    gap: 8px;
    max-width: 1200px;
    width: 100%;
    margin-inline: auto;
    color: #f7efe3;
  }

  .designer-board-admin-context .detective-level-select { margin-bottom: 0; }
  .designer-board-level-summary { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; }
  .designer-board-admin-context .admin-timing-summary { color: #d8d3cf; }

  .designer-board-game .designer-board-puzzle .detective-images {
    position: relative;
    inset: auto;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%;
    height: auto;
    max-width: 1200px;
    margin-inline: auto;
    gap: 8px;
  }

  .designer-board-game .designer-board-puzzle .image-figure {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
  }

  .designer-board-game .designer-board-puzzle .image-panel {
    min-height: 0;
  }

  .designer-board-tools {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px;
    max-width: 1200px;
    margin-inline: auto;
  }

  .designer-board-game .metrics-panel.visible {
    position: static;
    flex: none;
    width: min(100%, 900px);
    max-height: 55vh;
    margin-inline: auto;
  }

  @media (max-width: 720px) {
    .detective-game.daily-core-loop-game.designer-board-game { padding: 8px; }
    .designer-board-game .designer-board-puzzle .detective-images {
      grid-template-columns: minmax(0, 1fr);
    }
    .designer-board-game .designer-board-puzzle .image-figure {
      max-width: 100%;
    }
  }

  .daily-core-loop-penalty {
    position: absolute;
    z-index: 12;
    color: #8a3b32;
    font: 400 17px/1 'ET Title Slab', Georgia, serif;
    text-shadow: 0 0 6px rgb(255 251 247 / 90%), 0 1px 2px rgb(255 251 247 / 70%);
    pointer-events: none;
    transform: translate(-50%, -100%);
    animation: daily-core-loop-penalty-float 1s ease-out forwards;
  }

  @keyframes daily-core-loop-clock-oops { 25% { color: #e86b60; } }
  @keyframes daily-core-loop-penalty-float {
    to { transform: translate(-50%, -100%) translateY(-22px); opacity: 0; }
  }

  /* FOUND RING FADE: the changed photo's put-back patches sit just above the photo and below the
     overlay canvas (7) and the rings (8). Each patch fades by itself, a transition the browser runs
     off the main thread; game-core.js PUT_BACK_FADE_MS, RECAP_FADE_MS and RECAP_DELAY_MS hold the same
     lengths. Under reduced motion the loop's rule makes every transition instant. */
  .put-back-layer {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 6;
  }
  .put-back-layer .put-back-patch {
    position: absolute;
    display: block;
    opacity: 1;
    transition: opacity 700ms cubic-bezier(0.65, 0, 0.35, 1);
  }
  .put-back-layer .put-back-patch.is-hidden { opacity: 0; }
  .put-back-layer .put-back-patch.is-recap { transition-duration: 450ms; transition-delay: 150ms; }

/* Phone round controls share the accepted card's band; the layout owner writes board positions. */
.daily-core-loop-phone-layout .daily-core-loop-score,
.daily-core-loop-phone-layout .daily-core-loop-clock {
  translate: 0 -50%;
  color: #111;
  font-size: calc(24px * var(--daily-core-loop-phone-card-scale));
  line-height: 1;
}
.daily-core-loop-phone-layout .daily-core-loop-score { text-align: left; }
.daily-core-loop-phone-layout .daily-core-loop-score .of { opacity: .6; }
.daily-core-loop-phone-layout .daily-core-loop-tool-row { translate: -50% -50%; }
.daily-core-loop-phone-layout :is(#daily-core-loop-zoom-in, #daily-core-loop-zoom-out) { display: none; }
.daily-core-loop-phone-layout #hint-btn {
  width: calc(31px * var(--daily-core-loop-phone-card-scale));
  height: calc(31px * var(--daily-core-loop-phone-card-scale));
  padding: 0;
  position: relative;
  border: 1px solid var(--card-navy, #010B23);
  border-radius: 50%;
  background: transparent;
}
.daily-core-loop-phone-layout #hint-btn svg {
  width: calc(18px * var(--daily-core-loop-phone-card-scale));
  height: calc(18px * var(--daily-core-loop-phone-card-scale));
}
.daily-core-loop-phone-layout #hint-btn::before {
  content: '';
  position: absolute;
  inset: -7px;
  border-radius: 50%;
}
.daily-core-loop-phone-layout .daily-core-loop-clock {
  gap: calc(6px * var(--daily-core-loop-phone-card-scale));
  letter-spacing: .5px;
}
.daily-core-loop-phone-layout .daily-core-loop-clock svg {
  width: calc(20px * var(--daily-core-loop-phone-card-scale));
  height: calc(20px * var(--daily-core-loop-phone-card-scale));
}
/* Cap ink and inherited icon ink are nonanimated state; only the explicit miss keyframes animate. */
.daily-core-loop-phone-layout .daily-core-loop-clock,
.daily-core-loop-phone-layout .daily-core-loop-clock * { transition-property: none; }
.daily-core-loop-phone-layout .daily-core-loop-clock #timer-display { min-width: 0; color: inherit; animation: none; }
.daily-core-loop-phone-layout .daily-core-loop-clock:has(.timer-penalty) { animation: daily-core-loop-phone-clock-oops 500ms ease; }
.daily-core-loop-phone-layout .daily-core-loop-clock:has(.timer-capped) { color: #C2413A; animation: none; }
@keyframes daily-core-loop-phone-clock-oops { 25% { color: #C2413A; } }

.daily-core-loop-whole-photo {
  display: flex;
  position: absolute;
  translate: 0 -50%;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 15px 0 12px;
  border-radius: 17px;
  border: 1px solid rgba(255,255,255,.6);
  background: rgba(10,10,10,.28);
  color: #fff;
  cursor: pointer;
  font: 700 13px 'ET Sans', sans-serif;
  letter-spacing: .3px;
  pointer-events: auto;
  transition-property: none;
}
.daily-core-loop-whole-photo svg { width: 15px; height: 15px; display: block; }
.daily-core-loop-whole-photo::before { content: ''; position: absolute; inset: -5px -4px; }
.daily-core-loop-whole-photo[aria-hidden='true'] { opacity: 0; visibility: hidden; pointer-events: none; }

/* The live scroller owns the lesson's readable width independently of the picture arrangement. */


.daily-core-loop-touch-play .daily-core-loop-whole-photo { display: none; }
.daily-core-loop-touch-play .daily-core-loop-puzzle .detective-images { overflow: clip; }

[data-daily-core-loop-home-root]:not(.daily-core-loop-phone-layout) .daily-core-loop-whole-photo {
  top: calc(var(--daily-core-loop-pair-top) - 35px);
  left: 50%;
  translate: -50% -50%;
}
