/* ==========================================================================
   exp28 . hero living map (.heromap)
   Everything the component needs beyond assets/site.css. Loaded after it.
   Contract: partials/heromap.html + assets/heromap.js
   ========================================================================== */

.heromap{margin-top:clamp(2.2rem,4.5vw,3.4rem);}
.heromap .stage{overflow:hidden;}
.heromap .hm-svg{display:block;width:100%;height:auto;overflow:visible;}
.heromap .hm-m{display:none;max-width:440px;margin:0 auto;}

/* ---------- type inside the stage (1180-wide viewBox renders 1:1 at 1180) ---------- */
.heromap .stage text{font-family:var(--mono);font-size:11px;fill:var(--ink);}
.heromap .stage .lbl{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;fill:rgba(var(--ink-rgb),.56);font-weight:500;}
.heromap .stage .ttl{font-family:var(--sans);font-size:15.2px;font-weight:600;letter-spacing:-.015em;fill:var(--ink);}
.heromap .stage .tsig{fill:var(--signal);}
.heromap .stage .tgrn{fill:var(--pass);}
.heromap .stage .tred{fill:var(--fail);}
.heromap .stage .hm-el{font-size:10.5px;letter-spacing:.02em;text-transform:none;font-weight:400;fill:rgba(var(--ink-rgb),.5);paint-order:stroke;stroke:var(--card);stroke-width:4px;stroke-linejoin:round;}
.heromap .stage .hm-tag{fill:rgba(var(--ink-rgb),.5);}
.heromap .stage .hm-legend text{font-size:10.5px;fill:rgba(var(--ink-rgb),.55);letter-spacing:.02em;}
.heromap .stage .hm-lg{fill:var(--card);stroke:var(--ink);stroke-width:1.3;}
.heromap .stage .hm-lg-sig{stroke:var(--signal);}
.heromap .stage .hm-lg-good{stroke:var(--pass);}
.heromap .stage .hm-lg-bad{stroke:var(--fail);}

/* ---------- cards + base edges ---------- */
.heromap .stage .n{fill:var(--card);stroke:var(--ink);stroke-width:1.3;stroke-linejoin:round;}
.heromap .stage .n-sig{stroke:var(--signal);}
.heromap .stage .n-good{stroke:var(--pass);}
.heromap .stage .n-bad{stroke:var(--fail);}
.heromap .stage .edge{fill:none;stroke:rgba(var(--ink-rgb),.36);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
/* keep the shell's arrival draw AND animate the state changes on the same rect */
.heromap .stage .actor .n.dr{transition:stroke-dashoffset var(--dur,.6s) ease-out var(--d,0s),stroke-width .45s ease,stroke .45s ease;}
.heromap .stage .actor .n{transition:stroke-width .45s ease,stroke .45s ease;}
.heromap .stage .actor .lbl{transition:fill .45s ease;}
.heromap .stage .actor{transform-box:fill-box;transform-origin:center;}

/* ---------- story states (set by heromap.js) ---------- */
/* light travelling along an edge */
.heromap .stage .hm-hi{fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1;opacity:0;pointer-events:none;
  transition:stroke-dashoffset .8s cubic-bezier(.4,0,.2,1),opacity .28s ease,stroke .5s ease;}
.heromap .stage .hm-hi.on{stroke-dashoffset:0;opacity:1;}
.heromap .stage .hm-hi-sig{stroke:var(--signal);}
.heromap .stage .hm-hi-good{stroke:var(--pass);}
.heromap .stage .hm-hi-bad,.heromap .stage .hm-hi.bad{stroke:var(--fail);}
/* commit dot drops in, the code card warms up */
.heromap .stage .hm-commit{opacity:0;transform:translateY(-34px);pointer-events:none;transition:opacity .45s ease,transform .85s cubic-bezier(.22,1,.36,1);}
.heromap .stage .hm-commit.on{opacity:1;transform:none;}
.heromap .stage .hm-dot{fill:var(--ink);}
.heromap .stage .hm-commit-l{fill:rgba(var(--ink-rgb),.62);paint-order:stroke;stroke:var(--card);stroke-width:3.5px;stroke-linejoin:round;}
.heromap .stage .hm-ping{fill:none;stroke:var(--ink);stroke-width:1.2;opacity:0;transform-box:fill-box;transform-origin:center;}
.heromap .stage .hot .hm-ping{animation:hm-ping 1.2s ease-out 1;}
@keyframes hm-ping{0%{transform:scale(.6);opacity:.55;}100%{transform:scale(4.6);opacity:0;}}
.heromap .stage .hot .n{stroke-width:2.3;}
.heromap .stage .act .n{stroke-width:2.3;}
.heromap .stage .act .lbl{fill:var(--signal);}
/* ticks and the one red cross */
.heromap .stage .hm-tick,.heromap .stage .hm-x{fill:none;stroke:var(--pass);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1;opacity:0;
  transition:stroke-dashoffset .5s cubic-bezier(.4,0,.2,1),opacity .2s ease;}
.heromap .stage .hm-x{stroke:var(--fail);}
.heromap .stage .tick .hm-tick{stroke-dashoffset:0;opacity:1;}
.heromap .stage .fail .hm-x{stroke-dashoffset:0;opacity:1;}
.heromap .stage .fail .hm-x2{transition-delay:.18s;}
.heromap .stage .fail .n{stroke:var(--fail);stroke-width:2.3;}
.heromap .stage .fail .lbl{fill:var(--fail);}
.heromap .stage .hm-fail{font-size:11px;fill:var(--fail);opacity:0;pointer-events:none;transition:opacity .5s ease;paint-order:stroke;stroke:var(--card);stroke-width:3.5px;stroke-linejoin:round;}
.heromap .stage .hm-fail.on{opacity:1;}
/* the known-issue card springs in, then gets validated and registered */
.heromap .stage .hm-ki{opacity:0;transform:scale(.94);pointer-events:none;transition:opacity .5s ease,transform .7s cubic-bezier(.2,1.25,.4,1);}
.heromap .stage .hm-ki.on{opacity:1;transform:none;pointer-events:auto;}
.heromap .stage .hm-aff-l{opacity:0;transition:opacity .4s ease .3s;}
.heromap .stage .hm-aff.on ~ .hm-aff-l,.heromap .stage .hm-aff-l.on{opacity:1;}
.heromap .stage .hm-val{opacity:0;transition:opacity .45s ease;}
.heromap .stage .hm-val .hm-tick{stroke-dashoffset:1;transition:stroke-dashoffset .5s cubic-bezier(.4,0,.2,1) .15s,opacity .2s ease;}
.heromap .stage .hm-val-t{font-size:10px;fill:rgba(var(--ink-rgb),.66);letter-spacing:.01em;}
.heromap .stage .val .hm-val{opacity:1;}
.heromap .stage .val .hm-val .hm-tick{stroke-dashoffset:0;opacity:1;}
.heromap .stage .hm-reg{opacity:0;transform:translateY(-4px);transition:opacity .4s ease,transform .5s cubic-bezier(.22,1,.36,1);}
.heromap .stage .hm-reg rect{fill:var(--ink);}
.heromap .stage .hm-reg text{font-size:9px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;fill:var(--paper);}
.heromap .stage .reg .hm-reg{opacity:1;transform:none;}

/* ---------- hover highlight (own mechanism; .hm-lit / .hm-dim) ---------- */
.heromap .stage [data-node],.heromap .stage [data-edge],.heromap .stage [data-of]{transition:opacity .22s ease;}
.heromap .stage .hm-hi[data-edge]{transition:stroke-dashoffset .8s cubic-bezier(.4,0,.2,1),opacity .28s ease,stroke .5s ease;}
.heromap .stage .hm-ki[data-node]{transition:opacity .5s ease,transform .7s cubic-bezier(.2,1.25,.4,1);}
.heromap .stage .hm-dim{opacity:.14;}
.heromap .stage .hm-hi.hm-dim.on{opacity:.14;}
.heromap .stage .hm-lit .n{stroke-width:2.3;}
.heromap .stage .edge.hm-lit{stroke:rgba(var(--ink-rgb),.78);stroke-width:1.8;}
.heromap .stage .hm-el.hm-lit{fill:var(--ink);}
.heromap .stage [data-node]{cursor:default;}

/* ---------- rail ---------- */
.heromap .rail{margin-top:1.1rem;}
.heromap .rail-line i{transition:none;}
.heromap .rail-beats{gap:.3rem 1.8rem;}
.heromap .rail-beat{display:inline-flex;align-items:baseline;gap:.55em;}
.heromap .rail-beat .hm-n{font-weight:400;color:rgba(var(--ink-rgb),.38);letter-spacing:.04em;}
.heromap .rail-beat.is-on .hm-n{color:var(--signal);}
.heromap .rail-cap{transition:opacity .18s ease;}
.heromap .rail-cap.is-swap{opacity:0;}

/* ---------- still frames / reduced motion: no transitions ---------- */
.heromap.is-still .stage *,.heromap.is-still .rail-cap{transition:none !important;animation:none !important;}
@media (prefers-reduced-motion: reduce){
  .heromap .stage *,.heromap .rail-cap,.heromap .rail-line i{transition:none !important;animation:none !important;}
}

/* ---------- responsive ---------- */
@media (max-width: 899px){
  .heromap .hm-d{display:none;}
  .heromap .hm-m{display:block;}
  .heromap .stage{padding:6px 0;}
  .heromap .stage .lbl{font-size:9.5px;letter-spacing:.06em;}
  .heromap .stage .ttl{font-size:12px;letter-spacing:-.01em;}
  .heromap .stage .hm-el{font-size:9.5px;}
  .heromap .stage .hm-tag{font-size:9px;}
  .heromap .stage .hm-val-t{font-size:9px;}
  .heromap .stage .hm-reg text{font-size:8px;}
  .heromap .stage .n{stroke-width:1.15;}
  .heromap .stage .hm-hi{stroke-width:1.8;}
  .heromap .stage .hm-tick,.heromap .stage .hm-x{stroke-width:1.8;}
  .heromap .stage .hm-commit{transform:translateY(-22px);}
  .heromap .stage .hm-commit.on{transform:none;}
  .heromap .rail-cap{font-size:.98rem;}
}
@media (max-width: 639px){
  .heromap .stage .hm-sm{display:none;}
  .heromap .rail-beats{gap:.25rem 1.2rem;}
  .heromap .rail-beat{font-size:.68rem;}
}
