/* ============================================================
   Mapbox / RF-acquisition hero (experimental swap-in).
   Loaded AFTER style.css. Everything is scoped under #top so it
   only affects the hero and never leaks into the page below.
   ============================================================ */

/* posterized + duotoned satellite (see #rf-posterize in index.html) */
#map{position:absolute;inset:0;width:100%;height:100%;z-index:0;filter:url(#rf-posterize)}
#top .mapboxgl-control-container{display:none}

/* RF instrument treatment (fades in during the acquire sequence) */
#top .fxwrap{position:absolute;inset:0;z-index:1;opacity:0;transition:opacity 1.4s ease}
#top.go .fxwrap{opacity:1}
#top .fx{position:absolute;inset:0;pointer-events:none}
#top .fx-graticule{z-index:2;opacity:.55;background:
  repeating-linear-gradient(to right,rgba(22,200,222,.07) 0 1px,transparent 1px 68px),
  repeating-linear-gradient(to bottom,rgba(22,200,222,.05) 0 1px,transparent 1px 68px),
  repeating-linear-gradient(to bottom,rgba(200,246,252,.035) 0 1px,transparent 1px 3px)}
#top .fx-carriers{z-index:2;mix-blend-mode:screen;background:
  linear-gradient(to right,transparent calc(26% - 1px),rgba(22,200,222,.45) 26%,transparent calc(26% + 1px)),
  linear-gradient(to right,transparent calc(54% - 1px),rgba(200,246,252,.4) 54%,transparent calc(54% + 1px)),
  linear-gradient(to right,transparent calc(71% - 1px),rgba(22,200,222,.3) 71%,transparent calc(71% + 1px));
  animation:carrier 7s ease-in-out infinite}
@keyframes carrier{0%,100%{opacity:.32}50%{opacity:.62}}
#top .fx-sweep{z-index:3;mix-blend-mode:screen;width:46%;left:-46%;background:
  linear-gradient(90deg,transparent,rgba(22,200,222,.10) 72%,rgba(22,200,222,.32) 93%,rgba(232,246,248,.85) 99.3%,transparent);
  animation:hero-sweep 8s linear infinite}
@keyframes hero-sweep{0%{transform:translateX(0)}100%{transform:translateX(317%)}}
#top .fx-vignette{z-index:3;background:radial-gradient(128% 100% at 60% 44%,transparent 40%,rgba(4,16,30,.5) 78%,rgba(4,16,30,.88) 100%)}
#top .fx-grain{z-index:4;inset:-6%;opacity:.07;animation:grain .7s steps(4) infinite;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
@keyframes grain{0%{transform:translate(0,0)}25%{transform:translate(-3%,2%)}50%{transform:translate(2%,-2%)}75%{transform:translate(-2%,-3%)}100%{transform:translate(0,0)}}
#top .hero-scrim{z-index:5;background:
  linear-gradient(90deg,rgba(4,16,30,.94) 0%,rgba(4,16,30,.8) 32%,rgba(4,16,30,.24) 58%,rgba(4,16,30,0) 84%),
  linear-gradient(180deg,rgba(4,16,30,.5) 0%,rgba(4,16,30,0) 26%,rgba(4,16,30,0) 60%,var(--void) 100%)}
#top .fx-label{position:absolute;z-index:6;font-family:var(--mono);text-transform:uppercase;color:var(--signal);opacity:.42;pointer-events:none;letter-spacing:.28em;font-size:9.5px;text-shadow:0 1px 6px rgba(4,16,30,.95)}
#top .lab-rx{top:22px;left:28px;letter-spacing:.2em}
#top .lab-rx b{color:var(--lock);font-weight:500}
#top .lab-ampl{left:9px;top:50%;transform:translateY(-50%) rotate(180deg);writing-mode:vertical-rl}

/* plotted-track trail canvas */
#top .fx-track{position:absolute;inset:0;z-index:6;pointer-events:none}

/* secondary / tertiary contacts */
#top .contact{position:absolute;top:0;left:0;z-index:7;pointer-events:none;opacity:0;transition:opacity .7s ease;font-family:var(--mono);text-transform:uppercase}
#top .contact.on{opacity:1}
/* Every contact wears the same corner-bracket mark as the primary's lock —
   one targeting notation across the whole picture, differing only in scale and
   weight. Rings are reserved for the aircraft themselves. */
/* sized to sit just OUTSIDE the airframe it brackets, the way the primary's lock
   contains its aircraft — brackets that land inside the rotors read as a mistake */
#top .contact .mk{position:absolute;left:-29px;top:-29px;width:58px;height:58px;opacity:.9;transition:transform .3s cubic-bezier(.2,.7,.2,1),opacity .3s ease}
#top .contact .mk .c{position:absolute;width:8px;height:8px;border:1.5px solid var(--signal);transition:border-color .25s ease}
#top .contact .mk .c.tl{top:0;left:0;border-right:none;border-bottom:none}
#top .contact .mk .c.tr{top:0;right:0;border-left:none;border-bottom:none}
#top .contact .mk .c.bl{bottom:0;left:0;border-right:none;border-top:none}
#top .contact .mk .c.br{bottom:0;right:0;border-left:none;border-top:none}
/* centre pip: the resolved position. Absent on the encrypted track below. */
#top .contact .mk::before{content:"";position:absolute;left:50%;top:50%;width:3px;height:3px;margin:-1.5px 0 0 -1.5px;border-radius:50%;
  background:var(--signal);box-shadow:0 0 6px rgba(22,200,222,.7)}
/* hover ring: grows out of the mark to say "this is a target you can pick" */
#top .contact .mk::after{content:"";position:absolute;inset:-7px;border:1px solid var(--signal);border-radius:50%;opacity:0;transform:scale(.72);
  transition:opacity .3s ease,transform .35s cubic-bezier(.2,.7,.2,1)}
#top .contact .lbl{position:absolute;left:37px;top:-6px;white-space:nowrap;font-size:9px;letter-spacing:.18em;color:var(--signal);text-shadow:0 1px 6px rgba(4,16,30,.95);transition:color .25s ease,opacity .25s ease}
/* the small airframe for a contact the receiver has actually classified */
#top .contact .air{position:absolute;left:-48px;top:-48px;width:96px;height:96px;pointer-events:none;filter:drop-shadow(0 0 5px rgba(22,200,222,.42))}
/* unresolved: a grey best-guess airframe and no centre pip, because the
   position itself isn't pinned down */
#top .contact.unknown .air{width:88px;height:88px;left:-44px;top:-44px;filter:drop-shadow(0 0 4px rgba(184,202,214,.3))}
#top .contact.unknown .mk{opacity:.55;animation:jit .28s steps(2) infinite}
#top .contact.unknown .mk .c{border-color:var(--body-d)}
#top .contact.unknown .mk::before{display:none}
#top .contact.unknown .mk::after{border-color:var(--body-d)}
#top .contact.unknown .lbl{color:var(--body-d);opacity:.7}
@keyframes jit{0%{transform:translate(0,0)}50%{transform:translate(1px,-1px)}100%{transform:translate(-1px,1px)}}

/* ---- selectable contacts ---------------------------------------------
   Each contact carries an invisible hit button centred on its position. The
   visuals stay pointer-transparent so only the button takes the pointer. */
#top .hit{position:absolute;left:-32px;top:-32px;width:64px;height:64px;padding:0;border:0;border-radius:50%;background:none;cursor:pointer;
  pointer-events:auto;overflow:hidden;text-indent:-200vw;white-space:nowrap;-webkit-tap-highlight-color:transparent}
#top .reticle .hit{left:0;top:0;width:100%;height:100%;border-radius:3px}
#top .hit:focus-visible{outline:1.5px solid var(--lock);outline-offset:4px}

/* focus: keyboard gets the same bloom as the pointer */
#top .contact:not(.sel):has(.hit:focus-visible) .mk{transform:scale(1.14);opacity:1}
#top .contact:not(.sel):has(.hit:focus-visible) .mk .c{border-color:var(--lock)}
#top .contact:not(.sel):has(.hit:focus-visible) .mk::after{opacity:.5;transform:scale(1)}
#top .contact:not(.sel):has(.hit:focus-visible) .lbl{color:var(--lock);opacity:1}
#top .reticle:has(.hit:focus-visible) .c{border-color:var(--lock)}
/* hover, gated so a tap on a touch screen doesn't leave the state stuck on */
@media (hover:hover){
  #top .contact:not(.sel):has(.hit:hover) .mk{transform:scale(1.14);opacity:1}
  #top .contact:not(.sel):has(.hit:hover) .mk .c{border-color:var(--lock)}
  #top .contact:not(.sel):has(.hit:hover) .mk::after{opacity:.5;transform:scale(1)}
  #top .contact:not(.sel):has(.hit:hover) .lbl{color:var(--lock);opacity:1}
  #top .reticle:has(.hit:hover) .c{border-color:var(--lock)}
}

/* The contact the instrument is currently reporting on. Its own mark and label both
   step aside, because the lock has arrived and is now bracketing this aircraft:
   keeping the small mark stacks two sets of brackets around one target, and keeping
   the label prints its name twice in the same corner. This is why track 01 always
   read cleaner than 02 and 03 — its mark IS the lock, so it never doubled up.
   The short delay lets the lock come in before the mark leaves. */
#top .contact.sel .mk,#top .contact.sel .lbl{opacity:0;transition-delay:.18s}
@media (prefers-reduced-motion:reduce){
  #top .contact .mk,#top .contact .mk::after,#top .contact .lbl{transition:none}
  #top .contact.unknown .mk{animation:none}
}

/* primary contact: 3D quad + HUD lock (reticle inner styles come from style.css).
   The canvas sits inside .contact#c01, so the parent's reveal and transform carry it. */
#top .drone{position:absolute;top:0;left:0;width:160px;height:160px;margin:-80px 0 0 -80px;pointer-events:none;filter:drop-shadow(0 0 6px rgba(22,200,222,.5))}
/* a hit target scaled to the airframe rather than a bare point */
#top .hit.primary{left:-52px;top:-42px;width:104px;height:84px;border-radius:3px}
/* track 01 has no bracket mark of its own — the lock is its mark — so hovering it
   brightens the reticle instead. #c01 precedes .reticle in the markup. */
#top .contact.c01:has(.hit:focus-visible) ~ .reticle .c{border-color:var(--lock)}
@media (hover:hover){#top .contact.c01:has(.hit:hover) ~ .reticle .c{border-color:var(--lock)}}
#top .reticle{z-index:8;width:104px;height:84px}
/* Acquiring: brackets present and holding open, never snapping shut. This is the
   honest state for an encrypted emitter — detected, bearing known, not resolved. */
#top .reticle.acq{opacity:1}
#top .reticle.acq .box{transform:scale(1.1)}
#top .reticle.acq .c{border-color:var(--body-d);animation:acqPulse 1.7s ease-in-out infinite}
#top .reticle.acq .tag .cls{color:var(--body-d)}
@keyframes acqPulse{0%,100%{opacity:.42}50%{opacity:.9}}
@media (prefers-reduced-motion:reduce){#top .reticle.acq .c{animation:none;opacity:.8}}

/* live telemetry HUD */
#top .telem{position:absolute;right:26px;bottom:120px;z-index:8;width:238px;pointer-events:none;font-family:var(--mono);color:var(--body-d);opacity:0;transform:translateY(10px);transition:opacity .8s ease,transform .8s ease;background:linear-gradient(180deg,rgba(6,22,38,.6),rgba(6,22,38,.34));border:1px solid var(--hair-d);border-radius:6px;padding:12px 13px 13px;backdrop-filter:blur(7px)}
#top .telem.on{opacity:1;transform:none}
#top .telem .head{display:flex;justify-content:space-between;align-items:center;margin-bottom:9px;font-size:10px;letter-spacing:.22em;color:var(--signal)}
#top .telem .head .st{color:var(--lock);font-size:9px;display:flex;align-items:center;gap:5px}
#top .telem .head .st::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--signal);box-shadow:0 0 7px var(--signal);animation:pulse 2.4s ease-in-out infinite}
#top .telem-wf{display:block;width:100%;height:46px;margin-bottom:10px;border:1px solid var(--hair-d);background:var(--void);border-radius:2px}
#top .telem-bar{height:3px;background:rgba(22,200,222,.14);margin:1px 0 8px;overflow:hidden;border-radius:2px}
#top .telem-bar i{display:block;height:100%;width:40%;background:linear-gradient(90deg,var(--signal-dim),var(--signal));box-shadow:0 0 8px rgba(22,200,222,.7)}
#top .telem-kv{display:flex;justify-content:space-between;align-items:baseline;font-size:10.5px;letter-spacing:.04em;margin:5px 0}
#top .telem-kv .k{opacity:.55;text-transform:uppercase;letter-spacing:.14em;font-size:8.5px}
#top .telem-kv .v{color:var(--lock)}

/* keep the hero content above the HUD layers */
#top .hero-inner{z-index:9}
#top .hero-rail{z-index:9}
/* The headline block sits above the contacts (z 9 vs 7) so type never renders
   underneath an aircraft. That stacking also meant it swallowed every pointer
   aimed at a track, so the block itself goes pointer-transparent and hands the
   pointer back to the things that actually want it. */
#top .hero-inner,#top .hero-rail{pointer-events:none}
#top .hero-inner a,#top .hero-inner button,#top .hero-rail a,#top .hero-rail button{pointer-events:auto}

/* staged reveal of the headline block (scoped so page CTAs are untouched) */
#top .kicker,#top h1,#top .hero-sub,#top .sigline,#top .cta-row,#top .hero-rail-inner{opacity:0;transform:translateY(16px);transition:opacity .9s cubic-bezier(.2,.7,.2,1),transform .9s cubic-bezier(.2,.7,.2,1)}
#top.go .kicker{transition-delay:.05s}
#top.go h1{transition-delay:.16s}
#top.go .hero-sub{transition-delay:.30s}
#top.go .sigline{transition-delay:.42s}
#top.go .cta-row{transition-delay:.52s}
#top.go .hero-rail-inner{transition-delay:.62s}
#top.go .kicker,#top.go h1,#top.go .hero-sub,#top.go .sigline,#top.go .cta-row,#top.go .hero-rail-inner{opacity:1;transform:none}

/* acquire / boot overlay */
#top .boot{position:absolute;inset:0;z-index:40;background:var(--void);display:flex;align-items:center;justify-content:center;transition:opacity .8s ease}
#top .boot.off{opacity:0;pointer-events:none}
#top .boot-inner{text-align:center;font-family:var(--mono);color:var(--signal)}
#top .boot-title{font-size:11px;letter-spacing:.42em;text-transform:uppercase;opacity:.7;margin-bottom:15px}
#top .boot-status{font-size:13px;letter-spacing:.26em;text-transform:uppercase;color:var(--lock);margin-bottom:17px;min-height:1.2em}
#top .boot-bar{width:220px;height:2px;background:rgba(22,200,222,.16);margin:0 auto;overflow:hidden}
#top .boot-bar i{display:block;height:100%;width:0;background:var(--signal);box-shadow:0 0 8px var(--signal);transition:width .1s linear}

/* ---- responsive ---- */
@media (max-width:1040px){#top .telem{display:none}}
/* ---- mobile -----------------------------------------------------------
   On a phone the airspace picture is ambient rather than interactive. The
   contacts keep their natural spread across the frame and sit behind the
   headline (z 7 vs 9), so the message always wins; nothing is tappable, and
   every piece of overlay text goes, because type layered under type is mush.
   JS supplies the narrow hold positions. */
@media (max-width:760px){
  #top .fx-label{display:none}
  #top .hit{display:none}                       /* not clickable, and not a stray tab stop */
  #top .contact .lbl,#top .reticle .tag{display:none}
  /* stepped back so white headline type stays crisp over the line work */
  #top .contact.on{opacity:.72}
  #top .reticle.lock,#top .reticle.acq{opacity:.72}
  #top .drone{display:block;width:96px;height:96px;margin:-48px 0 0 -48px}
  /* re-show the lock on mobile (style.css hides .reticle < 700px for the old hero) */
  #top .reticle{display:block;width:68px;height:56px}
  #top .contact .air,#top .contact.unknown .air{width:64px;height:64px;left:-32px;top:-32px}
  #top .contact .mk{left:-20px;top:-20px;width:40px;height:40px}
  #top .contact .mk .c{width:7px;height:7px}
  #top .contact .mk::before{box-shadow:0 0 4px rgba(22,200,222,.5)}
  #top .contact .mk::after{inset:-6px}
}
@media (max-height:560px) and (orientation:landscape){
  #top .hero-rail{padding-top:24px}
}

@media (prefers-reduced-motion:reduce){
  #top .fx-carriers,#top .fx-sweep,#top .fx-grain{animation:none}
  #top .fxwrap{opacity:1;transition:none}
  #top .boot{display:none}
  #top .kicker,#top h1,#top .hero-sub,#top .sigline,#top .cta-row,#top .hero-rail-inner{opacity:1;transform:none;transition:none}
}
