/* ── TITUSVILLE SPOOKS ─────────────────────────────────────────────────────
   A Halloween in Titusville. Sister to Titusville Aglow. Cute with a real
   jump, in a hand-painted, glowing look. */
:root {
  --night: #000;
  --ghost: #eef1f6;          /* moon-white chalk */
  --ghost-glow: rgba(190, 215, 255, .55);
  --cobalt: #3d4dff;         /* the electric blue of a painted robe */
  --cobalt-glow: rgba(70, 90, 255, .75);
  --gold: #f4c64e;
  --note: rgba(238, 241, 246, .32);
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--night); color: var(--ghost); }
body { overflow: hidden; font-family: "Cinzel", Georgia, serif; }

/* ── THE INTRO ─────────────────────────────────────────────────────────── */
.intro {
  position: fixed; inset: 0;
  background: var(--night);
}
.intro__fx { position: absolute; width: 0; height: 0; }

/* every scene sits in the middle of the screen, one on top of another */
.intro__stage { position: absolute; inset: 0; }
/* the painted filter goes on each scene, shrink-wrapped to its words: on a
   full-screen layer the browser drew the filter's output scaled into the
   corner (seen 2026-10-20) */
[data-scene] {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: max-content; max-width: calc(100% - 32px); margin: 0; padding: 0 .3em;
  text-align: center;
  filter: url(#painted);                 /* smoke while words move; chalk and boil always */
}

/* the three lines: whispered, an italic hand */
.intro__verse {
  font-family: "Cormorant Garamond", Georgia, serif; font-style: italic; font-weight: 500;
  font-size: clamp(26px, 4.4vw, 60px); letter-spacing: .04em;
}

/* the title: bold classic capitals, TITUSVILLE in electric blue */
.intro__title {
  display: flex; flex-direction: column; align-items: center; gap: .1em;
  font-weight: 400; text-transform: uppercase; letter-spacing: .22em; line-height: 1.05;
}
.intro__line { display: block; font-size: clamp(22px, 4.6vw, 64px); }
.intro__line--to { font-size: clamp(14px, 2.2vw, 28px); letter-spacing: .5em; opacity: .8; margin: .2em 0; }
.intro__line--town { font-size: clamp(36px, 8.4vw, 124px); font-weight: 600; letter-spacing: .14em; color: var(--cobalt); }
.intro__line--town .wisp { text-shadow: 0 0 14px var(--cobalt-glow), 0 0 40px rgba(60, 80, 255, .45), 0 0 2px #9fb0ff; }

/* every letter is its own wisp (spooks.js wraps them) */
.wisp {
  display: inline-block;
  opacity: 0;
  filter: blur(14px);
  transform: translate(var(--dx, 0), var(--dy, 0)) scale(1.35);
  text-shadow: 0 0 18px var(--ghost-glow), 0 0 42px rgba(150, 190, 255, .25);
  will-change: opacity, filter, transform;
}
.wisp--space { width: .3em; }
/* gathering out of nothing */
.wisp.is-here {
  animation: gather var(--dur, 2.4s) cubic-bezier(.2, .7, .2, 1) var(--delay, 0s) forwards,
             haunt 5.5s ease-in-out calc(var(--delay, 0s) + var(--dur, 2.4s)) infinite alternate;
}
@keyframes gather {
  0%   { opacity: 0; filter: blur(14px); transform: translate(var(--dx, 0), var(--dy, 0)) scale(1.35); }
  55%  { opacity: .75; }
  100% { opacity: 1; filter: blur(0); transform: translate(0, 0) scale(1); }
}
/* once settled the letters are not quite solid: a slow float */
@keyframes haunt {
  from { transform: translate(0, 0); opacity: 1; }
  to   { transform: translate(0, var(--float, -3px)); opacity: .86; }
}
/* and back into smoke: rising, spreading, gone */
.wisp.is-gone {
  animation: vanish var(--out, 1s) ease-in var(--outdelay, 0s) forwards;
}
@keyframes vanish {
  from { opacity: 1; filter: blur(0); transform: translate(0, 0) scale(1); }
  to   { opacity: 0; filter: blur(12px); transform: translate(calc(var(--dx, 0) * .6), -28px) scale(1.2); }
}

.intro__sparks, .intro__rain { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
/* ── THE FIRE STATION ──────────────────────────────────────────────────
   Chrissy's layers, stacked 6 (back) to 0 (front), all covering the screen
   the same way so they line up. The station (1, 2) never moves; the sky
   breathes, the clouds drift, the fog rolls - each a little scaled up so a
   moving layer never shows its edge. */
.scene { position: absolute; inset: 0; overflow: hidden; opacity: 0; visibility: hidden; transition: opacity 1.3s ease; }
.scene.is-on { opacity: 1; visibility: visible; }
.scene__layer, .scene__inside { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.scene__inside { pointer-events: none; }
.scene__layer--6 { animation: sky 70s ease-in-out infinite alternate; }
.scene__layer--5 { animation: drift-a 80s ease-in-out infinite alternate; }
.scene__layer--4 { animation: drift-b 55s ease-in-out infinite alternate; }
.scene__layer--3 { animation: drift-c 42s ease-in-out infinite alternate; }
.scene__layer--0 { animation: fog 26s ease-in-out infinite alternate; }
/* the same fog flipped upside down, drifting the other way so the two never move together */
.scene__layer--0-flip { animation: fog-flip 31s ease-in-out infinite alternate; }
@keyframes sky     { from { transform: scale(1.03); } to { transform: scale(1.09) translateX(-1.2%); } }
@keyframes drift-a { from { transform: scale(1.12) translateX(-4%); } to { transform: scale(1.12) translateX(4%); } }
@keyframes drift-b { from { transform: scale(1.14) translateX(5%); } to { transform: scale(1.14) translateX(-5%); } }
@keyframes drift-c { from { transform: scale(1.1) translateX(-3%) translateY(.5%); } to { transform: scale(1.1) translateX(3.5%) translateY(-.5%); } }
@keyframes fog     { from { transform: scale(1.08) translateX(-3%); opacity: .82; } to { transform: scale(1.08) translateX(3%); opacity: 1; } }
@keyframes fog-flip { from { transform: scale(1.08, -1.08) translateX(3%); opacity: .9; } to { transform: scale(1.08, -1.08) translateX(-3%); opacity: .75; } }

/* the reaper: placed and walked by spooks.js, his feet the anchor */
.scene__reaper { position: absolute; left: 0; top: 0; height: auto; transform-origin: 50% 100%; pointer-events: none; will-change: transform, opacity, filter; }

.intro__portal { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* the title steps out of sight the moment its letters become rain */
.intro__title.is-crumbled { visibility: hidden; }

.intro__note {
  position: absolute; left: 16px; bottom: 14px; margin: 0;
  font-family: Georgia, serif; font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--note);
  opacity: 0; transition: opacity 2s ease;
}
.intro.is-titled .intro__note { opacity: 1; }

/* a calm version for anyone whose device asks for less motion */
@media (prefers-reduced-motion: reduce) {
  .intro__sparks { display: none; }
  .scene__layer { animation: none !important; }
  .wisp { filter: none; transform: none; }
  .wisp.is-here { animation: settle 1.2s ease var(--delay, 0s) forwards; }
  .wisp.is-gone { animation: fadeaway .8s ease forwards; }
  @keyframes settle { from { opacity: 0; } to { opacity: 1; } }
  @keyframes fadeaway { from { opacity: 1; } to { opacity: 0; } }
}
