/* In-match heads-up display: vitals, ammo, board, feed, minimap. */

/* ============ HUD ============ */
  .hud{position:fixed;inset:0;pointer-events:none;z-index:5;
    opacity:0;transition:opacity .35s ease}
  .hud.on{opacity:1}
  .pane{background:var(--panel);border:1px solid var(--edge);border-radius:14px;
    backdrop-filter:blur(10px) saturate(1.2);-webkit-backdrop-filter:blur(10px) saturate(1.2);
    box-shadow:0 8px 30px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,255,255,.06)}
  .micro{font-size:10px;letter-spacing:.22em;color:var(--dim);font-weight:700;text-transform:uppercase}

  /* ---------------------------------------------------------------- health --
     No card. A hard accent edge, a big number and a segmented bar with an
     angled end — read at a glance, at speed, without a rounded box sitting in
     the corner of a fight. Legibility comes from a tight text shadow rather
     than a backdrop, same as the clock. */
  .vitals{position:fixed;bottom:16px;left:16px;min-width:250px;padding-left:13px;
    border-left:3px solid var(--grn);transition:border-color .25s}
  .vitals.low{border-left-color:var(--red)}
  .vitals .top{display:flex;align-items:baseline;gap:10px;margin-bottom:7px}
  .vitals .hpn{order:2;font-family:'JetBrains Mono';font-size:29px;font-weight:700;
    line-height:.88;color:var(--grn);transition:color .2s;
    text-shadow:0 1px 3px rgba(0,0,0,.92),0 0 18px rgba(92,255,165,.35)}
  .vitals .top .micro{order:1;align-self:flex-end;padding-bottom:2px;
    text-shadow:0 1px 3px rgba(0,0,0,.9)}
  .vitals.low .hpn{color:var(--red);text-shadow:0 1px 3px rgba(0,0,0,.92),0 0 20px rgba(255,90,114,.5)}
  .bar{position:relative;width:100%;height:11px;background:rgba(255,255,255,.09);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.07);
    clip-path:polygon(0 0,100% 0,calc(100% - 8px) 100%,0 100%)}
  .bar .ghost{position:absolute;inset:0;width:100%;background:rgba(255,90,114,.6);
    transition:width .55s cubic-bezier(.2,.7,.3,1) .16s}
  .bar .fill{position:absolute;inset:0;width:100%;transition:width .1s linear;
    background:linear-gradient(90deg,#1c9a5f,var(--grn));
    box-shadow:0 0 14px rgba(92,255,165,.55)}
  /* ticks over the top, so the bar reads as a gauge and not a smear */
  .bar::after{content:'';position:absolute;inset:0;pointer-events:none;
    background:repeating-linear-gradient(90deg,transparent 0 13px,rgba(0,0,0,.5) 13px 15px)}
  .vitals.low .bar .fill{background:linear-gradient(90deg,#a32a3f,var(--red));
    box-shadow:0 0 16px rgba(255,90,114,.65);animation:hpulse .7s infinite}
  @keyframes hpulse{0%,100%{opacity:1}50%{opacity:.55}}
  /* one white frame when something lands */
  .vitals.hit .bar{animation:hhit .16s ease-out}
  @keyframes hhit{0%{background:rgba(255,255,255,.85)}100%{background:rgba(255,255,255,.09)}}
  /* the worn shield, stacked on the health bar because it is the pool that
     empties first — thinner, so the eye still reads health as the main one */
  .sbar{position:relative;width:100%;height:6px;margin-bottom:3px;
    background:rgba(255,255,255,.08);box-shadow:inset 0 0 0 1px rgba(255,255,255,.06);
    clip-path:polygon(0 0,100% 0,calc(100% - 5px) 100%,0 100%)}
  .sbar.hide{display:none}
  .sbar .fill{position:absolute;inset:0;width:100%;background:var(--cy);
    box-shadow:0 0 12px rgba(92,233,255,.6);transition:width .12s linear}
  .sbar::after{content:'';position:absolute;inset:0;pointer-events:none;
    background:repeating-linear-gradient(90deg,transparent 0 13px,rgba(0,0,0,.5) 13px 15px)}
  .vitals.shieldhit .sbar .fill{animation:shflash .18s ease-out}
  @keyframes shflash{0%{background:#fff;box-shadow:0 0 20px #fff}100%{background:var(--cy)}}
  .buffs{display:flex;gap:6px;margin-top:8px;min-height:18px}
  .buff{font-size:10px;font-weight:800;letter-spacing:.14em;padding:2px 8px;
    border:1px solid currentColor;opacity:.95;
    clip-path:polygon(4px 0,100% 0,calc(100% - 4px) 100%,0 100%)}

  /* ------------------------------------------------------------------ ammo --
     The count kicks as each round leaves. That one detail is most of the
     difference between a number on the screen and a weapon in your hands. */
  .arms{position:fixed;bottom:16px;right:16px;text-align:right;padding-right:13px;
    border-right:3px solid var(--neon);transition:border-color .2s}
  .arms.dry{border-right-color:var(--red)}
  .arms .wn{font-size:12px;letter-spacing:.22em;font-weight:800;color:#cfdcf6;
    text-shadow:0 1px 3px rgba(0,0,0,.9)}
  .arms .num{font-family:'JetBrains Mono';font-size:41px;font-weight:700;line-height:.92;
    color:#fff;text-shadow:0 1px 4px rgba(0,0,0,.92),0 0 22px rgba(255,226,92,.45);
    transform-origin:100% 50%}
  .arms.dry .num{color:var(--red);text-shadow:0 1px 4px rgba(0,0,0,.92),0 0 22px rgba(255,90,114,.55)}
  .arms.punch .num{animation:apunch .13s cubic-bezier(.2,.9,.3,1)}
  @keyframes apunch{0%{transform:scale(1.16)}100%{transform:scale(1)}}
  .arms .num small{font-size:14px;color:var(--dim);font-weight:400}
  /* slanted slivers rather than dots — a magazine, not a battery */
  .pips{display:flex;gap:3px;justify-content:flex-end;margin-top:8px;height:10px}
  .pip{width:5px;height:10px;background:var(--neon);transform:skewX(-16deg);
    box-shadow:0 0 7px rgba(255,226,92,.6);transition:background .1s,box-shadow .1s}
  .pip.off{background:rgba(255,255,255,.13);box-shadow:none}
  .arms.reloading .pips{animation:areload .85s linear infinite}
  @keyframes areload{0%{opacity:.30}50%{opacity:1}100%{opacity:.30}}
  .arms .rel{height:13px;font-size:10px;letter-spacing:.22em;font-weight:800;color:var(--red);
    text-shadow:0 1px 3px rgba(0,0,0,.9)}
  .arms .rel.dim{color:var(--dim)}

  /* ------------------------------------------------------------ scoreboard --
     A fade rather than a card: the scrim is strongest at the screen edge where
     the text sits and gone by the time it reaches the arena, with an angled
     leading corner. Nothing here is a rounded rectangle any more. */
  .board{position:fixed;top:14px;right:14px;min-width:212px;padding:10px 14px 8px 30px;
    background:linear-gradient(270deg,rgba(4,7,14,.88) 0%,rgba(4,7,14,.70) 62%,transparent 100%);
    clip-path:polygon(18px 0,100% 0,100% 100%,0 100%)}
  .board h4{margin-bottom:8px;display:flex;justify-content:space-between;gap:14px;
    padding-bottom:6px;border-bottom:1px solid rgba(122,163,255,.20)}
  .board h4 span:last-child{color:var(--neon)}
  .brow{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;padding:2.5px 0;
    position:relative}
  /* the leader, and you — the only two rows anybody looks for mid-fight */
  .brow:first-child .nm{color:#fff}
  .brow:first-child .rk{opacity:1;color:var(--neon)}
  .brow.me{margin-left:-8px;padding-left:6px;border-left:2px solid var(--neon);
    background:linear-gradient(270deg,rgba(255,226,92,.10),transparent 70%)}
  /* the standing, so a row pinned to the bottom because it is yours still
     says where you actually are */
  .brow .rk{font-family:'JetBrains Mono';font-size:10px;font-weight:700;
    min-width:12px;text-align:right;opacity:.45;flex:none}
  .brow .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .brow .sc{font-family:'JetBrains Mono';font-size:13px;font-weight:700;min-width:18px;text-align:right}
  .brow.me{color:var(--neon)}
  .brow .dot{width:8px;height:8px;border-radius:2px;flex:none;box-shadow:0 0 8px currentColor}
  .brow .prog{position:absolute;left:34px;right:0;bottom:0;height:2px;background:rgba(255,255,255,.08)}
  .brow .prog i{display:block;height:100%;background:currentColor;opacity:.7;
    box-shadow:0 0 6px currentColor;transition:width .3s}

  /* -------------------------------------------------------------- killfeed --
     Rows punch in from the left with a slight overshoot and carry an accent
     edge that says whose kill it was before you have read a single name. */
  .feed{position:fixed;top:14px;left:14px;font-size:14px;font-weight:600;color:var(--dim);
    display:flex;flex-direction:column;gap:4px;max-width:min(46vw,430px)}
  .feed div{opacity:0;transform:translateX(-16px);
    animation:fin .22s cubic-bezier(.2,1.35,.35,1) forwards, fout .5s 4.2s forwards;
    background:linear-gradient(90deg,rgba(4,7,14,.90) 0%,rgba(4,7,14,.66) 62%,transparent 100%);
    border-left:3px solid var(--cy);
    clip-path:polygon(0 0,100% 0,calc(100% - 14px) 100%,0 100%);
    padding:3px 30px 3px 9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .feed div.mine{border-left-color:var(--neon)}
  .feed div.died{border-left-color:var(--red)}
  .feed div.head b:last-of-type{color:#ffd2d8}
  .feed b{color:var(--ink);text-shadow:0 1px 3px rgba(0,0,0,.9)}
  .feed .me{color:var(--neon)}
  .feed .wp{color:#9fb2d4;font-size:11px;letter-spacing:.14em;font-weight:800;margin:0 7px}
  .feed .hs{color:var(--red);font-weight:800;font-size:11px;letter-spacing:.1em}
  @keyframes fin{to{opacity:1;transform:none}}
  @keyframes fout{to{opacity:0;transform:translateX(-10px)}}
  @media (prefers-reduced-motion:reduce){
    .feed div{animation:fin .01s forwards, fout .5s 4.2s forwards}
    .arms.punch .num,.vitals.hit .bar,.arms.reloading .pips{animation:none}
  }

  /* minimap */

  /* center announce */
  .announce{position:fixed;top:16%;left:50%;transform:translateX(-50%);text-align:center;
    font-size:34px;font-weight:800;letter-spacing:.16em;opacity:0;text-shadow:0 0 26px currentColor}
  .announce.go{animation:ann 1.9s cubic-bezier(.2,.8,.3,1) forwards}
  @keyframes ann{
    0%{opacity:0;transform:translateX(-50%) scale(1.5)}
    12%{opacity:1;transform:translateX(-50%) scale(1)}
    72%{opacity:1}100%{opacity:0;transform:translateX(-50%) scale(1.04)}}

  /* respawn */
  .respawn{position:fixed;top:38%;left:50%;transform:translate(-50%,-50%);text-align:center;display:none}
  .respawn .t{font-size:14px;letter-spacing:.35em;color:var(--red);font-weight:800}
  .respawn .n{font-family:'JetBrains Mono';font-size:64px;font-weight:700;line-height:1.05;
    text-shadow:0 0 30px rgba(255,90,114,.35)}
  .respawn .by{font-size:13px;color:var(--dim);font-weight:600;letter-spacing:.1em;margin-top:-4px}
  /* Kill cam cinema mode. The replay owns the whole game canvas, so the HUD
     steps out of the shot: every pane hides, and the death overlay compacts
     into camera-style UI riding above the footage. */
  body.cinema .board,body.cinema .vitals,body.cinema .arms,
  body.cinema .clock,body.cinema .teamBar,body.cinema .feed,body.cinema .hint,
  body.cinema .vig,body.cinema .pads{display:none!important}
  body.cinema .respawn{top:auto;bottom:9%;transform:translateX(-50%)}
  body.cinema .respawn .t{font-size:11px;letter-spacing:.42em;text-indent:.42em}
  body.cinema .respawn .n{font-size:30px;text-shadow:0 2px 14px rgba(0,0,0,.8)}
  body.cinema .respawn .by{display:none}   /* the verdict is burned into the footage */
  body.cinema .swap{margin-top:6px}
  body.touch.cinema .respawn{bottom:11%}
  body.touch.cinema .respawn .n{font-size:26px}

  .swap{margin-top:16px;display:flex;gap:8px;justify-content:center}
  .swap div{font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--dim);
    border:1px solid var(--edge);border-radius:8px;padding:4px 9px;background:rgba(9,15,29,.6)}
  .swap div.sel{color:var(--neon);border-color:var(--neon);background:rgba(255,226,92,.08)}
  .swap b{font-family:'JetBrains Mono';font-size:10px;color:var(--ink);opacity:.8}

  .hint{position:fixed;bottom:96px;left:50%;transform:translateX(-50%);font-size:12px;
    letter-spacing:.18em;color:var(--dim);font-weight:700;opacity:0}
  .hint.go{animation:hfade 5s ease forwards}
  @keyframes hfade{0%{opacity:0}12%{opacity:1}70%{opacity:1}100%{opacity:0}}

/* ---------------------------------------------------------- match clock ---
   No panel, no box. The minimap used to sit above it and the two shared a slab;
   with the minimap gone the clock owns the top of the screen on its own, so it
   is drawn rather than framed: tabular digits over a depletion bar that closes
   in on itself from both ends as the match runs out.

   Legibility without a background comes from the text shadow — a tight dark
   halo, not a plate — so the digits hold up over a bright arena without putting
   a rectangle in the middle of the player's view.

   --p is the fraction of the match remaining, set by hud.js. --c is the state
   colour and everything else follows it. */
  .clock{position:fixed;top:14px;left:50%;transform:translateX(-50%);
    display:flex;flex-direction:column;align-items:center;gap:7px;
    pointer-events:none;--c:#8ff0ff;--p:1}
  .clock .ct{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:30px;
    line-height:1;letter-spacing:.09em;color:#fff;font-variant-numeric:tabular-nums;
    text-shadow:0 1px 3px rgba(0,0,0,.92),0 0 20px rgba(0,0,0,.65);
    transition:color .3s}
  /* the track, with a notch at each end — the sci-fi bit, and it also tells you
     where "full" was once the bar has closed in */
  .clock .cbar{position:relative;width:190px;height:2px;
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.16) 12%,
      rgba(255,255,255,.16) 88%,transparent)}
  .clock .cbar::before,.clock .cbar::after{content:'';position:absolute;top:-4px;
    width:1px;height:10px;background:rgba(255,255,255,.26)}
  .clock .cbar::before{left:0} .clock .cbar::after{right:0}
  .clock .cbar i{display:block;height:100%;background:var(--c);border-radius:2px;
    transform:scaleX(var(--p));transform-origin:50% 50%;
    box-shadow:0 0 12px var(--c),0 0 3px var(--c);
    transition:transform .28s linear,background .3s,box-shadow .3s}

  /* one soft pulse as each second lands, so the clock reads as running even
     when nobody is looking straight at it */
  .clock.tick .cbar i{animation:ctick .55s ease-out}
  @keyframes ctick{0%{filter:brightness(1.75)}100%{filter:brightness(1)}}

  .clock.warn{--c:#ffd05c}
  .clock.warn .ct{color:#ffe9a8}
  .clock.crit{--c:#ff5a72}
  .clock.crit .ct{color:#ffd2d8;animation:cbeat 1s ease-out infinite}
  @keyframes cbeat{0%{transform:scale(1.07)}30%{transform:scale(1)}100%{transform:scale(1)}}

  /* overtime: the bar has nothing left to count, so it becomes a scanner */
  .clock.sudden{--c:#ff5a72}
  .clock.sudden .ct{font-family:'Saira Condensed',sans-serif;font-weight:800;
    font-size:19px;letter-spacing:.26em;color:#ff8f9e}
  .clock.sudden .cbar i{transform:none;
    background:linear-gradient(90deg,transparent,var(--c),transparent);
    animation:cscan 1.6s linear infinite}
  @keyframes cscan{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}

  @media (max-height:560px),(max-width:820px){
    .clock{top:9px;gap:5px}
    .clock .ct{font-size:22px}
    .clock .cbar{width:140px}
    .clock.sudden .ct{font-size:14px}
  }
  body.touch .clock{top:8px}
  @media (prefers-reduced-motion:reduce){
    .clock .ct,.clock .cbar i{animation:none!important}
  }

/* team score bar: the only number that matters in a 4v4, so it sits dead
   centre under the clock where both sides can read it without looking away */
  .teamBar{position:fixed;top:92px;left:50%;transform:translateX(-50%);
    display:flex;align-items:center;gap:10px;padding:5px 12px;border-radius:12px;
    font-family:'JetBrains Mono',monospace;font-weight:700}
  .teamBar .side{display:flex;align-items:center;gap:7px;font-size:19px;line-height:1}
  .teamBar .tn{font-family:'Saira Condensed',sans-serif;font-size:9px;letter-spacing:.18em;
    color:var(--dim)}
  .teamBar .blue b{color:#5ce9ff}
  .teamBar .red b{color:#ff5a72}
  .teamBar .split{position:relative;width:86px;height:4px;border-radius:3px;
    background:linear-gradient(90deg,rgba(92,233,255,.28),rgba(255,90,114,.28));overflow:hidden}
  .teamBar .split i{position:absolute;inset:0 auto 0 0;width:50%;
    background:#5ce9ff;transition:width .3s ease}
  @media (max-height:560px),(max-width:820px){
    .teamBar{top:82px;padding:3px 9px;gap:7px}
    .teamBar .side{font-size:16px}
    .teamBar .split{width:64px}
  }
  body.touch .teamBar{top:74px}
  /* our own row on the board, and everyone else's, tinted by side */
  .brow.tb .nm{color:#5ce9ff}
  .brow.tr .nm{color:#ff5a72}

/* ============================================================================
   START COUNTDOWN

   The fairness fix, 2026-08-18. The deploy card used to stay up until the match
   was live, and it lifted on each device's own schedule — a fast phone was
   already playing while a slow one still had a briefing on screen, which was
   two or three free seconds of shooting people who could not see yet.

   Now the card lifts the moment the room is FULL, so everyone is looking at the
   loaded arena with all eight fighters standing on their spawns, and the last
   seconds are counted here instead. The clock is the server's — the same number
   on every screen — and the server refuses input until it hits zero, so the
   countdown is not merely a picture of a fair start, it is the fair start.
   ========================================================================== */
.gostart{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:2px;pointer-events:none;z-index:40;
  background:radial-gradient(60% 70% at 50% 50%,rgba(5,9,20,.52),rgba(5,9,20,.14) 70%,transparent)}
.gostart.hide{display:none}

/* two counter-rotating rings, so the pause reads as the game holding its breath
   rather than as the game having frozen */
.gsRing{position:absolute;width:min(38vh,220px);height:min(38vh,220px)}
.gsRing i{position:absolute;inset:0;border-radius:50%;border:1px solid transparent}
.gsRing i:first-child{border-top-color:rgba(92,233,255,.55);
  border-right-color:rgba(92,233,255,.18);animation:gsSpin 2.6s linear infinite}
.gsRing i:last-child{inset:9%;border-bottom-color:rgba(255,170,60,.5);
  border-left-color:rgba(255,170,60,.16);animation:gsSpin 3.4s linear infinite reverse}
@keyframes gsSpin{to{transform:rotate(360deg)}}

.gsNum{font-family:'Saira Condensed',sans-serif;font-weight:900;line-height:.9;
  font-size:min(30vh,190px);font-variant-numeric:tabular-nums;color:#fff;
  text-shadow:0 0 30px rgba(92,233,255,.8),0 0 90px rgba(92,233,255,.4),
              0 6px 30px rgba(0,0,0,.7);
  animation:gsTick .92s cubic-bezier(.16,1,.3,1)}
@keyframes gsTick{
  0%{transform:scale(2.1);opacity:0;filter:blur(6px)}
  20%{transform:scale(1);opacity:1;filter:blur(0)}
  72%{opacity:1}
  100%{transform:scale(.82);opacity:.12}}

.gsSub{font-family:'Saira Condensed',sans-serif;font-size:clamp(10px,2.4vh,14px);
  letter-spacing:.32em;font-weight:800;color:var(--f2);
  margin-top:clamp(4px,2vh,14px);
  text-shadow:0 2px 14px rgba(0,0,0,.9),0 0 18px rgba(0,0,0,.7)}

/* FIGHT takes the same slot, wider and warmer, and does not fade out under
   itself the way a digit does */
.gostart.go{background:radial-gradient(60% 70% at 50% 50%,rgba(5,9,20,.34),transparent 72%)}
.gostart.go .gsNum{font-size:min(17vh,110px);letter-spacing:.14em;
  background:var(--fireGrad);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 26px rgba(255,150,50,.65));
  animation:gsGo .55s cubic-bezier(.16,1,.3,1) forwards}
.gostart.go .gsRing,.gostart.go .gsSub{opacity:0;transition:opacity .3s}
@keyframes gsGo{0%{transform:scale(.55);opacity:0}
  40%{transform:scale(1.1);opacity:1}100%{transform:scale(1);opacity:1}}

@media (prefers-reduced-motion:reduce){
  .gsRing i,.gsNum{animation:none}
  .gostart.go .gsNum{animation:none;opacity:1}}

/* ============================================================================
   CONNECTION LOST

   The socket can go at any moment on a phone — a lift, a handover from wifi to
   mobile data, a doze. What used to happen then was nothing at all: the arena
   kept drawing the fighters exactly where they were last seen, the player kept
   running around among them, and there was no way to tell a dead connection
   from a quiet moment. This is that moment, said out loud.
   ========================================================================== */
.lost{position:fixed;inset:0;z-index:9000;display:flex;align-items:center;
  justify-content:center;padding:20px;
  background:radial-gradient(70% 90% at 50% 40%,rgba(8,12,24,.86),rgba(4,6,13,.96));
  backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px)}
.lost.hide{display:none}
.lostCard{width:min(420px,94vw);text-align:center;
  padding:clamp(16px,4vh,26px) clamp(16px,4vw,26px);border-radius:18px;
  background:linear-gradient(180deg,rgba(17,27,50,.97),rgba(9,14,27,.98));
  border:1px solid rgba(255,90,114,.28);
  box-shadow:0 30px 90px -20px rgba(0,0,0,.85),inset 0 1px 0 rgba(255,255,255,.05)}
.lostIcon{color:var(--red);opacity:.9;margin-bottom:6px}
.lostIcon svg{width:clamp(34px,8vh,46px);height:clamp(34px,8vh,46px)}
.lostCard h2{margin:0 0 6px;font-family:'Saira Condensed',sans-serif;font-weight:900;
  font-size:clamp(20px,5vh,30px);letter-spacing:.06em;color:#ff8fa1}
.lostCard p{margin:0 0 clamp(10px,2.4vh,16px);font-size:clamp(10.5px,2.2vh,12.5px);
  line-height:1.6;color:var(--dim)}
.lostBtns{display:grid;grid-template-columns:1.5fr 1fr;gap:8px}

/* A blip, mid-match. Small, low, and out of the way of the fight — the seat is
   held for five seconds and most drops are repaired before this finishes its
   first pulse, so it must not read as a failure. */
.reconn{position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(14px + env(safe-area-inset-bottom));z-index:8500;
  display:flex;align-items:center;gap:9px;padding:7px 14px;border-radius:99px;
  background:rgba(9,14,27,.88);border:1px solid rgba(255,196,90,.35);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  font-family:'Saira Condensed',sans-serif;font-size:11px;letter-spacing:.2em;
  font-weight:800;color:var(--gold);pointer-events:none}
.reconn.hide{display:none}
.reconn i{width:9px;height:9px;border-radius:50%;background:var(--gold);
  animation:reconnPulse 1s ease-in-out infinite}
@keyframes reconnPulse{0%,100%{opacity:.25;transform:scale(.7)}50%{opacity:1;transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.reconn i{animation:none;opacity:.8}}
