@font-face {
  font-family: "Ogg Medium";
  src: url("assets/OggText-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --mx: 0;
  --my: 0;
  --back-opacity: 1;
  --back-x: 0px;
  --back-y: 0px;
  --back-scale: 0.76;
  --four-y: 10cqh;
  --four-scale: 0.78;
  --bazaar-y: 20cqh;
  --blur-mix: 0;
  --back-brightness: 1;
  --bazaar-blur-mix: 0;
  --bazaar-brightness: 1;
  --bazaar-saturation: 1;
  --shade-opacity: 1;
  --shade-z: 2;
  --shade-top-alpha: 0;
  --shade-mid-alpha: 0;
  --shade-bottom-alpha: 0;
  --blur-tint: 74, 181, 224;
  --title-y: 0px;
  --title-scale: 1;
  --title-opacity: 1;
  --bridge-x: -50%;
  --bridge-y: 0px;
  --bridge-bottom: 5cqh;
  --bridge-width: 67.2cqw;
  --bridge-scale: 1.02;
  --split-left-x: -50%;
  --split-left-y: 0px;
  --split-left-scale: 1;
  --split-right-x: -50%;
  --split-right-y: 0px;
  --split-right-scale: 1;
  --frame2-opacity: 0;
  --frame2-x: -50%;
  --frame2-y: -50%;
  --frame2-scale: 1.06;
  --intro-copy-y: 0px;
  --intro-copy-opacity: 1;
  --panel2-opacity: 0;
  --panel2-y: calc(-50% + 58px);
  --panel3-opacity: 0;
  --panel3-y: calc(-50% + 58px);
  --sights-opacity: 0;
  --sights-controls-opacity: 0;
  --sights-y: 0px;
  --sights-enter-x: 420cqw;
  --sights-visibility: hidden;
  --sights-shift: 0px;
  --sights-scale: 1;
  --sights-top: clamp(112px, 19cqh, 220px);
  --sights-screen-top: clamp(112px, 19cqh, 220px);
  --ink: #111411;
  --paper: #fdf1e1;
  --shadow: rgba(0, 0, 0, 0.32);
  --stage-aspect: 1.6;
  --frame-inset: 0px;
  font-family: Inter, Satoshi, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--paper);
  background: #0b1110;
  letter-spacing: 0;
}

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
  scroll-behavior: smooth;
  background: #0b1110;
}

/* The seek tween sets scroll position every frame; native smooth scrolling would
   animate each of those steps, so the trip must own the scroll outright. */
html.is-traveling {
  scroll-behavior: auto;
}

body {
  min-height: 100%;
  margin: 0;
  overflow-x: clip;
  background: #0b1110;
}

button {
  border: 0;
  font: inherit;
}

.site-shell {
  min-height: 100vh;
}

/* ---------- scroll rig ---------- */

.cinema-scroll {
  position: relative;
  height: calc(100vh + 4600px);
}

/* The scene is a fixed composition (designed at 16:10). Its internals are sized
   in container units against this box, so the layers hold their relationship at
   every window shape instead of drifting into each other. Below 900px the box
   goes full-bleed and the portrait layout takes over. */
.stage {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  min-height: 620px;
  overflow: hidden;
  isolation: isolate;
  container: stage / size;
  background: #7fb4d4;
}

@media (min-width: 900px) {
  .stage {
    --avail-w: calc(100vw - var(--frame-inset) * 2);
    --avail-h: calc(100vh - var(--frame-inset) * 2);
    --stage-w: min(var(--avail-w), var(--avail-h) * var(--stage-aspect));
    --stage-h: min(var(--avail-h), var(--avail-w) / var(--stage-aspect));
    top: calc((100vh - var(--stage-h)) / 2);
    width: var(--stage-w);
    height: var(--stage-h);
    min-height: 0;
    margin-inline: auto;
  }
}

.world,
.back-stack,
.sky-img,
.shade,
.scene-img,
.site-header,
.sights-slider,
.sights-controls,
.hero-title,
.intro-copy,
.story-panel {
  position: absolute;
}

.world {
  inset: 0;
  overflow: hidden;
  background: #79b7dd;
}


/* ---------- header ---------- */

.site-header {
  z-index: 10;
  top: 0;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: minmax(260px, 1fr) auto minmax(260px, 1fr);
  align-items: center;
  gap: 32px;
  padding: 32px;
  color: rgba(253, 241, 225, 0.86);
  pointer-events: auto;
}

.site-logo {
  justify-self: start;
  color: rgba(253, 241, 225, 0.92);
  font-family: "Ogg Medium", serif;
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

.site-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(24px, 2.2cqw, 44px);
}

.site-nav a,
.language-switcher {
  color: rgba(253, 241, 225, 0.86);
  font-weight: 700;
  line-height: 1;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.2);
}

.site-nav a {
  position: relative;
  font-size: 20px;
  font-weight: 400;
  text-decoration: none;
  transition: color 260ms ease;
}

.site-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: 0.85;
  transform: scaleX(0);
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1);
}

.site-nav a[aria-current="true"] {
  color: #fdf1e1;
}

.site-nav a[aria-current="true"]::after {
  transform: scaleX(1);
}

.language-switcher {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 0;
  background: transparent;
  font-size: 16px;
  cursor: pointer;
}

.language-switcher span {
  display: inline-flex;
  line-height: 1;
}

/* ---------- scene layers ---------- */

.scene-img {
  display: block;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform, opacity, filter;
  pointer-events: none;
}

.sky-img {
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: none;
}

/* The blur and the 0.745 darkening are baked into these twins at 640px wide, so the
   scene's soft state costs no filter work at all — only an opacity cross-fade, which
   the compositor does for free. Animating blur() instead re-rasterizes a 2880px layer
   every frame; doing it with a static filter on a full-size twin is no cheaper, because
   the twin still has to be rasterized at each new parent scale. Detail is not legible
   through a 14px blur, so the small source is indistinguishable. */
.sky-blur {
  opacity: var(--blur-mix);
}

.back-stack {
  z-index: 1;
  top: 0;
  bottom: 0;
  left: -3cqw;
  right: -3cqw;
  opacity: var(--back-opacity);
  transform: translate3d(var(--back-x), var(--back-y), 0) scale(var(--back-scale));
  transform-origin: 50% 100%;
  will-change: transform, filter, opacity;
}

/* Brightness alone is a per-pixel colour matrix over an existing raster. Adding a blur
   to the chain would force the whole chain to re-run each frame, and this layer is a
   screen-blended glow at 0.72 — its sharpness is not legible anyway. */
.back-img {
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.back-bazaar,
.back-four {
  top: auto;
  bottom: 0;
  left: 48%;
  right: auto;
  width: 112%;
  height: auto;
  object-fit: contain;
}

.back-bazaar {
  z-index: 3;
  opacity: 1;
  filter: saturate(var(--bazaar-saturation));
  transform: translate3d(-50%, var(--bazaar-y), 0) scale(0.86);
}

.back-bazaar-blur {
  filter: none;
  opacity: var(--bazaar-blur-mix);
}

.back-four {
  z-index: 1;
  opacity: calc(0.72 * var(--back-brightness));
  mix-blend-mode: screen;
  transform: translate3d(-50%, calc(var(--four-y) - 110px), 0) scale(var(--four-scale));
}

/* ---------- sights slider ---------- */

.sights-slider {
  z-index: 2;
  left: 0;
  right: 0;
  top: var(--sights-top);
  padding: 0;
  opacity: 1;
  visibility: var(--sights-visibility);
  transform: translate3d(var(--sights-enter-x), var(--sights-y), 0) scale(var(--sights-scale));
  transform-origin: 0 0;
  pointer-events: auto;
  will-change: transform;
}

.sights-track {
  display: flex;
  gap: clamp(16px, 1.15cqw, 24px);
  align-items: stretch;
  transform: translate3d(calc(var(--sights-shift) - 18cqw), 0, 0);
  transition: transform 640ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}

.sights-track.is-jumping {
  transition: none;
}

.sight-card {
  position: relative;
  flex: 0 0 clamp(360px, 19.4cqw, 430px);
  height: 220px;
  padding: 24px;
  overflow: hidden;
  border: 1px solid rgba(253, 241, 225, 0.42);
  border-radius: 24px;
  color: #000;
  background: #fdf1e1;
  box-shadow: 0 18px 52px rgba(2, 47, 64, 0.12);
  backdrop-filter: none;
  cursor: pointer;
  pointer-events: auto;
  user-select: none;
}

.sight-card::before,
.sight-card::after {
  content: none;
}

.sight-card:focus-visible,
.sight-card.is-active {
  outline: none;
}

.sight-kicker {
  position: relative;
  z-index: 1;
  display: block;
  margin-bottom: 56px;
  color: #000;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.05;
  text-transform: uppercase;
  text-shadow: none;
}

.sight-pin {
  position: absolute;
  top: 24px;
  right: 24px;
  width: 67.2px;
  height: 67.2px;
  pointer-events: none;
}

.sight-card h3 {
  position: absolute;
  z-index: 1;
  left: 24px;
  right: 24px;
  bottom: calc(24px + (16px * 1.16 * 2) + 12px);
  max-width: calc(100% - 76px);
  margin: 0;
  color: #000;
  font-size: 24px;
  font-weight: 800;
  line-height: 0.95;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: none;
  white-space: nowrap;
}

.sight-card p {
  position: absolute;
  z-index: 1;
  left: 24px;
  right: 24px;
  bottom: 24px;
  max-width: 100%;
  margin: 12px 0 0;
  color: #000;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.16;
  display: -webkit-box;
  max-height: calc(2em * 1.16);
  overflow: hidden;
  text-shadow: none;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.sights-controls {
  z-index: 5;
  left: 48px;
  right: auto;
  top: calc(var(--sights-screen-top) + 220px + 16px);
  display: flex;
  justify-content: flex-start;
  gap: 14px;
  opacity: var(--sights-controls-opacity);
  transform: translate3d(0, var(--sights-y), 0);
  pointer-events: none;
  will-change: transform, opacity;
}

.sights-controls.is-ready {
  pointer-events: auto;
}

.sight-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  border-radius: 999px;
  color: #111411;
  background: rgba(253, 241, 225, 0.94);
  box-shadow: 0 18px 36px rgba(0, 0, 0, 0.2);
  cursor: pointer;
}

/* ---------- hero ---------- */

.hero-title {
  z-index: 3;
  left: 50%;
  top: clamp(122px, 19cqh, 205px);
  width: min(94cqw, 1780px);
  margin: 0;
  color: #fdf1e1;
  font-family: "Ogg Medium", serif;
  font-size: 14rem;
  font-weight: 500;
  line-height: 0.78;
  text-align: center;
  text-shadow: none;
  transform: translate3d(-50%, var(--title-y), 0) scale(var(--title-scale));
  opacity: var(--title-opacity);
  will-change: transform, opacity;
}

.bridge-img {
  z-index: 4;
  left: 50%;
  bottom: var(--bridge-bottom);
  width: min(var(--bridge-width), 2140px);
  height: auto;
  transform: translate3d(var(--bridge-x), var(--bridge-y), 0) scale(var(--bridge-scale));
  transform-origin: 50% 48%;
}

.splitframe-img {
  z-index: 6;
  left: 50%;
  bottom: -2cqh;
  width: min(118cqw, 2240px);
  height: auto;
  pointer-events: none;
}

.splitframe-left {
  transform: translate3d(var(--split-left-x), var(--split-left-y), 0) scale(var(--split-left-scale));
  transform-origin: 21% 52%;
}

.splitframe-right {
  transform: translate3d(var(--split-right-x), var(--split-right-y), 0) scale(var(--split-right-scale));
  transform-origin: 79% 52%;
}

.frame-two-img {
  z-index: 5;
  filter: none !important;
  backdrop-filter: none;
  left: 50%;
  top: 50%;
  width: min(122cqw, 2160px);
  height: auto;
  opacity: var(--frame2-opacity);
  transform: translate3d(var(--frame2-x), var(--frame2-y), 0) scale(var(--frame2-scale));
  transform-origin: 50% 48%;
}

.shade {
  inset: 0;
  z-index: var(--shade-z);
  pointer-events: none;
  opacity: var(--shade-opacity);
  background: linear-gradient(
    180deg,
    rgba(var(--blur-tint), var(--shade-top-alpha)) 0%,
    rgba(var(--blur-tint), var(--shade-mid-alpha)) 48%,
    rgba(var(--blur-tint), var(--shade-bottom-alpha)) 100%
  );
}

/* ---------- copy ---------- */

.intro-copy {
  z-index: 9;
  left: 50%;
  bottom: clamp(56px, 28cqh, 400px);
  width: min(560px, calc(100cqw - 40px));
  text-align: center;
  transform: translate3d(-50%, var(--intro-copy-y), 0);
  opacity: var(--intro-copy-opacity);
  will-change: transform, opacity;
}

.intro-copy p {
  margin: 0 auto;
  max-width: 560px;
  color: #fdf1e1;
  font-size: 1.18rem;
  font-weight: 500;
  line-height: 1.18;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.42);
}

.hero-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 26px;
}

.hero-tags span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  padding: 0 25px;
  color: var(--ink);
  border-radius: 999px;
  background: #fdf1e1;
  font-size: 0.98rem;
  font-weight: 500;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.18);
}

.story-panel {
  z-index: 10;
  left: 50%;
  top: 45%;
  width: min(760px, calc(100cqw - 42px));
  text-align: center;
  pointer-events: none;
  transform: translate3d(-50%, -50%, 0);
  will-change: transform, opacity;
}

.story-panel h2 {
  margin: 0;
  color: #fdf1e1;
  font-family: "Ogg Medium", serif;
  font-size: 4.75rem;
  font-weight: 500;
  line-height: 0.95;
  text-shadow: 0 16px 38px var(--shadow);
}

.story-panel p {
  width: min(520px, 100%);
  margin: 26px auto 0;
  color: #fdf1e1;
  font-size: 1.14rem;
  font-weight: 500;
  line-height: 1.18;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.42);
}

.story-panel-bridge {
  top: 60%;
  opacity: var(--panel2-opacity);
  transform: translate3d(-50%, var(--panel2-y), 0);
}

.story-panel-bazaar {
  top: 29%;
  opacity: var(--panel3-opacity);
  transform: translate3d(-50%, var(--panel3-y), 0);
}

.facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 86px;
  width: min(470px, 100%);
  margin: 72px auto 0;
}

.facts dt {
  color: #fdf1e1;
  font-family: "Ogg Medium", serif;
  font-size: 4.2rem;
  font-weight: 500;
  line-height: 0.9;
  text-shadow: 0 14px 34px var(--shadow);
}

.facts dd {
  margin: 18px 0 0;
  color: #fdf1e1;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.14;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.42);
}

.note-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 50px;
  margin-top: 28px;
  gap: 12px;
  padding: 0 28px;
  border-radius: 999px;
  color: var(--ink);
  background: #fdf1e1;
  box-shadow: 0 16px 34px rgba(0, 0, 0, 0.18);
  pointer-events: auto;
  cursor: pointer;
}

.note-button span:first-child {
  font-size: 1.25rem;
  line-height: 1;
}

/* ---------- responsive ---------- */

@container stage (max-width: 1500px) {
  .hero-title {
    font-size: 11rem;
  }

  .story-panel h2 {
    font-size: 4.1rem;
  }
}

@container stage (max-width: 1100px) {
  .hero-title {
    top: 15cqh;
    font-size: 7.5rem;
  }

  .bridge-img {
    width: 138cqw;
  }

  .frame-two-img {
    width: 132cqw;
  }

  .story-panel h2 {
    font-size: 3.2rem;
  }

  .facts {
    gap: 34px;
    margin-top: 44px;
  }

  .facts dt {
    font-size: 3.2rem;
  }

  .sight-card {
    flex-basis: clamp(320px, 40cqw, 390px);
    min-height: 178px;
  }
}

@container stage (max-width: 640px) {
  .site-header {
    grid-template-columns: 1fr auto;
    gap: 18px;
    padding: 24px;
  }

  .site-nav {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-content: flex-start;
    gap: 18px;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .site-nav::-webkit-scrollbar {
    display: none;
  }

  .hero-title {
    top: 16cqh;
    font-size: 4.5rem;
  }

  .bridge-img {
    bottom: 2cqh;
    width: 190cqw;
  }

  .frame-two-img {
    width: 176cqw;
  }

  .intro-copy {
    bottom: 42px;
  }

  .intro-copy p,
  .story-panel p {
    font-size: 1rem;
  }

  .hero-tags {
    gap: 8px;
  }

  .hero-tags span {
    min-height: 38px;
    padding: 0 16px;
    font-size: 0.88rem;
  }

  .story-panel {
    top: 42%;
  }

  .story-panel-bazaar {
    top: 26%;
  }

  .story-panel h2 {
    font-size: 2.45rem;
  }

  .facts {
    gap: 18px;
    margin-top: 34px;
  }

  .facts dt {
    font-size: 2.5rem;
  }

  .sights-slider {
    padding: 0;
  }

  .sights-track {
    gap: 12px;
    transform: translate3d(calc(var(--sights-shift) - 18cqw), 0, 0);
  }

  .sight-card {
    flex-basis: min(82cqw, 330px);
    height: 220px;
    padding: 24px;
    border-radius: 24px;
  }

  .sights-controls {
    top: calc(var(--sights-screen-top) + 236px);
  }

  .sight-card h3 {
    max-width: 78%;
  }

  .sight-card p {
    max-width: 100%;
    margin-top: 10px;
  }

  .sight-kicker {
    margin-bottom: 56px;
  }

  .sight-pin {
    top: 24px;
    right: 24px;
    width: 57.6px;
    height: 57.6px;
  }
}

/* ---------- load intro ----------
   `js-intro` holds the pre-state and is only ever set by script, so a page without JS
   renders normally. `js-intro-play` starts the sequence; both are dropped when it ends,
   leaving no residue for the scroll engine to fight. Transform and opacity only. */

.js-intro .world {
  opacity: 0;
  transform: scale(1.05);
}

.js-intro .hero-title .glyph > span,
.js-intro .site-logo,
.js-intro .site-nav a,
.js-intro .language-switcher,
.js-intro .intro-copy p,
.js-intro .hero-tags span {
  opacity: 0;
}

.hero-title .glyph {
  display: inline-block;
  overflow: hidden;
  /* caps have no descenders, but the 0.78 line-height box crops tight — pad the mask
     and pull it back so nothing clips */
  padding: 0.14em 0.02em;
  margin: -0.14em -0.02em;
  vertical-align: bottom;
}

.hero-title .glyph > span {
  display: inline-block;
}

.js-intro .hero-title .glyph > span {
  transform: translateY(115%);
}

.js-intro-play .world {
  animation: intro-settle 1400ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.js-intro-play .hero-title .glyph > span {
  animation: intro-glyph 1000ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* Three families, by role. The headline is the only hero move; everything else supports
   it. Chrome arrives from the edge it belongs to, running copy wipes like text, and the
   pills arrive like objects. `both` fill so the from-state holds through the delay. */

/* Chrome, outer: assembles from its own edge */
.js-intro-play .site-logo {
  animation: intro-from-left 760ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 700ms;
}

.js-intro-play .language-switcher {
  animation: intro-from-right 760ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 1020ms;
}

/* Chrome, inner: one row, one family — differentiating each item would read as noise */
.js-intro-play .site-nav a {
  animation: intro-rise 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Running copy: wipes up behind its own edge, the way a line of type is set */
.js-intro-play .intro-copy p {
  animation: intro-wipe 900ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: 900ms;
}

/* Discrete objects, so they arrive with weight rather than appearing */
.js-intro-play .hero-tags span {
  animation: intro-pop 620ms cubic-bezier(0.34, 1.4, 0.64, 1) both;
}

.js-intro-play .site-nav a:nth-child(1) { animation-delay: 780ms; }
.js-intro-play .site-nav a:nth-child(2) { animation-delay: 840ms; }
.js-intro-play .site-nav a:nth-child(3) { animation-delay: 900ms; }
.js-intro-play .site-nav a:nth-child(4) { animation-delay: 960ms; }
.js-intro-play .hero-tags span:nth-child(1) { animation-delay: 1120ms; }
.js-intro-play .hero-tags span:nth-child(2) { animation-delay: 1200ms; }
.js-intro-play .hero-tags span:nth-child(3) { animation-delay: 1280ms; }

@keyframes intro-settle {
  from { opacity: 0; transform: scale(1.05); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes intro-glyph {
  from { transform: translateY(115%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

@keyframes intro-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes intro-from-left {
  from { opacity: 0; transform: translateX(-22px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes intro-from-right {
  from { opacity: 0; transform: translateX(22px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes intro-wipe {
  from { opacity: 1; clip-path: inset(0 0 105% 0); transform: translateY(10px); }
  to { opacity: 1; clip-path: inset(0 0 -5% 0); transform: translateY(0); }
}

@keyframes intro-pop {
  from { opacity: 0; transform: scale(0.86) translateY(12px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

/* ---------- optional presentation frame ----------
   Additive, not part of the spec. Drop `framed` from <body> to get the
   spec-exact full-bleed page back. Reuses the already-loaded sky layer as a
   blurred backdrop, so it costs no extra network request. */

body.framed {
  --frame-inset: clamp(14px, 3vh, 34px);
  --frame-radius: 26px;
  /* body's own background would paint over the z-index:-1 backdrop below */
  background: transparent;
}

body.framed::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: url("assets/backdrop.webp") center / cover no-repeat;
  filter: blur(5px) brightness(0.78) saturate(1.04);
  transform: scale(1.04);
}

body.framed .stage {
  border-radius: var(--frame-radius);
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.45), 0 6px 18px rgba(0, 0, 0, 0.28);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .scene-img,
  .back-stack,
  .hero-title,
  .intro-copy,
  .story-panel,
  .sights-track,
  .sights-slider {
    transition: none;
  }
}
