:root {
  --bg: #0a0a0a;
  --fg: #f2f2f2;
  --muted: #8a8a8a;
  --grid-line: rgba(255, 255, 255, 0.06);
  --spotlight-alpha: 0.14;
  --spotlight-radius: 280px;
  --cursor-dot-size: 6px;
  --glow-radius: 140px;
  --x: 50%;
  --y: 50%;
}

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

html, body {
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  cursor: none;
}

a, button {
  cursor: none;
}

/* custom cursor — a dot with a lagging ring, hidden on touch devices */
.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  pointer-events: none;
  border-radius: 50%;
  will-change: transform;
}

.cursor-dot {
  width: var(--cursor-dot-size);
  height: var(--cursor-dot-size);
  margin: calc(var(--cursor-dot-size) / -2) 0 0 calc(var(--cursor-dot-size) / -2);
  background: var(--fg);
}

.cursor-ring {
  width: 32px;
  height: 32px;
  margin: -16px 0 0 -16px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  transition: width 0.2s ease, height 0.2s ease, margin 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.cursor-ring.hover {
  width: 52px;
  height: 52px;
  margin: -26px 0 0 -26px;
  border-color: rgba(255, 255, 255, 0.7);
  background: rgba(255, 255, 255, 0.06);
}

@media (hover: none), (pointer: coarse) {
  html, body, a, button { cursor: auto; }
  .cursor-dot, .cursor-ring { display: none; }
}

/* hidden until the first mousemove, and whenever the mouse leaves the window */
body:not(.cursor-visible) :is(.cursor-dot, .cursor-ring, .cursor-trail, .cursor-brackets, .cursor-coords, .cursor-axes) {
  opacity: 0;
}

/* --- cursor mode variants (temporary, for comparison) --- */

/* crosshair: dot hidden, ring becomes a plus-sign reticle */
body[data-cursor="crosshair"] .cursor-dot {
  opacity: 0;
}
body[data-cursor="crosshair"] .cursor-ring {
  width: 0;
  height: 0;
  margin: 0;
  border: none;
  background: none;
}
body[data-cursor="crosshair"] .cursor-ring::before,
body[data-cursor="crosshair"] .cursor-ring::after {
  content: "";
  position: absolute;
  background: rgba(255, 255, 255, 0.6);
  transition: width 0.2s ease, height 0.2s ease, background-color 0.2s ease;
}
body[data-cursor="crosshair"] .cursor-ring::before {
  width: 22px;
  height: 1px;
  top: 0;
  left: -11px;
}
body[data-cursor="crosshair"] .cursor-ring::after {
  width: 1px;
  height: 22px;
  top: -11px;
  left: 0;
}
body[data-cursor="crosshair"] .cursor-ring.hover::before {
  width: 34px;
  left: -17px;
  background: rgba(255, 255, 255, 0.9);
}
body[data-cursor="crosshair"] .cursor-ring.hover::after {
  height: 34px;
  top: -17px;
  background: rgba(255, 255, 255, 0.9);
}

/* invert: single blob that inverts whatever it passes over, no ring */
body[data-cursor="invert"] .cursor-ring {
  display: none;
}
body[data-cursor="invert"] .cursor-dot {
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  background: #fff;
  mix-blend-mode: difference;
  transition: width 0.2s ease, height 0.2s ease, margin 0.2s ease;
}
body[data-cursor="invert"] .cursor-dot.hover {
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
}

/* outline: no dot, just a ring that tracks exactly (no lag) */
body[data-cursor="outline"] .cursor-dot {
  display: none;
}

/* extra cursor pieces stay hidden unless their mode is active */
.cursor-axes,
.cursor-trail,
.cursor-brackets,
.cursor-coords {
  display: none;
}

.cursor-trail span,
.cursor-brackets,
.cursor-coords {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  pointer-events: none;
}

/* trail: comet tail of shrinking dots */
body[data-cursor="trail"] .cursor-ring { display: none; }
body[data-cursor="trail"] .cursor-trail { display: block; }
.cursor-trail span {
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--fg);
}

/* magnetic: ring snaps around whatever you hover (sizing driven by JS) */
body[data-cursor="magnetic"] .cursor-ring {
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

/* brackets: viewfinder corners that frame the hovered element */
body[data-cursor="brackets"] .cursor-ring { display: none; }
body[data-cursor="brackets"] .cursor-brackets { display: block; }
.cursor-brackets i {
  position: absolute;
  width: 8px;
  height: 8px;
  border: 0 solid rgba(255, 255, 255, 0.75);
}
.cursor-brackets i:nth-child(1) { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.cursor-brackets i:nth-child(2) { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.cursor-brackets i:nth-child(3) { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; }
.cursor-brackets i:nth-child(4) { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }

/* coords: full-screen hairlines + live x/y readout, like a CAD tool */
body[data-cursor="coords"] .cursor-ring { display: none; }
body[data-cursor="coords"] .cursor-axes,
body[data-cursor="coords"] .cursor-coords { display: block; }
.cursor-axes {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.12)) var(--x) 0 / 1px 100% no-repeat,
    linear-gradient(rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.12)) 0 var(--y) / 100% 1px no-repeat;
}
.cursor-coords {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
}

/* glow: background dots light up near the cursor (drawn on the grid canvas) */
body[data-cursor="glow"] .cursor-ring { display: none; }

@media (hover: none), (pointer: coarse) {
  .cursor-axes, .cursor-trail, .cursor-brackets, .cursor-coords { display: none !important; }
}

/* subtle dot-grid background */
.grid-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  background-image: radial-gradient(var(--grid-line) 1.5px, transparent 1.5px);
  background-size: 28px 28px;
}

/* canvas dot grid — replaces the CSS dots wherever JS can animate it */
.grid-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  display: none;
}

body.grid-live .grid-canvas {
  display: block;
}

body.grid-live .grid-bg {
  display: none;
}

/* cursor-tracked spotlight — lightens the grayscale page wherever it falls */
.spotlight {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: screen;
  background: radial-gradient(circle var(--spotlight-radius) at var(--x) var(--y), rgba(255, 255, 255, var(--spotlight-alpha)), transparent 70%);
}

main {
  position: relative;
  z-index: 2;
  text-align: center;
}

h1 {
  font-size: clamp(2rem, 6vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
}

.tagline {
  margin-top: 0.5rem;
  font-size: 1rem;
  font-weight: 400;
  color: var(--muted);
}

.links {
  margin-top: 2rem;
  display: flex;
  justify-content: center;
  gap: 1.25rem;
}

.links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--muted);
  transition: color 0.2s ease, background-color 0.2s ease;
}

.links a:hover,
.links a:focus-visible {
  color: var(--fg);
  background-color: rgba(255, 255, 255, 0.08);
}

.links a:focus-visible {
  outline: 1px solid rgba(255, 255, 255, 0.3);
  outline-offset: 2px;
}


/* page transitions: the text and icons fade while the grid dots swarm.
   The cursor stays, since the dots swarm into it. */
:is(main, .spotlight) {
  transition: opacity 0.3s ease;
}

body.exiting :is(main, .spotlight) {
  opacity: 0;
  pointer-events: none;
}

/* hidden until the intro's dots land, then fades in; the delayed animation is a
   failsafe that reveals the page if script.js never runs */
html.intro :is(main, .spotlight) {
  opacity: 0;
  animation: intro-failsafe 0s 6s forwards;
}

@keyframes intro-failsafe {
  to { opacity: 1; }
}

/* a hint to click, revealed only where the cursor's light falls (the same radius as the dot glow).
   The layer covers the window so the mask lines up with the cursor's window coordinates. */
.hint {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(circle var(--glow-radius) at var(--x) var(--y), #000, transparent);
  mask-image: radial-gradient(circle var(--glow-radius) at var(--x) var(--y), #000, transparent);
}

.hint span {
  position: absolute;
  left: 50%;
  bottom: 40px;
  transform: translateX(-50%);
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}

/* gone once someone has played, and whenever there's no cursor light or something else is on screen */
body:not(.cursor-visible) .hint,
body.played .hint,
body.game .hint,
body.exiting .hint,
html.intro .hint {
  display: none;
}

@media (hover: none), (pointer: coarse) {
  .hint { display: none; }
}

/* brick breaker: the cursor becomes the paddle (sized in brickbreaker.js) and the links are bricks */
.paddle {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  background: var(--fg);
  pointer-events: none;
  display: none;
  transition: width 0.2s ease, margin 0.2s ease, box-shadow 0.2s ease;
}

/* catching a power-up */
.paddle.flash {
  box-shadow: 0 0 14px 3px rgba(255, 255, 255, 0.6);
}

/* a broken brick falling with a power-up: the letter/icon tumbles, its tag stays upright below it */
.falling-brick {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.falling-glyph {
  display: block;
  white-space: nowrap;
}

.falling-tag {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 4px;
  padding: 1px 5px;
  font-family: "JetBrains Mono", monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--fg);
  background: rgba(10, 10, 10, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 4px;
  white-space: nowrap;
}

body.game .paddle {
  display: block;
}

body.game :is(.cursor-dot, .cursor-ring) {
  opacity: 0;
}

body.game .links a {
  pointer-events: none;
}

.game-hud {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--muted);
  pointer-events: none;
  white-space: nowrap;
}
