/* Animated Blaze hero graph — self-contained (own vars) so it inlines on the landing.
   Reveal is JS-gated via html.js; no-JS shows the final state. */
.lens{
  --l-bg:#0a0b10; --l-panel:#141926; --l-line:#252c3b; --l-ink:#dfe5f0; --l-mut:#8b93a6;
  --c-identity:#63b3ff; --c-compute:#f5b544; --c-storage:#5ee0a0; --c-secret:#b98aff;
  --c-messaging:#3ad0d6; --c-admin:#ff6a7a; --c-hot:#ff4d4d;
  position:relative; margin:0; border-radius:16px; overflow:hidden;
  background:
    radial-gradient(90% 120% at 78% 42%, rgba(244,237,45,.10), transparent 60%),
    radial-gradient(70% 90% at 12% 8%, rgba(247,201,72,.06), transparent 55%),
    linear-gradient(180deg,#0c0e15,#090a0f);
  border:1px solid #1c2231;
  box-shadow:0 30px 80px -40px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.03);
}
.lens-svg{ display:block; width:100%; height:auto; }
.lens-bg{ opacity:.5; }
.bloom,.bloom-hot{ opacity:0; transition:opacity 1s ease; }
.lens.built .bloom{ opacity:1; } .lens.escalating .bloom-hot{ opacity:1; }

/* edges (curved) */
.gedge .eline{ stroke:#374155; stroke-width:1.8; fill:none; }
.gedge.derived .eline{ stroke-dasharray:5 6; stroke:#7a7326; }
.gedge.onpath .eline{ stroke:#4a5670; }
.gedge .elabel{ fill:var(--l-mut); font:600 11px/1 'JetBrains Mono',ui-monospace,monospace;
  letter-spacing:-.02em; paint-order:stroke; stroke:#0a0b10; stroke-width:3.5px; }

/* nodes */
.gnode .nbox{ fill:var(--l-panel); stroke:#39435a; stroke-width:1.6;
  filter:drop-shadow(0 6px 14px rgba(0,0,0,.5)); }
.gnode .nlabel{ fill:var(--l-ink); font:600 13px/1 'JetBrains Mono',ui-monospace,monospace; letter-spacing:-.02em; }
.gnode .npip{ fill:#5a6472; }
.gnode .halo{ fill:none; stroke:none; }
.gnode .ncrown{ fill:var(--c-admin); font-size:15px; text-anchor:middle; opacity:0; }
.cls-identity  .nbox{ stroke:var(--c-identity) }  .cls-identity  .npip{ fill:var(--c-identity) }
.cls-compute   .nbox{ stroke:var(--c-compute) }   .cls-compute   .npip{ fill:var(--c-compute) }
.cls-storage   .nbox{ stroke:var(--c-storage) }   .cls-storage   .npip{ fill:var(--c-storage) }
.cls-secret    .nbox{ stroke:var(--c-secret) }    .cls-secret    .npip{ fill:var(--c-secret) }
.cls-messaging .nbox{ stroke:var(--c-messaging) } .cls-messaging .npip{ fill:var(--c-messaging) }
.cls-admin     .nbox{ stroke:var(--c-admin) }     .cls-admin     .npip{ fill:var(--c-admin) }
.gnode.is-foothold .nbox{ stroke:#f4ed2d; stroke-width:2.3;
  filter:drop-shadow(0 0 10px rgba(244,237,45,.55)); }

/* ---- JS-gated reveal (no JS => final state visible) ---- */
.js .gnode{ opacity:0; transition:opacity .5s ease; }
.js .gnode.in{ opacity:1; }
.js .eline{ stroke-dasharray:900; stroke-dashoffset:900; }
.js .gedge.in .eline{ stroke-dashoffset:0; transition:stroke-dashoffset .7s ease; }
.js .gedge .elabel{ opacity:0; }
.js .gedge.in .elabel{ opacity:1; transition:opacity .45s ease .2s; }
.js .gedge.derived{ opacity:0; transition:opacity .5s ease; }
.js .gedge.derived.in{ opacity:1; }

/* ---- escalation ---- */
.lens.escalating .gedge:not(.hot){ opacity:.12; transition:opacity .55s; }
.lens.escalating .gnode:not(.hot):not(.is-foothold) .nbox{ opacity:.24; transition:opacity .55s; }
.lens.escalating .gnode:not(.hot):not(.is-foothold) .nlabel,
.lens.escalating .gnode:not(.hot):not(.is-foothold) .npip{ opacity:.3; }

.gedge.hot .eline{ stroke:var(--c-hot); stroke-width:3.4; stroke-dasharray:11 8;
  animation:lensflow .55s linear infinite; filter:drop-shadow(0 0 7px rgba(255,77,77,.75)); }
.gedge.hot .elabel{ fill:#ffb4ac; opacity:1; }
.gnode.hot .nbox{ stroke:var(--c-hot); stroke-width:2.6; fill:#22131a;
  filter:drop-shadow(0 0 14px rgba(255,77,77,.6)); }
.gnode.hot .nlabel{ fill:#ffe0dc; }
.gnode.hot .halo{ stroke:var(--c-hot); stroke-width:1.4; animation:lenspulse 1.5s ease-out infinite; }
.gnode.is-apex.hot .nbox{ stroke-width:3.2; filter:drop-shadow(0 0 20px rgba(255,77,77,.8)); }
.gnode.is-apex.hot .ncrown{ opacity:1; animation:lenspulse 1.5s ease-out infinite; }
.gnode.is-foothold.in .halo{ stroke:#f4ed2d; stroke-width:1.3; animation:lenspulse 2.2s ease-out infinite; }
.gnode .halo{ transform-box:fill-box; transform-origin:center; }

/* flowing particles along the hot path (spawned by JS) */
.lens-particle{ fill:#ffd9a1; filter:drop-shadow(0 0 5px rgba(255,120,80,.9)); }

@keyframes lensflow{ to{ stroke-dashoffset:-38; } }
@keyframes lenspulse{ 0%{ transform:scale(.9); opacity:.85; } 75%{ transform:scale(1.14); opacity:0; } 100%{ opacity:0; } }

/* legend */
.lens-legend{ position:absolute; right:14px; top:14px; display:flex; gap:7px; flex-wrap:wrap; max-width:60%; justify-content:flex-end; }
.lens-legend .lg{ font:600 10.5px/1 'JetBrains Mono',ui-monospace,monospace; color:var(--l-mut);
  border:1px solid #232a39; border-radius:20px; padding:4px 9px; background:rgba(10,12,18,.55); backdrop-filter:blur(4px); }
.lens-legend .cls-identity{ color:var(--c-identity) } .lens-legend .cls-compute{ color:var(--c-compute) }
.lens-legend .cls-storage{ color:var(--c-storage) } .lens-legend .cls-secret{ color:var(--c-secret) }
.lens-legend .cls-admin{ color:var(--c-admin) }
@media (max-width:640px){ .lens-legend{ display:none; } }

@media (prefers-reduced-motion: reduce){
  .js .gnode{ opacity:1; } .js .eline{ stroke-dashoffset:0; } .js .gedge .elabel{ opacity:1; }
  .js .gedge.derived{ opacity:1; } .bloom{ opacity:1; }
  .gedge.hot .eline{ animation:none; }
  .gnode.hot .halo,.gnode.is-foothold.in .halo,.gnode.is-apex.hot .ncrown{ animation:none; opacity:.9; }
}
