/* Map life: the storm at the rim, light along the paths, VALOR's sweep, PULSE's heartbeat, TAIL, the thirteenth mark,
   the Watchtower's live status lamp, and the fragment answering your taps. All decoration over the artwork:
   nothing here takes the pointer, and it all sits behind the place labels. */

/* --- the storm at the rim --- */
.storm-layer{position:absolute;inset:0;z-index:3;overflow:hidden;pointer-events:none}
.storm{position:absolute;top:0;bottom:0;width:11%;mix-blend-mode:screen;opacity:.55;
  background:
    repeating-linear-gradient(0deg,transparent 0 13px,rgba(255,255,255,.07) 13px 15px),
    linear-gradient(90deg,rgba(214,232,255,.3),rgba(198,160,255,.14) 45%,transparent);
  animation:storm-shimmer 9s ease-in-out infinite,storm-surge 38s ease-in-out infinite}
.storm-r{right:0;transform:scaleX(-1);animation-delay:-4s,-19s}
.storm-l{left:0}
.storm-mark{position:absolute;color:#dfe9ff;font:700 11px "Courier New",monospace;opacity:0;text-shadow:0 0 8px rgba(198,160,255,.9),0 0 3px #fff;animation:storm-flash 6s steps(1,end) infinite}
.storm-mark.m1{left:2.5%;top:18%}
.storm-mark.m2{left:6%;top:42%;animation-delay:-1.7s;animation-duration:8s}
.storm-mark.m3{left:3%;top:68%;animation-delay:-3.2s;animation-duration:7s}
.storm-mark.m4{right:3%;top:24%;animation-delay:-2.4s;animation-duration:9s}
.storm-mark.m5{right:6.5%;top:50%;animation-delay:-.6s}
.storm-mark.m6{right:2.5%;top:72%;animation-delay:-4.8s;animation-duration:7.5s}
@keyframes storm-shimmer{0%,100%{opacity:.4}45%{opacity:.62}50%{opacity:.35}55%{opacity:.7}}
@keyframes storm-surge{0%,78%,100%{width:11%}88%{width:19%}}
@keyframes storm-flash{0%,14%,19%,55%,58%,100%{opacity:0}15%{opacity:1}16%{opacity:.2}17%{opacity:.9}56%{opacity:.8}57%{opacity:.1}}

/* --- paths, VALOR's sweep, TAIL --- */
.life-layer{position:absolute;inset:0;width:100%;height:100%;z-index:5;pointer-events:none;overflow:hidden}
.life-layer .pkt{fill:#fff;filter:drop-shadow(0 0 4px #65faff) drop-shadow(0 0 9px rgba(101,250,255,.8))}
.life-layer .pkt.o{fill:#ffd9b0;filter:drop-shadow(0 0 4px #ff7a18) drop-shadow(0 0 9px rgba(255,122,24,.85))}
.life-layer .tail-dot{fill:#efe3ff;filter:drop-shadow(0 0 4px #c6a0ff) drop-shadow(0 0 8px rgba(198,160,255,.8))}
.life-layer .valor-beam{fill:url(#beamGrad);opacity:.3;mix-blend-mode:screen}
.life-layer[data-status="warning"] .valor-beam{fill:url(#beamGradWarn)}
.life-layer[data-status="critical"] .valor-beam{fill:url(#beamGradBad);opacity:.42}

/* --- PULSE's heartbeat along the shield --- */
.shield-spine .shield-pulse{fill:#ffd3ea;filter:drop-shadow(0 0 3px #ff4fa8) drop-shadow(0 0 8px rgba(255,79,168,.9))}

/* --- the thirteenth mark, beside Terminus --- */
.mark-13{position:absolute;left:59.4%;top:60.5%;z-index:6;width:30px;height:30px;transform:translate(-50%,-50%);pointer-events:none;
  display:grid;place-items:center;border:1.5px solid var(--orange,#ff7a18);border-radius:50%;background:rgba(5,5,11,.72);
  color:#fff;font:700 10px "Courier New",monospace;letter-spacing:0;
  box-shadow:0 0 8px rgba(255,122,24,.7),0 0 18px rgba(255,122,24,.35),inset 0 0 6px rgba(255,122,24,.35);
  animation:mark-breathe 5s ease-in-out infinite}
.mark-13::after{content:"";position:absolute;inset:-6px;border:1px solid rgba(255,122,24,.35);border-radius:50%;animation:mark-ring 5s ease-out infinite}
@keyframes mark-breathe{0%,100%{box-shadow:0 0 8px rgba(255,122,24,.6),0 0 16px rgba(255,122,24,.3),inset 0 0 6px rgba(255,122,24,.3)}50%{box-shadow:0 0 12px rgba(255,160,70,.95),0 0 26px rgba(255,122,24,.55),inset 0 0 9px rgba(255,122,24,.5)}}
@keyframes mark-ring{0%{transform:scale(.8);opacity:.8}70%,100%{transform:scale(1.5);opacity:0}}

/* --- the Watchtower's live status lamp --- */
.status-lamp{position:absolute;top:9px;right:16px;width:9px;height:9px;border-radius:50%;background:#8fa9b6;box-shadow:0 0 6px #8fa9b6;pointer-events:none;animation:lamp-beat 3s ease-in-out infinite}
.status-lamp[data-state="ok"]{background:#4dff9a;box-shadow:0 0 6px #4dff9a,0 0 14px rgba(77,255,154,.6)}
.status-lamp[data-state="warning"]{background:#ffcf33;box-shadow:0 0 6px #ffcf33,0 0 14px rgba(255,207,51,.6)}
.status-lamp[data-state="critical"]{background:#ff3b42;box-shadow:0 0 6px #ff3b42,0 0 14px rgba(255,59,66,.7);animation-duration:1s}
.status-lamp .sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@keyframes lamp-beat{0%,100%{opacity:1}50%{opacity:.55}}

/* --- the fragment answers a tap (js/map-life.js sets data-react on the layer) --- */
.fragment-layer.is-guided .frag-msg{animation:none;opacity:0}
.fragment-layer[data-react="archives"] .frag-body{filter:drop-shadow(0 0 5px #fff) drop-shadow(0 0 18px #c6a0ff) brightness(1.5);opacity:1;animation:fragment-bob 5.5s ease-in-out infinite}
.fragment-layer[data-react="forge"] .frag-body{filter:drop-shadow(0 0 3px #ff7a18) drop-shadow(0 0 10px rgba(255,59,66,.8)) brightness(.8);opacity:.5;animation:fragment-bob 5.5s ease-in-out infinite}
.fragment-layer[data-react="forge"] .frag-spark{background:#ffb27a;box-shadow:0 0 6px #ff3b42}
.fragment-layer[data-react="watchtower"] .frag-body,.fragment-layer[data-react="gateway"] .frag-body{filter:drop-shadow(0 0 5px #fff) drop-shadow(0 0 16px #65faff) brightness(1.3);opacity:1;animation:fragment-bob 5.5s ease-in-out infinite}
.fragment-layer[data-react="terminus"] .frag-body{filter:drop-shadow(0 0 5px #ffb27a) drop-shadow(0 0 18px rgba(255,122,24,.95)) brightness(1.3);opacity:1;animation:fragment-bob 5.5s ease-in-out infinite}
.fragment-layer[data-react="outer"] .frag-body .arc{animation:fragment-arc-fast .5s steps(1,end) infinite}
.fragment-layer[data-react]:not([data-react=""]) .frag:not(.frag-spark)::before{content:"";position:absolute;left:50%;top:50%;width:100%;aspect-ratio:1;border:1.5px solid rgba(255,255,255,.7);border-radius:50%;transform:translate(-50%,-50%) scale(.4);opacity:0;animation:frag-ring 2.2s ease-out 3}
@keyframes frag-ring{0%{transform:translate(-50%,-50%) scale(.4);opacity:.9}100%{transform:translate(-50%,-50%) scale(2.6);opacity:0}}
@keyframes fragment-arc-fast{0%,30%,60%,100%{opacity:0}10%,40%{opacity:1}20%{opacity:.3}50%{opacity:.8}}

@media(prefers-reduced-motion:reduce){
  .storm,.storm-mark,.mark-13,.mark-13::after,.status-lamp{animation:none}
  .storm-mark{display:none}
  .life-layer .pkt,.life-layer .tail-dot,.life-layer .valor-beam,.shield-pulse{display:none}
  .life-layer .valor-lamp{animation:none}
}

/* --- a computer, not a lamp: everything stays dim, and dimmer still at night (US Central, set by js/map-life.js) --- */
.storm-layer,.life-layer,.fragment-layer{opacity:.88}
.paradigm-chart[data-time="dusk"] .storm-layer,.paradigm-chart[data-time="dusk"] .life-layer,.paradigm-chart[data-time="dusk"] .fragment-layer{opacity:.74}
.paradigm-chart[data-time="night"] .storm-layer,.paradigm-chart[data-time="night"] .life-layer,.paradigm-chart[data-time="night"] .fragment-layer{opacity:.58}
.paradigm-chart[data-time="night"] .storm{opacity:.45}
.life-layer .valor-beam{opacity:.42}
.life-layer .valor-beam.core{opacity:.6}
.life-layer .valor-lamp{fill:#eaffff;opacity:.85;filter:drop-shadow(0 0 6px #65faff) drop-shadow(0 0 16px rgba(101,250,255,.85));animation:lamp-glow 4.4s ease-in-out infinite}
@keyframes lamp-glow{0%,100%{opacity:.6}50%{opacity:1}}
.life-layer[data-status="critical"] .valor-beam{opacity:.5}
.mark-13{opacity:.9}

/* --- extra packets only when the machine is really busy (coarse load from /api/watchtower) --- */
.life-layer .busy{display:none}
.life-layer[data-busy="1"] .busy{display:inline}

/* --- whispers on hover: a line from the story --- */
.map-whisper{position:absolute;z-index:9;max-width:min(260px,46%);padding:5px 9px;transform:translate(-50%,-100%);pointer-events:none;
  border:1px solid rgba(255,122,24,.55);background:rgba(5,5,11,.92);color:#d9e1ea;font:12px/1.4 "Courier New",monospace;letter-spacing:.04em;text-align:center;
  box-shadow:0 0 10px rgba(255,122,24,.18);opacity:0;transition:opacity .25s}
.map-whisper.on{opacity:1}

/* --- the tour: follow the fragment --- */
.tour-button{margin-top:10px;padding:9px 14px;border:1px solid rgba(255,122,24,.7);background:rgba(5,5,11,.9);color:#fff;font:700 11px "Courier New",monospace;letter-spacing:.18em;cursor:pointer;text-shadow:0 0 8px rgba(255,122,24,.5)}
.tour-button:hover,.tour-button:focus-visible,.tour-button[aria-pressed="true"]{border-color:#fff;box-shadow:0 0 12px rgba(255,122,24,.35)}
.tour-caption{min-height:3.2em;margin:12px 0 0;padding:10px 14px;border-left:2px solid var(--orange,#ff7a18);background:rgba(5,5,11,.7);color:#c3ced8;font:13px/1.6 "Courier New",monospace}
.tour-caption[hidden]{display:none}

/* VALOR's light stays readable even at night: the beam layer dims less than the rest */
.paradigm-chart[data-time="night"] .life-layer{opacity:.75}
.paradigm-chart[data-time="dusk"] .life-layer{opacity:.82}
