/* ============================================================
   FD LOADERS — 25 infographic preloaders
   Used by: full-page boot overlay + inline data placeholders
   ============================================================ */

/* ---------- full-page boot overlay ---------- */
.fdload{position:fixed;inset:0;z-index:9000;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(ellipse at 50% 45%,#06181f 0%,#020a0e 60%,#01060a 100%);
  transition:opacity .45s ease,visibility .45s ease}
.fdload::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(0deg,rgba(0,255,136,.045) 0 1px,transparent 1px 3px)}
.fdload.gone{opacity:0;visibility:hidden}
.fdload-in{position:relative;width:min(360px,84vw);text-align:center}
.fdload-in svg{width:100%;height:190px;display:block}
.fdload-t{font-family:var(--mono,'JetBrains Mono',monospace);font-size:11px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--grn,#00ff88);font-weight:800;margin-bottom:4px}
.fdload-c{font-family:var(--mono,'JetBrains Mono',monospace);font-size:10.5px;letter-spacing:.12em;
  color:rgba(255,255,255,.42);margin-top:10px;display:flex;justify-content:space-between;align-items:center;gap:10px}
.fdload-c .p{color:var(--cy,#25d0ff);font-weight:800;font-variant-numeric:tabular-nums}
.fdload-b{height:2px;margin-top:8px;background:rgba(255,255,255,.08);overflow:hidden}
.fdload-b i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--cy,#25d0ff),var(--grn,#00ff88));
  box-shadow:0 0 10px var(--grn,#00ff88);transition:width .28s ease}
.fdload-cnr{position:absolute;width:16px;height:16px;border:1px solid rgba(0,255,136,.5)}
.fdload-cnr.tl{top:-14px;left:-14px;border-right:0;border-bottom:0}
.fdload-cnr.tr{top:-14px;right:-14px;border-left:0;border-bottom:0}
.fdload-cnr.bl{bottom:-14px;left:-14px;border-right:0;border-top:0}
.fdload-cnr.br{bottom:-14px;right:-14px;border-left:0;border-top:0}
html.fd-booting,html.fd-booting body{overflow:hidden}

/* ---------- inline data placeholder ---------- */
.fdph{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;
  width:100%;box-sizing:border-box;min-height:150px;max-height:220px;
  padding:14px;border:1px solid var(--line,rgba(255,255,255,.1));border-radius:3px;
  background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(0,0,0,.22))}
.fdph svg{width:150px;height:96px;display:block}
.fdph .cap{font-family:var(--mono,'JetBrains Mono',monospace);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(255,255,255,.4);margin-top:8px}
.fdph .bar{width:120px;height:2px;margin-top:8px;background:rgba(255,255,255,.08);overflow:hidden}
.fdph .bar i{display:block;height:100%;width:34%;background:var(--grn,#00ff88);box-shadow:0 0 8px var(--grn,#00ff88);
  animation:fdl-slide 1.5s ease-in-out infinite}
@keyframes fdl-slide{0%{transform:translateX(-110%)}100%{transform:translateX(360%)}}
.fdph.wide{min-height:190px}
.fdph.wide svg{width:200px;height:120px}

/* buffer glyph tucked into the time-machine buffer chip */
.fdbuf{width:14px;height:14px;vertical-align:-3px;margin-right:4px;display:inline-block}

/* ---------- gallery grid (loaders.html) ---------- */
.lgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:14px;margin-top:22px}
.ld{border:1px solid var(--line,rgba(255,255,255,.1));border-radius:4px;overflow:hidden;position:relative;
  background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(0,0,0,.25))}
.ld:hover{border-color:rgba(0,255,136,.45)}
.ld-h{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--line,rgba(255,255,255,.1));
  font-family:var(--mono,'JetBrains Mono',monospace);font-size:10px;letter-spacing:.12em;text-transform:uppercase}
.ld-h .n{color:var(--grn,#00ff88);font-weight:800}
.ld-h .t{color:var(--text,#dfe9ee);font-weight:600;letter-spacing:.08em}
.ld-h .p{margin-left:auto;color:rgba(255,255,255,.35);font-size:9px}
.ld-s{height:150px;display:flex;align-items:center;justify-content:center;
  background:radial-gradient(ellipse at 50% 60%,rgba(0,255,136,.06),transparent 70%)}
.ld-s svg{width:100%;height:100%;display:block}
.ld-f{display:flex;align-items:center;gap:8px;padding:7px 10px;border-top:1px solid var(--line,rgba(255,255,255,.1));
  font-family:var(--mono,'JetBrains Mono',monospace);font-size:10px;color:rgba(255,255,255,.4);letter-spacing:.08em}
.ld-f .pct{margin-left:auto;color:var(--grn,#00ff88);font-weight:800}
.ld-bar{height:2px;background:rgba(255,255,255,.07)}
.ld-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--cy,#25d0ff),var(--grn,#00ff88));
  box-shadow:0 0 8px var(--grn,#00ff88)}

/* ============================================================
   ANIMATION KEYFRAMES — one block per loader
   ============================================================ */
@keyframes fdl-spin{to{transform:rotate(360deg)}}
@keyframes fdl-dash{to{stroke-dashoffset:0}}

/* 01 rocket ascent */
@keyframes rk-rise{0%{transform:translateY(30px)}70%{transform:translateY(-34px)}100%{transform:translateY(-34px)}}
@keyframes rk-flame{0%,100%{transform:scaleY(.6);opacity:.7}50%{transform:scaleY(1.35);opacity:1}}
@keyframes rk-star{0%{transform:translateY(-40px);opacity:0}20%{opacity:1}100%{transform:translateY(120px);opacity:0}}
.rk{animation:rk-rise 3s cubic-bezier(.4,0,.5,1) infinite}
.rkf{animation:rk-flame .16s ease-in-out infinite;transform-origin:100px 74px}
.rks line{animation:rk-star 1.4s linear infinite}

/* 02 robot walk */
@keyframes rb-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
@keyframes rb-l1{0%,100%{transform:rotate(20deg)}50%{transform:rotate(-20deg)}}
@keyframes rb-l2{0%,100%{transform:rotate(-20deg)}50%{transform:rotate(20deg)}}
@keyframes rb-eye{0%,100%{fill:#00ff88}50%{fill:#25d0ff}}
.rb{animation:rb-bob .7s ease-in-out infinite}
.rbl1{animation:rb-l1 .7s ease-in-out infinite;transform-origin:92px 78px}
.rbl2{animation:rb-l2 .7s ease-in-out infinite;transform-origin:108px 78px}
.rba1{animation:rb-l2 .7s ease-in-out infinite;transform-origin:86px 54px}
.rba2{animation:rb-l1 .7s ease-in-out infinite;transform-origin:114px 54px}
.rbe{animation:rb-eye 1.1s steps(1) infinite}

/* 03 orbit trace */
.orbg{animation:fdl-spin 3.4s linear infinite;transform-origin:100px 62px}
.orbtrail{stroke-dasharray:210;stroke-dashoffset:210;animation:fdl-dash 3.4s linear infinite}

/* 04 die fill */
@keyframes cpu-fill{0%{height:0}100%{height:42px}}
@keyframes cpu-tr{0%{stroke-dashoffset:40}100%{stroke-dashoffset:0}}
.cpuf{animation:cpu-fill 2.2s ease-in-out infinite alternate}
.cput{stroke-dasharray:40;animation:cpu-tr 1.4s linear infinite}

/* 05 element tiles */
@keyframes el-in{0%{opacity:.12;transform:translateY(4px)}40%{opacity:1;transform:translateY(0)}100%{opacity:.12}}
.eltile rect{animation:el-in 1.8s ease-in-out infinite}

/* 06 radar */
@keyframes rd-blip{0%,100%{opacity:0}10%{opacity:1}}
.rdw{animation:fdl-spin 2.2s linear infinite;transform-origin:100px 62px}
.rdb{animation:rd-blip 2.2s linear infinite}

/* 07 pad release */
@keyframes cl-l{0%,60%{transform:rotate(0)}80%,100%{transform:rotate(-38deg)}}
@keyframes cl-r{0%,60%{transform:rotate(0)}80%,100%{transform:rotate(38deg)}}
@keyframes cl-smoke{0%,55%{opacity:0;transform:scale(.4)}75%{opacity:.8;transform:scale(1.5)}100%{opacity:0;transform:scale(2.2)}}
.cll{animation:cl-l 3s ease-in-out infinite;transform-origin:82px 84px}
.clr{animation:cl-r 3s ease-in-out infinite;transform-origin:118px 84px}
.cls{animation:cl-smoke 3s ease-out infinite}

/* 08 rack cascade */
@keyframes rl{0%,100%{opacity:.14}50%{opacity:1}}
.rl rect.led{animation:rl 1.2s ease-in-out infinite}

/* 09 molecule */
@keyframes mo-in{0%{opacity:0}30%{opacity:1}100%{opacity:1}}
.mog{animation:fdl-spin 6s linear infinite;transform-origin:100px 62px}
.mo circle.at{animation:mo-in 2.6s ease-out infinite}
.mo line{stroke-dasharray:30;stroke-dashoffset:30;animation:fdl-dash 2.6s ease-out infinite}

/* 10 globe tile-in */
@keyframes gt-in{0%{opacity:0}25%{opacity:.95}90%{opacity:.95}100%{opacity:0}}
@keyframes gt-mer{0%{transform:scaleX(1)}50%{transform:scaleX(.15)}100%{transform:scaleX(1)}}
.gt rect{animation:gt-in 2.4s ease-in-out infinite}
.gtm{animation:gt-mer 4s ease-in-out infinite;transform-origin:100px 62px}

/* 11 telemetry */
@keyframes ek{to{transform:translateX(-120px)}}
@keyframes ek-dot{0%,100%{opacity:.2}50%{opacity:1}}
.ekg{animation:ek 1.6s linear infinite}
.ekd{animation:ek-dot .8s ease-in-out infinite}

/* 12 propellant tank */
@keyframes tk{0%{transform:translateY(0)}100%{transform:translateY(-46px)}}
@keyframes tkw{0%{transform:translateX(0)}100%{transform:translateX(-40px)}}
.tkl{animation:tk 3s ease-in-out infinite alternate}
.tkw{animation:tkw 1.2s linear infinite}

/* 13 orrery */
@keyframes sunp{0%,100%{opacity:.85}50%{opacity:1}}
.o1{animation:fdl-spin 1.6s linear infinite;transform-origin:100px 62px}
.o2{animation:fdl-spin 2.8s linear infinite;transform-origin:100px 62px}
.o3{animation:fdl-spin 4.6s linear infinite;transform-origin:100px 62px}
.sun{animation:sunp 1.6s ease-in-out infinite}

/* 14 terminal */
@keyframes typ{from{width:0}to{width:132px}}
@keyframes cur{0%,100%{opacity:1}50%{opacity:0}}
.tmw{animation:typ 2.4s steps(22) infinite}
.tmc{animation:cur .7s steps(1) infinite}

/* 15 deep space link */
@keyframes arc{0%{opacity:0;transform:scale(.35)}25%{opacity:1}100%{opacity:0;transform:scale(1.5)}}
.arc{animation:arc 2s ease-out infinite;transform-origin:78px 62px}

/* 16 bar race */
@keyframes br1{0%,100%{height:12px;y:74}50%{height:52px;y:34}}
@keyframes br2{0%,100%{height:46px;y:40}50%{height:18px;y:68}}
@keyframes br3{0%,100%{height:26px;y:60}50%{height:60px;y:26}}
.b1{animation:br1 1.9s ease-in-out infinite}
.b2{animation:br2 1.9s ease-in-out infinite}
.b3{animation:br3 1.9s ease-in-out infinite}

/* 17 assembly arm */
@keyframes ar1{0%,100%{transform:rotate(-28deg)}50%{transform:rotate(14deg)}}
@keyframes ar2{0%,100%{transform:rotate(38deg)}50%{transform:rotate(-8deg)}}
@keyframes arbx{0%,45%{opacity:0}55%,100%{opacity:1}}
.ar1{animation:ar1 2.4s ease-in-out infinite;transform-origin:66px 88px}
.ar2{animation:ar2 2.4s ease-in-out infinite;transform-origin:0 0}
.arbx{animation:arbx 2.4s steps(1) infinite}

/* 18 hex ripple */
@keyframes hx{0%,100%{opacity:.1;transform:scale(.86)}45%{opacity:1;transform:scale(1)}}
.hx polygon{animation:hx 1.9s ease-in-out infinite;transform-box:fill-box;transform-origin:center}

/* 19 re-entry */
@keyframes cap{0%{transform:translateY(-38px)}100%{transform:translateY(24px)}}
@keyframes heat{0%,100%{opacity:.35;transform:scaleX(.8)}50%{opacity:1;transform:scaleX(1.25)}}
@keyframes chute{0%,55%{transform:scale(.05);opacity:0}75%,100%{transform:scale(1);opacity:1}}
.rcap{animation:cap 3.4s ease-in infinite}
.heat{animation:heat .18s ease-in-out infinite;transform-origin:100px 74px}
.chute{animation:chute 3.4s ease-out infinite;transform-origin:100px 44px}

/* 20 constellation */
@keyframes cst{0%{opacity:0}25%{opacity:1}90%{opacity:1}100%{opacity:0}}
.cst circle{animation:cst 3s ease-in-out infinite}
.cst line{stroke-dasharray:60;stroke-dashoffset:60;animation:fdl-dash 3s ease-in-out infinite}

/* 21 core sample */
@keyframes drl{0%{transform:translateY(-26px)}100%{transform:translateY(24px)}}
@keyframes strat{0%{width:0}100%{width:96px}}
.drl{animation:drl 3.2s ease-in infinite}
.strat{animation:strat 3.2s ease-out infinite}

/* 22 contour draw */
.ct path{stroke-dasharray:300;stroke-dashoffset:300;animation:fdl-dash 2.8s ease-in-out infinite}

/* 23 booster landing */
@keyframes bl{0%{transform:translateY(-30px)}75%,100%{transform:translateY(16px)}}
@keyframes leg-l{0%,60%{transform:rotate(0)}85%,100%{transform:rotate(-46deg)}}
@keyframes leg-r{0%,60%{transform:rotate(0)}85%,100%{transform:rotate(46deg)}}
@keyframes burn{0%,70%{opacity:1;transform:scaleY(1)}90%,100%{opacity:0;transform:scaleY(.2)}}
.bstr{animation:bl 3.2s cubic-bezier(.3,0,.2,1) infinite}
.legl{animation:leg-l 3.2s ease-out infinite;transform-origin:94px 76px}
.legr{animation:leg-r 3.2s ease-out infinite;transform-origin:106px 76px}
.burn{animation:burn 3.2s ease-out infinite;transform-origin:100px 78px}

/* 24 inference pass */
@keyframes nn{0%,100%{opacity:.16}40%{opacity:1}}
.nn circle{animation:nn 2s ease-in-out infinite}
.nn line{stroke-dasharray:44;stroke-dashoffset:44;animation:fdl-dash 2s linear infinite}

/* 25 sonar depth */
@keyframes png{0%{r:2;opacity:1}100%{r:44;opacity:0}}
@keyframes dpt{0%,100%{transform:scaleY(.3)}50%{transform:scaleY(1)}}
.png{animation:png 2s ease-out infinite}
.dpt rect{animation:dpt 1.6s ease-in-out infinite;transform-box:fill-box;transform-origin:bottom}

@media (prefers-reduced-motion:reduce){
  .fdload *,.fdph *,.ld *{animation-duration:.001s!important;animation-iteration-count:1!important}
}
