@font-face {
  font-family: "Press Start 2P";
  font-style: normal;
  font-weight: 400;
  font-display: block;          /* avoid fallback-font flash during the slam */
  src: url("/assets/fonts/press-start-2p-latin.woff2") format("woff2");
  unicode-range: U+0020-007F;   /* hostnames + GET BARKED only use ASCII */
}

:root {
  --bg: #050505;
  --fg: #f5f5f5;
  --tick-color: #ff006e;    /* silhouette palette tick (every 8th-note) */
  --text-color: #ff006e;    /* headline color — same palette, but stepped at
                               half the silhouette rate (once per beat) */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  overflow: hidden;
  cursor: crosshair;
}

#stage {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  display: block;
}

#overlay {
  position: fixed;
  inset: auto 0 6vh 0;
  z-index: 5;
  text-align: center;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4vh;
  opacity: 0;            /* hidden during intro; the drop adds .dropped */
}

#overlay.dropped { opacity: 1; }
#overlay.dropped #headline { animation: slam 0.36s cubic-bezier(0.18,1.4,0.36,1) 1, beat-pulse 0.5371s cubic-bezier(.2,.85,.4,1) 0.36s infinite; }
#overlay.dropped #domain   { animation: fade-up 0.5s 0.2s cubic-bezier(.2,.6,.3,1) backwards; }
#overlay.dropped #owner    { animation: fade-up 0.5s 0.32s cubic-bezier(.2,.6,.3,1) backwards; }

@keyframes slam {
  0%   { transform: scale(3.0) translateZ(0) rotate(-6deg); opacity: 0;
         text-shadow: 0 0 30px var(--tick-color), 0 0 50px var(--tick-color); }
  55%  { transform: scale(0.9) translateZ(0) rotate(0.7deg); opacity: 1; }
  100% { transform: scale(1)   translateZ(0) rotate(0);     opacity: 1; }
}

@keyframes fade-up {
  0%   { opacity: 0; transform: translateY(14px); }
  100% { opacity: 1; transform: translateY(0); }
}

#headline {
  font-family: "Press Start 2P", "JetBrains Mono", ui-monospace, monospace;
  font-weight: 400;
  font-size: clamp(1.4rem, 6vw, 5rem);     /* PS2P glyphs fill the em-box,
                                              ~2x wider than Bungee per char */
  line-height: 1.1;
  letter-spacing: 0.02em;
  color: var(--text-color);
  /* Cheap, saturated halo: ONE tight blur for the neon glow + a chunky pixel
     offset for the CRT-style drop. The 56px wide-blur layer that used to be
     here is the most expensive part of text-shadow paint (the blur kernel
     grows quadratically), and we repaint on every bounce — keeping it tight
     keeps the per-bounce paint cost low. The pixel-art glyphs don't need a
     soft outer halo; a saturated tight one reads as neon, not blown out. */
  text-shadow:
    0 0 14px var(--text-color),
    3px 3px 0 rgba(0,0,0,0.55);
  will-change: transform, text-shadow;
  transform: translateZ(0);     /* promote to its own composite layer up-front */
  position: relative;
  white-space: nowrap;
}

/* glitch-shift duplicate via ::before/::after using data-text.
   will-change: transform promotes each ghost layer onto its own composited
   surface so jitter-a/jitter-b transforms don't trigger a paint on the parent
   stacking context — pure compositor work. mix-blend-mode is preserved (the
   additive CRT-bleed look is part of the design). */
#headline::before,
#headline::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  will-change: transform;
}
/* Glitch ghosts: cyan/yellow with screen blend used to add to the magenta base
   and bleach the overlap regions toward white. Halve opacity so the chromatic
   aberration reads as a thin colored fringe instead of a bright bleed. */
#headline::before {
  color: #00e5ff;
  transform: translate(-2px, -1px);
  opacity: 0.28;
  animation: jitter-a 1.07s steps(8, end) infinite;
}
#headline::after {
  color: #ffd600;
  transform: translate(2px, 2px);
  opacity: 0.24;
  animation: jitter-b 0.83s steps(7, end) infinite;
}

@keyframes beat-pulse {
  0%   { transform: scale(1)    translateZ(0) skewX(0deg); }
  8%   { transform: scale(1.07) translateZ(0) skewX(-1.2deg); }
  30%  { transform: scale(1.02) translateZ(0) skewX(0deg); }
  100% { transform: scale(1)    translateZ(0) skewX(0deg); }
}

@keyframes jitter-a {
  0%, 100% { transform: translate(-2px, -1px); }
  25%      { transform: translate(-4px, 1px); }
  50%      { transform: translate(-1px, -3px); }
  75%      { transform: translate(-3px, 2px); }
}
@keyframes jitter-b {
  0%, 100% { transform: translate(2px, 2px); }
  20%      { transform: translate(4px, -1px); }
  55%      { transform: translate(1px, 3px); }
  80%      { transform: translate(3px, -2px); }
}

#domain {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 700;
  font-size: clamp(1.1rem, 2.6vw, 1.9rem);
  letter-spacing: 0.35em;
  text-transform: uppercase;
  color: var(--fg);
  opacity: 0.92;
  text-shadow: 0 0 10px var(--tick-color);
}

#owner {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-weight: 400;
  font-size: clamp(0.7rem, 1.3vw, 1rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  opacity: 0.55;
}

/* Arcade-style attract prompt: static dog on canvas + blinking white pixel-art
   text. Stays visible until the first user gesture (or browser-granted
   autoplay) starts the visuals + audio together from t=0. Sits just below
   where the dog renders (mascot.centerY = 30% of viewport, h ≈ 46% of min
   dim) so the dog and the prompt read as one composition. */
#attract {
  position: fixed;
  left: 0;
  right: 0;
  top: 58%;
  z-index: 6;
  text-align: center;
  pointer-events: none;
  color: #ffffff;
  font-family: "Press Start 2P", "JetBrains Mono", ui-monospace, monospace;
  font-size: clamp(0.85rem, 2vw, 1.3rem);
  letter-spacing: 0.1em;
  /* No glow halo — arcade machines just blit white pixels onto a CRT. */
  text-shadow: none;
}
#attract.hidden { display: none; }

/* steps(2, end) gives a hard on/off square wave at ~1 Hz — same flicker rate
   as a classic CADILLAC/INSERT-COIN attract loop. */
@keyframes arcade-blink {
  0%, 50%       { opacity: 1; }
  50.01%, 100%  { opacity: 0; }
}
#attract { animation: arcade-blink 1.07s steps(2, end) infinite; }

/* Respect motion preferences: skip the slam, beat-pulse, and glitch jitter.
   The canvas-side bob + ripples still play (they're tied to audio, not the
   slam). Reduced-motion users get a calm fade-in instead of a screen-shaker. */
@media (prefers-reduced-motion: reduce) {
  #overlay.dropped #headline,
  #overlay.dropped #domain,
  #overlay.dropped #owner {
    animation: fade-up 0.4s ease-out backwards;
  }
  #headline::before,
  #headline::after { animation: none; }
  #attract { animation: none; }
}
