:root {
  --ink: #17110e;
  --cream: #fff4de;
  --muted: rgba(255, 244, 222, 0.72);
  --gold: #e9b95b;
  --gold-bright: #ffd986;
  --glass: rgba(20, 14, 14, 0.5);
  --display: "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
  --ui: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color-scheme: dark;
  font-family: var(--ui);
  color: var(--cream);
  background: var(--ink);
}

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  min-height: 100%;
  margin: 0;
  background: var(--ink);
}

body {
  overflow: hidden;
}

button {
  font: inherit;
}

button:focus-visible {
  outline: 2px solid var(--cream);
  outline-offset: 4px;
}

#scene {
  position: fixed;
  inset: 0;
  isolation: isolate;
  overflow: hidden;
  background: #191510;
}

.city-layer {
  position: absolute;
  inset: -3%;
  transform: translate3d(var(--scene-x, 0), var(--scene-y, 0), 0) scale(1.04);
  animation: city-breathe 24s ease-in-out infinite alternate;
  will-change: transform;
}

.city-backdrop {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: 50% 50%;
  filter: saturate(0.92) brightness(0.78);
}

.home-backdrops {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  /* mouse parallax and zoom removed by owner decision: a perfectly still,
     full-size picture; life comes from the clouds and tower lights */
}

/* fixed stage in the wide master's aspect (3840x1648): the picture and the
   living-clouds canvas share one coordinate space, registered to the PICTURE.
   COVER sizing: always fills the viewport, only the side margins get cropped. */
.city-stage {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  aspect-ratio: 3840 / 1648;
  width: max(100vw, calc(100vh * 3840 / 1648));
  /* phones (fix 2026-09-07): 100vh is the FULL screen height, but the page
     under the browser bars is shorter, and the flight video came out that
     much larger than the panorama it lands on - a visible jump in scale at
     the cut. dvh is the height the page really has, the same box the
     district uses, so the last frame and the first frame now match. */
  width: max(100vw, calc(100dvh * 3840 / 1648));
}

/* the clouds' own layer, ABOVE the sun (6): clouds pass in front of the
   sun, never behind it (owner 2026-08-15). Same stage geometry as the
   picture, so nothing shifts by a pixel. */
.cloud-layer {
  position: absolute;
  inset: 0;
  z-index: 7;
  overflow: hidden;
  pointer-events: none;
}
#cloudCanvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* district flight: fullscreen video transition (homepage -> arrival -> district) */
#flightOverlay {
  position: fixed;
  inset: 0;
  z-index: 80;
  /* no backdrop: the video covers the box, and an unready video must never
     flash black over the page */
  background: transparent;
  cursor: pointer;
}

/* the overlay itself never fades: the cloud canvas re-parented inside must
   stay fully visible from the first frame (the SAME clouds keep rising).
   Only the VIDEO dissolves in and out underneath the clouds. */
#flightOverlay video {
  opacity: 0;
  transition: opacity 700ms ease;
}

#flightOverlay.is-visible video {
  opacity: 1;
}

#flightOverlay video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* during a flight the cloud canvas is re-parented into #flightStage (same
   .city-stage geometry), so the clouds fly UP over the playing video */

.flight-skip-hint {
  position: absolute;
  right: 22px;
  bottom: 18px;
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(240, 230, 207, 0.75);
  text-shadow: 0 1px 8px rgba(10, 6, 5, 0.8);
  pointer-events: none;
}
/* phones have no mouse and no Esc key - the hint says "tap" there */
.flight-skip-hint .skip-hint-touch { display: none; }
@media (max-width: 900px) {
  .flight-skip-hint .skip-hint-desktop { display: none; }
  .flight-skip-hint .skip-hint-touch { display: inline; }
}

.home-backdrop {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  opacity: 0;
  filter: saturate(0.96) brightness(0.8);
  transition: opacity 300ms ease;
  will-change: opacity;
}

.home-backdrop.is-active {
  opacity: 1;
}

/* the city sun = the music play/pause control (old player panel removed).
   Anchored to the SCREEN, not the picture (owner decision 2026-08-12: cover
   cropping hides picture corners on 16:9 and mobile), so it is always in the
   viewer's top-left. Sizes per approved spec: ~150-170 desktop, ~96 mobile. */
.city-sun {
  position: absolute;
  z-index: 6;
  top: max(16px, env(safe-area-inset-top));
  left: max(20px, env(safe-area-inset-left));
  width: clamp(96px, 10vw, 164px);
  aspect-ratio: 1;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  container-type: inline-size;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
.city-sun-img {
  display: block;
  width: 100%;
  height: 100%;
  filter: saturate(0.96) brightness(0.8);
}
/* play/pause mark (owner spec 2026-08-13): stays visible, LARGE, dead-center,
   drawn as LINES (stroked outline, round joins) - never a solid fill, never
   a dark shape over the sun */
.city-sun-symbol {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.city-sun-symbol svg {
  position: absolute;
  width: 62%;
  height: 62%;
  filter: drop-shadow(0 0 8px rgba(255, 180, 85, 0.6));
  transition: opacity 300ms ease;
}
/* owner spec 2026-08-13: solid FILLED marks at ~50% opacity - the sign reads
   instantly, the sun's filigree stays visible through it */
.city-sun-symbol svg path,
.city-sun-symbol svg rect {
  fill: rgba(248, 192, 78, 0.1);
  stroke: rgba(120, 78, 22, 0.32);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
  transition: fill 250ms ease, stroke 250ms ease, stroke-width 250ms ease;
}
.city-sun:hover .city-sun-symbol svg path,
.city-sun:hover .city-sun-symbol svg rect {
  fill: rgba(250, 200, 90, 0.85);
  stroke: rgba(92, 56, 12, 0.75);
  stroke-width: 2.5;
  stroke-linejoin: round;
}
.city-sun-symbol .sym-play { transform: translateX(3.5%); }
/* states (owner 2026-08-15): paused = translucent play triangle, playing =
   translucent pause bars with the same treatment - everyone must SEE how to
   stop the sound. The living equalizer moved to its own corner (.city-eq). */
.city-sun-symbol .sym-pause { opacity: 0; }
.city-sun.is-playing .sym-play { opacity: 0; }
.city-sun.is-playing .sym-pause { opacity: 1; }

/* the living equalizer: bottom-left corner, pure indicator (no clicks).
   5 bars scale with their band, VU colors fed by the same analyser loop
   that drives the rays - no extra audio work per frame. */
.city-eq {
  position: fixed;
  z-index: 21; /* over the district (20) so the TOUR shows it too */
  left: max(20px, env(safe-area-inset-left));
  bottom: max(16px, env(safe-area-inset-bottom));
  width: 64px;
  opacity: 0;
  transition: opacity 400ms ease;
  pointer-events: none;
}
body.city-music-on .city-eq { opacity: 1; }
/* the equalizer lives on the HOMEPAGE only (owner 2026-09-07): in a district
   and in the tour attention belongs to the pictures, the Sound button is the
   only sign of the music there */
#district.is-open ~ .city-eq { opacity: 0; }
.city-eq svg {
  display: block;
  width: 100%;
  filter: drop-shadow(0 1px 6px rgba(10, 6, 5, 0.6));
}
.city-eq .eq-bar {
  fill: rgba(248, 192, 78, 0.8);
  stroke: rgba(92, 56, 12, 0.45);
  transform-box: fill-box;
  transform-origin: center;
  transform: scaleY(var(--eq, 0.4));
}

/* corona: a wide warm halo that makes the disc read as a light source, not a
   coin. Always on with a slow breath; swells a little while music plays. */
/* softened since v005: the asset now carries its own baked halo, the CSS
   corona only breathes on top of it */
.city-sun::before {
  content: "";
  position: absolute;
  inset: -55%;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 205, 105, 0.30),
    rgba(255, 205, 105, 0.14) 38%,
    rgba(252, 180, 70, 0.06) 55%,
    rgba(252, 180, 70, 0) 72%);
  mix-blend-mode: screen;
  pointer-events: none;
  animation: sunGlowBreath 10s ease-in-out infinite;
}
.city-sun.is-playing::before {
  animation-duration: 7s;
}
@keyframes sunGlowBreath {
  0%, 100% { opacity: 0.75; transform: scale(0.96); }
  50%      { opacity: 1;    transform: scale(1.08); }
}

/* rays: soft light petals around the disc - very slow breathing, no sharp
   sticks, no spinning UI ring. At rest the fan is drawn in and calm; while
   music plays it opens wider. Each petal breathes on its own slow clock.
   Petals are long enough to clearly reach past the disc (visible tail
   ~1x..2.4x of the disc radius) and blend additively over the sky. */
/* no screen blending: over the bright blue sky it bleached the rays to
   white; plain alpha keeps them the sun's own gold */
.city-sun-rays {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.92;
  transform: scale(0.88);
  transition: opacity 1600ms ease, transform 1600ms ease;
  /* the whole fan slowly revolves (owner 2026-08-13): a calm celestial
     rotation, and every ray eventually visits the visible sector */
  animation: sunFanSpin 90s linear infinite;
}
@keyframes sunFanSpin {
  from { rotate: 0deg; }
  to   { rotate: 360deg; }
}
.city-sun.is-playing .city-sun-rays {
  opacity: 1;
  transform: scale(1);
}
/* while music plays the breath animation yields to the spectrum: JS feeds
   each ray its band level via --m (0..1) every frame */
.city-sun.is-playing .city-sun-rays i {
  animation: none;
  opacity: calc(0.4 + var(--g, 0.3) * 0.45 + var(--m, 0) * 0.15);
  /* inner end pinned at the disc: the +14% / -42.5% terms cancel the
     center-based scaling, so ALL growth shoots outward. Width untouched. */
  transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--ty, -66%) + 10% - var(--m, 0) * 40%)) rotate(var(--tilt, 0deg))
    scaleY(calc(0.8 + var(--m, 0) * 0.6));
}
.city-sun-rays i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--w, 20%);
  height: var(--h, 78%);
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(255, 214, 120, var(--o, 0.85)),
    rgba(252, 180, 70, calc(var(--o, 0.85) * 0.6)) 58%,
    rgba(252, 176, 66, 0) 82%);
  transform: translate(-50%, -50%) rotate(var(--a)) translateY(var(--ty, -66%)) rotate(var(--tilt, 0deg));
  filter: blur(var(--b, 0px));
  animation: sunPetalBreath var(--d, 9s) ease-in-out var(--dl, 0s) infinite;
  will-change: transform, opacity;
}
/* a groomed magical crown: 12 rays, long-short alternating (classic sun
   iconography), spacing almost even with a small living jitter, gentle
   off-radial tilts. Rich and combed - the life comes from the breathing,
   not from chaos or density. */
.city-sun-rays i:nth-of-type(1)  { --a: 4deg;   --tilt: 2deg;  --w: 20%; --h: 128%; --ty: -76%; --o: 0.9;  --b: 0.5px; --d: 8.6s;  --dl: 0s; }
.city-sun-rays i:nth-of-type(2)  { --a: 33deg;  --tilt: -2deg; --w: 17%; --h: 92%;  --ty: -68%; --o: 0.7;  --b: 1px;   --d: 10.2s; --dl: -3.1s; }
.city-sun-rays i:nth-of-type(3)  { --a: 62deg;  --tilt: 3deg;  --w: 20%; --h: 134%; --ty: -78%; --o: 0.9;  --b: 0.5px; --d: 9.4s;  --dl: -6.4s; }
.city-sun-rays i:nth-of-type(4)  { --a: 95deg;  --tilt: -3deg; --w: 17%; --h: 90%;  --ty: -67%; --o: 0.7;  --b: 1px;   --d: 11.1s; --dl: -1.7s; }
.city-sun-rays i:nth-of-type(5)  { --a: 124deg; --tilt: 2deg;  --w: 21%; --h: 124%; --ty: -75%; --o: 0.9;  --b: 0.5px; --d: 8.9s;  --dl: -4.9s; }
.city-sun-rays i:nth-of-type(6)  { --a: 153deg; --tilt: 3deg;  --w: 16%; --h: 94%;  --ty: -68%; --o: 0.7;  --b: 1px;   --d: 10.7s; --dl: -8.2s; }
.city-sun-rays i:nth-of-type(7)  { --a: 186deg; --tilt: -2deg; --w: 20%; --h: 130%; --ty: -77%; --o: 0.9;  --b: 0.5px; --d: 9.8s;  --dl: -2.6s; }
.city-sun-rays i:nth-of-type(8)  { --a: 214deg; --tilt: 2deg;  --w: 17%; --h: 90%;  --ty: -68%; --o: 0.7;  --b: 1px;   --d: 11.5s; --dl: -5.5s; }
.city-sun-rays i:nth-of-type(9)  { --a: 243deg; --tilt: -3deg; --w: 20%; --h: 132%; --ty: -77%; --o: 0.9;  --b: 0.5px; --d: 9.1s;  --dl: -7.3s; }
.city-sun-rays i:nth-of-type(10) { --a: 275deg; --tilt: 3deg;  --w: 17%; --h: 92%;  --ty: -68%; --o: 0.7;  --b: 1px;   --d: 10.4s; --dl: -0.9s; }
.city-sun-rays i:nth-of-type(11) { --a: 304deg; --tilt: -2deg; --w: 21%; --h: 126%; --ty: -76%; --o: 0.9;  --b: 0.5px; --d: 9.6s;  --dl: -4.2s; }
.city-sun-rays i:nth-of-type(12) { --a: 334deg; --tilt: 2deg;  --w: 17%; --h: 94%;  --ty: -69%; --o: 0.7;  --b: 1px;   --d: 8.8s;  --dl: -6.8s; }
@keyframes sunPetalBreath {
  0%, 100% {
    opacity: 0.6;
    transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--ty, -66%) + 3%)) rotate(var(--tilt, 0deg)) scale(0.94, 0.9);
  }
  50% {
    opacity: 1;
    transform: translate(-50%, -50%) rotate(var(--a)) translateY(calc(var(--ty, -66%) - 2%)) rotate(var(--tilt, 0deg)) scale(1, 1.08);
  }
}
@media (prefers-reduced-motion: reduce) {
  .city-sun::before,
  .city-sun-rays i { animation: none; }
}

/* Mobile music pan (owner idea 2026-08-12): on narrow screens cover-cropping
   shows only the middle band of the picture and the lit towers (23-34% of
   picture width) stay off-screen. When music starts, the whole stage slowly
   pans right to bring the towers into view; on pause it drifts back to center.
   Towers are visible when viewport aspect > ~5/4, so the pan only exists below.
   Clouds and tower scans live inside the same stage, so they travel along. */
@media (max-aspect-ratio: 5/4) {
  #cityStage,
  #cloudStage {
    transition: transform 7000ms ease-in-out;
  }
  body.city-music-on #cityStage,
  body.city-music-on #cloudStage {
    transform: translate(-28.5%, -50%);
  }
  /* flights film the CENTER view: before take-off the stage glides back to
     center (never a jump), and the pan stays off until the return dissolve
     has finished (owner 2026-08-15) */
  body.flight-prep #cityStage,
  body.flight-prep #cloudStage {
    transform: translate(-50%, -50%);
    transition: transform 1400ms ease-in-out;
  }
}

.cloud-fragments,
.cloud-banks {
  position: absolute;
  inset: 0;
  pointer-events: none;
  display: none; /* clouds disabled by owner decision 2026-08-09; layers kept for possible return */
}

.cloud-fragment {
  position: absolute;
  height: auto;
  opacity: var(--cloud-opacity, 0.45);
  filter: saturate(0.96) brightness(0.82);
  will-change: transform;
  animation: cloud-drift var(--drift-duration, 60s) ease-in-out var(--drift-delay, 0s) infinite alternate;
}

@keyframes cloud-drift {
  from { transform: translate3d(calc(var(--drift-x, 1.5%) * -1), calc(var(--drift-y, 0.4%) * -1), 0); }
  to { transform: translate3d(var(--drift-x, 1.5%), var(--drift-y, 0.4%), 0); }
}

.cloud-fragment--01 { top: 0%; left: 24%; width: 32%; --cloud-opacity: 0.4; --drift-x: 2.4%; --drift-y: 0.4%; --drift-duration: 74s; --drift-delay: -31s; }
.cloud-fragment--03 { top: -3%; left: 58%; width: 30%; --cloud-opacity: 0.35; --drift-x: -2%; --drift-y: 0.5%; --drift-duration: 88s; --drift-delay: -55s; }
.cloud-fragment--04 { display: none; }
.cloud-fragment--05 { top: 6%; left: 72%; width: 30%; --cloud-opacity: 0.42; --drift-x: -2.6%; --drift-y: 0.4%; --drift-duration: 52s; --drift-delay: -40s; }
.cloud-fragment--07 { top: 4%; left: 6%; width: 24%; --cloud-opacity: 0.35; --drift-x: 2%; --drift-y: 0.5%; --drift-duration: 47s; --drift-delay: -20s; }

.cloud-bank {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.96) brightness(0.82);
  will-change: transform;
  animation: cloud-drift var(--drift-duration, 80s) ease-in-out var(--drift-delay, 0s) infinite alternate;
}

.cloud-bank--left { object-position: 50% 50%; --drift-x: 0.35%; --drift-y: 0.2%; --drift-duration: 68s; --drift-delay: -17s; }
.cloud-bank--right { object-position: 50% 50%; --drift-x: -0.4%; --drift-y: 0.15%; --drift-duration: 82s; --drift-delay: -49s; }
.cloud-bank--bottom { object-position: 50% 50%; --drift-x: 0.3%; --drift-y: -0.25%; --drift-duration: 90s; --drift-delay: -63s; }

@media (max-width: 900px) {
  .cloud-fragment--04,
  .cloud-fragment--07 { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .home-backdrops,
  .cloud-fragment,
  .cloud-bank {
    animation: none;
  }
}

.home-story {
  position: absolute;
  z-index: 7; /* the headline is UI, it stays above the passing clouds */
  left: max(4vw, 48px);
  top: 45%;
  width: min(570px, 47vw);
  transform: translateY(-50%);
  text-shadow: 0 3px 24px rgba(10, 6, 5, 0.9);
  transition: opacity 150ms ease, transform 150ms ease;
}

.home-story.is-changing {
  opacity: 0;
  transform: translateY(calc(-50% + 7px));
}

.home-story h1 {
  margin: 11px 0 0;
  font-family: var(--display);
  font-size: clamp(48px, 5.5vw, 76px);
  font-weight: 400;
  letter-spacing: -0.045em;
  line-height: 0.92;
}

.home-story h1 em {
  color: var(--gold-bright);
  font-weight: 400;
}

.home-story__subtitle {
  margin: 17px 0 0;
  color: rgba(255, 233, 190, 0.96);
  font-family: var(--display);
  font-size: clamp(16px, 1.55vw, 21px);
  font-style: italic;
  line-height: 1.25;
}

.home-story__lore {
  max-width: 48ch;
  margin: 11px 0 0;
  color: rgba(255, 244, 222, 0.74);
  font-size: 13px;
  line-height: 1.6;
}

.home-picker {
  position: absolute;
  z-index: 6;
  left: max(28px, env(safe-area-inset-left));
  right: max(28px, env(safe-area-inset-right));
  bottom: max(22px, env(safe-area-inset-bottom));
  display: grid;
  grid-template-columns: 142px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  padding: 10px;
  border: 1px solid rgba(255, 226, 172, 0.22);
  border-radius: 20px;
  background: rgba(18, 12, 11, 0.64);
  box-shadow: 0 18px 46px rgba(8, 5, 4, 0.32);
  backdrop-filter: blur(18px);
}

.home-picker__header {
  display: grid;
  gap: 8px;
  padding: 0 10px;
  color: rgba(255, 244, 222, 0.58);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.17em;
  line-height: 1.35;
  text-transform: uppercase;
}

.home-picker__header span:last-child {
  color: var(--gold-bright);
  font-family: var(--display);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.12em;
}

.home-slides {
  display: grid;
  min-width: 0;
  grid-template-columns: repeat(5, minmax(112px, 1fr));
  gap: 8px;
}

.home-slide-button {
  position: relative;
  min-width: 0;
  height: 76px;
  padding: 0;
  overflow: hidden;
  border: 1px solid rgba(255, 227, 176, 0.16);
  border-radius: 13px;
  background: #1a1311;
  color: var(--cream);
  cursor: pointer;
  opacity: 0.7;
  text-align: left;
  transform: translateY(0);
  transition: opacity 180ms ease, transform 180ms ease, border-color 180ms ease;
  scroll-snap-align: start;
}

.home-slide-button::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 22%, rgba(13, 9, 8, 0.88) 100%);
  pointer-events: none;
}

.home-slide-button img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  filter: saturate(0.84) brightness(0.76);
  transition: filter 180ms ease, transform 420ms ease;
}

.home-slide-button > span {
  position: absolute;
  z-index: 1;
  left: 9px;
  right: 9px;
  bottom: 8px;
  display: grid;
  gap: 2px;
}

.home-slide-button strong {
  overflow: hidden;
  font-family: var(--display);
  font-size: clamp(11px, 1.05vw, 14px);
  font-weight: 400;
  line-height: 1.05;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-slide-button small {
  overflow: hidden;
  color: rgba(255, 244, 222, 0.56);
  font-size: 7px;
  font-weight: 650;
  letter-spacing: 0.06em;
  line-height: 1.1;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.home-slide-button:hover,
.home-slide-button.is-active {
  opacity: 1;
  transform: translateY(-2px);
  border-color: rgba(255, 217, 134, 0.86);
}

.home-slide-button:hover img,
.home-slide-button.is-active img {
  filter: saturate(1.04) brightness(0.96);
  transform: scale(1.025);
}

.city-wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(15, 10, 9, 0.48), transparent 24%, transparent 66%, rgba(15, 10, 9, 0.7)),
    radial-gradient(110% 90% at 50% 48%, transparent 55%, rgba(9, 7, 8, 0.32) 100%);
}

#motes {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.brand {
  position: absolute;
  z-index: 5;
  top: max(24px, env(safe-area-inset-top));
  left: max(32px, env(safe-area-inset-left));
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 244, 222, 0.8);
}

.brand-mark {
  color: var(--gold-bright);
  font-size: 16px;
  filter: drop-shadow(0 0 9px rgba(255, 210, 117, 0.9));
}

.brand-separator {
  width: 28px;
  height: 1px;
  background: rgba(255, 224, 162, 0.42);
}

.hero {
  position: absolute;
  z-index: 4;
  left: max(7vw, 48px);
  top: 50%;
  width: min(430px, 38vw);
  transform: translateY(-47%);
}

.eyebrow {
  margin: 0;
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.28em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--gold-bright);
}

.hero h1 {
  margin: 14px 0 0;
  font-family: var(--display);
  font-size: clamp(48px, 6.6vw, 92px);
  font-weight: 400;
  letter-spacing: -0.045em;
  line-height: 0.8;
  text-shadow: 0 4px 34px rgba(11, 7, 7, 0.7);
}

.hero h1 em {
  color: var(--gold-bright);
  font-weight: 400;
}

.hero-copy {
  max-width: 41ch;
  margin: 24px 0 0;
  color: var(--muted);
  font-size: clamp(13px, 1.1vw, 15px);
  line-height: 1.7;
}

.selected-district {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 30px;
}

.selected-number {
  display: grid;
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid rgba(255, 221, 153, 0.38);
  border-radius: 50%;
  background: rgba(39, 26, 22, 0.46);
  color: var(--gold-bright);
  font-family: var(--display);
  font-size: 16px;
  box-shadow: inset 0 0 18px rgba(234, 184, 85, 0.1);
  backdrop-filter: blur(8px);
}

.selected-region {
  display: block;
  margin-bottom: 3px;
  color: rgba(255, 244, 222, 0.52);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.selected-district h2 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(19px, 2vw, 27px);
  font-weight: 400;
  letter-spacing: 0.01em;
}

.enter-button {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  min-height: 52px;
  margin-top: 23px;
  padding: 5px 6px 5px 20px;
  border: 1px solid rgba(255, 223, 158, 0.42);
  border-radius: 999px;
  background: rgba(43, 27, 22, 0.56);
  color: var(--cream);
  cursor: pointer;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.07em;
  box-shadow: 0 12px 36px rgba(8, 5, 4, 0.24);
  backdrop-filter: blur(10px);
  transition: border-color 180ms ease, background 180ms ease, transform 180ms ease;
}

.enter-button:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 223, 158, 0.8);
  background: rgba(80, 48, 31, 0.72);
}

.enter-arrow {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border-radius: 50%;
  background: linear-gradient(145deg, #f3c66f, #c98d35);
  color: #25160d;
  font-size: 18px;
  box-shadow: 0 0 22px rgba(237, 185, 89, 0.34);
}

.portal-navigation {
  position: absolute;
  z-index: 4;
  top: 50%;
  right: clamp(30px, 5vw, 84px);
  width: min(48vw, 610px);
  height: min(67vw, 560px);
  max-height: 76vh;
  transform: translateY(-48%);
}

.orbit-halo,
.portal-orbit {
  position: absolute;
  inset: 0;
}

.orbit-halo::before,
.orbit-halo::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  border: 1px solid rgba(255, 215, 135, 0.2);
  border-radius: 50%;
  transform: translate(-50%, -50%) rotate(-10deg);
}

.orbit-halo::before {
  width: 76%;
  height: 58%;
  box-shadow: 0 0 42px rgba(234, 181, 78, 0.08), inset 0 0 34px rgba(234, 181, 78, 0.06);
}

.orbit-halo::after {
  width: 58%;
  height: 43%;
  border-color: rgba(255, 215, 135, 0.1);
}

.portal-button {
  --x: 0px;
  --y: 0px;
  --scale: 1;
  --portal-opacity: 1;
  position: absolute;
  left: 50%;
  top: 50%;
  width: clamp(60px, 6.3vw, 92px);
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  opacity: var(--portal-opacity);
  transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(var(--scale));
  transition: transform 620ms cubic-bezier(0.22, 0.82, 0.24, 1), opacity 420ms ease, filter 420ms ease;
  will-change: transform;
}

.portal-button::before,
.portal-button::after {
  content: "";
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
}

.portal-button::before {
  inset: -6px;
  z-index: -1;
  border: 1px solid rgba(255, 235, 194, 0.48);
  box-shadow: 0 0 0 3px rgba(215, 158, 58, 0.25), 0 0 24px rgba(235, 181, 82, 0.36);
}

.portal-button::after {
  inset: -15px;
  z-index: -2;
  border: 1px solid rgba(241, 192, 100, 0.12);
  animation: portal-ring 4.5s ease-in-out infinite;
}

.portal-button img {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%;
  object-fit: cover;
  filter: saturate(0.92) brightness(0.82);
  box-shadow: 0 16px 34px rgba(8, 5, 4, 0.45);
  transition: filter 220ms ease;
}

.portal-button:hover img,
.portal-button:focus-visible img,
.portal-button[data-slot="0"] img {
  filter: saturate(1.08) brightness(1);
}

.portal-button[data-slot="0"] {
  --x: 0px;
  --y: 0px;
  --scale: 1.58;
  z-index: 7;
}

.portal-button[data-slot="0"]::before {
  box-shadow: 0 0 0 4px rgba(215, 158, 58, 0.3), 0 0 44px rgba(244, 193, 91, 0.62), 0 18px 50px rgba(8, 5, 4, 0.55);
}

.portal-button[data-slot="-1"] { --x: -150px; --y: -112px; --scale: 0.92; z-index: 5; }
.portal-button[data-slot="1"] { --x: 150px; --y: -112px; --scale: 0.92; z-index: 5; }
.portal-button[data-slot="-2"] { --x: -194px; --y: 70px; --scale: 0.72; --portal-opacity: 0.78; z-index: 3; }
.portal-button[data-slot="2"] { --x: 194px; --y: 70px; --scale: 0.72; --portal-opacity: 0.78; z-index: 3; }
.portal-button[data-slot="-3"] { --x: -105px; --y: 184px; --scale: 0.58; --portal-opacity: 0.52; z-index: 2; }
.portal-button[data-slot="3"] { --x: 105px; --y: 184px; --scale: 0.58; --portal-opacity: 0.52; z-index: 2; }
.portal-button[data-slot="hidden-left"] { --x: -245px; --y: 160px; --scale: 0.3; --portal-opacity: 0; pointer-events: none; }
.portal-button[data-slot="hidden-right"] { --x: 245px; --y: 160px; --scale: 0.3; --portal-opacity: 0; pointer-events: none; }

.portal-label {
  position: absolute;
  left: 50%;
  top: calc(100% + 16px);
  width: max-content;
  max-width: 180px;
  opacity: 0;
  transform: translate(-50%, 6px);
  color: var(--cream);
  font-family: var(--display);
  font-size: 14px;
  letter-spacing: 0.03em;
  line-height: 1.1;
  text-align: center;
  text-shadow: 0 2px 14px rgba(12, 7, 6, 1);
  transition: opacity 260ms ease, transform 260ms ease;
  pointer-events: none;
}

.portal-button[data-slot="0"] .portal-label {
  opacity: 1;
  transform: translate(-50%, 0) scale(0.7);
}

.orbit-arrow {
  position: absolute;
  z-index: 10;
  bottom: 6%;
  display: grid;
  width: 46px;
  height: 46px;
  place-items: center;
  border: 1px solid rgba(255, 229, 177, 0.32);
  border-radius: 50%;
  background: rgba(28, 18, 16, 0.52);
  color: var(--cream);
  cursor: pointer;
  font-size: 18px;
  backdrop-filter: blur(8px);
  transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}

.orbit-arrow:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 229, 177, 0.7);
  background: rgba(71, 43, 29, 0.66);
}

.orbit-arrow--previous { left: 35%; }
.orbit-arrow--next { right: 35%; }

.orbit-caption {
  position: absolute;
  left: 50%;
  bottom: 8.2%;
  display: flex;
  gap: 5px;
  margin: 0;
  transform: translateX(-50%);
  color: rgba(255, 244, 222, 0.48);
  font-family: var(--display);
  font-size: 12px;
  letter-spacing: 0.12em;
}

.orbit-caption span:first-child {
  color: var(--gold-bright);
}

.interaction-hint {
  position: absolute;
  z-index: 5;
  right: max(28px, env(safe-area-inset-right));
  bottom: max(18px, env(safe-area-inset-bottom));
  margin: 0;
  color: rgba(255, 244, 222, 0.5);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}

.interaction-hint span {
  margin-right: 7px;
  color: var(--gold-bright);
  font-size: 14px;
}

.intro {
  position: absolute;
  z-index: 5;
  left: max(34px, env(safe-area-inset-left));
  bottom: max(30px, env(safe-area-inset-bottom));
  width: min(420px, 42vw);
  padding-left: 18px;
  border-left: 1px solid rgba(255, 218, 145, 0.5);
  text-shadow: 0 2px 20px rgba(10, 6, 5, 0.9);
}

.intro h1 {
  margin: 7px 0 0;
  font-family: var(--display);
  font-size: clamp(34px, 4.2vw, 58px);
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 0.95;
}

.intro h1 em {
  color: var(--gold-bright);
  font-weight: 400;
}

.intro > p:last-child {
  max-width: 48ch;
  margin: 10px 0 0;
  color: rgba(255, 244, 222, 0.72);
  font-size: 12px;
  line-height: 1.55;
}

#district {
  position: fixed;
  inset: 0;
  z-index: 20;
  overflow: hidden;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  background: var(--ink);
  transition: opacity 520ms ease, visibility 0s linear 520ms;
}

#district.is-open {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  transition: opacity 520ms ease;
}

.district-art,
.district-art img,
.district-scrim {
  position: absolute;
  inset: 0;
}

.district-art {
  overflow: hidden;
  background: #16100e;
}

.district-art img {
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 150ms cubic-bezier(0.33, 0, 0.25, 1);
  will-change: opacity;
}

.district-art img.is-active {
  z-index: 1;
  opacity: 1;
}

.district-art img.is-entering {
  z-index: 2;
  opacity: 0;
}

.district-art img.is-entering.is-active {
  opacity: 0.85;
}

.district-art img.is-entering.is-settling {
  opacity: 1;
}

.district-art img.is-leaving {
  opacity: 0;
}

.district-scrim {
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(17, 11, 10, 0.88), rgba(17, 11, 10, 0.24) 52%, rgba(17, 11, 10, 0.08)),
    linear-gradient(0deg, rgba(13, 9, 8, 0.68), transparent 46%);
}

.district-loading {
  position: absolute;
  left: 50%;
  top: 50%;
  margin: 0;
  transform: translate(-50%, -50%);
  color: rgba(255, 244, 222, 0.72);
  font-family: var(--display);
  font-size: 14px;
  letter-spacing: 0.08em;
  transition: opacity 180ms ease;
}

.district-loading[hidden] {
  display: block;
  opacity: 0;
}

.back-button {
  position: absolute;
  z-index: 4;
  top: max(22px, env(safe-area-inset-top));
  left: max(26px, env(safe-area-inset-left));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 17px;
  /* translucency matched to the homepage search pill (owner 2026-08-15) */
  border: 1px solid rgba(255, 233, 180, 0.4);
  border-radius: 999px;
  background: rgba(20, 14, 8, 0.62);
  color: var(--cream);
  cursor: pointer;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.back-button .back-arrow {
  display: block; /* a real drawn arrow: text glyphs sit on the baseline
                     and always hang below the optical center */
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--gold-bright);
}

.tour-status {
  position: absolute;
  z-index: 4;
  top: max(22px, env(safe-area-inset-top));
  right: max(72px, calc(env(safe-area-inset-right) + 66px)); /* clears the global ☰ */
  display: flex;
  min-height: 44px;
  align-items: center;
  gap: 12px;
  padding: 5px 6px 5px 15px;
  border: 1px solid rgba(255, 228, 176, 0.3);
  border-radius: 999px;
  background: rgba(25, 16, 14, 0.58);
  color: rgba(255, 244, 222, 0.78);
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  backdrop-filter: blur(10px);
}

.tour-status[hidden] {
  display: none;
}

/* plain district visit: the bar is a lone Sound button - one strong picture,
   the attention goes to the resident ingredients (owner 2026-08-15) */
.tour-status:not(.is-tour-mode) #tourStatusText,
.tour-status:not(.is-tour-mode) .tour-pause-button,
.tour-status:not(.is-tour-mode) .tour-step-buttons {
  display: none;
}
/* ...and the bar's own pill chrome disappears: just the button, no big
   empty oval around it */
.tour-status:not(.is-tour-mode) {
  padding: 0;
  border-color: transparent;
  background: none;
  backdrop-filter: none;
}
/* the lone Sound button: a quiet utility, translucent like the homepage
   search pill. NO hover/press states - same stoic behavior as City Map
   (the tour buttons' hover wash leaked in on touch-hold) */
.tour-status:not(.is-tour-mode) .tour-sound-button,
.tour-status:not(.is-tour-mode) .tour-sound-button:hover,
.tour-status:not(.is-tour-mode) .tour-sound-button:active {
  min-height: 34px;
  background: rgba(20, 14, 8, 0.62);
  border-color: rgba(255, 233, 180, 0.4);
  -webkit-tap-highlight-color: transparent;
}
/* and no view thumbnails outside the tour, on any screen - the panoramas
   live in the tour */
#district:not(.is-tour) .district-views {
  display: none;
}

.tour-status button {
  min-height: 32px;
  padding: 0 13px;
  border: 1px solid rgba(255, 226, 171, 0.28);
  border-radius: 999px;
  background: rgba(232, 185, 92, 0.12);
  color: var(--cream);
  cursor: pointer;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.tour-step-buttons {
  display: flex;
  align-items: center;
  gap: 4px;
}

.tour-status .tour-step-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  min-width: 32px;
  padding: 0;
}
.tour-step-button .tour-arrow {
  display: block; /* drawn gold arrows, same pen as the City Map one */
  width: 14px;
  height: 14px;
  color: var(--gold-bright);
}

.tour-status .tour-step-button:hover,
.tour-status .tour-pause-button:hover,
.tour-status .tour-sound-button:hover {
  border-color: rgba(255, 226, 171, 0.62);
  background: rgba(232, 185, 92, 0.22);
}

.district-panel {
  position: absolute;
  z-index: 3;
  /* floor raised past the corner equalizer (ends ~84px): the hero text must
     not touch it on narrow desktop windows (owner 2026-08-15) */
  left: max(7vw, 108px);
  bottom: max(7vh, 42px);
  width: min(530px, 50vw);
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 520ms 420ms ease, transform 520ms 420ms ease;
}

#district.is-open .district-panel {
  opacity: 1;
  transform: none;
}

.district-panel h2 {
  margin: 9px 0 0;
  font-family: var(--display);
  font-size: clamp(38px, 5.3vw, 70px);
  font-weight: 400;
  letter-spacing: -0.035em;
  line-height: 0.95;
  text-shadow: 0 4px 28px rgba(8, 5, 4, 0.65);
}

.district-subtitle {
  margin: 8px 0 0;
  color: var(--gold-bright);
  font-family: var(--display);
  font-size: clamp(16px, 1.55vw, 21px);
  font-style: italic;
}

.district-lore {
  max-width: 57ch;
  margin: 17px 0 0;
  color: rgba(255, 244, 222, 0.82);
  font-size: 13px;
  line-height: 1.68;
}

.resident-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}

.resident-chips span,
.resident-chips button {
  padding: 7px 12px;
  border: 1px solid rgba(255, 224, 164, 0.28);
  border-radius: 999px;
  background: rgba(24, 15, 13, 0.36);
  color: rgba(255, 244, 222, 0.82);
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.06em;
  backdrop-filter: blur(8px);
}
/* a resident whose room exists reads as a door, not a label */
.resident-chips .resident-chip--open {
  cursor: pointer;
  border-color: rgba(255, 217, 134, 0.6);
  color: var(--gold-bright);
  transition: background 220ms ease, border-color 220ms ease, transform 220ms ease;
}
.resident-chips .resident-chip--open:hover,
.resident-chips .resident-chip--open:focus-visible {
  background: rgba(233, 185, 91, 0.18);
  border-color: var(--gold-bright);
  transform: translateY(-1px);
}

.district-views {
  position: absolute;
  z-index: 4;
  right: max(30px, env(safe-area-inset-right));
  bottom: max(30px, env(safe-area-inset-bottom));
  display: flex;
  gap: 10px;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 520ms 560ms ease, transform 520ms 560ms ease;
}

#district.is-open .district-views {
  opacity: 1;
  transform: none;
}

/* cinematic arrival: near the end of the flight the district page opens in
   "ghost mode" ABOVE the video — transparent, panorama hidden — so only the
   title, description and view squares fade in over the moving picture */
body.flight-ui-early #district {
  z-index: 90;
  background: transparent;
}

body.flight-ui-early .district-art,
body.flight-ui-early .district-scrim,
body.flight-ui-early .back-button,
body.flight-ui-early .district-loading {
  visibility: hidden;
}

.view-button {
  position: relative;
  width: clamp(72px, 7vw, 104px);
  aspect-ratio: 3 / 2;
  overflow: hidden;
  padding: 0;
  border: 1px solid rgba(255, 240, 210, 0.36);
  border-radius: 9px;
  background: #211712;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 180ms ease, transform 180ms ease, border-color 180ms ease;
}

.view-button::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--gold-bright);
  box-shadow: 0 0 10px rgba(255, 213, 128, 0.7);
  transform: scaleX(0);
  transform-origin: left;
}

.view-button.is-current.is-playing::after {
  animation: view-progress var(--slide-duration, 6400ms) linear both;
}

.view-button img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.view-button:hover,
.view-button.is-current {
  opacity: 1;
  transform: translateY(-3px);
  border-color: var(--gold-bright);
}

@keyframes city-breathe {
  from { transform: translate3d(calc(var(--scene-x, 0px) - 0.5%), calc(var(--scene-y, 0px) - 0.35%), 0) scale(1.04); }
  to { transform: translate3d(calc(var(--scene-x, 0px) + 0.5%), calc(var(--scene-y, 0px) + 0.35%), 0) scale(1.065); }
}

@keyframes view-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes portal-ring {
  0%, 100% { opacity: 0.28; transform: scale(0.94) rotate(0); }
  50% { opacity: 0.72; transform: scale(1.07) rotate(180deg); }
}

@media (max-width: 900px) {
  body { overflow: auto; }

  #scene {
    position: relative;
    min-height: 100svh;
  }

  .city-layer,
  .home-backdrops { inset: -1%; }

  .city-backdrop { object-position: 57% 50%; }

  .city-wash {
    background:
      linear-gradient(180deg, rgba(17, 11, 10, 0.54), rgba(17, 11, 10, 0.08) 30%, rgba(17, 11, 10, 0.32) 55%, rgba(17, 11, 10, 0.94) 100%),
      radial-gradient(circle at 50% 36%, transparent 0 22%, rgba(12, 8, 7, 0.26) 68%);
  }

  .home-story {
    left: 20px;
    right: 20px;
    top: auto;
    bottom: max(174px, calc(env(safe-area-inset-bottom) + 162px));
    width: auto;
    transform: none;
  }

  .home-story.is-changing {
    transform: translateY(7px);
  }

  .home-story h1 {
    margin-top: 8px;
    font-size: clamp(37px, 11.5vw, 52px);
    line-height: 0.92;
  }

  .home-story__subtitle {
    margin-top: 11px;
    font-size: 15px;
  }

  .home-story__lore {
    display: none;
  }

  .home-picker {
    left: 12px;
    right: 12px;
    bottom: max(10px, env(safe-area-inset-bottom));
    display: block;
    padding: 8px;
    border-radius: 17px;
  }

  .home-picker__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 1px 5px 7px;
  }

  .home-picker__header span:last-child {
    font-size: 11px;
  }

  .home-slides {
    display: flex;
    gap: 7px;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }

  .home-slides::-webkit-scrollbar {
    display: none;
  }

  .home-slide-button {
    width: 106px;
    height: 68px;
    flex: 0 0 106px;
  }

  .home-slide-button strong {
    font-size: 12px;
  }

  .home-slide-button small {
    display: none;
  }

  .brand {
    left: max(20px, env(safe-area-inset-left));
    right: 20px;
    justify-content: center;
    font-size: 9px;
  }

  .hero {
    left: 22px;
    right: 22px;
    top: max(88px, calc(env(safe-area-inset-top) + 70px));
    width: auto;
    transform: none;
    text-align: center;
  }

  .hero h1 {
    margin-top: 9px;
    font-size: clamp(42px, 13vw, 68px);
    line-height: 0.84;
  }

  .hero-copy {
    max-width: 34ch;
    margin: 15px auto 0;
    font-size: 12px;
    line-height: 1.55;
  }

  .selected-district {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100svh - 255px);
    justify-content: center;
    margin: 0;
  }

  .selected-region { text-align: left; }

  .enter-button {
    position: absolute;
    left: 50%;
    top: calc(100svh - 183px);
    min-height: 48px;
    margin: 0;
    transform: translateX(-50%);
    white-space: nowrap;
  }

  .enter-button:hover { transform: translateX(-50%); }

  .portal-navigation {
    top: auto;
    left: 0;
    right: 0;
    bottom: max(24px, env(safe-area-inset-bottom));
    width: 100%;
    height: 150px;
    max-height: none;
    transform: none;
  }

  .orbit-halo::before {
    width: min(92vw, 560px);
    height: 94px;
  }

  .orbit-halo::after { display: none; }

  .portal-button {
    width: 58px;
    top: 42%;
  }

  .portal-button[data-slot="0"] { --x: 0px; --y: 0px; --scale: 1.32; }
  .portal-button[data-slot="-1"] { --x: -84px; --y: 4px; --scale: 0.88; }
  .portal-button[data-slot="1"] { --x: 84px; --y: 4px; --scale: 0.88; }
  .portal-button[data-slot="-2"] { --x: -148px; --y: 10px; --scale: 0.63; --portal-opacity: 0.62; }
  .portal-button[data-slot="2"] { --x: 148px; --y: 10px; --scale: 0.63; --portal-opacity: 0.62; }
  .portal-button[data-slot="-3"],
  .portal-button[data-slot="3"] { --portal-opacity: 0; pointer-events: none; }
  .portal-button[data-slot="hidden-left"] { --x: -210px; --y: 10px; }
  .portal-button[data-slot="hidden-right"] { --x: 210px; --y: 10px; }

  .portal-label { display: none; }

  .orbit-arrow {
    bottom: 5px;
    width: 38px;
    height: 38px;
  }

  .orbit-arrow--previous { left: calc(50% - 72px); }
  .orbit-arrow--next { right: calc(50% - 72px); }

  .orbit-caption { bottom: 17px; }

  .interaction-hint { display: none; }

  .intro {
    left: 20px;
    right: 20px;
    bottom: max(112px, calc(env(safe-area-inset-bottom) + 100px));
    width: auto;
    padding-left: 14px;
  }

  .intro h1 {
    font-size: clamp(35px, 11vw, 50px);
  }

  .intro > p:last-child {
    max-width: 34ch;
    font-size: 11px;
  }

  /* ---- phone panorama mode (owner 2026-08-15) ----
     The picture sits in the TOP zone at FULL image height (no vertical
     crop: every view fits by height, wider than the screen), then slowly
     pans left-to-right; the next view starts at its left edge again.
     Arrival from a flight is seamless: the art opens fullscreen on the
     video's center crop, then the black bar fades in and the picture
     glides into the top zone - no jumps. ---- */
  .district-art {
    bottom: 45%;
    transition: bottom 850ms cubic-bezier(0.33, 0.01, 0.2, 1);
  }
  .district-scrim { transition: opacity 850ms ease; }
  body.flight-settle .district-art { bottom: 0; transition: none; }
  body.flight-settle .district-scrim { opacity: 0; transition: none; }

  .district-art img {
    width: auto;
    max-width: none;
    height: 100%;
  }
  .district-art img.is-active {
    animation: panoramaPan var(--pan-ms, 5800ms) linear forwards;
  }
  /* plain district visit on phones (owner 2026-08-15): NO picture motion.
     The view sits still on its center crop - exactly as the flight left it.
     Every pan below applies to the TOUR only. */
  #district:not(.is-tour) .district-art img.is-active {
    animation: none;
    transform: translateX(calc(min(0px, 100vw - 100%) / 2));
  }
  body.pan-hold .district-art img.is-active {
    animation-name: panoramaArrive; /* arrival view: starts on the video's
      CENTER crop (seamless), settles first, then pans right */
    animation-delay: 900ms; /* settle first (the shrink is 850ms) */
    animation-fill-mode: both;
  }
  @keyframes panoramaPan {
    from { transform: translateX(0); }
    to   { transform: translateX(min(0px, calc(100vw - 100%))); }
  }
  @keyframes panoramaArrive {
    from { transform: translateX(calc(min(0px, 100vw - 100%) / 2)); }
    to   { transform: translateX(min(0px, calc(100vw - 100%))); }
  }

  /* phones: a compact City Map pill (the desktop one is huge on a photo
     this small) */
  .back-button {
    top: max(12px, env(safe-area-inset-top));
    left: 12px;
    min-height: 34px;
    padding: 0 12px;
    gap: 6px;
    font-size: 9.5px;
  }
  .back-button .back-arrow { width: 13px; height: 13px; }

  /* phones (owner 2026-08-15): the tour controls must NOT cover the
     panorama - they sit at the very bottom of the black bar, and the
     thumbnails/panel lift up to make room while the tour is on */
  .tour-status {
    top: auto;
    bottom: max(6px, env(safe-area-inset-bottom));
    left: 10px;
    right: 10px;
    justify-content: center;
    gap: 6px;
    padding: 4px 6px;
  }
  /* mobile tour: the equalizer rides one floor ABOVE the tour bar */
  #district.is-open.is-tour ~ .city-eq {
    bottom: max(58px, calc(env(safe-area-inset-bottom) + 52px));
  }

  /* plain visit: the lone Sound button sits top-right, LEFT of the global ☰ */
  .tour-status:not(.is-tour-mode) {
    top: max(16px, env(safe-area-inset-top));
    bottom: auto;
    left: auto;
    right: 64px;
    padding: 0;
  }

  .tour-status #tourStatusText {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 9px;
    letter-spacing: 0.08em;
    white-space: nowrap;
  }

  .tour-status button { white-space: nowrap; }

  .tour-status .tour-pause-button {
    padding: 0 10px;
  }


  .tour-step-buttons { gap: 3px; }

  .district-art img { height: 100%; }

  .district-scrim {
    background: linear-gradient(0deg, rgba(16, 10, 9, 1) 0 41%, rgba(16, 10, 9, 0.5) 58%, transparent 74%);
  }

  /* percentage anchoring (owner 2026-08-15): the text block hangs from the
     TOP of the black zone (photo = top 55%), so every phone height shows
     the SAME composition. The eyebrow line rides ON the photo's bottom
     edge; the district name starts the black zone. */
  .district-panel {
    left: 22px;
    right: 22px;
    top: 55%; /* the district NAME starts exactly at the black zone */
    bottom: auto;
    width: auto;
  }
  .district-panel .eyebrow {
    /* the eyebrow hangs fully ABOVE the panel, on the photo's bottom edge -
       whatever its height, the name below never climbs onto the picture */
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    margin: 0 0 7px;
    text-shadow: 0 1px 10px rgba(10, 6, 5, 0.85);
  }
  .district-panel h2 { margin-top: 0; }

  .district-panel h2 { font-size: clamp(35px, 10vw, 52px); }

  .district-lore {
    display: -webkit-box;
    overflow: hidden;
    margin-top: 11px;
    font-size: 12px;
    line-height: 1.5;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
  }

  .resident-chips { margin-top: 12px; }

  /* phones (owner 2026-08-15): no view thumbnails - they doubled the tour
     arrows, ate precious screen and other buttons peeked from under them.
     Views rotate on their own (and via the tour arrows). */
  .district-views { display: none; }
}

@media (max-width: 420px) and (max-height: 740px) {
  .hero-copy { display: none; }
  .hero { top: 78px; }
  .selected-district { top: calc(100svh - 244px); }
  .enter-button { top: calc(100svh - 176px); }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* 2026 immersive city entrance */
.home-backdrop {
  opacity: 1;
  filter: none;
  transition: none;
}

/* full-screen wash removed by owner decision: the picture stays untouched;
   readability comes from a local scrim under the text block only */
.city-wash {
  background: none;
}

.home-story::before {
  content: "";
  position: absolute;
  inset: -48px -64px -56px -64px;
  z-index: -1;
  border-radius: 32px;
  background: radial-gradient(closest-side, rgba(12, 8, 7, 0.55) 0%, rgba(12, 8, 7, 0.38) 55%, transparent 100%);
  pointer-events: none;
}

/* owner trial 2026-08-09: header block in the TOP-RIGHT corner */
.home-story {
  left: auto;
  right: max(3vw, 40px);
  top: max(7vh, 54px);
  transform: none;
  width: min(540px, 44vw);
}

.home-story__lore {
  max-width: 46ch;
  font-size: 14px;
}

.home-city-count {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-top: 19px;
  color: rgba(255, 244, 222, 0.82);
  text-shadow: 0 3px 24px rgba(10, 6, 5, 0.9);
}

.home-city-count strong {
  color: var(--gold-bright);
  font-family: var(--display);
  font-size: clamp(54px, 5vw, 72px);
  font-weight: 400;
  letter-spacing: -0.06em;
  line-height: 0.75;
}

.home-city-count span {
  padding-left: 14px;
  border-left: 1px solid rgba(255, 221, 157, 0.38);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.13em;
  line-height: 1.35;
  text-transform: uppercase;
}

.home-city-count small {
  color: rgba(255, 244, 222, 0.56);
  font-size: 8px;
  letter-spacing: 0.12em;
}

.home-tour-icon {
  color: var(--gold-bright);
  font-size: 9px;
}

@media (max-width: 900px) {
  .home-backdrop {
    object-position: 50% 50%;
  }

  .home-story {
    right: 20px;
    top: auto;
    bottom: max(30px, calc(env(safe-area-inset-bottom) + 22px));
    width: auto;
  }

  .home-story__lore {
    display: block;
    max-width: 38ch;
    font-size: 12px;
    line-height: 1.45;
  }

  .home-city-count {
    margin-top: 16px;
  }

  .home-city-count strong {
    font-size: 54px;
  }
}

@media (max-width: 420px) and (max-height: 740px) {
  .home-story__lore {
    display: none;
  }

  .home-story h1 {
    font-size: 39px;
  }

  .home-city-count {
    margin-top: 12px;
  }

  .home-city-count strong {
    font-size: 45px;
  }
}

/* (old city-player panel removed 2026-08-12: the sun is the player now) */



.sheet-grid {
  flex: 1;
  overflow-y: auto;
  display: grid;
  /* four to a row in the same width (owner 2026-09-07): the cards grow */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 12px;
  padding: 6px 18px calc(18px + env(safe-area-inset-bottom));
  max-width: 1180px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
  align-content: start;
  grid-auto-rows: max-content;
}
.sheet-card {
  display: flex;
  flex-direction: column;
  padding: 0;
  border: 1px solid rgba(255, 223, 150, 0.3);
  border-radius: 14px;
  overflow: hidden;
  background: rgba(18, 12, 7, 0.88);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4);
  cursor: pointer;
  text-align: left;
  transition: border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
.sheet-card:hover {
  border-color: rgba(255, 223, 150, 0.65);
  box-shadow: 0 4px 18px rgba(255, 214, 130, 0.18);
  transform: translateY(-2px);
}
.sheet-card img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
  flex: none;
}
.sheet-card-copy {
  display: flex;
  flex-direction: column;
  padding: 8px 12px 9px;
}
/* the tour card (first in the grid): three cities fanned diagonally */
.tour-collage {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  /* only the hairline seams between the slices show this - warm gold, in
     tone with the card borders (dark seams read as mourning bands) */
  background: rgba(228, 195, 130, 0.85);
}
/* three cities in one frame, split by TRUE 45-degree diagonals (owner
   2026-08-15). The box is 3:2, so a 45-degree line shifts 66.7% of the
   width over the full height; 3% gaps leave dark diagonal seams. */
.tour-collage img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.tour-collage img:nth-child(1) { clip-path: polygon(-100% 0, 56% 0, -10.7% 100%, -100% 100%); object-position: 0% 50%; }    /* Respiratory: the cheese */
.tour-collage img:nth-child(2) { clip-path: polygon(56.8% 0, 109% 0, 42.3% 100%, -9.9% 100%); }                             /* Energy: fin roofs */
.tour-collage img:nth-child(3) { clip-path: polygon(109.8% 0, 250% 0, 250% 100%, 43.1% 100%); object-position: 11% 50%; }   /* Weight: the ring tower */
.tour-collage::after { /* play badge so the card reads as "watch". Kept clear
  of the card's rounded corner: overflow clipping was shaving the circle */
  content: "\25B6";
  position: absolute;
  right: 10%;
  top: 15%;
  z-index: 3;
  display: grid;
  place-items: center;
  box-sizing: border-box; /* the play-nudge padding must not stretch the circle */
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(18, 12, 7, 0.78);
  border: 1px solid rgba(255, 233, 180, 0.55);
  color: #ffe9bd;
  font-size: 11px;
  padding-left: 3px;
}
.sheet-card-copy strong {
  font-family: var(--display);
  font-size: 16px;
  color: #fff6e2;
}
.sheet-card-copy small {
  font-size: 11.5px;
  line-height: 1.35;
  color: rgba(255, 233, 189, 0.6);
}
.sheet-empty {
  padding: 30px 20px;
  text-align: center;
  color: rgba(255, 233, 189, 0.65);
}


/* ---- top bar (2026-08-13): search is the site's primary function and
   lives at the very top, with the city tour and the future settings menu
   beside it. Left padding clears the sun. ---- */
.top-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 14px 16px 10px;
  /* the bar is a layout strip only - taps must reach the sun and the sky
     beneath it (mobile bug 2026-08-14); only its controls catch clicks */
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.top-bar > * { pointer-events: auto; }
/* the GLOBAL menu button: one element, fixed top-right over EVERY view
   (home, districts, tour). Future settings live behind it. */
.top-menu-button {
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  right: max(14px, env(safe-area-inset-right));
  z-index: 30;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(255, 233, 180, 0.4);
  background: rgba(20, 14, 8, 0.62);
  color: #ffe9bd;
  font-size: 17px;
  cursor: pointer;
  transition: border-color 250ms ease, box-shadow 250ms ease;
}
.top-menu-button:hover {
  border-color: rgba(255, 233, 180, 0.9);
  box-shadow: 0 0 14px rgba(255, 214, 130, 0.4);
}

/* ---- the site menu and its pages (owner 2026-08-15): standard pages,
   text first - About, Disclaimer, Terms, Privacy, Contact ---- */
.menu-panel {
  position: fixed;
  top: calc(max(14px, env(safe-area-inset-top)) + 50px);
  right: max(14px, env(safe-area-inset-right));
  z-index: 30;
  display: flex;
  flex-direction: column;
  min-width: 214px;
  padding: 8px;
  border: 1px solid rgba(255, 223, 150, 0.35);
  border-radius: 16px;
  background: rgba(18, 12, 7, 0.94);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
}
.menu-panel[hidden] { display: none; }
.menu-panel button {
  padding: 11px 14px;
  border: none;
  border-radius: 10px;
  background: none;
  color: rgba(255, 244, 222, 0.88);
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}
.menu-panel button:hover {
  background: rgba(232, 185, 92, 0.14);
  color: #fff6e2;
}

.info-page {
  position: fixed;
  inset: 0;
  z-index: 25; /* over districts (20), under the global menu (30) */
  visibility: hidden;
  opacity: 0;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(64, 42, 20, 0.5), transparent 60%),
    var(--ink);
  transition: opacity 380ms ease, visibility 0s linear 380ms;
}
.info-page.is-open {
  visibility: visible;
  opacity: 1;
  transition: opacity 380ms ease;
}
.info-back { z-index: 2; }
.info-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  padding: 104px 22px 72px;
}
.info-content {
  max-width: 680px;
  margin: 0 auto;
  color: rgba(255, 244, 222, 0.86);
}
.info-hero {
  margin: 0 0 26px;
}
.info-hero img {
  display: block;
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
  border: 1px solid rgba(255, 223, 150, 0.35);
  border-radius: 18px;
  box-shadow: 0 10px 36px rgba(0, 0, 0, 0.45);
}
.info-content h2 {
  margin: 6px 0 22px;
  font-family: var(--display);
  font-size: clamp(34px, 6vw, 52px);
  font-weight: 500;
  color: #fff6e2;
}
.info-content #infoBody h3 {
  margin: 30px 0 8px;
  font-family: var(--display);
  font-size: 21px;
  font-weight: 500;
  color: var(--gold-bright);
}
.info-content #infoBody p {
  margin: 12px 0;
  font-size: 15px;
  line-height: 1.75;
}
.info-content #infoBody ul {
  margin: 12px 0;
  padding-left: 22px;
  font-size: 15px;
  line-height: 1.75;
}
.info-content #infoBody a {
  color: var(--gold-bright);
  text-decoration-color: rgba(232, 185, 92, 0.5);
}
.info-content #infoBody .info-note {
  margin-top: 30px;
  padding: 14px 18px;
  border: 1px solid rgba(255, 223, 150, 0.3);
  border-radius: 12px;
  background: rgba(232, 185, 92, 0.07);
  font-size: 13.5px;
  line-height: 1.6;
  color: rgba(255, 233, 189, 0.75);
}
.sheet-search {
  flex: 0 1 360px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-radius: 999px;
  background: rgba(20, 14, 8, 0.62);
  border: 1px solid rgba(255, 233, 180, 0.4);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
  color: rgba(255, 233, 189, 0.75);
  cursor: pointer;
}
.sheet-search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  font: inherit;
  font-size: 15px;
  color: #fff6e2;
  -webkit-user-select: text;
  user-select: text;
}
.sheet-search input::placeholder { color: rgba(255, 233, 189, 0.55); }

/* the district panel now DROPS from under the bar */
.district-sheet {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 8;
  height: min(86vh, 900px);
  display: flex;
  flex-direction: column;
  /* cards start BELOW the sun (bug 2026-08-14: scrolled card slivers used to
     hide right beside the sun and steal "close" taps, opening random
     districts). The strip around the sun is pure sky = tap-to-close. */
  padding-top: calc(max(16px, env(safe-area-inset-top)) + clamp(96px, 10vw, 164px) + 8px);
  /* no backdrop (owner 2026-08-13): the cards float over the living site */
  background: transparent;
  pointer-events: none;
  transform: translateY(-104%);
  transition: transform 420ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
.district-sheet.is-open { transform: translateY(0); }
.district-sheet .sheet-grid { pointer-events: auto; }
/* while the panel is open the search pill must stay clearly visible - the
   user is mid-typing an ingredient */
body.sheet-open .sheet-search {
  background: rgba(18, 12, 7, 0.88);
  border-color: rgba(255, 233, 180, 0.65);
}
body.sheet-open .top-menu-button {
  background: rgba(18, 12, 7, 0.88);
}
/* open panel = the sun is DISABLED as a music control: default cursor, no
   hover glow on the play mark, no pause-bars hover swap (owner 2026-08-14) */
body.sheet-open .city-sun { cursor: default; }
body.sheet-open .city-sun:hover .city-sun-symbol svg path,
body.sheet-open .city-sun:hover .city-sun-symbol svg rect {
  fill: rgba(248, 192, 78, 0.1);
  stroke: rgba(120, 78, 22, 0.32);
  stroke-width: 1;
}

/* hero drops below the bar */
.home-story { padding-top: 0; }

@media (max-width: 640px) {
  .top-bar { justify-content: flex-start; padding-left: 106px; padding-right: 64px; gap: 8px; } /* right pad clears the global ☰ */
  .sheet-grid { grid-template-columns: repeat(2, 1fr); gap: 9px; padding: 4px 10px 16px; }
  .sheet-card-copy strong { font-size: 14px; }
  .sheet-card-copy small { font-size: 10.5px; }
  .district-sheet { height: 92vh; }
  .home-story { padding-top: 0; }
}


/* ---- the resident's room (owner 2026-09-06) ------------------------------
   Portrait on the left in a plate that will later become the district frame
   with its museum label; the reading column on the right. On a phone the
   plate goes full width and the text falls underneath. ---- */
.resident-page {
  position: fixed;
  inset: 0;
  z-index: 24; /* over districts (20); UNDER the info pages (25) so the global
                 menu can open About / Shop / Terms on top of a resident's room */
  visibility: hidden;
  opacity: 0;
  background: var(--ink);
  transition: opacity 380ms ease, visibility 0s linear 380ms;
}
.resident-page.is-open {
  visibility: visible;
  opacity: 1;
  transition: opacity 380ms ease;
}
.resident-back { z-index: 2; }
.resident-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  padding: 96px 22px 96px;
}
.resident-content {
  /* one reading column, 60-75 characters a line, nothing beside it */
  display: block;
  max-width: 760px;
  margin: 0 auto;
  color: rgba(255, 244, 222, 0.88);
}
.resident-plate {
  /* the portrait opens the page and then scrolls away with everything else */
  position: static;
  margin: 0 auto 34px;
  max-width: 500px;
}
.resident-plate img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 70vh;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border: 1px solid rgba(255, 223, 150, 0.35);
  border-radius: 18px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
}
/* the museum label: today a plain plate, later the engraved plaque on the frame */
.resident-label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 14px;
  padding: 12px 16px;
  border: 1px solid rgba(255, 223, 150, 0.28);
  border-radius: 12px;
  background: rgba(24, 15, 13, 0.5);
  text-align: center;
}
.resident-label__name {
  font-family: var(--display);
  font-size: 19px;
  color: var(--gold-bright);
}
.resident-label__place {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 244, 222, 0.6);
}
.resident-text .eyebrow { text-align: center; }
.resident-text h2 {
  margin: 6px 0 4px;
  font-family: var(--display);
  font-size: clamp(38px, 5.4vw, 56px);
  font-weight: 500;
  line-height: 1.08;
  color: #fff6e2;
  text-align: center;
}
.resident-role {
  margin: 0 0 26px;
  font-family: var(--display);
  font-size: 19px;
  font-style: italic;
  color: var(--gold);
  text-align: center;
}
.resident-text h3 {
  margin: 44px 0 12px;
  font-family: var(--display);
  font-size: 27px;
  font-weight: 500;
  line-height: 1.25;
  color: var(--gold-bright);
}
.resident-text p {
  margin: 15px 0;
  font-size: 20px;
  line-height: 1.7;
}
.resident-text ul {
  margin: 15px 0;
  padding-left: 26px;
  font-size: 20px;
  line-height: 1.7;
}
.resident-text li { margin: 8px 0; }
.resident-lede {
  font-family: var(--display);
  font-size: 17px !important;
  line-height: 1.8 !important;
  color: rgba(255, 244, 222, 0.95);
}
/* the honest small print: quieter than the story, never hidden */
.resident-limit {
  padding-left: 14px;
  border-left: 2px solid rgba(233, 185, 91, 0.45);
  font-size: 14px !important;
  color: rgba(255, 244, 222, 0.66);
}
.resident-fiction {
  margin-top: 30px !important;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 223, 150, 0.18);
  font-size: 13px !important;
  color: rgba(255, 244, 222, 0.5);
}

@media (max-width: 860px) {
  .resident-scroll { padding: 88px 18px 80px; }
  .resident-text p, .resident-text ul { font-size: 17.5px; }
  .resident-plate { max-width: 400px; }
}


/* ---- resident room: hook, quick take-away, quiet sources -----------------
   Owner 2026-09-06: no footnote numbers in the flow. A claim carries a dotted
   rule; clicking it drops its source under the paragraph. A reader who does not
   care never sees a citation. ---- */
.resident-hook {
  margin: 0 0 30px !important;
  font-family: var(--display);
  font-size: clamp(24px, 3vw, 33px) !important;
  line-height: 1.4 !important;
  color: var(--gold-bright);
  text-align: center;
}
.resident-quick {
  display: grid;
  grid-template-columns: minmax(150px, auto) 1fr;
  gap: 14px 22px;
  margin: 0 0 34px;
  padding: 20px 22px;
  border: 1px solid rgba(255, 223, 150, 0.22);
  border-radius: 14px;
  background: rgba(24, 15, 13, 0.42);
}
.resident-quick dt {
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 244, 222, 0.55);
  padding-top: 5px; /* sits on the first line of its answer, not mid-block */
}
.resident-quick dd {
  margin: 0;
  font-size: 17px;
  line-height: 1.6;
  color: rgba(255, 244, 222, 0.9);
}
.resident-quick em { font-style: italic; color: var(--gold-bright); }

/* the claim that can be checked */
.resident-text .fact {
  /* a <button> is inline-block by default: a long claim would jump to its own
     line, centre itself and strand the comma after it. Flow it like words. */
  display: inline;
  text-align: inherit;
  white-space: normal;
  line-height: inherit;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline dotted rgba(233, 185, 91, 0.75);
  text-underline-offset: 4px;
  transition: color 200ms ease;
}
.resident-text .fact:hover,
.resident-text .fact:focus-visible,
.resident-text .fact.is-open { color: var(--gold-bright); }
.resident-text .fact:focus-visible {
  outline: 2px solid rgba(255, 217, 134, 0.6);
  outline-offset: 3px;
  border-radius: 3px;
}

/* the source line, folded away until asked for */
.resident-text .cite-note {
  margin: -2px 0 18px !important;
  padding: 10px 14px;
  border-left: 2px solid rgba(233, 185, 91, 0.5);
  background: rgba(233, 185, 91, 0.06);
  border-radius: 0 8px 8px 0;
  font-size: 15.5px !important;
  line-height: 1.6 !important;
  color: rgba(255, 244, 222, 0.68);
}
.resident-text .cite-note a {
  color: var(--gold-bright);
  text-decoration-color: rgba(232, 185, 92, 0.5);
}

/* the honest line between the plant and the story */
.resident-truth {
  margin-top: 38px;
  padding: 22px 24px;
  border: 1px solid rgba(255, 223, 150, 0.2);
  border-radius: 14px;
  background: rgba(24, 15, 13, 0.42);
}
.resident-truth h3 { margin-top: 0 !important; }
.resident-truth strong { color: var(--gold-bright); font-weight: 500; }

@media (max-width: 860px) {
  .resident-quick { grid-template-columns: 1fr; gap: 4px 0; }
  .resident-quick dt { padding-top: 12px; }
  .resident-quick dt:first-of-type { padding-top: 0; }
}


/* ---- the room's district backdrop ----------------------------------------
   Owner 2026-09-06, final rule: the panorama stays BRIGHT and SHARP over the
   whole screen, nothing dims it. The darkening lives only under the text, as a
   panel a little wider than the words, so the letters never mix with the
   picture. No blur, no washes, no filters. ---- */
.resident-backdrop {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.resident-backdrop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 35%;
  filter: none;
}
.resident-scrim { display: none; }
.resident-scroll { position: absolute; }

/* the reading panel: the only dark thing on the page */
.resident-text {
  padding: 26px 40px 44px;
  border-radius: 20px;
  background: rgba(14, 10, 9, 0.8);
  border: 1px solid rgba(255, 223, 150, 0.14);
  text-shadow: none;
}
/* insets inside the panel sit a shade deeper than the panel itself */
.resident-quick,
.resident-truth,
.resident-text .cite-note {
  background: rgba(10, 7, 6, 0.6);
}
/* the museum label under the portrait is its own small dark plate */
.resident-label {
  background: rgba(14, 10, 9, 0.72);
}
@media (max-width: 860px) {
  .resident-text { padding: 18px 20px 32px; border-radius: 16px; }
}


/* ---- the room in its district's colours ----------------------------------
   Owner 2026-09-06: the world is many-coloured, so is the room. Chapter heads
   rotate through the district's accents; the hook, labels, source marks, inset
   rules and the portrait plate each take their own. Body text stays cream so
   the reading never suffers. Variables are set per district by app.js. ---- */
.resident-page {
  --room-1: var(--gold-bright); --room-2: var(--gold-bright); --room-3: var(--gold-bright);
  --room-4: var(--gold-bright); --room-5: var(--gold-bright); --room-6: var(--gold-bright);
  --room-neutral: rgba(255, 223, 150, 0.35);
}
.resident-text .eyebrow { color: var(--room-2); }
.resident-role { color: var(--room-3); }
.resident-hook { color: var(--room-1); }
/* chapter heads: cream by default, and each one lit by a different accent */
.resident-text h3 { color: #fff6e2; padding-left: 0; }
.resident-text h3:nth-of-type(6n+1) { color: var(--room-1); }
.resident-text h3:nth-of-type(6n+2) { color: var(--room-2); }
.resident-text h3:nth-of-type(6n+3) { color: var(--room-3); }
.resident-text h3:nth-of-type(6n+4) { color: var(--room-4); }
.resident-text h3:nth-of-type(6n+5) { color: var(--room-5); }
.resident-text h3:nth-of-type(6n+6) { color: var(--room-6); }
/* the five-second take-away: each label its own colour */
.resident-quick { border-color: var(--room-neutral); }
.resident-quick dt:nth-of-type(1) { color: var(--room-1); }
.resident-quick dt:nth-of-type(2) { color: var(--room-2); }
.resident-quick dt:nth-of-type(3) { color: var(--room-3); }
.resident-quick dt:nth-of-type(4) { color: var(--room-4); }
.resident-quick em { color: var(--room-5); }
/* sources: the claim's dotted mark and the note that opens under it */
/* sourced phrases wear their chapter's colour at rest; hover and open only
   brighten them. The note under the paragraph matches. */
.resident-text .fact { color: var(--chapter, var(--room-2)); text-decoration-color: var(--chapter, var(--room-2)); }
.resident-text .fact:hover,
.resident-text .fact:focus-visible,
.resident-text .fact.is-open { color: var(--chapter, var(--room-2)); filter: brightness(1.18); text-decoration-style: solid; }
.resident-text .cite-note { border-left-color: var(--chapter, var(--room-2)); }
.resident-text .cite-note a { color: var(--chapter, var(--room-2)); text-decoration-color: var(--chapter, var(--room-2)); }
.resident-text [data-chapter="1"] { --chapter: var(--room-1); }
.resident-text [data-chapter="2"] { --chapter: var(--room-2); }
.resident-text [data-chapter="3"] { --chapter: var(--room-3); }
.resident-text [data-chapter="4"] { --chapter: var(--room-4); }
.resident-text [data-chapter="5"] { --chapter: var(--room-5); }
.resident-text [data-chapter="6"] { --chapter: var(--room-6); }
/* what is real / what is ours */
.resident-truth { border-color: var(--room-neutral); }
.resident-truth strong { color: var(--room-4); }
/* the portrait plate and its label take the district marble */
.resident-plate img { border-color: var(--room-neutral); }
.resident-label { border-color: var(--room-neutral); }
.resident-label__name { color: var(--room-1); }
.resident-text { border-color: var(--room-neutral); }


/* ---- the resident's own ornament (owner 2026-09-06) ------------------------
   A small piece of the resident, drawn from their card, stands before every
   chapter head and replaces the dot of every list item. Serious things said
   with a smile. The image comes per resident from app.js as --room-ornament. */
.resident-page.has-ornament .resident-text h3 {
  display: flex;
  align-items: center;
  gap: 12px;
}
.resident-page.has-ornament .resident-text h3::before {
  content: "";
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  background: var(--room-ornament) center / contain no-repeat;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.45));
}
.resident-page.has-ornament .resident-text ul {
  list-style: none;
  padding-left: 0;
}
.resident-page.has-ornament .resident-text ul li {
  position: relative;
  padding-left: 32px;
}
.resident-page.has-ornament .resident-text ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35em;
  width: 20px;
  height: 20px;
  background: var(--room-ornament) center / contain no-repeat;
}
/* between chapters: her beam, a thin brass line with the pivot orb in the middle */
.resident-text h3:not(:first-of-type) {
  position: relative;
  margin-top: 54px;
}
.resident-text h3:not(:first-of-type)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -30px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--room-2) 18%, var(--room-2) 82%, transparent);
  opacity: 0.55;
}
.resident-quick dt {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}


/* ---- resident cards in the district panel (owner 2026-09-06) --------------
   Pills are gone. Each resident is a small portrait card, the same grammar as
   the district sheet, in a grid that takes any number of residents. ---- */
.resident-chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  padding: 6px 18px calc(18px + env(safe-area-inset-bottom));
  max-width: 1180px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
  align-content: start;
  grid-auto-rows: max-content;
  overflow-y: auto;
  pointer-events: auto;
}
.resident-chips .resident-card {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  border: 1px solid rgba(255, 223, 150, 0.3);
  border-radius: 12px;
  overflow: hidden;
  background: rgba(18, 12, 7, 0.88);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4);
  font: inherit;
  color: rgba(255, 244, 222, 0.9);
  text-align: left;
  cursor: default;
}
.resident-chips .resident-card img {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: 50% 12%;
}
.resident-chips .resident-card strong {
  display: block;
  padding: 8px 11px 9px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.3;
}
/* a built room is a door */
.resident-chips .resident-card--open {
  cursor: pointer;
  border-color: rgba(255, 217, 134, 0.6);
  transition: border-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
.resident-chips .resident-card--open:hover,
.resident-chips .resident-card--open:focus-visible {
  border-color: var(--gold-bright);
  box-shadow: 0 4px 18px rgba(255, 214, 130, 0.18);
  transform: translateY(-2px);
}
.resident-chips .resident-card--open strong { color: var(--gold-bright); }
@media (max-width: 860px) {
  .resident-chips { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 8px; }
}


/* ---- residents sheet inside a district (owner 2026-09-06) -----------------
   The pill sits top-centre like the homepage search; the sheet slides down
   from the top over the panorama, transparent, and leaves when tapped away. */
#district .residents-search {
  position: absolute;
  z-index: 6;
  top: max(22px, env(safe-area-inset-top)); /* same row and height as Land map */
  left: 50%;
  transform: translateX(-50%);
  width: min(320px, 26vw);
  pointer-events: auto;
  opacity: 0;
  transition: opacity 400ms 500ms ease, background 200ms ease, border-color 200ms ease;
}
#district.is-open .residents-search { opacity: 1; }
#district.residents-open .residents-search {
  background: rgba(18, 12, 7, 0.88);
  border-color: rgba(255, 233, 180, 0.65);
}
.residents-sheet {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  height: min(86vh, 900px);
  display: flex;
  flex-direction: column;
  padding-top: calc(max(14px, env(safe-area-inset-top)) + 64px);
  background: transparent;
  pointer-events: none;
  /* owner 2026-09-07: no sliding, no dimming. The residents fade in with the
     district words (same timing as .district-panel) and stay on the page. */
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 520ms 420ms ease, transform 520ms 420ms ease;
}
#district.is-open .residents-sheet { opacity: 1; transform: none; }
.residents-empty { pointer-events: none; }
@media (max-width: 860px) {
  /* narrow screens: the top row belongs to Land map / Sound / menu; the
     residents pill takes the next row so nothing overlaps */
  #district .residents-search {
    top: calc(max(14px, env(safe-area-inset-top)) + 58px);
    width: min(320px, 78vw);
  }
  .residents-sheet { padding-top: calc(max(14px, env(safe-area-inset-top)) + 120px); }
  .resident-chips { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
}


/* ---- resident cards in the homepage search (owner 2026-09-06) ---- */
.sheet-card--resident img { object-position: 50% 50%; } /* same 3:2 picture as a district card */
.sheet-card--resident .sheet-card-copy small {
  margin-top: 2px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 244, 222, 0.55);
}
.sheet-card--resident strong { color: var(--gold-bright); }


/* ---- soft haze under the district words (owner 2026-09-06) ----------------
   The same borderless dark pool the homepage headline sits in
   (.home-story::before): only under the text block, fading to nothing, so the
   panorama stays untouched everywhere else. Lives inside the panel's own
   stacking context, so nothing in the picture layers can get above it. */
.district-panel { isolation: isolate; }
.district-panel::before {
  content: "";
  position: absolute;
  inset: -56px -72px -64px -72px;
  z-index: -1;
  border-radius: 36px;
  background: radial-gradient(closest-side, rgba(12, 8, 7, 0.62) 0%, rgba(12, 8, 7, 0.42) 55%, transparent 100%);
  pointer-events: none;
}
@media (max-width: 860px) {
  /* phones already sit the text on the black zone; no extra pool there */
  .district-panel::before { display: none; }
}

/* in the land tour the top-right bar is wide (counter, arrows, pause, sound):
   the residents pill drops to the next row so they never touch */
#district.is-tour .residents-search,
#district.is-tour .residents-sheet { display: none; } /* the tour is a ride, not a place to search (owner 2026-09-07) */


/* ---- glass card behind the words (owner 2026-09-07) -------------------------
   Option two from the research: one clean semi-transparent card behind the
   whole text block, crisp edges, thin rim, the picture softly frosted behind
   it. Nothing outside the card is touched. */
.city-wash { background: none; }

.home-story::before,
.district-panel::before {
  /* --card-feather: how far the edge fades out, in pixels. The fill in the
     middle stays even; only the rim dissolves. --card-dark: the darkening. */
  --card-feather: 28px;
  --card-dark: 0.5;
  content: "";
  position: absolute;
  /* the box grows by the feather so the solid part still covers the words */
  inset: calc(-14px - var(--card-feather)) calc(-18px - var(--card-feather)) calc(-16px - var(--card-feather)) calc(-18px - var(--card-feather));
  z-index: -1;
  border-radius: 16px;
  background: rgba(12, 8, 7, var(--card-dark));
  filter: blur(var(--card-feather));
  pointer-events: none;
}
/* the blocks shrink to their own text, so the card is only as wide as the words */
.home-story { isolation: isolate; width: fit-content; max-width: min(540px, 44vw); }
.district-panel { isolation: isolate; width: fit-content; max-width: min(530px, 50vw); }
@media (max-width: 900px) {
  .home-story { width: fit-content; max-width: calc(100vw - 40px); }
}
@media (max-width: 860px) {
  /* phones already give the district words a black zone */
  .district-panel::before { display: none; }
}

/* the card starts at the first line: the old inner padding became position */
@media (min-width: 901px) {
  .home-story { top: calc(max(7vh, 54px) + 66px); }
}

/* larger small print inside the headline card and the district words (owner 2026-09-07) */
.home-story .eyebrow, .district-panel .eyebrow { font-size: 12px; letter-spacing: 0.24em; }
.home-story__lore, .district-lore { font-size: 16px; line-height: 1.6; }
.home-story__subtitle, .district-subtitle { font-size: 21px; }
.home-city-count span { font-size: 14px; letter-spacing: 0.12em; }
.home-city-count small { font-size: 11.5px; letter-spacing: 0.1em; }


/* ---- resident cards = district cards (owner 2026-09-07) -------------------
   Same grid, same size, same name strip. The portrait is cropped 3:2 from the
   top so the face, the crown and the shoulders make the picture. A card whose
   room exists is a door; the rest are plain cards. */
.sheet-card--resident img { object-position: 50% 50%; } /* wide cards are pre-framed */
.sheet-card--resident:not(.sheet-card--door) { cursor: default; }
.sheet-card--resident:not(.sheet-card--door):hover {
  border-color: rgba(255, 223, 150, 0.3);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4);
  transform: none;
}
.sheet-card--door { border-color: rgba(255, 217, 134, 0.6); }
.sheet-card--door .sheet-card-copy strong { color: var(--gold-bright); }
.resident-grid { padding-top: 0; pointer-events: auto; } /* the sheet itself lets taps through; the cards catch them */

.sheet-card--resident img { aspect-ratio: 3 / 2 !important; height: auto; }


/* ---- the search filter must actually hide (owner 2026-09-07) ---------------
   .sheet-card is display:flex, which beat the [hidden] attribute, so filtered
   cards stayed on screen while the script believed they were gone. */
.sheet-card[hidden],
.resident-card[hidden] { display: none !important; }
/* the residents grid starts below the pill, cards were cut at the top */
.residents-sheet { padding-top: calc(max(22px, env(safe-area-inset-top)) + 84px); }


.sheet-search { position: relative; }

/* the list's text must render as plain text whatever the pill styles its own children */


/* the search pills sit above the sheets while typing */
body.sheet-open .top-bar { z-index: 45; }         /* over the district sheet (8) while typing */
#district .residents-search { z-index: 45; }      /* over the residents sheet (5) */

/* the list is re-homed under <body> by app.js: fixed, above every layer */

/* every resident card is a door now */
.sheet-card--resident { cursor: pointer; }
.resident-text [data-go-back] { text-decoration-style: solid; }

/* a closed door has no quick facts: the empty frame must not draw */
.resident-quick[hidden] { display: none !important; }
/* while the room fades out it must not swallow the click meant for the page under it */
.resident-page:not(.is-open) { pointer-events: none; }

/* ---- ONE top row for the whole site (owner 2026-09-07) ----------------------
   The homepage pill and the global menu button are 42px tall with a 14px top
   gap, centre line 35px. The district row (Land map, residents pill, Sound)
   used to sit at 22px / 44px tall, so the menu hung 9px above it. Every
   top-row control now shares the homepage geometry; the menu is untouched. */
.sheet-search { padding-top: 8px; padding-bottom: 8px; min-height: 42px; } /* the pills measured 45px */
@media (min-width: 641px) {
  .back-button,
  .tour-status { top: max(14px, env(safe-area-inset-top)); min-height: 42px; }
}
@media (min-width: 861px) {
  /* on narrow screens the residents pill keeps its own second row (rule above) */
  #district .residents-search { top: max(14px, env(safe-area-inset-top)); }
  .residents-sheet { padding-top: calc(max(14px, env(safe-area-inset-top)) + 84px); }
}
@media (max-width: 640px) {
  /* phones: the compact 34px Land map / Sound pills share the menu's 35px centre line */
  .back-button,
  .tour-status:not(.is-tour-mode) { top: calc(max(14px, env(safe-area-inset-top)) + 4px); min-height: 34px; }
}

/* ---- the menu is dusk over the Land (owner 2026-09-07) ------------------------
   Full screen over any page. The page behind darkens to evening (400ms), then
   three postcards rise one after another (60ms steps): picture, name, a word
   under it. Nothing to hover for. The settings line stands under the cards,
   centred and big enough to be seen; small print at the foot. Close: 320ms. */
.top-menu-button { z-index: 31; transition: border-color 250ms ease, box-shadow 250ms ease, transform 320ms ease; }
.top-menu-button.is-open { transform: rotate(90deg); font-size: 15px; }
.menu-panel {
  position: fixed;
  inset: 0;
  top: 0; right: 0;
  z-index: 30;
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-width: 0;
  padding: max(14px, env(safe-area-inset-top)) max(4vw, 40px) max(22px, env(safe-area-inset-bottom));
  border: none;
  border-radius: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  color: var(--cream);
  pointer-events: auto;
}
.menu-panel[hidden] { display: none; }
.menu-dusk {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(80, 48, 20, 0.35), transparent 60%),
    rgba(12, 8, 7, 0.84);
  opacity: 0;
  transition: opacity 400ms ease;
}
.menu-panel.is-open .menu-dusk { opacity: 1; }
.menu-brand {
  margin: 0;
  height: 42px;
  display: flex;
  align-items: center;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(255, 217, 134, 0.85);
  opacity: 0;
  transition: opacity 320ms ease 120ms;
}
.menu-panel.is-open .menu-brand { opacity: 1; }
.menu-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 34px;
  min-height: 0;
}
.menu-cards {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 2.2vw, 30px);
  width: min(1180px, 100%);
}
.menu-cards li {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 360ms ease, transform 360ms ease;
}
.menu-panel.is-open .menu-cards li:nth-child(1) { transition-delay: 140ms; }
.menu-panel.is-open .menu-cards li:nth-child(2) { transition-delay: 200ms; }
.menu-panel.is-open .menu-cards li:nth-child(3) { transition-delay: 260ms; }
.menu-panel.is-open .menu-cards li:nth-child(4) { transition-delay: 320ms; }
.menu-panel.is-open .menu-cards li { opacity: 1; transform: none; }
.menu-panel .menu-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  color: var(--cream);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.menu-panel .menu-card img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border: 1px solid rgba(255, 223, 150, 0.42);
  border-radius: 18px;
  box-shadow: 0 22px 50px rgba(0, 0, 0, 0.5);
  transition: transform 260ms ease, border-color 260ms ease, box-shadow 260ms ease;
}
.menu-panel .menu-card:hover img,
.menu-panel .menu-card:focus-visible img {
  transform: translateY(-4px);
  border-color: rgba(255, 233, 180, 0.9);
  box-shadow: 0 26px 56px rgba(0, 0, 0, 0.6), 0 0 22px rgba(255, 214, 130, 0.25);
}
.menu-panel .menu-card:hover { background: none; }
.menu-card__name {
  margin-top: 16px;
  font-family: var(--display);
  font-size: clamp(24px, 2.2vw, 32px);
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: rgba(255, 244, 222, 0.94);
  text-shadow: 0 3px 24px rgba(10, 6, 5, 0.9);
  transition: color 200ms ease;
}
.menu-panel .menu-card:hover .menu-card__name { color: var(--gold-bright); }
.menu-card__note {
  margin-top: 5px;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: rgba(255, 244, 222, 0.62);
}
/* the settings line: centred under the cards, a lit lantern, readable text */
.menu-settings {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 22px;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 360ms ease 360ms, transform 360ms ease 360ms;
}
.menu-panel.is-open .menu-settings { opacity: 1; transform: none; }
.menu-panel .menu-toggle {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 18px 10px 14px;
  border: 1px solid rgba(255, 223, 150, 0.35);
  border-radius: 999px;
  background: rgba(24, 15, 13, 0.55);
  color: rgba(255, 244, 222, 0.92);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
  transition: border-color 200ms ease, background 200ms ease;
}
.menu-panel .menu-toggle:hover { border-color: rgba(255, 233, 180, 0.7); background: rgba(30, 20, 12, 0.7); color: #fff6e2; }
.menu-lantern { flex: none; width: 22px; height: 30px; overflow: visible; }
.menu-lantern .lantern-lines { fill: none; stroke: rgba(255, 223, 150, 0.9); stroke-width: 1.2; stroke-linejoin: round; stroke-linecap: round; }
.menu-lantern .lantern-body { fill: rgba(255, 217, 134, 0.18); }
.menu-lantern .lantern-flame { fill: var(--gold-bright); filter: drop-shadow(0 0 6px rgba(255, 210, 120, 0.95)); transition: opacity 200ms ease; }
.menu-toggle.is-off .menu-lantern .lantern-flame { opacity: 0; }
.menu-toggle.is-off .menu-lantern .lantern-body { fill: rgba(255, 244, 222, 0.05); }
.menu-toggle.is-off .menu-lantern .lantern-lines { stroke: rgba(255, 244, 222, 0.4); }
.menu-toggle__state {
  flex: none;
  min-width: 40px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid rgba(255, 217, 134, 0.6);
  background: rgba(233, 185, 91, 0.22);
  color: var(--gold-bright);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
}
.menu-toggle.is-off .menu-toggle__state { border-color: rgba(255, 244, 222, 0.22); background: none; color: rgba(255, 244, 222, 0.5); }
/* the foot: small print only */
.menu-foot {
  display: flex;
  justify-content: center;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 223, 150, 0.18);
  opacity: 0;
  transition: opacity 320ms ease 420ms;
}
.menu-panel.is-open .menu-foot { opacity: 1; }
.menu-panel:not(.is-open) .menu-dusk,
.menu-panel:not(.is-open) .menu-brand,
.menu-panel:not(.is-open) .menu-cards li,
.menu-panel:not(.is-open) .menu-settings,
.menu-panel:not(.is-open) .menu-foot { transition-delay: 0ms; transition-duration: 320ms; }
.menu-small-print { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 26px; }
.menu-panel .menu-foot button,
.menu-panel .menu-foot a {
  padding: 6px 0;
  border: none;
  border-radius: 0;
  background: none;
  color: rgba(255, 244, 222, 0.7);
  font: inherit;
  font-size: 13px;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
}
.menu-panel .menu-foot button:hover,
.menu-panel .menu-foot a:hover { background: none; color: var(--gold-bright); }
.menu-small-print a { color: rgba(255, 217, 134, 0.75); }
/* under the dusk the page's own top row and the sun step back */
body.menu-open .city-sun, body.menu-open .city-eq { opacity: 0.25; pointer-events: none; }
body.menu-open .top-bar, body.menu-open .back-button, body.menu-open .tour-status,
body.menu-open #district .residents-search { opacity: 0; pointer-events: none; transition: opacity 300ms ease; }
@media (max-width: 860px) {
  .menu-panel { padding-left: 20px; padding-right: 20px; overflow-y: auto; }
  .menu-body { gap: 24px; }
  .menu-cards { grid-template-columns: 1fr; gap: 16px; width: min(100%, 440px); }
  /* phones: picture left, name over its note on the right */
  .menu-panel .menu-card { display: grid; grid-template-columns: 44% minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 14px; align-items: center; }
  .menu-panel .menu-card img { grid-row: 1 / span 2; width: 100%; border-radius: 14px; }
  .menu-card__name { margin-top: 0; font-size: 22px; align-self: end; }
  .menu-card__note { margin-top: 3px; font-size: 12px; align-self: start; }
  .menu-settings { width: 100%; }
  .menu-panel .menu-toggle { width: min(100%, 440px); justify-content: space-between; }
  .menu-toggle__label { flex: 1 1 auto; text-align: left; }
  .menu-small-print { gap: 4px 18px; }
}

/* ---- the cards are the suggestions (owner 2026-09-07) --------------------------
   The typed letters light up inside the gold names in a warm bright red, so
   they read against the gold; nothing else about the name changes. */
.sheet-card strong b.hit { color: #ff4a3c; font-weight: inherit; }

/* ---- phones: the panorama fills the screen (owner 2026-09-07) ---------------
   The August layout put the picture on the top 55% and the words in a black
   zone below. The owner wants the phone to behave like the homepage: the
   picture covers the whole screen on its centre crop, the district words sit
   bottom-left on the feathered card, the residents run as one row under the
   pill. In the TOUR the centre crop drifts sideways (object-position), so the
   panorama still travels; a plain visit stands still. Arrival from a flight
   already lands on the video's centre crop, so nothing jumps. */
@media (max-width: 860px) {
  .district-art { bottom: 0 !important; transition: none !important; }
  .district-art img {
    width: 100% !important;
    max-width: none;
    height: 100% !important;
    object-fit: cover;
    object-position: 50% 50%;
    animation: none !important;
  }
  /* a plain visit stands still on its centre crop */
  #district:not(.is-tour) .district-art img { transform: none !important; }
  /* the tour pans the WHOLE picture, left edge to right edge. It moves by
     TRANSFORM, which the compositor animates without repainting (fix
     2026-09-07: animating object-position repainted the big picture every
     frame and the phone stuttered). The picture stands at full height, its
     natural width, and slides by (screen width - picture width); the pace is
     set by app.js through --pan-ms. */
  #district.is-tour .district-art img {
    width: auto !important;
    max-width: none;
    height: 100% !important;
    object-fit: fill;
    left: 0;
    right: auto;
  }
  #district.is-tour .district-art img.is-active {
    animation: panoramaPan var(--pan-ms, 5800ms) linear forwards !important;
  }
  body.pan-hold #district.is-tour .district-art img.is-active {
    animation-name: panoramaArrive !important; /* a flight lands on the centre crop */
    animation-delay: 900ms; animation-fill-mode: both;
  }
  .district-scrim {
    background: linear-gradient(0deg, rgba(16, 10, 9, 0.5) 0 14%, transparent 40%);
  }
  .district-panel {
    top: auto;
    bottom: max(26px, calc(env(safe-area-inset-bottom) + 18px));
    left: 20px;
    right: auto;
    width: fit-content;
    max-width: calc(100vw - 40px);
  }
  /* in the tour the bar sits along the bottom edge: the words stand above it */
  #district.is-tour .district-panel { bottom: max(76px, calc(env(safe-area-inset-bottom) + 68px)); }
  .district-panel .eyebrow { position: static; margin: 0; text-shadow: none; }
  .district-panel h2 { margin-top: 8px; }
  .district-panel::before { display: block; } /* the same feathered card as on the homepage */
  /* owner 2026-09-07: two cards across, two rows tall, and the list scrolls
     DOWN inside its own window, never over the district words. The window
     runs from a small step under the pill to a fixed floor above the words. */
  .residents-sheet {
    height: auto;
    top: 0;
    bottom: 230px; /* room for the eyebrow, the name, the subtitle and three lines of lore */
    padding-top: calc(max(14px, env(safe-area-inset-top)) + 114px); /* pill bottom 114px, cards from 134px */
    display: flex;
    flex-direction: column;
  }
  #district .resident-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: max-content;
    gap: 10px;
    padding: 0 16px 12px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
  }
  #district .resident-grid::-webkit-scrollbar { display: none; }
}

/* phones (owner 2026-09-07): the equalizer moves to the bottom-RIGHT corner;
   bottom-left it sat on the "21 districts" figure of the homepage headline */
@media (max-width: 860px) {
  .city-eq {
    left: auto;
    right: max(16px, env(safe-area-inset-right));
    bottom: max(16px, env(safe-area-inset-bottom));
  }
}

/* owner 2026-09-07: no wash over the panorama. The district darkened its whole
   left side and bottom with a gradient; the homepage darkens ONLY under the
   words with the feathered card, and the district now does the same. The
   scrim element stays (the flight timing fades it) but paints nothing. */
.district-scrim { background: none !important; }

/* owner 2026-09-07: the tour controls live at the BOTTOM on every screen, as on
   phones, so the hand learns one place. On desktop the bar stands bottom
   centre, level with the three view thumbnails; the lone Sound button of a
   plain visit stays top-right, exactly like on phones. */
@media (min-width: 641px) {
  /* bottom centre of the page, its lower edge on the same line as the view thumbnails */
  #district.is-tour .tour-status.is-tour-mode {
    top: auto;
    bottom: max(30px, env(safe-area-inset-bottom));
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
  /* the words rise above the bar's line, so the two never cross on narrow windows */
  #district.is-tour .district-panel { bottom: calc(max(30px, env(safe-area-inset-bottom)) + 44px + 22px); }
}

/* ---- tour bar: icons instead of words (owner 2026-09-07) --------------------- */
.tour-status .tour-pause-button,
.tour-status .tour-sound-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  min-width: 36px;
  padding: 0 !important;
}
.tour-icon { display: none; width: 20px; height: 20px; fill: var(--gold-bright); color: var(--gold-bright); }
.tour-status:not(.is-tour-mode) .tour-icon { width: 24px; height: 24px; }
.tour-pause-button .icon-pause { display: block; }
.tour-pause-button.is-paused .icon-pause { display: none; }
.tour-pause-button.is-paused .icon-play { display: block; }
.tour-sound-button .icon-sound-on { display: block; }
.tour-sound-button.is-muted .icon-sound-on { display: none; }
.tour-sound-button.is-muted .icon-sound-off { display: block; }
/* the lone Sound button of a plain visit keeps the same round shape */
.tour-status:not(.is-tour-mode) .tour-sound-button,
.tour-status:not(.is-tour-mode) .tour-sound-button:hover,
.tour-status:not(.is-tour-mode) .tour-sound-button:active { width: 42px; min-width: 42px; min-height: 42px; }
@media (max-width: 640px) {
  .tour-status:not(.is-tour-mode) .tour-sound-button,
  .tour-status:not(.is-tour-mode) .tour-sound-button:hover,
  .tour-status:not(.is-tour-mode) .tour-sound-button:active { width: 34px; min-width: 34px; min-height: 34px; }
}

/* Pause really pauses (owner 2026-09-07): the pan freezes where it is and
   continues from the same spot on Resume */
#district.is-paused .district-art img.is-active { animation-play-state: paused !important; }

/* ---- touch feedback (owner 2026-09-07) ----------------------------------------
   Android Chrome paints a translucent blue box over anything tapped; it is not
   ours. Off everywhere; a pressed control answers with a brighter rim instead. */
button, a, [role="button"], .sheet-card, .menu-card, .view-button {
  -webkit-tap-highlight-color: transparent;
}
.back-button:active, .tour-status button:active, .top-menu-button:active,
.sheet-search:active, .menu-toggle:active, .menu-panel .menu-foot button:active {
  border-color: rgba(255, 233, 180, 0.9);
}
.sheet-card:active img, .menu-card:active img { border-color: rgba(255, 233, 180, 0.9); }
