/* The Vision (pearl 02): concept C, "From grid to mind" (vision.js, VISION-CONCEPTS.md).
   Black leads, lilac is the light. The network fills the right of the screen; the copy sits on the left; the
   pillars take the whole width at the end. The header reuses the journey page's .j-head / .j-back. */
.vision { position: absolute; inset: 0; z-index: 4; visibility: hidden; pointer-events: none; cursor: pointer; }
.vision.is-open { pointer-events: auto; }
.vision .v-bg {
  position: absolute; inset: 0; opacity: 0;
  background:
    radial-gradient(55% 60% at 70% 50%, rgba(140, 124, 255, 0.09), transparent 70%),
    linear-gradient(180deg, #060609 0%, #030304 100%);
}
.vision .v-net { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* ---------- the copy, left ---------- */
.v-copy {
  position: absolute; left: calc(var(--fx) + 115.2 * var(--dpx)); top: 50%; width: calc(640 * var(--dpx)); transform: translateY(-50%);
  visibility: hidden; opacity: 0; pointer-events: none;
}
.v-kicker {
  margin: 0; display: flex; align-items: center; gap: calc(14 * var(--dpx));
  font-size: calc(14 * var(--dpx)); font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--lilac-pale);
}
.v-kicker::before { content: ""; width: calc(34 * var(--dpx)); height: 1px; background: rgba(214, 208, 255, 0.7); }
.v-kicker span { color: #9e98bd; font-weight: 500; }
.v-title {
  margin: calc(22 * var(--dpx)) 0 0; font-weight: 300; font-size: calc(92.16 * var(--dpx)); line-height: 1.02; letter-spacing: -0.035em; color: #fff;
}
.v-title em {
  font-style: normal; font-weight: 400;
  background: linear-gradient(100deg, #ffffff 0%, #d6d0ff 45%, #a69aff 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.v-body { margin: calc(28 * var(--dpx)) 0 0; max-width: 30ch; font-size: calc(24.96 * var(--dpx)); line-height: 1.5; color: #d9d5ef; }

/* a shift: "From" (struck through as the network changes), then "To" */
.v-from, .v-to { margin: 0; display: grid; grid-template-columns: calc(78 * var(--dpx)) 1fr; align-items: baseline; }
.v-from { margin-top: calc(34 * var(--dpx)); font-size: calc(32.64 * var(--dpx)); font-weight: 300; color: #b9b4d4; line-height: 1.2; }
.v-to { margin-top: calc(26 * var(--dpx)); font-size: calc(72.96 * var(--dpx)); font-weight: 300; color: #fff; line-height: 1.04; letter-spacing: -0.03em; }
.v-lab { font-size: calc(13 * var(--dpx)); font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: #8f8aa8; align-self: center; }
.v-to .v-lab { color: var(--lilac-pale); }
/* the strike-through: a lilac line drawn across every line of the "From" text (box-decoration-break: clone gives
   each wrapped line its own) */
.v-ftext { background: linear-gradient(#a69aff, #a69aff) no-repeat 0 58% / 0% 2px;
  -webkit-box-decoration-break: clone; box-decoration-break: clone; }

/* ---------- the pillars: a loose constellation (v0.5.2) ----------
   Each .v-pillar is a zero-size anchor at its node (placed by vision.js); the ring is centred on it and the text
   sits to its right, its left or below it. The title sits off-centre, top left. */
.v-pillars { position: absolute; inset: 0; visibility: hidden; opacity: 0; pointer-events: none; }
.v-phead { position: absolute; left: calc(var(--fx) + 115.2 * var(--dpx)); top: calc(var(--fy) + 135 * var(--dpx)); }
.v-pkicker { margin: 0; display: flex; align-items: center; gap: calc(14 * var(--dpx));
  font-size: calc(14 * var(--dpx)); font-weight: 600; letter-spacing: 0.24em; text-transform: uppercase; color: var(--lilac-pale); }
.v-pkicker::before { content: ""; width: calc(34 * var(--dpx)); height: 1px; background: rgba(214, 208, 255, 0.7); }
.v-ptitle { margin: calc(18 * var(--dpx)) 0 0; font-size: calc(78.72 * var(--dpx)); font-weight: 300; line-height: 1.04; letter-spacing: -0.025em; color: #fff; }
.v-ptitle b { font-weight: 600; }
.v-ptitle em { font-style: normal; background: linear-gradient(100deg, #ffffff 0%, #d6d0ff 45%, #a69aff 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.v-pillar { position: absolute; width: 0; height: 0; }
.v-ring {
  position: absolute; left: calc(var(--rs) / -2); top: calc(var(--rs) / -2); width: var(--rs); height: var(--rs);
  border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 35% 30%, rgba(60, 52, 110, 0.85), rgba(10, 9, 18, 0.92) 70%);
  border: 1px solid rgba(214, 208, 255, 0.5);
  box-shadow: 0 0 0 calc(6 * var(--dpx)) rgba(166, 154, 255, 0.07), 0 0 calc(34 * var(--dpx)) rgba(166, 154, 255, 0.4);
}
.v-ring svg { width: 52%; height: 52%; display: block; }
/* a soft dark halo keeps the text clear where a thread runs behind it */
.v-ptext { position: absolute; width: calc(250 * var(--dpx)); text-shadow: 0 0 calc(14 * var(--dpx)) #030304, 0 0 calc(6 * var(--dpx)) #030304, 0 0 2px #030304; }
.side-r .v-ptext { left: calc(var(--rs) / 2 + calc(24 * var(--dpx))); top: 0; translate: 0 -50%; text-align: left; }
.side-l .v-ptext { right: calc(var(--rs) / 2 + calc(24 * var(--dpx))); top: 0; translate: 0 -50%; text-align: right; }
.side-b .v-ptext { left: calc(-125 * var(--dpx)); top: calc(var(--rs) / 2 + calc(18 * var(--dpx))); text-align: center; }
/* a pillar is its icon, its number and name, and one line (v0.5.1) */
.v-pname { margin: 0 0 calc(8 * var(--dpx)); font-size: calc(15 * var(--dpx)); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; line-height: 1.35; color: #fff; text-wrap: balance; }
.v-pname span { display: block; margin-bottom: calc(6 * var(--dpx)); font-size: calc(12 * var(--dpx)); letter-spacing: 0.24em; color: var(--lilac-pale); font-weight: 600; }
.v-pline { margin: 0; font-size: calc(17 * var(--dpx)); line-height: 1.45; color: #cfcae6; text-wrap: balance; }

/* ---------- v0.15: the hero film, full screen at the end ----------
   The film fills the whole screen at its own shape: object-fit: contain never stretches or crops it, so a 21:9 film
   on the 16:9 kiosk gets black bars above and below. It plays at its own resolution (4K is drawn sharp by the
   browser's scaler). It shows inside the merged pillar as that pillar grows to cover the screen (vision.js sets its
   clip-path circle as it grows). */
.v-hero { position: absolute; inset: 0; z-index: 20; background: #000; opacity: 0; visibility: hidden; }
/* the film's circle sits just inside the growing pillar, so the pillar's rim stays visible round it */
.v-hero-v { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #000; }
/* until the film is added: its 21:9 frame, letterboxed as the film will be */
.v-hero-ph { position: absolute; inset: 0; display: none; place-items: center; }
.v-hero.is-missing .v-hero-ph { display: grid; }
.v-hero.is-missing .v-hero-v { visibility: hidden; }
.v-hero-frame { width: min(100vw, calc(100vh * 21 / 9)); aspect-ratio: 21 / 9; box-sizing: border-box; display: grid; place-items: center;
  border: 1px dashed rgba(214, 208, 255, 0.55);
  background: radial-gradient(60% 70% at 50% 50%, rgba(166, 154, 255, 0.16), rgba(10, 9, 18, 0.9) 70%), #05050a; }
.v-hero-frame p { margin: 0; display: flex; flex-direction: column; align-items: center; gap: calc(10 * var(--dpx)); text-align: center; }
.v-hero-frame b { font-weight: 300; font-size: calc(44 * var(--dpx)); letter-spacing: -0.02em; color: #fff; }
.v-hero-frame span { font-size: calc(15 * var(--dpx)); font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--lilac-pale); }
.v-hero-x { position: absolute; top: calc(var(--fy) + 28 * var(--dpx)); right: calc(var(--fx) + 28 * var(--dpx)); z-index: 2;
  width: calc(64 * var(--dpx)); height: calc(64 * var(--dpx)); padding: 0; display: grid; place-items: center; cursor: pointer; border-radius: 50%;
  color: #fff; background: rgba(14, 14, 20, 0.7); border: 1px solid rgba(214, 208, 255, 0.55); opacity: 0; visibility: hidden; transition: background 200ms, border-color 200ms; }
.v-hero-x:hover, .v-hero-x:focus-visible { background: rgba(60, 44, 140, 0.7); border-color: #fff; }
.v-hero-x svg { width: calc(26 * var(--dpx)); height: calc(26 * var(--dpx)); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* ---------- progress: one bar per chapter, and the hint ---------- */
.v-progress { position: absolute; left: calc(var(--fx) + 115.2 * var(--dpx)); bottom: calc(var(--fy) + 54 * var(--dpx)); display: flex; align-items: center; gap: calc(26 * var(--dpx)); opacity: 0; visibility: hidden; }
.v-progress ol { display: flex; gap: calc(8 * var(--dpx)); margin: 0; padding: 0; list-style: none; }
.v-progress button { position: relative; width: calc(44 * var(--dpx)); height: calc(28 * var(--dpx)); padding: 0; border: 0; background: none; cursor: pointer; }
.v-progress button::after { content: ""; position: absolute; left: 0; right: 0; top: calc(12 * var(--dpx)); height: calc(4 * var(--dpx)); border-radius: 2px;
  background: rgba(214, 208, 255, 0.22); transition: background 300ms; }
.v-progress button.is-done::after { background: rgba(214, 208, 255, 0.55); }
.v-progress button.is-on::after { background: #fff; box-shadow: 0 0 calc(10 * var(--dpx)) rgba(214, 208, 255, 0.8); }
.v-hint { font-size: calc(13 * var(--dpx)); font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: #a9a4c4;
  animation: v-hint 2.4s ease-in-out infinite; }
@keyframes v-hint { 50% { color: #f2efff; } }
@media (prefers-reduced-motion: reduce) { .v-hint { animation: none; } }
