/* ============================================================
   Living background canvas
   Sizing is JS-only (window.screen.height technique) — CSS must
   never set height via %, inset, or vh, or the buffer will be
   stretched by the browser on address-bar show/hide.
   ============================================================ */
#bg-canvas {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  pointer-events: none;
  display: block;
}

/* ============================================================
   Intro overlay: a backdrop (the opaque "void" behind the star)
   separate from the canvas that draws the star itself. The backdrop
   fades out mid-journey so the real site materializes gradually
   while the star is still flying home — the canvas stays fully
   opaque throughout so the star itself never dims. Both created
   dynamically by star-intro.js.
   ============================================================ */
#intro-backdrop {
  position: fixed;
  inset: 0;
  z-index: 9998;
  cursor: pointer; /* click-to-skip — canvas delegates to backdrop */
  background: radial-gradient(ellipse at 50% 40%, #131a2c 0%, #0a0e17 70%);
  opacity: 1;
  transition: opacity 4.2s ease; /* stage 1: reaches 50% by roughly when the dialogue appears */
}
#intro-backdrop.is-revealing-half {
  opacity: 0.5;
}
#intro-backdrop.is-revealing-full {
  /* higher specificity than .is-revealing-half so it always wins once both are present */
  opacity: 0;
  transition: opacity 1.4s ease; /* stage 2: the rest of the reveal, once the visitor continues */
  pointer-events: none; /* once fading out, stop intercepting clicks on the real site */
}
#intro-canvas {
  position: fixed;
  inset: 0;
  z-index: 10001; /* above #intro-dialogue (10000) so compositor layer order never inverts the star */
  pointer-events: none; /* click-to-skip is handled by #intro-backdrop below */
  background: transparent;
}
#intro-canvas.is-fading {
  opacity: 0;
  transition: opacity 0.42s ease;
  pointer-events: none;
}

/* The real site stays blurred behind the backdrop while the star is
   still greeting the visitor, and comes into focus in step with the
   stage-2 reveal above (see revealFully() in star-intro.js). The
   transition lives on the always-matching base rule (not inside the
   .nova-intro-blur variant) so it's armed for both directions —
   scoping it only to the "blurred" state would make the blur-out on
   class removal snap instantly instead of animating. */
body > header,
body > main,
body > footer,
body > #bg-canvas {
  transition: filter 1.4s ease;
}
body.nova-intro-blur > header,
body.nova-intro-blur > main,
body.nova-intro-blur > footer,
body.nova-intro-blur > #bg-canvas {
  filter: blur(18px);
}

/* ============================================================
   Intro dialogue panel — the star's mid-flight greeting. Real DOM
   text (crisp, accessible) fixed near the bottom of the viewport,
   independent of the star's own canvas position. pointer-events:none
   so clicking it still triggers the canvas's skip-intro handler.
   ============================================================ */
#intro-dialogue {
  position: fixed;
  left: 50%;
  bottom: 10%;
  transform: translate(-50%, 12px);
  width: min(94vw, 864px); /* +80% of the original 480px cap */
  z-index: 10000;
  pointer-events: none;
  background: rgba(16, 22, 46, 0.92);
  border: 1px solid rgba(108, 92, 231, 0.5);
  border-radius: 29px;
  padding: 1.8em 2.25em; /* em — scales with the element's own px font-size above, not root */
  color: #e8ecf4;
  font-family: 'Inter', sans-serif;
  /* Scales fluidly with viewport width instead of a fixed desktop size —
     at 27.36px (the desktop-verified +80% size) on anything narrower
     than ~650px wide, this much text wrapped that large ran taller
     than the screen itself, cutting the greeting off top and bottom. */
  /* px instead of rem — immune to Chrome's per-profile font-size preference
     (Settings → Appearance → Font size), which silently scales rem units and
     was causing the dialogue to render at different sizes across profiles.
     Manual zoom (Ctrl+/−) still works correctly — it scales px too. */
  font-size: clamp(16px, 4.2vw, 27px);
  line-height: 1.5;
  text-align: center;
  /* Safety net: however long the greeting text or however narrow the
     screen, the panel scrolls internally instead of overflowing past
     the top/bottom of the viewport (fixed-position elements don't
     get pushed into document flow, so an overflow here is invisible
     content, not just an ugly one). */
  max-height: 74vh;
  overflow-y: auto;
  opacity: 0;
  transition: opacity 0.4s ease, transform 0.4s ease;
  box-shadow: 0 16px 60px -16px rgba(0, 0, 0, 0.65);
}
#intro-dialogue p { margin: 0 0 1.1em; }
#intro-dialogue::after {
  content: '';
  position: absolute;
  top: -14px;
  left: 50%;
  width: 25px;
  height: 25px;
  transform: translateX(-50%) rotate(45deg);
  background: rgba(16, 22, 46, 0.92);
  border-left: 1px solid rgba(108, 92, 231, 0.5);
  border-top: 1px solid rgba(108, 92, 231, 0.5);
}
#intro-dialogue.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}
#intro-dialogue strong { color: #ffc247; }
#intro-dialogue em { color: #00d4ff; font-style: normal; }
#intro-dialogue #introContinue {
  pointer-events: auto;
  font-size: 0.55em; /* relative to the (now much larger) dialogue font-size */
  padding: 0.6em 1.3em;
}

/* ============================================================
   Nav "living logo" star
   ============================================================ */
.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.logo-star {
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
  filter: drop-shadow(0 0 4px rgba(255, 201, 92, 0.5));
  animation: novaPulse 2.6s ease-in-out infinite;
}
.logo-star.is-ready {
  opacity: 1;
  transform: scale(1);
}
@keyframes novaPulse {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(255, 201, 92, 0.5)); }
  50%      { filter: drop-shadow(0 0 11px rgba(255, 201, 92, 0.95)); }
}

/* ============================================================
   Custom cursor — real, functional cursor with a star glyph.
   Sparkle trail (canvas-drawn) is additive, see living-background.js.
   Only on devices with a precise pointer — never on touch.
   ============================================================ */
@media (pointer: fine) {
  body {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M12 0 L14.5 9.5 L24 12 L14.5 14.5 L12 24 L9.5 14.5 L0 12 L9.5 9.5 Z' fill='%23ffd166' opacity='0.9'/%3E%3C/svg%3E") 12 12, auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .logo-star { animation: none; transition: opacity 0.3s ease; }
}
