/* hard2code — silent riddle. black / grey / dark red. */

:root {
  --bg: #111111;
  --ink: #8f8f8f;
  --ink-dim: #4a4a4a;
  --blood: #7f1d1d;
  --blood-bright: #a12626;
  --mono: "Courier New", Courier, monospace;
}

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

html {
  background: var(--bg);
  scrollbar-width: thin;
  scrollbar-color: #2a2a2a var(--bg);
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--mono);
  overflow-x: hidden;
  cursor: crosshair;
}

/* rare full-screen glitch: light/dark flash over everything + text jolt */
.screen-flash {
  position: fixed;
  inset: 0;
  z-index: 8;
  pointer-events: none;
  opacity: 0;
  background: rgba(228, 228, 228, 0.06);
}

.screen-flash.dark { background: rgba(0, 0, 0, 0.45); }
.screen-flash.on { opacity: 1; }

/* the score's breakdown: hard cuts, not whispers */
.screen-flash.hard { background: rgba(232, 232, 232, 0.30); }
.screen-flash.hard.dark { background: rgba(0, 0, 0, 0.88); }

main.jolt { transform: translate(var(--bgx, 0), var(--bgy, 0)); }

::selection {
  background: var(--blood);
  color: #d4d4d4;
}

/* ---------- layers ---------- */

#fog {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.grain {
  position: fixed;
  inset: -100%;
  z-index: 2;
  pointer-events: none;
  opacity: 0.07;
  animation: grain-jitter 0.9s steps(4) infinite;
}

@keyframes grain-jitter {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-2%, 3%); }
  50%  { transform: translate(3%, -2%); }
  75%  { transform: translate(-3%, -3%); }
  100% { transform: translate(2%, 2%); }
}

.vignette {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(ellipse at center,
    transparent 40%,
    rgba(0, 0, 0, 0.55) 78%,
    rgba(0, 0, 0, 0.92) 100%);
}

.red-pulse {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(ellipse at 50% 120%,
    rgba(127, 29, 29, 0.28) 0%,
    transparent 60%);
}

.red-pulse.flash {
  animation: red-flash 1.4s ease-out;
}

@keyframes red-flash {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  100% { opacity: 0; }
}

/* paint drips leaking from the hero letters down to the footer */
#drips {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 4;
  pointer-events: none;
}

/* the score's darkness — driven by the track's narrative (JS transitions) */
.dread {
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  background: #000;
  opacity: 0;
}

/* approaching dread: the content itself trembles */
main.tremor { animation: tremor 0.12s linear infinite; }

@keyframes tremor {
  0%   { transform: translate(0.4px, -0.3px); }
  25%  { transform: translate(-0.4px, 0.3px); }
  50%  { transform: translate(0.3px, 0.4px); }
  75%  { transform: translate(-0.3px, -0.4px); }
  100% { transform: translate(0.4px, -0.3px); }
}

/* the breakdown thrash: stepped like scratched film (~10fps),
   not smooth — smooth reads artificial. sits after tremor so it
   wins the animation while both classes are on */
main.breakdown { animation: breakdown 1.05s steps(1, end); }

@keyframes breakdown {
  0%   { transform: translate(0, 0) rotate(0deg); }
  8%   { transform: translate(-17px, 9px) rotate(-0.8deg); }
  17%  { transform: translate(14px, -12px) rotate(0.9deg); }
  27%  { transform: translate(-19px, -5px) rotate(-1deg); }
  39%  { transform: translate(12px, 13px) rotate(0.7deg); }
  51%  { transform: translate(-8px, -14px) rotate(-0.5deg); }
  63%  { transform: translate(9px, 6px) rotate(0.4deg); }
  77%  { transform: translate(-5px, -4px) rotate(-0.3deg); }
  89%  { transform: translate(3px, 2px) rotate(0.15deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}

/* ---------- content ---------- */

main {
  position: relative;
  z-index: 5;
}

.screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 12vh 8vw;
  gap: 1.6rem;
  position: relative;
}

.line {
  font-size: clamp(0.95rem, 2.2vw, 1.35rem);
  letter-spacing: 0.35em;
  text-transform: lowercase;
  color: var(--ink);
}

.reveal {
  opacity: 0;
  filter: blur(6px);
  transform: translateY(10px);
  transition:
    opacity 2.8s ease,
    filter 2.8s ease,
    transform 2.8s ease;
}

.reveal.visible {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}

/* ---------- hero ---------- */

.screen--hero { gap: 2.4rem; }

.glitch {
  font-size: clamp(2.2rem, 8vw, 6rem);
  font-weight: 700;
  letter-spacing: 0.28em;
  text-indent: 0.28em; /* recentre letter-spacing */
  color: #c9c9c9;
  position: relative;
  animation: hero-in 6s ease-out both;
  /* cold fluorescent tube glow */
  text-shadow:
    0 0 14px rgba(190, 205, 215, 0.22),
    0 0 46px rgba(190, 205, 215, 0.10);
}

@keyframes hero-in {
  from { opacity: 0; filter: blur(14px); }
  to   { opacity: 1; filter: blur(0); }
}

/* the 25th frame: during the breakdown the name is 1984,
   for a blink the conscious mind misses */
.subliminal {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  letter-spacing: 0.28em;
  text-indent: 0.28em;
  pointer-events: none;
  opacity: 0;
}

.glitch.framed { opacity: 1 !important; } /* punches through the sunk dark */
.glitch.framed .glyph,
.glitch.framed .two { visibility: hidden; }
.glitch.framed .subliminal { opacity: 1; }

/* the accent "2": slightly taller, paint chipped off (mask generated in JS) */
.two {
  font-size: 1.18em;
  letter-spacing: 0;           /* kill the inherited trailing space… */
  margin-right: 0.237em;       /* …add back 0.28em of the base font, symmetric */
}

.sub {
  font-size: clamp(0.8rem, 2.1vw, 1.1rem); /* accent: the anchor speaks here */
  letter-spacing: 0.35em; /* narrower than before — long quotes must survive */
  text-indent: 0.35em;
  color: var(--ink);
  animation-delay: 1.8s;
}

/* the echo under it — quieter, dimmer */
.sub2,
.sub3 {
  font-size: clamp(0.7rem, 1.7vw, 0.95rem);
  letter-spacing: 0.35em;
  text-indent: 0.35em;
  color: var(--ink-dim);
}

/* the last step of the ladder is warm — an ember, not a siren */
.sub3 { color: var(--blood-bright); }

/* thin blinking scroll line */
.scroll-hint {
  position: absolute;
  bottom: 6vh;
  left: 50%;
  width: 1px;
  height: 7vh;
  background: linear-gradient(to bottom, transparent, var(--ink-dim));
  animation: hint-breathe 4s ease-in-out infinite;
}

@keyframes hint-breathe {
  0%, 100% { opacity: 0.15; }
  50%      { opacity: 0.6; }
}

/* ---------- last screen secrets ---------- */

.wall-note {
  position: absolute;
  right: 6vw;
  bottom: 14vh;
  font-size: 0.7rem;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0.08;
  transform: rotate(-2deg);
  user-select: none;
}

.dot {
  position: absolute;
  left: 9vw;
  top: 30vh;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--blood);
  opacity: 0.3;
  cursor: pointer;
  transition: opacity 0.25s ease;
  /* it breathes like the lamp — a patient eye catches the motion */
  animation: dot-breathe 7s ease-in-out infinite;
}

/* a wider invisible grip around the pinhead */
.dot::after {
  content: "";
  position: absolute;
  inset: -11px;
}

.dot:hover {
  animation-play-state: paused;
  opacity: 0.75;
}

/* every knock is answered — a brief freeze at full blood */
.dot.tick {
  animation-play-state: paused;
  opacity: 0.9;
}

@keyframes dot-breathe {
  0%, 100% { opacity: 0.14; }
  50% { opacity: 0.55; }
}

.hidden-line {
  position: absolute;
  left: 9vw;
  top: 26vh;
  font-size: 0.8rem;
  letter-spacing: 0.5em;
  color: var(--blood-bright);
  opacity: 0;
  transition: opacity 3s ease;
  user-select: none;
}

.hidden-line.shown { opacity: 0.85; cursor: pointer; }

/* ---------- balloon (banksy easter egg) ---------- */

#balloon {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 7;
  pointer-events: none;
}

/* ---------- language switch ---------- */

.lang {
  position: fixed;
  top: 3vh;
  right: 3vw;
  z-index: 10;
  display: flex;
  gap: 1.4em;
}

.lang button {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.3em;
  color: #383838;
  cursor: pointer;
  transition: color 1.2s ease;
}

.lang button:hover { color: var(--ink); }
.lang button.active { color: var(--ink); }

/* ---------- colophon ---------- */

.colophon {
  position: relative;
  z-index: 5;
  text-align: center;
  padding: 6vh 0 5vh;
  font-size: 0.75rem;
  letter-spacing: 0.5em;
  color: #2e2e2e;
  user-select: none;
}

/* the years underneath — quieter than quiet */
.colophon .years {
  display: block;
  margin-top: 1.1em;
  color: #242424;
}

/* ---------- accessibility ---------- */

@media (prefers-reduced-motion: reduce) {
  .grain,
  .scroll-hint,
  .glitch,
  .dot,
  .sub { animation: none; }
  .reveal { transition: opacity 0.6s ease; filter: none; transform: none; }
}

/* ---------- the blood web ----------
   veins seep in from the edges once the performance begins;
   the wash closes the field to almost solid blood by the apogee.
   both sit above the fog, under the grain */
#veins {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

#blood-wash {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: #3a0909;
  opacity: 0;
}

/* the guitar burst: the background itself turns to blood.
   sits under the veins lace, driven by the score (inline transitions) */
.apogee {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: #7f1d1d;
  opacity: 0;
}

/* tears on the glass — pale droplets sliding down while she cries;
   above the content, under the balloons */
#tears {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
}

/* ---------- the wake ----------
   appears only when the track has played itself out */
#wake {
  position: fixed;
  left: 50%;
  bottom: 18vh;
  transform: translateX(-50%);
  z-index: 11;
  background: none;
  border: 1px solid rgba(201, 201, 201, 0.25);
  border-radius: 2px;
  color: var(--ink);
  font: inherit;
  font-size: clamp(0.95rem, 2vw, 1.2rem);
  letter-spacing: 0.35em;
  text-transform: lowercase;
  padding: 0.9em 2.2em 0.9em calc(2.2em + 0.35em);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 4s ease, border-color 0.6s ease;
}

#wake.shown {
  opacity: 1;
  pointer-events: auto;
}

#wake:hover { border-color: rgba(201, 201, 201, 0.6); }

/* the dawn: one press and everything ends in slow light */
.dawn {
  position: fixed;
  inset: 0;
  z-index: 12;
  pointer-events: none;
  background: #e9e5dc;
  opacity: 0;
  transition: opacity 9s ease;
}

.dawn.risen { opacity: 1; }

/* the morning after: the inversion, in soft ink on the light */
.morning {
  position: fixed;
  inset: 0;
  z-index: 13;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1.8rem;
  text-align: center;
  padding: 0 8vw;
  pointer-events: none;
  opacity: 0;
  transition: opacity 4s ease;
}

.morning.shown { opacity: 1; }

.morning-line {
  color: #3a3833;
  letter-spacing: 0.35em;
  text-indent: 0.35em;
  text-transform: lowercase;
  font-size: clamp(1.15rem, 3vw, 1.8rem);
}

.morning-line--dim {
  color: #6b675f;
  font-size: clamp(0.85rem, 2vw, 1.15rem);
}
