/*
 * Viewer controls (js/core/viewer.js), the maker's camera rail and LOD status (js/core/camera-ui.js).
 * In @layer engine like base.css, so a direction can restyle any of it on cascade order alone.
 * Surfaces come from .chrome-surface (base.css); every colour is a theme token.
 */
@layer engine {

/* ── Camera rail (maker) ─────────────────────────────────────────────────────────────── */
.camera-rail {
  --cam-btn: 36px;
  position: fixed; z-index: 20; right: 16px; top: 50%;
  display: flex; flex-direction: column; gap: 2px;
  width: calc(var(--cam-btn) + 10px); max-height: calc(100svh - 160px);
  padding: 4px; border-radius: var(--radius-lg);
  overflow: hidden auto; scrollbar-width: none; overscroll-behavior: contain;
  opacity: 0; transform: translate(12px, -50%);
  transition:
    width calc(280ms * var(--u-motion)) var(--ease-enter),
    opacity calc(360ms * var(--u-motion)) var(--ease-enter),
    transform calc(360ms * var(--u-motion)) var(--ease-enter),
    background-color calc(600ms * var(--u-motion)) var(--ease-move),
    border-color calc(600ms * var(--u-motion)) var(--ease-move);
}
.camera-rail::-webkit-scrollbar { display: none; }
.camera-rail.is-in { opacity: 1; transform: translate(0, -50%); }
.camera-rail.is-in.is-away { opacity: 0; transform: translate(12px, -50%); pointer-events: none; transition-timing-function: var(--ease-exit); }
.camera-rail:hover, .camera-rail:focus-within { width: 196px; }
/* The rail is the maker's layer: it shows while ⌘⇧D is open, or with ?maker=1. */
html:not(.is-maker) .camera-rail { display: none; }

.cam-group { display: flex; flex-direction: column; gap: 2px; }
.cam-sep { flex: none; height: 1px; margin: 4px 8px; background: var(--line); }

.cam-btn {
  position: relative; flex: none;
  display: grid; grid-template-columns: var(--cam-btn) 1fr auto; align-items: center;
  width: 100%; height: var(--cam-btn); padding: 0 8px 0 0;
  border-radius: calc(var(--radius-lg) - 6px);
  color: var(--text-2); text-align: left; white-space: nowrap;
  transition: background-color var(--dur-fast), color var(--dur-fast), opacity var(--dur-fast);
}
.cam-btn:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.cam-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cam-btn[aria-checked='true'], .cam-btn[aria-pressed='true'] { color: var(--text); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.cam-btn[aria-checked='true'] .cam-ico { color: var(--accent); }
.cam-btn:disabled { color: var(--text-3); background: none; cursor: default; }
.cam-ico { display: grid; place-items: center; width: var(--cam-btn); height: var(--cam-btn); }
.cam-label, .cam-btn kbd {
  opacity: 0; transform: translateX(-4px);
  transition: opacity calc(200ms * var(--u-motion)) var(--ease-enter), transform calc(200ms * var(--u-motion)) var(--ease-enter);
}
.cam-label { font-size: 13px; letter-spacing: 0.005em; overflow: hidden; text-overflow: ellipsis; }
.cam-label b { font-weight: 500; color: var(--text); }
.cam-btn kbd {
  min-width: 18px; height: 18px; padding: 0 4px; display: grid; place-items: center;
  border-radius: 4px; box-shadow: inset 0 0 0 1px var(--line-strong);
  font: 500 10px/1 var(--font-mono); color: var(--text-3);
}
.camera-rail:hover :is(.cam-label, kbd), .camera-rail:focus-within :is(.cam-label, kbd) {
  opacity: 1; transform: none; transition-delay: calc(60ms * var(--u-motion));
}
/* The mode pair reads as one control: the inactive half recedes. */
.cam-mode .cam-btn[aria-checked='false'] .cam-ico { opacity: 0.8; }

/* Detail pips: four bars, filled to the current level; they breathe while generating. */
.cam-pips { display: flex; align-items: flex-end; justify-content: center; gap: 2px; }
.cam-pips i { width: 3px; border-radius: 1px; background: var(--line-strong); transition: background-color calc(240ms * var(--u-motion)); }
.cam-pips i:nth-child(1) { height: 6px; } .cam-pips i:nth-child(2) { height: 9px; }
.cam-pips i:nth-child(3) { height: 12px; } .cam-pips i:nth-child(4) { height: 15px; }
.cam-pips i.on { background: currentColor; }
.is-generating .cam-pips i.on:last-of-type, .is-generating .cam-regen .cam-ico { color: var(--accent); }
.is-generating .cam-regen .cam-ico svg { animation: cam-spin calc(900ms * var(--u-motion)) linear infinite; }
@keyframes cam-spin { to { transform: rotate(360deg); } }

/* Short or narrow screens: tighter buttons; the rail scrolls within its own height. */
@media (max-height: 760px) { .camera-rail { --cam-btn: 30px; } }
@media (max-width: 640px) {
  .camera-rail { right: 8px; --cam-btn: 32px; }
  .camera-rail:hover, .camera-rail:focus-within { width: calc(var(--cam-btn) + 10px); }
  .camera-rail :is(.cam-label, kbd), .cam-zoom-in, .cam-zoom-out { display: none; }
}

/* ── Viewer controls ─────────────────────────────────────────────────────────── */
/* One surface for light and view, bottom-right; the dock owns bottom-left. */
.viewer {
  --vw-h: 48px; --vw-btn: 40px;
  position: fixed; z-index: 20; right: 16px; bottom: calc(16px + var(--vw-lift, 0px));
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  font-size: 13px; color: var(--chrome-text, var(--text));
  opacity: 0; transform: translateY(8px);
  transition: opacity calc(420ms * var(--u-motion)) var(--ease-enter), transform calc(420ms * var(--u-motion)) var(--ease-enter), bottom calc(420ms * var(--u-motion)) var(--ease-move);
}
.viewer.is-in { opacity: 1; transform: none; }
.viewer.is-away { opacity: 0; transform: translateY(8px); pointer-events: none; transition-timing-function: var(--ease-exit); }
.viewer[data-light='none'] .vw-needs-light { display: none !important; }

.vw-bar { display: flex; align-items: center; gap: 2px; height: var(--vw-h); padding: 3px; border-radius: var(--radius-lg); }
.vw-btn {
  position: relative; display: inline-flex; align-items: center; gap: 8px; flex: none;
  height: var(--vw-btn); min-width: var(--vw-btn); padding: 0; border-radius: calc(var(--radius-lg) - 4px);
  color: var(--text-2); white-space: nowrap;
  transition: background-color var(--dur-fast), color var(--dur-fast);
}
.vw-btn:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.vw-btn:focus-visible, .vw-word:focus-visible, .vw-link:focus-visible, .vw-close:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.vw-ico { display: grid; place-items: center; width: var(--vw-btn); height: var(--vw-btn); flex: none; }
.vw-text { font-size: 13px; letter-spacing: 0.005em; color: var(--text); }
.vw-btn .vw-ico + .vw-text { margin-left: -6px; padding-right: 12px; }

/* ── A · Lantern: two labelled halves, LIGHT | CAMERA ── */
/* Each half is a button: a live icon, an eyebrow that says what it is, and the current value. */
.vw-cluster {
  position: relative; display: inline-flex; align-items: center; gap: 8px; flex: none;
  height: var(--vw-btn); padding: 0 12px 0 6px; border-radius: calc(var(--radius-lg) - 4px);
  color: var(--text-2); white-space: nowrap; text-align: left;
  transition: background-color var(--dur-fast), color var(--dur-fast), box-shadow var(--dur-fast);
}
.vw-cluster:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.vw-cluster:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.vw-cluster[aria-expanded='true'] { color: var(--text); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.vw-cluster .vw-ico { width: 28px; height: 28px; }
.vw-two { display: grid; gap: 3px; min-width: 0; }
.vw-eyebrow { font: 600 9.5px/1 var(--font-mono); letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-2); }
.vw-value { font-size: 13px; line-height: 1.1; color: var(--text); max-width: 112px; overflow: hidden; text-overflow: ellipsis; }
.vw-rule { flex: none; width: 1px; height: 24px; margin: 0 2px; background: var(--line); }

/* The light's icon: a sun whose disc is the mood's sky. Its rays turn with the sun's bearing,
   shorten at blue hour and retract at night, when a bite slides in and leaves a crescent. */
.vw-sunico .vw-rays { transform-origin: 12px 12px; transform: rotate(var(--vw-rays, 0deg)) scale(1);
  transition: transform calc(var(--vw-wedge, 420ms) * var(--u-motion)) var(--ease-move), opacity calc(var(--vw-wedge, 420ms) * var(--u-motion)); }
.vw-sunico .vw-bite { transform: translate(10px, -10px); transition: transform calc(var(--vw-wedge, 420ms) * var(--u-motion)) var(--ease-move); }
.vw-sunico stop { transition: stop-color calc(600ms * var(--u-motion)) var(--ease-move); }
.viewer[data-sky='low'] .vw-sunico .vw-rays { transform: rotate(var(--vw-rays, 0deg)) scale(0.82); opacity: 0.7; }
.viewer[data-sky='moon'] .vw-sunico .vw-rays { transform: rotate(var(--vw-rays, 0deg)) scale(0.4); opacity: 0; }
.viewer[data-sky='moon'] .vw-sunico .vw-bite { transform: none; }

/* The camera's icon: the plan in miniature — subject, orbit, and the camera's wedge on it. */
.vw-mini { overflow: visible; }
.vw-mini-arc { opacity: 0.55; }
.vw-mini-cone { fill: var(--accent); opacity: 0.6; }
.vw-camera.is-arrived .vw-mini { animation: vw-pop calc(var(--vw-pop, 460ms) * var(--vw-pulse-k, 1) * var(--u-motion)) var(--ease-enter); }
@keyframes vw-pop { 0% { transform: scale(1); } 35% { transform: scale(1.18); } 100% { transform: scale(1); } }

/* View: a glyph of the set, the camera's dot, and a ghost dot where the next view stands. */
.vw-glyph .vw-dot, .vw-glyph .vw-ghost { transition: transform calc(520ms * var(--u-motion)) var(--ease-move), opacity var(--dur-fast); }
.vw-glyph .vw-ghost { opacity: 0; }
.vw-view:hover .vw-ghost, .vw-view:focus-visible .vw-ghost { opacity: 0.35; }
.vw-view .vw-ico + .vw-text { display: block; max-width: 0; overflow: hidden; padding-right: 0; margin-left: -6px; opacity: 0;
  transition: max-width calc(280ms * var(--u-motion)) var(--ease-enter), opacity calc(200ms * var(--u-motion)), padding calc(280ms * var(--u-motion)) var(--ease-enter); }
.vw-view:hover .vw-ico + .vw-text, .vw-view:focus-visible .vw-ico + .vw-text { max-width: 110px; opacity: 1; padding-right: 12px; }

/* Recentre: only once the visitor has moved off the director's shot. */
.vw-recentre { max-width: 0; min-width: 0; opacity: 0; overflow: hidden; pointer-events: none;
  transition: max-width calc(320ms * var(--u-motion)) var(--ease-enter), opacity calc(220ms * var(--u-motion)) var(--ease-enter), background-color var(--dur-fast), color var(--dur-fast); }
.viewer.is-moved .vw-recentre { max-width: 140px; opacity: 1; pointer-events: auto; }
.vw-recentre .vw-text { color: var(--text-2); }
.vw-recentre:hover .vw-text { color: var(--text); }

/* Lamps: the bulb glows when the practicals are on. */
.vw-lamp .vw-ico { position: relative; }
.vw-lamp-glow { position: absolute; left: 50%; top: 46%; width: 18px; height: 18px; margin: -9px; border-radius: 50%;
  background: radial-gradient(circle, rgb(255 200 120 / 0.85), rgb(255 190 110 / 0) 70%); opacity: 0; transform: scale(0.4);
  transition: opacity calc(420ms * var(--u-motion)) var(--ease-enter), transform calc(420ms * var(--u-motion)) var(--ease-enter); }
.vw-lamp[aria-pressed='true'] { color: var(--text); }
.vw-lamp[aria-pressed='true'] .vw-lamp-glow { opacity: 1; transform: scale(1); }
.vw-lamp svg { position: relative; }

/* ── A · Lantern: the cards rise out of the pill, one at a time ── */
.vw-cards { position: absolute; right: 0; bottom: calc(100% + 8px); display: grid; justify-items: end; align-items: end; pointer-events: none; }
.vw-cards > .vw-card { grid-area: 1 / 1; }
.vw-card {
  width: 320px; padding: 12px; border-radius: var(--radius-lg);
  display: grid; gap: 12px;
  transform-origin: 70% 100%;
  opacity: 0; transform: translateY(8px) scale(0.98); visibility: hidden; pointer-events: none;
  transition: opacity calc(var(--vw-card-out, 220ms) * var(--u-motion)) var(--ease-exit), transform calc(var(--vw-card-out, 220ms) * var(--u-motion)) var(--ease-exit), visibility 0s calc(var(--vw-card-out, 220ms) * var(--u-motion)), background-color calc(600ms * var(--u-motion)) var(--ease-move);
}
.vw-card-camera { transform-origin: 40% 100%; }
.viewer.is-open-light .vw-card-light, .viewer.is-open-camera .vw-card-camera {
  opacity: 1; transform: none; visibility: visible; pointer-events: auto;
  transition: opacity calc(260ms * var(--u-motion)) var(--ease-enter), transform calc(var(--vw-card-in, 360ms) * var(--u-motion)) var(--ease-enter), visibility 0s;
}
.vw-card-head .vw-card-ico { grid-row: 1 / span 2; display: grid; place-items: center; width: 28px; height: 28px; margin: -2px 0 0 -2px; color: var(--text-2); }
.vw-card-head:has(.vw-card-ico) { grid-template-columns: auto 1fr auto; }
.vw-card-head:has(.vw-card-ico) .vw-card-title { grid-column: 2; }
.vw-card-head:has(.vw-card-ico) .vw-card-note { grid-column: 2; }
.vw-card-head:has(.vw-card-ico) .vw-close { grid-column: 3; }

/* The camera card's plan: the set from above, the director's side at the bottom. Bookmark wedges
   point at the subject; the live wedge (accent) orbits as the picture moves. */
.vw-planwrap { border-radius: var(--radius-md); overflow: hidden; background: color-mix(in srgb, var(--text) 4%, var(--surface-2)); box-shadow: inset 0 0 0 1px var(--line); }
.vw-plan { display: block; width: 100%; height: auto; touch-action: none; cursor: crosshair; -webkit-user-select: none; user-select: none; }
.vw-plan.is-held { cursor: grabbing; }
.vw-plan pattern circle { fill: color-mix(in srgb, var(--text) 20%, transparent); }
.vw-plan-orbit { fill: none; stroke: color-mix(in srgb, var(--text) 32%, transparent); stroke-width: 1; stroke-dasharray: 2 4; stroke-linecap: round; }
.vw-plan-stage { fill: color-mix(in srgb, var(--text) 6%, transparent); stroke: color-mix(in srgb, var(--text) 28%, transparent); stroke-width: 1; }
.vw-plan-object { fill: var(--text-2); }
.vw-plan-shadow { fill: color-mix(in srgb, var(--text) 18%, transparent); transition: opacity var(--dur-fast); }
.vw-plan-sun { fill: var(--vw-sun, #fff4dc); stroke: var(--text-2); stroke-width: 1; }
.viewer[data-plan-light='off'] .vw-plan-light { display: none; }
.vw-mark { cursor: pointer; }
.vw-mark-hit { fill: transparent; }
.vw-mark-cone { fill: color-mix(in srgb, var(--text) 10%, transparent); stroke: color-mix(in srgb, var(--text) 50%, transparent); stroke-width: 1; stroke-linejoin: round;
  transform-box: view-box; transform-origin: 0 0;
  transition: fill calc(var(--vw-wedge, 420ms) * var(--u-motion)) var(--ease-move), stroke calc(var(--vw-wedge, 420ms) * var(--u-motion)), transform calc(var(--vw-wedge, 420ms) * var(--u-motion)) var(--ease-enter); }
.vw-mark-body { fill: var(--chrome-bg, var(--bg)); stroke: var(--text-2); stroke-width: 1.5; transition: fill var(--dur-fast), stroke var(--dur-fast); }
.vw-mark.is-hover .vw-mark-cone { fill: color-mix(in srgb, var(--text) 18%, transparent); stroke: var(--text); transform: scale(1.14); }
.vw-mark.is-hover .vw-mark-body { stroke: var(--text); }
.vw-mark.is-on .vw-mark-cone { fill: color-mix(in srgb, var(--accent) 22%, transparent); stroke: var(--accent); }
.vw-mark.is-on .vw-mark-body { fill: var(--accent); stroke: var(--accent); }
.vw-plan[data-snap]:not([data-snap='']) .vw-mark-cone { transition-duration: calc(160ms * var(--u-motion)); }
.vw-mark-pulse { fill: none; stroke: var(--accent); stroke-width: 1.5; opacity: 0; transform-box: fill-box; transform-origin: center; }
.vw-mark.is-arrived .vw-mark-pulse { animation: vw-ring calc(var(--vw-pulse, 720ms) * var(--vw-pulse-k, 1) * var(--u-motion)) var(--ease-enter); }
@keyframes vw-ring { 0% { opacity: 0.9; transform: scale(0.5); } 100% { opacity: 0; transform: scale(2.1); } }
.vw-live { pointer-events: none; }
.vw-plan #vw-plan-cone stop:first-child { stop-color: var(--accent); stop-opacity: 0.5; }
.vw-plan #vw-plan-cone stop:last-child { stop-color: var(--accent); stop-opacity: 0.04; }
.vw-live-halo { fill: color-mix(in srgb, var(--accent) 16%, transparent); }
.vw-live-body, .vw-live-lens { fill: var(--accent); stroke: var(--chrome-bg, var(--bg)); stroke-width: 1.25; }
.vw-plan-tag { font: 600 9.5px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; fill: var(--text);
  paint-order: stroke; stroke: var(--chrome-bg, var(--bg)); stroke-width: 3.5px; stroke-linejoin: round; pointer-events: none; }

/* The views, as chips under the plan (the plan's wedges and these light up together). */
.vw-views { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.vw-viewchip { display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 32px; padding: 0 6px; border-radius: 8px;
  font-size: 12px; color: var(--text-2); background: color-mix(in srgb, var(--text) 5%, transparent);
  transition: background-color var(--dur-fast), color var(--dur-fast), box-shadow var(--dur-fast); }
.vw-viewchip:hover, .vw-viewchip.is-hover { color: var(--text); background: color-mix(in srgb, var(--text) 10%, transparent); }
.vw-viewchip[aria-pressed='true'] { color: var(--text); background: color-mix(in srgb, var(--accent) 14%, transparent); box-shadow: inset 0 0 0 1.5px var(--accent); }
.vw-viewchip:focus-visible, .vw-step:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.vw-zoom { display: inline-flex; gap: 2px; margin-right: auto; }
.vw-step { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; color: var(--text-2); transition: background-color var(--dur-fast), color var(--dur-fast); }
.vw-step:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.vw-cam-foot .vw-home svg { flex: none; }

.vw-card-head { display: grid; grid-template-columns: 1fr auto; align-items: start; gap: 2px 8px; }
.vw-card-title { font-weight: 600; color: var(--text); }
.vw-card-note { grid-row: 2; color: var(--text-2); font-size: 12px; line-height: 1.35; }
.vw-close { grid-row: 1 / span 2; grid-column: 2; display: grid; place-items: center; width: 28px; height: 28px; margin: -4px -4px 0 0; border-radius: 8px; color: var(--text-3); }
.vw-close:hover { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.vw-moods { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.vw-mood { display: grid; justify-items: center; gap: 5px; padding: 6px 0 4px; border-radius: 10px; color: var(--text-2); font-size: 10.5px; line-height: 1.1; }
.vw-mood:hover { color: var(--text); background: color-mix(in srgb, var(--text) 6%, transparent); }
.vw-chip { position: relative; width: 30px; height: 30px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.14); transition: transform calc(240ms * var(--u-motion)) var(--ease-enter), box-shadow calc(240ms * var(--u-motion)); }
.vw-chip i { position: absolute; left: 50%; top: 42%; width: 8px; height: 8px; margin: -4px; border-radius: 50%; box-shadow: 0 0 6px 1px currentColor; color: rgb(255 240 210 / 0.7); }
.vw-mood[data-mood='look'] .vw-chip i { display: none; }
.vw-mood[aria-checked='true'] { color: var(--text); }
.vw-mood[aria-checked='true'] .vw-chip { box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.14), 0 0 0 2px var(--chrome-bg, var(--bg)), 0 0 0 3.5px var(--accent); transform: scale(1.04); }
.vw-mood-name { white-space: nowrap; }
.vw-mood:focus-visible { outline: none; }
.vw-mood:focus-visible .vw-chip { outline: 2px solid var(--accent); outline-offset: 4px; }

.vw-pad { position: relative; height: 104px; border-radius: var(--radius-md); overflow: hidden; cursor: grab; touch-action: none;
  box-shadow: inset 0 0 0 1px var(--line); }
.vw-pad:active { cursor: grabbing; }
.vw-pad:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vw-pad-sky { position: absolute; inset: 0; transition: background calc(600ms * var(--u-motion)) var(--ease-move); }
.vw-pad-horizon { position: absolute; left: 0; right: 0; bottom: 0; height: 18px; display: flex; align-items: center; padding: 0 8px; font: 500 9.5px/1 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-2); background: color-mix(in srgb, var(--text) 18%, var(--surface-2)); border-top: 1px solid color-mix(in srgb, var(--text) 22%, transparent); }
.vw-pad-sun {
  position: absolute; width: 16px; height: 16px; margin: -8px;
  left: calc(8px + var(--u, 0.5) * (100% - 16px)); top: calc(8px + var(--v, 0.5) * (100% - 26px));
  border-radius: 50%; background: radial-gradient(circle at 40% 40%, #fff, var(--vw-sun, #fff8e8) 70%);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.18), 0 0 14px 4px color-mix(in srgb, var(--vw-sun, #fff) 70%, transparent);
}
.vw-card-foot { display: flex; align-items: center; gap: 4px; }
.vw-card-foot .vw-lamp { margin-right: auto; padding-right: 4px; }
.vw-card-foot .vw-lamp .vw-ico { width: 32px; }
.vw-card-foot .vw-lamp .vw-text { margin-left: -4px; padding-right: 8px; color: inherit; }
.vw-link { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; border-radius: 8px; color: var(--text-2); font-size: 12px; }
.vw-link:hover:not(:disabled) { color: var(--text); background: color-mix(in srgb, var(--text) 7%, transparent); }
.vw-link:disabled { color: var(--text-3); cursor: default; }

/* ── B · Sundial ── */
.viewer[data-concept='b'] { flex-direction: row; align-items: center; }
.vw-dialwrap { position: relative; }
.vw-dial { position: relative; width: 64px; height: 64px; border-radius: 50%; padding: 0; }
.vw-dial-ring { position: absolute; inset: 4px; border-radius: 50%; cursor: grab; touch-action: none;
  -webkit-mask: radial-gradient(circle, transparent 0 17px, #000 17.5px); mask: radial-gradient(circle, transparent 0 17px, #000 17.5px); }
.vw-dial.is-turning .vw-dial-ring { cursor: grabbing; }
.vw-dial-ring:focus-visible { outline: none; }
.vw-dial:has(.vw-dial-ring:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.vw-dial-needle { position: absolute; inset: 4px; pointer-events: none; transform: rotate(var(--vw-angle, 0deg));
  transition: transform calc(620ms * var(--u-motion)) var(--ease-move); }
.vw-dial.is-turning .vw-dial-needle { transition-duration: calc(90ms * var(--u-motion)); }
.vw-dial-needle i { position: absolute; left: 50%; top: 1px; width: 11px; height: 11px; margin-left: -5.5px; border-radius: 50%;
  background: var(--vw-sun, #fff); box-shadow: 0 0 0 1.5px var(--chrome-bg, var(--bg)), 0 0 0 2.5px var(--text), 0 0 10px 2px color-mix(in srgb, var(--vw-sun, #fff) 60%, transparent); }
.vw-dial-lamp.vw-btn { position: absolute; left: 50%; top: 50%; width: 32px; height: 32px; min-width: 0; margin: -16px; border-radius: 50%; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.vw-dial-lamp .vw-ico { width: 32px; height: 32px; }
.vw-dial-label { position: absolute; right: 0; bottom: calc(100% + 8px); display: grid; gap: 2px; width: max-content; max-width: 240px; padding: 8px 12px; border-radius: var(--radius-md);
  opacity: 0; transform: translateY(4px); pointer-events: none;
  transition: opacity calc(220ms * var(--u-motion)) var(--ease-exit), transform calc(220ms * var(--u-motion)) var(--ease-exit); }
.vw-dial-label b { font-weight: 600; color: var(--text); }
.vw-dial-label span { font-size: 12px; color: var(--text-2); }
.vw-dialwrap:hover .vw-dial-label, .vw-dialwrap:focus-within .vw-dial-label, .vw-dialwrap:has(.is-turning) .vw-dial-label { opacity: 1; transform: none; transition-timing-function: var(--ease-enter); }
.vw-side { height: 48px; }

/* ── D · Caption ── */
.vw-caption { display: flex; align-items: center; flex-wrap: wrap; gap: 0 6px; min-height: 44px; margin: 0; padding: 6px 8px 6px 14px; border-radius: var(--radius-lg); color: var(--text-2); font-size: 13px; }
.vw-caption > span { display: contents; }
.vw-word { padding: 3px 4px; margin: 0 -2px; border-radius: 6px; color: var(--text); font-weight: 500;
  text-decoration: underline dotted color-mix(in srgb, var(--text) 45%, transparent); text-underline-offset: 4px; text-decoration-thickness: 1.5px;
  transition: background-color var(--dur-fast), text-decoration-color var(--dur-fast); }
.vw-word:hover { background: color-mix(in srgb, var(--text) 7%, transparent); text-decoration-color: var(--accent); }
.vw-dot-sep { color: var(--text-3); }
.vw-word-recentre { display: none; text-decoration: none; padding: 4px; margin-left: 4px; color: var(--text-2); }
.viewer.is-moved .vw-word-recentre { display: inline-grid; place-items: center; }

/* ── The sun in the scene ── */
.vw-sky { position: fixed; inset: 0; z-index: 18; pointer-events: none; }
.vw-sky[data-light='none'] { display: none; }
.vw-sun {
  position: absolute; left: 0; top: 0; width: 48px; height: 48px; margin: -24px 0 0 -24px; padding: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: grab; touch-action: none; pointer-events: none;
  opacity: 0; scale: 0.6;
  transition: opacity calc(320ms * var(--u-motion)) var(--ease-exit), scale calc(320ms * var(--u-motion)) var(--ease-exit);
}
.vw-sky.is-on .vw-sun { opacity: 1; scale: 1; pointer-events: auto; transition-timing-function: var(--ease-enter); }
.vw-sky.is-away .vw-sun { opacity: 0; pointer-events: none; }
.vw-sky.is-held .vw-sun { cursor: grabbing; scale: 1.12; }
.vw-sun:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vw-sun-disc { position: absolute; left: 50%; top: 50%; width: 20px; height: 20px; margin: -10px; border-radius: 50%;
  background: radial-gradient(circle at 40% 38%, #fff 0 22%, var(--vw-sun, #fff4dc) 70%);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.16), 0 0 18px 5px color-mix(in srgb, var(--vw-sun, #fff4dc) 60%, transparent), 0 0 52px 18px color-mix(in srgb, var(--vw-sun, #fff4dc) 22%, transparent);
  transition: background calc(600ms * var(--u-motion)) var(--ease-move), box-shadow calc(600ms * var(--u-motion)) var(--ease-move); }
.vw-sun-halo { position: absolute; inset: 4px; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--vw-sun, #fff) 85%, transparent) 0 5deg, transparent 5deg 30deg);
  -webkit-mask: radial-gradient(circle, transparent 0 14px, #000 15px 19px, transparent 19.5px); mask: radial-gradient(circle, transparent 0 14px, #000 15px 19px, transparent 19.5px);
  animation: vw-turn 48s linear infinite; opacity: 0.9; transition: opacity calc(400ms * var(--u-motion)); }
.vw-sun:hover .vw-sun-halo, .vw-sky.is-held .vw-sun-halo { animation-duration: 12s; }
@keyframes vw-turn { to { transform: rotate(360deg); } }
.vw-sun[data-kind='moon'] .vw-sun-halo, .vw-sun[data-kind='set'] .vw-sun-halo { opacity: 0; }
.vw-sun[data-kind='moon'] .vw-sun-disc { background: #f4efe2; -webkit-mask: radial-gradient(circle at 72% 30%, transparent 0 7.5px, #000 8px); mask: radial-gradient(circle at 72% 30%, transparent 0 7.5px, #000 8px);
  box-shadow: 0 0 16px 4px rgb(220 230 255 / 0.35); }
.vw-sun[data-kind='set'] .vw-sun-disc { opacity: 0.75; }
.vw-sun-tip { position: absolute; top: calc(100% + 2px); left: 50%; translate: -50% 0; padding: 4px 8px; border-radius: 999px; white-space: nowrap;
  font: 500 11px/1.2 var(--font-mono); letter-spacing: 0.02em; color: var(--chrome-text, var(--text)); background: var(--chrome-bg); border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  opacity: 0; transform: translateY(-3px); transition: opacity calc(200ms * var(--u-motion)) var(--ease-exit), transform calc(200ms * var(--u-motion)) var(--ease-exit); pointer-events: none; }
.vw-sun:hover .vw-sun-tip, .vw-sun:focus-visible .vw-sun-tip, .vw-sky.is-held .vw-sun-tip { opacity: 1; transform: none; transition-timing-function: var(--ease-enter); }
.vw-horizon { position: absolute; left: 10%; right: 10%; top: 70%; height: 0; border-top: 1px dashed color-mix(in srgb, var(--text) 40%, transparent);
  opacity: 0; transition: opacity calc(300ms * var(--u-motion)) var(--ease-move); }
.vw-horizon b { position: absolute; right: 0; top: 4px; font: 500 10px/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-2); }
.vw-sky.is-held .vw-horizon { opacity: 0.8; }

/* ── First-visit hint ── */
/* It sits on the viewer it belongs to (bottom-right, above the pill), clear of the centred story
   cue and the dock; on narrow screens it floats in the open sky under the top bar instead. */
.vw-hint { --hx: 0; position: fixed; z-index: 19; right: 16px; bottom: calc(76px + var(--vw-lift, 0px)); margin: 0; display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  height: 36px; padding: 0 14px 0 10px; border-radius: 999px; font-size: 13px; color: var(--text); pointer-events: none;
  opacity: 0; transform: translate(var(--hx), 6px);
  transition: opacity calc(500ms * var(--u-motion)) var(--ease-exit), transform calc(500ms * var(--u-motion)) var(--ease-exit); }
.vw-hint.is-on { opacity: 1; transform: translate(var(--hx), 0); transition-timing-function: var(--ease-enter); }
.vw-hint-hand { position: relative; width: 28px; height: 16px; }
.vw-hint-hand::before { content: ''; position: absolute; left: 2px; right: 2px; top: 50%; border-top: 1.5px dotted var(--text-3); }
.vw-hint-hand i { position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px; border-radius: 50%; background: var(--text); box-shadow: 0 0 0 3px color-mix(in srgb, var(--text) 18%, transparent);
  animation: vw-swipe calc(1800ms * var(--u-motion, 1)) var(--ease-move) infinite; }
@keyframes vw-swipe { 0%, 100% { transform: translateX(-8px); } 50% { transform: translateX(8px); } }

/* Narrow: the dock spans the bottom, so the viewer sits just above it on the right. */
@media (max-width: 760px) {
  .viewer { right: 12px; bottom: 72px; --vw-h: 44px; --vw-btn: 38px; }
  .vw-card { width: min(320px, calc(100vw - 24px)); }
  .vw-hint { --hx: -50%; right: auto; left: 50%; bottom: auto; top: 96px; }
  /* The dock's one-time invite spans the row the viewer sits on (and above it is the story cue):
     the viewer steps aside for those nine seconds and comes back when the invite goes. */
  html:has(.director.is-inviting) .viewer.is-in { opacity: 0; pointer-events: none; transform: translateY(8px); }
  .vw-dial { width: 56px; height: 56px; }
  .vw-dial-ring { -webkit-mask: radial-gradient(circle, transparent 0 14px, #000 14.5px); mask: radial-gradient(circle, transparent 0 14px, #000 14.5px); }
  .vw-dial-lamp.vw-btn { width: 28px; height: 28px; margin: -14px; }
  .vw-caption { font-size: 12.5px; max-width: calc(100vw - 24px); }
}
/* Touch: every Lantern target reaches 44px. */
@media (pointer: coarse) {
  .vw-viewchip, .vw-step, .vw-link { height: 44px; }
  .vw-step { width: 44px; }
  .vw-close { width: 44px; height: 44px; margin: -10px -10px -6px 0; }
  .viewer[data-concept='a'] .vw-cluster, .viewer[data-concept='a'] .vw-bar .vw-recentre { min-height: 44px; }
  .viewer.is-moved[data-concept='a'] .vw-bar .vw-recentre { min-width: 44px; justify-content: center; }
}
/* Narrowest: the pill's recentre keeps only its icon; both labels stay. */
@media (max-width: 480px) {
  .viewer[data-concept='a'] .vw-recentre .vw-text { display: none; }
  .vw-value { max-width: 96px; }
}
@media (prefers-reduced-motion: reduce) {
  .vw-sun-halo, .vw-hint-hand i, .vw-mark-pulse, .vw-camera .vw-mini { animation: none !important; }
  .vw-mark-cone, .vw-sunico .vw-rays, .vw-sunico .vw-bite { transition: none; }
}

/* Generation status: a quiet pill at top centre, only while the set builds up. */
.cam-status {
  position: fixed; z-index: 20; top: var(--edge, 16px); left: 50%;
  height: 28px; padding: 0 12px; display: inline-flex; align-items: center;
  border-radius: 999px; font: 500 11px/1 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-2);
  opacity: 0; transform: translate(-50%, -6px); pointer-events: none;
  transition: opacity calc(240ms * var(--u-motion)) var(--ease-exit), transform calc(240ms * var(--u-motion)) var(--ease-exit);
}
.cam-status.on:not(.is-away) { opacity: 1; transform: translate(-50%, 0); transition-timing-function: var(--ease-enter); }

/* Touch pad behind the hero copy (see camera-ui.js). */
.camera-pad { position: absolute; inset: 0; z-index: -1; pointer-events: auto; touch-action: pan-y; }

/* Cursor: the free camera announces itself wherever a drag would move it. */
html.is-camera-over, html.is-camera-over .camera-pad { cursor: grab; }

} /* @layer engine */
