/* Vulcora world v2 — premium marker grammar over film.
   Palette sampled from the renders; type: Cormorant Garamond (myth) ·
   Archivo caps (wayfinding) · JetBrains Mono (proof). */

:root {
  --night:  #0a0b0d;
  --night-1:#101216;
  --bone:   #e8e4da;   /* the pale stone */
  --ash:    #8e8a80;
  --faint:  #55584f;
  --nacre:  #3fbfb4;   /* the ocelli glow */
  --ember:  #c96a2b;   /* the forge */
  --true:   #f2f3f0;

  --serif: 'Cormorant Garamond', Georgia, serif;
  --caps:  'Archivo', system-ui, sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, monospace;

  --ease: cubic-bezier(.22,.9,.28,1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

html, body { height: 100%; background: var(--night); color: var(--bone); overflow: hidden; }
html, body {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;                 /* every touch belongs to the game */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;        /* long-press holds, not save-sheets */
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}
body { font-family: var(--serif); }
/* panels scroll by finger even though the game owns every other touch */
#help-modal, #journal-layer, #card, #card-body { touch-action: pan-y; }

#world { position: fixed; inset: 0; }
.layer { position: absolute; inset: 0; pointer-events: none; }

/* ── the stage — fixed-aspect, cover-fit, markers track the film ─────── */
#stage { position: absolute; /* sized by JS */ }
#stage-image {
  position: absolute; inset: 0;
  background-size: 100% 100%;
  opacity: 0;
  transition: opacity 1.6s var(--ease);
}
#stage-image.on { opacity: 1; }
#stage.strain #stage-image { animation: shudder .3s linear infinite; }
@keyframes shudder {
  0%{transform:translate(0,0)} 25%{transform:translate(2px,-1px)}
  50%{transform:translate(-2px,1px)} 75%{transform:translate(1px,2px)} 100%{transform:translate(0,0)}
}

#fx { position: absolute; inset: 0; pointer-events: none; }
#streams { position: absolute; inset: 0; pointer-events: none; }
#items-near, #items-far { position: absolute; inset: 0; pointer-events: none; }

/* ── the item layer — objects that pop and mean ──────────────────────── */
.item {
  position: absolute;
  transform: translate(-50%, -50%);
  background: none; border: 0; cursor: pointer;
  pointer-events: auto;
  filter: drop-shadow(0 8px 20px rgba(0,0,0,.7));
  transition: transform .35s var(--ease), filter .35s var(--ease);
}
.item img {
  width: 100%; display: block;
  animation: item-breathe 5s ease-in-out infinite;
}
/* the sprite only BREATHES — the color lives behind it, never on it */
@keyframes item-breathe {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.14); }
}
.item::before {
  content: '';
  position: absolute;
  inset: -42%;
  background: radial-gradient(circle, var(--aura, rgba(63,191,180,.28)), transparent 66%);
  border-radius: 50%;
  z-index: -1;
  animation: aura-breathe 5.5s ease-in-out infinite;
  pointer-events: none;
}
.item:hover, .item:focus-visible {
  transform: translate(-50%, -52%) scale(1.14);
  filter: drop-shadow(0 14px 30px rgba(0,0,0,.8)) drop-shadow(0 0 22px rgba(63,191,180,.25));
  outline: none;
  z-index: 5;
}
.item.depth-far { opacity: .85; }
/* dormant watchers: a readable SILHOUETTE inside a breathing aura — the
   color sits BEHIND the artifact (a halo), never smeared on top of it */
.item.dim { opacity: .95; filter: grayscale(.5) brightness(.9); }
.item.dim img {
  animation: none;
  /* a hair of warm rim: a sleeping statue, not a shadow */
  filter: drop-shadow(0 0 2px rgba(201, 106, 43, .4)) drop-shadow(0 2px 8px rgba(0, 0, 0, .8));
}
.item.dim::before {
  content: '';
  position: absolute;
  inset: -50%;
  background: radial-gradient(circle, rgba(63, 191, 180, .38), rgba(63, 191, 180, .14) 45%, transparent 68%);
  border-radius: 50%;
  z-index: -1;
  animation: aura-breathe 5.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes aura-breathe {
  0%, 100% { opacity: .65; transform: scale(.92); }
  50% { opacity: 1; transform: scale(1.08); }
}
.item.woke { opacity: 1; }
.item.woke img { animation: woke-warm 5s ease-in-out infinite; }
@keyframes woke-warm {
  0%, 100% { filter: brightness(1.05) drop-shadow(0 0 8px rgba(201, 106, 43, .2)); }
  50% { filter: brightness(1.25) drop-shadow(0 0 18px rgba(201, 106, 43, .5)); }
}
.instrument {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 4.5vmin;
  pointer-events: none;
  transition: filter 1.2s ease, opacity 1.2s ease;
  filter: brightness(1) drop-shadow(0 0 12px rgba(201,106,43,.35));
}
.instrument.cold { filter: brightness(.32) saturate(.5); opacity: .75; }
/* the instrument sprites are pure visuals — their hotspot column owns the clicks */
.centered-form { width: 13vmin; }
.item-label {
  position: absolute; top: calc(100% + 2px); left: 50%;
  transform: translateX(-50%);
  font-family: var(--caps);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--bone);
  white-space: nowrap;
  text-shadow: 0 1px 10px rgba(0,0,0,.95);
  opacity: 0; transition: opacity .3s;
  pointer-events: none;
}
.item:hover .item-label, .item:focus-visible .item-label { opacity: 1; }

/* ── presence — the scene answers your hand ──────────────────────────── */
.presence-fx {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.p-glint, .p-thread {
  width: 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle, rgba(63,191,180,.8), transparent 70%);
  animation: p-fade 1.1s ease-out forwards;
}
.p-ripple {
  width: 10px; height: 10px; border-radius: 50%;
  border: 1px solid rgba(232,228,218,.5);
  animation: p-ring 1.2s ease-out forwards;
}
.p-spark {
  width: 5px; height: 5px; border-radius: 50%;
  background: radial-gradient(circle, rgba(201,106,43,.95), transparent 75%);
  animation: p-rise 1.1s ease-out forwards;
}
.p-ash {
  width: 6px; height: 6px;
  background: rgba(201,106,43,.5);
  transform: translate(-50%,-50%) rotate(45deg);
  animation: p-fade 1.3s ease-out forwards;
}
.p-stir {
  width: 9px; height: 9px; border-radius: 50%;
  background: radial-gradient(circle, rgba(122,66,180,.6), transparent 70%);
  animation: p-fade 1.2s ease-out forwards;
}
.p-stone {
  width: 9px; height: 9px; border-radius: 50%;
  background: radial-gradient(circle, rgba(232,228,218,.55), transparent 70%);
  animation: p-fade 1s ease-out forwards;
}
/* the crown — centering noon-gold, held and even, not flame */
.p-noon {
  width: 11px; height: 11px; border-radius: 50%;
  background: radial-gradient(circle, rgba(240,199,92,.85), rgba(224,168,64,.22) 45%, transparent 72%);
  animation: p-fade 1.25s ease-out forwards;
}
@keyframes p-fade { from { opacity: .9; } to { opacity: 0; } }
@keyframes p-ring { from { opacity: .8; } to { opacity: 0; width: 52px; height: 52px; } }
@keyframes p-rise { from { opacity: .95; } to { opacity: 0; translate: 0 -34px; } }

/* ── the games, visible: vessels, threads, stamps, oaths ─────────────── */
.vessel {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 6.5vmin;
  pointer-events: none;
  animation: vessel-bob 3.4s ease-in-out infinite;
}
@keyframes vessel-bob { 0%,100% { margin-top: 0; } 50% { margin-top: 6px; } }
.vessel img { width: 100%; display: block; filter: drop-shadow(0 6px 16px rgba(0,0,0,.7)); }
.vessel-noise {
  position: absolute; top: -4px; left: 50%;
  width: 9px; height: 9px; border-radius: 50%;
  background: radial-gradient(circle, rgba(63,191,180,.95), transparent 70%);
  animation: noise-flicker .55s steps(2) infinite;
}
@keyframes noise-flicker { 0% { opacity: 1; translate: -6px 0; } 50% { opacity: .15; translate: 5px -3px; } 100% { opacity: .9; translate: 0 2px; } }
.reality-chip {
  position: absolute; top: calc(100% + 3px); left: 50%;
  transform: translateX(-50%);
  font-family: var(--caps);
  font-size: 8.5px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: color-mix(in oklab, var(--bone) 75%, transparent);
  background: rgba(10,11,13,.6);
  padding: 2px 7px;
  white-space: nowrap;
  pointer-events: none;
}
.vessel.settled .vessel-noise { display: none; }
.vessel.settled img { filter: brightness(.55) drop-shadow(0 6px 16px rgba(0,0,0,.7)); transition: filter .8s; }
.vessel.the-one img { filter: brightness(1.35) drop-shadow(0 0 26px rgba(242,243,240,.5)); transition: filter .8s; }

.game-drifter {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 7.5vmin;
  background: none; border: 0; cursor: pointer;
  opacity: 0;
  filter: drop-shadow(0 4px 12px rgba(0,0,0,.7));
  transition: filter .3s;
}
.game-drifter img { width: 100%; display: block; }
.game-drifter:hover, .game-drifter:focus-visible { filter: drop-shadow(0 0 16px rgba(63,191,180,.4)); outline: none; }
.game-drifter.flawed img { animation: flaw-flicker 1.1s steps(3) infinite; filter: hue-rotate(65deg) saturate(1.3); }
@keyframes flaw-flicker { 0%,100% { opacity: 1; } 55% { opacity: .55; } 62% { opacity: .95; } 78% { opacity: .7; } }
.game-drifter.caught img { animation: none; filter: none; }

/* hotspots — the object itself is the button. Hit region lives in
   #markers; the VISUAL (lift + label) lives inside #stage-image so it
   inherits the parallax transform exactly — pixel-true at any size. */
.marker.hotspot {
  transform: translate(-50%, -50%);
  background: none; border: 0; padding: 0;
  cursor: pointer;
}
.marker.hotspot:focus-visible { outline: none; }
.hotspot-film {
  position: absolute;
  pointer-events: none;
}
.hotspot-film .hotspot-lift {
  position: absolute; inset: 0;
  background-repeat: no-repeat;
  filter: brightness(1.34) saturate(1.08);
  opacity: 0;
  transition: opacity .6s ease;
  -webkit-mask-image: radial-gradient(ellipse closest-side at center, black 22%, rgba(0,0,0,.55) 48%, transparent 78%);
  mask-image: radial-gradient(ellipse closest-side at center, black 22%, rgba(0,0,0,.55) 48%, transparent 78%);
}
.hotspot-film.on .hotspot-lift { opacity: 1; }
.hotspot-film .hotspot-label {
  position: absolute;
  top: calc(100% - 12px); left: calc(50% + 6px);
  transform: translateX(-50%);
  color: color-mix(in oklab, var(--bone) 55%, transparent);
  transition: color .35s, text-shadow .35s;
}
.hotspot-film.on .hotspot-label {
  color: var(--bone);
  text-shadow: 0 0 14px rgba(201, 106, 43, .45), 0 1px 10px rgba(0, 0, 0, .95);
}
.hotspot-film.done .hotspot-label { color: var(--ash); text-decoration: line-through; text-decoration-color: var(--faint); }
.hotspot-film.quest-target .hotspot-label { color: var(--bone); animation: breathe 2.2s ease-in-out infinite; }
/* the beckon reads on the hotspot film too: warm the label to ember, slow breathe */
.hotspot-film.beckon .hotspot-label { color: var(--ember); animation: beckon-breathe 2.2s ease-in-out infinite; text-shadow: 0 0 16px rgba(201, 106, 43, .55), 0 1px 10px rgba(0, 0, 0, .95); }

/* the question mark — always there, never in the way */
#help-btn {
  position: fixed;
  top: 22px; right: 26px;
  width: 46px; height: 46px;
  font-family: var(--serif, 'Cormorant Garamond', serif);
  font-size: 27px; font-weight: 400;
  color: color-mix(in oklab, var(--bone) 55%, transparent);
  background: rgba(8, 10, 12, .55);
  border: 1px solid color-mix(in oklab, var(--bone) 18%, transparent);
  border-radius: 50%;
  cursor: pointer;
  z-index: 58;
  transition: color .3s, border-color .3s, box-shadow .3s;
}
/* step aside while a panel owns the corner (its x lives there) */
#world:has(#card:not([hidden])) #help-btn,
#world:has(#journal-layer:not([hidden])) #help-btn {
  opacity: 0;
  pointer-events: none;
}
#fs-btn {
  position: fixed;
  top: 22px; right: 82px;
  width: 46px; height: 46px;
  font-size: 19px;
  color: color-mix(in oklab, var(--bone) 60%, transparent);
  background: rgba(8, 10, 12, .55);
  border: 1px solid color-mix(in oklab, var(--ember) 40%, transparent);
  border-radius: 50%;
  cursor: pointer;
  z-index: 58;
  animation: onward-glow 3.8s ease-in-out infinite;
}
#help-btn:hover, #help-btn:focus-visible {
  color: var(--bone);
  border-color: color-mix(in oklab, var(--ember) 55%, transparent);
  box-shadow: 0 0 22px rgba(201, 106, 43, .25);
  outline: none;
}

#help-scrim {
  position: fixed; inset: 0;
  background: rgba(4, 5, 7, .72);
  backdrop-filter: blur(6px);
  z-index: 70;
  animation: fadein .35s ease;
}
#help-modal {
  position: fixed;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(620px, calc(100vw - 48px));
  max-height: min(78vh, 720px);
  overflow-y: auto;
  background: rgba(12, 14, 17, .97);
  border: 1px solid color-mix(in oklab, var(--bone) 16%, transparent);
  border-top: 2px solid color-mix(in oklab, var(--ember) 60%, transparent);
  padding: 40px 46px 34px;
  z-index: 71;
  animation: help-in .4s var(--ease);
}
@keyframes help-in {
  from { opacity: 0; transform: translate(-50%, -47%); }
  to { opacity: 1; transform: translate(-50%, -50%); }
}
@keyframes fadein { from { opacity: 0; } }
#help-close {
  position: absolute; top: 14px; right: 16px;
  font-size: 22px; color: color-mix(in oklab, var(--bone) 50%, transparent);
  background: none; border: 0; cursor: pointer;
  transition: color .3s;
}
#help-close:hover { color: var(--bone); }
.help-kicker {
  font-family: var(--caps);
  font-size: 10.5px; letter-spacing: .26em; text-transform: uppercase;
  color: color-mix(in oklab, var(--teal, #3fbfb4) 80%, transparent);
  margin: 0 0 6px;
}
.help-title {
  font-family: var(--serif, 'Cormorant Garamond', serif);
  font-size: 34px; font-weight: 400;
  color: var(--bone);
  margin: 0 0 22px;
}
.help-block { margin: 0 0 20px; }
.help-label {
  display: block;
  font-family: var(--caps);
  font-size: 10px; letter-spacing: .3em; text-transform: uppercase;
  color: color-mix(in oklab, var(--ember) 85%, transparent);
  margin-bottom: 6px;
}
.help-block p {
  font-family: var(--serif, 'Cormorant Garamond', serif);
  font-size: 17.5px; line-height: 1.55;
  color: color-mix(in oklab, var(--bone) 88%, transparent);
  margin: 0;
}
.help-foot {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10.5px; letter-spacing: .1em;
  color: color-mix(in oklab, var(--bone) 34%, transparent);
  margin: 26px 0 0;
  border-top: 1px solid color-mix(in oklab, var(--bone) 10%, transparent);
  padding-top: 14px;
}

/* the sea's needs — half-sunk offers in the dark water */
.need-chip {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px; letter-spacing: .14em; text-transform: lowercase;
  color: color-mix(in oklab, var(--teal, #3fbfb4) 62%, var(--bone) 20%);
  background: rgba(6, 9, 11, .62);
  border: 1px solid color-mix(in oklab, var(--teal, #3fbfb4) 30%, transparent);
  border-radius: 3px; padding: 5px 11px;
  cursor: pointer; pointer-events: auto;
  backdrop-filter: blur(2px);
  animation: need-surface 1.4s var(--ease) backwards;
  transition: color .4s, border-color .4s, box-shadow .4s;
  z-index: 26;
}
.need-chip:hover, .need-chip:focus-visible {
  color: var(--bone);
  border-color: color-mix(in oklab, var(--teal, #3fbfb4) 70%, transparent);
  box-shadow: 0 0 16px rgba(63, 191, 180, .25);
  outline: none;
}
.need-chip.granted {
  color: color-mix(in oklab, var(--ember, #c96a2b) 75%, var(--bone) 15%);
  border-color: color-mix(in oklab, var(--ember, #c96a2b) 55%, transparent);
  cursor: default;
  text-decoration: line-through;
  text-decoration-color: color-mix(in oklab, var(--ember, #c96a2b) 60%, transparent);
}
@keyframes need-surface {
  from { opacity: 0; transform: translate(-50%, -30%); filter: blur(3px); }
  to { opacity: 1; transform: translate(-50%, -50%); filter: blur(0); }
}
.risen-lantern {
  position: absolute;
  width: 5vmin;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: left 1.7s cubic-bezier(.22,.9,.28,1), top 1.7s cubic-bezier(.22,.9,.28,1), opacity 1.4s ease;
  pointer-events: none;
  z-index: 22;
}
.risen-lantern.afloat { opacity: 1; animation: lantern-bob 5s ease-in-out 1.7s infinite; }
@keyframes lantern-bob {
  0%, 100% { transform: translate(-50%, -50%) rotate(-1.5deg); }
  50% { transform: translate(-50%, -48%) rotate(1.5deg); }
}

/* the fresh miss — lands loud, pulses until touched */
.delta-chip.broken.laid.fresh-miss {
  animation: waterin .9s var(--ease), miss-pulse 1.3s ease-in-out infinite;
  z-index: 40;
}
@keyframes miss-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(208, 85, 69, .55); transform: translate(-50%, -50%) scale(1); }
  50% { box-shadow: 0 0 18px 6px rgba(208, 85, 69, .35); transform: translate(-50%, -50%) scale(1.08); }
}

/* the grip's procedure — HOLD · DETECT · EXCISE · ATTEST */
.procedure {
  position: absolute;
  left: 50%; top: 19%;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px; letter-spacing: .22em;
  pointer-events: none;
  z-index: 30;
}
.proc-step {
  color: color-mix(in oklab, var(--bone) 34%, transparent);
  border: 1px solid color-mix(in oklab, var(--bone) 16%, transparent);
  padding: 3px 9px; border-radius: 3px;
  background: rgba(8, 10, 12, .45);
  transition: all .9s ease;
}
.proc-step.lit {
  color: var(--ember, #c96a2b);
  border-color: color-mix(in oklab, var(--ember, #c96a2b) 55%, transparent);
  text-shadow: 0 0 12px rgba(201, 106, 43, .6);
}
.proc-sep { color: color-mix(in oklab, var(--bone) 25%, transparent); }

/* the shallows orbit — seven models circling the heron */
.orbit-model {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: none; border: 0; padding: 0; cursor: pointer;
  pointer-events: auto;
  z-index: 24;
  transition: filter .4s ease;
}
.orbit-model.seen { filter: brightness(1.35) drop-shadow(0 0 14px rgba(63,191,180,.4)); }
.orbit-model:hover { filter: brightness(1.3); }
.orbit-model .reality-chip { position: static; transform: none; }
.orbit-model.picked img { outline: 2px solid color-mix(in oklab, var(--ember, #c96a2b) 70%, transparent); outline-offset: 3px; border-radius: 50%; }
.orbit-model.breaking img { animation: convulse .5s ease infinite; }
.orbit-model.arrival { animation: arrive 1.4s ease; }
@keyframes convulse {
  0%, 100% { transform: rotate(-7deg) scale(1); }
  50% { transform: rotate(7deg) scale(1.12); }
}
@keyframes arrive {
  from { opacity: 0; transform: translate(-50%, -80%) scale(.4); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.read-tag {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--teal, #3fbfb4);
  border: 1px solid color-mix(in oklab, var(--teal, #3fbfb4) 45%, transparent);
  background: rgba(8, 10, 12, .72);
  padding: 2px 7px; border-radius: 3px;
  margin-top: 3px;
  animation: tag-in .6s ease;
}
.read-tag.tampered {
  color: #d05545;
  border-color: rgba(208, 85, 69, .6);
  text-shadow: 0 0 10px rgba(208, 85, 69, .5);
}
@keyframes tag-in { from { opacity: 0; transform: translateY(6px); } }

/* plaque action buttons (are-you-sure / read-or-deploy) */
.plaque-actions { display: flex; gap: 12px; justify-content: center; margin-top: 12px; pointer-events: auto; }

.dam {
  position: absolute;
  left: 45%; top: 66%;
  width: 3px; height: 16%;
  background: linear-gradient(180deg, transparent, color-mix(in oklab, var(--bone) 55%, transparent), transparent);
  box-shadow: 0 0 18px rgba(232,228,218,.25);
  pointer-events: none;
  transition: opacity 1.2s ease;
}
.dam.open { opacity: 0; }
.game-drifter.pr { display: flex; flex-direction: column; align-items: center; gap: 2px; }
/* the wolf: near-perfect wool, a heartbeat of tell */
.game-drifter.pr.sneak img { animation: wolf-blink 2.4s linear infinite; }
@keyframes wolf-blink {
  0%, 91%, 100% { filter: none; }
  93%, 96% { filter: hue-rotate(-42deg) brightness(1.35) saturate(1.4); }
}
.game-drifter.pr .reality-chip { position: static; transform: none; }

.stamp {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 7vmin;
  pointer-events: none;
  animation: stamp-in .7s var(--ease) forwards;
  filter: drop-shadow(0 0 24px rgba(63,191,180,.4));
}
@keyframes stamp-in { from { opacity: 0; scale: 2.2; } to { opacity: 1; scale: 1; } }

.oath-badge {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--mono);
  font-size: 10px; letter-spacing: .12em;
  color: var(--bone);
  border: 1px solid color-mix(in oklab, var(--ember) 55%, transparent);
  background: rgba(10,11,13,.6);
  padding: 5px 10px;
  pointer-events: none;
}

.item.pulse { transform: translate(-50%, -54%) scale(1.22); filter: drop-shadow(0 0 26px rgba(63,191,180,.45)); }

/* ── the games v8: problem states, reads, witnesses, excisions ───────── */
.shake { animation: shake .5s ease; }
@keyframes shake { 0%,100% { rotate: 0deg; } 25% { rotate: 3deg; } 50% { rotate: -3deg; } 75% { rotate: 2deg; } }

.scan-beam {
  position: absolute; top: 30%; bottom: 8%;
  left: -8%;
  width: 7%;
  background: linear-gradient(90deg, transparent, rgba(63,191,180,.28), transparent);
  mix-blend-mode: screen;
  animation: scan 2.2s var(--ease) forwards;
  pointer-events: none;
}
@keyframes scan { to { left: 101%; } }

.essence {
  position: absolute; bottom: calc(100% + 6px); left: 50%;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  animation: waterin .8s var(--ease);
  pointer-events: none;
}
.essence img { width: 3.4vmin; height: 3.4vmin; object-fit: contain; filter: drop-shadow(0 0 10px rgba(63,191,180,.35)); }
.essence-word {
  font-family: var(--mono);
  font-size: 10.5px; letter-spacing: .1em;
  color: var(--bone);
  background: rgba(10,11,13,.72);
  border: 1px solid color-mix(in oklab, var(--nacre) 40%, transparent);
  padding: 3px 8px;
  white-space: nowrap;
}
.essence.flagged .essence-word { color: #cf9be0; border-color: rgba(122,66,180,.6); }
.essence.flagged img { filter: drop-shadow(0 0 12px rgba(122,66,180,.55)); }
.vessel { pointer-events: auto; cursor: pointer; background: none; border: 0; }

.delta-chip {
  position: absolute;
  transform: translate(-50%, -50%);
  background: rgba(10,11,13,.6);
  border: 0; cursor: pointer;
  border-left: 2px solid var(--ash);
  font-family: var(--mono);
  font-size: 11.5px; letter-spacing: .1em;
  color: var(--ash);
  padding: 7px 12px;
  transition: color .3s;
  /* bound the label so the two-column ledger lane never has a wide chip reach
     into the neighbouring column; the full text opens on tap. */
  max-width: min(18vw, 185px);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.delta-chip:hover, .delta-chip:focus-visible { color: var(--bone); outline: none; }
.delta-chip.kept { border-left-color: color-mix(in oklab, var(--bone) 70%, transparent); }
.delta-chip.broken { border-left-color: color-mix(in oklab, var(--ember) 80%, transparent); }
.delta-chip.found { color: var(--ember); border-left-color: var(--ember); }
.delta-chip.laid { animation: waterin .9s var(--ease); }
.delta-chip.yours { border-left-width: 3px; color: var(--bone); background: rgba(10,11,13,.75); }
.delta-chip.broken.laid { animation: waterin .9s var(--ease), miss-pulse 2.2s ease-in-out 3; }
@keyframes miss-pulse { 0%,100% { box-shadow: none; } 50% { box-shadow: 0 0 22px rgba(201,106,43,.5); } }
.worker-carry { width: 3vmin; filter: drop-shadow(0 0 10px rgba(232,228,218,.35)); }
.worker-carry.carry-broken { filter: drop-shadow(0 0 14px rgba(201,106,43,.7)); }
.worker-carry.heavy { width: 4.6vmin; filter: drop-shadow(0 4px 14px rgba(232,228,218,.4)); }
.worker-carry.heavy.carry-broken { filter: drop-shadow(0 4px 16px rgba(201,106,43,.75)); }

/* ── the delta redesign: WEIGHT not flow. Heavy stones that thud into the
   ground, faces ENGRAVED (small caps) into the stone, that SINK when touched —
   and your own words as the centerpiece. These rules sit AFTER the base
   .delta-chip block so, at equal specificity, source order gives them the
   edge (they neutralise the old thin-chip animations for stones). ─────────── */
.delta-chip.slab {
  background: linear-gradient(158deg, rgba(31,31,34,.94), rgba(11,12,14,.96));
  border: 1px solid rgba(140,138,128,.16);
  border-left: 3px solid var(--ash);
  border-radius: 3px;
  padding: 9px 13px;
  max-width: min(32vw, 240px);
  box-shadow: 0 3px 14px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.045);
  text-align: center; line-height: 1;
  transition: color .35s, transform .55s var(--ease), box-shadow .4s, opacity .6s;
}
.delta-chip.slab .stone-face { display: inline-block; vertical-align: middle; }
.delta-chip.slab.big { padding: 13px 18px; border-left-width: 4px; max-width: min(26vw, 200px); box-shadow: 0 7px 24px rgba(0,0,0,.72), inset 0 1px 0 rgba(255,255,255,.06); }
.delta-chip.slab.kept   { border-left-color: color-mix(in oklab, var(--bone) 66%, transparent); }
.delta-chip.slab.broken { border-left-color: color-mix(in oklab, var(--ember) 82%, transparent); }
.delta-chip.slab.yours  { border-left-color: var(--nacre); background: linear-gradient(158deg, rgba(16,26,28,.95), rgba(9,12,14,.97)); }
.delta-chip.slab.yours.broken { border-left-color: var(--ember); }
.delta-chip.slab:hover, .delta-chip.slab:focus-visible { outline: none; box-shadow: 0 5px 20px rgba(0,0,0,.68), inset 0 1px 0 rgba(255,255,255,.07); }

/* the engraved face — small caps cut into the stone, subtle until touched */
.stone-face {
  font-family: var(--caps);
  font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase;
  color: color-mix(in oklab, var(--ash) 78%, transparent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 28vw;
  text-shadow: 0 1px 2px rgba(0,0,0,.85);
  transition: color .5s, opacity .5s, letter-spacing .5s;
}
.delta-chip.slab.big .stone-face { font-size: 11px; letter-spacing: .2em; color: color-mix(in oklab, var(--bone) 70%, transparent); }

/* the stone ANSWERS the touch: it sinks, and its engraved grade SURFACES */
.delta-chip.slab.sunk { transform: translate(-50%, calc(-50% + 6px)) scale(.94); box-shadow: 0 1px 6px rgba(0,0,0,.72), inset 0 3px 8px rgba(0,0,0,.5); }
.delta-chip.slab.sunk-deep { transform: translate(-50%, calc(-50% + 12px)) scale(.9); transition: transform 1.05s cubic-bezier(.2,.7,.2,1), box-shadow .6s, color .5s; }
.delta-chip.slab.sunk .stone-face { color: var(--true); opacity: 1; }
.delta-chip.slab.sunk.broken .stone-face, .delta-chip.slab.sunk-deep .stone-face { color: color-mix(in oklab, var(--ember) 80%, var(--bone)); }
.delta-chip.slab.found .stone-face { color: var(--ember); }

/* the house record recedes when YOUR words take the head of the ledger */
.delta-chip.slab.receded { opacity: .3; transform: translate(-50%,-50%) scale(.82); }

/* the THUD — a heavy stone overshoots and settles into the ground */
.delta-chip.slab.thud { animation: stone-thud .6s var(--ease); }
@keyframes stone-thud {
  0%   { transform: translate(-50%, calc(-50% - 9px)) scale(1.07); }
  52%  { transform: translate(-50%, calc(-50% + 4px)) scale(.965); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
/* YOUR words RISE into the ledger's head — the centerpiece */
.delta-chip.slab.rise { animation: stone-rise .9s var(--ease); }
@keyframes stone-rise {
  0%   { opacity: 0; transform: translate(-50%, calc(-50% + 18px)) scale(.88); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
/* the fresh miss breathes until it is touched (5 classes — beats .broken.laid) */
.delta-chip.slab.broken.laid.fresh-miss { animation: stone-pulse 1.5s ease-in-out infinite; z-index: 40; }
@keyframes stone-pulse {
  0%,100% { box-shadow: 0 3px 14px rgba(0,0,0,.6), 0 0 0 0 rgba(208,85,69,.5); transform: translate(-50%,-50%) scale(1); }
  50%     { box-shadow: 0 3px 14px rgba(0,0,0,.6), 0 0 22px 6px rgba(208,85,69,.42); transform: translate(-50%,-50%) scale(1.06); }
}
/* the beckon, on a stone: a warm, slow swell that collects the hesitant */
.delta-chip.slab.beckon { animation: stone-beckon 2.4s ease-in-out infinite; border-left-color: var(--ember); }
.delta-chip.slab.beckon .stone-face { color: var(--true); }
@keyframes stone-beckon {
  0%,100% { box-shadow: 0 4px 16px rgba(0,0,0,.6); transform: translate(-50%,-50%) scale(1); }
  50%     { box-shadow: 0 0 22px 5px rgba(201,106,43,.4); transform: translate(-50%,-50%) scale(1.05); }
}

.flow-chip {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--caps);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: .26em; text-transform: uppercase;
  color: var(--true);
  text-shadow: 0 1px 12px rgba(0,0,0,.95), 0 0 20px rgba(63,191,180,.3);
  animation: waterin .5s ease;
  pointer-events: none;
}

.excise-line {
  position: absolute;
  transform: translate(-50%, -50%) rotate(-38deg);
  width: 12vmin; height: 2px;
  background: linear-gradient(90deg, transparent, var(--true), transparent);
  box-shadow: 0 0 18px rgba(242,243,240,.8);
  animation: excise .9s var(--ease) forwards;
  pointer-events: none;
}
@keyframes excise { from { scale: 0 1; opacity: 1; } 60% { scale: 1 1; opacity: 1; } to { scale: 1 1; opacity: 0; } }

.true-form-stamp { width: 11vmin; }

.ghost-work {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 10px; height: 10px; border-radius: 50%;
  background: radial-gradient(circle, rgba(201,106,43,.55), transparent 70%);
  pointer-events: none;
}
.agent {
  position: absolute;
  transform: translate(-50%, -50%);
  background: none; border: 0; cursor: pointer;
  pointer-events: auto;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  z-index: 5;
}
.agent img { width: 4.6vmin; filter: drop-shadow(0 4px 12px rgba(0,0,0,.7)); transition: filter .4s; }
.agent.seen img { filter: drop-shadow(0 0 14px rgba(63,191,180,.45)); }
.agent.bound img { filter: drop-shadow(0 0 12px rgba(201,106,43,.5)); }
.agent .reality-chip { position: static; transform: none; }
.err-dots { display: flex; gap: 3px; min-height: 8px; }
.err-dots i {
  width: 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle, rgba(220,60,40,.95), rgba(150,30,20,.7));
  box-shadow: 0 0 8px rgba(220,60,40,.6);
  animation: err-blink 1.1s ease-in-out infinite;
}
@keyframes err-blink { 50% { opacity: .5; } }

.ghost-skein {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 4.2vmin;
  pointer-events: auto; cursor: pointer;
  opacity: .8;
  filter: drop-shadow(0 3px 10px rgba(0,0,0,.7));
}
.boat-adrift {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 5vmin;
  pointer-events: none;
  opacity: .55;
  filter: drop-shadow(0 4px 12px rgba(0,0,0,.7)) brightness(.8);
  animation: vessel-bob 4.2s ease-in-out infinite;
}
.read-pass img { filter: brightness(1.6) drop-shadow(0 0 14px rgba(63,191,180,.6)) !important; transition: filter .3s; }
.witness-focus { scale: 1.5; z-index: 8; transition: scale .6s var(--ease); }

.claim-chip {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--mono);
  font-size: 11px; letter-spacing: .08em;
  color: var(--ash);
  background: rgba(10,11,13,.66);
  border: 1px solid color-mix(in oklab, var(--ash) 35%, transparent);
  padding: 6px 12px;
  pointer-events: none;
  animation: waterin 1.2s ease;
}
.claim-chip.doubted { color: var(--faint); text-decoration: line-through; text-decoration-color: var(--ember); transition: all .8s; }

/* ── comprehension gates: objects to weigh, chips that tempt ─────────── */
.gate-object {
  position: absolute;
  transform: translate(-50%, -50%);
  background: none; border: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  pointer-events: auto;
  animation: waterin .8s var(--ease), gate-breathe 2.6s ease-in-out infinite;
  z-index: 6;
}
/* breathe's transform REPLACES the centering translate — gates need both */
@keyframes gate-breathe {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.09); }
}
.gate-object img { width: 7vmin; filter: drop-shadow(0 8px 22px rgba(0,0,0,.75)); }
.gate-object.shiny img { filter: brightness(1.55) drop-shadow(0 0 22px rgba(242,243,240,.35)); }
.gate-object:hover img, .gate-object:focus-visible img { transform: scale(1.1); transition: transform .3s var(--ease); }
.gate-object:focus-visible { outline: none; }
.gate-chip {
  font-family: var(--mono);
  font-size: 10.5px; letter-spacing: .08em;
  color: var(--bone);
  background: rgba(10,11,13,.78);
  border: 1px solid color-mix(in oklab, var(--ash) 35%, transparent);
  padding: 3px 9px;
  white-space: nowrap;
}
.gate-chip.good { border-color: color-mix(in oklab, var(--nacre) 55%, transparent); color: var(--true); }
.gate-chip.warn { border-color: color-mix(in oklab, var(--ember) 55%, transparent); color: color-mix(in oklab, var(--ember) 70%, var(--bone)); }
.gate-object.crumble { animation: crumble 1.4s ease forwards; pointer-events: none; }
@keyframes crumble { 40% { transform: translate(-50%, -48%) rotate(3deg); opacity: 1; } 100% { transform: translate(-50%, -30%) rotate(8deg); opacity: 0; } }

/* gate choices pulse EQUALLY — the blink never leaks the answer
   (except the one deliberate trap, which wears quest-target) */
.marker.gate-choice .marker-ring { animation: breathe 2.2s ease-in-out infinite; }

/* card scrim — the rest of the world dims, and closes the panel */
#card-scrim {
  position: absolute; inset: 0;
  background: rgba(10,11,13,.42);
  z-index: 29;
  animation: waterin .4s ease;
}

/* the way OUT is the CTA; the reset is a small quiet word beneath it */
#journal-close {
  display: block;
  background: none;
  border: 1px solid color-mix(in oklab, var(--ember) 55%, transparent);
  color: var(--bone);
  font-family: var(--caps);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: .24em; text-transform: uppercase;
  padding: 12px 22px;
  cursor: pointer;
  margin-top: 10px;
}
#journal-close:hover, #journal-close:focus-visible { border-color: var(--ember); color: var(--bone); outline: none; }
#journal-reset {
  display: block;
  background: none;
  border: 1px solid color-mix(in oklab, var(--ember) 22%, transparent);
  color: var(--faint);
  font-family: var(--caps);
  font-size: 7.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  padding: 6px 12px;
  cursor: pointer;
  margin-top: 8px;
}
#journal-reset:hover { color: var(--ash); border-color: color-mix(in oklab, var(--ember) 45%, transparent); }
#journal-reset.armed {
  color: #d05545;
  border-color: rgba(208, 85, 69, .7);
  animation: breathe 1.4s ease-in-out infinite;
}

/* ── the residue drifters — the synergy, flowing ─────────────────────── */
.drifter {
  position: absolute;
  width: 3.4vmin;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  filter: drop-shadow(0 3px 10px rgba(0,0,0,.7)) brightness(.95);
}
.drifter img { width: 100%; display: block; }
.drifter-tag {
  font-family: var(--caps);
  font-size: 8px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  color: color-mix(in oklab, var(--bone) 70%, transparent);
  background: rgba(10,11,13,.62);
  padding: 1px 5px;
  white-space: nowrap;
}

.fx-glow {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 1.4s var(--ease);
}
.fx-glow.on { opacity: 1; }

#grain {
  opacity: .05;
  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='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 1.4s steps(4) infinite;
}
@keyframes grain {
  0%{transform:translate(0,0)} 25%{transform:translate(-6px,4px)}
  50%{transform:translate(4px,-6px)} 75%{transform:translate(-3px,-3px)} 100%{transform:translate(0,0)}
}
#vignette { background: radial-gradient(130% 100% at 50% 40%, transparent 52%, rgba(0,0,0,.5) 84%, rgba(0,0,0,.78) 100%); }

/* ── markers — always visible; the world is legible ──────────────────── */
#markers { position: absolute; inset: 0; pointer-events: none; }
.marker, .delta-chip, .game-drifter { pointer-events: auto; }
.marker {
  position: absolute;
  transform: translate(-50%, -50%);
  background: none; border: 0; cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  padding: 6px;
  color: var(--bone);
}
.marker-ring {
  width: 14px; height: 14px; flex: none;
  border: 1px solid color-mix(in oklab, var(--bone) 75%, transparent);
  border-radius: 50%;
  position: relative;
  transition: border-color .3s, transform .3s var(--ease);
  animation: breathe 3.4s ease-in-out infinite;
}
.marker-ring::after {
  content: ''; position: absolute; inset: 4px;
  border-radius: 50%;
  background: var(--bone);
  opacity: .9;
}
@keyframes breathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.18); } }
.marker-label {
  font-family: var(--caps);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: color-mix(in oklab, var(--bone) 86%, transparent);
  white-space: nowrap;
  text-shadow: 0 1px 10px rgba(0,0,0,.95), 0 0 26px rgba(0,0,0,.85);
  transition: color .3s;
}
.marker:hover .marker-ring, .marker:focus-visible .marker-ring {
  transform: scale(1.35);
  animation-play-state: paused;
}
.marker:hover .marker-label, .marker:focus-visible .marker-label { color: var(--true); }
.marker:focus-visible { outline: none; }

/* one currency, three verbs: ember = do · bone = learn · teal = the record */
.marker.verb-do .marker-ring, .marker.primary .marker-ring { border-color: color-mix(in oklab, var(--ember) 90%, white); }
.marker.verb-do .marker-ring::after, .marker.primary .marker-ring::after { background: var(--ember); }
.marker.verb-learn .marker-ring { border-color: color-mix(in oklab, var(--bone) 80%, transparent); }
.marker.verb-learn .marker-ring::after { background: var(--bone); }
.marker.verb-record .marker-ring { border-color: color-mix(in oklab, var(--nacre) 85%, transparent); }
.marker.verb-record .marker-ring::after { background: var(--nacre); }
.marker.verb-walk .marker-ring { border-color: color-mix(in oklab, var(--bone) 80%, transparent); }
.marker.verb-walk .marker-ring::after { background: var(--bone); }

.marker.primary .marker-ring { width: 18px; height: 18px; }
.marker.primary .marker-label { color: var(--true); font-size: 11.5px; }
/* spent markers step back — history should not cover the scene */
.marker.done .marker-label { font-size: 8.5px; opacity: .7; }
.marker.primary.done .marker-ring { width: 12px; height: 12px; }
.marker.left { flex-direction: row-reverse; }
.marker.done .marker-ring { border-color: var(--faint); animation: none; }
.marker.done .marker-ring::after { background: var(--faint); }
.marker.done .marker-label { color: var(--ash); text-decoration: line-through; text-decoration-color: var(--faint); }

/* doors — placed where the geography leads; the glyph points the walk.
   Until the room is won, a door is STILL and gray — no invitation. */
.door-marker { gap: 12px; }
.door-marker:not(.onward) .door-glyph {
  animation: none;
  color: color-mix(in oklab, var(--bone) 42%, transparent);
}
.door-marker:not(.onward) .marker-label { color: color-mix(in oklab, var(--bone) 52%, transparent); }
/* the room is won — the way onward takes ONE BIG BREATH: the whole
   component (glyph + text) swells together inside a warm ember halo.
   Completion exhale, welcome inhale — never a command. */
.door-marker.onward {
  color: var(--bone);
  animation: onward-breath 4.2s ease-in-out infinite;
}
.door-marker.onward .marker-label, .door-marker.onward .door-glyph { color: var(--bone); }
@keyframes onward-breath {
  0%, 100% {
    transform: translate(-50%, -50%) scale(1);
    filter: drop-shadow(0 0 4px rgba(201, 106, 43, .18));
  }
  50% {
    transform: translate(-50%, -50%) scale(1.16);
    filter: drop-shadow(0 0 14px rgba(201, 106, 43, .6)) drop-shadow(0 0 30px rgba(201, 106, 43, .25));
  }
}
.door-marker .door-glyph {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  border: 1px solid color-mix(in oklab, var(--bone) 55%, transparent);
  border-radius: 50%;
  font-family: var(--serif);
  font-size: 17px; line-height: 1;
  color: var(--bone);
  background: rgba(10,11,13,.4);
  transition: transform .3s var(--ease), border-color .3s;
  animation: breathe 3.4s ease-in-out infinite;
}
.door-marker:hover .door-glyph, .door-marker:focus-visible .door-glyph {
  border-color: var(--true);
  transform: scale(1.2);
  animation-play-state: paused;
}
.door-marker.dir-forward:hover .door-glyph { transform: scale(1.2) translateY(-3px); }
.door-marker.dir-back:hover .door-glyph { transform: scale(1.2) translateY(3px); }

#back-btn {
  position: fixed; bottom: 92px; left: 30px;
  z-index: 20;
  background: none; border: 0; cursor: pointer;
  font-family: var(--caps); font-size: 10px; font-weight: 500;
  letter-spacing: .28em; text-transform: uppercase;
  color: var(--faint);
  transition: color .3s;
}
#back-btn:hover { color: var(--bone); }

/* first-touch micro-instruction — rituals teach themselves */
.marker-hint {
  position: absolute; top: calc(100% + 2px); left: 24px;
  font-family: var(--caps);
  font-size: 9px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ember);
  white-space: nowrap;
  text-shadow: 0 1px 8px rgba(0,0,0,.95);
}

/* hold progress: the ring fills while held */
.hold-ring { position: absolute; inset: -12px; width: calc(100% + 24px); height: calc(100% + 24px); transform: rotate(-90deg); pointer-events: none; }
.hold-ring circle {
  fill: none;
  stroke: var(--ember);
  stroke-width: 2.4;
  pathLength: 100;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  stroke-linecap: round;
}
.marker:not(.verb-do):not(.primary) .hold-ring { display: none; }
.marker.done .hold-ring { display: none; }

/* ── scene identity ──────────────────────────────────────────────────── */
#title-block {
  position: absolute; top: 34px; left: 42px;
  max-width: 44ch;
  pointer-events: none;
  z-index: 10;
  opacity: 0;
  transition: opacity .9s var(--ease);
}
#title-block.on { opacity: 1; }
#scene-kicker {
  font-family: var(--caps);
  font-size: 10px; font-weight: 500;
  letter-spacing: .34em; text-transform: uppercase;
  color: var(--ash);
  margin-bottom: 10px;
}
#scene-title {
  font-family: var(--serif);
  font-weight: 300; font-style: italic;
  font-size: clamp(20px, 2.1vw, 27px);
  line-height: 1.35;
  color: var(--bone);
  text-shadow: 0 1px 18px rgba(0,0,0,.9);
  opacity: 0; transform: translateY(6px);
  transition: opacity 1.6s var(--ease), transform 1.6s var(--ease);
}
#scene-title.on { opacity: .95; transform: none; }
#scene-product {
  margin-top: 12px;
  font-family: var(--caps);
  font-size: 11px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--nacre);
  text-shadow: 0 1px 12px rgba(0,0,0,.95);
  opacity: 0; transform: translateY(5px);
  transition: opacity 1.4s var(--ease), transform 1.4s var(--ease);
  max-width: 46ch; line-height: 1.8;
}
#scene-product.on { opacity: .95; transform: none; }
#quest {
  margin-top: 14px;
  font-family: var(--mono);
  font-size: 11.5px; letter-spacing: .06em;
  color: var(--ember);
  opacity: 0;
  transition: opacity .8s var(--ease);
  max-width: 52ch; line-height: 1.7;
}
#quest.on { opacity: 1; }
#quest::before { content: '◆ '; }
.marker.quest-target:not(.done) .marker-ring { border-color: var(--ember) !important; animation: breathe 1.2s ease-in-out infinite; }
.marker.quest-target:not(.done) .marker-ring::after { background: var(--ember) !important; }
.marker.quest-target:not(.done) .marker-label { color: var(--true); }

/* THE BECKON — a quest-target left unengaged (~12s) warms up: a slower, larger,
   warmer breathe with a soft ember halo. Banked coals, never a blaze — it must
   read against orbiting/drifting sprites without becoming a second sun. Placed
   after the quest-target rules (equal specificity) so it wins by source order. */
@keyframes beckon-breathe {
  0%, 100% { transform: scale(1);    box-shadow: 0 0 5px 0 rgba(201, 106, 43, .18); }
  50%      { transform: scale(1.12); box-shadow: 0 0 16px 5px rgba(201, 106, 43, .5); }
}
.marker.beckon:not(.done) .marker-ring {
  border-color: var(--ember) !important;
  animation: beckon-breathe 2.2s ease-in-out infinite;
}
.marker.beckon:not(.done) .marker-ring::after { background: var(--ember) !important; }
.marker.beckon:not(.done) .marker-label { color: var(--true); }

/* the mobile cure: a HOLD's press-and-hold instruction, made visible under the
   label when it beckons — the house register (caps, faint ember) */
.marker-hold-hint {
  position: absolute; top: calc(100% + 3px); left: 24px;
  font-family: var(--caps);
  font-size: 8.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  color: color-mix(in oklab, var(--ember) 62%, var(--bone));
  white-space: nowrap;
  text-shadow: 0 1px 8px rgba(0,0,0,.95);
  pointer-events: none;
  opacity: .88;
}
.marker.left .marker-hold-hint { left: auto; right: 24px; text-align: right; }

/* ── the walk — upstream / downstream ────────────────────────────────── */
.arrow {
  position: absolute; top: 50%;
  transform: translateY(-50%);
  background: none; border: 0; cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  padding: 22px 16px;
  color: var(--ash);
  z-index: 10;
  transition: color .3s;
}
.arrow:hover, .arrow:focus-visible { color: var(--true); }
.arrow:focus-visible { outline: none; }
#arrow-up { left: 10px; }
#arrow-down { right: 10px; }
.arrow-glyph { font-family: var(--serif); font-size: 44px; font-weight: 300; line-height: 1; }
.arrow-label {
  font-family: var(--caps);
  font-size: 10px; font-weight: 500;
  letter-spacing: .26em; text-transform: uppercase;
  writing-mode: vertical-rl;
  opacity: .75; transition: opacity .3s;   /* the doors are named, always */
}
.arrow:hover .arrow-label, .arrow:focus-visible .arrow-label { opacity: 1; }
.arrow[disabled] { opacity: 0; pointer-events: none; }

/* ── the river-strip — the geography IS the nav ──────────────────────── */
#river-strip {
  position: absolute; left: 50%; bottom: 26px;
  transform: translateX(-50%);
  width: min(560px, 72vw);
  z-index: 10;
}
#strip-line {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 1px;
  background: repeating-linear-gradient(90deg,
    color-mix(in oklab, var(--nacre) 55%, transparent) 0 7px, transparent 7px 14px);
  background-size: 28px 1px;
  animation: flow 2.6s linear infinite;
  opacity: .5;
}
@keyframes flow { from { background-position: 0 0; } to { background-position: 28px 0; } }
#strip-stones { display: flex; justify-content: space-between; position: relative; }
.stone {
  background: none; border: 0; cursor: pointer;
  padding: 14px 6px;
  position: relative;
  display: grid; place-items: center;
}
.stone-dot {
  width: 7px; height: 7px;
  background: var(--faint);
  transform: rotate(45deg);
  transition: background .3s, transform .3s;
}
.stone.visited .stone-dot { background: var(--ash); }
.stone.paid .stone-dot { background: color-mix(in oklab, var(--ember) 85%, white); }
.stone.here .stone-dot { background: var(--ember); transform: rotate(45deg) scale(1.5); box-shadow: 0 0 10px color-mix(in oklab, var(--ember) 70%, transparent); }
.stone-name {
  position: absolute; bottom: 100%; left: 50%;
  transform: translateX(-50%);
  font-family: var(--caps);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--ash);
  white-space: nowrap;
  opacity: 0; transition: opacity .25s;
  pointer-events: none;
  text-shadow: 0 1px 8px rgba(0,0,0,.9);
}
.stone:hover .stone-name, .stone:focus-visible .stone-name, .stone.here .stone-name { opacity: 1; }
.stone.here .stone-name { color: var(--bone); }
.stone:focus-visible { outline: none; }
.stone:focus-visible .stone-dot { background: var(--nacre); }

/* ── the product card ────────────────────────────────────────────────── */
#card {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(420px, 92vw);
  background: linear-gradient(to left, rgba(10,11,13,.97) 60%, rgba(10,11,13,.88));
  border-left: 1px solid color-mix(in oklab, var(--ash) 25%, transparent);
  z-index: 30;
  display: flex; align-items: center;
  animation: cardin .55s var(--ease);
  backdrop-filter: blur(6px);
}
@keyframes cardin { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
#card-close {
  position: absolute; top: 22px; right: 26px;
  background: none; border: 0; cursor: pointer;
  color: var(--ash); font-family: var(--serif); font-size: 26px; line-height: 1;
}
#card-close:hover { color: var(--true); }
#card-body {
  padding: 48px 44px; width: 100%;
  max-height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.card-sprite {
  width: 190px; height: 190px;
  object-fit: contain;
  display: block;
  margin: 0 0 26px -8px;
  filter: drop-shadow(0 12px 34px rgba(0,0,0,.65));
}
.card-kicker {
  font-family: var(--caps);
  font-size: 10px; font-weight: 500;
  letter-spacing: .32em; text-transform: uppercase;
  color: var(--nacre);
  margin-bottom: 12px;
}
.card-name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 40px; line-height: 1.05;
  color: var(--true);
  margin-bottom: 16px;
}
.card-line {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 18.5px; line-height: 1.5;
  color: var(--bone);
  margin-bottom: 20px;
}
.card-for {
  font-family: var(--caps);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--faint);
  margin: -8px 0 14px;
}
.card-edge {
  border-left: 1px solid color-mix(in oklab, var(--nacre) 60%, transparent);
  padding: 4px 0 4px 16px;
  font-family: var(--serif);
  font-size: 16.5px; line-height: 1.5;
  color: var(--bone);
  margin-bottom: 16px;
}
.card-discipline {
  border-left: 1px solid color-mix(in oklab, var(--ember) 65%, transparent);
  padding: 4px 0 4px 16px;
  font-family: var(--serif); font-style: italic;
  font-size: 15.5px; line-height: 1.55;
  color: var(--ash);
  margin-bottom: 30px;
}
/* the synergy row — fed by → the instrument → feeds (icons, not text) */
.card-flows {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 0 6px;
  margin-bottom: 22px;
  border-top: 1px solid color-mix(in oklab, var(--ash) 20%, transparent);
  flex-wrap: wrap;
}
.flow-side { display: inline-flex; align-items: center; gap: 6px; }
.flow-tag {
  font-family: var(--caps);
  font-size: 8.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--faint);
  margin-right: 2px;
}
.flow-thumb {
  width: 30px; height: 30px; object-fit: contain;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.6));
}
.flow-arrow { color: var(--faint); font-family: var(--serif); font-size: 15px; }

.plaque-item {
  width: 110px; height: 110px; object-fit: contain;
  display: block; margin: 0 auto 10px;
  filter: drop-shadow(0 8px 22px rgba(0,0,0,.7));
}

.card-doors { display: flex; gap: 12px; flex-wrap: wrap; }
.insight-name { font-size: 26px; line-height: 1.3; font-style: italic; }
.card-human {
  font-family: var(--serif);
  font-size: 15.5px; line-height: 1.65;
  color: var(--ash);
  margin-bottom: 26px;
}
.bet-chip {
  position: absolute; bottom: calc(100% + 4px); left: 50%;
  transform: translateX(-50%);
  font-family: var(--caps);
  font-size: 9px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--ember);
  border: 1px solid color-mix(in oklab, var(--ember) 55%, transparent);
  background: rgba(10,11,13,.75);
  padding: 3px 8px;
  white-space: nowrap;
  animation: waterin .4s ease;
  pointer-events: none;
}
.bet-chip.clean { color: var(--bone); border-color: color-mix(in oklab, var(--bone) 40%, transparent); }
.ghost-work { pointer-events: auto; cursor: pointer; }
.card-door {
  font-family: var(--caps);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--bone);
  background: none;
  border: 1px solid color-mix(in oklab, var(--ash) 40%, transparent);
  padding: 12px 20px;
  cursor: pointer;
  transition: border-color .3s, color .3s;
}
.card-door:hover, .card-door:focus-visible { border-color: var(--nacre); color: var(--true); outline: none; }
.card-note { font-family: var(--caps); font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); padding: 12px 2px; }

/* ── the whispers — the record surfaces, in-scene ────────────────────── */
.whisper {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: var(--mono);
  font-size: 15.5px;
  letter-spacing: .14em;
  color: var(--true);
  text-shadow: 0 1px 14px rgba(0,0,0,1), 0 0 36px rgba(0,0,0,.9), 0 0 18px rgba(63,191,180,.25);
  pointer-events: none;
  opacity: 0;
  animation: whisper 5.6s var(--ease) forwards;
  white-space: nowrap;
}
@keyframes whisper {
  0% { opacity: 0; transform: translate(-50%, -30%); }
  16% { opacity: .95; }
  70% { opacity: .8; }
  100% { opacity: 0; transform: translate(-50%, -120%); }
}
@media (prefers-reduced-motion: reduce) { .whisper { animation: whisper-still 5s ease forwards; } }
@keyframes whisper-still { 0% { opacity: 0; } 12% { opacity: .95; } 82% { opacity: .9; } 100% { opacity: 0; } }

/* ── the directive — a gate instruction that STAYS until acted on ─────── */
#directive {
  position: absolute; left: 50%; top: 86px;
  transform: translateX(-50%);
  font-family: var(--caps);
  font-size: 11.5px; font-weight: 500;
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--true);
  background: rgba(10,11,13,.78);
  border-top: 1px solid color-mix(in oklab, var(--ember) 60%, transparent);
  padding: 12px 22px;
  pointer-events: none;
  z-index: 24;
  white-space: nowrap;
  animation: waterin .6s ease;
}
#directive::before { content: '→ '; color: var(--ember); }
/* the delta's upstream door sits top-center - give the directive room
   (the door is %-positioned, so scale with the stage, not the pixel) */
/* the delta's title runs long (down to ~28% on desktop) — drop its directive
   clear of the block so the two never cross */
#world:has(#stage[data-room="delta"]) #directive { top: max(212px, 30%); }

/* the river: TOP-HEAVY quest text — directive, plaque beneath it, the
   water below stays unblocked (agents work at the bottom) */
#world:has(#stage[data-room="river"]) #directive { top: max(180px, 26%); }

/* sea-edge: the excise action plays at mid-stage — quest text rides high,
   just under the HOLD·DETECT·EXCISE·ATTEST strip (19%) */
#world:has(#stage[data-room="sea-edge"]) #plaque { top: max(168px, 23%); }

/* the bind protocol chips — refused → declares → bound */
.bind-chip {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .12em;
  padding: 2px 8px; border-radius: 3px;
  background: rgba(8, 10, 12, .8);
  white-space: nowrap;
  animation: tag-in .4s ease;
}
.bind-chip.refused { color: #d05545; border: 1px solid rgba(208, 85, 69, .55); }
.bind-chip.declares { color: var(--teal, #3fbfb4); border: 1px solid color-mix(in oklab, var(--teal, #3fbfb4) 45%, transparent); }
.bind-chip.limits { color: var(--bone); border: 1px solid color-mix(in oklab, var(--ember) 55%, transparent); }
.agent.banned img { filter: grayscale(.7) brightness(.65) drop-shadow(0 0 10px rgba(208, 85, 69, .4)) !important; }
/* the supervisor — a different kind of watcher: it reads, it does not hover */
.agent.supervisor img {
  width: 6vmin;
  filter: drop-shadow(0 0 14px rgba(63, 191, 180, .45));
  animation: breathe 4.6s ease-in-out infinite;
}
.graded-drop {
  position: absolute;
  width: 3vmin;
  transform: translate(-50%, -50%);
  opacity: .85;
  transition: top 2.2s ease-in, opacity 2.2s ease-in;
  pointer-events: none;
}

/* the bet - two loud dark choices that own the eye */
.marker.bet-choice .marker-label {
  background: rgba(8, 10, 12, .88);
  border: 1px solid color-mix(in oklab, var(--ember) 45%, transparent);
  border-radius: 3px;
  padding: 9px 14px;
  font-size: 11.5px;
  color: var(--bone);
  box-shadow: 0 6px 22px rgba(0, 0, 0, .65);
}

/* ── plaque ──────────────────────────────────────────────────────────── */
#plaque {
  position: absolute; left: 50%; top: max(232px, 33%); bottom: auto;
  transform: translateX(-50%);
  max-width: 52ch;
  padding: 20px 30px;
  background: rgba(10,11,13,.88);
  border-top: 1px solid color-mix(in oklab, var(--ash) 35%, transparent);
  font-family: var(--serif);
  font-size: 17.5px; font-weight: 400; line-height: 1.6;
  text-align: center;
  color: var(--bone);
  cursor: pointer;
  z-index: 25;
  backdrop-filter: blur(4px);
  animation: waterin .5s var(--ease);
}
#plaque em { font-style: italic; color: var(--true); }
.plaque-tap {
  display: block;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 8.5px; letter-spacing: .24em; text-transform: uppercase;
  color: color-mix(in oklab, var(--ember) 70%, transparent);
  margin-top: 8px;
  animation: tap-invite 2.6s ease-in-out infinite;
}
@keyframes tap-invite {
  0%, 100% { opacity: .45; }
  50% { opacity: 1; }
}
.plaque-burn {
  display: block;
  height: 1px;
  margin: 14px auto 0;
  background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--ember) 75%, transparent), transparent);
  width: 100%;
}
#plaque:hover { border-top-color: color-mix(in oklab, var(--ember) 60%, transparent); }
#plaque .plaque-actions { display: flex; gap: 10px; justify-content: center; margin-top: 14px; flex-wrap: wrap; }
#plaque .card-door { font-size: 10px; padding: 10px 16px; }

/* ── journal ─────────────────────────────────────────────────────────── */
#journal-mark {
  position: fixed; bottom: 26px; left: 30px;
  z-index: 20;
  background: none; border: 0; cursor: pointer;
  font-family: var(--caps); font-size: 10px; font-weight: 500;
  letter-spacing: .28em; text-transform: uppercase;
  color: var(--faint);
  transition: color .3s;
}
#journal-mark:hover { color: var(--bone); }
#journal-layer {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(10,11,13,.94);
  display: grid; place-items: center; align-content: center; gap: 14px;
  animation: waterin .5s var(--ease);
}
#journal-entries {
  list-style: none;
  width: min(90vw, 68ch); max-height: 58vh; overflow-y: auto;
  color: var(--ash); font-size: 13px; line-height: 1.95;
}
#journal-entries li::before { content: '· '; color: var(--faint); }
#journal-entries .kept { color: var(--bone); }
#journal-entries .broken { color: var(--ember); }

/* ── the earned door — the sea-edge recognition, mounted only post-trophy.
   A quiet ember-marked marker, not a banner; it opens a recognition card. ── */
.marker.earned-door .marker-ring { border-color: color-mix(in oklab, var(--ember) 78%, transparent); }
.marker.earned-door .marker-ring::after { background: var(--ember); }
.marker.earned-door .marker-label { color: color-mix(in oklab, var(--ember) 80%, var(--bone)); }

/* ── THE SEEN — the hidden recognition chamber (house full-screen register,
   like the journal; static, no backend) ─────────────────────────────────── */
#seen-layer {
  position: fixed; inset: 0; z-index: 62;
  background: radial-gradient(ellipse at 50% 36%, rgba(16,18,22,.97), rgba(7,8,10,.99));
  display: grid; place-items: center; align-content: center; gap: 24px;
  padding: 6vh 6vw;
  animation: waterin .8s var(--ease);
}
#seen-body { width: min(92vw, 62ch); text-align: center; }
.seen-kicker {
  font-family: var(--caps);
  font-size: 10px; font-weight: 500; letter-spacing: .32em; text-transform: uppercase;
  color: var(--nacre); margin-bottom: 22px;
}
.seen-title {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(30px, 5vw, 52px); line-height: 1.06;
  color: var(--true); margin-bottom: 26px;
}
.seen-line {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(16px, 2.4vw, 21px); line-height: 1.62;
  color: var(--bone); margin: 0 auto 20px; max-width: 52ch;
}
.seen-line em { font-style: italic; color: var(--true); }
.seen-invite { color: var(--ash); }
.seen-doors { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin: 8px 0 18px; }
.seen-foot {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  color: var(--faint); max-width: 48ch; margin: 0 auto; line-height: 1.65;
}
#seen-close {
  background: none;
  border: 1px solid color-mix(in oklab, var(--ember) 45%, transparent);
  color: var(--ash);
  font-family: var(--caps); font-size: 9.5px; font-weight: 500;
  letter-spacing: .24em; text-transform: uppercase;
  padding: 11px 22px; cursor: pointer; margin-top: 6px;
}
#seen-close:hover, #seen-close:focus-visible { border-color: var(--ember); color: var(--bone); outline: none; }

/* ── curtain ─────────────────────────────────────────────────────────── */
#curtain {
  position: absolute; inset: 0;
  background: var(--night);
  opacity: 0; pointer-events: none;
  transition: opacity .65s var(--ease);
  z-index: 50;
}
#curtain.on { opacity: 1; }

/* ── arrival — souls-style: lands large and centered, travels to corner ─ */
#splash {
  position: absolute; left: 50%; top: 40%;
  transform: translate(-50%, -50%) scale(1);
  transform-origin: center;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .8s var(--ease);
  z-index: 15;
}
#splash.on { opacity: 1; }
#splash.on::after {
  content: '';
  height: 1px;
  width: 0;
  background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--bone) 60%, transparent), transparent);
  animation: rule-grow 1.6s var(--ease) .3s forwards;
}
@keyframes rule-grow { to { width: min(46vw, 520px); } }
#splash.to-corner {
  transition: transform .85s var(--ease), opacity .85s ease;
  transform: translate(calc(-50vw + 50% + 42px), calc(-40vh + 50% + 44px)) scale(.34);
  opacity: 0;
}
#splash-num {
  font-family: var(--caps);
  font-size: 13px; font-weight: 500;
  letter-spacing: .6em; text-transform: uppercase;
  color: var(--ember);
}
#splash-name {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(44px, 6.4vw, 84px);
  color: var(--true);
  text-shadow: 0 2px 40px rgba(0,0,0,.95), 0 0 80px rgba(0,0,0,.7);
  letter-spacing: .03em;
}

/* ── the bang ────────────────────────────────────────────────────────── */
#flash {
  position: absolute; inset: 0;
  background: radial-gradient(60% 60% at 50% 46%, rgba(242,243,240,.5), rgba(201,106,43,.12) 55%, transparent 80%);
  opacity: 0; pointer-events: none;
  transition: opacity .35s ease;
  mix-blend-mode: screen;
  z-index: 22;
}
#flash.on { opacity: 1; }

#relic-fly {
  position: fixed; left: 50%; top: 44%;
  width: 0; height: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 45;
  filter: drop-shadow(0 0 34px rgba(242,243,240,.35));
}
#relic-fly.reveal {
  width: 240px; height: 240px;
  transition: width .9s var(--ease), height .9s var(--ease);
}
#relic-fly.fly {
  left: calc(100vw - 130px); top: calc(100vh - 60px);
  width: 30px; height: 30px;
  transition: all .9s cubic-bezier(.5,0,.6,1);
}

/* ── the satchel — where you have been, as objects ───────────────────── */
#satchel {
  position: fixed; right: 26px; bottom: 22px;
  display: flex; align-items: center; gap: 7px;
  z-index: 20;
}
.satchel-slot {
  width: 30px; height: 30px;
  border: 1px solid color-mix(in oklab, var(--ash) 30%, transparent);
  border-radius: 2px;
  display: grid; place-items: center;
  background: rgba(10,11,13,.55);
}
.satchel-slot.held { border-color: color-mix(in oklab, var(--ember) 60%, transparent); cursor: pointer; transition: border-color .3s, transform .3s; }
.satchel-slot.held:hover, .satchel-slot.held:focus-visible { border-color: var(--ember); transform: translateY(-3px); outline: none; }
.satchel-slot.fresh {
  animation: fresh-pulse 1.8s ease-in-out infinite;
  border-color: var(--ember);
}
@keyframes fresh-pulse {
  0%, 100% { box-shadow: 0 0 0 rgba(201,106,43,0); transform: translateY(0); }
  50% { box-shadow: 0 0 16px rgba(201,106,43,.55); transform: translateY(-3px); }
}
.satchel-slot[disabled] { cursor: default; }
.satchel-slot img { width: 24px; height: 24px; object-fit: contain; }
.satchel-count {
  font-family: var(--caps);
  font-size: 9.5px; letter-spacing: .18em;
  color: var(--faint);
  margin-left: 6px;
}

/* the finale: the river runs gold */
#river-strip.gold #strip-line {
  background: repeating-linear-gradient(90deg, color-mix(in oklab, var(--ember) 80%, white) 0 7px, transparent 7px 14px);
  background-size: 28px 1px;
  opacity: .8;
}

#sound-toggle, #music-toggle {
  position: fixed; left: 30px; bottom: 48px;
  background: none; border: 0; cursor: pointer;
  font-family: var(--caps); font-size: 10px; font-weight: 500;
  letter-spacing: .28em; text-transform: uppercase;
  color: var(--faint);
  z-index: 20;
}
#music-toggle { bottom: 70px; }  /* stacks one line above sound — even 22px rhythm with back/journal */
#sound-toggle:hover, #music-toggle:hover { color: var(--bone); }

/* ── the chrome row — one markup, two faces ──────────────────────────────
   DESKTOP: the wrapper is transparent (display:contents) so back / music /
   sound / journal / fullscreen keep their own fixed positions and text
   labels — nothing about the desktop chrome changes. The inline icons are
   hidden. MOBILE (the phone tier far below) packs the same buttons into one
   horizontal icon row and hides the text. State drives the toggle glyphs. */
#chrome-row { display: contents; }
.chrome-icon { display: none; }
/* a toggle OFF is unmistakable: the note/speaker dims and a diagonal slash
   crosses it (the slash is an <line> inside the same svg). */
.chrome-icon .icon-slash { opacity: 0; }
[data-state="off"] .chrome-icon .glyph { opacity: .3; }
[data-state="off"] .chrome-icon .icon-slash { opacity: 1; }

.relic-name {
  font-family: var(--caps);
  font-size: 10.5px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--ember);
  display: inline-block; margin-bottom: 8px;
}

/* ── small screens ───────────────────────────────────────────────────── */
@media (max-width: 720px) {
  #title-block { left: 22px; top: 22px; max-width: 30ch; }
  .arrow-glyph { font-size: 34px; }
  #river-strip { width: 82vw; bottom: 18px; }
  #card { width: 100vw; border-left: 0; }
  .marker-label { font-size: 9.5px; letter-spacing: .16em; }
}

/* ── reduced motion — the stills carry it ────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  #grain, .marker-ring, #strip-line { animation: none !important; }
  #stage.strain #stage-image { animation: none !important; }
  #scene-title, #stage-image, #curtain { transition-duration: .2s; }
  /* the beckon: no animation — a STATIC brighter ember halo instead */
  .marker.beckon:not(.done) .marker-ring {
    animation: none !important;
    transform: scale(1.12);
    box-shadow: 0 0 16px 5px rgba(201, 106, 43, .5);
  }
  .hotspot-film.beckon .hotspot-label { animation: none !important; color: var(--ember); }
}


/* ═══ MOBILE ═══════════════════════════════════════════════════════════ */

/* the two bottom bars share one lane only on wide glass — below 1240px
   the trophies rise above the map line */
@media (max-width: 1240px) {
  #satchel {
    bottom: 66px;
    transform: scale(.88);
    transform-origin: bottom right;
  }
}
@media (max-width: 900px) {
  #satchel { bottom: 48px; transform: scale(.72); }
}

/* portrait phones: the gate — the art is horizon-shaped, and we say so */
#rotate-gate { display: none; }
/* while the front door is open, the rotate gate does not exist */
#world:has(#welcome:not(.gone)) #rotate-gate { display: none !important; }
@media (orientation: portrait) and (max-width: 1080px) {
  #rotate-gate {
    display: flex;
    position: fixed; inset: 0;
    z-index: 200;
    background: #07090b;
    flex-direction: column; align-items: center; justify-content: center;
    gap: 18px; text-align: center; padding: 32px;
  }
  #rotate-gate img {
    width: 64px;
    transform: rotate(90deg);
    filter: drop-shadow(0 0 18px rgba(201, 106, 43, .35));
    animation: gate-turn 3.2s ease-in-out infinite;
  }
  @keyframes gate-turn {
    0%, 20% { transform: rotate(0deg); }
    55%, 100% { transform: rotate(90deg); }
  }
  #rotate-gate .rotate-line {
    font-family: var(--serif, 'Cormorant Garamond', serif);
    font-size: 26px; color: var(--bone);
    margin: 0;
  }
  #rotate-gate .rotate-sub {
    font-family: var(--mono, ui-monospace, monospace);
    font-size: 11px; letter-spacing: .18em;
    color: color-mix(in oklab, var(--bone) 45%, transparent);
    margin: 0;
  }
}
/* the front door — professional, quiet, ours */
#welcome {
  position: fixed; inset: 0;
  z-index: 210;
  background:
    radial-gradient(ellipse at 50% 120%, rgba(201, 106, 43, .08), transparent 60%),
    #07090b;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 14px; text-align: center; padding: 32px;
}
#welcome { transition: opacity .8s var(--ease); }
#welcome.gone { opacity: 0; pointer-events: none; } /* fade the door open on one breath — do not snap */
#welcome.instant { display: none; }                 /* revisit-skip + post-fade: fully out of layout */
.welcome-mark {
  width: 52px;
  filter: brightness(2.1) saturate(1.15) drop-shadow(0 0 18px rgba(201, 106, 43, .45));
  margin-bottom: 4px;
}
.welcome-word {
  font-family: var(--serif, 'Cormorant Garamond', serif);
  font-size: 40px; font-weight: 400;
  letter-spacing: .34em; text-indent: .34em;
  color: var(--bone);
  margin: 0;
}
.welcome-line {
  font-family: var(--serif, 'Cormorant Garamond', serif);
  font-size: 16px; line-height: 1.6;
  color: color-mix(in oklab, var(--bone) 78%, transparent);
  margin: 0;
  max-width: 56ch;
}
.welcome-register {
  font-family: var(--caps);
  font-size: 10px; letter-spacing: .34em; text-indent: .34em;
  color: color-mix(in oklab, var(--teal, #3fbfb4) 75%, transparent);
  margin: 6px 0 0;
}
.welcome-register a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in oklab, var(--teal, #3fbfb4) 30%, transparent);
  padding-bottom: 1px;
  transition: color .3s, border-color .3s;
}
.welcome-register a:hover, .welcome-register a:focus-visible {
  color: var(--teal, #3fbfb4);
  border-color: var(--teal, #3fbfb4);
  outline: none;
}
.welcome-credo {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10.5px; letter-spacing: .14em;
  color: color-mix(in oklab, var(--bone) 42%, transparent);
  margin: 0;
}
#welcome-enter {
  font-family: var(--caps);
  font-size: 12px; letter-spacing: .28em; text-indent: .28em; text-transform: uppercase;
  color: var(--bone);
  background: none;
  border: 1px solid color-mix(in oklab, var(--ember) 55%, transparent);
  border-radius: 4px;
  padding: 15px 34px;
  margin-top: 14px;
  cursor: pointer;
  animation: onward-glow 3.8s ease-in-out infinite;
  transition: border-color .3s, box-shadow .3s;
}
#welcome-enter:hover, #welcome-enter:focus-visible {
  border-color: var(--ember);
  box-shadow: 0 0 26px rgba(201, 106, 43, .25);
  outline: none;
}
.welcome-sound {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .2em;
  color: color-mix(in oklab, var(--bone) 48%, transparent);
  background: none; border: 0; cursor: pointer;
  padding: 6px 10px;
  border-bottom: 1px solid color-mix(in oklab, var(--bone) 14%, transparent);
  transition: color .3s;
}
.welcome-sound:hover, .welcome-sound:focus-visible { color: var(--bone); outline: none; }

.welcome-turn {
  display: none;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .16em;
  color: color-mix(in oklab, var(--ember) 80%, transparent);
  margin: 4px 0 0;
}
@media (orientation: portrait) {
  .welcome-sound {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .2em;
  color: color-mix(in oklab, var(--bone) 48%, transparent);
  background: none; border: 0; cursor: pointer;
  padding: 6px 10px;
  border-bottom: 1px solid color-mix(in oklab, var(--bone) 14%, transparent);
  transition: color .3s;
}
.welcome-sound:hover, .welcome-sound:focus-visible { color: var(--bone); outline: none; }

.welcome-turn { display: block; }
}
.welcome-install {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .14em;
  color: color-mix(in oklab, var(--teal, #3fbfb4) 72%, transparent);
  margin: 2px 0 0;
}
.welcome-foot {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 9.5px; letter-spacing: .22em;
  color: color-mix(in oklab, var(--bone) 32%, transparent);
  margin: 18px 0 0;
}
@media (max-height: 500px) {
  #welcome { gap: 8px; }
  .welcome-word { font-size: 28px; }
  .welcome-line { font-size: 13px; }
  .welcome-mark { width: 38px; }
  #welcome-enter { padding: 11px 26px; margin-top: 8px; }
  .welcome-sound {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .2em;
  color: color-mix(in oklab, var(--bone) 48%, transparent);
  background: none; border: 0; cursor: pointer;
  padding: 6px 10px;
  border-bottom: 1px solid color-mix(in oklab, var(--bone) 14%, transparent);
  transition: color .3s;
}
.welcome-sound:hover, .welcome-sound:focus-visible { color: var(--bone); outline: none; }

.welcome-turn {
  display: none;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .16em;
  color: color-mix(in oklab, var(--ember) 80%, transparent);
  margin: 4px 0 0;
}
@media (orientation: portrait) {
  .welcome-sound {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px; letter-spacing: .2em;
  color: color-mix(in oklab, var(--bone) 48%, transparent);
  background: none; border: 0; cursor: pointer;
  padding: 6px 10px;
  border-bottom: 1px solid color-mix(in oklab, var(--bone) 14%, transparent);
  transition: color .3s;
}
.welcome-sound:hover, .welcome-sound:focus-visible { color: var(--bone); outline: none; }

.welcome-turn { display: block; }
}
.welcome-foot { margin-top: 8px; }
}

/* small-height landscape (phones): everything scales to the little stage.
   The px floors in max() assume desktop heights — at 390px tall they'd
   push text past mid-stage, so plain percentages take over here. */
@media (max-height: 500px) {
  #title-block { max-width: 30%; }
  #scene-kicker { font-size: 8px; letter-spacing: .18em; }
  #scene-product { font-size: 9px; }
  #scene-title { font-size: 16px; line-height: 1.3; }
  #quest { font-size: 8.5px; }

  #directive { top: 11%; font-size: 9px; padding: 7px 12px; letter-spacing: .18em; }
  #plaque { top: 30%; max-width: min(58ch, 72vw); font-size: 13px; padding: 12px 18px; }
  #world:has(#stage[data-room="river"]) #directive { top: 22%; }
  #world:has(#stage[data-room="delta"]) #directive { top: 15%; }
  #world:has(#stage[data-room="sea-edge"]) #plaque { top: 24%; }

  .marker-label { font-size: 8.5px; letter-spacing: .16em; }
  .marker { gap: 7px; padding: 4px; }
  .marker-ring { width: 11px; height: 11px; }
  .door-marker .door-glyph { font-size: 13px; }
  .procedure { font-size: 8.5px; gap: 6px; top: 16%; }
  .proc-step { padding: 2px 6px; }
  .reality-chip, .bind-chip, .read-tag, .drifter-tag { font-size: 8px; }
  .need-chip { font-size: 9px; padding: 4px 8px; }

  #river-strip { transform: translateX(-50%) scale(.82); bottom: 2px; }
  #satchel { transform: scale(.8); transform-origin: bottom right; }
  #help-btn { width: 36px; height: 36px; font-size: 20px; top: 10px; right: 12px; }
  #sound-toggle, #music-toggle, #journal-mark, #back-btn { font-size: 9px; }

  #help-modal { width: calc(100vw - 36px); max-height: 84vh; padding: 22px 26px 20px; }
  .help-title { font-size: 23px; margin-bottom: 12px; }
  .help-block p { font-size: 14px; }
  .help-block { margin-bottom: 12px; }
  .help-foot { margin-top: 14px; padding-top: 10px; font-size: 9px; }

  #splash-num { font-size: 11px; }
  #splash-name { font-size: 30px; }

  /* nameplates collide at this scale — the object reveals its name on touch */
  .hotspot-film .hotspot-label { opacity: 0; transition: opacity .35s; }
  .hotspot-film.on .hotspot-label { opacity: 1; }

  #card { width: min(420px, 92vw); }
}

/* ── PHONE TIER: small + coarse — chrome shrinks hard, the film wins ──── */
@media (max-height: 440px), (pointer: coarse) and (max-height: 540px) {
  #title-block { max-width: 27%; }
  #scene-kicker { font-size: 7px; letter-spacing: .14em; }
  #scene-product { font-size: 7.5px; }
  #scene-title { font-size: 12.5px; line-height: 1.25; }
  #quest { font-size: 7px; }

  #directive { font-size: 7.5px; padding: 5px 9px; letter-spacing: .14em; }
  #plaque { font-size: 11px; padding: 8px 13px; max-width: 72vw; line-height: 1.45; }
  .plaque-actions .card-door { font-size: 9px; padding: 8px 12px; }

  .marker-label { font-size: 7px; letter-spacing: .12em; }
  .marker { gap: 5px; padding: 3px; }
  .marker-ring { width: 9px; height: 9px; }
  .door-marker .door-glyph { font-size: 10px; }
  .procedure { font-size: 7px; gap: 4px; }
  .proc-step { padding: 1px 5px; }
  .reality-chip, .bind-chip, .read-tag, .drifter-tag { font-size: 6.5px; }
  .need-chip { font-size: 7.5px; padding: 3px 6px; }
  .gate-chip { font-size: 7.5px; }
  .flow-chip, .delta-chip { font-size: 7.5px; }
  .item-label { font-size: 7px; }

  #river-strip { transform: translateX(-50%) scale(.64); bottom: 0; }
  #satchel { transform: scale(.55); transform-origin: bottom right; bottom: 34px; }
  #help-btn { width: 28px; height: 28px; font-size: 15px; top: 8px; right: 8px; }
  /* #fs-btn lives in #chrome-row on this tier — no bottom-right pill */

  #help-modal { padding: 16px 18px 14px; }
  .help-title { font-size: 19px; margin-bottom: 8px; }
  .help-kicker { font-size: 8.5px; }
  .help-block p { font-size: 12px; line-height: 1.45; }
  .help-block { margin-bottom: 9px; }
  .help-foot { font-size: 8px; margin-top: 10px; padding-top: 8px; }

  #splash-num { font-size: 9px; }
  #splash-name { font-size: 22px; }

  /* the delta bets: same shrink as everything else (the 2-class rule
     out-specified the tier), side by side without touching */
  .marker.bet-choice .marker-label {
    font-size: 8px;
    padding: 5px 9px;
    letter-spacing: .1em;
    white-space: normal;
    max-width: 23vw;
    text-align: center;
    line-height: 1.35;
  }

  /* sea-edge: the procedure plays mid-stage — quest text hugs the top */
  #world:has(#stage[data-room="sea-edge"]) #plaque { top: 15%; }
  .procedure { top: 8%; }

  /* delta: the px floor put the directive mid-screen on phones — % only,
     and the bets sit in the band between the title and the settling ledger
     (which starts at ~48%), clear of both. */
  #world:has(#stage[data-room="delta"]) #directive { top: 12%; }
  .marker.bet-choice { top: 43% !important; }

  /* dormant watchers stay majestic at phone scale */
  .item { min-width: 34px; }
  .item.dim { min-width: 40px; }

  /* the side panel (product cards + trophy insights) reads at phone scale */
  #card { width: min(340px, 88vw); }
  #card-body { padding: 26px 22px; }
  #card-body h2, .card-title { font-size: 21px; }
  #card-body p, #card-body li { font-size: 12.5px; line-height: 1.5; }
  .card-kicker { font-size: 8.5px; }
  .card-for { font-size: 9px; }
  .card-edge { font-size: 11.5px; }
  .card-human { font-size: 11px; }
  .card-door { font-size: 9.5px; padding: 8px 12px; }
  .card-note { font-size: 9px; }
  .relic-name { font-size: 12px; }
  #card-close { top: 12px; right: 14px; font-size: 22px; }
}

/* ═══ CHROME ROW (mobile) ═══════════════════════════════════════════════
   the bottom-left stacked text menu becomes ONE horizontal icon row:
   [back] [music] [sound] [journal] [fullscreen] — compact square touch
   targets (42px), even spacing, safe-area aware. Doors clear it because the
   engine measures #chrome-row as a bottom-chrome band, exactly like the
   river-strip and the satchel. Bottom-right is freed (fullscreen moved in). */
@media (max-height: 440px), (pointer: coarse) and (max-height: 540px) {
  #chrome-row {
    position: fixed;
    left: calc(10px + env(safe-area-inset-left, 0px));
    /* sits ABOVE the centered river-strip (which reaches ~29px up from the
       bottom): the horizontal row is wider than the old vertical text menu,
       so it clears the strip by riding just over it — like the old menu did */
    bottom: calc(36px + env(safe-area-inset-bottom, 0px));
    z-index: 25;
    display: flex; align-items: center; gap: 5px;
  }
  #chrome-row > button {
    position: relative; inset: auto; margin: 0;
    width: 30px; height: 30px; padding: 0;           /* the ? pill's weight (28px tier) */
    display: grid; place-items: center;
    font-size: 0; letter-spacing: 0;                 /* no stray label metrics */
    color: var(--ash);
    background: rgba(8, 10, 12, .5);
    border: 1px solid color-mix(in oklab, var(--bone) 12%, transparent);
    border-radius: 8px;
    animation: none;                                 /* the row is still, not pulsing */
    transition: color .3s, border-color .3s, background .3s;
  }
  /* visually the ?'s size, but the finger still gets a ~44px target */
  #chrome-row > button::before { content: ''; position: absolute; inset: -7px; }
  #chrome-row > button:hover,
  #chrome-row > button:focus-visible {
    color: var(--bone);
    border-color: color-mix(in oklab, var(--ember) 42%, transparent);
    background: rgba(10, 12, 14, .62);
    outline: none;
  }
  #chrome-row .chrome-label { display: none; }
  #chrome-row .chrome-icon { display: block; width: 16px; height: 16px; }
  /* toggles read their state through icon brightness too, not the slash alone */
  #chrome-row [data-state="on"]  { color: color-mix(in oklab, var(--bone) 80%, transparent); }
  #chrome-row [data-state="off"] { color: var(--faint); }
  /* the fullscreen key carries the ember hint (the way onward) */
  #chrome-row #fs-btn { border-color: color-mix(in oklab, var(--ember) 40%, transparent); }
}

/* ═══ NOTCH / DYNAMIC ISLAND ═══════════════════════════════════════════
   viewport-fit=cover runs the film under the notch (right, for the art) —
   but readable chrome must step out of it. env() is 0 where there is no
   notch, and iOS swaps the insets per rotation, so both edges are safe. */
#title-block { left: calc(42px + env(safe-area-inset-left, 0px)); }
#back-btn, #sound-toggle, #music-toggle, #journal-mark { left: calc(30px + env(safe-area-inset-left, 0px)); }
#help-btn { right: calc(12px + env(safe-area-inset-right, 0px)); }
#fs-btn { right: calc(44px + env(safe-area-inset-right, 0px)); }
#satchel { margin-right: env(safe-area-inset-right, 0px); }

@media (max-height: 440px), (pointer: coarse) and (max-height: 540px) {
  #title-block { left: calc(20px + env(safe-area-inset-left, 0px)); }
  #back-btn, #sound-toggle, #music-toggle, #journal-mark { left: calc(14px + env(safe-area-inset-left, 0px)); }
  /* iPhone Safari overlays the TOP — the help pill lives at the bottom-right
     corner, where the screen is provably visible. Fullscreen moved into the
     bottom-left #chrome-row, so this corner holds only the help pill now. */
  #help-btn { top: auto; bottom: calc(8px + env(safe-area-inset-bottom, 0px)); right: calc(8px + env(safe-area-inset-right, 0px)); }
}

/* the forge hearth breathes — a faint living shimmer over the coals
   (testers: the fire read as too subtle). Screen-blend light over film. */
.hearth-shimmer {
  position: absolute; width: 9vmin; height: 7vmin; transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(228, 128, 66, .38), rgba(201, 106, 43, .16) 55%, transparent 75%);
  mix-blend-mode: screen; filter: blur(4px); pointer-events: none;
  animation: hearth-shimmer 2.6s ease-in-out infinite alternate;
}
.hearth-shimmer.lit { animation-duration: 1.7s; }
.hearth-shimmer.lit::after {
  content: ''; position: absolute; inset: 18%;
  background: radial-gradient(closest-side, rgba(240, 168, 90, .3), transparent 70%);
  animation: hearth-shimmer 1.1s ease-in-out infinite alternate-reverse;
}
@keyframes hearth-shimmer {
  from { opacity: .5; transform: translate(-50%, -50%) scale(.94); }
  to   { opacity: .95; transform: translate(-50%, -52%) scale(1.07); }
}
@media (prefers-reduced-motion: reduce) { .hearth-shimmer, .hearth-shimmer.lit::after { animation: none; opacity: .6; } }

/* ═══ MOBILE BOTTOM ALIGNMENT + CARD SCALE (operator polish) ═══════════
   the two bottom rows — the icon menu (left) and the trophy bar (right) —
   share one baseline and one box height. The satchel rides ABOVE the
   journey strip's band, so it can wear its full 30px slots here. And the
   trophy card stops shouting: smaller type, the relic centered at the top. */
@media (max-height: 440px), (pointer: coarse) and (max-height: 540px) {
  #satchel {
    transform: none;
    bottom: calc(36px + env(safe-area-inset-bottom, 0px));
    right: calc(8px + env(safe-area-inset-right, 0px));
    gap: 5px;
  }
  .satchel-slot { width: 30px; height: 30px; }

  #card-body { padding: 20px 22px 18px; }
  .card-sprite { width: 108px; height: 108px; margin: 0 auto 12px; }
  .card-kicker { font-size: 8.5px; margin-bottom: 8px; text-align: center; }
  .card-name { font-size: 22px; margin-bottom: 10px; }
  .card-for { font-size: 11px; }
  .card-line, .card-edge, .card-discipline, .card-human { font-size: 12.5px; line-height: 1.55; }
  .card-doors .card-door { font-size: 9px; padding: 8px 12px; }
  #card-close { top: 12px; right: 16px; font-size: 22px; }
}
