/* Depth behind the pinned stage.
 *
 * Three planes, each moving at its own rate against `--pos` (0–4, written by
 * experience.js): coloured light far back, a bento-tray floor in the middle,
 * and small work tokens up front. The tokens belong to one beat each, so the
 * background shows what the sentence says — a conversation, the sources, the
 * result, the permissions, the invitation — without adding more copy.
 *
 * Positions and identity colours live here, never in style attributes: the
 * production CSP is `style-src 'self'`.
 */
.depth {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  --glow-alpha: 0.2;
}
:root[data-theme="dark"] .depth {
  --glow-alpha: 0.3;
}
.depth > * {
  position: absolute;
}
.depth-chips {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

/* Far plane: light pools in the characters' colours. They drift slowly and
   the one belonging to the bot in focus brightens. */
.depth-glow {
  width: 62vmax;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--glow) calc(var(--glow-alpha) * 100%), transparent),
    transparent
  );
  opacity: 0.55;
  transition: opacity 900ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: translate;
}
.depth-glow[data-glow="pink"] {
  --glow: #ff6ccb;
  left: -18vmax;
  top: 22%;
  translate: calc(var(--pos, 0) * 3vw) calc(var(--pos, 0) * -4vh);
}
.depth-glow[data-glow="lilac"] {
  --glow: #b694ff;
  left: 30%;
  top: -34vmax;
  translate: calc(var(--pos, 0) * -2vw) calc(var(--pos, 0) * 5vh);
}
.depth-glow[data-glow="acid"] {
  --glow: #ccff00;
  right: -22vmax;
  bottom: -30vmax;
  translate: calc(var(--pos, 0) * -4vw) calc(var(--pos, 0) * -3vh);
}
/* Lime light over a dark room reads as olive, so at night the third pool is
   a cool blue instead. */
:root[data-theme="dark"] [data-glow="acid"] {
  --glow: #6d7cff;
}
.journey:is([data-scene="0"], [data-scene="4"]) [data-glow="acid"],
.journey[data-scene="1"] [data-glow="pink"],
.journey[data-scene="2"] [data-glow="lilac"],
.journey[data-scene="3"] :is([data-glow="pink"], [data-glow="lilac"]) {
  opacity: 1;
}

/* Middle plane: no floor to stand on. A soft pool of light sits where the
   cast is, following it from the right of the room to the left, and fades
   out long before any edge could show. */
.depth-floor {
  left: -20%;
  right: -20%;
  bottom: -25%;
  height: 80%;
  --cast-x: calc(64% - min(1, var(--pos, 0)) * 36%);
  background: radial-gradient(
    ellipse 34% 30% at var(--cast-x) 52%,
    var(--pool),
    transparent 72%
  );
  --pool: #ffffffd0;
}
:root[data-theme="dark"] .depth-floor {
  --pool: #9fb0ff14;
}

/* Near plane: work tokens. Each beat owns three; they fade in with it and
   slide past at different speeds, the nearest fastest. */
.depth-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 13px 8px 10px;
  border-radius: 999px;
  font-size: 13px;
  line-height: 1.2;
  letter-spacing: -0.005em;
  white-space: nowrap;
  color: var(--fg);
  background: color-mix(in srgb, var(--surface) 78%, transparent);
  border: 1px solid var(--edge);
  box-shadow:
    0 12px 32px var(--soft-shadow),
    inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent);
  backdrop-filter: blur(10px);
  opacity: 0;
  scale: 0.94;
  --depth: 1;
  --dy: calc((var(--pos, 0) - var(--b)) * -110px * var(--depth));
  --dx: calc((var(--pos, 0) - var(--b)) * 18px * var(--depth));
  translate: var(--dx) var(--dy);
  transition:
    opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
    scale 520ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: translate, opacity;
}
.depth-chip svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: var(--id-text, var(--fg));
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
:root[data-theme="dark"] .depth-chip svg {
  stroke: var(--id, var(--fg));
}
.depth-chip::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  border: 1px solid color-mix(in srgb, var(--id, transparent) 45%, transparent);
  mask-image: linear-gradient(100deg, #000, transparent 55%);
}
.depth-chip[data-b="0"] { --b: 0; }
.depth-chip[data-b="1"] { --b: 1; }
.depth-chip[data-b="2"] { --b: 2; }
.depth-chip[data-b="3"] { --b: 3; }
.depth-chip[data-b="4"] { --b: 4; }
.depth-chip[data-slot="a"] { --depth: 1; }
.depth-chip[data-slot="b"] { --depth: 1.7; }
.depth-chip[data-slot="c"] { --depth: 0.55; font-size: 12px; opacity: 0; }

.journey[data-scene="0"] .depth-chip[data-b="0"],
.journey[data-scene="1"] .depth-chip[data-b="1"],
.journey[data-scene="2"] .depth-chip[data-b="2"],
.journey[data-scene="3"] .depth-chip[data-b="3"],
.journey[data-scene="4"] .depth-chip[data-b="4"] {
  opacity: 1;
  scale: 1;
}
/* The far token sits out of focus, like the back of a real room. */
.journey .depth-chip[data-slot="c"] {
  filter: blur(1.1px);
}
.journey[data-scene] .depth-chip[data-slot="c"] {
  opacity: 0;
}
.journey[data-scene="0"] .depth-chip[data-slot="c"][data-b="0"],
.journey[data-scene="1"] .depth-chip[data-slot="c"][data-b="1"],
.journey[data-scene="2"] .depth-chip[data-slot="c"][data-b="2"],
.journey[data-scene="3"] .depth-chip[data-slot="c"][data-b="3"],
.journey[data-scene="4"] .depth-chip[data-slot="c"][data-b="4"] {
  opacity: 0.72;
}
.journey[data-scene] .depth-chip[data-slot="c"][data-b] {
  transition-delay: 60ms;
}
.journey[data-scene] .depth-chip[data-slot="b"] {
  transition-delay: 120ms;
}

/* Opening beat: the free space is above and to the right of the cast. */
.depth-chip[data-b="0"][data-slot="a"] { left: 43%; top: 17%; }
.depth-chip[data-b="0"][data-slot="b"] { left: 79%; top: 27%; }
.depth-chip[data-b="0"][data-slot="c"] { left: 84%; top: 66%; }
/* Later beats: the cast moves down-left and the document owns the right, so
   tokens use the band above the document and the gap beneath it. */
.depth-chip:not([data-b="0"])[data-slot="a"] { left: 58%; top: 12.5%; }
.depth-chip:not([data-b="0"])[data-slot="b"] { left: 72%; top: 84%; }
.depth-chip:not([data-b="0"])[data-slot="c"] { left: 34%; top: 15%; }

/* Without the scene the stage is a plain column; keep only the light. */
html:not(.scene-enabled) body:not(.scene-enabled) :is(.depth-floor, .depth-chips) {
  display: none;
}
@media (max-width: 760px), (max-height: 620px) {
  .depth-chips {
    display: none;
  }
  .depth-floor {
    --cast-x: 50%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .depth-glow,
  .depth-chip {
    translate: none;
    transition: opacity 1ms;
  }
  .depth-floor {
    --cast-x: 58%;
  }
}

/* The ground floor gets the same far plane, drifting at a third of the
   reader's pace so the page keeps depth after the stage releases. */
.ground {
  position: relative;
  isolation: isolate;
}
.ground-depth {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  --glow-alpha: 0.12;
}
:root[data-theme="dark"] .ground-depth {
  --glow-alpha: 0.16;
}
.ground-depth .depth-glow {
  position: absolute;
  width: 70vmax;
  opacity: 1;
}
.ground-depth [data-glow="lilac"] {
  left: auto;
  right: -30vmax;
  top: 8%;
  translate: 0 calc(var(--gy, 0) * 0.3px);
}
.ground-depth [data-glow="pink"] {
  left: -34vmax;
  top: 38%;
  translate: 0 calc(var(--gy, 0) * -0.22px);
}
.ground-depth [data-glow="acid"] {
  right: auto;
  bottom: auto;
  left: 20%;
  top: 72%;
  translate: 0 calc(var(--gy, 0) * 0.18px);
}
@media (prefers-reduced-motion: reduce) {
  .ground-depth .depth-glow {
    translate: none;
  }
}

/* The sprite casts (phones, no-WebGL) used a painted disc as a floor. Like the
   3D stage, they now stand on nothing but a soft shadow that fades to the
   room before any edge can show. */
.static-cast:before,
.mobile-cast:before {
  background: radial-gradient(
    ellipse 42% 36% at 50% 42%,
    #0000002e,
    #0000000f 55%,
    transparent 72%
  );
  box-shadow: none;
  border-radius: 0;
}
:root[data-theme="dark"] :is(.static-cast, .mobile-cast):before {
  background: radial-gradient(
    ellipse 42% 36% at 50% 42%,
    #00000080,
    #0000002e 55%,
    transparent 72%
  );
}
