@font-face { font-family: "DM Sans"; font-style: normal; font-weight: 300 800; font-display: swap; src: url("../fonts/dm-sans.woff2") format("woff2"); }
@font-face { font-family: "Space Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/space-mono-400.woff2") format("woff2"); }

@property --sweep { syntax: "<angle>"; inherits: false; initial-value: 360deg; }

/* --u is one logo "unit" in px: the artwork is drawn in a 1320x300 box (the
   logo's own 400x400 coordinates, extended sideways), so everything that has
   to line up with the mountains — layer height, text position — is expressed
   in --u instead of vw/vh. */
:root {
  --bg: #040a15;
  --ink: #eef0f2;
  --soft: #a8b2bd;
  --gold: #c9a84c;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --sans: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Space Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --uw: calc(94vw / 320);
  --uh: calc(98vh / 300);
  --u: min(var(--uw), var(--uh));
}
@supports (height: 100svh) { :root { --uh: calc(98svh / 300); } }
@media (orientation: portrait) { :root { --uw: calc(125vw / 320); --uh: calc((100vh - 270px) / 300); } }
@supports (height: 100svh) { @media (orientation: portrait) { :root { --uh: calc((100svh - 270px) / 300); } } }

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; overflow: hidden; background: var(--bg); color: var(--ink); color-scheme: dark; }
body { font-family: var(--sans); font-weight: 300; line-height: 1.6; -webkit-font-smoothing: antialiased; }

@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(16px); filter: blur(6px); } }
@keyframes lift { from { opacity: 0; transform: translateY(calc(18 * var(--u))); } }
@keyframes sweep { from { --sweep: 0deg; } }
@keyframes breathe { from { opacity: .82; } }
@keyframes drift { from { transform: translateX(-5vw); } to { transform: translateX(5vw); } }
@keyframes slide { from { transform: translateX(-110%); } to { transform: translateX(290%); } }
@keyframes draw {
  0%   { stroke-dashoffset: 1; opacity: 1; }
  62%  { stroke-dashoffset: 0; opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: .26; }
}

/* --- Scene ---------------------------------------------------------------- */
.scene { position: fixed; inset: 0; overflow: hidden; animation: fade 1.6s ease .1s backwards, dolly 4.8s var(--ease) .1s backwards; }
.sky {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 75% 62% at 50% 66%, #0d2149 0%, #091a38 34%, #060f22 62%, rgba(4, 10, 21, 0) 100%),
    linear-gradient(#02060f, #040a15 55%, #050d1b);
}
.stars, .rim, .vignette, .grain { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.vignette { background: radial-gradient(ellipse 85% 75% at 50% 52%, rgba(2, 5, 12, 0) 52%, rgba(2, 5, 12, .72) 100%); }
.grain { opacity: .07; mix-blend-mode: overlay; background-size: 160px 160px; }

.scape { position: absolute; left: -5vw; right: -5vw; bottom: 0; height: calc(300 * var(--u)); pointer-events: none; will-change: transform; }
.scape svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; shape-rendering: geometricPrecision; }

.halo__ring, .halo__bloom {
  --sweep: 360deg;
  -webkit-mask-image: conic-gradient(from -112deg at 50% 65.7%, #000 0 var(--sweep), transparent var(--sweep) 360deg);
  mask-image: conic-gradient(from -112deg at 50% 65.7%, #000 0 var(--sweep), transparent var(--sweep) 360deg);
  animation: sweep 2.8s var(--ease) .5s backwards;
}
.halo__ring { animation: sweep 2.8s var(--ease) .5s backwards, breathe 9s ease-in-out 3.3s infinite alternate; }
.halo__bloom { filter: blur(calc(6 * var(--u))); opacity: .3; }
.halo__glow { animation: fade 2.4s ease .3s backwards; }

.scape--far svg { animation: lift 1.9s var(--ease) .7s backwards; }
.scape--mid svg { animation: lift 1.9s var(--ease) 1s backwards; }
.scape--near svg { animation: lift 1.9s var(--ease) 1.3s backwards; }

.crest {
  fill: none; stroke: var(--gold); stroke-width: .55; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1 1; opacity: .26;
  animation: draw 4.8s var(--ease) 1.3s backwards;
}

/* The logo's white relief band (snow cap + blades) sits on the far mountain; the
   relief layer on top carries one moving light, a glint sweeping over it. It is
   hidden by default so reduced-motion (animations off) leaves only the band. */
.snow { animation: fade 2.2s var(--ease) 2.5s backwards; }
.scape--relief svg { animation: fade 2s ease 3.4s backwards; }
.glint { opacity: 0; transform: translateX(110px) skewX(-24deg); animation: glint 14s linear 6s infinite; }
@keyframes glint {
  0%   { transform: translateX(110px) skewX(-24deg); opacity: 0; }
  3%   { opacity: .9; }
  38%  { transform: translateX(620px) skewX(-24deg); opacity: .9; }
  41%, 100% { transform: translateX(620px) skewX(-24deg); opacity: 0; }
}

/* Stars inside the ring are static, all behind the mountain: they light up once,
   left to right, as the ring draws itself (the sweep runs .5s -> ~1.8s), then
   just stay there. The centre group would sit under the title in landscape, so
   it only shows in portrait (where the title is above the ring). */
.cstar { fill: #eef3ff; transform-box: fill-box; transform-origin: center; animation: ignite 1.3s var(--ease) 1.2s backwards; }
.cstars--flank path:nth-child(1) { animation-delay: 1.2s; }
.cstars--flank path:nth-child(2) { animation-delay: 1.5s; }
.cstars--flank path:nth-child(3) { animation-delay: 1.8s; }
.cstars--flank path:nth-child(4) { animation-delay: 1.4s; }
.cstars--flank path:nth-child(5) { animation-delay: 2.1s; }
.cstars--flank path:nth-child(6) { animation-delay: 2.4s; }
.cstars--flank path:nth-child(7) { animation-delay: 2.2s; }
.cstars--flank path:nth-child(8) { animation-delay: 2.6s; }
.cstars--center { display: none; }
@media (orientation: portrait) { .cstars--center { display: inline; } }
.cstars--center path:nth-child(1) { animation-delay: 1.9s; }
.cstars--center path:nth-child(2) { animation-delay: 2.3s; }
.cstars--center path:nth-child(3) { animation-delay: 3s; }
.cstars--center path:nth-child(4) { animation-delay: 2.6s; }
.cstars--center path:nth-child(5) { animation-delay: 2.8s; }
.cstars--center path:nth-child(6) { animation-delay: 2.1s; }
.cglow { animation: fade 1.6s ease backwards; }
.cstars--flank .cglow--1 { animation-delay: 1.5s; }
.cstars--flank .cglow--5 { animation-delay: 2.4s; }
.cstars--center .cglow--0 { animation-delay: 1.9s; }
@keyframes ignite {
  0%   { opacity: 0; transform: scale(0) rotate(-60deg); }
  55%  { opacity: 1; transform: scale(1.4) rotate(8deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes dolly { from { transform: scale(1.06); } }

.mist {
  position: absolute; left: -25vw; right: -25vw; height: calc(86 * var(--u)); pointer-events: none;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(125, 160, 220, .2), rgba(125, 160, 220, 0) 70%);
  animation: drift 46s ease-in-out infinite alternate, fade 3s ease 1.6s backwards;
}
.mist--a { bottom: calc(30 * var(--u)); }
.mist--b { bottom: calc(-6 * var(--u)); animation-duration: 62s, 3s; animation-direction: alternate-reverse, normal; }

/* Edge light that follows the pointer: only the crest lines, revealed by a mask. */
.rim {
  --mx: 50%; --my: 60%;
  -webkit-mask-image: radial-gradient(circle clamp(200px, 34vmin, 440px) at var(--mx) var(--my), #000 0, rgba(0, 0, 0, .55) 38%, transparent 100%);
  mask-image: radial-gradient(circle clamp(200px, 34vmin, 440px) at var(--mx) var(--my), #000 0, rgba(0, 0, 0, .55) 38%, transparent 100%);
  animation: fade 2s ease 2.4s backwards;
}
.rim path { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.rim .halo-line { stroke: #8fb2ff; stroke-width: 3.4; opacity: .26; }
.rim .edge-line { stroke: #dfe9ff; stroke-width: .75; opacity: .8; }

.glow {
  display: none; position: absolute; left: 0; top: 0; width: min(70vmin, 720px); height: min(70vmin, 720px);
  border-radius: 50%; pointer-events: none; mix-blend-mode: screen; will-change: transform;
  background: radial-gradient(circle, rgba(120, 165, 255, .13) 0, rgba(120, 165, 255, .05) 38%, rgba(120, 165, 255, 0) 66%);
}

.is-live .glow { display: block; }

/* Foreground snow, in front of every mountain: soon.js draws the drifting flakes
   and the gusts that cross the screen; the haze is just a cold veil at the foot. */
.haze {
  position: absolute; left: 0; right: 0; bottom: 0; height: calc(70 * var(--u)); pointer-events: none;
  background: linear-gradient(to top, rgba(160, 188, 232, .17), rgba(160, 188, 232, 0));
  animation: fade 3s ease 3s backwards;
}
.blizzard { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; }

/* --- Text ----------------------------------------------------------------- */
.stack {
  position: absolute; z-index: 5; left: 50%; bottom: calc(173 * var(--u)); transform: translateX(-50%);
  width: min(92vw, 760px); text-align: center; pointer-events: none;
}
@media (orientation: portrait) { .stack { bottom: calc(264 * var(--u) + 28px); } }

.wordmark {
  margin: 0; font-weight: 700; font-size: clamp(1.6rem, calc(25 * var(--u)), 6rem);
  line-height: .94; letter-spacing: -.022em; color: var(--ink);
  text-shadow: 0 0 28px rgba(4, 10, 21, .6);
  animation: rise 1.5s var(--ease) 2.3s backwards;
}
.zero { position: relative; display: inline-block; }
.zero::after {
  content: ""; position: absolute; left: 50%; bottom: .28em; width: .11em; height: .11em;
  border-radius: 50%; background: currentColor; transform: translateX(-50%);
}

.tagline {
  margin: clamp(12px, 1.8vh, 20px) 0 0; padding-left: .34em; text-wrap: balance;
  font: 400 clamp(.62rem, calc(5.2 * var(--u)), .92rem)/1.6 var(--mono);
  letter-spacing: .34em; text-transform: uppercase; color: var(--gold);
  animation: rise 1.3s var(--ease) 2.9s backwards;
}
.status {
  margin: clamp(20px, 3.4vh, 36px) 0 0; padding-left: .3em;
  font: 400 clamp(.62rem, calc(4.9 * var(--u)), .84rem)/1.9 var(--mono);
  letter-spacing: .3em; text-transform: uppercase; color: var(--soft);
  animation: rise 1.3s var(--ease) 3.3s backwards;
}
.status span + span::before {
  content: ""; display: inline-block; width: 5px; height: 5px; margin: 0 1.2em; border-radius: 50%;
  background: var(--gold); opacity: .85; vertical-align: .14em; letter-spacing: 0;
}
@media (max-width: 560px) {
  .status span { display: block; }
  .status span + span::before { display: none; }
}
@media (max-height: 520px) and (orientation: landscape) {
  .tagline, .bar { display: none; }
  .status { margin-top: 12px; font-size: .6rem; letter-spacing: .2em; padding-left: .2em; }
  .status span + span::before { margin: 0 .9em; }
}
/* During the 500's repeating storm the lines stay readable over the snow */
body[data-storm] .tagline, body[data-storm] .status, body[data-storm] .back { text-shadow: 0 0 14px rgba(4, 10, 21, .95), 0 0 4px rgba(4, 10, 21, .8); }
/* "Back to the map" on the 404 and the unsubscribed page (the stack itself ignores the pointer) */
.back {
  margin: clamp(18px, 3vh, 30px) 0 0; padding-left: .26em; text-wrap: balance;
  font: 400 clamp(.6rem, calc(4.6 * var(--u)), .76rem)/1.9 var(--mono);
  letter-spacing: .26em; text-transform: uppercase;
  animation: rise 1.3s var(--ease) 3.6s backwards;
}
.back a {
  pointer-events: auto; color: var(--gold); text-decoration: none; padding: 8px 2px;
  border-bottom: 1px solid rgba(201, 168, 76, .45); transition: color .3s ease, border-color .3s ease;
}
.back a:hover, .back a:focus-visible { color: #f2d98a; border-color: #f2d98a; outline: none; }
.back a { display: inline-block; }
@media (max-width: 560px) {
  .back a > span[aria-hidden] { display: none; }
  .back a > span[lang] { display: block; margin-top: 2px; }
}
.bar {
  position: relative; width: 132px; height: 1px; margin: 12px auto 0; overflow: hidden;
  background: rgba(238, 240, 242, .14); animation: fade 1.3s ease 3.6s backwards;
}
.bar i {
  position: absolute; inset: 0 auto 0 0; width: 38%;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  animation: slide 2.8s var(--ease) infinite;
}

/* --- Error pages: each one adds one element to the same scene -----------------
   404  .veil  fog over the mountains that clears around the pointer's light
                (soon.js sets --mx/--my on .scene; with no pointer the light drifts on its own)
   403  .tape  gold "trail closed" tape across the mountain, text scrolling
   500  (no element) the storm comes back every 12s, see soon.js (data-storm)
   503  .camp  a lantern flickering at the foot of the mountains                      */
.veil {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(120% 80% at 50% 100%, rgba(120, 150, 205, .32), rgba(30, 50, 90, 0) 62%),
    rgba(7, 14, 30, .84);
  -webkit-mask-image: radial-gradient(circle at var(--mx, 50%) var(--my, 62%), transparent 0, transparent calc(32 * var(--u)), #000 calc(88 * var(--u)));
          mask-image: radial-gradient(circle at var(--mx, 50%) var(--my, 62%), transparent 0, transparent calc(32 * var(--u)), #000 calc(88 * var(--u)));
  animation: fade 3s ease 2.4s backwards;
}

.tape {
  --r: -5.5deg;
  position: absolute; left: -8%; width: 116%; height: clamp(30px, calc(11 * var(--u)), 56px); overflow: hidden; pointer-events: none;
  transform: rotate(var(--r)); box-shadow: 0 8px 34px rgba(0, 0, 0, .5);
  animation: sway 7s ease-in-out infinite alternate, fade 2s ease 2.2s backwards;
}
.tape--a { top: 63%; background: var(--gold); }
.tape--b {
  --r: 4deg; top: 74%;
  background: repeating-linear-gradient(135deg, #0a1426 0 18px, #c9a84c 18px 36px);
  background-size: 51px 51px;
  animation: sway 9s ease-in-out infinite alternate-reverse, stripes 4s linear infinite, fade 2s ease 2.4s backwards;
}
.tape__row {
  display: flex; width: max-content; height: 100%; align-items: center; white-space: nowrap;
  font: 400 clamp(.62rem, calc(4.4 * var(--u)), .8rem)/1 var(--mono); letter-spacing: .34em; text-transform: uppercase; color: #0a1426;
  animation: marquee 28s linear infinite;
}
.tape__row span { padding: 0 1.6em; }
@keyframes sway { from { transform: rotate(calc(var(--r) - .5deg)); } to { transform: rotate(calc(var(--r) + .5deg)); } }
@keyframes marquee { to { transform: translateX(-50%); } }
@keyframes stripes { to { background-position: 51px 0; } }

.camp {
  position: absolute; left: 50%; bottom: calc(12 * var(--u)); width: calc(96 * var(--u)); aspect-ratio: 1;
  transform: translate(-50%, 40%); border-radius: 50%; pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(circle, rgba(255, 208, 128, .85) 0, rgba(255, 164, 74, .32) 30%, rgba(255, 140, 50, 0) 66%);
  animation: flicker 2.8s ease-in-out infinite alternate, fade 3s ease 2.4s backwards;
}
.camp::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: calc(2.4 * var(--u)); height: calc(2.4 * var(--u));
  min-width: 5px; min-height: 5px; transform: translate(-50%, -50%); border-radius: 50%;
  background: #ffe3a8; box-shadow: 0 0 calc(7 * var(--u)) calc(2 * var(--u)) rgba(255, 190, 100, .9);
}
@keyframes flicker {
  0% { opacity: .82; scale: 1; } 18% { opacity: 1; scale: 1.05; } 31% { opacity: .78; scale: .97; }
  52% { opacity: .96; scale: 1.03; } 70% { opacity: .84; scale: .99; } 100% { opacity: 1; scale: 1.06; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
