/* ---------------------------------------------------------
   HCH INTELLIGENCE — visual system
   No typography by design: the interface communicates
   exclusively through light, motion and sound.
   --------------------------------------------------------- */

:root {
  --red: #e30613;
  --red-hot: #ff2f3d;
  --navy: #141d4f;
  --cream: #f2efe4;
  --ink: #04060d;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #04060d;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

body { cursor: default; }

#stage {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: radial-gradient(62% 58% at 50% 47%, #0a0f21 0%, #060a16 46%, #03050c 100%);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

#stage.running { cursor: none; }

/* ---------- background ---------- */
#bg { position: absolute; inset: 0; width: 100%; height: 100%; }

#grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  background-size: 160px 160px;
}

#vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 46%, rgba(227, 6, 19, 0.07) 0%, rgba(227, 6, 19, 0) 48%),
    radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0) 34%, rgba(0, 0, 0, 0.55) 76%, rgba(0, 0, 0, 0.92) 100%);
}

/* ---------- viewfinder frame ---------- */
#frame {
  position: absolute;
  inset: 2.6vmin;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.6s ease 0.4s;
}

#stage.booted #frame { opacity: 0.5; }

#frame i {
  position: absolute;
  width: 2.4vmin;
  height: 2.4vmin;
  border: 0 solid rgba(170, 190, 245, 0.55);
}

#frame i:nth-child(1) { left: 0; top: 0; border-left-width: 1px; border-top-width: 1px; }
#frame i:nth-child(2) { right: 0; top: 0; border-right-width: 1px; border-top-width: 1px; }
#frame i:nth-child(3) { left: 0; bottom: 0; border-left-width: 1px; border-bottom-width: 1px; }
#frame i:nth-child(4) { right: 0; bottom: 0; border-right-width: 1px; border-bottom-width: 1px; }

/* ---------- HUD ---------- */
#hud {
  position: absolute;
  width: 100vmin;
  height: 100vmin;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  overflow: visible;
  opacity: 0.0;
  transition: opacity 2.2s ease;
  pointer-events: none;
}

#hud.on { opacity: 0.32; }
#stage.booted #hud.on { opacity: 1; }

#hud .rot-a { animation: spin 90s linear infinite; transform-origin: 500px 500px; }
#hud .rot-b { animation: spin 64s linear infinite reverse; transform-origin: 500px 500px; }
#hud .rot-c { animation: spin 150s linear infinite; transform-origin: 500px 500px; }

#hud .rot-d { animation: spin 36s linear infinite reverse; transform-origin: 500px 500px; }
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ---------- core ---------- */
#core {
  position: relative;
  perspective: 1600px;
  height: 49vmin;
  aspect-ratio: 1400 / 2251;
  z-index: 3;
  will-change: transform;
  pointer-events: none;
}

#core img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

#halo {
  position: absolute;
  left: 50%;
  top: 52%;
  width: 96vmin;
  height: 96vmin;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle,
      rgba(255, 232, 222, 0.07) 0%,
      rgba(227, 6, 19, 0.16) 24%,
      rgba(227, 6, 19, 0.06) 44%,
      rgba(227, 6, 19, 0) 66%);
  opacity: 0.45;
  filter: blur(2px);
  pointer-events: none;
}

#crestBloom {
  z-index: 1;
  opacity: 0;
  filter: blur(0.9vmin) saturate(1.2);
  mix-blend-mode: screen;
  transform: scale(1.06);
  transition: opacity 2.6s ease;
}

#stage.booted #crestBloom { opacity: 0.52; }

#crest {
  z-index: 2;
  opacity: 0.55;
  filter: saturate(0.85) brightness(0.78) contrast(1.04)
          drop-shadow(0 0 1.2vmin rgba(227, 6, 19, 0.30))
          drop-shadow(0 0 3.2vmin rgba(227, 6, 19, 0.16));
  transition: opacity 1.4s ease, filter 1.8s ease;
  animation: breathe 7s ease-in-out infinite;
}

#stage.booted #crest,
#stage.speaking #crest,
#stage.listening #crest,
#stage.thinking #crest {
  opacity: 0.96;
  filter: saturate(0.97) brightness(0.94) contrast(1.03)
          drop-shadow(0 0 1.4vmin rgba(255, 60, 72, 0.34))
          drop-shadow(0 0 4.2vmin rgba(227, 6, 19, 0.20));
}

@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.008); }
}

/* fine horizontal lines, clipped to the crest — the "projection" texture */
#scanlines {
  position: absolute;
  inset: 0;
  z-index: 3;
  background-image: repeating-linear-gradient(0deg,
      rgba(255, 255, 255, 0.13) 0px,
      rgba(255, 255, 255, 0.13) 1px,
      rgba(255, 255, 255, 0) 1px,
      rgba(255, 255, 255, 0) 3px);
  -webkit-mask-image: url("assets/crest.png");
  -webkit-mask-size: contain;
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-image: url("assets/crest.png");
  mask-size: contain;
  mask-position: center;
  mask-repeat: no-repeat;
  mix-blend-mode: overlay;
  opacity: 0;
  transition: opacity 1.2s ease;
}

#stage.booted #scanlines { opacity: 0.55; }

/* thin light edge around the whole mark */
#crestRim {
  z-index: 4;
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 1.6s ease;
  filter: drop-shadow(0 0 4px rgba(255, 110, 100, 0.55));
}

#stage.booted #crestRim { opacity: 0.30; }
#stage.speaking #crestRim { opacity: 0.45; }

#crestEdge {
  z-index: 5;
  opacity: 0;
  mix-blend-mode: screen;
  filter: drop-shadow(0 0 6px rgba(200, 220, 255, 0.6));
  transition: opacity 0.55s ease;
}

#stage.booting #crestEdge { opacity: 1; }
#stage.booting #crest { opacity: 0; }

#stage.booting #core { animation: bootscale 2.4s cubic-bezier(0.2, 0.7, 0.2, 1); }

@keyframes bootscale {
  0%   { transform: scale(0.90); }
  64%  { transform: scale(1.012); }
  100% { transform: scale(1); }
}

#stage.booted #crest {
  animation: ignite 1.15s cubic-bezier(0.2, 0.75, 0.2, 1) both,
             breathe 7s ease-in-out 1.15s infinite;
}

@keyframes ignite {
  0%   { opacity: 0; transform: scale(0.955); }
  45%  { opacity: 1; transform: scale(1.018); }
  100% { opacity: 0.96; transform: scale(1); }
}

#flash {
  position: absolute;
  inset: 0;
  z-index: 7;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at 50% 48%,
      rgba(255, 255, 255, 0.9) 0%,
      rgba(255, 150, 150, 0.35) 22%,
      rgba(227, 6, 19, 0) 55%);
  mix-blend-mode: screen;
}

#stage.booted #flash { animation: flash 1.2s ease-out; }

@keyframes flash {
  0%   { opacity: 0.85; }
  100% { opacity: 0; }
}

#sheen {
  position: absolute;
  inset: 0;
  z-index: 6;
  background-image: linear-gradient(180deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, 0.45) 46%,
      rgba(255, 255, 255, 0.85) 50%,
      rgba(255, 255, 255, 0.45) 54%,
      rgba(255, 255, 255, 0) 100%);
  background-size: 100% 24%;
  background-repeat: no-repeat;
  background-position: 0 -40%;
  -webkit-mask-image: url("assets/crest.png");
  -webkit-mask-size: contain;
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-image: url("assets/crest.png");
  mask-size: contain;
  mask-position: center;
  mask-repeat: no-repeat;
  mix-blend-mode: screen;
  opacity: 0;
  animation: scanline 10s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  pointer-events: none;
}

#stage.booted #sheen,
#stage.speaking #sheen,
#stage.listening #sheen { opacity: 0.18; }

@keyframes scanline {
  0%   { background-position: 0 -30%; }
  60%  { background-position: 0 130%; }
  100% { background-position: 0 130%; }
}

/* ---------- agent nodes ---------- */
#nodes {
  position: absolute;
  width: 100vmin;
  height: 100vmin;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.4s ease 0.5s;
}

#stage.booted #nodes { opacity: 1; }

.node {
  position: absolute;
  width: 8.2vmin;
  height: 8.2vmin;
  margin: -4.1vmin 0 0 -4.1vmin;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: rgba(226, 236, 255, 0.95);
  background:
    radial-gradient(circle at 50% 50%, rgba(14, 21, 46, 0.96) 0%, rgba(7, 11, 26, 0.72) 72%, rgba(8, 12, 28, 0) 100%);
  border: 1px solid rgba(185, 205, 255, 0.42);
  box-shadow: 0 0 3vmin rgba(90, 120, 220, 0.12);
  transition:
    transform 0.55s cubic-bezier(0.2, 0.9, 0.25, 1),
    color 0.5s ease,
    border-color 0.5s ease,
    box-shadow 0.6s ease,
    opacity 0.6s ease;
  opacity: 0.85;
  will-change: transform;
}

.node svg {
  width: 46%;
  height: 46%;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.55;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

.node.active {
  opacity: 1;
  color: #fff2ef;
  border-color: rgba(255, 96, 106, 0.85);
  transform: scale(1.22);
  box-shadow:
    0 0 2.4vmin rgba(227, 6, 19, 0.55),
    inset 0 0 2vmin rgba(227, 6, 19, 0.30);
}

.node.done { opacity: 0.34; }
.node.done.active { opacity: 1; }

/* ---------- spectrum ---------- */
#spectrum {
  position: absolute;
  left: 50%;
  bottom: 5.2vmin;
  transform: translateX(-50%);
  width: 46vmin;
  height: 7vmin;
  z-index: 5;
  opacity: 0;
  transition: opacity 1.2s ease;
  pointer-events: none;
}

#stage.booted #spectrum { opacity: 0.9; }

/* ---------- tap affordance ---------- */
#tap {
  position: absolute;
  width: 70vmin;
  height: 70vmin;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  pointer-events: none;
  transition: opacity 0.8s ease;
}

#stage.running #tap { opacity: 0; }

#tap .pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(227, 6, 19, 0.42);
  animation: pulseout 3.6s cubic-bezier(0.22, 0.6, 0.3, 1) infinite;
  opacity: 0;
}

#tap .pulse.d2 { animation-delay: 1.2s; }
#tap .pulse.d3 { animation-delay: 2.4s; }

@keyframes pulseout {
  0%   { transform: scale(0.58); opacity: 0; }
  16%  { opacity: 0.55; }
  100% { transform: scale(1.02); opacity: 0; }
}

/* ---------- mic badge ---------- */
#mic {
  position: absolute;
  left: 3.4vmin;
  bottom: 3.4vmin;
  width: 3vmin;
  height: 3vmin;
  z-index: 6;
  color: rgba(190, 205, 255, 0.45);
  transition: opacity 0.6s ease, color 0.6s ease;
}

#mic svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 1.6; }

#mic.live { color: rgba(255, 96, 106, 0.9); animation: micpulse 2.6s ease-in-out infinite; }
#mic.idle { color: rgba(170, 190, 240, 0.40); }
#mic.paused { color: rgba(255, 170, 90, 0.75); }
#mic.off  { color: rgba(150, 160, 190, 0.5); }

@keyframes micpulse {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 1; }
}

/* ---------- reactive states ---------- */
#stage.thinking #halo { opacity: 0.95; }
#stage.thinking #crest { filter: saturate(1) brightness(1.03) contrast(1.02)
          drop-shadow(0 0 1.6vmin rgba(255, 60, 72, 0.4))
          drop-shadow(0 0 5vmin rgba(227, 6, 19, 0.24)); }

#stage.listening #halo { animation: listenhalo 5.6s ease-in-out infinite; }

@keyframes listenhalo {
  0%, 100% { opacity: 0.34; }
  50%      { opacity: 0.62; }
}
#stage.speaking #hud { filter: brightness(1.1); }

.hidden { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  #tap .pulse, #sheen, #crest { animation: none; }
}


/* legal links: only on the idle screen, gone the moment the show starts */
#startbar {
  position: fixed;
  left: 0; right: 0;
  bottom: max(14px, env(safe-area-inset-bottom));
  display: flex;
  justify-content: center;
  gap: 10px;
  font: 400 10px/1 ui-sans-serif, system-ui, -apple-system, sans-serif;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(242, 239, 228, .26);
  z-index: 30;
  transition: opacity .6s ease;
}
#startbar a { color: inherit; text-decoration: none; }
#startbar a:hover { color: rgba(242, 239, 228, .6); }
#stage.booted ~ #startbar { opacity: 0; pointer-events: none; }
