:root {
  --bg: #001222;
  --text: #ffffff;
  --text-dim: rgba(255, 255, 255, 0.55);
  --text-fade: rgba(255, 255, 255, 0.4);
  --green: #00D16A;
  --line: #B2B6B9;
  --t-slow:   0.9s cubic-bezier(0.4, 0, 0.2, 1);
  --t-med:    0.6s cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast:   0.35s cubic-bezier(0.4, 0, 0.2, 1);
  /* The actual draw-animation duration (used by JS to time F2→F3) */
  --draw-ms: 2200ms;
}

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

html, body {
  background: var(--bg);
  color: var(--text);
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-feature-settings: 'ss01', 'cv11';
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  display: flex;
  flex-direction: column;
  background-image:
    radial-gradient(ellipse at center, rgba(0, 209, 106, 0.035) 0%, transparent 65%),
    var(--bg);
  position: relative;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  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' seed='3'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0.07 0 0 0 0 0.13 0 0 0 0.35 0'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
}

.stage-wrap, .controls {
  position: relative;
  z-index: 1;
}

/* ── Stage ── */
.stage-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 24px;
  min-height: 0;
}

.stage {
  position: relative;
  width: min(1080px, calc(100vh - 160px), calc(100vw - 64px));
  aspect-ratio: 1;
}

.canvas {
  width: 100%;
  height: 100%;
  display: block;
}

/* ── Grids ── */
.grid {
  transform-box: view-box;
  transform-origin: center;
  transition: opacity 1.4s cubic-bezier(0.4, 0, 0.2, 1),
              transform 1.6s cubic-bezier(0.5, 0, 0.3, 1);
}
.grid-dense  { opacity: 1; transform: scale(1); }
.grid-sparse { opacity: 0; transform: scale(0.5); }

/* ── Halos ── */
.halo {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0.6);
  transition: opacity var(--t-slow), transform var(--t-slow);
}

/* ── Endpoint dots ── */
.dot-origin, .dot-dest {
  fill: var(--green);
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0.3);
  transition: opacity var(--t-med), transform var(--t-med) cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ── Pulse rings ── */
.pulse-ring {
  fill: none;
  stroke: var(--green);
  stroke-width: 2;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes pulse-expand {
  0%   { transform: scale(0.8); opacity: 0.7; stroke-width: 2; }
  100% { transform: scale(4.5); opacity: 0;   stroke-width: 0.4; }
}

@keyframes dot-breathe {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.18); opacity: 0.92; }
}

/* ── Travel pulse (comet flying along the path during F3) ── */
.travel-pulse {
  fill: var(--green);
  opacity: 0;
  filter: drop-shadow(0 0 14px rgba(0, 209, 106, 0.9)) drop-shadow(0 0 28px rgba(0, 209, 106, 0.5));
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes travel-pulse-fly {
  0%   { transform: translate(0, 0)     scale(0.4); opacity: 0; }
  8%   { transform: translate(40px, 0)  scale(1.1); opacity: 1; }
  92%  { transform: translate(680px, 0) scale(1.1); opacity: 1; }
  100% { transform: translate(720px, 0) scale(0.4); opacity: 0; }
}

/* ── Paths ── */
.path-bg, .path-fg, .path-candidate {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.path-candidate {
  stroke: rgba(255, 255, 255, 0.65);
  stroke-width: 1;
  opacity: 0;
  transition: opacity var(--t-slow);
}
.path-bg {
  stroke: rgba(255, 255, 255, 0.22);
  stroke-width: 1;
  opacity: 0;
  transition: opacity var(--t-slow);
}
.path-fg {
  stroke: url(#green-trail);
  stroke-width: 2;
  /* Total path length = 720 (180 → 900 horizontal). Use a slight pad. */
  stroke-dasharray: 740;
  stroke-dashoffset: 740;
  opacity: 0;
  transition:
    stroke-dashoffset var(--draw-ms) cubic-bezier(0.25, 0.46, 0.45, 0.94),
    opacity var(--t-med),
    stroke-width var(--t-med);
}

/* ── Chip ── */
.chip {
  position: absolute;
  background: rgba(0, 18, 34, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  padding: 14px 20px;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 18px;
  letter-spacing: 0.06em;
  color: var(--text);
  font-weight: 500;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.chip-transaction {
  top: 2.2%;
  left: 2.2%;
}

.chip-icon {
  width: 16px;
  height: 16px;
  background: var(--green);
  display: inline-block;
}

/* ── Tooltip ── */
.tooltip {
  position: absolute;
  /* Centered slightly left of destination */
  left: 60%;
  top: 41%;
  background: var(--bg);
  border: 1px solid rgba(0, 209, 106, 0.55);
  padding: 12px 16px 13px;
  letter-spacing: 0.05em;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 8px);
  transition: opacity var(--t-slow), transform var(--t-slow);
  white-space: nowrap;
}

.tip-title {
  color: var(--text);
  font-size: 13px;
  letter-spacing: 0.08em;
  margin-bottom: 5px;
  font-weight: 500;
}

.tip-sub {
  color: var(--text-dim);
  font-size: 12px;
}

/* ── Frame label (bottom-right) ── */
.frame-label {
  position: absolute;
  bottom: 2.2%;
  right: 2.2%;
  font-size: 13px;
  letter-spacing: 0.04em;
  display: flex;
  gap: 12px;
  font-feature-settings: 'tnum';
}

.frame-num { color: var(--text-fade); }
.frame-body { color: rgba(255, 255, 255, 0.85); }

/* ── Frame states ── */

/* F1 — Network at rest: dense grid (zoomed-out view) + chip only */
.stage[data-frame="1"] .grid-dense  { opacity: 1; transform: scale(1)   translate(0,0); }
.stage[data-frame="1"] .grid-sparse { opacity: 0; transform: scale(0.5) translate(0,0); }
.stage[data-frame="1"] .halo,
.stage[data-frame="1"] .dot-origin,
.stage[data-frame="1"] .dot-dest,
.stage[data-frame="1"] .path-bg,
.stage[data-frame="1"] .path-fg,
.stage[data-frame="1"] .path-candidate,
.stage[data-frame="1"] .pulse-ring,
.stage[data-frame="1"] .travel-pulse,
.stage[data-frame="1"] .tooltip {
  opacity: 0;
}

/* F2 — Zoom-in complete: dense grid scales OUT (invisible), sparse grid scales IN to 1 */
.stage[data-frame="2"] .grid-dense  { opacity: 0; transform: scale(2.6) translate(0,0); }
.stage[data-frame="2"] .grid-sparse { opacity: 1; transform: scale(1)   translate(0,0); }
.stage[data-frame="2"] .halo-origin {
  opacity: 1;
  transform: scale(1);
}
.stage[data-frame="2"] .dot-origin {
  opacity: 1;
  transform: scale(1);
  animation: dot-breathe 2s ease-in-out infinite;
}
.stage[data-frame="2"] .pulse-origin {
  animation: pulse-expand 2.2s ease-out infinite;
}
.stage[data-frame="2"] .path-candidate {
  opacity: 0.14;
}

/* F3 — Evaluating route: optimal path draws + grid parallaxes left + travel pulse flies */
.stage[data-frame="3"] .grid-dense  { opacity: 0; transform: scale(2.6) translate(0,0); }
.stage[data-frame="3"] .grid-sparse { opacity: 1; transform: scale(1)   translate(-48px, -12px); }
.stage[data-frame="3"] .travel-pulse {
  animation: travel-pulse-fly var(--draw-ms) cubic-bezier(0.4, 0.05, 0.4, 1);
}
.stage[data-frame="3"] .halo-origin {
  opacity: 1;
  transform: scale(1);
}
.stage[data-frame="3"] .dot-origin {
  opacity: 1;
  transform: scale(1);
  animation: dot-breathe 2s ease-in-out infinite;
}
.stage[data-frame="3"] .pulse-origin {
  animation: pulse-expand 2.2s ease-out infinite;
}
.stage[data-frame="3"] .path-candidate {
  opacity: 0.18;
}
.stage[data-frame="3"] .path-fg {
  opacity: 1;
  stroke-dashoffset: 0;
  stroke-width: 2;
}
.stage[data-frame="3"] .path-bg {
  opacity: 1;
}

/* F4 — Route traced: halo gone, optimal path faint, candidates still visible */
.stage[data-frame="4"] .grid-dense  { opacity: 0; transform: scale(2.6) translate(0,0); }
.stage[data-frame="4"] .grid-sparse { opacity: 1; transform: scale(1)   translate(-48px, -12px); }
.stage[data-frame="4"] .halo-origin {
  opacity: 0;
  transform: scale(0.6);
}
.stage[data-frame="4"] .dot-origin {
  opacity: 0.5;
}
.stage[data-frame="4"] .path-candidate {
  opacity: 0.12;
}
.stage[data-frame="4"] .path-bg {
  opacity: 1;
}
.stage[data-frame="4"] .path-fg {
  opacity: 0;
  stroke-dashoffset: 0;
  stroke-width: 1;
}

/* F5 — Optimal locked: green path + dest halo + pulse + tooltip */
.stage[data-frame="5"] .grid-dense  { opacity: 0; transform: scale(2.6) translate(0,0); }
.stage[data-frame="5"] .grid-sparse { opacity: 1; transform: scale(1)   translate(-48px, -12px); }
.stage[data-frame="5"] .halo-dest {
  opacity: 1;
  transform: scale(1);
}
.stage[data-frame="5"] .dot-origin {
  opacity: 0.85;
  transform: scale(1);
}
.stage[data-frame="5"] .dot-dest {
  opacity: 1;
  transform: scale(1);
  animation: dot-breathe 2s ease-in-out infinite;
}
.stage[data-frame="5"] .pulse-dest {
  animation: pulse-expand 2.2s ease-out infinite;
}
.stage[data-frame="5"] .path-candidate {
  opacity: 0.1;
}
.stage[data-frame="5"] .path-bg {
  opacity: 0;
}
.stage[data-frame="5"] .path-fg {
  opacity: 1;
  stroke-dashoffset: 0;
  stroke-width: 2.5;
}
.stage[data-frame="5"] .tooltip {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ── Controls ── */
.controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 32px;
  padding: 16px 36px 28px;
}

#replay {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: var(--text);
  padding: 10px 18px;
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

#replay:hover {
  border-color: rgba(0, 209, 106, 0.6);
  color: var(--green);
}

#replay:active { transform: translateY(1px); }

.replay-glyph { display: inline-block; font-size: 14px; line-height: 1; }

.step-dots {
  display: flex;
  gap: 8px;
  align-items: center;
}

.step {
  background: rgba(255, 255, 255, 0.15);
  border: none;
  width: 28px;
  height: 2px;
  padding: 0;
  cursor: pointer;
  transition: background 0.3s;
}
.step:hover { background: rgba(255, 255, 255, 0.4); }
.step.active { background: var(--green); }

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.001s !important;
    animation-duration: 0.001s !important;
  }
  .path-fg { stroke-dasharray: none; }
}

/* ── Small screens ── */
@media (max-width: 720px) {
  .chip { font-size: 14px; padding: 10px 14px; gap: 10px; }
  .chip-icon { width: 12px; height: 12px; }
  .frame-label { font-size: 11px; }
  .tooltip { font-size: 11px; padding: 9px 12px; }
  .tip-title { font-size: 11px; }
  .tip-sub { font-size: 10px; }
  .controls { padding: 12px 16px 20px; gap: 20px; }
  #replay { padding: 8px 14px; font-size: 10px; }
}
