/* ============================================================================
   THEME — Neobrutalism (dark)
   Shared design tokens + reusable component utilities.

   Loads site-wide via `stylesheet_link_tag :app`, but the visual *base* is
   scoped to `body.theme` so pages that manage their own look (radar, the
   full-bleed /work canvases) are untouched. Tokens and `.nb-*` utilities are
   inert until referenced, so future pages can opt in by adding the class.
   ========================================================================== */

:root {
  /* Surfaces */
  --bg:       #0d0d11;
  --bg-2:     #15151c;
  --ink:      #f6f4ea;   /* cream — borders + primary text */
  --ink-dim:  #a8a596;

  /* Clashing accents (the kitsch) */
  --pink:     #ff2e88;
  --lime:     #c2ff1f;
  --cyan:     #1fe0ff;
  --yellow:   #ffd60a;
  --violet:   #a06bff;
  --orange:   #ff7a1a;

  /* Structure */
  --bd:        3px;      /* border weight */
  --shadow:    8px;      /* hard offset distance */
  --c:         var(--pink);  /* per-element accent, overridden inline */

  /* Type */
  --font-display: 'Unbounded', system-ui, sans-serif;
  --font-mono:    'Space Mono', ui-monospace, 'Courier New', monospace;
}

/* --- Light, safe global reset (harmless on existing pages) --- */
*, *::before, *::after { box-sizing: border-box; }

:focus-visible {
  outline: var(--bd) solid var(--yellow);
  outline-offset: 3px;
}

/* --- Themed base — only applies where the layout stamps body.theme ---
   Resets, not just additions: radar.css sets a bare `body { display:flex;
   overflow:hidden }` globally, which would otherwise flex-row our layout and
   clip page scroll. body.theme (0,1,1) overrides body (0,0,1) and loads later. */
body.theme {
  display: block;
  overflow-x: clip;        /* guard against any wide child */
  overflow-y: visible;     /* MUST reset: radar.css `body{overflow:hidden}` sets BOTH axes */
  margin: 0;
  min-height: 100vh;
  background-color: var(--bg);   /* the warp-grid canvas (welcome) draws the grid on top */
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* :where() keeps this reset at specificity (0,0,1) so component classes
   like .brand and .btn (0,1,0) can still set their own text color. */
:where(body.theme) a { color: inherit; text-decoration: none; }

/* ============================================================================
   Utility components
   ========================================================================== */

/* Hard-shadowed block */
.nb-card {
  background: var(--bg-2);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--shadow) var(--shadow) 0 var(--c);
}

/* Tactile press: hover lifts toward the shadow, active flattens it.
   The shadow "absorbs" the element — the signature neobrutalist click. */
.nb-press {
  transition: transform 0.09s ease, box-shadow 0.09s ease, background 0.12s ease, color 0.12s ease;
}
.nb-press:hover {
  transform: translate(3px, 3px);
  box-shadow: calc(var(--shadow) - 3px) calc(var(--shadow) - 3px) 0 var(--c);
}
.nb-press:active {
  transform: translate(var(--shadow), var(--shadow));
  box-shadow: 0 0 0 var(--c);
}

/* Staggered entrance */
@keyframes nb-pop {
  from { opacity: 0; transform: translateY(20px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
.nb-in {
  opacity: 0;
  animation: nb-pop 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.4) forwards;
}

/* Infinite ticker. Track is duplicated in markup; translating -50% loops seamlessly. */
.nb-marquee {
  overflow: hidden;
  border-block: var(--bd) solid var(--ink);
  background: var(--lime);
}
.nb-marquee__track {
  display: inline-flex;
  white-space: nowrap;
  will-change: transform;
  animation: nb-scroll 26s linear infinite;
}
.nb-marquee:hover .nb-marquee__track { animation-play-state: paused; }
@keyframes nb-scroll { to { transform: translateX(-50%); } }

/* Rotating circular sticker */
@keyframes nb-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .nb-in { opacity: 1; }
}
