/* =========================================================================
   resonating loop — v0
   -------------------------------------------------------------------------
   A single dark "plate": an instrument face on a desert night. Warm amber
   line-work (the radiating compass) on cold blue-black, with a cool
   iridescent accent borrowed from the haloed figure in the banner.

   HOW TO TWEAK THIS PAGE (your reps live here):
   Everything visual is a token in :root below. Change a token once and the
   whole page re-tunes. The rest of the file just *spends* these tokens.
   Each token block says what it's for and what happens if you push it.
   ========================================================================= */

:root {

  /* --- COLOR ----------------------------------------------------------
     Warm light on cold dark. The page is mostly --ground; --ember is the
     glowing instrument; --iris is the rare cool spark. Restraint is the
     point — two accents, used sparingly, beat a rainbow. */
  --ground:        #07090f;   /* deep blue-black — the desert night    */
  --ground-warm:   #140d0a;   /* faint ember warmth pooled at center   */
  --ember:         #e08a3c;   /* the amber line-work / compass glow     */
  --ember-bright:  #ffb066;   /* hotter amber for the live core/hover   */
  --ember-dim:     #7a5230;   /* recessed amber — quiet rings, ticks    */
  --iris:          #8fb4ff;   /* cool iridescent accent (the halo)      */
  --iris-2:        #b69cff;   /* violet end of the same spark           */
  --bone:          #ece3d4;   /* warm off-white text — desert bone      */
  --bone-dim:      #8d8576;   /* muted bone for labels/secondary        */
  --inscription-fill: #5f574c;/* cut-face of the carved creed — WARM stone, lean-in dim
                                 (was cool #3b3a3e: read dead on a warm plate. warm > cool here) */

  /* --- GLOW ------------------------------------------------------------
     The page lives or dies on bloom. These drive text-shadow / drop-shadow.
     Kill them and it goes flat and corporate; over-do them and it smears. */
  --glow-ember:  0 0 18px rgba(224, 138, 60, 0.45);
  --glow-iris:   0 0 22px rgba(143, 180, 255, 0.40);
  --glow-soft:   0 0 40px rgba(224, 138, 60, 0.12);

  /* --- TYPE ------------------------------------------------------------
     Serif for the names (oracular), mono for the machine readout. */
  --font-display: "Cormorant Garamond", Georgia, serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, monospace;

  /* Fluid type via clamp(min, preferred, max). The name scales hardest.
     Want more drama on big screens? Raise the middle vw number. */
  --size-name:      clamp(3.2rem, 11vw, 8.5rem);
  --size-bio:       clamp(1.05rem, 3vw, 1.5rem);
  --size-bio-small: clamp(.8rem, 2vw, 1.14rem);
  --size-label:     clamp(0.7rem, 1.4vw, 0.82rem);

  /* Tracking. Mono labels get generous letter-spacing — instrument panels
     space their text out. The display name gets a touch of negative. */
  --track-label:  0.42em;
  --track-name:  -0.01em;

  /* --- SPACE -----------------------------------------------------------
     One rhythm, scaled. Change --space-unit to retune the whole vertical
     cadence at once (this is the single most fun knob to turn). */
  --space-unit: clamp(0.9rem, 2.2vw, 1.4rem);
  --space-sm:  calc(var(--space-unit) * 0.6);
  --space-md:  var(--space-unit);
  --space-lg:  calc(var(--space-unit) * 2);
  --space-xl:  calc(var(--space-unit) * 3.2);
}

/* --- RESET (minimal, just the sharp edges) ----------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--bone);
  font-family: var(--font-display);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* =========================================================================
   THE PLATE — full-viewport stage with layered atmosphere
   ========================================================================= */
.plate {
  position: relative;
  isolation: isolate;            /* keep the grain/glow stacking local */
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--space-xl) var(--space-lg);
  overflow: hidden;

  /* Atmosphere, not a flat fill: a warm ember pool low-and-center fading
     into cold blue-black at the edges — the lit horizon of the banner.
     Two radial gradients layered: warm glow + a vignette to pull the eyes in. */
  background:
    radial-gradient(120% 90% at 50% 62%,
        var(--ground-warm) 0%,
        rgba(20, 13, 10, 0.35) 22%,
        transparent 55%),
    radial-gradient(140% 120% at 50% 40%,
        #0b0e16 0%,
        var(--ground) 60%,
        #04050a 100%);
}

/* Film grain over everything — texture so the dark never reads as dead
   space. Inline SVG turbulence; ::after so it sits above the gradient.
   Lower the opacity for cleaner, raise it for a dustier plate. */
.plate::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* =========================================================================
   CORNER REGISTRATION TICKS — the cartographic bezel
   Small L-marks framing the plate like a map's reticle. Pure decoration.
   ========================================================================= */
.tick {
  position: absolute;
  width: 22px; height: 22px;
  z-index: 4;
  border: 1px solid var(--ember-dim);
  opacity: 0.55;
}
.tick--tl { top: var(--space-lg);    left: var(--space-lg);  border-right: 0; border-bottom: 0; }
.tick--tr { top: var(--space-lg);    right: var(--space-lg); border-left: 0;  border-bottom: 0; }
.tick--bl { bottom: var(--space-lg); left: var(--space-lg);  border-right: 0; border-top: 0; }
.tick--br { bottom: var(--space-lg); right: var(--space-lg); border-left: 0;  border-top: 0; }

/* =========================================================================
   IDENTITY — the centerpiece
   ========================================================================= */
.identity {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* This gap separates the two PAIRS — [name+callsign] and [tagline+creed] —
     and the creed from the channels. Each pair is tighter internally (see
     .identity__text gap and .bio__secondline margin) so they read as units,
     not as evenly-spaced loose lines. Turn this to set the breathing room
     BETWEEN groups; turn the pair-internal gaps to set tightness WITHIN. */
  gap: var(--space-md);
}

/* --- the resonance rings (static in slice 1) --------------------------- */
.rings {
  position: absolute;
  z-index: -1;                    /* sit behind the name */
  top: 50%; left: 50%;
  transform: translate(-50%, -58%);
  width: min(118vw, 720px);
  height: min(118vw, 720px);
  pointer-events: none;
  filter: drop-shadow(var(--glow-soft));
}
.rings circle, .rings line {
  fill: none;
  stroke: var(--ember-dim);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.rings__group circle { opacity: 0.5; }
.rings__spokes line  { stroke: var(--ember-dim); opacity: 0.28; }
.rings__core {
  fill: var(--ember-bright);
  stroke: none;
  filter: drop-shadow(var(--glow-ember));
}

/* --- the names -------------------------------------------------------- */
.identity__text { display: flex; flex-direction: column; align-items: center; gap: var(--space-sm); }

.name {
  margin: 0;
  font-weight: 300;               /* thin display weight = ethereal */
  font-size: var(--size-name);
  line-height: 0.92;
  letter-spacing: var(--track-name);
  color: var(--bone);
  text-shadow: var(--glow-ember);
}

.callsign {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ember);
  text-shadow: var(--glow-ember);
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding-left: var(--track-label);  /* optically re-center the tracked text */
}
.callsign__glyph { color: var(--ember-bright); }

/* --- the two-liner ---------------------------------------------------- */
.bio {
  margin: 0;
  max-width: 60ch;
  font-style: italic;
  font-weight: 400;
  line-height: 1.5;
  /* color: var(--bone-dim); */
}
/* placeholder styling — visibly provisional so it begs to be replaced */
.bio__firstline {
  display: block;
  color: var(--ember-dim);
  font-size: var(--size-bio);
}

/* the creed — lapidary INSCRIPTION, carved into the plate rather than lit.
   Roman inscriptional capitals (think Trajan): serif caps, wide tracking,
   interpuncts where prose would put commas. The illusion of incision is
   three cheap tricks stacked:
     · fill near the ground color so the glyph reads as the *cut face* in shade
     · a faint LIGHT line below each glyph = the lower bevel catching overhead light
     · a dark line above = the shadowed upper wall of the groove
   No glow: carving doesn't emit, it's found. Quiet on purpose — you lean in.
   Knobs: lift --inscription-fill toward --bone-dim for a more legible cut;
   raise the bevel-light alpha for a deeper-pressed look. */
.bio__secondline {
  display: block;
  margin-top: var(--space-sm);        /* tight under its tagline → the two read as one pair */
  font-family: var(--font-display);
  font-style: normal;                 /* inscriptions stand upright */
  font-weight: 500;
  font-size: var(--size-bio-small);
  text-transform: uppercase;
  letter-spacing: 0.34em;
  text-indent: 0.34em;                /* balance the trailing track → optically centered */
  color: var(--inscription-fill);
  text-shadow:
     0  1px 0   rgba(236, 227, 212, 0.18),  /* lit lower bevel (bone) */
     0 -1px 1px rgba(0, 0, 0, 0.55);        /* shadowed upper inner wall */
}

/* --- channels (links as instrument readouts) -------------------------- */
.channels {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-md) var(--space-lg);
  margin-top: var(--space-sm);
}
.channel {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-mono);
  font-size: var(--size-label);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--bone-dim);
  transition: color 0.35s ease, text-shadow 0.35s ease;
}
.channel__glyph {
  color: var(--ember-dim);
  font-size: 1.15em;
  transition: color 0.35s ease, text-shadow 0.35s ease;
}
/* hover: the channel "lights up" — cool iris on the label, hot amber glyph.
   the only place the iridescent accent touches an interaction. */
.channel:hover,
.channel:focus-visible {
  color: var(--iris);
  text-shadow: var(--glow-iris);
  outline: none;
}
.channel:hover .channel__glyph,
.channel:focus-visible .channel__glyph {
  color: var(--ember-bright);
  text-shadow: var(--glow-ember);
}

/* =========================================================================
   SLICE 2 — THE INSTRUMENT WAKES
   · Idle: a slow resonance brightens outward through the rings, on a loop —
     the loop, looping. Pure CSS keyframes, staggered per ring.
   · Cursor: vars (--drift-*, --engage, --spin) are eased every frame by
     main.js — the plate leans toward you, brightens as you near center, and
     the reticle tips to track. "faintly listening back."
   · Click: main.js spawns a .ripple that expands from the touch point.
   All suppressed under prefers-reduced-motion (JS opts out; keyframes killed
   by the media query below).
   ========================================================================= */

/* resonance period — lower = more urgent pulse. a tweak knob like the rest. */
:root { --breath: 5.5s; }

/* idle resonance: a brightening that sweeps inner → outer ring, forever */
@keyframes resonate {
  0%, 100% { stroke: var(--ember-dim); opacity: 0.32; }
  50%      { stroke: var(--ember);     opacity: 0.70; }
}
.rings__group circle {
  animation: resonate var(--breath) ease-in-out infinite;
}
/* outward stagger: inner ring leads, each outer ring lags → a travelling pulse */
.rings__group circle:nth-child(1) { animation-delay: 0s;   }
.rings__group circle:nth-child(2) { animation-delay: 0.3s; }
.rings__group circle:nth-child(3) { animation-delay: 0.6s; }
.rings__group circle:nth-child(4) { animation-delay: 0.9s; }
.rings__group circle:nth-child(5) { animation-delay: 1.2s; }

/* the hot point breathes in glow only — JS leaves its transform free */
@keyframes core-breath {
  0%, 100% { opacity: 0.75; }
  50%      { opacity: 1;    }
}
.rings__core { animation: core-breath var(--breath) ease-in-out infinite; }

/* cursor-driven state — main.js eases these. The svg only centers + brightens;
   the drift/spin live on the reticle LAYERS (live + ghosts) so each can lag. */
.rings {
  overflow: visible;                 /* let click-ripples + ghost trail extend past the box */
  transform: translate(-50%, -58%);
  filter: drop-shadow(var(--glow-soft))
          brightness(calc(1 + 0.3 * var(--engage, 0)));
}

/* each reticle layer is transformed by JS (translate toward pointer + tilt);
   rotation pivots on the layer's own centre (the hot point). */
.reticle {
  transform-box: fill-box;
  transform-origin: center;
}

/* PHOSPHOR PERSISTENCE — the ghost trail.
   main.js clones the live reticle into two layers that ease toward the pointer
   MORE SLOWLY and sit DIMMER, so movement leaves a fading afterimage. At rest
   they converge under the live reticle and vanish. Turn these opacities (and
   the per-layer EASE in main.js) to make the trail longer / brighter. */
.reticle--ghost { pointer-events: none; }
.reticle--g1 { opacity: 0.34; }
.reticle--g2 { opacity: 0.16; filter: blur(0.7px); }

/* spokes fade up as you engage — the reticle "powers on" toward the cursor */
.rings__spokes line { opacity: calc(0.16 + 0.40 * var(--engage, 0)); }

/* the click-answer ripple (created + scaled by main.js) */
.ripple {
  fill: none;
  stroke: var(--ember-bright);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

/* =========================================================================
   MOTION SAFETY — respect reduced-motion
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition-duration: 0.01ms !important; }
}
