/* V6 · final design base (V4 Premiere world, V5 loader / floor counter / skyline depth).
   Type: Archivo (variable width + weight, SIL OFL) for titles; Hanken Grotesk (SIL OFL) for text;
   Martian Mono (SIL OFL) only for true measurements (clock, countdown, floor). Google Fonts.
   Icons: authored SVG (icons.js). Section modules add their own stylesheet (sections/README.md). */

:root {
  --black: #070605;
  --ink: #120f0c;
  --bone: #efe9df;
  --bone-dim: #a39c90;
  --molten: #ff5a14;
  --molten-hover: #ff7a3f;
  --chapter-size: clamp(3.3rem, 13vw, 12.5rem);
  --warm-light: #ffe2c4;

  --ground: var(--black);
  --ground-2: #110f0d;
  --ground-3: #1b1815;
  --text: var(--bone);
  --muted: var(--bone-dim);
  --line: rgba(239, 233, 223, 0.16);
  --line-strong: rgba(239, 233, 223, 0.38);
  --wall: var(--black);
  --bar-color: #000;
  --sheet-bg: #0d0b09;
  --sheet-text: var(--bone);
  --sheet-muted: var(--bone-dim);
  --sheet-line: rgba(239, 233, 223, 0.16);
  --knock-bg: var(--black);
  --knock-ink: #fff;
  --knock-blend: multiply;

  --display: "Archivo", "Arial Narrow", "Helvetica Neue", sans-serif;
  --text-font: "Hanken Grotesk", "Helvetica Neue", system-ui, sans-serif;
  --mono: "Martian Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --gutter: clamp(16px, 4vw, 56px);
  --section: clamp(104px, 13vw, 200px);
  --topbar-h: 64px;
  --dock-h: 58px;
  --dock-clear: calc(var(--dock-h) + max(14px, env(safe-area-inset-bottom)) + 24px);
  --screen-inset: 0px;
  --screen-top: 0px;
  --bar-h: clamp(36px, calc((100svh - 100vw / 2.39) / 2), 16svh);

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

  color-scheme: dark;
}

/* House lights up: a warm screen-white wall, the film framed as a projection on it. */
:root[data-theme="light"] {
  --ground: #efe7da;
  --ground-2: #e5dacb;
  --ground-3: #d9ccb9;
  --text: #14100c;
  --muted: #574e44;
  --line: rgba(20, 16, 12, 0.16);
  --line-strong: rgba(20, 16, 12, 0.42);
  --wall: #efe7da;
  --bar-color: #efe7da;
  --sheet-bg: #f6f0e7;
  --sheet-text: #14100c;
  --sheet-muted: #574e44;
  --sheet-line: rgba(20, 16, 12, 0.16);
  --knock-bg: #efe7da;
  --knock-ink: #000;
  --knock-blend: screen;
  --screen-inset: clamp(10px, 2vw, 32px);
  --screen-top: 64px;
  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
/* Clip at the viewport, not only the body: overscanned cinematic layers must
   never enlarge the mobile layout viewport or move fixed controls off screen.
   `clip` preserves the document's native scrolling and sticky descendants. */
html { overflow-x: clip; scrollbar-color: var(--molten) var(--ground); -webkit-text-size-adjust: 100%; }
html.scrollbar-on-molten { scrollbar-color: var(--black) var(--molten); }
html.scrollbar-on-molten::-webkit-scrollbar-thumb { background-color: var(--black); }
html.scrollbar-on-molten::-webkit-scrollbar-track { background-color: var(--molten); }
body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font: 400 17px/1.55 var(--text-font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  transition: background-color 220ms var(--ease-in-out), color 220ms var(--ease-in-out);
}
.is-loading body { overflow: hidden; }
::selection { background: var(--molten); color: var(--black); }
:focus-visible { outline: 2px solid var(--molten); outline-offset: 3px; }
input, textarea { caret-color: var(--molten); }

/* Every interactive object gets a baseline response; component-specific hover treatments below can build on it.
   `scale` and `translate` are individual transform properties, so they do not overwrite scroll or entrance transforms. */
:where(a[href], button:not(:disabled), summary, [role="button"]):active { translate: 0 1px; scale: 0.985; }
@media (hover: hover) and (pointer: fine) {
  :where(a[href], button:not(:disabled), summary, [role="button"]) { transition: opacity 180ms ease, scale 140ms var(--ease-out), translate 140ms var(--ease-out); }
  :where(a[href], button:not(:disabled), summary, [role="button"]):hover { opacity: 0.92; }
}
:root { view-transition-name: none; }
[data-main] { view-transition-name: theme-body; }
::view-transition { pointer-events: none; }
::view-transition-group(*), ::view-transition-image-pair(*), ::view-transition-old(*), ::view-transition-new(*) { pointer-events: none; }
::view-transition-old(theme-body), ::view-transition-new(theme-body) { animation: none; mix-blend-mode: normal; }
::view-transition-new(theme-body) {
  clip-path: circle(var(--theme-radius, 0px) at var(--theme-x, 100%) var(--theme-y, 0));
  animation: theme-radial-hold 680ms linear both;
}
@keyframes theme-radial-hold { from { opacity: 0.999; } to { opacity: 1; } }
h1, h2, h3, p, dl, dd, ol, ul, figure { margin: 0; }
ol, ul { padding: 0; list-style: none; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
button { font: inherit; color: inherit; }
.icon { width: 1.25em; height: 1.25em; flex: none; display: block; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 0.86em; letter-spacing: -0.01em; }

.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.skip-link { position: fixed; left: 12px; top: 12px; z-index: 200; padding: 12px 16px; background: var(--molten); color: var(--black); font-weight: 600; transform: translateY(-160%); }
.skip-link:focus-visible { transform: none; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  min-height: 54px; padding: 0 22px;
  border: 0; border-radius: 0;
  font: 600 16px/1.1 var(--text-font);
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 200ms ease, color 200ms ease, box-shadow 200ms ease;
}
.btn .icon { width: 20px; height: 20px; }
.btn:active { transform: scale(0.97); }
.btn--molten { background: var(--molten); color: var(--black); }
.btn--line { background: transparent; color: inherit; box-shadow: inset 0 0 0 1px currentColor; }
.btn--text { background: transparent; color: inherit; min-height: 44px; text-decoration: underline; text-underline-offset: 0.3em; }
.btn--wide { width: 100%; justify-content: space-between; }
.btn--square { width: 54px; padding: 0; }
@media (hover: hover) and (pointer: fine) {
  .btn--molten:hover { background: var(--molten-hover); }
  .btn--line:hover { background: var(--molten); color: var(--black); box-shadow: inset 0 0 0 1px var(--molten); }
}
.icon-button { display: grid; place-items: center; width: 44px; height: 44px; background: transparent; border: 0; border-radius: 0; cursor: pointer; transition: transform 160ms var(--ease-out); }
.icon-button:active { transform: scale(0.94); }
.icon-button .icon { width: 22px; height: 22px; }
/* Every close (X) moves the same way, wherever it lives: the sheets, the archive, the Directions menu and any section
   module that uses icon("close"). It turns in as its container opens, then answers the pointer with a quarter turn
   and a crisp press. The entrance uses the individual rotate/scale properties and the interaction uses transform, so
   the two compose instead of fighting; :is() keeps the rule alive in engines without :popover-open. */
.icon--close { transform-origin: 50% 50%; transition: transform 220ms var(--ease-out), color 180ms ease; }
:is(dialog[open], :popover-open, .is-open) .icon--close { animation: x-in 460ms var(--ease-out) 80ms backwards; }
@keyframes x-in { from { opacity: 0; rotate: -90deg; scale: 0.4; } to { opacity: 1; rotate: 0deg; scale: 1; } }
@keyframes x-fade { from { opacity: 0; } to { opacity: 1; } }
@media (hover: hover) and (pointer: fine) {
  :is(button, a):hover .icon--close { transform: rotate(90deg); color: var(--molten); }
}
:is(button, a):active > .icon--close { transform: rotate(90deg) scale(0.82); transition-duration: 110ms; }

/* ---------- loader: a lift floor indicator (V5) ---------- */

.loader { position: fixed; inset: 0; z-index: 150; display: grid; place-items: center; pointer-events: none; color: var(--text); }
.loader__doors { position: absolute; inset: 0; display: grid; grid-template-columns: 1fr 1fr; }
.loader__door { position: relative; overflow: hidden; background: var(--ground); transition: transform 500ms var(--ease-out); }
/* The seam is drawn on each door's inner edge and parts around the floor readout, like a lift indicator set into the doors. */
.loader__door::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 1px; background: var(--molten);
  --gap: clamp(96px, 12vw, 150px);
  -webkit-mask: linear-gradient(to bottom, #000 calc(50% - var(--gap) - 24px), transparent calc(50% - var(--gap)), transparent calc(50% + var(--gap)), #000 calc(50% + var(--gap) + 24px));
  mask: linear-gradient(to bottom, #000 calc(50% - var(--gap) - 24px), transparent calc(50% - var(--gap)), transparent calc(50% + var(--gap)), #000 calc(50% + var(--gap) + 24px));
}
.loader__door--l::after { right: 0; }
.loader__door--r::after { left: 0; }
.loader__panel { position: relative; display: grid; justify-items: center; gap: 8px; }
/* A full-loader-sized readout inside each half-width door, aligned at the seam. */
.loader__readout { position: absolute; inset: 0 auto 0 0; width: 200%; display: grid; place-items: center; }
.loader__door--r .loader__readout { left: -100%; }
.loader__label { display: grid; text-align: center; font: 600 0.78rem/1 var(--text-font); letter-spacing: 0.24em; text-transform: uppercase; color: var(--muted); }
.loader__label > span { grid-area: 1 / 1; }
.loader__waiting { opacity: 0; }
.loader__dots { display: inline-flex; margin-left: .25em; letter-spacing: 0; }
.loader__dots i { display: inline-block; width: .4em; font-style: normal; }
.loader__floor { font: 200 clamp(5rem, 16vw, 9rem)/0.9 var(--display); font-stretch: 112%; font-variant-numeric: tabular-nums; letter-spacing: -0.04em; color: var(--molten); }
.loader__bar { width: 120px; height: 1px; margin-top: 10px; background: var(--line); overflow: hidden; }
.loader__bar span { display: block; height: 100%; background: var(--molten); transform: scaleX(0); transform-origin: left; }
.loader--open .loader__door--l { transform: translate3d(-101%, 0, 0); }
.loader--open .loader__door--r { transform: translate3d(101%, 0, 0); }
.loader--done { opacity: 0; transition: opacity 0.35s; }

/* ---------- top bar ---------- */

.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 70;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
  height: var(--topbar-h); padding: 0 calc(var(--gutter) - 10px) 0 var(--gutter);
  color: var(--bone);
  background: linear-gradient(to bottom, rgba(7, 6, 5, 0.66), rgba(7, 6, 5, 0));
  transition: background-color 240ms ease, color 240ms ease, box-shadow 240ms ease;
}
:root[data-theme="light"] .topbar { color: var(--text); background: var(--wall); }
.topbar.on-molten { background: transparent; color: var(--black); }
.topbar.is-solid { background: var(--ground); color: var(--text); box-shadow: inset 0 -1px 0 var(--line); }
.topbar__invite { justify-self: start; display: flex; align-items: center; gap: 10px; font: 700 12px/1 var(--text-font); letter-spacing: 0.18em; text-transform: uppercase; white-space: nowrap; }
.topbar__dot { width: 4px; height: 4px; background: var(--molten); }
.topbar__count { font-family: var(--mono); font-weight: 400; font-size: 12px; letter-spacing: 0; text-transform: none; }
.topbar__invite { min-width: 0; max-width: 100%; }
.topbar__invite [data-invited-label] { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.topbar__guest-name { color: var(--molten); }
:root[data-theme="dark"] .topbar.on-molten .topbar__guest-name { color: var(--bone); }
.topbar__count, .topbar__dot { flex: none; }
.topbar__status { font-size: 14px; font-weight: 500; }
.topbar__end { justify-self: end; display: flex; align-items: center; gap: 8px; }
.topbar__clock { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; font-weight: 600; white-space: nowrap; color: inherit; text-decoration: none; }
.topbar__clock-city { font-weight: 500; opacity: 0.72; }

/* ---------- film stages ---------- */

.act { position: relative; }
.act--city { height: 640vh; }
.doors-hold { position: relative; height: 54vh; margin-top: -100vh; }
/* The film keeps its own 620vh clock. Extra distance belongs only to reading:
   arrival hold, word reveal, full letter hold, then the slower contraction. */
.act--ascent { height: 1437vh; }

.stage {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden; isolation: isolate;
  background: var(--wall); color: var(--bone);
}
.screen {
  position: absolute;
  inset: var(--screen-top) var(--screen-inset) var(--screen-inset) var(--screen-inset);
  overflow: hidden; isolation: isolate;
  background: var(--black);
}
:root[data-theme="light"] .screen { box-shadow: 0 30px 60px -30px rgba(20, 16, 12, 0.45), 0 2px 6px rgba(20, 16, 12, 0.18); }
.screen__poster, .screen__film, .screen__fg {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.screen__film { opacity: 0; transition: opacity 500ms var(--ease-out); }
.screen__scene { position: absolute; inset: 0; transform-origin: center; }
.stage.is-live .screen__film { opacity: 1; }
/* No separate poster underneath on this path: paint the complete first frame
   immediately instead of fading it up from black as the loader doors open. */
.stage--canvas-first .screen__film { transition: none; }
.screen__fg { z-index: 2; pointer-events: none; display: none; }
/* the grid's centre frame, alive once the pull-back lands: a slow camera drift, a pulse per city light (canvas) and a
   breathing warm glow. main.js drives all three from one eased weight so they fade in and out with the pull-back
   instead of snapping (see drawTwinkles). */
.screen__twinkle { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; mix-blend-mode: screen; }
.screen__glow { display: none; }
.stage.has-matte .screen__fg { display: block; }

.bar {
  position: absolute; left: 0; right: 0; z-index: 6;
  height: var(--bar-h);
  background: var(--bar-color);
  transform: scaleY(0);
}
.bar--top { top: 0; transform-origin: top; }
.bar--bottom { bottom: 0; transform-origin: bottom; }
.stage.has-matte .bar { height: min(var(--bar-h), 9svh); }

.scrim { position: absolute; left: 0; right: 0; pointer-events: none; z-index: 3; }
.scrim--bottom { bottom: 0; height: 64%; background: linear-gradient(to top, rgba(7, 6, 5, 0.82), rgba(7, 6, 5, 0)); opacity: 0; }
.scrim--strong { background: linear-gradient(to top, rgba(7, 6, 5, 0.9) 10%, rgba(7, 6, 5, 0)); }
.scrim--top { top: 0; height: 30%; background: linear-gradient(to bottom, rgba(7, 6, 5, 0.55), rgba(7, 6, 5, 0)); }

/* the wordmark: a field with the city inside the letters */
/* The wordmark opens molten: a colour layer under the field tints the city inside the letters (the field around them
   hides it) and main.js fades it out with the zoom, so the film plays with no filter once the letters have gone. */
.knock-tint { position: absolute; inset: 0; z-index: 4; background: var(--molten); mix-blend-mode: color; pointer-events: none; }
.knockout { position: absolute; inset: 0; z-index: 4; pointer-events: none; background: var(--knock-bg); mix-blend-mode: var(--knock-blend); }
/* Set like the footer wordmark: each line's ink justified to the full width between equal gutters (main.js fitWordmark
   sizes the SVG and its viewBox; the lines are scaled inside it). */
.knockout__lockup { position: absolute; left: var(--gutter); top: 72px; display: block; overflow: visible; }
.knockout__text { fill: var(--knock-ink); font-family: var(--display); font-size: 300px; font-weight: 900; font-stretch: 125%; letter-spacing: 0; }

/* the sky words between the sky and the buildings: static in the sky band, rise with the film; main.js fitForty sizes
   the line to the frame. */
.forty {
  position: absolute; inset: 0; z-index: 1;
  display: grid; justify-items: center; align-content: start;
  padding-top: calc(min(var(--bar-h), 9svh) + 5svh);
  pointer-events: none; opacity: 0; --rise: 1; --matte: 0;
}
.forty span {
  --sunset: 0; --glare: 0;
  position: relative; display: block; width: max-content; white-space: nowrap; text-align: center;
  font-family: var(--display); font-weight: 900; font-stretch: 125%;
  line-height: 0.8; letter-spacing: -0.02em; color: #f6f1e9;
  transform: translate3d(0, calc(var(--rise) * 105%), 0);
  opacity: var(--matte);
}
.forty span::after {
  content: attr(data-text);
  position: absolute; inset: 0;
  color: transparent;
  /* A narrow sunset edge climbs through the white letters. Everything below the edge stays molten, while the
     cream-hot rim and soft glare move upward with scroll and leave the system orange behind. */
  background: linear-gradient(to top,
    var(--molten) 0 calc(var(--sunset) * 100% - 7%),
    #ff9c55 calc(var(--sunset) * 100% - 3%),
    #fff0d4 calc(var(--sunset) * 100%),
    rgba(255, 175, 96, 0.7) calc(var(--sunset) * 100% + 3%),
    transparent calc(var(--sunset) * 100% + 8%));
  -webkit-background-clip: text; background-clip: text;
  opacity: 1;
  filter: drop-shadow(0 0 calc(var(--glare) * 12px) rgba(255, 112, 34, calc(var(--glare) * 0.62)));
  pointer-events: none;
}
/* no matte (reduced motion, no WebGL): the same words flat over the film, above the scrim, with a shadow for contrast */
.stage:not(.has-matte) .forty { z-index: 3; }
.stage:not(.has-matte) .forty span { opacity: 1; text-shadow: 0 2px 40px rgba(0, 0, 0, 0.45); }
@media (orientation: portrait) { .forty { padding-top: calc(min(var(--bar-h), 9svh) + 6svh); } .forty span { font-stretch: 62%; letter-spacing: -0.01em; } }

.hero-meta {
  position: absolute; z-index: 7;
  left: calc(var(--gutter) + var(--screen-inset)); right: calc(var(--gutter) + var(--screen-inset)); bottom: calc(var(--dock-clear) + var(--screen-inset) + 8px);
  display: grid; grid-template-columns: auto auto auto 1fr; align-items: center; gap: 14px clamp(28px, 4vw, 64px);
  color: var(--text);
}
.hero-meta--date { display: none; }
.hero-meta__date {
  font: 800 clamp(1.05rem, 1.7vw, 1.45rem)/1.1 var(--display);
  font-stretch: 112%;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.hero-meta__headline { grid-column: 1 / -1; margin-bottom: 4px; font: 800 clamp(1.25rem, 2vw, 1.7rem)/1.1 var(--display); font-stretch: 112%; letter-spacing: -0.005em; }
.hero-meta__item { display: flex; align-items: center; gap: 10px; font-size: 15px; line-height: 1.35; font-weight: 600; white-space: nowrap; }
.hero-meta__item .icon { flex: none; width: 20px; height: 20px; color: var(--molten); }

/* title cards over act 1 */
.card {
  position: absolute; inset: 0; z-index: 5;
  display: grid; place-content: center; justify-items: center; gap: 12px; text-align: center;
  padding: 0 var(--gutter);
  color: var(--bone); opacity: 0; visibility: hidden;
}
.card__big { font: 900 clamp(2.7rem, min(7.8vw, 13svh), 8.5rem)/0.88 var(--display); font-stretch: 125%; letter-spacing: -0.02em; text-transform: uppercase; color: var(--molten); text-shadow: 0 2px 40px rgba(0, 0, 0, 0.35); }
/* the date card: act 1's second big beat, one masked line per part of the date rising in turn (main.js) */
.card__line { display: block; overflow: hidden; padding-block: 0.04em; white-space: nowrap; }
.card__line > span { display: block; will-change: transform; }
@media (orientation: portrait) { .card__big { font-stretch: 72%; letter-spacing: -0.01em; font-size: clamp(2.25rem, min(14vw, 9svh), 5.5rem); } }

/* ---------- doors: a fixed overlay that closes over the end of act 1 and opens into the lift ---------- */

.doors { position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: 0; visibility: hidden; overflow: hidden; --seam: 0; }
.door { position: absolute; z-index: 1; top: 0; bottom: 0; width: 50.5%; overflow: hidden; background: var(--molten); will-change: transform; }
.door--left { left: 0; transform: translateX(-100%); }
.door--right { right: 0; transform: translateX(100%); }
.door__edge { position: absolute; z-index: 3; top: 0; bottom: 0; width: 1px; background: rgba(7, 6, 5, 0.3); opacity: var(--seam); }
.door--left .door__edge { right: 0; }
.door--right .door__edge { left: 0; }
.door__light {
  position: absolute; z-index: 2; top: 0; bottom: 0; left: 50%; width: 2px; translate: -50% 0;
  background: linear-gradient(to bottom, rgba(255, 226, 196, 0), var(--warm-light) 30%, #fff 50%, var(--warm-light) 70%, rgba(255, 226, 196, 0));
  opacity: 0; visibility: hidden;
}
.doors__type {
  position: absolute; z-index: 2; top: 0; bottom: 0; width: 100vw;
  display: grid; place-content: center; padding: 0 var(--gutter);
  color: var(--black); opacity: 0; visibility: hidden;
}
.door--left .doors__type { left: 0; }
.door--right .doors__type { right: 0; }
.door-date { width: min(84vw, 78rem); margin: auto; text-transform: uppercase; }
.door-date__weekday {
  margin: 0 0 clamp(12px, 2.4vh, 24px); font: 700 clamp(1rem, 1.5vw, 1.35rem)/1.2 var(--mono);
  letter-spacing: 0.2em;
}
.door-date__lockup { display: grid; grid-template-columns: auto 1fr auto; align-items: end; column-gap: clamp(14px, 2.4vw, 40px); margin: 0; }
.door-date__lockup strong { font: 900 clamp(6.5rem, 18vw, 18rem)/0.69 var(--display); font-stretch: 125%; letter-spacing: -0.065em; }
.door-date__lockup span { padding-bottom: 0.02em; font: 760 clamp(2.35rem, 6.8vw, 7rem)/0.78 var(--display); font-stretch: 112%; letter-spacing: -0.045em; }
.door-date__lockup em { padding-bottom: 0.22em; font: 620 clamp(1rem, 2vw, 2rem)/1 var(--mono); font-style: normal; letter-spacing: 0.14em; }
@media (orientation: portrait) {
  .door-date { width: min(84vw, 35rem); }
  .door-date__weekday { margin-bottom: 18px; }
  .door-date__lockup { grid-template-columns: auto 1fr; gap: 12px 16px; }
  .door-date__lockup strong { font-size: clamp(6rem, 31vw, 10rem); }
  .door-date__lockup span { font-size: clamp(2.4rem, 13vw, 4.5rem); }
  .door-date__lockup em { grid-column: 2; padding-bottom: 0; }
}

/* ---------- act 2: floor readout (V5 design), arrival, pull-back ---------- */

.floor-read {
  position: absolute; z-index: 5;
  right: var(--gutter); bottom: calc(var(--bar-h) + 40px);
  display: grid; justify-items: end;
  color: #f6f1e9; opacity: 0; visibility: hidden; pointer-events: none;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.45);
  --floor: 0; --rail: 44svh;
}
.floor-read__rail { position: absolute; right: calc(var(--gutter) * -0.5); bottom: 0; width: 2px; height: var(--rail); background: rgba(246, 241, 233, 0.3); box-shadow: 0 0 12px rgba(0, 0, 0, 0.35); }
.floor-read__rail::before { content: ""; position: absolute; inset: auto 0 0; height: calc(var(--floor) * 100%); background: var(--molten); }
.floor-read__dot { position: absolute; z-index: 1; left: -5px; bottom: calc(var(--floor) * (var(--rail) - 12px)); width: 12px; height: 12px; border-radius: 50%; background: var(--molten); box-shadow: 0 0 0 3px rgba(7, 6, 5, 0.45); }
.floor-read__label { font: 600 0.78rem/1 var(--text-font); letter-spacing: 0.24em; text-transform: uppercase; color: rgba(246, 241, 233, 0.86); }
.floor-read__value { margin-top: 6px; font: 250 clamp(6rem, 17vw, 12.5rem)/0.8 var(--display); font-stretch: 112%; font-variant-numeric: tabular-nums; letter-spacing: -0.045em; transition: color 600ms var(--ease-out); }
.floor-read.is-top .floor-read__value { color: var(--molten); }

.arrival {
  position: absolute; z-index: 5;
  left: var(--gutter); bottom: calc(var(--bar-h) + 36px);
  width: min(620px, calc(100% - var(--gutter) * 2 - 240px));
  display: grid; gap: 14px; justify-items: start;
  color: #f6f1e9; opacity: 0; visibility: hidden;
}
.arrival__label { display: flex; width: max-content; align-items: center; gap: 10px; margin-top: -2px; font: 600 clamp(0.82rem, 1vw, 0.95rem)/1.2 var(--text-font); letter-spacing: 0.14em; text-transform: uppercase; text-decoration: none; color: rgba(246, 241, 233, 0.9); text-shadow: 0 1px 18px rgba(0, 0, 0, 0.5); transition: color 180ms ease, transform 180ms var(--ease-out); }
.arrival__label .icon { flex: none; width: 20px; height: 20px; color: var(--molten); }
@media (hover: hover) and (pointer: fine) { .arrival__label:hover { color: var(--molten); opacity: 1; } }
.arrival__label:focus-visible { color: var(--molten); outline: 2px solid var(--molten); outline-offset: 5px; }
.arrival__label:active { transform: translateX(4px) scale(0.98); }
.arrival__line { font: 850 clamp(2.9rem, 6.8vw, 6.5rem)/0.9 var(--display); font-stretch: 100%; letter-spacing: -0.03em; text-shadow: 0 2px 40px rgba(0, 0, 0, 0.35); }
.rsvp-box {
  margin-top: 12px;
  display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 28px; row-gap: 4px;
  min-width: min(360px, 100%); padding: 18px 20px 18px 22px;
  border: 0; background: var(--molten); color: var(--black); text-align: left; cursor: pointer;
  transition: background-color 200ms ease, transform 160ms var(--ease-out);
}
.rsvp-box__label { font: 900 clamp(1.9rem, 3vw, 2.5rem)/0.9 var(--display); font-stretch: 125%; letter-spacing: -0.02em; text-transform: uppercase; }
.rsvp-box__meta { grid-column: 1; font-size: 14px; font-weight: 600; }
.rsvp-box .icon { grid-column: 2; grid-row: 1 / span 2; width: 32px; height: 32px; }
.rsvp-box:active { transform: scale(0.98); }
@media (hover: hover) and (pointer: fine) { .rsvp-box:hover { background: var(--molten-hover); } }

.stage--ascent { background: var(--ground); isolation: isolate; visibility: hidden; opacity: 0; }
.reel__backdrop { position: absolute; inset: -28px; z-index: 0; overflow: hidden; background: var(--black); }
.reel__backdrop img { width: 100%; height: 100%; object-fit: cover; filter: blur(22px) saturate(0.78) brightness(0.66); transform: scale(1.08); }
.reel__backdrop::after { content: ""; position: absolute; inset: 0; background: rgba(7, 6, 5, 0.18); }
.screen-clip { position: absolute; inset: 0; z-index: 2; will-change: clip-path; }
.screen-clip .screen { transform-origin: 50% 50%; will-change: transform; }
.reel__grid {
  position: absolute; z-index: 1;
  inset: calc(var(--topbar-h) + 2vh) var(--gutter) calc(var(--dock-clear) + 1vh);
  display: grid; gap: clamp(8px, 1.2vw, 16px);
  grid-template-columns: repeat(5, minmax(0, 1fr));
  grid-template-rows: repeat(3, minmax(0, 1fr));
  grid-template-areas:
    "t1 t2 t3 t4 t5"
    "t6 c  c  c  t7"
    "t8 t9 t10 t11 t12";
  perspective: 1200px;
}
/* Grid invitation: the skyline owns the complete middle row. Removing the two flank images gives the letter enough
   calm width to read as the invitation's centre, not as copy floating over a busy collage. */
.stage--ascent:has([data-reel-note]) .reel__grid {
  grid-template-areas:
    "t1 t2 t3 t4 t5"
    "c  c  c  c  c"
    "t8 t9 t10 t11 t12";
}
.stage--ascent:has([data-reel-note]) :is(.reel__tile--6, .reel__tile--7) { display: none; }
.reel__tile { position: relative; padding: 0; border: 0; background: var(--ground-3); cursor: zoom-in; opacity: 0; will-change: transform, opacity; min-width: 0; min-height: 0; transition: scale 140ms var(--ease-out); }
.reel__tile .shot { height: 100%; }
.reel__tile .shot__img { will-change: auto; }
.reel__tile { overflow: hidden; }
/* tile hover effect: scale in the frame plus a one-pass shimmer sheen (a clip becomes a looping clip when published) */
@media (hover: hover) and (pointer: fine) {
  /* Scroll/tilt owns image transform and tile opacity/translate. A timed hover
     transition on those properties chases the previous pose on every reversal. */
  .reel__tile .shot__img { transition: filter 450ms var(--ease-out); }
  .reel__tile:hover .shot__img { transform: scale(1.22); filter: saturate(1.12) brightness(1.06); }
  .reel__tile::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0; transform: translateX(-120%); background: linear-gradient(105deg, rgba(255, 238, 214, 0) 32%, rgba(255, 238, 214, 0.26) 50%, rgba(255, 238, 214, 0) 68%); }
  .reel__tile:hover::after { opacity: 1; transform: translateX(120%); transition: transform 900ms var(--ease-out), opacity 160ms var(--ease-out); }
}
.reel__tile:focus-visible { outline-offset: 2px; }
.reel__tile--1 { grid-area: t1; } .reel__tile--2 { grid-area: t2; } .reel__tile--3 { grid-area: t3; } .reel__tile--4 { grid-area: t4; }
.reel__tile--5 { grid-area: t5; } .reel__tile--6 { grid-area: t6; } .reel__tile--7 { grid-area: t7; } .reel__tile--8 { grid-area: t8; }
.reel__tile--9 { grid-area: t9; } .reel__tile--10 { grid-area: t10; } .reel__tile--11 { grid-area: t11; } .reel__tile--12 { grid-area: t12; }
.reel__cell { grid-area: c; }
.reel__note { width: 100%; max-width: 1440px; margin: 0 auto; font: 850 clamp(1.6rem, 3.75vw, 4.2rem)/1.18 var(--display); font-stretch: 100%; letter-spacing: -0.035em; text-wrap: balance; }
.reel__letter { position: relative; width: 100%; height: 100%; min-width: 0; display: grid; align-content: center; padding: 140px var(--gutter); transform-origin: center; }
.reel__letter-copy { position: absolute; pointer-events: none; }
.reel__letter-copy .word { transition: none; }
.reel__sentence { display: block; }
.reel__rsvp { position: absolute; inset: var(--note-top, 0) auto auto var(--note-left, 0); width: var(--note-width, 100%); height: var(--note-height, 100%); display: grid; place-items: center; opacity: 0; visibility: hidden; }
.reel__rsvp .rsvp-box { width: min(420px, 88%); pointer-events: auto; text-shadow: none; }
.reel__title.is-contracting .word { transition: none; }
/* The letter over the grid: each word is invisible until its turn, then rises into place (a scroll-triggered
   transition, so a word can also leave again when scrolling back). The greeting opens the letter, the name in molten. */
.reel__greeting { position: absolute; top: calc(var(--topbar-h) + 7vh); left: var(--gutter); margin: 0; font: 900 clamp(3.5rem, 14.5vw, 15rem)/.86 var(--display); font-stretch: 100%; letter-spacing: -.025em; text-align: left; color: var(--molten); }
.reel__greeting .word--name { padding: 0; background: transparent; text-decoration: none; }
.reel__note .word, .reel__greeting .word { display: inline-block; color: var(--note-ink); opacity: 0; filter: blur(9px); transition: none; }
.reel__note .word.is-lit, .reel__greeting .word.is-lit { color: var(--note-ink); opacity: 1; filter: none; }
.reel__greeting .word.word--name, .reel__greeting .word.word--name.is-lit { color: var(--molten); }
/* One readable letter travels through a bounded aperture, not over the grid. */
/* WebKit applies align-content to block containers too. Do not inherit the
   old single-screen letter's centring: it puts a long letter above its aperture. */
.reel__letter:has(.reel__reading) { position: absolute; top: calc(var(--topbar-h) + 7vh); bottom: calc(var(--dock-clear) + 4vh); height: auto; padding: 0 var(--gutter); display: block; align-content: start; overflow: hidden; mask-image: linear-gradient(transparent, #000 32px, #000 calc(100% - 24px), transparent); }
.reel__reading { position: relative; padding-block: 24px 4vh; will-change: transform; }
.reel__reading .reel__greeting { position: relative; top: auto; left: auto; margin: 0 0 6vh; }
.reel__reading .reel__passage { margin-bottom: 14vh; }
.reel__reading .reel__passage:last-child { margin-bottom: 0; }
@media (prefers-reduced-motion: reduce) { .reel__reading { will-change: auto; } }
.reel__title {
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-content: center; padding: 0 var(--gutter);
  color: #f6f1e9; pointer-events: none; text-align: center;
  font: 900 clamp(4rem, 11vw, 11rem)/0.84 var(--display); font-stretch: 125%; letter-spacing: -0.03em; text-transform: uppercase;
  text-shadow: 0 2px 50px rgba(0, 0, 0, 0.35);
  opacity: 0; visibility: hidden;
}
/* Over the photographs the letter is bone on a soft dark pool. As the scroll-out clears the photographs from behind it
   (main.js sets --bare from how much of the letter they still cover) the pool fades and the ink turns to the page's
   text colour, so on the light ground the letter stays readable instead of sitting in a grey smudge. */
.reel__title.reel__title--note {
  --bare: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  display: block;
  --note-ink: color-mix(in srgb, #f6f1e9, var(--text) calc(var(--bare) * 100%));
  font: 400 16px/1.2 var(--text-font); font-stretch: normal; text-transform: none; letter-spacing: 0;
  text-shadow: 0 2px 30px rgba(0, 0, 0, calc(0.5 * (1 - var(--bare))));
}
.reel__shade {
  position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0;
  background: radial-gradient(64% 60% at 50% 50%, rgba(7, 6, 5, 0.8), rgba(7, 6, 5, 0.42) 70%, rgba(7, 6, 5, 0) 100%);
}
/* A moving film must not share raster tiles with the resolving letter or dark
   pool. Keep their surfaces stable at opacity 1 as well as during the fades. */
.reel__title--note, .reel__shade { isolation: isolate; }
.stage--ascent.is-compositing .reel__title--note { will-change: transform, opacity; }
.stage--ascent.is-compositing .reel__shade { will-change: opacity; }
/* The scroll clock owns these transforms. A timed transition would chase stale
   values on every frame and lurch when the user reverses. Hover colours remain. */
.arrival .arrival__label { transition: color 180ms ease; }
.arrival .rsvp-box { transition: background-color 200ms ease; }


/* ---------- depth on photographs ---------- */
.photo-ambient { position: absolute; inset: 0; object-position: inherit; transform-origin: center; }
.photo-ambient > img { width: 100%; height: 100%; object-fit: cover; object-position: inherit; }
.photo-life { position: absolute; z-index: 1; pointer-events: none; overflow: hidden; mix-blend-mode: screen; opacity: 0; }
.photo-life.is-active { transition: opacity 1000ms ease; }
.photo-life--batched > :not(.photo-life__batch) { display: none; }
.photo-life__batch { display: block; width: 100%; height: 100%; }
.photo-life i { position: absolute; display: block; border-radius: 50%; background: radial-gradient(circle, rgba(var(--light),1) 8%, rgba(var(--light),.6) 25%, transparent 70%); translate: -50% -50%; animation: photo-window 8s ease-in-out infinite; animation-play-state: paused; }
.photo-life.is-living i { animation-play-state: running; }
.photo-life .photo-life__exposure { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; opacity: 0; animation: photo-exposure 6s ease-in-out infinite; animation-play-state: paused; }
.photo-life.is-living .photo-life__exposure { animation-play-state: running; }
.photo-life .photo-life__emitter { position: absolute; max-width: none; object-fit: fill; opacity: .12; animation: photo-emitter 8s ease-in-out infinite; animation-play-state: paused; }
.photo-life.is-living .photo-life__emitter { animation-play-state: running; }
.photo-life .photo-life__emitter--beam { filter: blur(1px); }
@keyframes photo-emitter { 0%,100% { opacity: .12; } 42%,58% { opacity: .95; } }
.photo-life--arrival .photo-life__exposure { animation-name: photo-arrival-exposure; }
@keyframes photo-arrival-exposure { 0%,100% { opacity: .12; } 45%,55% { opacity: .32; } }
@keyframes photo-exposure { 0%,100% { opacity: .05; } 35%,52% { opacity: .9; } 72% { opacity: .18; } }
.photo-life .photo-life__lamp { animation-name: photo-lamp; }
.photo-life .photo-life__office { min-width: 1.5px; border-radius: 0; background: #ffe0a0; box-shadow: 0 0 3px rgba(255,210,130,.45); animation-duration: 14s; }
.photo-life .photo-life__beam { translate: -50% 0; transform-origin: 50% 0; border-radius: 0; background: radial-gradient(ellipse at 50% 0, rgba(255,210,130,.6), rgba(255,196,115,.12) 48%, transparent 72%); clip-path: polygon(48% 0,52% 0,100% 100%,0 100%); animation-name: photo-beam; }
.photo-life .photo-life__car { min-width: 2px; background: #fff4d9; box-shadow: 0 0 4px 1px rgba(255,220,180,.6); animation-name: photo-traffic; animation-timing-function: linear; }
.photo-life__car::after { content: ""; position: absolute; top: 20%; right: 20%; width: 350%; height: 60%; transform-origin: right center; transform: rotate(var(--road-angle)); background: linear-gradient(90deg, transparent, rgba(255,235,198,.55)); }
.photo-life .photo-life__car--tail { background: #ff7657; box-shadow: 0 0 4px 1px rgba(255,90,50,.6); }
.photo-life__car--tail::after { background: linear-gradient(90deg, transparent, rgba(255,90,55,.55)); }
@keyframes photo-window { 0%,100% { opacity:.12; } 26% { opacity:.35; } 42%,57% { opacity:1; } 77% { opacity:.18; } }
@keyframes photo-lamp { 0%,100% { opacity:.3; } 35% { opacity:.85; } 67% { opacity:.45; } }
@keyframes photo-beam { 0%,100% { opacity:.2; transform:rotate(-2deg); } 45% { opacity:.55; transform:rotate(2deg); } }
@keyframes photo-traffic { 0% { transform:translate(0,0); opacity:0; } 8%,90% { opacity:1; } 100% { transform:translate(var(--travel-x),var(--travel-y)); opacity:0; } }
@media (prefers-reduced-motion: reduce) { .photo-life { display: none; } }
.rsvp-cinematic { position: relative; isolation: isolate; overflow: hidden; }
.rsvp-cinematic > * { position: relative; z-index: 1; }
.rsvp-cinematic::before { content: ""; position: absolute; inset: -1px; z-index: 0; background: var(--black); clip-path: polygon(0 0, 0 0, 0 100%, 0 100%); transition: clip-path 280ms var(--ease-in-out); }
.rsvp-cinematic::after { content: ""; position: absolute; inset: -35% -15%; z-index: 2; pointer-events: none; background: linear-gradient(110deg, transparent 44%, rgba(255,244,226,.5) 49%, transparent 54%); transform: translateX(-110%); transition: transform 280ms var(--ease-in-out); }
.rsvp-roll { display: inline-flex; vertical-align: middle; line-height: 1.1; }
.rsvp-roll__cell { overflow: hidden; display: inline-block; }
.rsvp-roll__char { position: relative; display: inline-block; transition: transform 240ms var(--ease-out); }
.rsvp-roll__char::after { content: attr(data-echo); position: absolute; left: 0; top: 100%; color: var(--molten); }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .rsvp-cinematic:hover::before { clip-path: polygon(0 0, 110% 0, 100% 100%, 0 100%); }
  .rsvp-cinematic:hover::after { transform: translateX(110%); }
  .rsvp-cinematic:hover .rsvp-roll__char { transform: translateY(-100%); }
  .rsvp-cinematic:hover .rsvp-box__meta { color: var(--bone); }
  .rsvp-cinematic:hover > .icon, .rsvp-cinematic:hover .rsvp-arrow { color: var(--molten); }
  .rsvp-cinematic:hover .rsvp-arrow svg:first-child { transform: translate(140%, -140%); }
  .rsvp-cinematic:hover .rsvp-arrow svg:last-child { transform: translate(0, 0); }
}
.rsvp-arrow { display: inline-grid; overflow: hidden; }
.rsvp-cinematic .rsvp-arrow svg { grid-area: 1 / 1; width: 100%; height: 100%; transition: transform 280ms var(--ease-out); }
.rsvp-arrow svg:last-child { transform: translate(-140%, 140%); }
.rsvp-cinematic:focus-visible { outline: 2px solid var(--bone); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) {
  .rsvp-cinematic::before, .rsvp-cinematic::after { display: none; }
  .rsvp-roll__char { transition: none; }
}

.shot { position: relative; aspect-ratio: var(--ar); perspective: 900px; margin: 0; }
.shot--fill { aspect-ratio: auto; width: 100%; height: 100%; }
.shot__tilt {
  position: relative; width: 100%; height: 100%;
  overflow: hidden; background: var(--ground-3);
  transform-style: preserve-3d; will-change: transform;
}
.shot__img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.14); will-change: transform; }
.shot__sheen {
  position: absolute; inset: -40%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(255, 244, 228, 0.42), rgba(255, 244, 228, 0) 45%);
  mix-blend-mode: soft-light; opacity: 0.18;
}

/* ---------- section mount points: minimal readable fallbacks (modules replace these) ---------- */

.mount { position: relative; background: var(--ground); }
.mount[data-module="fallback"], .mount:not([data-module]) { padding: var(--section) var(--gutter); }
.mount--gallery-scrollout:not([data-module]), .mount--gallery-scrollout[data-module="fallback"] { padding: 0; }
.fallback__title { font: 900 clamp(2.6rem, 6.4vw, 5.5rem)/0.92 var(--display); letter-spacing: -0.025em; margin-bottom: clamp(28px, 4vw, 56px); max-width: 16ch; }
.fallback__lead { max-width: 30ch; font: 750 clamp(1.8rem, 4vw, 3.6rem)/1.08 var(--display); letter-spacing: -0.02em; }
.fallback__sign { margin-top: 24px; font: 800 20px/1 var(--display); font-stretch: 125%; }
.fallback__list { display: grid; gap: 0; max-width: 980px; }
.fallback__row { display: grid; grid-template-columns: minmax(120px, 0.35fr) 1fr; gap: 24px; padding: 28px 0; box-shadow: inset 0 1px 0 var(--line); }
.fallback__time { font: 850 clamp(1.4rem, 2.4vw, 2rem)/1 var(--display); color: var(--molten); }
.fallback__name { font: 850 clamp(1.6rem, 3vw, 2.4rem)/1 var(--display); letter-spacing: -0.015em; }
.fallback__body { margin-top: 10px; color: var(--muted); max-width: 52ch; }
.fallback__body--wide { max-width: 60ch; margin: 0 0 28px; }
.fallback__detail { margin-top: 10px; font-size: 15px; }
.fallback__detail span, .fallback__label { font-weight: 700; color: var(--molten); }
.fallback__columns { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(24px, 4vw, 64px); }
.fallback__columns article { padding-top: 22px; box-shadow: inset 0 1px 0 var(--line-strong); }
.fallback__columns .fallback__name { margin-top: 10px; }
.fallback__columns .fallback__body { margin-top: 6px; }
.fallback__links { display: grid; max-width: 760px; }
.fallback__links a { display: flex; align-items: center; gap: 14px; padding: 22px 0; box-shadow: inset 0 1px 0 var(--line); text-decoration: none; font: 800 clamp(1.3rem, 2.4vw, 2rem)/1.1 var(--display); }
.fallback__links a .icon:last-child { margin-left: auto; }
.fallback__index { font: 600 15px/1 var(--text-font); color: var(--muted); min-width: 7rem; }
.fallback__faq { max-width: 880px; }
.fallback__faq details { box-shadow: inset 0 1px 0 var(--line); }
.fallback__faq summary { display: flex; justify-content: space-between; gap: 24px; padding: 24px 0; cursor: pointer; list-style: none; font: 750 clamp(1.2rem, 2.2vw, 1.6rem)/1.2 var(--display); }
.fallback__faq summary::-webkit-details-marker { display: none; }
.fallback__faq details[open] summary .icon { transform: rotate(45deg); }
.fallback__faq p { padding: 0 0 24px; color: var(--muted); max-width: 62ch; }
.mount--close[data-module="fallback"], .mount--close:not([data-module]) { position: relative; min-height: 100svh; display: grid; align-items: end; padding: 0; overflow: hidden; background: var(--black); color: var(--bone); }
.fallback__close-media { position: absolute; inset: 0; }
.fallback__close-media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(7, 6, 5, 0.9), rgba(7, 6, 5, 0.15) 60%); }
.fallback__close-copy { position: relative; display: grid; justify-items: start; gap: 32px; padding: var(--section) var(--gutter) var(--dock-clear); }
.fallback__close-title { font: 900 clamp(3.4rem, 11vw, 10rem)/0.86 var(--display); font-stretch: 125%; letter-spacing: -0.03em; text-transform: uppercase; }
.fallback__close-title span { display: block; }
.fallback__close-title span + span { font-weight: 250; color: var(--molten); }
.mount--footer[data-module="fallback"], .mount--footer:not([data-module]) { padding: clamp(40px, 6vw, 88px) var(--gutter) var(--dock-clear); overflow: hidden; }
.fallback__word { font: 900 clamp(6rem, 26vw, 26rem)/0.78 var(--display); font-stretch: 125%; letter-spacing: -0.04em; text-transform: uppercase; }
.fallback__footrow { display: flex; flex-wrap: wrap; gap: 10px 32px; margin-top: 28px; padding-top: 20px; box-shadow: inset 0 1px 0 var(--line); color: var(--muted); font-size: 15px; }
.fallback__footrow a { margin-left: auto; color: var(--text); font-weight: 600; text-decoration: none; display: inline-flex; gap: 8px; align-items: center; }
.word { color: var(--muted); opacity: 0.35; transition: opacity 260ms ease, color 260ms ease; }
.word.is-lit { color: var(--text); opacity: 1; }

/* ---------- effects layer ---------- */

.fx { position: fixed; inset: 0; z-index: 60; width: 100%; height: 100%; pointer-events: none; mix-blend-mode: screen; }
:root[data-theme="light"] .fx { opacity: 0.55; }
body::after {
  content: ""; position: fixed; inset: -60px; z-index: 61; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.4 -0.35'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.06; mix-blend-mode: overlay;
  animation: grain 0.9s steps(6) infinite;
}
:root[data-theme="light"] body::after { opacity: 0.1; }
@keyframes grain {
  0% { transform: translate(0, 0); } 17% { transform: translate(-38px, 22px); } 33% { transform: translate(24px, -40px); }
  50% { transform: translate(-16px, 46px); } 67% { transform: translate(42px, 12px); } 83% { transform: translate(-28px, -26px); } 100% { transform: translate(0, 0); }
}

/* ---------- dock: RSVP is always one tap away ---------- */

.dock {
  --dock-x: -50%;
  position: fixed; z-index: 80; left: 50%; bottom: max(14px, env(safe-area-inset-bottom));
  width: min(560px, calc(100vw - 24px)); height: var(--dock-h); translate: var(--dock-x) 0;
  display: grid; grid-template-columns: 1.3fr 1fr 1fr;
  color: var(--bone);
  transition: opacity 240ms ease, translate 280ms var(--ease-out);
}
/* The dock's ground is a layer of its own so it can narrow with a transform when the RSVP segment yields. */
.dock::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--black);
  box-shadow: 0 0 0 1px rgba(239, 233, 223, 0.16), 0 18px 40px rgba(0, 0, 0, 0.35);
  transform-origin: right center;
  transition: transform 280ms var(--ease-out);
}
/* One RSVP at a time: while an in-page RSVP is on screen, the dock's RSVP slides out through the bottom edge,
   the ground narrows to the two remaining segments (1 − 1.3/3.3 of the width) and the dock re-centres on them. */
.dock--yield { --dock-x: calc(-50% - 19.697%); }
.dock--yield::before { transform: scaleX(0.60606); }
.dock--yield .dock__item--rsvp { transform: translateY(calc(100% + 24px)); opacity: 0; pointer-events: none; }
.is-loading .dock { opacity: 0; translate: var(--dock-x) 16px; pointer-events: none; }
.dock__item { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 0 14px; background: transparent; border: 0; cursor: pointer; font: 600 15px/1 var(--text-font); text-decoration: none; white-space: nowrap; box-shadow: inset 1px 0 0 rgba(239, 233, 223, 0.14); transition: background-color 200ms ease, color 200ms ease; }
.dock__item--rsvp { justify-content: space-between; padding: 0 16px 0 18px; background: var(--molten); color: var(--black); box-shadow: none; transition: background-color 200ms ease, color 200ms ease, transform 280ms var(--ease-out), opacity 200ms var(--ease-out); }
/* over a molten field (the calendar section) the RSVP turns bone so it keeps its edge; colour only, no movement */
.dock--on-molten .dock__item--rsvp { background: var(--bone); color: var(--black); }
.dock__rsvp { font: 900 17px/1 var(--display); font-stretch: 125%; letter-spacing: 0.02em; text-transform: uppercase; }
.dock__arrow .icon { width: 20px; height: 20px; }
.dock__item:not(.dock__item--rsvp) { position: relative; isolation: isolate; overflow: hidden; transition: color 180ms ease, transform 140ms var(--ease-out); }
.dock__item:not(.dock__item--rsvp)::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--bone); transform: translateY(102%); transition: transform 240ms var(--ease-out); }
.dock__item:not(.dock__item--rsvp):focus-visible { outline: 2px solid var(--molten); outline-offset: 3px; color: var(--molten); }
.dock__item:not(.dock__item--rsvp):active { transform: translateY(2px); color: var(--black); }
.dock__item:not(.dock__item--rsvp):active::before,
.dock__item[aria-expanded="true"]::before { transform: none; }
.dock__item[aria-expanded="true"] { color: var(--black); }
@media (prefers-reduced-motion: reduce) { .dock__item:not(.dock__item--rsvp), .dock__item:not(.dock__item--rsvp)::before { transition: none; } }
@media (max-width: 760px) { :root { --chapter-size: clamp(3.3rem, 16vw, 7rem); } }
@media (hover: hover) and (pointer: fine) {
  .dock__item:not(.dock__item--rsvp):hover { color: var(--black); opacity: 1; }
  .dock__item:not(.dock__item--rsvp):hover::before { transform: none; }
  .dock__item--rsvp:hover { background: var(--molten-hover); }
  .dock--on-molten .dock__item--rsvp:hover { background: color-mix(in srgb, var(--bone) 70%, #fff); }
}
.has-dialog .dock { opacity: 0; translate: var(--dock-x) 16px; pointer-events: none; }

/* Eight static, progressively stronger backdrop layers; dock stays above them. */
.viewport-bottom-blur { position: fixed; z-index: 19; pointer-events: none; bottom: 0; left: 0; width: 100%; height: clamp(108px, 22vh, 200px); }
.viewport-bottom-blur > span { position: absolute; inset: 0; pointer-events: none; backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur)); mask-image: linear-gradient(transparent var(--from), #000 var(--to)); -webkit-mask-image: linear-gradient(transparent var(--from), #000 var(--to)); }
.viewport-bottom-blur > span:nth-child(1) { --blur: 0.3px; --from: 0.0%; --to: 8.75%; }
.viewport-bottom-blur > span:nth-child(2) { --blur: 1.3px; --from: 8.75%; --to: 17.5%; }
.viewport-bottom-blur > span:nth-child(3) { --blur: 2.8px; --from: 17.5%; --to: 26.25%; }
.viewport-bottom-blur > span:nth-child(4) { --blur: 5px; --from: 26.25%; --to: 35.0%; }
.viewport-bottom-blur > span:nth-child(5) { --blur: 7.8px; --from: 35.0%; --to: 43.75%; }
.viewport-bottom-blur > span:nth-child(6) { --blur: 11.3px; --from: 43.75%; --to: 52.5%; }
.viewport-bottom-blur > span:nth-child(7) { --blur: 15.3px; --from: 52.5%; --to: 61.25%; }
.viewport-bottom-blur > span:nth-child(8) { --blur: 20px; --from: 61.25%; --to: 70.0%; }
@media (prefers-reduced-motion: reduce) { .viewport-bottom-blur { display: none; } }

/* ---------- Directions menu: springs up out of the dock's Directions segment ---------- */

.routes {
  position: fixed; inset: auto auto var(--routes-bottom, 96px) var(--routes-left, 12px);
  width: var(--routes-width, 360px); max-width: calc(100vw - 16px); margin: 0; padding: 4px 0 0;
  border: 0; overflow: visible;
  background: var(--sheet-bg); color: var(--sheet-text);
  box-shadow: 0 0 0 1px var(--sheet-line), 0 28px 64px -18px rgba(7, 6, 5, 0.6);
  transform-origin: var(--routes-origin, 50%) 100%;
  opacity: 0; transform: translateY(18px) scale(0.94);
  transition: opacity 220ms var(--ease-out), transform 260ms var(--ease-in-out), overlay 260ms allow-discrete, display 260ms allow-discrete;
}
.routes:popover-open {
  opacity: 1; transform: none;
  transition: opacity 240ms var(--ease-out), transform 420ms cubic-bezier(0.16, 1, 0.3, 1), overlay 420ms allow-discrete, display 420ms allow-discrete;
}
@starting-style { .routes:popover-open { opacity: 0; transform: translateY(12px) scale(0.94); } }
.routes.is-open { opacity: 1; transform: none; }
.routes.routes--directed, .routes.routes--directed .routes__list li { transition: none; }
.routes.routes--directed .routes__list li { opacity: 1; transform: none; }
.routes[data-motion="running"] :is(.routes__label, .routes__row > .icon) { transition: none; }
.routes::backdrop { background: transparent; }
.routes__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 2px 4px 4px 18px; }
.routes__title { display: flex; align-items: center; gap: 8px; min-width: 0; font: 600 14px/1.25 var(--text-font); color: var(--sheet-muted); }
.routes__title .icon { width: 18px; height: 18px; color: var(--molten); }
.routes__list { margin: 0; padding: 0; list-style: none; }
.routes__list li { opacity: 0; transform: translateY(10px); transition: opacity 160ms var(--ease-out), transform 180ms var(--ease-out); transition-delay: calc((2 - var(--i, 0)) * 30ms); }
.routes:popover-open .routes__list li, .routes.is-open .routes__list li {
  opacity: 1; transform: none;
  transition: opacity 280ms var(--ease-out), transform 380ms var(--ease-out); transition-delay: calc(90ms + var(--i, 0) * 50ms);
}
@starting-style { .routes:not(.routes--directed):popover-open .routes__list li { opacity: 0; transform: translateY(10px); } }
/* GSAP owns the content build/drop. The legacy CSS row delay must not add a
   second 570ms entrance underneath the piece-level animation. */
.routes.routes--directed:is(:popover-open,.is-open) .routes__list li { opacity: 1; transform: none; transition: none; }
.routes__row {
  display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: center; gap: 12px;
  width: 100%; min-height: 60px; padding: 8px 16px 8px 14px;
  background: transparent; border: 0; color: inherit; text-align: left; text-decoration: none;
  font: 600 16px/1.2 var(--text-font); cursor: pointer;
  box-shadow: inset 0 1px 0 var(--sheet-line);
  transition: background-color 180ms ease, color 180ms ease;
  -webkit-tap-highlight-color: transparent;
}
.routes__row > .icon { width: 20px; height: 20px; color: var(--sheet-muted); transition: transform 220ms var(--ease-out), color 180ms ease; }
.routes__row:active { background: color-mix(in srgb, var(--sheet-text) 9%, transparent); }
.routes__row:active .routes__label { transform: scale(0.98); }
.routes__label { transform-origin: 0 50%; transition: transform 120ms var(--ease-out); }
.routes__logo { display: grid; place-items: center; width: 52px; height: 40px; }
.routes__logo img { display: block; max-width: 100%; }
.routes__logo--grab img { width: 46px; height: auto; }
.routes__logo--google-maps img { width: auto; height: 32px; }
.routes__logo--waze img { width: 30px; height: 30px; }
:root:not([data-theme="light"]) .routes__logo--grab img { filter: brightness(0) invert(1); } /* Grab's rule: white mark on dark */
@media (hover: hover) and (pointer: fine) {
  .routes__row:hover { background: color-mix(in srgb, var(--sheet-text) 6%, transparent); }
  .routes__row:hover > .icon { color: var(--molten); transform: translate(2px, -2px); }
}
.dock__item[aria-expanded="true"] { background: #1b1815; }

/* ---------- sheets ---------- */

dialog { padding: 0; border: 0; max-width: none; max-height: none; color: var(--sheet-text); }
dialog::backdrop { background: rgba(7, 6, 5, 0.66); }
/* Only the optional dialog polyfill creates these siblings. Its stacking and
   focus manager owns their lifetime; the selected drawer animation is unchanged. */
dialog + .backdrop { position: fixed; inset: 0; background: rgba(7, 6, 5, 0.66); }
._dialog_overlay { position: fixed; inset: 0; }
dialog:not([open]) { display: none; }
.startup-error { padding: max(120px, 20vh) var(--gutter, 24px); }
.startup-error p { margin: 24px 0; }
.sheet {
  position: fixed; inset: 0 0 0 auto; margin: 0;
  width: min(540px, 100vw); height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  background: var(--sheet-bg); box-shadow: -1px 0 0 var(--sheet-line);
  transform: translateX(100%);
  transition: transform 460ms var(--ease-drawer), overlay 460ms allow-discrete, display 460ms allow-discrete;
}
.sheet[open] { transform: none; }
.sheet.sheet--directed { transition: none !important; }
.sheet.sheet--directed[open] { transform: none; }
@starting-style { .sheet.sheet--directed[open] { transform: none; } }
/* Author `display: flex` overrides the UA's closed-dialog `display: none`; restore it so a closed sheet never
   intercepts clicks (under reduced motion it is only faded out, not moved off-screen). The discrete display
   transition above still lets the exit animation finish before it hides. */
.sheet:not([open]) { display: none; }
@starting-style { .sheet[open] { transform: translateX(100%); } }
.sheet__bar { display: flex; align-items: center; justify-content: space-between; padding: 10px 10px 10px clamp(20px, 5vw, 40px); box-shadow: inset 0 -1px 0 var(--sheet-line); }
.sheet__bar--end { justify-content: flex-end; }
.menu__back { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; margin-right: auto; padding: 0 8px; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.menu__back[hidden] { display: none; }
.menu__back:focus-visible { outline: 2px solid var(--molten); outline-offset: 2px; }
.menu__back:active { transform: translateX(-2px); }
@media (hover: hover) and (pointer: fine) { .menu__back:hover { color: var(--molten); } }
.sheet__kicker { display: flex; align-items: center; gap: 10px; font: 700 12px/1 var(--text-font); letter-spacing: 0.18em; text-transform: uppercase; }
.sheet__kicker::before { content: ""; width: 6px; height: 6px; background: var(--molten); }
.sheet__body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: clamp(28px, 5vw, 44px) clamp(20px, 5vw, 40px) calc(48px + env(safe-area-inset-bottom)); }
.sheet__title { font: 900 clamp(2.9rem, 10vw, 4.4rem)/0.9 var(--display); letter-spacing: -0.025em; outline: none; }
.sheet__guest { margin-top: 18px; font-size: 15px; font-weight: 600; }
.sheet__intro { margin-top: 14px; color: var(--sheet-muted); font-size: 17px; }
.sheet__lead { font: 850 clamp(1.9rem, 6vw, 2.5rem)/1 var(--display); letter-spacing: -0.02em; }
.sheet__foot { margin-top: 36px; font-size: 15px; color: var(--sheet-muted); }
.sheet__foot a { color: var(--sheet-text); font-weight: 600; }
.tag { display: inline-block; vertical-align: 0.12em; margin-left: 6px; padding: 3px 7px 2px; font: 600 12px/1.2 var(--text-font); letter-spacing: 0.02em; box-shadow: inset 0 0 0 1px currentColor; }

.form { margin-top: 12px; }
.field { display: grid; gap: 6px; margin-top: 26px; }
.field[hidden], .form__attending[hidden] { display: none; }
.field label, .choice legend, .plusone legend { font-size: 15px; font-weight: 600; color: var(--sheet-text); }
.field input, .field textarea {
  width: 100%; padding: 12px 0 11px; background: transparent; color: var(--sheet-text);
  border: 0; border-bottom: 1px solid var(--line-strong); border-radius: 0;
  font: 400 17px/1.4 var(--text-font); transition: border-color 200ms ease;
}
.field textarea { resize: vertical; min-height: 88px; }
.field input::placeholder, .field textarea::placeholder { color: var(--sheet-muted); opacity: 0.9; }
.field input:focus-visible, .field textarea:focus-visible { outline: none; border-bottom: 2px solid var(--molten); padding-bottom: 10px; }
.field input[aria-invalid="true"] { border-bottom-color: var(--molten); }
.field__row { display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: end; }
.field__hint { font-size: 14px; color: var(--sheet-muted); margin-top: 4px; }
.field__error { display: flex; gap: 8px; align-items: center; margin-top: 14px; font-size: 15px; font-weight: 600; color: #ff8a55; }
.field__error .icon { width: 20px; height: 20px; }
:root[data-theme="light"] .field__error { color: #b53400; }
.choice, .plusone { border: 0; padding: 0; margin: 30px 0 0; min-width: 0; }
.choice { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.choice legend { grid-column: 1 / -1; margin-bottom: 12px; padding: 0; }
.choice__option { position: relative; }
.choice__option input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.choice__option span { display: flex; align-items: center; justify-content: center; min-height: 66px; padding: 0 12px; box-shadow: inset 0 0 0 1px var(--line-strong); font: 850 19px/1.1 var(--display); text-align: center; transition: background-color 200ms ease, color 200ms ease, box-shadow 200ms ease; }
.choice__option input:checked + span { background: var(--molten); color: var(--black); box-shadow: none; }
.choice__option input:focus-visible + span { outline: 2px solid var(--molten); outline-offset: 3px; }
.plusone legend { padding: 0; margin-bottom: 6px; }
.toggle { position: relative; display: grid; grid-template-columns: 30px 1fr; gap: 14px; align-items: start; margin-top: 16px; font-size: 16px; line-height: 1.4; cursor: pointer; }
.toggle input { position: absolute; opacity: 0; width: 30px; height: 30px; margin: 0; cursor: pointer; }
.toggle__box { display: grid; place-items: center; width: 30px; height: 30px; box-shadow: inset 0 0 0 1px var(--line-strong); color: transparent; transition: background-color 160ms ease, color 160ms ease, box-shadow 160ms ease; }
.toggle__box .icon { width: 18px; height: 18px; }
.toggle input:checked + .toggle__box { background: var(--molten); color: var(--black); box-shadow: none; }
.toggle input:focus-visible + .toggle__box { outline: 2px solid var(--molten); outline-offset: 3px; }
.form__privacy { margin-top: 22px; font-size: 14px; color: var(--sheet-muted); }
.form__foot { display: grid; gap: 10px; margin-top: 34px; }
.form__foot .btn--text { justify-self: start; padding: 0; }
.form__saved { min-height: 20px; font-size: 14px; color: var(--sheet-muted); }

.pass { container-type: inline-size; display: grid; gap: 16px; padding: 0 22px 22px; margin-bottom: 28px; background: var(--molten); color: var(--black); }
.pass__strip { display: flex; justify-content: space-between; gap: 12px; margin: 0 -22px; padding: 10px 22px; background: var(--black); color: var(--bone); font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.14em; }
.pass__strip .mono { letter-spacing: 0; text-transform: none; }
.pass__mark { margin-top: 8px; font: 900 13.5cqi/0.8 var(--display); font-stretch: 125%; letter-spacing: -0.03em; }
.pass__status { font: 800 20px/1 var(--display); font-stretch: 125%; text-transform: uppercase; }
.pass__guest { font-size: 17px; font-weight: 600; }
.tag--ink { box-shadow: inset 0 0 0 1px var(--black); }
.pass__facts { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding-top: 16px; box-shadow: inset 0 1px 0 rgba(7, 6, 5, 0.3); }
.pass__facts dt { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: rgba(7, 6, 5, 0.74); }
.pass__facts dt .icon { width: 16px; height: 16px; }
.pass__facts dd { margin-top: 4px; font: 800 20px/1.15 var(--display); }
.pass__facts dd span { font: 500 15px/1.4 var(--text-font); }
.pass__actions { margin-top: 26px; }
.pass__action { display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 12px; padding: 16px 0; text-decoration: none; font-weight: 600; box-shadow: inset 0 1px 0 var(--sheet-line); }
.pass__action .icon { width: 22px; height: 22px; }

.night-facts { display: grid; gap: 12px; margin: 24px 0 28px; }
.night-facts li { display: flex; align-items: center; gap: 12px; font: 750 clamp(1.2rem, 4vw, 1.45rem)/1.15 var(--display); }
.night-facts .icon { width: 22px; height: 22px; color: var(--molten); }
.concierge__list { box-shadow: inset 0 -1px 0 var(--sheet-line); }
.concierge__celebration { grid-column: 1 / -1; margin: 0; padding-bottom: 16px; border-bottom: 1px solid var(--sheet-line); font: 400 22px/1.3 var(--display); letter-spacing: -.025em; color: var(--sheet-text); white-space: nowrap; }
@media (max-width: 420px) { .concierge__celebration { margin-inline: -8px; } }
.concierge__occasion { display: grid; grid-template-columns: minmax(88px, 0.7fr) minmax(0, 1.7fr); gap: clamp(20px, 4vw, 40px); align-items: center; padding-block: 12px 20px; margin-block: 8px 20px; border-bottom: 1px solid var(--sheet-line); }
.concierge__date { display: grid; gap: 8px; text-align: center; font-size: 14px; color: var(--sheet-muted); }
.concierge__date strong { font: 900 clamp(4rem, 9vw, 6rem)/0.9 var(--display); font-stretch: 125%; letter-spacing: -0.04em; color: var(--molten); }
.concierge__date span:first-child { text-transform: uppercase; letter-spacing: 0.1em; font-size: 12px; }
.concierge__details { display: grid; gap: 4px; }
.concierge__venue .icon { flex: none; width: 18px; height: 18px; color: var(--molten); }
.concierge__details .concierge__venue { justify-content: flex-start; gap: 8px; }
.concierge__outgoing { position: absolute; left: 0; right: 0; pointer-events: none; overflow: hidden; }
[data-concierge-body] { position: relative; z-index: 1; background: var(--sheet-bg, var(--ground)); }
.concierge__time { font: 800 clamp(1.5rem, 3.7vw, 2rem)/1.15 var(--display); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; white-space: nowrap; }
.concierge__venue { display: inline-flex; gap: 16px; justify-content: space-between; align-items: center; min-height: 44px; color: inherit; text-decoration: none; font-size: 16px; line-height: 1.5; }
.concierge__venue:focus-visible { outline: 2px solid var(--molten); outline-offset: 4px; }
@media (hover: hover) and (pointer: fine) { .concierge__venue:hover { color: var(--molten); } }
.concierge__group { margin-block: 28px; }
.concierge__heading { margin-bottom: 10px; font: 750 14px/1.3 var(--text-font); color: var(--sheet-muted); }
.concierge__row[type="button"] { width: 100%; border: 0; background: none; color: inherit; text-align: left; cursor: pointer; }
.concierge__row { display: grid; grid-template-columns: 44px 1fr auto auto; align-items: center; gap: 14px; padding: 14px 0; text-decoration: none; box-shadow: inset 0 1px 0 var(--sheet-line); transition: color 200ms ease; }
.concierge__icon { display: grid; place-items: center; width: 44px; height: 44px; box-shadow: inset 0 0 0 1px var(--sheet-line); }
.concierge__icon .icon { width: 22px; height: 22px; }
.concierge__title { font: 800 19px/1.1 var(--display); }
.concierge__note { font-size: 14px; color: var(--sheet-muted); }
.concierge__row > .icon { width: 20px; height: 20px; }
@media (hover: hover) and (pointer: fine) {
  .concierge__row:hover .concierge__icon { background: var(--molten); color: var(--black); box-shadow: none; }
}
.sheet--concierge .btn--wide { margin-top: 28px; }

.gallery {
  position: fixed; inset: 0; width: 100vw; height: 100vh; height: 100dvh; margin: 0;
  background: var(--black); color: var(--bone); flex-direction: column; opacity: 0;
  transition: opacity 240ms var(--ease-out), overlay 240ms allow-discrete, display 240ms allow-discrete;
}
.gallery[open] { display: flex; opacity: 1; }
@starting-style { .gallery[open] { opacity: 0; } }
.gallery__bar { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 16px; padding: 10px 10px 10px var(--gutter); }
.gallery__title { font: 900 22px/1 var(--display); font-stretch: 125%; }
.gallery__count { font-size: 14px; color: var(--bone-dim); }
.gallery__nav { display: flex; }
.gallery__track { flex: 1; min-height: 0; display: flex; align-items: center; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; padding: 0 var(--gutter) calc(20px + env(safe-area-inset-bottom)); scrollbar-width: thin; }
.gallery__item { flex: 0 0 min(80vw, 1080px); scroll-snap-align: center; display: grid; gap: 12px; }
/* These are non-interactive photographs, not hover targets. Keep their raster
   scale stable while browsing: repeated large-image zooms shimmer on fine detail. */
.gallery__frame { position: relative; overflow: hidden; cursor: default; }
.gallery__item img { display: block; width: 100%; max-height: 76dvh; aspect-ratio: 3 / 2; object-fit: cover; background: #1b1815; }
.gallery__item figcaption { font-size: 14px; color: var(--bone-dim); }

.toast { position: fixed; z-index: 120; left: 50%; bottom: calc(max(14px, env(safe-area-inset-bottom)) + 72px); translate: -50% 8px; padding: 12px 18px; background: var(--bone); color: var(--black); font-size: 15px; font-weight: 600; opacity: 0; pointer-events: none; transition: opacity 200ms var(--ease-out), translate 200ms var(--ease-out); }
.toast.is-visible { opacity: 1; translate: -50% 0; }

/* ---------- preview-only variant switcher ---------- */

.variants { position: fixed; z-index: 90; left: 12px; bottom: calc(max(14px, env(safe-area-inset-bottom)) + 4px); font: 500 13px/1.2 var(--text-font); color: var(--bone); }
.is-loading .variants, .has-dialog .variants { display: none; }
.variants__toggle { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 12px; border: 0; background: rgba(18, 15, 12, 0.86); box-shadow: inset 0 0 0 1px rgba(239, 233, 223, 0.22); cursor: pointer; font-size: 13px; }
.variants__toggle .icon { width: 16px; height: 16px; }
.variants__panel { position: absolute; left: 0; bottom: calc(100% + 8px); width: 236px; padding: 14px; background: #120f0c; box-shadow: inset 0 0 0 1px rgba(239, 233, 223, 0.22), 0 18px 40px rgba(0, 0, 0, 0.4); display: grid; gap: 12px; }
.variants__note { font-size: 12px; color: var(--bone-dim); }
.variants__label { font-size: 12px; font-weight: 600; margin-bottom: 6px; }
.variants__options { display: flex; gap: 6px; }
.variants__options button { min-width: 36px; min-height: 36px; border: 0; background: transparent; box-shadow: inset 0 0 0 1px rgba(239, 233, 223, 0.3); cursor: pointer; font-weight: 700; }
.variants__options button[aria-pressed="true"] { background: var(--molten); color: var(--black); box-shadow: none; }
.is-clean .variants { display: none; }

/* ---------- small screens ---------- */

@media (orientation: portrait) {
  :root { --bar-h: 7svh; }
}

@media (max-width: 760px) {
  :root { --topbar-h: 58px; }
  /* Keep the texture without continuously compositing a moving full-screen
     noise surface on a phone. The skyline and photographic motion stay live. */
  body::after { inset: 0; animation: none; }
  :root[data-theme="light"] { --screen-top: 58px; --screen-inset: 10px; }
  .act--city { height: 540vh; }
  .doors-hold { height: 48vh; }
  .act--ascent { height: 1337vh; }

  .topbar { grid-template-columns: 1fr auto; }
  .topbar__status, .topbar__clock { display: none; }
  .topbar__invite { gap: 6px; letter-spacing: 0.06em; font-size: 10px; }

  /* A portrait date poster, not the desktop lockup squeezed across two doors.
     Both halves still reveal the same perfectly registered composition. */
  .door-date { width: 84vw; }
  .door-date__weekday { margin-bottom: 28px; }
  .door-date__lockup { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .door-date__lockup strong { font-size: 43vw; }
  .door-date__lockup span { font-size: 12vw; font-stretch: 100%; }
  .door-date__lockup em { grid-column: 1; margin-top: 4px; }

  .hero-meta { grid-template-columns: auto 1fr; gap: 12px 22px; bottom: calc(var(--dock-clear) + var(--screen-inset)); }
  .hero-meta--date { display: block; }
  .hero-meta__date { font-size: clamp(1rem, 4.8vw, 1.3rem); }
  .hero-meta__item { justify-content: start; font-size: 16px; gap: 8px; }
  .hero-meta__headline { font-size: clamp(1.2rem, 5.6vw, 1.5rem); }
  .reel__note { font-size: clamp(1.35rem, 5.8vw, 2.35rem); max-width: 28ch; line-height: 1.19; }
  .reel__sentence { display: contents; }
  .reel__sentence:first-child { display: block; max-width: 22ch; margin-inline: auto; }
  .reel__greeting { font-size: clamp(3.2rem, 14.5vw, 6.8rem); }
  .reel__letter { padding-block: 160px 120px; }
  .hero-meta__item .icon { width: 20px; height: 20px; }
  .hero-meta__item:nth-of-type(3) { grid-column: 1 / -1; }

  .floor-read { top: calc(var(--bar-h) + 20svh); bottom: auto; --rail: 26svh; }
  .floor-read__rail { top: calc(100% + 16px); bottom: auto; height: var(--rail); transition: opacity 400ms var(--ease-out); }
  .floor-read.is-top .floor-read__rail { opacity: 0; } /* arrived: clear the rail before the arrival copy rises into it */
  .floor-read__dot { bottom: auto; top: calc((1 - var(--floor)) * (var(--rail) - 12px)); }
  .floor-read__value { font-size: clamp(5rem, 26vw, 7.5rem); }
  .arrival { width: auto; right: var(--gutter); bottom: calc(var(--dock-clear) + 4px); gap: 10px; }
  .arrival__line { font-size: clamp(2.6rem, 13vw, 3.6rem); max-width: 9ch; }
  .rsvp-box { width: 100%; min-width: 0; padding: 14px 16px; }
  .rsvp-box__label { font-size: 1.7rem; }

  .reel__grid {
    inset: calc(var(--topbar-h) + 1vh) 10px calc(var(--dock-clear));
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(6, minmax(0, 1fr));
    grid-template-areas:
      "t1 t2 t3"
      "t4 t5 t6"
      "c  c  c"
      "c  c  c"
      "t7 t8 t9"
      "t10 t11 t12";
  }
  .stage--ascent:has([data-reel-note]) .reel__grid {
    grid-template-areas:
      "t1 t2 t3"
      "t4 t5 t6"
      "c  c  c"
      "c  c  c"
      "t7 t8 t9"
      "t10 t11 t12";
  }
  .stage--ascent:has([data-reel-note]) :is(.reel__tile--6, .reel__tile--7) { display: block; }
  .reel__title { font-size: min(18vw, 5.5rem); font-stretch: 100%; line-height: 0.86; }

  .fallback__columns { grid-template-columns: 1fr; }
  .fallback__row { grid-template-columns: 1fr; gap: 8px; }
  .fallback__footrow { flex-direction: column; }
  .fallback__footrow a { margin-left: 0; }

  .sheet { inset: auto 0 0 0; width: 100vw; transform: translateY(100%); }
  @starting-style { .sheet[open] { transform: translateY(100%); } }
  .sheet--concierge { height: 92dvh; max-height: 92dvh; }
  .concierge__row { grid-template-columns: 44px 1fr auto; }
  .concierge__note { display: none; }
  .gallery__bar { grid-template-columns: 1fr auto auto; }
  .gallery__count { grid-column: 1; grid-row: 2; }
  .gallery__nav { display: none; }
  .gallery__item { flex-basis: 86vw; }
  .gallery__item img { aspect-ratio: 4 / 5; }

  .variants { bottom: calc(var(--dock-clear) + 4px); }
}

/* Narrowest phones (320px): keep all three dock labels whole. */
@media (max-height: 500px) and (pointer: coarse) {
  .topbar { grid-template-columns: 1fr auto; }
  .topbar__status { display: none; }
}
@media (max-width: 360px) {
  .concierge__celebration { font-stretch: 82%; }
  .topbar__invite { flex-wrap: wrap; gap: 3px 0; }
  .topbar__invite [data-invited-label] { flex-basis: 100%; }
  .topbar__dot { display: none; }
  .topbar__count { font-size: 11px; }
  .dock { width: calc(100vw - 16px); }
  .dock__item { padding: 0 8px; gap: 6px; font-size: 13px; }
  .dock__item--rsvp { padding: 0 10px 0 12px; }
  .dock__rsvp { font-size: 15px; }
  .dock__arrow .icon { width: 16px; height: 16px; }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  :is(dialog[open], :popover-open, .is-open) .icon--close { animation: x-fade 200ms ease backwards; }
  :is(button, a):hover > .icon--close, :is(button, a):active > .icon--close { transform: none; }
  .routes, .routes:popover-open { transform: none; transition: opacity 180ms ease, overlay 180ms allow-discrete, display 180ms allow-discrete; }
  @starting-style { .routes:popover-open { opacity: 0; transform: none; } }
  .routes__list li, .routes:popover-open .routes__list li { opacity: 1; transform: none; transition: none; }
  .routes__row > .icon, .routes__label { transition: none; transform: none !important; }
  body::after { animation: none; }
  .sheet { transform: none; opacity: 0; transition: opacity 200ms ease, overlay 200ms allow-discrete, display 200ms allow-discrete; }
  .sheet[open] { opacity: 1; transform: none; }
  @starting-style { .sheet[open] { opacity: 0; transform: none; } }
  .knockout, .knock-tint, .forty, .hero-meta, .card, .doors__type, .arrival { transition: opacity 240ms ease; }
  .btn:active, .icon-button:active { transform: none; }
  .shot__img { transform: none; }
  .word { opacity: 1; color: var(--text); }
  .loader__door { transition: none; }
  .dock, .dock::before, .dock__item--rsvp { transition: none; }
  .reel__tile .shot__img, .reel__tile::after, .gallery__frame, .gallery__item img { transition: none; transform: none; }
  .reel__note .word, .reel__greeting .word { transform: none; filter: none; transition: none; }
}

/* Highlight only the guest's name when hovering the invitation greeting. */
.topbar__guest-name { transition: color 160ms ease, background-color 160ms ease; }
@media (hover: hover) and (pointer: fine) {
  :root[data-theme] .topbar [data-invited-label]:hover .topbar__guest-name { background-color: var(--molten); color: var(--black); }
}

/* Header controls: stable hit areas, independent icon/title motion. */
.topbar__status { transform-origin: center; }
.topbar [data-theme-toggle] { border-radius: 50%; transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out); }
.topbar [data-theme-toggle]:active { transform: none; }
.topbar [data-theme-toggle] svg { transform-origin: center; }
.topbar [data-theme-toggle]:focus-visible { outline: 2px solid var(--molten); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
 :root[data-theme="dark"] .topbar [data-theme-toggle]:hover { background-color: #fff; color: var(--black); }
 :root[data-theme="light"] .topbar [data-theme-toggle]:hover { background-color: var(--black); color: #fff; }
}

/* Header hit targets stay in layout; decorative children own their animation. */
.topbar__status { display:flex; align-items:center; justify-content:center; align-self:stretch; min-height:44px; transform:none; }
.topbar__status [data-status-line] { display:block; transform-origin:center; pointer-events:none; }
.topbar__clock { height:var(--topbar-h); }
.topbar__clock > span, .topbar [data-theme-toggle] svg { pointer-events:none; }
.topbar [data-theme-toggle] { position:relative; }
.topbar [data-theme-toggle]::after { content:""; position:absolute; inset:-10px 0; }
.topbar :is(a,button):active { translate:none; scale:1; }
.gallery__frame { perspective:1000px; }
@media (hover:hover) and (pointer:fine) {
 .gallery__nav button svg { transition:transform 250ms var(--ease-out),color 180ms ease; }
 .gallery__nav button:hover { color:var(--molten); }
 .gallery__nav [data-gallery-step="-1"]:hover svg { transform:translateX(-4px); }
 .gallery__nav [data-gallery-step="1"]:hover svg { transform:translateX(4px); }
 .gallery__nav button:active svg { scale:.85; }
}
@media(prefers-reduced-motion:reduce){ .gallery__nav button:hover svg { transform:none; } }

@media(max-width:760px),(max-height:500px) and (pointer:coarse){ .topbar__status { display:none; } }

.rsvp-roll__word { display:inline-flex; }
@media(max-width:760px){
 .dock__rsvp[data-roll-label="Update RSVP"] { font-size:14px; letter-spacing:0; }
 .dock__rsvp[data-roll-label="Update RSVP"] .rsvp-roll { flex-direction:column; align-items:flex-start; gap:3px; }
 .dock__rsvp[data-roll-label="Update RSVP"] .rsvp-roll__space { display:none; }
}

@media(hover:hover) and (pointer:fine){
 .gallery__frame img { transition:filter 250ms var(--ease-out); }
 .gallery__frame:hover img { filter:contrast(1.035) brightness(1.035); }
}

/* The salutation fits the household before identification, then its selected member. */
.reel__reading .reel__greeting { width: 65vw; max-width: 100%; line-height: 1; text-wrap: balance; }
.reel__greeting .word--name { max-width: 100%; overflow-wrap: anywhere; font-size: clamp(2rem, var(--name-size, 14.5vw), 15rem); }

.reel__person { display: inline-block; white-space: nowrap; }
