/* astrosite-v2 — scroll-scrubbed journey.
   All UI motion is CSS (transform/opacity only). JS scrubs the clip canvases and publishes one number
   per scene (--p, scene progress); CSS keyframes paused at -p seconds do the rest. */

:root {
  --bg: #04100f;
  --ink: #eaf4ef;
  --ink-dim: #a9c4ba;
  --teal: #5fe3c9;
  --fire: #ffb35c;
  --vh: 100vh;
  --cs: 1;
  --fade: 0.5s;
  --display: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --ui: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --pad: clamp(1.25rem, 5vw, 5rem);
}
@supports (height: 100lvh) { :root { --vh: 100lvh; } }

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); color-scheme: dark; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 400 1.0625rem/1.55 var(--ui);
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
a { color: inherit; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------- scene geometry ----------
   Section = spacer only; the stage is zero-height (negative bottom margin) and sticky.
   Each section is pulled up 2 viewports so the next stage pins exactly one span after this one,
   while this one stays pinned underneath through the crossfade. */
.scene { position: relative; }
.scene + .scene { margin-top: calc(-2 * var(--vh)); }
.spacer { height: calc((var(--span) + 2) * var(--vh)); }
.scene.last .spacer { height: calc(var(--span) * var(--vh)); }

.stage {
  position: sticky; top: 0;
  height: var(--vh);
  margin-bottom: calc(-1 * var(--vh));
  overflow: hidden;
  background: var(--bg);
  --p: 0;
  /* inactive: stay opaque for the fade (the entering stage fades in on top), then vanish */
  z-index: 1; opacity: 0; visibility: hidden;
  transition: opacity 0s linear var(--fade), visibility 0s linear var(--fade);
}
.stage.active {
  z-index: 2; opacity: 1; visibility: visible;
  transition: opacity var(--fade) linear, visibility 0s;
}
html:not(.js) #s01 .stage { opacity: 1; visibility: visible; }
/* soft vignette keeps the windows and the picture in one lighting space */
.stage::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%, rgb(0 0 0 / 0) 58%, rgb(1 8 8 / .42) 100%);
}

.media, .media > * { position: absolute; inset: 0; width: 100%; height: 100%; }
.media img, .media canvas { object-fit: cover; display: block; }
.media canvas { opacity: 0; }
.media.has-canvas canvas { opacity: 1; }
.media.has-canvas .still { display: none; }

/* ---------- frame space ----------
   The clip's own pixels (1344x768), cover-fitted to the viewport exactly like the canvas (JS sets --cs).
   Anything placed in it sticks to the same spot of the picture at any screen size. */
.cover {
  position: absolute; left: 50%; top: 50%;
  width: 1344px; height: 768px;
  transform: translate(-50%, -50%) scale(var(--cs));
  perspective: 1800px;
  pointer-events: none;
}
.world { position: absolute; inset: 0; transform-style: preserve-3d; }

/* ---------- panels: poses + a window of scene progress ----------
   Poses: 0 = enter, 1 = middle, 2 = exit. Missing values fall back sensibly (see below). */
.panel {
  position: absolute; left: 0; top: 0;
  width: var(--w, 320px);
  --wa: var(--a, 0); --wb: var(--b, 1);

  --ex0: var(--x0, 672px);  --ey0: var(--y0, 384px);
  --ex2: var(--x2, var(--ex0)); --ey2: var(--y2, var(--ey0));
  --ex1: var(--x1, calc((var(--ex0) + var(--ex2)) / 2));
  --ey1: var(--y1, calc((var(--ey0) + var(--ey2)) / 2));
  --es0: var(--s0, 1); --es2: var(--s2, var(--es0));
  --es1: var(--s1, calc((var(--es0) + var(--es2)) / 2));
  --er0: var(--r0, 0deg); --er2: var(--r2, var(--er0));
  --er1: var(--r1, calc((var(--er0) + var(--er2)) / 2));
  --eq0: var(--q0, 0deg); --eq2: var(--q2, var(--eq0));
  --eq1: var(--q1, calc((var(--eq0) + var(--eq2)) / 2));
  --ez0: var(--z0, 0px); --ez2: var(--z2, var(--ez0));
  --ez1: var(--z1, calc((var(--ez0) + var(--ez2)) / 2));

  --T0: translate3d(var(--ex0), var(--ey0), var(--ez0)) translate(-50%, -50%) scale(var(--es0)) rotateY(var(--er0)) rotateX(var(--eq0));
  --T1: translate3d(var(--ex1), var(--ey1), var(--ez1)) translate(-50%, -50%) scale(var(--es1)) rotateY(var(--er1)) rotateX(var(--eq1));
  --T2: translate3d(var(--ex2), var(--ey2), var(--ez2)) translate(-50%, -50%) scale(var(--es2)) rotateY(var(--er2)) rotateX(var(--eq2));

  transform: var(--T0);
  opacity: 0; visibility: hidden;
  animation: track 1s linear both paused;
  animation-delay: calc((var(--p) - var(--wa)) / (var(--wb) - var(--wa)) * -1s);
  will-change: transform, opacity;
}
/* settle in and stay anchored: pose 0 -> pose 1 (rest), then nothing */
.panel.pop {
  --ex1: var(--x1, var(--ex0)); --ey1: var(--y1, var(--ey0));
  --es1: var(--s1, 1); --er1: var(--r1, 0deg); --eq1: var(--q1, 0deg); --ez1: var(--z1, 0px);
  --ex2: var(--ex1); --ey2: var(--ey1); --es2: var(--es1); --er2: var(--er1); --eq2: var(--eq1); --ez2: var(--ez1);
  animation-name: track-pop;
}
.panel.hold  { animation-name: track-hold; }
/* settle quickly into pose 1, then ride the picture to pose 2 (anchored to something that moves) */
.panel.pin {
  --ex1: var(--x1, var(--ex0)); --ey1: var(--y1, var(--ey0));
  --es1: var(--s1, 1); --er1: var(--r1, 0deg); --eq1: var(--q1, 0deg); --ez1: var(--z1, 0px);
  --ex2: var(--x2, var(--ex1)); --ey2: var(--y2, var(--ey1));
  --es2: var(--s2, var(--es1)); --er2: var(--r2, var(--er1)); --eq2: var(--q2, var(--eq1)); --ez2: var(--z2, var(--ez1));
  animation-name: track-pin;
}
.panel.start { animation-name: track-start; }

@keyframes track {
  0%   { transform: var(--T0); opacity: 0; visibility: hidden; }
  8%   { opacity: 1; visibility: visible; }
  50%  { transform: var(--T1); }
  92%  { opacity: 1; visibility: visible; }
  100% { transform: var(--T2); opacity: 0; visibility: hidden; }
}
@keyframes track-hold {
  0%   { transform: var(--T0); opacity: 0; visibility: hidden; }
  8%   { opacity: 1; visibility: visible; }
  50%  { transform: var(--T1); }
  100% { transform: var(--T2); opacity: 1; visibility: visible; }
}
@keyframes track-pop {
  0%   { transform: var(--T0); opacity: 0; visibility: hidden; }
  14%  { transform: var(--T1); opacity: 1; visibility: visible; }
  100% { transform: var(--T1); opacity: 1; visibility: visible; }
}
@keyframes track-pin {
  0%   { transform: var(--T0); opacity: 0; visibility: hidden; }
  10%  { transform: var(--T1); opacity: 1; visibility: visible; }
  100% { transform: var(--T2); opacity: 1; visibility: visible; }
}
@keyframes track-start {
  0%   { transform: var(--T0); opacity: 1; visibility: visible; }
  50%  { transform: var(--T1); }
  86%  { opacity: 1; visibility: visible; }
  100% { transform: var(--T2); opacity: 0; visibility: hidden; }
}

/* narrow (portrait) screens only show a slice of the frame: everything stacks in the visible middle,
   one window at a time, using the alternate windows (--an/--bn) */
html.narrow .panel {
  --ex0: 672px; --ex1: 672px; --ex2: 672px;
  --wa: var(--an, var(--a, 0)); --wb: var(--bn, var(--b, 1));
  width: min(var(--w, 320px), 340px);
}
html.narrow .contact-panel { --es0: .9; --es1: 1; --es2: 1; }

/* ---------- the window ---------- */
.win {
  position: relative; margin: 0;
  padding: 36px 24px 22px;
  border: 1px solid rgb(95 227 201 / .55);
  border-radius: 12px;
  background:
    repeating-linear-gradient(0deg, rgb(95 227 201 / .035) 0 2px, transparent 2px 5px),
    linear-gradient(160deg, rgb(6 34 33 / .82), rgb(3 16 18 / .78));
  box-shadow: 0 0 0 1px rgb(95 227 201 / .1) inset, 0 0 36px rgb(95 227 201 / .2), 0 18px 50px rgb(0 0 0 / .45);
  text-shadow: 0 1px 8px rgb(0 0 0 / .6);
  pointer-events: auto;
  transition: box-shadow .25s ease, border-color .25s ease, transform .25s ease;
}
/* window chrome: three dots */
.win::before {
  content: ""; position: absolute; left: 16px; top: 13px; width: 46px; height: 8px;
  background:
    radial-gradient(circle at 4px 4px, rgb(95 227 201 / .9) 3px, transparent 3.5px),
    radial-gradient(circle at 23px 4px, rgb(255 179 92 / .7) 3px, transparent 3.5px),
    radial-gradient(circle at 42px 4px, rgb(169 196 186 / .45) 3px, transparent 3.5px);
}
.win::after { /* corner glints */
  content: ""; position: absolute; inset: -1px; border-radius: 12px; pointer-events: none;
  background:
    linear-gradient(var(--teal), var(--teal)) top left / 18px 1px no-repeat,
    linear-gradient(var(--teal), var(--teal)) top left / 1px 18px no-repeat,
    linear-gradient(var(--teal), var(--teal)) bottom right / 18px 1px no-repeat,
    linear-gradient(var(--teal), var(--teal)) bottom right / 1px 18px no-repeat;
}
.win:hover { border-color: var(--teal); box-shadow: 0 0 0 1px rgb(95 227 201 / .25) inset, 0 0 56px rgb(95 227 201 / .4), 0 18px 50px rgb(0 0 0 / .45); transform: translate3d(0, -3px, 0); }

.win p { margin: 0; font: 400 26px/1.3 var(--display); }
.win p + p { margin-top: 10px; }
.win h2 { margin: 0 0 8px; font: 400 36px/1.1 var(--display); color: var(--teal); }
.win .meta { margin-top: 12px; font: 400 19px/1.3 var(--ui); color: var(--ink-dim); }
.win .meta a, .win a { text-underline-offset: 4px; text-decoration-thickness: 1px; }
.win .meta a { color: var(--teal); transition: color .2s; }
.win .meta a:hover, .win .meta a:focus-visible { color: var(--ink); }
.win time { display: block; margin-bottom: 6px; font: 500 19px/1.3 var(--mono); color: var(--fire); }
.flagship .win { border-color: rgb(95 227 201 / .85); }
.flagship h2 { font-size: 44px; }
.flagship p { font-size: 30px; }

/* the name: big type, no box */
.panel.bare .win {
  padding: 0; border: 0; background: none; box-shadow: none; pointer-events: none;
  font: 400 150px/.95 var(--display); letter-spacing: -.02em; text-align: center; margin: 0;
  text-shadow: 0 0 60px rgb(95 227 201 / .35), 0 4px 40px rgb(0 0 0 / .8);
}
.panel.bare .win::before, .panel.bare .win::after { display: none; }

/* link-only windows (hall) */
.panel.link .win { text-align: center; padding: 34px 20px 18px; }
.panel.link a { font: 400 30px/1.2 var(--display); text-decoration: none; color: var(--ink); }
.panel.link a:hover, .panel.link a:focus-visible { color: var(--teal); }

/* dwell-triggered second lines: reward for stopping */
.dwell {
  opacity: 0; transform: translate3d(0, 8px, 0);
  transition: opacity .9s ease, transform .9s ease;
}
.win p.dwell { font: 400 22px/1.4 var(--ui); color: var(--ink-dim); }
.dwell.show { opacity: 1; transform: none; }

/* visible placeholders for anything not yet confirmed in the inventory */
.ph {
  display: inline-block;
  font: 500 22px/1.4 var(--mono) !important;
  color: var(--fire);
  border: 1px dashed rgb(255 179 92 / .7);
  border-radius: 4px; padding: .1em .5em;
  background: rgb(20 10 0 / .4);
}

/* scene 7: the held dark beat before the peak */
.dim {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse at 50% 58%, rgb(0 10 12 / .4), rgb(0 4 6 / .9));
  transition: opacity 1.4s ease;
}
.stage.hold .dim { opacity: 1; }
/* the transition out of scene 7 starts as dark as scene 7 ended, then lifts while the clip itself
   darkens and brightens: dark, held, then release */
.dim.lift {
  opacity: clamp(0, calc((.46 - var(--p)) / .3), 1);
  transition: none;
}

/* ---------- scene 9: contact window + rest ---------- */
.contact-panel .win { padding-bottom: 26px; }
.say { display: grid; gap: 10px; }
.field { position: relative; display: block; border-bottom: 1px solid rgb(255 179 92 / .6); transition: border-color .25s; }
.field:focus-within { border-color: var(--fire); }
.field input {
  width: 100%; background: transparent; border: 0; outline: 0; padding: 4px 0 10px;
  color: var(--ink); caret-color: var(--fire);
  font: 400 38px/1.2 var(--display);
}
/* an always-on cursor, so the input reads as live before anyone touches it */
.field::after {
  content: ""; position: absolute; left: 0; top: 7px; width: 2px; height: 40px; background: var(--fire);
  animation: blink 1.1s steps(1) infinite; pointer-events: none;
}
.field:focus-within::after, .field:has(input:not(:placeholder-shown))::after { display: none; }
@keyframes blink { 50% { opacity: 0; } }
.mail {
  justify-self: start; font: 400 21px/1.4 var(--ui); color: var(--ink-dim);
  text-decoration: none; border-bottom: 1px solid transparent; transition: color .2s, border-color .2s;
}
.mail:hover, .mail:focus-visible { color: var(--ink); border-color: var(--fire); }
.links { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 22px; }
.links a { font: 400 20px/1.4 var(--ui); color: var(--ink-dim); text-decoration: none; transition: color .2s; }
.links a:hover, .links a:focus-visible { color: var(--teal); }

/* the hall holds still while the page hands over to normal flow */
.contact {
  position: relative; z-index: 3; min-height: var(--vh);
  background: linear-gradient(0deg, var(--bg) 0, rgb(4 16 15 / 0) 16vh);
}

/* pointer parallax in the hall: the room leans slightly toward the pointer (hover devices only) */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  #s09 .media { transform: translate3d(calc(var(--mx, 0) * -10px), calc(var(--my, 0) * -6px), 0) scale(1.03); transition: transform .6s ease-out; }
  #s09 .world { transform: rotateY(calc(var(--mx, 0) * 2.2deg)) rotateX(calc(var(--my, 0) * -1.6deg)); transition: transform .6s ease-out; }
}

/* ==========================================================================
   TAGS: the page's one UI component. A tag is pinned to a real object in the clip:
     .tag        exists while scene progress is inside its window (JS toggles .in)
       .tk       tracked: generated keyframes (tracks.css) move it frame by frame with the object,
                 scale it with the object's distance and turn it toward the camera axis
         .tk::before / ::after   scene ornaments at the anchor (scan arc, sonar ping, sun halo, HUD beam)
         .reticle  sits on the object (bracket lock by default)
         .leader   elbow leader: a ticked line from the object to a knee, then a shelf along the card edge
         .card     the content. ::before = the shelf (or a bead), ::after = the scene's skin layer
   Direction classes say where the card sits relative to the anchor, so the elbow bends the right way:
     (none) card above-right   .l card on the left   .b card below   .c / .pin / .node centered, no elbow
   One component, seven skins: .comms (space), .hud (plains), .pin (village), .pod (underwater),
   .node (golden hour), and the hall (#s09). Entrances are staged CSS: lock, draw, shelf, unfold, text.
   Depth: tags inside .cover.mid sit behind the foreground canvas (.fg), so near things in the clip
   (kelp, benches, the ship) pass in front of them. Tags in .cover.front stay on top and cast deeper shadows.
   All motion here is transform/opacity. backdrop-filter is static.
   ========================================================================== */
.tag {
  position: absolute; left: 0; top: 0;
  opacity: 0; visibility: hidden;
  transition: opacity .45s ease, visibility 0s linear .45s;
  --L: 34px;                       /* shelf length */
  --kn: calc(-1 * var(--L));       /* knee: where the leader meets the shelf, relative to the card corner */
}
.tag.l { --kn: var(--L); }
.tag.c, .tag.pin, .tag.node, .tag.planet { --kn: 0px; }
.tag.in { opacity: 1; visibility: visible; transition: opacity .45s ease, visibility 0s; }
.tag.past { opacity: .86; }

.tk {
  position: absolute; left: 0; top: 0;
  transform-style: preserve-3d;
  animation-duration: 1s; animation-timing-function: linear; animation-fill-mode: both;
  animation-play-state: paused;
  /* the clip's playhead: scene progress mapped through the scene's play range (--pe = its end) */
  animation-delay: calc(min(var(--p) / var(--pe, 1), 1) * -1s);
  will-change: transform;
}

/* ---------- anchor ornaments: default is a scan arc circling the lock ---------- */
.tk::before, .tk::after {
  content: ""; position: absolute; left: 0; top: 0; pointer-events: none; opacity: 0;
}
.tk::before {
  width: 46px; height: 46px; margin: -23px 0 0 -23px; border-radius: 50%;
  background: conic-gradient(rgb(var(--tint)) 0 54deg, transparent 54deg 180deg, rgb(var(--tint) / .55) 180deg 204deg, transparent 204deg);
  -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px));
  mask: radial-gradient(closest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px));
  transition: opacity .4s ease .35s;
}
.tag.in .tk::before { opacity: .85; animation: spin 5s linear infinite; }
@keyframes spin { to { transform: rotate(1turn); } }
@keyframes ping { 0% { opacity: .9; transform: scale(.45); } 100% { opacity: 0; transform: scale(2.7); } }

/* ---------- reticle: four brackets that lock onto the object ---------- */
.reticle {
  position: absolute; left: 0; top: 0; width: 24px; height: 24px; margin: -12px 0 0 -12px;
  opacity: 0; transform: scale(2.4) rotate(45deg);
  transition: transform .5s cubic-bezier(.2, .9, .25, 1), opacity .25s ease;
}
.reticle::before {
  content: ""; position: absolute; inset: 0;
  --c: rgb(var(--tint));
  background:
    linear-gradient(var(--c), var(--c)) 0 0 / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 0 / 1.5px 7px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 0 / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 0 / 1.5px 7px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 100% / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 100% / 1.5px 7px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 100% / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 100% / 1.5px 7px no-repeat;
  filter: drop-shadow(0 0 3px rgb(var(--tint) / .8));
}
.reticle::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 4px; height: 4px; margin: -2px 0 0 -2px;
  border-radius: 50%; background: rgb(var(--tint)); box-shadow: 0 0 8px rgb(var(--tint));
}
.tag.in .reticle { opacity: 1; transform: none; }

/* ---------- leader: object -> knee, ticked like a rangefinder ---------- */
.leader {
  position: absolute; left: 0; top: -3px; height: 7px;
  transform-origin: 0 50%;
  background:
    linear-gradient(90deg, rgb(var(--tint) / .95), rgb(var(--tint) / .5)) 0 50% / 100% 1px no-repeat,
    repeating-linear-gradient(90deg, rgb(var(--tint) / .6) 0 1px, transparent 1px 11px) 0 50% / 100% 5px no-repeat;
  filter: drop-shadow(0 0 3px rgb(var(--tint) / .55));
  transform: scaleX(0);
  transition: transform .45s cubic-bezier(.5, 0, .2, 1) .2s;
}
.tag .tk .leader {   /* beats fx.css: ends at the knee, not the corner */
  width: hypot(calc(var(--dx) + var(--psx, 0px) + var(--kn)), calc(var(--dy) + var(--psy, 0px)));
  rotate: atan2(calc(var(--dy) + var(--psy, 0px)), calc(var(--dx) + var(--psx, 0px) + var(--kn)));
}
.tag.in .leader { transform: scaleX(1); }

/* ---------- card ---------- */
.card {
  --edge: rgb(var(--tint));
  --brk:
    linear-gradient(var(--edge), var(--edge)) 0 0 / 13px 2px no-repeat,
    linear-gradient(var(--edge), var(--edge)) 0 0 / 2px 13px no-repeat,
    linear-gradient(var(--edge), var(--edge)) 100% 100% / 13px 2px no-repeat,
    linear-gradient(var(--edge), var(--edge)) 100% 100% / 2px 13px no-repeat;
  --tilt: rotate(0deg);
  position: absolute; left: var(--dx); top: var(--dy);
  width: var(--w, 300px);
  translate: var(--cx, 0%) var(--cy, -100%);
  padding: 16px 18px 15px;
  background:
    var(--brk),
    linear-gradient(180deg, rgb(var(--tint) / .08), rgb(var(--tint) / 0) 40%),
    linear-gradient(160deg, rgb(5 26 28 / .68), rgb(3 12 14 / .62));
  background-origin: border-box;
  -webkit-backdrop-filter: blur(7px) saturate(1.35);
  backdrop-filter: blur(7px) saturate(1.35);
  border: 1px solid rgb(var(--tint) / .38);
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgb(0 0 0 / .25), 0 0 28px rgb(var(--tint) / .14), 0 12px 30px rgb(0 0 0 / .45);
  color: var(--ink);
  text-shadow: 0 1px 6px rgb(0 0 0 / .55);
  pointer-events: auto;
  transform: var(--tilt);
  transform-origin: 0 100%;
  transition: border-color .25s, box-shadow .25s;
}
.tag.b .card { transform-origin: 0 0; }
.tag.l .card { transform-origin: 100% 100%; }
.tag.l.b .card { transform-origin: 100% 0; }
/* staged entrance: the card unfolds from the corner the leader lands on, then its text arrives */
.tag.in .card { animation: card-in .55s cubic-bezier(.2, .8, .2, 1) .55s backwards; }
.tag.in .card > :not(.dwell) { animation: text-in .45s ease .9s backwards; }
@keyframes card-in {
  0%   { opacity: 0; transform: var(--tilt) scale(.5, .04); }
  50%  { opacity: 1; transform: var(--tilt) scale(1, .04); }
  100% { opacity: 1; transform: var(--tilt); }
}
@keyframes text-in { from { opacity: 0; } }

/* the shelf: from the knee along the card edge, with a dot at the knee */
.card::before {
  content: ""; position: absolute; pointer-events: none;
  width: var(--L); height: 7px; bottom: -4px; left: calc(-1 * var(--L) - 1px);
  background:
    linear-gradient(var(--edge), var(--edge)) 0 50% / 100% 1px no-repeat,
    radial-gradient(circle at 3.5px 50%, var(--edge) 2px, transparent 2.6px);
  filter: drop-shadow(0 0 3px rgb(var(--tint) / .6));
  transform-origin: 0 50%; transform: scaleX(0);
  transition: transform .25s ease .55s;
}
.tag.in .card::before { transform: none; }
.tag.b .card::before { bottom: auto; top: -4px; }
.tag.l .card::before {
  left: calc(100% + 1px); transform-origin: 100% 50%;
  background:
    linear-gradient(var(--edge), var(--edge)) 0 50% / 100% 1px no-repeat,
    radial-gradient(circle at calc(100% - 3.5px) 50%, var(--edge) 2px, transparent 2.6px);
}
.tag.c .card::before, .tag.pin .card::before { display: none; }
.card::after { content: none; }
.card:hover { border-color: rgb(var(--tint) / .8); box-shadow: 0 0 0 1px rgb(0 0 0 / .25), 0 0 40px rgb(var(--tint) / .3), 0 16px 40px rgb(0 0 0 / .5); }

.card h3 { margin: 0 0 6px; font: 400 25px/1.1 var(--display); color: rgb(var(--tint)); letter-spacing: -.005em; }
.card p { margin: 0; font: 400 18px/1.35 var(--display); }
.card p + p { margin-top: 6px; }
.card .meta { margin-top: 9px; font: 400 13px/1.3 var(--mono); color: var(--ink-dim); letter-spacing: .02em; }
.card .meta a { color: rgb(var(--tint)); text-underline-offset: 3px; transition: color .2s; }
.card .meta a:hover, .card .meta a:focus-visible { color: var(--ink); }
.card time { display: block; margin-bottom: 5px; font: 500 13px/1.2 var(--mono); color: var(--fire); letter-spacing: .04em; }
.card .dwell { font: 400 14px/1.35 var(--ui); color: var(--ink-dim); }
.card .ph { font-size: 15px !important; }

/* ---------- depth of field: the plane a tag lives on changes how it's lit and focused ---------- */
.cover.front .card { box-shadow: 0 0 0 1px rgb(0 0 0 / .25), 0 0 30px rgb(var(--tint) / .16), 0 26px 60px rgb(0 0 0 / .55); }
.cover.mid .card { box-shadow: 0 0 0 1px rgb(0 0 0 / .25), 0 0 22px rgb(var(--tint) / .12), 0 8px 22px rgb(0 0 0 / .4); }
.tag.far .reticle, .tag.far .leader, .tag.far .tk::before, .tag.far .tk::after { filter: blur(.9px); }
.tag.far .reticle { opacity: .75; }
.tag.far .card {
  background: var(--brk), linear-gradient(160deg, rgb(10 38 40 / .6), rgb(6 22 24 / .58));
  border-color: rgb(var(--tint) / .22);
  -webkit-backdrop-filter: blur(4px) saturate(1.1); backdrop-filter: blur(4px) saturate(1.1);
}

/* ==========================================================================
   SPACE (s01, s02): comms readouts. Cold glass, scanlines, a segmented header strip,
   a signal meter on the right edge. They boot like a screen: a line, then the panel.
   ========================================================================== */
.tag.comms .card {
  padding: 22px 62px 16px 20px;
  background:
    var(--brk),
    linear-gradient(var(--edge), var(--edge)) right 18px bottom 15px / 3px 7px no-repeat,
    linear-gradient(var(--edge), var(--edge)) right 24px bottom 15px / 3px 12px no-repeat,
    linear-gradient(var(--edge), var(--edge)) right 30px bottom 15px / 3px 17px no-repeat,
    linear-gradient(rgb(var(--tint) / .35), rgb(var(--tint) / .35)) right 36px bottom 15px / 3px 22px no-repeat,
    linear-gradient(rgb(var(--tint) / .2), rgb(var(--tint) / .2)) right 42px bottom 15px / 3px 27px no-repeat,
    repeating-linear-gradient(90deg, rgb(var(--tint) / .85) 0 16px, transparent 16px 20px) 20px 9px / 100px 2px no-repeat,
    linear-gradient(90deg, rgb(var(--tint) / .3), rgb(var(--tint) / 0)) 124px 9px / 60% 1px no-repeat,
    repeating-linear-gradient(0deg, rgb(var(--tint) / .05) 0 1px, transparent 1px 4px),
    linear-gradient(160deg, rgb(4 22 32 / .74), rgb(2 10 18 / .7));
  border-color: rgb(var(--tint) / .32);
  border-left: 2px solid rgb(var(--tint) / .8);
  border-radius: 0 3px 3px 0;
}
.tag.comms.in .card { animation: boot .6s cubic-bezier(.2, .8, .2, 1) .55s backwards; }
@keyframes boot {
  0%   { opacity: 0; transform: var(--tilt) scale(.02, .03); }
  45%  { opacity: 1; transform: var(--tilt) scale(1, .03); }
  60%  { opacity: .6; }
  100% { opacity: 1; transform: var(--tilt); }
}
/* on the hull: the readout is mounted on the ship, so it shares the ship's angle */
.tag.comms.hull .card { --tilt: perspective(900px) rotateY(16deg) rotateX(3deg); }

/* the planet lock: a wide ring with a slow degree scale */
.tag.planet .reticle.lg {
  width: 330px; height: 330px; margin: -165px 0 0 -165px; border-radius: 50%;
  border: 1px solid rgb(var(--tint) / .35); box-shadow: 0 0 40px rgb(var(--tint) / .14);
  transform: scale(1.25);
  transition: transform 1.4s cubic-bezier(.2, .8, .2, 1), opacity 1s ease;
}
.tag.planet .reticle.lg::before {
  inset: -16px; border-radius: 50%; filter: none;
  background: repeating-conic-gradient(rgb(var(--tint) / .55) 0 .5deg, transparent .5deg 5deg);
  -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 9px), #000 calc(100% - 8px));
  mask: radial-gradient(closest-side, transparent calc(100% - 9px), #000 calc(100% - 8px));
}
.tag.planet .reticle.lg::after { display: none; }
.tag.planet.in .reticle.lg { transform: none; }
.tag.planet .tk::before {
  width: 392px; height: 392px; margin: -196px 0 0 -196px;
  background: conic-gradient(rgb(var(--tint) / .8) 0 22deg, transparent 22deg 120deg, rgb(var(--tint) / .5) 120deg 128deg, transparent 128deg 240deg, rgb(var(--tint) / .8) 240deg 262deg, transparent 262deg);
}
.tag.planet.in .tk::before { opacity: .7; animation: spin 40s linear infinite; }

/* ==========================================================================
   PLAINS (s04): the suit HUD. The bio projects out of the backpack ring as a beam that opens into a
   panel; it's attached to the astronaut, so it doesn't drift on a plane of its own.
   ========================================================================== */
.tag.hud { --tint: 150 250 214; }
.tag.hud .card {
  background:
    var(--brk),
    linear-gradient(90deg, rgb(var(--tint) / .75), rgb(var(--tint) / 0) 75%) 0 0 / 100% 1px no-repeat,
    repeating-linear-gradient(0deg, rgb(var(--tint) / .06) 0 1px, transparent 1px 3px),
    linear-gradient(0deg, rgb(var(--tint) / .2), rgb(var(--tint) / .03) 65%),
    linear-gradient(160deg, rgb(4 30 28 / .6), rgb(2 16 16 / .56));
  border-color: rgb(var(--tint) / .42);
  text-shadow: 0 0 12px rgb(var(--tint) / .35), 0 1px 4px rgb(0 0 0 / .7);
}
.tag.hud .reticle { border-radius: 50%; border: 1.5px solid rgb(var(--tint)); box-shadow: 0 0 10px rgb(var(--tint) / .6), inset 0 0 6px rgb(var(--tint) / .4); }
.tag.hud .reticle::before { inset: -6px; }
.tag.hud .tk::after { width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; border: 1px solid rgb(var(--tint)); }
.tag.hud.in .tk::after { animation: ping 2.6s ease-out .7s infinite; }

.tag.hud.pack, .tag.hud.pack .card { --psx: 0px; --psy: 0px; }
.tag.hud.pack .card { --tilt: perspective(1100px) rotateY(-10deg); transform-origin: 0 100%; }
.tag.hud.pack .leader { display: none; }
.tag.hud.pack .card::before { display: none; }
/* the beam: from the ring to the panel's lower edge */
.tag.hud.pack .tk::before {
  left: 0; top: var(--dy); margin: 0; border-radius: 0;
  width: calc(var(--dx) + var(--w)); height: calc(-1 * var(--dy));
  background:
    repeating-linear-gradient(0deg, rgb(var(--tint) / .14) 0 1px, transparent 1px 5px),
    linear-gradient(0deg, rgb(var(--tint) / .6), rgb(var(--tint) / .12) 75%, rgb(var(--tint) / .3));
  -webkit-mask: none; mask: none;
  clip-path: polygon(0 100%, var(--dx) 0, 100% 0);
  transform-origin: 0 100%; transform: scale(0);
  transition: transform .5s cubic-bezier(.3, .8, .3, 1) .2s, opacity .3s ease .2s;
}
.tag.hud.pack.in .tk::before { opacity: 1; transform: none; animation: hum 3.4s ease-in-out 1s infinite; }
@keyframes hum { 50% { opacity: .7; } }
.tag.hud.pack.in .card { animation: project .6s cubic-bezier(.2, .8, .2, 1) .5s backwards; }
@keyframes project {
  0%   { opacity: 0; transform: var(--tilt) scaleY(.02); }
  40%  { opacity: .8; }
  55%  { opacity: .35; }
  70%  { opacity: 1; }
  100% { opacity: 1; transform: var(--tilt); }
}

/* ==========================================================================
   VILLAGE (s05): carved signboards staked into the roofs. Wood plank with a knotwork border
   (assets/ui/wood-plank.webp), firelit lettering, a rope stake, a rune ring on the finial.
   ========================================================================== */
.tag.pin { --tint: 255 190 112; }
.tag.pin .card {
  padding: 15px 26px 14px; text-align: center;
  border: 1px solid transparent; border-radius: 0;
  border-image: url("assets/ui/wood-plank.webp") 74 fill / 22px / 2px round;
  background: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: 0 16px 30px rgb(0 0 0 / .5);
  color: #f8e7c9;
  text-shadow: 0 0 14px rgb(255 160 70 / .5), 0 1px 2px rgb(0 0 0 / .95);
  transform-origin: 50% 100%;
}
.cover.mid .tag.pin .card { box-shadow: 0 8px 18px rgb(0 0 0 / .45); }
.tag.pin .card p { font-size: 17px; letter-spacing: .01em; }
.tag.pin .card::after {   /* the point the sign is staked on */
  content: ""; position: absolute; left: 50%; top: calc(100% + 1px); width: 16px; height: 11px; margin-left: -8px;
  background: linear-gradient(#3a2a1a, #1f2a20);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.tag.pin.in .card { animation: pin-drop .75s cubic-bezier(.3, .7, .3, 1) .5s backwards; }
@keyframes pin-drop {
  0%   { opacity: 0; transform: translateY(-28px) rotate(-5deg); }
  50%  { opacity: 1; transform: translateY(3px) rotate(2.5deg); }
  78%  { transform: rotate(-1deg); }
  100% { transform: none; }
}
.tag.pin .leader {
  height: 3px; top: -1px;
  background: repeating-linear-gradient(90deg, rgb(255 196 120 / .95) 0 5px, rgb(110 64 28 / .95) 5px 8px);
  filter: drop-shadow(0 0 3px rgb(255 150 60 / .7));
}
.tag.pin .reticle { width: 30px; height: 30px; margin: -15px 0 0 -15px; }
.tag.pin .reticle::before {
  inset: 0; border-radius: 50%;
  background: repeating-conic-gradient(rgb(var(--tint)) 0 9deg, transparent 9deg 30deg);
  -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 4px), #000 calc(100% - 3.5px));
  mask: radial-gradient(closest-side, transparent calc(100% - 4px), #000 calc(100% - 3.5px));
}
.tag.pin.in .reticle::before { animation: spin 14s linear infinite; }
.tag.pin .reticle::after { width: 6px; height: 6px; margin: -3px 0 0 -3px; background: #ffd9a0; box-shadow: 0 0 10px 3px rgb(255 150 60 / .8); }
.tag.pin .tk::before {   /* ember glow on the roof */
  width: 64px; height: 64px; margin: -32px 0 0 -32px;
  background: radial-gradient(closest-side, rgb(255 160 70 / .45), rgb(255 160 70 / 0));
  -webkit-mask: none; mask: none;
}
.tag.pin.in .tk::before { opacity: 1; animation: hum 2.8s ease-in-out infinite; }

/* ==========================================================================
   UNDERWATER (s07): dome readouts. Light from the surface catches the top edge, the glass darkens
   with depth, sonar rings radiate from the corner the leader lands on, a sweep line passes down
   the panel. Bubble-dot leaders, double sonar pings on the pods.
   ========================================================================== */
.tag.pod .card {
  --ox: 0%; --oy: 100%;
  background:
    var(--brk),
    linear-gradient(90deg, transparent, rgb(var(--tint) / .95) 30%, rgb(var(--tint) / .95) 70%, transparent) 0 0 / 100% 1px no-repeat,
    repeating-radial-gradient(circle at var(--ox) var(--oy), rgb(var(--tint) / .09) 0 1px, transparent 1.5px 20px),
    linear-gradient(180deg, rgb(8 46 54 / .6), rgb(2 12 22 / .82));
  border-color: rgb(var(--tint) / .26); border-top-color: rgb(var(--tint) / .55);
}
.tag.pod.b .card { --oy: 0%; }
.tag.pod.l .card { --ox: 100%; }
.tag.pod .card::after {   /* the sweep */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 100%; pointer-events: none;
  background: linear-gradient(180deg, rgb(var(--tint) / 0), rgb(var(--tint) / .14) 13px, rgb(var(--tint) / .7) 13px, transparent 14px) 0 0 / 100% 14px no-repeat;
  opacity: 0;
}
.tag.pod.in .card::after { animation: sweep 5.5s linear 1.3s infinite; }
@keyframes sweep {
  0%   { opacity: 0; transform: translateY(-14px); }
  8%   { opacity: .9; }
  85%  { opacity: .5; }
  100% { opacity: 0; transform: translateY(calc(100% - 14px)); }
}
.tag.pod .leader {
  background:
    radial-gradient(circle, rgb(var(--tint) / .9) 1.3px, transparent 1.9px) 0 50% / 9px 7px repeat-x,
    linear-gradient(rgb(var(--tint) / .3), rgb(var(--tint) / .3)) 0 50% / 100% 1px no-repeat;
}
.tag.pod .tk::before, .tag.pod .tk::after {
  width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%;
  background: none; -webkit-mask: none; mask: none;
  border: 1px solid rgb(var(--tint) / .9);
}
.tag.pod.in .tk::before { animation: ping 3.2s ease-out .5s infinite; }
.tag.pod.in .tk::after { animation: ping 3.2s ease-out 2.1s infinite; }

/* the flagship: firelight in the dome, a double frame, the sonar plate behind the title */
.tag.flag { --tint: 255 186 104; }
.tag.flag .card {
  padding: 22px 26px 22px;
  background:
    var(--brk),
    linear-gradient(90deg, transparent, rgb(255 214 160 / .95) 25%, rgb(255 214 160 / .95) 75%, transparent) 0 0 / 100% 1px no-repeat,
    radial-gradient(120% 90% at 0% 100%, rgb(255 160 70 / .16), rgb(255 160 70 / 0) 60%),
    linear-gradient(180deg, rgb(10 40 44 / .66), rgb(3 12 20 / .86));
  border-color: rgb(var(--tint) / .55);
  box-shadow: 0 0 0 4px rgb(var(--tint) / .07), 0 0 0 5px rgb(var(--tint) / .32), 0 0 46px rgb(var(--tint) / .22), 0 14px 34px rgb(0 0 0 / .5);
}
.tag.flag .card::after {
  background: url("assets/ui/sonar-rings.webp") 50% 62% / 140% auto no-repeat;
  mix-blend-mode: screen; opacity: .5;
}
.tag.flag.in .card::after { animation: hum 4s ease-in-out 1.2s infinite; }
.tag.flag .card h3 { font-size: 33px; color: var(--ink); text-shadow: 0 0 22px rgb(255 170 80 / .45), 0 1px 6px rgb(0 0 0 / .6); }
.tag.flag .card p { font-size: 20px; }
.tag.flag .reticle { width: 30px; height: 30px; margin: -15px 0 0 -15px; }
.tag.flag .tk::before, .tag.flag .tk::after { border-width: 1.5px; }

/* ==========================================================================
   GOLDEN HOUR (s08, the peak): sunlit glass on the water. Each card hangs from a light tether to a
   landmark that glints, a bead where the tether lands, its own broken reflection on the water.
   The Now card sits under the sun: brightest glass, a slow ring of rays around the sun.
   ========================================================================== */
.tag.node { --tint: 255 200 136; }
.tag.node .card {
  padding: 13px 14px 13px;
  background:
    linear-gradient(180deg, rgb(255 236 200 / .18), rgb(255 236 200 / 0) 22%),
    linear-gradient(205deg, rgb(255 200 120 / .34), rgb(255 200 120 / 0) 50%),
    linear-gradient(170deg, rgb(122 62 12 / .72), rgb(62 26 4 / .82));
  border: 1px solid rgb(255 214 160 / .4); border-top-color: rgb(255 236 204 / .9);
  border-radius: 6px;
  -webkit-backdrop-filter: blur(10px) saturate(1.6) sepia(.35); backdrop-filter: blur(10px) saturate(1.6) sepia(.35);
  box-shadow: inset 0 1px 0 rgb(255 240 214 / .35), 0 0 26px rgb(255 170 80 / .2), 0 18px 40px rgb(40 14 0 / .45);
  color: #fff4e4;
  text-shadow: 0 1px 4px rgb(40 14 0 / .8);
  transform-origin: 50% 0;
}
.tag.node .card p { font-size: 15.5px; line-height: 1.3; }
.tag.node .card time { color: #ffd59a; }
.tag.node .card .dwell { color: rgb(255 232 204 / .78); }
.tag.node .card::before {   /* the bead */
  display: block; width: 9px; height: 9px; left: 50%; top: -5px; bottom: auto; margin-left: -4.5px;
  border-radius: 50%; background: #ffe6bb; box-shadow: 0 0 10px 2px rgb(255 190 110 / .85);
  filter: none; transform-origin: 50% 50%; transform: scale(0); transition: transform .3s ease .5s;
}
.tag.node .card::after {   /* the reflection */
  content: ""; position: absolute; left: 16%; right: 16%; top: calc(100% + 5px); height: 48px; pointer-events: none;
  background: linear-gradient(180deg, rgb(255 210 150 / .55), rgb(255 204 140 / 0));
  -webkit-mask: repeating-linear-gradient(180deg, #000 0 2px, transparent 2px 5px);
  mask: repeating-linear-gradient(180deg, #000 0 2px, transparent 2px 5px);
  transform-origin: 50% 0;
}
.tag.node.in .card::after { animation: shimmer 3.4s ease-in-out 1.2s infinite; }
@keyframes shimmer { 50% { opacity: .45; transform: scaleX(.82); } }
.tag.node.in .card { animation: rise .7s cubic-bezier(.2, .8, .2, 1) .5s backwards; }
@keyframes rise { from { opacity: 0; transform: translateY(18px) scale(.94); } }
.tag.node .leader {
  height: 5px; top: -2px;
  background:
    linear-gradient(90deg, rgb(255 236 204 / .95), rgb(255 190 110 / .45)) 0 50% / 100% 1px no-repeat,
    radial-gradient(circle, rgb(255 218 160 / .9) 1.3px, transparent 2px) 0 50% / 18px 5px repeat-x;
  filter: drop-shadow(0 0 3px rgb(255 180 90 / .6));
  transition-duration: .7s;
}
.tag.node .reticle { width: 12px; height: 12px; margin: -6px 0 0 -6px; }
.tag.node .reticle::before { inset: 0; background: none; border: 1.5px solid rgb(var(--tint)); transform: rotate(45deg); }
.tag.node .reticle::after { width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px; }
.tag.node .tk::before {   /* the glint on the landmark */
  width: 38px; height: 38px; margin: -19px 0 0 -19px; border-radius: 0;
  background:
    linear-gradient(90deg, transparent, rgb(255 240 214 / .95), transparent) 50% 50% / 100% 1px no-repeat,
    linear-gradient(0deg, transparent, rgb(255 240 214 / .95), transparent) 50% 50% / 1px 100% no-repeat;
  -webkit-mask: none; mask: none;
}
.tag.node.in .tk::before { opacity: 1; animation: twinkle 3.2s ease-in-out infinite; }
@keyframes twinkle { 50% { opacity: .35; transform: scale(.55) rotate(45deg); } }

.tag.node.now .card {
  padding: 16px 18px 16px;
  background:
    linear-gradient(205deg, rgb(255 226 170 / .4), rgb(255 226 170 / 0) 55%),
    linear-gradient(170deg, rgb(92 46 10 / .62), rgb(44 20 4 / .74));
  border-color: rgb(255 226 180 / .75); border-top-color: #fff0d6;
  box-shadow: inset 0 1px 0 rgb(255 244 222 / .5), 0 0 0 4px rgb(255 210 150 / .1), 0 0 70px rgb(255 180 90 / .4), 0 18px 40px rgb(40 14 0 / .45);
}
.tag.node.now .card time { font-size: 16px; color: #ffe2b4; text-shadow: 0 0 14px rgb(255 190 110 / .8); }
.tag.node.now .card::after {
  inset: 0; left: 0; right: 0; top: 0; height: auto; border-radius: inherit;
  background: url("assets/ui/sun-glints.webp") 70% 40% / 150% auto no-repeat;
  -webkit-mask: none; mask: none;
  mix-blend-mode: screen; opacity: .45;
}
.tag.node.now.in .card::after { animation: hum 4.5s ease-in-out 1.2s infinite; }
.tag.node.now .reticle { width: 34px; height: 34px; margin: -17px 0 0 -17px; }
.tag.node.now .reticle::before { border-radius: 50%; transform: none; border-width: 1px; }
.tag.node.now .tk::before {   /* rays around the sun */
  width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 50%;
  background: repeating-conic-gradient(rgb(255 228 180 / .55) 0 .8deg, transparent .8deg 10deg);
  -webkit-mask: radial-gradient(closest-side, transparent 22%, #000 26%, rgb(0 0 0 / 0) 100%);
  mask: radial-gradient(closest-side, transparent 22%, #000 26%, rgb(0 0 0 / 0) 100%);
}
.tag.node.now.in .tk::before { opacity: .75; animation: spin 90s linear infinite; }

/* ==========================================================================
   HALL (s09): the holographic rune panels in the room. Teal light-glass, a knotwork frame of light
   (assets/ui/holo-frame.webp, screen-blended), a rune diamond on each panel, a flicker on arrival.
   ========================================================================== */
#s09 .tag { --tint: 112 240 222; }
#s09 .card {
  background:
    radial-gradient(120% 140% at 50% 0%, rgb(var(--tint) / .17), rgb(var(--tint) / .04) 62%),
    repeating-linear-gradient(0deg, rgb(var(--tint) / .045) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, rgb(6 42 42 / .5), rgb(3 20 22 / .66));
  border: 1px solid rgb(var(--tint) / .42); border-radius: 2px;
  box-shadow: 0 0 20px rgb(var(--tint) / .25), inset 0 0 24px rgb(var(--tint) / .12), 0 16px 40px rgb(0 0 0 / .5);
  text-shadow: 0 0 12px rgb(var(--tint) / .45), 0 1px 3px rgb(0 0 0 / .8);
}
#s09 .card::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border: 1px solid transparent;
  border-image: url("assets/ui/holo-frame.webp") 86 fill / 26px round;
  mix-blend-mode: screen; opacity: .95;
}
#s09 .tag.in .card { animation: holo-in .8s ease-out .5s backwards; }
@keyframes holo-in {
  0%   { opacity: 0; transform: scaleY(.8); }
  18%  { opacity: .85; }
  26%  { opacity: .15; }
  38%  { opacity: .9; transform: none; }
  48%  { opacity: .45; }
  100% { opacity: 1; transform: none; }
}
#s09 .reticle { width: 18px; height: 18px; margin: -9px 0 0 -9px; }
#s09 .reticle::before {
  background: none; border: 1.5px solid rgb(var(--tint)); transform: rotate(45deg);
  box-shadow: inset 0 0 6px rgb(var(--tint) / .6);
}
#s09 .tk::before {
  width: 54px; height: 54px; margin: -27px 0 0 -27px;
  background: repeating-conic-gradient(rgb(var(--tint) / .85) 0 14deg, transparent 14deg 45deg);
}
#s09 .tag.in .tk::before { opacity: .7; animation: spin 18s linear infinite reverse; }
.tag.link .card { padding: 14px 18px 13px; text-align: center; }
.tag.link .card a { font: 400 24px/1.2 var(--display); color: var(--ink); text-decoration: none; transition: color .2s; }
.tag.link .card a:hover, .tag.link .card a:focus-visible { color: rgb(var(--tint)); }

/* the contact card */
.tag.reach .card { padding: 22px 26px 22px; }
#s09 .tag.reach .card { border-color: rgb(var(--tint) / .55); }
.tag.reach .field { padding-left: 26px; }
.tag.reach .field::before { content: "›"; position: absolute; left: 0; top: 2px; font: 400 30px/1.2 var(--display); color: var(--fire); }
.tag.reach .field::after { left: 26px; }
.tag.reach .field input { font-size: 30px; }
.tag.reach .field::after { height: 32px; }
.tag.reach .mail { font-size: 16px; }
.tag.reach .links a { font-size: 15px; }

/* the foreground matte canvas: the clip drawn again through a depth mask, above .cover.mid */
.fg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }

/* ---------- card mode: narrow screens and reduced motion ----------
   A portrait screen sees a sliver of the frame, and reduced motion means nothing tracks, so tags become
   plain caption cards at the bottom, one at a time (the newest, .top). They keep their scene's skin. */
html.cards .tk { animation: none !important; transform: none !important; position: static; }
html.cards .tag { left: 50%; top: auto; bottom: calc(14px + var(--pad)); position: absolute; width: min(92vw, 420px); translate: -50% 0; }
html.cards .cover { transform: none; left: 0; top: 0; width: 100%; height: 100%; perspective: none; }
html.cards .reticle, html.cards .leader, html.cards .tk::before, html.cards .tk::after { display: none; }
html.cards .card { position: relative; left: 0; top: 0; translate: none; width: 100%; --tilt: rotate(0deg); transform-origin: 50% 100%; }
html.cards .card::before { display: none; }
html.cards .tag .card { --tilt: rotate(0deg) !important; }
html.cards .tag.pin .card::after, html.cards .tag.node:not(.now) .card::after { display: none; }
html.cards .tag:not(.top):not(.rail .tag) { opacity: 0 !important; visibility: hidden !important; }
html.cards .world { transform-style: flat; }
html.cards .fg { display: none; }   /* captions are never occluded */
html.cards .tag.flag .card h3 { font-size: 28px; }
html.cards #s09 .card::after { border-image-width: 22px; }

:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; border-radius: 2px; }

/* ---------- reduced motion: windows fade in place over still frames; nothing tracks or scrubs ---------- */
@media (prefers-reduced-motion: reduce) {
  .spacer { height: calc((var(--span) * .6 + 2) * var(--vh)); }
  .scene.last .spacer { height: calc(var(--span) * .6 * var(--vh)); }
  .panel, .panel.pop, .panel.hold, .panel.start, .panel.pin {
    animation: none;
    transform: var(--T1);
    opacity: 0; visibility: hidden;
    transition: opacity .6s ease, visibility 0s linear .6s;
  }
  .panel.in { opacity: 1; visibility: visible; transition: opacity .6s ease, visibility 0s; }
  .win:hover { transform: none; }
  .field::after { animation: none; }
  .tag .card, .tag .card > *, .tag .card::after, .tk::before, .tk::after, .reticle::before { animation: none !important; }
}
