/* Virtual Places. BUILD 1. Mobile-first, dark, about the world. */

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  background: var(--ink);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input { font: inherit; }
a { color: var(--limb); text-decoration: none; }
button:focus-visible, a:focus-visible, input:focus-visible {
  outline: 2px solid var(--limb);
  outline-offset: 3px;
}
/* The hidden attribute always wins, whatever display a class sets.
   (The Morning Window once rendered as an empty ghost box without
   this; Kent tried to type in it from a hotel in Mexico.) */
[hidden] { display: none !important; }

#app { position: fixed; inset: 0; }

/* ---------- The Earth stage (persists under everything) ---------- */
#globe {
  position: absolute; inset: 0;
  background: var(--ink);
}
/* Poster earth: shown until MapLibre streams in. A dark disk with a
   lit limb, drawn in CSS. The only gradient allowed is this one. */
#globePoster {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  transition: opacity 900ms ease;
}
#globePoster.gone { opacity: 0; pointer-events: none; }
#globePoster .disk {
  width: min(78vw, 420px);
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgba(var(--limb-rgb),0.16), transparent 55%),
    radial-gradient(circle at 50% 50%, #0c1526 0%, #080e1a 60%, #05090f 100%);
  box-shadow:
    inset -18px -14px 60px rgba(0,0,0,0.75),
    inset 10px 8px 40px rgba(var(--limb-rgb),0.10),
    var(--limb-glow);
}
/* A real sky: canvas starfield drawn once (static, reduced-safe) */
#stars { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* The atmosphere halo: the planet wears its own light, breathing */
#halo {
  position: absolute; inset: 0; pointer-events: none;
  /* B51, Kent's field order: a faint glow around the planet, blue
     into green. Two breaths of atmosphere: the limb's blue close in,
     a fainter aurora green further out. World, never chrome. */
  background:
    radial-gradient(ellipse 46% 34% at 50% 40%,
      rgba(var(--limb-rgb), 0.22), rgba(var(--limb-rgb), 0.07) 55%, transparent 72%),
    radial-gradient(ellipse 62% 46% at 50% 42%,
      rgba(var(--aurora-rgb), 0.10), rgba(var(--aurora-rgb), 0.03) 58%, transparent 80%);
  mix-blend-mode: screen;
  animation: halo-breathe 9s ease-in-out infinite;
}
@keyframes halo-breathe { 50% { opacity: 0.82; } }

/* Film grain over the world only: texture on imagery, never chrome */
#grain {
  position: absolute; inset: -20px;
  pointer-events: none;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="220" height="220"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="2" stitchTiles="stitch"/></filter><rect width="220" height="220" filter="url(%23n)" opacity="0.55"/></svg>');
  opacity: 0.05;
  mix-blend-mode: overlay;
}

/* The dive speaks: place names fading through the falling sky */
#diveCaption {
  position: absolute;
  left: 50%; top: 34%;
  transform: translateX(-50%);
  max-width: 86vw;
  pointer-events: none;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(30px, 8vw, 46px);
  color: var(--text);
  text-align: center;
  text-shadow: 0 2px 24px rgba(var(--ink-rgb), 0.9);
  opacity: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#diveCaption.show { animation: caption-through 1050ms ease-in-out; }
@keyframes caption-through {
  0%   { opacity: 0; transform: translateX(-50%) translateY(14px) scale(0.985); }
  30%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translateX(-50%) translateY(-16px) scale(1.02); }
}

/* The limb arc: thin curved horizon structuring every overlay screen */
.limb-arc {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: 160vw; height: 160vw; border-radius: 50%;
  pointer-events: none;
  border-top: 1px solid rgba(var(--limb-rgb), 0.35);
  box-shadow: 0 -18px 60px -12px rgba(var(--limb-rgb), 0.28);
}
.limb-arc.amber {
  border-top-color: rgba(var(--sodium-rgb), 0.4);
  box-shadow: 0 -18px 60px -12px rgba(var(--sodium-rgb), 0.3);
}

/* Atmosphere bloom during the dive */
#atmosphere {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse at 50% 120%, rgba(var(--limb-rgb),0.22), transparent 55%);
  transition: opacity 600ms ease;
}
#atmosphere.bloom { opacity: 1; }

/* ---------- Screens ---------- */
.screen {
  position: absolute; inset: 0;
  display: none;
  flex-direction: column;
}
.screen.on { display: flex; }

/* Rooms rise to meet you: three tiers, one breath. The home veil's
   first three children (arc, wordmark, tagline) keep their own
   arrival choreography and are left alone here. */
#wonders.entering > *, #atlas.entering > *,
#home.entering .veil-scroll > :nth-child(n+3) {
  animation: tier-rise 300ms var(--ease-settle) backwards;
}
#wonders.entering > :nth-child(2), #atlas.entering > :nth-child(2),
#home.entering .veil-scroll > :nth-child(n+5) { animation-delay: 60ms; }
#wonders.entering > :nth-child(n+3), #atlas.entering > :nth-child(n+3),
#home.entering .veil-scroll > :nth-child(n+6) { animation-delay: 120ms; }
@keyframes tier-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- HOME ---------- */
/* The Earth is the point of this room: the veil may NEVER swallow it
   (Kent: we don't see the Earth anymore). The veil caps at ~68vh and
   scrolls inside itself; the top of home stays naked turning planet.
   Bottom anchor is margin-top:auto, NOT justify-end: end-justified
   overflow is unscrollable at the start edge in every engine. */
#home { pointer-events: none; overflow: hidden; display: flex; flex-direction: column; }
#home > * { pointer-events: auto; }
#home .home-veil {
  margin-top: auto;
  /* B51, Kent's field order: bring the words DOWN, show more of the
     turning planet. 68vh gave the Earth 37% of a phone; 55vh gives
     it ~45%. The scroll inside carries whatever no longer fits. */
  max-height: min(55vh, 520px);
  display: flex;
  flex-direction: column;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
/* the SCROLL lives one level in, so the limb arc crowning the veil
   never gets clipped by its own scrollbox */
.veil-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.veil-scroll::-webkit-scrollbar { display: none; }

/* How the Earth is lit: the user's call, kept.
   B54, Kent's field find: #home stays displayed under every room
   (the Earth-window law), so the z-raised pill bled through onto
   My places and could even steal taps there. The pill exists only
   while the Earth room is the front room. */
#home:not(.on) .home-mode { display: none; }
.home-mode {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 14px);
  right: 14px;
  /* above the veil, always: paint order buried it untappable */
  z-index: 5;
  display: flex; gap: 2px;
  /* B51: Kent could not find the pill in the field; it must read
     against bright daylight Earth as clearly as against stars */
  background: rgba(var(--surface-rgb), 0.88);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 4px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.home-mode button {
  min-height: 36px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12px; font-weight: 600;
  color: var(--text-dim);
  transition: color 200ms ease, background 200ms ease;
}
.home-mode button.on { background: var(--surface-2); color: var(--text); }

.home-veil {
  position: relative;
  padding: var(--pad);
  padding-top: 32px;
  padding-bottom: max(var(--pad), env(safe-area-inset-bottom));
  /* thinner glass: the turning Earth stays present behind the words */
  background: rgba(var(--ink-rgb), 0.66);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
}
.home-veil .limb-arc { top: -22px; }

.wordmark {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(38px, 11vw, 54px);
  line-height: 0.94;
  letter-spacing: -0.025em;
  font-variation-settings: "opsz" 144;
  animation: word-rise 700ms var(--ease-settle) 150ms backwards;
}
.tagline {
  color: var(--text-soft);
  font-size: 16px;
  line-height: 1.4;
  margin: 8px 0 24px;
  animation: word-rise 700ms var(--ease-settle) 280ms backwards;
}
@keyframes word-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
/* The arc draws itself once at first light */
.home-veil .limb-arc { animation: arc-draw 1100ms ease-out 100ms backwards; }
@keyframes arc-draw {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* The Morning Window: a real window now, the place as the backdrop */
.window-card {
  position: relative;
  width: 100%;
  min-height: 128px;
  display: flex; align-items: flex-end; gap: 14px;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 14px 16px;
  margin-bottom: 12px;
  text-align: left;
  box-shadow: var(--lift-2);
  transition: transform 150ms var(--ease-settle), border-color 200ms ease;
}
.window-card:active { transform: scale(0.98); }
.home-hint {
  color: var(--text-dim);
  font-size: 13px;
  margin: -12px 0 14px;
}

/* Dawn is happening somewhere: a live invitation, no API behind it */
.dawn-line {
  margin-top: 12px;
  width: 100%;
  text-align: left;
  font-family: var(--serif);
  font-style: italic;
  font-size: 15px;
  line-height: 1.4;
  color: var(--sodium);
  opacity: 0.9;
  transition: opacity 200ms ease;
}
.dawn-line:active { opacity: 1; }
.window-card .wc-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* the scrim rides the imagery (lawful) and carries the shelf's light */
.window-card .wc-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(var(--ink-rgb), 0.92) 0%, rgba(var(--ink-rgb), 0.35) 55%, rgba(var(--ink-rgb), 0.15) 100%);
  border-left: 2px solid var(--t, var(--sodium));
}
.window-card .wc-body { position: relative; flex: 1; min-width: 0; display: block; }
.window-card .wc-name {
  display: block;
  font-family: var(--serif); font-weight: 600; font-size: 22px; line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-shadow: 0 1px 12px rgba(var(--ink-rgb), 0.8);
}
.window-card .wc-line {
  display: block; color: var(--text-soft); font-size: 13px; margin-top: 4px;
  text-shadow: 0 1px 8px rgba(var(--ink-rgb), 0.8);
}
.window-card .wc-go {
  position: relative; flex: none;
  font-size: 13px; font-weight: 600;
  color: var(--sodium);
  text-shadow: 0 1px 8px rgba(var(--ink-rgb), 0.9);
}

/* Voice pinned to a place */
.voice-row { margin: 0 0 10px; }
.voice-cta, .voice-live, .voice-has { display: flex; align-items: center; gap: 10px; }
.voice-cta button, .voice-has button, .voice-live button {
  min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: 13px; font-weight: 600;
  padding: 8px 14px;
  display: flex; align-items: center; gap: 8px;
  transition: border-color 200ms ease, color 200ms ease;
}
.voice-cta button { flex: 1; justify-content: center; color: var(--text-dim); }
.voice-cta button:hover, .voice-cta button:active { color: var(--text); border-color: var(--sodium); }
.voice-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--sodium); flex: none;
}
.voice-live .voice-dot { animation: voice-pulse 1200ms ease-in-out infinite; }
@keyframes voice-pulse { 50% { opacity: 0.3; transform: scale(0.8); } }
.voice-live .vtime { font-family: var(--mono); font-size: 13px; color: var(--sodium); flex: 1; }
.voice-live button { border-color: var(--sodium); color: var(--text); }
.voice-has .vlen { font-family: var(--mono); font-size: 12px; color: var(--text-dim); flex: 1; }
.voice-has button.playing { border-color: var(--sodium); color: var(--sodium); }

/* Atlas tools */
.film-btn {
  min-height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: 13px; font-weight: 600;
  padding: 6px 14px;
  color: var(--text-dim);
  transition: color 200ms ease, border-color 200ms ease;
}
.film-btn:hover, .film-btn:active { color: var(--text); border-color: var(--sodium); }
/* Atlas custody: the calm ask that keeps a kept life safe (B55) */
#custody {
  margin: 0 0 16px;
  padding: 16px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  box-shadow: var(--lift-1);
}
.cust-name {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 18px;
  margin-bottom: 6px;
}
.cust-line {
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.5;
  margin-bottom: 8px;
}
.cust-row { display: flex; gap: 10px; margin-top: 10px; }
.cust-row button {
  min-height: 40px;
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 13px; font-weight: 600;
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--line);
}
.cust-row .cust-how { background: var(--sodium); color: var(--on-sodium); border-color: transparent; }
/* POST-REVIEW: the review's press-physics gap: these buttons give too */
.cust-row button, #ddShare, #ddStand {
  transition: transform 150ms var(--ease-settle), border-color 200ms ease;
}
.cust-row button:active, #ddShare:active, #ddStand:active { transform: scale(0.96); }

.atlas-tools {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  padding: 26px var(--pad) 0;
  max-width: 720px; margin: 0 auto;
}
.atlas-tools button {
  min-height: 44px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  color: var(--text-faint);
  font-size: 13px;
  transition: color 200ms ease, border-color 200ms ease;
}
.atlas-tools button:hover, .atlas-tools button:active { color: var(--text-dim); border-color: var(--silver); }

/* The local air: live radio pinned to the ground you stand on */
.radio-row { margin-top: 10px; }
.radio-btn {
  width: 100%;
  min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text-dim);
  font-size: 13px; font-weight: 600;
  padding: 8px 14px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  transition: border-color 200ms ease, color 200ms ease;
}
.radio-btn:hover, .radio-btn:active { color: var(--text); border-color: var(--limb); }
.radio-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--limb); flex: none;
}
.radio-dot.tuning, .radio-dot.live { animation: voice-pulse 1200ms ease-in-out infinite; }
.radio-on {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px;
  border: 1px solid rgba(var(--limb-rgb), 0.4);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  padding: 8px 8px 8px 14px;
}
.radio-on .radio-name {
  flex: 1; min-width: 0;
  font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.radio-on #radioOff {
  flex: none;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  color: var(--text-dim);
  font-size: 13px; font-weight: 600;
}
.radio-on #radioOff:hover, .radio-on #radioOff:active { color: var(--text); }
.radio-quiet {
  display: block; text-align: center;
  color: var(--text-faint); font-size: 13px;
  padding: 12px 0;
}

/* Then: the archive chips, NYC first */
.then-row {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 10px; margin-top: 12px;
}
.then-chip {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--silver);
  font-size: 13px; font-weight: 600;
  padding: 8px;
  transition: color 200ms ease, border-color 200ms ease;
}
.then-chip:hover, .then-chip:active { color: var(--text); border-color: var(--silver); }

.searchbar {
  display: flex; gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 6px 6px 6px 16px;
  align-items: center;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
.searchbar:focus-within { border-color: rgba(var(--limb-rgb),0.5); box-shadow: var(--limb-glow); }
.searchbar input {
  flex: 1; min-width: 0;
  background: none; border: 0; outline: 0;
  color: var(--text);
  font-size: 16px;
  padding: 10px 0;
}
.searchbar input::placeholder { color: var(--text-faint); }
.searchbar .mic {
  flex: none;
  width: 42px; min-height: 42px;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  font-size: 12px;
  transition: color 200ms ease;
}
.searchbar .mic.listening { color: var(--sodium); animation: voice-pulse 1200ms ease-in-out infinite; }
.searchbar .go {
  background: var(--limb);
  color: var(--on-limb);
  font-weight: 600;
  border-radius: var(--r-sm);
  padding: 10px 18px;
  transition: transform 150ms var(--ease-settle), filter 150ms ease;
}
.searchbar .go:active { transform: scale(0.96); filter: brightness(1.15); }

.chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 14px;
}
.chip {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 10px;
  min-height: 48px;
  padding: 12px 14px;
  font-size: 15px;
  color: var(--text-dim);
  text-align: left;
  transition: color 200ms ease, border-color 200ms ease;
}
.chip:hover, .chip:active { color: var(--text); border-color: var(--line-strong); }

/* The teleport strip: your places, one tap from the door */
.teleport {
  display: flex; gap: 14px;
  margin-top: 16px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 2px;
  cursor: grab;
}
.teleport:active { cursor: grabbing; }
/* the fade only while there IS more: at the strip's end it was
   dissolving the last thumb into nothing (deep-dive catch) */
.teleport.more-right, .seven-strip.more-right {
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 40px), transparent);
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 40px), transparent);
}
.teleport::-webkit-scrollbar { display: none; }
.tp {
  flex: none; width: 64px;
  display: grid; justify-items: center; gap: 6px;
}
.tp img {
  width: 56px; height: 56px;
  border-radius: 50%; object-fit: cover;
  box-shadow: 0 0 0 2px var(--t, var(--line-strong));
  filter: saturate(0.9);
  transition: transform 150ms var(--ease-settle);
}
.tp:active img { transform: scale(0.92); }
.tp span {
  font-size: 11px; font-weight: 600; /* the caption role, one voice */
  letter-spacing: 0.02em;
  color: var(--text-dim);
  max-width: 64px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.buildtag {
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-faint);
  display: flex; justify-content: flex-end;
  opacity: 0.6;
}

/* ---------- PLACE ---------- */
#place { pointer-events: none; }
#place > * { pointer-events: auto; }
/* The layout spacer must never eat a tap meant for the world beneath:
   it sat exactly where a Daily Drop guess lands (Kent's dead globe) */
#place > .spacer { pointer-events: none; }

.place-top {
  display: flex; align-items: center; gap: 12px;
  padding: max(14px, env(safe-area-inset-top)) var(--pad) 10px;
  position: relative; z-index: 45; /* always above the panorama */
}

/* The lens pill: four ways of seeing the same world */
.lens-pill {
  display: flex; gap: 2px;
  background: rgba(var(--surface-rgb), 0.72);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.lens-pill button {
  min-height: 36px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12px; font-weight: 600;
  color: var(--text-dim);
  transition: color 200ms ease, background 200ms ease;
}
.lens-pill button.on { background: var(--surface-2); color: var(--text); }
.back {
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(var(--surface-rgb), 0.8);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  font-size: 18px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* The pin: one tap keeps the ground you are standing on */
.pin-btn {
  margin-left: auto;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(var(--surface-rgb), 0.8);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  color: var(--text-dim);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: color 200ms ease, border-color 200ms ease;
  z-index: 45;
}
.pin-btn svg {
  width: 20px; height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pin-btn.pinned { color: var(--sodium); border-color: rgba(var(--sodium-rgb), 0.5); }
.pin-btn.pinned svg { fill: rgba(var(--sodium-rgb), 0.25); }
.pin-btn:active { transform: scale(0.94); }

/* Street panel: fills the stage when street rung is active.
   Keyless it is GLASS: the live satellite stays visible underneath,
   one sodium streetlight marks the rooftop, a slim band hands off. */
#streetPanel {
  position: absolute; inset: 0;
  display: none;
  background: var(--ink);
  z-index: 5; /* under the controls, always */
}
#streetPanel.on { display: block; }
#streetPanel.fallback { background: transparent; pointer-events: none; }
#streetPanel iframe { width: 100%; height: 100%; border: 0; }

.street-dot {
  position: absolute; left: 50%; top: 50%;
  width: 10px; height: 10px; margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--sodium);
  box-shadow: var(--sodium-glow);
  animation: dot-in 600ms var(--ease-settle) backwards;
}
@keyframes dot-in {
  from { transform: scale(0); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.street-band {
  pointer-events: auto;
  position: absolute;
  left: 20px; right: 84px;
  top: calc(env(safe-area-inset-top) + 70px);
  max-width: 420px;
  display: flex; align-items: center; gap: 12px;
  background: rgba(var(--surface-rgb), 0.88);
  border: 1px solid var(--line-strong);
  border-top: 1px solid rgba(var(--sodium-rgb), 0.45);
  border-radius: var(--r-md);
  padding: 12px 14px;
}
.street-band .sb-body { flex: 1; min-width: 0; }
.street-band h3 {
  font-family: var(--serif); font-weight: 600; font-size: 20px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.street-band p { color: var(--text-dim); font-size: 13px; margin-top: 1px; }
.street-band .open-street {
  flex: none;
  background: var(--sodium);
  color: var(--on-sodium);
  font-weight: 600; font-size: 13px;
  border-radius: var(--r-sm);
  min-height: 44px;
  padding: 10px 14px;
  transition: transform 150ms var(--ease-settle);
}
.street-band .open-street:active { transform: scale(0.96); }

/* Orbit panel: today's Earth, centered in the air ABOVE the sheet
   so the photograph and its caption are never covered */
#orbitPanel {
  position: absolute; inset: 0;
  display: none;
  background: var(--ink);
  place-items: center;
  padding: calc(env(safe-area-inset-top) + 60px) 0 176px;
  z-index: 5;
}
#orbitPanel.on { display: grid; }
#orbitPanel .orbit-wrap {
  position: relative; display: block;
  width: min(86vw, 40vh, 480px);
  /* the story lines widened the figure and the Earth drifted off
     center (Kent's sideways planet); the disk owns the middle */
  margin: 0 auto;
}

/* Tonight breathes: the room arrives in tiers, the halo swells like
   slow breathing, every day-swap re-enters. All of it stands down
   under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  #orbitPanel .orbit-wrap::after {
    content: ""; position: absolute; inset: -5%;
    border-radius: 50%;
    box-shadow: 0 0 90px 10px rgba(var(--limb-rgb), 0.32);
    /* its OWN keyframes: reusing halo-breathe silently retuned the
       home halo (last definition wins document-wide; deep-dive) */
    animation: orbit-halo-breathe 7s ease-in-out infinite;
    pointer-events: none;
  }
  #orbitPanel figure > * { animation: tier-rise 400ms var(--ease-settle) backwards; }
  #orbitPanel .orbit-wrap { animation: disk-arrive 700ms var(--ease-settle) backwards; }
  #orbitPanel figcaption { animation-delay: 90ms; }
  #orbitPanel .night-head { animation-delay: 160ms; }
  #orbitPanel .sky-lines { animation-delay: 230ms; }
  #orbitPanel .time-strip { animation-delay: 300ms; }
}
@keyframes orbit-halo-breathe { 50% { opacity: 0.4; } }
@keyframes disk-arrive {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1); }
}
#orbitPanel img {
  width: 100%;
  border-radius: 50%;
  box-shadow: var(--limb-glow);
  display: block;
}
/* The bright star: where the place is, on today's actual Earth */
.orbit-star {
  position: absolute;
  width: 10px; height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--sodium);
  box-shadow: 0 0 10px 2px rgba(var(--sodium-rgb), 0.9), 0 0 26px 8px rgba(var(--sodium-rgb), 0.35);
  animation: star-breathe 2600ms ease-in-out infinite;
}
@keyframes star-breathe {
  50% { box-shadow: 0 0 14px 3px rgba(var(--sodium-rgb), 1), 0 0 34px 12px rgba(var(--sodium-rgb), 0.45); }
}

/* The stride: walk the street with two big honest buttons */
.stride {
  position: absolute;
  left: 14px; top: 50%;
  transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 10px;
  z-index: 40;
}
.stride .step {
  width: 54px; height: 54px;
  border-radius: 50%;
  background: rgba(var(--surface-rgb), 0.85);
  border: 1px solid var(--line-strong);
  color: var(--sodium);
  font-size: 16px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 150ms var(--ease-settle), border-color 200ms ease;
  /* holding is a gesture now: no double-tap zoom, no long-press
     menu, and NO panning from the buttons at all: a held finger's
     tiny drift was turning the walk into a page-pan and cutting
     the chain (B53, Kent on Fuji) */
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
/* until the first real held walk, the arrow teaches itself: three
   soft breaths on every fresh street, then never again */
.stride.teach .fwd { animation: walk-teach 2.4s ease-in-out 3; }
@keyframes walk-teach {
  50% { box-shadow: 0 0 14px 3px rgba(var(--sodium-rgb), 0.55); transform: scale(1.06); }
}
.stride .step:active { transform: scale(0.92); border-color: var(--sodium); }
/* A lone photosphere has no exits: the walk buttons step aside */
.stride.no-walk .fwd, .stride.no-walk .bck { display: none; }
/* B48, the walk feel: the arrow leans the way the road bends, dims
   past a walkable turn, and pulses while the hands-free walk is on */
.stride .fwd .glyph { display: inline-block; transition: transform 240ms var(--ease-settle); }
.stride.off-axis .fwd { opacity: 0.55; }
.stride.walking .fwd { border-color: var(--sodium); animation: walk-pulse 1700ms ease-in-out infinite; }
@keyframes walk-pulse { 50% { box-shadow: 0 0 12px 2px rgba(var(--sodium-rgb), 0.5); } }
/* Every stride is felt: one breath of forward motion per step */
#streetPanel.stepping { animation: step-in 280ms var(--ease-settle); }
@keyframes step-in {
  0% { transform: scale(1); }
  35% { transform: scale(1.035); }
  100% { transform: scale(1); }
}
/* In the theater, the door out wears a plain X and stronger ink */
.stride .step.exit {
  color: var(--text);
  border-color: var(--line-strong);
  background: rgba(var(--surface-rgb), 0.94);
  font-size: 20px;
}
#orbitPanel figcaption {
  margin-top: 14px; text-align: center;
  font-family: var(--mono); font-size: 12px; color: var(--text-dim);
}

/* Turning back the days: the Earth of other days, photographs only */
/* Tonight's voice: the place of the night, named */
.night-head {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 600;
  font-size: 18px;
  line-height: 1.4;
  color: var(--text);
  text-align: center;
  max-width: 360px;
  margin: 14px auto 0;
  cursor: pointer;
  text-decoration: underline dotted rgba(var(--sodium-rgb), 0.5);
  text-underline-offset: 4px;
}
.sky-lines {
  margin-top: 8px;
  text-align: center;
}
.sky-lines p {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
  /* the ISS line was printing edge to edge into the notch zone */
  max-width: 340px;
  margin-left: auto;
  margin-right: auto;
}

.time-strip {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 8px;
  margin: 14px auto 0;
  max-width: 300px; /* two by two, never three and one */
}
.time-strip button {
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--text-dim);
  font-size: 13px; font-weight: 600;
  transition: color 200ms ease, border-color 200ms ease, background 200ms ease,
    transform 150ms var(--ease-settle);
}
.time-strip button:active { transform: scale(0.95); }
.time-strip button:active { color: var(--text); }
.time-strip button.on {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--line-strong);
}

/* Altitude rail: 4 rungs + the readout, right edge, clear of the
   plate on every phone height (top-anchored, not centered) */
.rail {
  position: absolute; right: 10px;
  z-index: 45;
  top: calc(env(safe-area-inset-top) + 76px);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: rgba(var(--surface-rgb), 0.72);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.rung {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 10px;
  color: var(--text-dim);
  transition: background 200ms ease, color 200ms ease, transform 150ms var(--ease-settle);
}
.rung:active { transform: scale(0.94); }
.rung.on { background: var(--limb); color: var(--on-limb); }

/* Altimeter readout: counts the descent, lands on 0 M at the thump.
   Lives at the rail's foot so it can never collide with the plate. */
.altimeter {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-dim);
  writing-mode: vertical-rl;
  letter-spacing: 0.08em;
  opacity: 0.85;
  padding: 6px 0 10px;
  min-height: 58px;
  transition: color 300ms ease;
}
.altimeter.live { color: var(--limb); }
/* Touchdown: the number lands with one bright flick */
.altimeter.flick { animation: alt-flick 320ms ease-out; }
@keyframes alt-flick {
  0% { color: var(--sodium); filter: brightness(1.9); }
  100% { filter: none; }
}

/* The dive holds the instruments back; touchdown releases them.
   The rail keeps its own transition (it carries the altimeter). */
.place-top, .plate {
  transition: opacity 500ms var(--ease-settle), transform 500ms var(--ease-settle);
}
.rail { transition: opacity 500ms var(--ease-settle), background 200ms ease; }
#place.diving .place-top,
#place.diving .plate {
  opacity: 0;
  transform: translateY(18px);
  pointer-events: none;
}
#place.diving .rail { opacity: 0; pointer-events: none; }
#place.diving .altimeter { opacity: 1; }
/* During the dive only the falling number shows, riding the rail spot */
#place.diving .rail.counting { opacity: 1; background: transparent; border-color: transparent; }
#place.diving .rail.counting .rung { opacity: 0; }

/* The plate: one caption card pinned beneath every altitude */
.plate {
  position: relative;
  z-index: 30;
  margin: 0 var(--pad);
  /* the navbar lives below at all times now */
  margin-bottom: calc(max(var(--pad), env(safe-area-inset-bottom)) + 66px);
  background: rgba(var(--surface-rgb), 0.92);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: 18px;
  overflow: hidden;
  animation: plate-in 400ms var(--ease-settle);
}
@keyframes plate-in {
  from { transform: translateY(14px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.plate .limb-arc {
  top: -158vw; opacity: 0.5;
  border-top-color: var(--arc-c, rgba(var(--limb-rgb), 0.35));
  box-shadow: 0 -18px 60px -12px var(--arc-g, rgba(var(--limb-rgb), 0.28));
}
.plate h2 {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(25px, 7vw, 32px); line-height: 1.15;
}
.plate .coords {
  font-family: var(--mono); font-size: 12px;
  color: var(--text-dim);
  margin: 5px 0 10px;
  letter-spacing: 0.03em;
  min-height: 1.2em;
}
.plate .coords .cur { animation: cur-blink 900ms steps(1) infinite; }
@keyframes cur-blink { 50% { opacity: 0; } }
/* When the photograph was really made: the honesty line */
.plate .seen {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-faint);
  letter-spacing: 0.05em;
  margin: -6px 0 8px;
}
/* How far this street is from the first one */
.plate .fromhome {
  font-family: var(--mono); font-size: 10px;
  color: var(--silver);
  letter-spacing: 0.08em;
  margin: -6px 0 8px;
}
/* The memory line: what you wrote, standing there */
.plate .memory {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: 20px; line-height: 1.35;
  margin: 0 0 8px;
}
.plate .intel {
  color: var(--text-dim); font-size: 13px;
  min-height: 1.4em;
}
.plate .intel + .intel { margin-top: 2px; }
.plate .actions {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 10px; margin-top: 14px;
}
.plate .actions button {
  border-radius: var(--r-md);
  padding: 13px 10px;
  font-weight: 600; font-size: 15px;
  transition: transform 150ms var(--ease-settle);
}
.plate .actions button:active { transform: scale(0.97); }
.keep { background: var(--sodium); color: var(--on-sodium); }
.share { background: var(--surface-2); border: 1px solid var(--line-strong); color: var(--text); }
/* the quiet third door: the view as a wallpaper */
.poster-link {
  width: 100%; margin-top: 12px;
  min-height: 44px;
  color: var(--text-faint);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.poster-link:hover, .poster-link:active { color: var(--silver); }
#place.earth-mode .poster-link, #place.drop-mode .poster-link { display: none; }

/* ---------- ATLAS ---------- */
#atlas {
  background: var(--ink);
  overflow-y: auto;
  padding: max(14px, env(safe-area-inset-top)) 0 40px;
}
.atlas-head {
  display: flex; align-items: center; gap: 12px;
  padding: 0 var(--pad) 6px;
}
.atlas-head h1 { font-family: var(--serif); font-weight: 600; font-size: 26px; flex: 1; }
.atlas-count { font-family: var(--mono); font-size: 12px; color: var(--text-dim); }

/* Two readings of one atlas */
.atlas-pill {
  display: flex; gap: 2px;
  margin: 8px var(--pad) 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px;
  width: fit-content;
}
.atlas-pill button {
  min-height: 38px;
  padding: 7px 16px;
  border-radius: 999px;
  font-size: 13px; font-weight: 600;
  color: var(--text-dim);
  transition: color 200ms ease, background 200ms ease;
}
.atlas-pill button.on { background: var(--surface-2); color: var(--text); }

/* The timeline: a life in decades, hung on one thin light */
.tl {
  margin: 18px var(--pad) 0;
  padding-left: 18px;
  border-left: 1px solid rgba(var(--limb-rgb), 0.28);
  max-width: 560px;
}
.tl-decade {
  font-family: var(--mono); font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--silver);
  margin: 22px 0 10px;
  position: relative;
}
.tl-decade:first-child { margin-top: 4px; }
.tl-decade::before {
  content: ""; position: absolute;
  left: -22.5px; top: 5px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--limb);
  box-shadow: 0 0 10px rgba(var(--limb-rgb), 0.6);
}
.tl-row {
  position: relative;
  width: 100%;
  display: flex; align-items: center; gap: 12px;
  padding: 8px 10px 8px 0;
  border-radius: var(--r-md);
  text-align: left;
  transition: transform 150ms var(--ease-settle);
  animation: plate-in 240ms var(--ease-settle) backwards;
  animation-delay: calc(var(--i, 0) * 30ms);
}
.tl-row:active { transform: scale(0.98); }
.tl-row .tl-dot {
  position: absolute; left: -22.5px; top: 50%;
  width: 8px; height: 8px; margin-top: -4px;
  border-radius: 50%;
  background: var(--t, var(--line-strong));
}
.tl-row img {
  width: 46px; height: 46px; flex: none;
  border-radius: 10px; object-fit: cover;
  box-shadow: 0 0 0 1.5px var(--t, var(--line-strong));
  filter: saturate(0.9);
}
.tl-row .tl-body { flex: 1; min-width: 0; }
.tl-row .tl-name {
  display: block;
  font-family: var(--serif); font-weight: 600; font-size: 16px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tl-row .tl-note {
  display: block;
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: 13px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tl-row .tl-year {
  flex: none;
  font-family: var(--mono); font-size: 12px;
  color: var(--text-dim);
}
.tl-empty, .tl-hint {
  margin: 26px var(--pad) 0;
  color: var(--text-faint);
  font-size: 13px;
  max-width: 400px;
}
.tl .tl-hint { margin: 4px 0 14px; }

.shelf { padding: 14px var(--pad) 0; }
.shelf h3 {
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-dim);
  display: flex; align-items: center; gap: 8px;
}
.shelf h3 .dot { width: 8px; height: 8px; border-radius: 50%; }
.shelf-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 12px; margin-top: 10px;
}

/* A saved place is a plate */
.place-card {
  position: relative; overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-align: left;
  transition: transform 150ms var(--ease-settle), border-color 200ms ease;
}
.place-card:active { transform: scale(0.97); }
.place-card img {
  width: 100%; aspect-ratio: 8 / 5;
  object-fit: cover; display: block;
  filter: saturate(0.9);
}
.place-card .pc-body { padding: 10px 12px 12px; }
.place-card .pc-name {
  font-family: var(--serif); font-weight: 600; font-size: 15px;
  line-height: 1.3;
}
.place-card .pc-meta {
  font-family: var(--mono); font-size: 10px;
  color: var(--text-dim); margin-top: 3px;
}
.place-card .pc-note {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: 13px;
  color: var(--text-dim); margin-top: 5px;
}
/* Shelf entrance: plates arrive in reading order */
.place-card {
  animation: plate-in 240ms var(--ease-settle) backwards;
  animation-delay: calc(var(--i, 0) * 30ms);
}
.place-card .pc-temp {
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
}
/* Collection temperatures */
.t-grewup .pc-temp { background: var(--temp-grewup); }
.t-been   .pc-temp { background: var(--temp-been); }
.t-dream  .pc-temp { background: var(--temp-dream); }
.t-gone   .pc-temp { background: var(--temp-gone); }
/* shelf plates print in their own temperature */
.place-card.t-grewup img { filter: grayscale(1) sepia(1) saturate(1.35) brightness(0.8) contrast(1.15); }
.place-card.t-dream img { filter: grayscale(1) sepia(1) hue-rotate(212deg) saturate(1.05) brightness(0.76) contrast(1.15); }
.place-card.t-gone img { filter: grayscale(1) contrast(1.1) brightness(0.8); }

/* Empty collection: dashed orbit ring circling one empty slot */
.empty-slot {
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  aspect-ratio: 8 / 7;
  display: grid; place-items: center;
  color: var(--text-faint);
  font-size: 13px;
  text-align: center;
  padding: 12px;
  position: relative;
}
.empty-slot::before {
  content: ""; position: absolute;
  width: 54px; height: 54px;
  border: 1px dashed var(--line-strong);
  border-radius: 50%;
  animation: orbit-spin 14s linear infinite;
  top: 18px;
}
@keyframes orbit-spin { to { transform: rotate(360deg); } }
.empty-slot span { margin-top: 66px; }

/* ---------- Save dialog ---------- */
#saveDialog {
  border: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface);
  color: var(--text);
  width: 100%; max-width: 560px;
  margin: auto auto 0;
  padding: 22px var(--pad) max(22px, env(safe-area-inset-bottom));
}
#saveDialog::backdrop { background: rgba(var(--scrim-rgb), 0.6); backdrop-filter: blur(4px); }
#saveDialog h3 { font-family: var(--serif); font-weight: 600; font-size: 22px; }
#saveDialog .sd-place { color: var(--text-dim); font-size: 15px; margin: 2px 0 16px; }
.coll-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.coll-btn {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 14px 12px;
  text-align: left;
  font-size: 15px; font-weight: 600;
  display: flex; align-items: center; gap: 10px;
  transition: border-color 150ms ease, background 150ms ease;
}
.coll-btn .dot { width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--t); }
.coll-btn.sel { background: var(--surface-2); border-color: var(--t); }
#saveDialog .fields { display: grid; grid-template-columns: 100px 1fr; gap: 10px; margin-top: 12px; }
#saveDialog input {
  background: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--text);
  padding: 11px 12px;
  outline: 0;
}
#saveDialog input:focus { border-color: rgba(var(--limb-rgb),0.5); }
#saveDialog .sd-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
#saveDialog .sd-actions button { border-radius: var(--r-md); padding: 13px; font-weight: 600; }
.sd-cancel { background: var(--surface-2); border: 1px solid var(--line-strong); }
.sd-keep { background: var(--sodium); color: var(--on-sodium); }
.sd-drop {
  width: 100%; margin-top: 14px;
  min-height: 44px;
  color: var(--text-faint);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.sd-drop:hover, .sd-drop:active { color: var(--silver); }
/* Save confirmation: the plate stamps down */
@keyframes stamp {
  0% { transform: scale(1.06); opacity: 0; }
  60% { transform: scale(0.99); opacity: 1; }
  100% { transform: scale(1); }
}
.stamped { animation: stamp 350ms var(--ease-settle); }

/* The whole Earth has no altitude ladder: Tonight is one view */
#place.earth-mode .rail { display: none; }
/* the orbit photograph covers the map: the lens pill steps off */
#place.orbit-view .lens-pill, #place.earth-mode .lens-pill { display: none; }

/* The plate assembles rather than appearing (its arc keeps its own
   transform and stays out of the cascade) */
.plate.assemble > :not(.limb-arc) { animation: plate-in 260ms var(--ease-settle) backwards; }
.plate.assemble > :nth-child(3) { animation-delay: 40ms; }
.plate.assemble > :nth-child(4) { animation-delay: 80ms; }
.plate.assemble > :nth-child(5) { animation-delay: 120ms; }
.plate.assemble > :nth-child(n+6) { animation-delay: 160ms; }

/* Instrument numerals: aligned like instruments everywhere */
.plate .coords, .altimeter, .dd-num span, .fromhome, .tl-year,
.atlas-count, .buildtag, #orbitPanel figcaption {
  font-variant-numeric: tabular-nums;
}

/* The street warms up unseen while the dive falls. Opacity, not
   visibility: a hidden container starves Google's renderer and its
   internals throw; an invisible one lets it warm honestly. */
#place.diving #streetPanel { opacity: 0; pointer-events: none; }
#streetPanel { transition: opacity 300ms ease; }

/* ---------- STREET MODE: the photograph owns the screen ---------- */
#place.street-mode .lens-pill { display: none; }
#place.street-mode .rail { padding: 6px; }
#place.street-mode .rung { width: 36px; height: 36px; font-size: 10px; }
#place.street-mode .altimeter { display: none; }
/* but the FALL always shows its number, even on warm street dives */
#place.street-mode.diving .altimeter { display: block; }

/* The plate as a sheet: name row visible, tap to open the rest */
.plate.sheet {
  max-height: 76px;
  overflow: hidden;
  cursor: pointer;
  transition: max-height 380ms var(--ease-settle);
}
.plate.sheet::before {
  content: "";
  position: absolute; top: 8px; left: 50%;
  width: 36px; height: 4px; margin-left: -18px;
  border-radius: 999px;
  background: var(--line-strong);
}
.plate.sheet h2 { margin-top: 8px; font-size: 20px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }
/* The opened sheet must never clip its own actions (Codex 11):
   a full NYC plate outgrows a fixed cap, so it scrolls */
.plate.sheet.open {
  max-height: min(70vh, 560px);
  max-height: min(70dvh, 560px);
  overflow-y: auto;
}

/* ---------- THEATER: the panorama takes everything ----------
   Real fullscreen is forbidden on iOS Safari; this is ours, and it
   works everywhere. Only the stride column stays, to keep walking. */
#place.theater .place-top,
#place.theater .rail,
#place.theater .plate { opacity: 0; pointer-events: none; }
#place.theater ~ .navbar { opacity: 0; pointer-events: none; }
#place.theater #streetPanel { z-index: 35; }

/* ---------- THE DAILY DROP: walk a mystery, guess the world ------- */
#place.drop-mode .plate,
#place.drop-mode .rail,
#place.drop-mode .lens-pill { display: none; }
/* Tonight names itself: the Earth plate sheet only buried the time
   strip on small phones (deep-dive blocker) */
#place.earth-mode .plate { display: none; }
/* the rail steps aside while the street sheet stands tall */
.rail { transition: opacity 200ms ease; }
#place.sheet-open .rail { opacity: 0; pointer-events: none; }
#place.drop-guess #streetPanel { display: none; }

.drop-bar {
  position: absolute;
  left: var(--pad); right: var(--pad);
  bottom: calc(max(var(--pad), env(safe-area-inset-bottom)) + 74px);
  z-index: 45;
  background: rgba(var(--surface-rgb), 0.8);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: 14px 16px;
  animation: plate-in 400ms var(--ease-settle);
}
.drop-bar p {
  font-family: var(--serif);
  font-size: 16px;
  margin-bottom: 10px;
}
/* Name your guess: the second door into the same pin */
.drop-bar .db-name {
  display: flex; gap: 8px; align-items: center;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 4px 4px 4px 12px;
  margin-bottom: 10px;
  transition: border-color 200ms ease;
}
.drop-bar .db-name:focus-within { border-color: rgba(var(--limb-rgb), 0.5); }
.drop-bar .db-name input {
  flex: 1; min-width: 0;
  background: none; border: 0; outline: 0;
  color: var(--text);
  font-size: 16px; /* 16 keeps iOS from zooming the focused field */
  padding: 9px 0;
}
.drop-bar .db-name input::placeholder { color: var(--text-faint); }
.drop-bar .db-go {
  flex: none;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  min-height: 40px;
  padding: 0 14px;
  font-weight: 600; font-size: 13px;
  color: var(--text);
  transition: transform 150ms var(--ease-settle), opacity 200ms ease;
}
.drop-bar .db-go:disabled { opacity: 0.5; }
.drop-bar .db-go:active { transform: scale(0.96); }
.drop-bar .db-standing {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin: -2px 0 10px;
}
.drop-bar .db-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.drop-bar .db-main {
  width: 100%;
  background: var(--sodium); color: var(--on-sodium);
  font-weight: 600; font-size: 15px;
  border-radius: var(--r-md);
  min-height: 48px;
  transition: transform 150ms var(--ease-settle), opacity 200ms ease;
}
.drop-bar .db-main:disabled { opacity: 0.45; }
.drop-bar .db-main:active { transform: scale(0.97); }
.drop-bar .db-back {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  min-height: 48px;
  font-weight: 600; font-size: 15px;
}

#dropDialog {
  border: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface);
  color: var(--text);
  width: 100%; max-width: 560px;
  margin: auto auto 0;
  padding: 22px var(--pad) max(22px, env(safe-area-inset-bottom));
}
#dropDialog::backdrop { background: rgba(var(--scrim-rgb), 0.6); backdrop-filter: blur(4px); }
#dropDialog h3 { font-family: var(--serif); font-weight: 600; font-size: 22px; }
#dropDialog .dd-place {
  font-family: var(--serif); font-style: italic;
  color: var(--text-soft); font-size: 16px; margin-top: 2px;
}
.dd-nums { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0 10px; }
.dd-num {
  background: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  padding: 12px; text-align: center;
}
.dd-num span { font-family: var(--mono); font-size: 26px; color: var(--limb); display: block; }
.dd-num.sod span { color: var(--sodium); }
.dd-num label {
  font-size: 11px; color: var(--text-dim);
  letter-spacing: 0.05em; text-transform: uppercase;
}
.dd-line { color: var(--text-dim); font-size: 15px; min-height: 1.4em; }
.dd-duel { color: var(--sodium); font-size: 15px; margin-top: 6px; }
.dd-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
.dd-actions button { border-radius: var(--r-md); padding: 13px; font-weight: 600; }
#ddShare { background: var(--surface-2); border: 1px solid var(--line-strong); }
#ddStand { background: var(--sodium); color: var(--on-sodium); }
.dd-close {
  width: 100%; margin-top: 14px;
  min-height: 44px;
  color: var(--text-faint);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.dd-close:hover, .dd-close:active { color: var(--silver); }

@media (min-width: 720px) { .drop-bar { max-width: 560px; margin-left: auto; margin-right: auto; } }

/* A postcard opens like an envelope */
#dedication {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  background: var(--ink);
  font-family: var(--serif); font-style: italic; font-weight: 600;
  font-size: clamp(22px, 6vw, 30px);
  color: var(--text);
  animation: word-rise 700ms var(--ease-settle);
  transition: opacity 600ms ease;
}
#dedication.leaving { opacity: 0; }

/* Toast */
#toast {
  position: fixed; left: 50%; bottom: 34px;
  transform: translateX(-50%) translateY(20px);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 10px 20px;
  font-size: 15px;
  opacity: 0; pointer-events: none;
  transition: opacity 250ms ease, transform 250ms var(--ease-settle);
  z-index: 60;
}
#toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  /* enter with a settle, leave without ceremony (council) */
  animation: toast-in 380ms var(--ease-settle);
}
@keyframes toast-in {
  0% { opacity: 0; transform: translateX(-50%) translateY(16px); }
  70% { transform: translateX(-50%) translateY(-2px); }
  100% { transform: translateX(-50%) translateY(0); }
}

/* ---------- THE LIFE PASS (council motion spec) ---------- */
/* a caption that is waiting breathes instead of freezing */
#orbitPanel figcaption.waiting { animation: cap-wait 1200ms ease-in-out infinite; }
@keyframes cap-wait { 50% { opacity: 0.45; } }
/* an honest miss shakes its head */
.time-strip.shake { animation: strip-shake 180ms ease-in-out 2; }
@keyframes strip-shake { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
/* the outgoing Earth dissolves over the incoming one */
.orbit-ghost { position: absolute; pointer-events: none; z-index: 2; transition: opacity 500ms ease; }
.orbit-ghost.fading { opacity: 0; }
.orbit-ghost .orbit-star { animation: none; }
/* press physics: every pressable gives under the thumb; press is
   fast implicit, release rides the settle */
.coll-btn, .sd-actions button, .atlas-tools button, .voice-cta button, .tp {
  transition: transform 240ms var(--ease-settle), border-color 200ms ease,
    background 200ms ease, color 200ms ease, opacity 200ms ease;
}
.coll-btn:active, .sd-actions button:active, .atlas-tools button:active,
.voice-cta button:active { transform: scale(0.96); }
.tp:active { transform: scale(0.98); }
/* the sheet's grabber answers the hand */
.plate.sheet::before { transition: transform 200ms var(--ease-settle), background 200ms ease; }
.plate.sheet:active::before { transform: scaleX(1.4); background: var(--text-dim); }

/* Touchdown settle: one frame vignette pulse + scale settle */
@keyframes touchdown {
  0% { transform: scale(1.015); }
  100% { transform: scale(1); }
}
.settling { animation: touchdown 60ms ease-out; }
#vignette {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  box-shadow: inset 0 0 120px rgba(0,0,0,0.8);
}
#vignette.pulse { animation: vg 120ms ease-out; }
@keyframes vg { 0% { opacity: 1; } 100% { opacity: 0; } }

/* ---------- The opening film: a miniature world, once ---------- */
#intro {
  position: fixed; inset: 0; z-index: 80;
  background: var(--ink);
  display: flex; align-items: center; justify-content: center;
}
#intro video {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 700ms ease;
}
#intro video.rolling { opacity: 1; }
#intro.leaving { animation: intro-out 700ms ease forwards; }
@keyframes intro-out { to { opacity: 0; } }
#introSkip {
  position: absolute;
  bottom: max(28px, env(safe-area-inset-bottom));
  left: 50%; transform: translateX(-50%);
  color: var(--text-dim);
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.04em;
  padding: 12px 22px;
  border-radius: 999px;
  background: rgba(var(--ink-rgb), 0.5);
  border: 1px solid var(--line);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* ---------- Bottom navigation: four rooms of the house ---------- */
.navbar {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: none;
  grid-template-columns: repeat(4, 1fr);
  gap: 2px;
  padding: 8px max(12px, env(safe-area-inset-left)) max(8px, env(safe-area-inset-bottom));
  /* real glass: the world glows through the house (Peliteca's bar;
     its law rides along: no press state on the glass element itself,
     backdrop-filter blinks) */
  background: rgba(var(--ink-rgb), 0.55);
  border-top: 1px solid rgba(var(--limb-rgb), 0.14);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
}
.navbar.show { display: grid; }
.navbar { transition: opacity 400ms ease; z-index: 50; } /* the ONE z-index (a stale 40 sat in the main block) */
/* the dive is the one moment the house recedes */
#place.diving ~ .navbar { opacity: 0; pointer-events: none; }
.navbar button {
  min-height: 52px;
  border-radius: var(--r-sm);
  font-size: 11px; font-weight: 600; /* the caption role, one voice */
  letter-spacing: 0.02em;
  /* dim not faint, and a breath of shadow: over noon-bright streets
     the faint labels washed to ~1.3:1 (deep-dive measurement) */
  color: var(--text-dim);
  text-shadow: 0 1px 8px rgba(var(--ink-rgb), 0.9);
  transition: color 200ms ease, background 200ms ease;
}
.navbar button.on { color: var(--text); background: rgba(var(--sodium-rgb), 0.08); }
/* the instrument cluster: four drawn glyphs, sodium when home */
.navbar button svg {
  display: block;
  width: 20px; height: 20px;
  margin: 0 auto 3px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 200ms ease, transform 150ms var(--ease-settle);
}
.navbar button.on svg { stroke: var(--sodium); }
.navbar button:active svg { transform: scale(0.88); }

/* ---------- WONDERS: visit the world ---------- */
#wonders {
  background: var(--ink);
  overflow-y: auto;
  padding: max(14px, env(safe-area-inset-top)) 0 96px;
}
.wonders-head { padding: 0 var(--pad) 4px; max-width: 720px; margin: 0 auto; }
.wonders-head h1 { font-family: var(--serif); font-weight: 600; font-size: 26px; }
.wonders-head p { color: var(--text-dim); font-size: 15px; margin-top: 2px; }
.tour-btn {
  margin-top: 12px;
  min-height: 46px;
  padding: 10px 20px;
  border-radius: var(--r-md);
  background: var(--sodium);
  color: var(--on-sodium);
  font-weight: 600; font-size: 15px;
  box-shadow: var(--lift-2); /* glow is for the world, not a rectangle */
  transition: transform 150ms var(--ease-settle);
}
.tour-btn:active { transform: scale(0.97); }

.wonders-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  padding: 14px var(--pad) 0;
  max-width: 720px; margin: 0 auto;
}
@media (min-width: 720px) { .wonders-grid { grid-template-columns: repeat(4, 1fr); } }
.wo-cat {
  grid-column: 1 / -1;
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-dim);
  margin-top: 10px;
}
.wo-cat:first-child { margin-top: 0; }

/* The classic eight: one strip, shoulder to shoulder */
.seven-strip {
  grid-column: 1 / -1;
  display: flex; gap: 12px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 2px;
  cursor: grab;
}
.seven-strip:active { cursor: grabbing; }
.seven-strip::-webkit-scrollbar { display: none; }
.wonder-mini {
  flex: none; width: 108px;
  text-align: left;
  transition: transform 240ms var(--ease-settle);
}
.wonder-mini:active { transform: scale(0.95) rotate(-0.6deg); }
.wonder-mini img {
  width: 108px; height: 108px;
  border-radius: var(--r-md);
  object-fit: cover; display: block;
  /* a coal of sodium around every window on the world (Kent: give
     the squares radiant life) */
  border: 1px solid rgba(var(--sodium-rgb), 0.28);
  box-shadow: 0 0 14px -6px rgba(var(--sodium-rgb), 0.35);
  filter: saturate(0.95);
  transition: border-color 240ms ease, box-shadow 240ms ease;
}
@media (hover: hover) {
  .wonder-mini:hover { transform: translateY(-3px) rotate(-0.8deg); }
  .wonder-mini:hover img {
    border-color: rgba(var(--sodium-rgb), 0.65);
    box-shadow: 0 0 22px -4px rgba(var(--sodium-rgb), 0.55);
  }
}
.wonder-mini span {
  font-family: var(--serif); font-weight: 600;
  font-size: 13px; line-height: 1.25;
  margin-top: 6px;
  height: 32px; /* two lines reserved: the strip stays lined up */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.wonder-card {
  position: relative; overflow: hidden;
  background: var(--surface);
  border: 1px solid rgba(var(--sodium-rgb), 0.24);
  box-shadow: 0 0 18px -8px rgba(var(--sodium-rgb), 0.3);
  border-radius: var(--r-md);
  text-align: left;
  transition: transform 240ms var(--ease-settle), border-color 240ms ease, box-shadow 240ms ease;
  animation: plate-in 240ms var(--ease-settle) backwards;
  animation-delay: calc(var(--i, 0) * 25ms);
}
.wonder-card:active { transform: scale(0.97) rotate(-0.5deg); }
@media (hover: hover) {
  .wonder-card:hover {
    transform: translateY(-4px) rotate(-0.6deg) scale(1.01);
    border-color: rgba(var(--sodium-rgb), 0.6);
    box-shadow: 0 0 26px -4px rgba(var(--sodium-rgb), 0.5), var(--lift-2);
  }
}
.wonder-card img {
  width: 100%; aspect-ratio: 1; object-fit: cover; display: block;
  filter: saturate(0.95);
}
.wonder-card .wo-body { padding: 9px 11px 11px; display: block; }
.wonder-card .wo-name {
  display: block;
  font-family: var(--serif); font-weight: 600; font-size: 15px; line-height: 1.25;
}
.wonder-card .wo-meta {
  display: block;
  font-family: var(--mono); font-size: 10px;
  color: var(--text-dim); margin-top: 2px;
  text-transform: uppercase; letter-spacing: 0.06em;
}

/* Screens that carry the navbar leave room for it */
#home .home-veil { padding-bottom: calc(max(var(--pad), env(safe-area-inset-bottom)) + 66px); }
#atlas { padding-bottom: 110px; }

/* MapLibre chrome, dressed for the dark */
.maplibregl-ctrl-attrib { background: rgba(var(--ink-rgb), 0.55) !important; }
.maplibregl-ctrl-attrib a, .maplibregl-ctrl-attrib { color: var(--text-faint) !important; font-size: 10px; }
.maplibregl-ctrl-attrib-button { filter: invert(0.8) opacity(0.5); }

/* ---------- Reduced motion: same story, told in stills ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    /* delays must clamp too: a backwards-fill stagger with a live
       delay leaves content BLANK under reduced motion (council catch) */
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}

/* ---------- NIGHT PLATES: no raw noon suburbia in a night app ------
   Every satellite thumbnail prints as a moonlit lith in limb blue;
   the atlas shelves override with their own temperatures above. */
.wonder-card img, .wonder-mini img, .place-card img,
.tl-row img, .tp img {
  /* --lith-lum: each wonder plate measures its own raw light and
     dims toward one shared moonlit band (B51: Petra's bright desert
     read as a highlight next to the Great Wall's dark forest).
     Plates that never measure keep the classic 1. */
  filter: grayscale(1) sepia(1) hue-rotate(var(--lith-hue)) saturate(1.1) brightness(calc(0.78 * var(--lith-lum, 1))) contrast(1.18);
}
/* the Window's backdrop keeps its daylight, dimmed to evening */
.window-card .wc-bg { filter: saturate(0.75) brightness(0.85) contrast(1.05); }

/* ---------- ELEVATION: depth instead of more hairlines ---------- */
.plate, .searchbar, .window-card { box-shadow: var(--lift-2); }
.wonder-card, .place-card, .drop-bar { box-shadow: var(--lift-1); }
#saveDialog, #dropDialog, #pastDialog, #shareDialog { box-shadow: var(--lift-3); }

/* ---------- Share preview: what goes out, shown first ---------- */
#shareDialog {
  border: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface);
  color: var(--text);
  width: 100%; max-width: 560px;
  margin: auto auto 0;
  padding: 22px var(--pad) max(22px, env(safe-area-inset-bottom));
}
#shareDialog::backdrop { background: rgba(var(--scrim-rgb), 0.6); backdrop-filter: blur(4px); }
#shareDialog h3 { font-family: var(--serif); font-weight: 600; font-size: 22px; }
#shareImg {
  display: block;
  width: auto; max-width: 100%;
  max-height: 38vh;
  margin: 14px auto 0;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
}
.sh-text {
  font-family: var(--serif);
  font-style: italic;
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-soft);
  margin: 12px 0 4px;
}
.sh-link {
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 14px;
}
.sh-miss {
  font-family: var(--serif);
  font-style: italic;
  font-size: 13px;
  color: var(--sodium);
  opacity: 0.85;
  margin-top: 12px;
}
.sh-text:last-of-type { margin-bottom: 14px; }
.sh-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sh-actions button {
  min-height: 48px;
  border-radius: var(--r-md);
  font-weight: 600; font-size: 15px;
}
#shareCancel { background: var(--surface-2); border: 1px solid var(--line-strong); }
#shareSend { background: var(--limb); color: var(--on-limb); }
#shareSend:active { transform: scale(0.97); }

/* the tappable nearby line: the story waits behind it */
.intel.tappable {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* ---------- The story: the world's memory, read in-app ---------- */
#storyDialog {
  border: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface);
  color: var(--text);
  width: 100%; max-width: 560px;
  margin: auto auto 0;
  padding: 22px var(--pad) max(22px, env(safe-area-inset-bottom));
  box-shadow: var(--lift-3);
}
#storyDialog::backdrop { background: rgba(var(--scrim-rgb), 0.6); backdrop-filter: blur(4px); }
#storyDialog h3 { font-family: var(--serif); font-weight: 600; font-size: 22px; }
#stImg {
  display: block;
  width: 100%;
  max-height: 30vh;
  object-fit: cover;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  margin-top: 12px;
}
.st-text {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-soft);
  margin: 12px 0 14px;
  max-height: 32vh;
  overflow-y: auto;
}
.st-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  align-items: center;
}
.st-row a {
  text-align: center;
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- The past near here: a sheet of silver plates ---------- */
#pastDialog {
  border: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--surface);
  color: var(--text);
  width: 100%; max-width: 560px;
  margin: auto auto 0;
  padding: 22px var(--pad) max(22px, env(safe-area-inset-bottom));
}
#pastDialog::backdrop { background: rgba(var(--scrim-rgb), 0.6); backdrop-filter: blur(4px); }
#pastDialog h3 { font-family: var(--serif); font-weight: 600; font-size: 22px; }
.past-doors {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin-top: 12px;
}
.past-line {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin: 10px 0;
}
.past-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  max-height: 44vh; overflow-y: auto;
  margin-bottom: 12px;
}
.past-card {
  position: relative;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--ink);
  display: block;
}
.past-card img {
  width: 100%; height: 116px;
  object-fit: cover; display: block;
  /* the archive prints in the Gone shelf's silver, never full color:
     the past keeps its own temperature */
  filter: grayscale(1) sepia(0.12) brightness(0.94) contrast(1.04);
}
.past-card span {
  position: absolute; left: 8px; bottom: 6px;
  font-family: var(--mono); font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}

/* The viewer: the photograph opens INSIDE the app, credited */
.past-view img {
  display: block;
  width: 100%;
  max-height: 46vh;
  object-fit: contain;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--ink);
  margin-top: 10px;
  /* full silver in the viewer too: the past keeps its temperature */
  filter: grayscale(1) sepia(0.12) brightness(0.96) contrast(1.03);
}
.pv-cap {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin: 10px 0 12px;
}
.pv-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  align-items: center;
  margin-bottom: 12px;
}
.pv-row button {
  min-height: 44px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font-weight: 600; font-size: 13px;
}
.pv-row a {
  text-align: center;
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* the dream shelf's printing press */
.board-btn {
  margin-left: auto;
  min-height: 34px;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid rgba(var(--violet-rgb), 0.45);
  color: var(--temp-dream, #a99bd6);
  font-size: 12px; font-weight: 600;
  transition: opacity 200ms ease;
}
.board-btn:disabled { opacity: 0.5; }

/* Wider screens: the phone frame stays the star */
@media (min-width: 720px) {
  .home-veil, .plate { max-width: 560px; margin-left: auto; margin-right: auto; }
  .plate { margin-bottom: 28px; }
  .shelf { max-width: 720px; margin: 0 auto; }
  .shelf-grid { grid-template-columns: repeat(4, 1fr); }
}
