:root {
  --night: #1b2033;
  --slate: #2e3550;
  --dusk: #6b5e8a;
  --snow: #f4f7ff;
  --ember: #f2b48a;
  --lavender: #b9b2e6;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--night);
  color: var(--snow);
  font-family: "Nunito", system-ui, sans-serif;
  overflow: hidden;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  isolation: isolate;
}

body.is-loading .stage { opacity: 0; }

.layer { position: absolute; inset: 0; pointer-events: none; }
.mist { opacity: 0; }

/* Scene */
/* Promoted for the whole visit: the intro's camera moves these layers, and
   keeping them promoted means the end of the move never triggers a repaint. */
.scene, .peaks { transform-origin: 50% 60%; will-change: transform; }
.scene picture { position: absolute; inset: 0; }
.scene-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
  image-rendering: pixelated;
}
.scene-day { opacity: 0; }

/* Birds: 4-frame pixel sprite (40x40 cells) cycling through the wing beat */
.bird {
  position: absolute;
  left: 0; top: 0;
  width: 40px; height: 40px;
  transform-origin: 0 0;
  will-change: transform;
}
.bird::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url(assets/bird-sprite.png) 0 0 / 160px 40px no-repeat;
  image-rendering: pixelated;
  animation: flap var(--flap-rate, .45s) steps(4) infinite;
  animation-delay: var(--flap-delay, 0s);
}
/* Gliding: wings held level (frame 2) with the beat paused */
.bird.gliding::before {
  animation: none;
  background-position: -40px 0;
}

@keyframes flap {
  to { background-position: -160px 0; }
}

/* Mist: Gemini-painted haze (brightness baked into alpha), drifting on the
   compositor with a CSS animation. No blur filter, so it stays cheap. */
.mist-band {
  position: absolute;
  left: -15%;
  width: 130%;
  height: 26%;
  background: url(assets/mist.webp) center / 100% 100% no-repeat;
  image-rendering: pixelated;
  /* Fade all four edges so bands never show a hard top, bottom or end. */
  -webkit-mask-image:
    linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent),
    linear-gradient(transparent, #000 35%, #000 65%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent),
    linear-gradient(transparent, #000 35%, #000 65%, transparent);
  mask-composite: intersect;
  will-change: transform;
}
/* Two light layers: a faint valley haze and a little ground mist. */
.mist-a { top: 52%; height: 18%; opacity: .18; animation: mist-drift 52s ease-in-out infinite alternate; }
.mist-d { top: 80%; height: 16%; opacity: .16; animation: mist-drift 38s ease-in-out -5s infinite alternate; }
@keyframes mist-drift {
  from { transform: translate3d(-6%, 0, 0); }
  to { transform: translate3d(6%, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .mist-band { animation: none; }
}

.vignette {
  background:
    radial-gradient(ellipse at 50% 22%, rgba(27, 32, 51, .6), transparent 55%),
    linear-gradient(to bottom, rgba(27, 32, 51, .35), transparent 35%, transparent 75%, rgba(27, 32, 51, .55));
}

/* Hero */
.hero {
  position: absolute;
  left: 50%;
  top: 4vh;
  transform: translateX(-50%);
  width: min(94vw, 900px);
  text-align: center;
  z-index: 2;
}

.logo-wrap {
  position: relative;
  width: clamp(280px, 46vw, 720px);
  margin: 0 auto;
  opacity: 0;
  will-change: transform, opacity;
}

/* Soft light pool behind the name so it reads as the highlight of the page */
.logo-halo {
  position: absolute;
  left: 50%; top: 50%;
  width: 130%; height: 220%;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(255, 226, 196, .45), rgba(185, 178, 230, .22) 45%, transparent 75%);
  filter: blur(6px);
  opacity: 0;
}

.logo {
  position: relative;
  filter:
    drop-shadow(0 8px 20px rgba(27, 32, 51, .6))
    drop-shadow(0 0 16px rgba(244, 247, 255, .2));
}
.logo-full { display: block; width: 100%; height: auto; }

/* The tagline reads like an old inscription: carved serif capitals, wide
   tracking, an ember glow, framed by lines that fade into the dark. */
.tagline {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 1.6vw, 22px);
  margin: clamp(12px, 2.4vh, 24px) auto 0;
  font-family: "Cinzel", "Times New Roman", serif;
  font-size: clamp(12px, 1.35vw, 18px);
  font-weight: 500;
  letter-spacing: .32em;
  text-transform: uppercase;
  color: #f1e9ff;
  text-shadow:
    0 0 12px rgba(242, 180, 138, .55),
    0 0 28px rgba(185, 178, 230, .35),
    0 2px 6px rgba(15, 18, 32, .95);
  opacity: 0;
}
.tag-text { padding-left: .32em; } /* balance the trailing letter-spacing */
.tag-text .w { display: inline-block; white-space: pre; }
.tag-line {
  flex: 0 0 clamp(24px, 5vw, 90px);
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(242, 200, 160, .85));
  box-shadow: 0 0 8px rgba(242, 180, 138, .6);
}
.tag-line:last-child { background: linear-gradient(270deg, transparent, rgba(242, 200, 160, .85)); }
@media (max-width: 520px) {
  .tagline { letter-spacing: .2em; font-size: 11px; }
  .tag-line { flex-basis: 16px; }
  .tag-text { max-width: 78vw; line-height: 1.7; text-wrap: balance; }
}

.coming {
  display: inline-block;
  margin: clamp(12px, 2.2vh, 22px) 0 0;
  padding: .9em 1.3em;
  font-family: "Press Start 2P", monospace;
  font-size: clamp(10px, 1.2vw, 14px);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--snow);
  background: rgba(27, 32, 51, .55);
  border: 3px solid var(--lavender);
  box-shadow: 4px 4px 0 var(--slate), 0 0 24px rgba(242, 180, 138, .25);
  opacity: 0;
}

/* Soft, irregular Gemini cloud layers share a breeze and clear at unequal
   times. Centre by the actual image dimensions, including in portrait. */
.clouds { z-index: 3; overflow: hidden; contain: strict; }
/* Preserve the original bank's proportions. The fixed contours follow its
   painted inner edges; main.js maps source pixels through background-cover. */
.cloud-gate {
  position: absolute;
  inset: -6%;
  z-index: 20;
  background: url(assets/cloud-cover.webp) center / cover no-repeat;
  image-rendering: pixelated;
  will-change: transform, opacity;
}
.cloud-gate-left { clip-path: inset(0 50% 0 0); }
.cloud-gate-right { clip-path: inset(0 0 0 50%); }
.cloud-haze {
  position: absolute;
  inset: -6%;
  background:
    url(assets/cloud-cover.webp) center / cover no-repeat,
    radial-gradient(ellipse at 54% 60%, #b5a5ad 0%, #9690a6 42%, #686d8b 100%);
  will-change: transform, opacity;
}
.cloud {
  position: absolute;
  left: 50%; top: 50%;
  height: auto;
  opacity: 0;
  image-rendering: pixelated;
  will-change: transform, opacity;
}

/* Long low cloud banks that keep drifting along the slopes after the reveal */
.banks { opacity: 0; will-change: transform; }
.bank {
  position: absolute;
  left: 0; top: 0;
  height: auto;
  image-rendering: pixelated;
  will-change: transform;
}
.bank-banner { transform-origin: 0 50%; }  /* stretches away from the summit */

/* First light on the snowy summits: a warm bloom when the peaks are revealed,
   then a slow shimmer, as if the snow catches the coming dawn. */
.peak-light {
  position: absolute;
  left: 0; top: 0;
  width: 26vmin;
  height: 26vmin;
  margin: -13vmin 0 0 -13vmin;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 244, 228, .75), rgba(255, 214, 178, .32) 45%, rgba(242, 180, 138, 0) 100%);
  mix-blend-mode: screen;
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}
.peak-light.lit { animation: peak-shimmer 6s ease-in-out infinite alternate; }

@keyframes peak-shimmer {
  from { opacity: .55; }
  to { opacity: .65; }
}
@media (prefers-reduced-motion: reduce) {
  .peak-light { opacity: .55; }
  .peak-light.lit { animation: none; }
}

/* Foreground pines that bend in the wind from their base */
.trees { opacity: 0; }
.tree {
  position: absolute;
  width: auto;
  image-rendering: pixelated;
  transform-origin: 50% 100%;
  will-change: transform;
}

/* Pixel-styled button to watch the cloud reveal again */
.replay {
  position: absolute;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: .6em;
  padding: .85em 1.1em;
  font: 400 clamp(9px, 1vw, 11px)/1 "Press Start 2P", monospace;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--snow);
  background: rgba(27, 32, 51, .6);
  border: 2px solid rgba(185, 178, 230, .7);
  box-shadow: 3px 3px 0 var(--slate);
  cursor: pointer;
  opacity: 0;
  transition: background .2s, transform .1s, box-shadow .1s;
}
.replay span { font-family: system-ui, sans-serif; font-size: 1.5em; line-height: .6; }
.replay:hover { background: rgba(46, 53, 80, .85); }
.replay:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--slate); }
.replay:focus-visible { outline: 3px solid var(--ember); outline-offset: 3px; }
.replay[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .replay { display: none; } }

.foot {
  position: absolute;
  left: 0; right: 0;
  bottom: max(14px, env(safe-area-inset-bottom));
  z-index: 2;
  text-align: center;
  font-size: 12px;
  color: rgba(244, 247, 255, .6);
  text-shadow: 0 1px 6px rgba(27, 32, 51, .9);
}
.foot a { color: inherit; text-decoration: none; border-bottom: 1px solid rgba(244, 247, 255, .3); pointer-events: auto; }
.foot a:hover, .foot a:focus-visible { color: var(--snow); border-bottom-color: var(--ember); }
/* Phones: the footer moves to the left so it never sits under Replay. */
@media (max-width: 600px) {
  .foot {
    right: auto;
    left: max(16px, env(safe-area-inset-left));
    bottom: max(22px, env(safe-area-inset-bottom));
    text-align: left;
    font-size: 11px;
    max-width: calc(100vw - 200px);  /* wraps beside Replay instead of under it */
    line-height: 1.6;
  }
}

/* Portrait: the wide scene is cropped, so anchor it to the bottom and let a
   matching sky fill the space above for the name. */
@media (orientation: portrait) {
  .scene { background: linear-gradient(to bottom, #3c4361, #4d4f72 60%, #5a5578); }
  .scene picture {
    top: auto;
    height: 54%;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%);
    mask-image: linear-gradient(to bottom, transparent, #000 22%);
  }
  .scene-img { object-position: 50% 100%; }
  .hero { top: 8vh; }
  .logo-wrap { width: clamp(260px, 86vw, 620px); }
}

@media (prefers-reduced-motion: reduce) {
  .clouds, .birds, .banks { display: none; }
  .logo-wrap, .logo-halo, .tagline, .coming, .mist { opacity: 1; }
}

/* ---------- The gate ----------------------------------------------------
   An old standing stone half-lost in the clouds. Text is carved into it
   (dark fill, light lower lip), the runes breathe with ember light, and the
   whole stone drifts as if the cloud it rests in were moving. */
.gate {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2.4vh, 22px);
  padding: 16px;
  opacity: 0;
}
.gate[hidden] { display: none; }
.tablet {
  position: relative;
  width: min(92vw, 640px);
  aspect-ratio: 970 / 558;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 1.6vh, 14px);
  padding: 9% 17% 8%;
  text-align: center;
  background: url(assets/tablet.webp) center / 100% 100% no-repeat;
  image-rendering: pixelated;
  filter: drop-shadow(0 18px 30px rgba(15, 18, 32, .55));
  animation: tablet-drift 7s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes tablet-drift {
  from { transform: translate3d(0, -4px, 0) rotate(-.4deg); }
  to { transform: translate3d(0, 5px, 0) rotate(.3deg); }
}
.gate-title {
  margin: 0;
  font-family: "Cinzel", serif;
  font-weight: 600;
  font-size: clamp(15px, 2.7vw, 26px);
  line-height: 1.35;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #f1e9ff;
  /* lit from within the stone, like the runes around it */
  text-shadow: 0 0 12px rgba(242, 180, 138, .55), 0 0 26px rgba(185, 178, 230, .3), 0 2px 4px rgba(10, 10, 20, .9);
}
.gate-enter {
  margin-top: clamp(2px, 1vh, 8px);
  padding: .95em 1.6em;
  font: 400 clamp(10px, 1.25vw, 13px)/1 "Press Start 2P", monospace;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #fff3e4;
  background: rgba(27, 32, 51, .78);
  border: 3px solid #f2b48a;
  box-shadow: 4px 4px 0 var(--slate), 0 0 18px rgba(242, 180, 138, .45);
  cursor: pointer;
  transition: box-shadow .25s, background .25s, transform .1s;
  animation: ember-pulse 2.6s ease-in-out infinite alternate;
}
@keyframes ember-pulse {
  from { box-shadow: 4px 4px 0 var(--slate), 0 0 10px rgba(242, 180, 138, .3); }
  to { box-shadow: 4px 4px 0 var(--slate), 0 0 26px rgba(242, 180, 138, .7); }
}
.gate-enter:hover { background: rgba(46, 53, 80, .9); }
.gate-enter:active { transform: translate(2px, 2px); }
.gate-enter:focus-visible, .gate-quiet:focus-visible, .sound:focus-visible {
  outline: 3px solid var(--ember);
  outline-offset: 4px;
}
.gate-quiet {
  padding: .6em 1em;
  font-family: "Cinzel", serif;
  font-size: clamp(11px, 1.2vw, 13px);
  letter-spacing: .2em;
  text-transform: lowercase;
  color: rgba(244, 247, 255, .85);
  background: rgba(27, 32, 51, .5);
  border: 0;
  text-shadow: 0 1px 6px rgba(27, 32, 51, .9);
  cursor: pointer;
}
.gate-quiet:hover { color: #fff; }
/* While waiting at the gate the clouds keep breathing toward the viewer. */
.clouds.waiting { animation: cloud-breathe 14s ease-in-out infinite alternate; }
/* One promoted layer for the whole bank: the gate breathing and the push
   into the cloud only scale this layer, they never repaint the art. */
.clouds { will-change: transform; }
@keyframes cloud-breathe { from { transform: scale(1); } to { transform: scale(1.035); } }
@media (max-width: 520px) {
  .tablet { width: 96vw; aspect-ratio: 4 / 3; padding: 12% 18% 10%; }
  .gate-title { font-size: 13px; letter-spacing: .05em; }
}
@media (prefers-reduced-motion: reduce) {
  .tablet, .gate-enter, .clouds.waiting { animation: none; }
}

/* Music toggle, sits beside Replay in the same pixel style. */
.sound {
  position: absolute;
  right: max(16px, env(safe-area-inset-right));
  bottom: calc(max(16px, env(safe-area-inset-bottom)) + 52px);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: .6em;
  padding: .85em 1.1em;
  font: 400 clamp(9px, 1vw, 11px)/1 "Press Start 2P", monospace;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--snow);
  background: rgba(27, 32, 51, .6);
  border: 2px solid rgba(185, 178, 230, .7);
  box-shadow: 3px 3px 0 var(--slate);
  cursor: pointer;
}
.sound[hidden] { display: none; }
.sound:hover { background: rgba(46, 53, 80, .85); }
.sound[aria-pressed="true"] { border-color: var(--ember); }
.sound-icon { font-family: system-ui, sans-serif; font-size: 1.4em; line-height: .6; }
@media (prefers-reduced-motion: reduce) { .replay { display: none; } }
