/* Christopher Dreamstate — single-row layout, serif, soft-hole reveal */

/* Instrument Sans (OFL) — self-hosted, no external dependency */
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/instrument-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/instrument-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@property --r {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

/* --ap drives the "aperture to another layer of colour" opening on .veil-b */
@property --ap {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

:root {
  --ground: #0a0304;
  --red: #c8102e;
  --red-glow: rgba(200, 16, 46, 0.5);
  --text: #f3ece9;
  --muted: rgba(243, 236, 233, 0.5);
  --line: rgba(243, 236, 233, 0.22);

  --reveal-radius: 240px;
  --mx: 50%;
  --my: 50%;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --menu: "Instrument Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mark-h: clamp(30px, 3.9vh, 46px);   /* shared height for ABOUT + signature */
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }

body {
  background: var(--ground);
  color: var(--text);
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

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

/* ---------- stage + layers ---------- */

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

.hidden-layer {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--ground);
}

.burst {
  position: absolute;
  inset: 0;
  z-index: 5;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
}
.burst.is-firing { opacity: 1; }

/* The base hero (.veil) sits at the bottom. Every ~2s main.js drops a
   .veil-flow layer on top with the next colour and opens its aperture —
   a soft, ill-defined blob of radius --ap spreading from near the brow —
   so colour keeps pulsing across the screen. Each layer also carries the
   cursor reveal hole; mask-composite: intersect means a pixel shows only
   outside the reveal hole AND inside the aperture. */
.veil, .veil-b, .veil-flow {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #000 center / cover no-repeat;
  pointer-events: none;
  --apx: 37%;
  --apy: 42%;
  transition: --ap 4300ms cubic-bezier(.4,0,.35,1);
  -webkit-mask-image:
    radial-gradient(circle var(--r) at var(--mx) var(--my), transparent 0%, transparent 30%, rgba(0,0,0,0.5) 64%, #000 96%),
    radial-gradient(ellipse var(--ap) var(--ap) at var(--apx) var(--apy),
      #000 0%, #000 28%, rgba(0,0,0,0.55) 52%, rgba(0,0,0,0.16) 78%, transparent 100%);
  mask-image:
    radial-gradient(circle var(--r) at var(--mx) var(--my), transparent 0%, transparent 30%, rgba(0,0,0,0.5) 64%, #000 96%),
    radial-gradient(ellipse var(--ap) var(--ap) at var(--apx) var(--apy),
      #000 0%, #000 28%, rgba(0,0,0,0.55) 52%, rgba(0,0,0,0.16) 78%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
.veil {
  background-image: url("assets/background.jpg");
  --ap: 260%;   /* the base layer is always fully open */
}
/* during a colour turn the base hero dips, so the menu beneath ghosts
   through — visible but faint — then the new colour hides it again */
@keyframes veilBleed {
  0%   { opacity: 1; }
  18%  { opacity: 0.86; }
  60%  { opacity: 0.86; }   /* hold the faint ghost, so the menu lingers */
  100% { opacity: 1; }
}
.veil.is-bleeding { animation: veilBleed var(--bleed, 5600ms) ease-in-out both; }
.veil-b { --ap: 0%; }
.veil-flow { z-index: 2; --ap: 0%; }   /* stacks above the base, newest on top */

/* ---------- drifting thoughts (lines of poetry) ---------- */

.thoughts {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow: hidden;
  pointer-events: none;
}

/* golden particle-track trails that follow each thought and decay,
   like tracks in a bubble chamber */
.trails {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.thought {
  position: absolute;
  font-size: clamp(0.52rem, 0.72vw, 0.76rem);
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: #fff;
  text-shadow: 0 0 22px rgba(0, 0, 0, 0.7), 0 0 6px rgba(0, 0, 0, 0.55), 0 1px 2px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  opacity: 0;
  transform: translate(0, 0);
  animation: thoughtDrift var(--dur, 18s) linear forwards;
}

@keyframes thoughtDrift {
  0%   { opacity: 0; transform: translate(0, 0); }
  12%  { opacity: var(--peak, 0.5); }
  50%  { transform: translate(var(--mx2, 0), var(--my2, 0)); }   /* bowed midpoint — a gentle curve */
  70%  { opacity: var(--peak, 0.5); }
  100% { opacity: 0; transform: translate(var(--dx, 0), var(--dy, 0)); }
}

/* ---------- the single row ---------- */

.grid {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: fit-content;
  max-width: 92vw;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.7rem, 2.2vw, 2.4rem);
}

/* the line the words sit on — spans just the row */
.grid::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--line);
}

.cell {
  position: relative;
  z-index: 1;
  background: var(--ground);
  padding: 0.55rem clamp(0.45rem, 1.1vw, 1rem);
  color: var(--text);
  text-decoration: none;
  font-family: var(--menu);
  font-size: clamp(0.92rem, 1.32vw, 1.4rem);
  font-weight: 400;
  letter-spacing: 0.005em;
  line-height: 1.25;
  text-transform: lowercase;
  white-space: nowrap;
  transition: color 300ms ease, text-shadow 200ms ease, transform 170ms ease-out;
}

/* the last item is long — keep it on one line, same size as the rest */
.cell:last-child {
  white-space: nowrap;
}

.cell.is-near {
  text-shadow: 0 0 22px var(--red-glow);
}
.cell:hover,
.cell.is-near:hover {
  text-shadow: 0 0 24px var(--red-glow);
}
.cell--soon { color: var(--muted); cursor: default; }
.cell--soon:hover { text-shadow: none; }

/* each letter is its own box so it can bulge as the cursor rolls across */
.cell .ch {
  display: inline-block;
  white-space: pre;
  transform-origin: 50% 50%;
  transition: transform 140ms cubic-bezier(.34, 1.5, .64, 1);
}

a.cell:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }

/* ---------- About (top centre) ---------- */

.about-trigger {
  position: absolute;
  z-index: 4;   /* always visible, above the field + drifting text — a fixed anchor */
  top: clamp(5rem, 26vh, 16rem);
  left: 50%;
  transform: translateX(-50%);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  line-height: 0;
  animation: aboutFloat 72s ease-in-out infinite;   /* desktop only — 25% of the thought lines' speed */
}
@keyframes aboutFloat {
  0%   { transform: translateX(-50%) translateY(0); }
  50%  { transform: translateX(-50%) translateY(calc(-1 * var(--about-rise, 200px))); }
  100% { transform: translateX(-50%) translateY(0); }
}
.about-trigger img {
  display: block;
  width: auto;
  height: var(--mark-h);
  opacity: 0.92;
  filter: drop-shadow(0 0 14px rgba(0, 0, 0, 0.6));   /* legible over any pulse colour */
  transition: transform 170ms ease-out, opacity 200ms ease;
}
.about-trigger:hover img { transform: scale(1.16); opacity: 1; }
.about-trigger:focus-visible { outline: 2px solid var(--red); outline-offset: 6px; }

/* ---------- logo (top left) ---------- */

.logo {
  position: absolute;
  left: clamp(1rem, 3vw, 2.75rem);
  top: clamp(1rem, 3vw, 2.75rem);
  z-index: 3;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  width: clamp(72px, 7.5vw, 108px);
  filter: drop-shadow(0 0 18px rgba(0, 0, 0, 0.5));
}
.logo img {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0.92;
  transition: transform 170ms ease-out, opacity 200ms ease;
}
.logo:hover img { transform: scale(1.16); opacity: 1; }
.logo:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; }

/* ---------- signature (bottom centre, revealed on hover) ---------- */

.signature {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: clamp(3.5rem, 13vh, 8.5rem);
  transform: translateX(-50%);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  line-height: 0;
}
.signature img {
  display: block;
  width: auto;
  height: var(--mark-h);
  opacity: 0.92;
  transition: transform 170ms ease-out, opacity 200ms ease;
}
.signature:hover img { transform: scale(1.16); opacity: 1; }
.signature:focus-visible { outline: 2px solid var(--red); outline-offset: 6px; }

/* ---------- hint ---------- */

.hint {
  position: absolute;
  left: 50%; top: 66%;
  transform: translate(-50%, -50%);
  z-index: 3;
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--text);
  mix-blend-mode: difference;
  opacity: 0;
  animation: hintIn 1.1s ease 1.5s forwards;
  pointer-events: none;
}
.stage.touched .hint { animation: none; opacity: 0; transition: opacity 400ms ease; }
@keyframes hintIn {
  from { opacity: 0; letter-spacing: 0.5em; }
  to   { opacity: 0.6; letter-spacing: 0.36em; }
}

/* ---------- ambient music mute toggle ---------- */

.sound-toggle {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 4;
  background: none;
  border: 0;
  padding: 0.5rem 0.3rem;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 0.6rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--text);
  mix-blend-mode: difference;
  opacity: 0.55;
  transition: opacity 300ms ease;
}
.sound-toggle:hover,
.sound-toggle:focus-visible { opacity: 0.95; }
.sound-toggle:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; }

/* ---------- About panel ---------- */

.about {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: grid;
  place-items: center;
  padding: 2rem;
  background: rgba(6, 2, 3, 0);
  visibility: hidden;
  opacity: 0;
  transition: opacity 600ms ease, background 600ms ease, visibility 0s linear 600ms;
}
.about.is-open {
  visibility: visible;
  opacity: 1;
  background: rgba(6, 2, 3, 0.94);
  transition: opacity 600ms ease, background 600ms ease;
  cursor: pointer;
}
.about__inner {
  max-width: 46ch;
  text-align: center;
  transform: translateY(12px);
  transition: transform 700ms cubic-bezier(.22, 1, .36, 1);
}
.about.is-open .about__inner { transform: translateY(0); }
.about__text {
  font-size: clamp(0.78rem, 1.15vw, 0.92rem);
  line-height: 1.7;
}
.about__tbc { color: var(--muted); }
.about__close {
  margin-top: 2.5rem;
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- touch / no hover: plain, visible, scrollable ---------- */

@media (hover: none), (pointer: coarse) {
  body { overflow: auto; }
  .stage { position: relative; min-height: 100svh; display: flex; flex-direction: column; }
  .hidden-layer { position: relative; inset: auto; order: 2; padding-top: 2rem; }
  /* the hero image comes first, above the menu; the colour pulse runs
     inside this banner (main.js appends .veil-flow layers into it) */
  .veil { position: relative; order: 1; height: 44svh; overflow: hidden; -webkit-mask-image: none; mask-image: none; }
  .veil-b { display: none; }
  /* mobile pulse: a plain opacity crossfade — no aperture mask */
  .veil-flow--fade {
    -webkit-mask-image: none;
    mask-image: none;
    opacity: 0;
    transition: opacity 3000ms ease;
  }
  .thoughts { display: none; }
  .trails { display: none; }
  .cell__tail { display: none; }   /* "post advent calendar" only, on mobile */
  .grid {
    position: relative;
    top: auto; left: auto; transform: none;
    width: auto; max-width: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0;
  }
  .grid::before { display: none; }
  .cell {
    white-space: normal;
    text-align: center;
    padding: 1.1rem;
    border-top: 1px solid var(--line);
    font-size: 1.05rem;
  }
  .cell:last-child { max-width: none; }

  /* header: logo left, ABOUT centred — equal breathing room top & bottom */
  .logo { width: 44px; left: 1rem; top: 1.8rem; }
  .about-trigger {
    position: absolute;
    z-index: 4;
    top: 1.8rem;
    left: 50%;
    transform: translateX(-50%);
    animation: none;
    margin: 0;
    width: fit-content;
  }
  .about-trigger img { height: 28px; }

  .signature { position: static; transform: none; display: block; width: fit-content; margin: 1.8rem auto 1.8rem; }
  .hint { display: none; }
  .about { position: fixed; }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  body { overflow: auto; }
  .stage { position: relative; min-height: 100svh; display: flex; flex-direction: column; }
  .hidden-layer { position: relative; inset: auto; order: 2; }
  .veil { position: relative; order: 1; height: 42svh; -webkit-mask-image: none; mask-image: none; transition: none; }
  .veil-b { display: none; }
  .thoughts { display: none; }
  .trails { display: none; }
  .about-trigger { order: 0; }
  .grid { position: relative; top: auto; left: auto; transform: none; width: auto; max-width: none; flex-wrap: wrap; justify-content: center; padding: 1.5rem; }
  .grid::before { display: none; }
  .cell { white-space: normal; }
  .cell.is-near { transform: none; text-shadow: none; }
  .signature { position: static; transform: none; display: block; width: fit-content; margin: 1.5rem auto; }
  .about-trigger { position: relative; left: auto; transform: none; animation: none; display: block; width: fit-content; margin: 1rem auto; }
  .hint { display: none; }
  .about__inner { transition: none; }
}
