/* ============================================================
   COLDWATER TERMINAL — field console UI
   Single visual world by intent: a cold industrial dusk HUD.

   P5 (2026-09-29): STENCIL CARGO, the language Peter picked from
   mock-ui.html. It lands at the token layer: the display face is
   the local Kenney Future Narrow (the whole UI's headers, nav and
   labels inherit it through --disp), the amber is the mock's, and
   the masthead carries the hazard stripe. Oswald remains in the
   fallback stack only until every screen is verified under the
   new face.
   ============================================================ */
@font-face{
  font-family:"KenneyFutureNarrow";
  src:url("assets_src/ui/fonts/KenneyFutureNarrow.ttf") format("truetype");
}
@font-face{
  font-family:"KenneyFuture";
  src:url("assets_src/ui/fonts/KenneyFuture.ttf") format("truetype");
}
:root{
  --void:#0a0c0d;
  --steel:#14181a;
  --steel-2:#1b2124;
  --fog:#262d30;
  --fog-2:#384347;
  --bone:#d8dcd8;
  --bone-dim:#8b9491;
  --amber:#e0a51e;
  --amber-deep:#9a6f12;
  --red:#e0483a;
  --cold:#6fb3c4;
  --cold-deep:#2f6b7a;
  --good:#7fb069;
  --shadow:0 18px 44px rgba(0,0,0,.6);
  --disp:"KenneyFutureNarrow","Oswald","Arial Narrow",system-ui,sans-serif;
  --body:"IBM Plex Sans",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
}*{box-sizing:border-box}html,
body{height:100%}body{
  margin:0; background:var(--void); color:var(--bone);
  font-family:var(--body); font-size:14px; overflow:hidden;
  -webkit-font-smoothing:antialiased;
}button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}:focus-visible{outline:2px solid var(--amber);outline-offset:2px}.off{display:none!important}.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}.lbl{
  font-family:var(--disp);font-weight:500;font-size:10px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--bone-dim);
}.dim{color:var(--bone-dim)}#app{position:fixed;inset:0}#scene{position:absolute;inset:0}#scene canvas{display:block;width:100%;height:100%}/* ==================== HUD ==================== */
#hud{position:absolute;inset:0;pointer-events:none;user-select:none}/* --- crosshair --- */
#xhair{position:absolute;left:50%;top:50%;width:0;height:0}#xhair i{position:absolute;background:rgba(232,238,235,.85);display:block}#xhair .xt,
#xhair .xb{width:2px;height:7px;left:-1px}#xhair .xl,
#xhair .xr{height:2px;width:7px;top:-1px}#xhair .xt{bottom:var(--sp,8px)}#xhair .xb{top:var(--sp,8px)}#xhair .xl{right:var(--sp,8px)}#xhair .xr{left:var(--sp,8px)}#xhair .xd{width:2px;height:2px;left:-1px;top:-1px;background:rgba(232,238,235,.5)}#hitmark{
  position:absolute;left:50%;top:50%;width:34px;height:34px;
  margin:-17px 0 0 -17px;opacity:0;
}#hitmark svg{width:100%;height:100%;fill:none;stroke:#fff;stroke-width:2.4;stroke-linecap:round}#hitmark.on{animation:hm .26s ease-out}#hitmark.kill svg{stroke:var(--red)}@keyframes hm{0%{opacity:1;transform:scale(.7)}100%{opacity:0;transform:scale(1.25)}}#vig{
  position:absolute;inset:0;opacity:0;transition:opacity .35s;
  background:radial-gradient(ellipse at center,transparent 38%,rgba(120,10,6,.72) 100%);
}#suppress{
  position:absolute;inset:0;opacity:0;transition:opacity .12s;
  background:radial-gradient(ellipse at center,transparent 52%,rgba(0,0,0,.85) 100%);
}/* --- top bar --- */
#topbar{
  position:absolute;top:0;left:0;right:0;height:56px;
  display:flex;align-items:center;justify-content:space-between;
  padding:0 20px;gap:24px;
  background:linear-gradient(180deg,rgba(10,12,13,.82),transparent);
}.tb-block{display:flex;flex-direction:column;gap:2px;min-width:0;max-width:33%}.tb-right{align-items:flex-end}#objText{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:38vw}#objProg{font-size:11px}#clockText.big{font-size:19px;font-weight:600;letter-spacing:.02em}#clockText.urgent{color:var(--red)}/* Pinned to the centre of the screen rather than placed by the top bar's
   space-between. The centre tick reads as the heading you are facing,
so it
   has to sit directly over the crosshair — and letting flex position it meant
   a long contract line on the left shoved the compass ~90px right of where
   the player was actually aiming. */
#compass{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(430px,36vw);height:38px;overflow:hidden;
  border-left:1px solid var(--fog);border-right:1px solid var(--fog);
  mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);
}#compassStrip{position:absolute;top:0;height:100%;white-space:nowrap;will-change:transform}#compassStrip span{
  position:absolute;top:4px;transform:translateX(-50%);
  font-family:var(--disp);font-size:11px;letter-spacing:.1em;color:var(--bone-dim);
}#compassStrip span.card{color:var(--bone);font-weight:700;font-size:15px}#compassStrip span.north{color:var(--amber)}#bearingNum{
  position:absolute;left:50%;bottom:1px;transform:translateX(-50%);
  font-family:var(--disp);font-size:11px;letter-spacing:.18em;color:var(--bone-dim);
}#compassStrip b{position:absolute;top:2px;width:1px;height:6px;background:var(--fog-2)}#compassStrip i.poi{
  position:absolute;top:5px;width:0;height:0;transform:translateX(-50%);
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:6px solid var(--amber);
}#compassStrip i.poi.ex{border-top-color:var(--cold)}/* A posted position is intelligence,
not a live contact — so it is drawn
   hollow and dim,
and it disappears the moment the roster goes stale. */
#compassStrip i.poi.roster{
  border-top-color:transparent;border-bottom:6px solid var(--amber-deep);
  border-top:0;opacity:.62;top:7px;
}#compassMark{
  position:absolute;left:50%;top:0;width:1px;height:100%;
  background:var(--amber);transform:translateX(-50%);
}/* --- alerts --- */
#alerts{
  position:absolute;top:70px;left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:6px;
}.alert{
  font-family:var(--disp);font-size:13px;letter-spacing:.14em;text-transform:uppercase;
  padding:5px 14px;background:rgba(10,12,13,.78);border-left:2px solid var(--amber);
  animation:alertIn .2s ease-out;
}.alert.bad{border-left-color:var(--red);color:#ffb9b3}.alert.good{border-left-color:var(--cold);color:#cfeaf1}@keyframes alertIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}/* --- bottom-left: body + vitals --- */
#bl{position:absolute;left:20px;bottom:20px;display:flex;gap:14px;align-items:flex-end}#bodyRig{position:relative;width:54px;height:86px}#bodyRig .z{position:absolute;background:var(--fog-2);transition:background .2s}.z-head{left:19px;top:0;width:16px;height:15px;border-radius:7px 7px 3px 3px}.z-thorax{left:14px;top:18px;width:26px;height:33px}.z-larm{left:4px;top:19px;width:8px;height:29px}.z-rarm{left:42px;top:19px;width:8px;height:29px}.z-lleg{left:15px;top:54px;width:11px;height:32px}.z-rleg{left:28px;top:54px;width:11px;height:32px}.z.blk{background:var(--red)!important}.z.hit{animation:zhit .3s}@keyframes zhit{0%{filter:brightness(3)}100%{filter:none}}/* 190 was narrower than the medRow it contains (196),
and four medical
   chips need about 200 -- so the DEFAULT buyable loadout (bandage,
tourniquet,
trauma kit,
painkillers) wrapped onto a second line by roughly four pixels.
   224 fits four chips on one line even when a count reaches double digits,
which widens them to 53,
and drops the carry-everything case from three
   lines to two. Measured,
not guessed. */
#vitals{display:flex;flex-direction:column;gap:6px;width:224px}.bar-row{display:flex;align-items:center;gap:8px}.bar-row .lbl{width:50px;flex:none}/* 34px fitted Oswald; the stencil PLATE ran 15px over (t-layout, every width) *//* 40px fits the wind readout ("38") and not the plate one ("III · 62%"),
which broke across two lines -- the armour number,
in a firefight,
is the
   worst place in the game for a value to arrive in two pieces. The vitals
   column has the room now that it is 224 wide. */
.bar-row .mono{width:62px;text-align:right;font-size:11px;white-space:nowrap}.track{flex:1;height:5px;background:rgba(56,67,71,.55);overflow:hidden}#plateFill{height:100%;width:100%;background:var(--cold);transition:width .18s}#stamFill{height:100%;width:100%;background:var(--bone-dim);transition:width .1s}#stamFill.low{background:var(--amber)}#statusRow{display:flex;gap:6px;min-height:18px;flex-wrap:wrap}.chip{
  font-family:var(--disp);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  padding:2px 7px;border:1px solid var(--fog-2);color:var(--bone-dim);
}.chip.bleed{border-color:var(--red);color:#ff9a90;animation:pulse 1s infinite}.chip.on{border-color:var(--amber);color:var(--amber)}@keyframes pulse{50%{opacity:.4}}/* --- bottom-right: weapon --- */
#br{position:absolute;right:20px;bottom:20px;text-align:right;display:flex;flex-direction:column;gap:2px}#wpnName{font-family:var(--disp);font-size:15px;letter-spacing:.14em;text-transform:uppercase}#ammoRow{display:flex;align-items:baseline;justify-content:flex-end;gap:7px}#ammoCur{font-size:32px;font-weight:600;line-height:1}#ammoCur.dry{color:var(--red)}#ammoRes{font-size:15px;color:var(--bone-dim)}#ammoRes::before{content:"+ "}#wpnMeta{font-family:var(--disp);font-size:11px;letter-spacing:.14em;color:var(--bone-dim)}#wpnMeta .sep{opacity:.4;margin:0 5px}#loadRow{display:flex;justify-content:flex-end;align-items:baseline;gap:5px;font-size:11px;margin-top:3px}#loadRow .unit{color:var(--bone-dim);font-size:10px;margin-right:5px}#loadRow.over{color:var(--red)}/* --- interaction prompt --- */
#prompt{
  position:absolute;left:50%;top:56%;transform:translateX(-50%);
  font-family:var(--disp);font-size:13px;letter-spacing:.12em;text-transform:uppercase;
  background:rgba(10,12,13,.8);padding:6px 14px;border:1px solid var(--fog-2);
}#prompt kbd{
  font-family:var(--mono);font-size:11px;background:var(--bone);color:var(--void);
  padding:1px 5px;margin-right:8px;font-weight:600;
}/* --- extract --- */
#extractBar{
  position:absolute;left:50%;bottom:26%;transform:translateX(-50%);width:280px;text-align:center;
}#extractBar .track{height:3px;margin-top:7px}#extractFill{height:100%;width:0;background:var(--cold)}/* --- loot / inventory panels --- */
#lootPanel,
#invPanel{
  position:absolute;pointer-events:auto;background:rgba(14,18,20,.96);
  border:1px solid var(--fog-2);box-shadow:var(--shadow);
}#lootPanel{left:50%;top:50%;transform:translate(-50%,-50%);width:min(860px,94vw)}#invPanel{left:50%;top:50%;transform:translate(-50%,-50%);width:min(940px,94vw)}.panel-head{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:11px 16px;border-bottom:1px solid var(--fog);
}.panel-head h3{margin:0;font-family:var(--disp);font-size:14px;letter-spacing:.18em;text-transform:uppercase;font-weight:500}.panel-body{max-height:min(62vh,520px);overflow-y:auto}.panel-foot{display:flex;gap:10px;padding:11px 16px;border-top:1px solid var(--fog);align-items:center}.item{
  display:grid;grid-template-columns:1fr auto auto auto;gap:14px;align-items:center;
  padding:8px 16px;border-bottom:1px solid rgba(38,45,48,.6);width:100%;text-align:left;
}.item:last-child{border-bottom:none}.item:hover{background:rgba(240,160,60,.09)}.item.no:hover{background:rgba(224,72,58,.09)}.item-name{font-size:13px;display:flex;align-items:center;gap:8px;min-width:0}.item-name em{
  font-family:var(--disp);font-style:normal;font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;padding:1px 5px;border:1px solid var(--fog-2);color:var(--bone-dim);flex:none;
}.item-name em.key{border-color:var(--amber);color:var(--amber)}.item-name em.task{border-color:var(--cold);color:var(--cold)}.item-val{font-family:var(--mono);font-size:12px;color:var(--amber);text-align:right;min-width:62px}.item-w,
.item-v{font-family:var(--mono);font-size:11px;color:var(--bone-dim);min-width:48px;text-align:right}.empty{padding:26px 16px;text-align:center;color:var(--bone-dim);font-size:13px}.btn{
  font-family:var(--disp);font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  padding:8px 16px;border:1px solid var(--fog-2);color:var(--bone);
  transition:background .12s,border-color .12s,color .12s;
}.btn:hover{border-color:var(--amber);color:var(--amber);background:rgba(240,160,60,.08)}.btn.primary{background:var(--amber);border-color:var(--amber);color:#160d02;font-weight:600}.btn.primary:hover{background:#ffb457;color:#160d02}.btn:disabled{opacity:.38;cursor:not-allowed}.btn:disabled:hover{border-color:var(--fog-2);color:var(--bone);background:none}
/* Repeated actions in a list stay quiet. A solid amber fill is the one DEPLOY
   that ends the screen;three of them stacked down a pane reads as a pricing
   page,
so an affordable skill gets an amber outline and fills only on hover. */
.btn.sm{font-size:10.5px;letter-spacing:.12em;padding:6px 12px}.sk-train{margin-top:8px;align-self:flex-start;width:fit-content}.btn.go{border-color:var(--amber);color:var(--amber);background:rgba(240,160,60,.07)}.btn.go:hover{background:var(--amber);color:#160d02;border-color:var(--amber)}.btn.ghost{border-color:transparent;color:var(--bone-dim)}.btn.ghost:hover{color:var(--bone);border-color:var(--fog-2);background:none}/* --- toast --- */
#toast{position:absolute;left:50%;bottom:84px;transform:translateX(-50%);display:flex;flex-direction:column;gap:5px;align-items:center;pointer-events:none}.toast{
  font-size:12px;background:rgba(10,12,13,.9);border:1px solid var(--fog-2);
  padding:6px 13px;animation:tIn .2s;
}.toast b{color:var(--amber);font-weight:500}.toast.cold b{color:var(--cold)}@keyframes tIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}/* ==================== META SCREENS ==================== */
#ui{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;background:var(--void)}#ui.off{display:none}.screen{min-height:100%;display:flex;flex-direction:column}/* backdrop: cold dusk gradient + faint grid,
drawn once */
.screen::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(900px 520px at 78% -8%,rgba(240,160,60,.13),transparent 70%),
    radial-gradient(700px 480px at 8% 104%,rgba(111,179,196,.09),transparent 70%),
    linear-gradient(180deg,#0a0c0d,#0d1113 60%,#0a0c0d);
}.screen>*{position:relative;z-index:1}/* --- masthead --- */
/* A title bar,
not a document masthead: half the height,
a hard bottom edge
   and a stencilled feel,
so the screen belongs to the operator and the
   controls rather than to a heading. */
.mast{
  display:flex;align-items:center;justify-content:space-between;gap:28px;
  padding:11px 26px 12px;flex-wrap:wrap;
  background:linear-gradient(180deg,#1c2327 0%,#12171a 100%);
  border-bottom:5px solid transparent;
  border-image:repeating-linear-gradient(45deg,var(--amber) 0 12px,#14130d 12px 24px) 5;
  box-shadow:0 2px 14px rgba(0,0,0,.6);
}.mast-id{display:flex;flex-direction:column;gap:1px}.mast-id h1{
  margin:0;font-family:var(--disp);font-weight:500;font-size:clamp(17px,1.9vw,23px);
  letter-spacing:.26em;text-transform:uppercase;line-height:1;
}.mast-id h1 b{font-weight:600;color:var(--amber)}.mast-id .sub{font-family:var(--mono);font-size:11px;color:var(--bone-dim);letter-spacing:.06em}.mast-stats{display:flex;gap:30px;align-items:flex-end}.stat{display:flex;flex-direction:column;gap:2px;align-items:flex-end}.stat .v{font-family:var(--mono);font-size:19px;font-weight:600}
/* ---- colour classes ----
   These names state an intent -- amber is cash, cold is intel, red is what you
   lose -- and until now each one only worked where somebody had written a
   container rule for it: .stat .v.amber, .tbl td.n.amber, .kfin .v.amber,
   .lobby .kitfoot .amber, and so on. Anywhere else the markup said "amber" and
   the text came out bone, silently.

   Eight elements were in that state, found by listing everything carrying one
   of these classes and comparing its computed colour against the token the
   class is named after. Two of them were the contract payout on the lobby --
   the reward line, the most-read number on the screen -- where the cash and
   the intel were both plain bone. The rest were on stash, traders and skills.

   One definition each. The scoped rules above and below still win where they
   exist, since they are more specific;this only reaches the elements that had
   nothing at all. */
.amber{color:var(--amber)}.cold{color:var(--cold)}.red{color:var(--red)}.stat .v.amber{color:var(--amber)}.stat .v.cold{color:var(--cold)}/* --- three-rail progression strip: the design thesis --- */
.rails{
  display:grid;grid-template-columns:repeat(3,1fr);border-bottom:1px solid #000;
  background:linear-gradient(180deg,#1b2225,#141a1c);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}.rail{padding:9px 20px 11px;border-right:1px solid rgba(0,0,0,.6);display:flex;flex-direction:column;gap:5px}.rail:last-child{border-right:none}/* .rail-p is gone: the tier explanations are tooltips now,
so the strip
   stays a readout instead of three paragraphs of design notes */
.rail.perm{border-top:2px solid var(--cold)}.rail.perm h4{color:var(--cold)}.rail.dur{border-top:2px solid var(--amber)}.rail.dur h4{color:var(--amber)}.rail.vol{border-top:2px solid var(--red)}.rail.vol h4{color:var(--red)}.xpTrack{height:4px;background:rgba(56,67,71,.5);overflow:hidden}.xpTrack i{display:block;height:100%;background:var(--cold)}/* --- main grid ---
   Three columns: what you can do,
who you are,
what you are looking at. The
   operator bay sits in the middle at every screen — a lobby that never shows
   the character reads as a settings page,
whatever the colours are. */
.work{
  flex:1;display:grid;grid-template-columns:208px minmax(230px,300px) 1fr;min-height:0;
  background:
    linear-gradient(180deg, rgba(0,0,0,.34), transparent 120px),
    var(--steel);
}.nav{
  padding:14px 0;display:flex;flex-direction:column;gap:2px;
  /* must NOT fade to --void: that is the page colour, so the column
     dissolves into the background and the whole UI reads as a small card
     floating in black rather than a panel that runs the height of the screen */
  background:linear-gradient(180deg, #1d2427 0%, #161c1e 100%);
  border-right:1px solid #000;
  box-shadow:inset -1px 0 0 rgba(255,255,255,.05);
}.nav button{
  position:relative;text-align:left;padding:15px 18px 15px 20px;
  font-family:var(--disp);font-size:15px;letter-spacing:.17em;text-transform:uppercase;
  color:var(--bone-dim);border-left:3px solid transparent;transition:none;
}.nav button::after{
  content:"";position:absolute;left:20px;right:18px;bottom:0;height:1px;
  background:rgba(255,255,255,.045);
}.nav button:hover{color:var(--bone);background:rgba(255,255,255,.045)}.nav button.sel{
  color:var(--void);border-left-color:var(--amber);
  background:linear-gradient(90deg, var(--amber), var(--amber-deep));
  font-weight:600;
}.nav button.sel .n{color:var(--void);opacity:.72}.nav button .n{font-family:var(--mono);font-size:10px;opacity:.45;margin-right:10px}.nav .deploy{margin:0 14px;padding:12px 0}/* --- operator bay --- */
.bay{
  /* Sticky and viewport-tall. As a plain grid item it stretched to the pane's
     full scroll height — the canvas came out 1627px tall and framed the
     operator somewhere off-screen. He should also stay put while the pane
     scrolls, which is what a lobby does anyway. */
  position:sticky;top:0;align-self:start;
  height:calc(100vh - 136px);max-height:860px;
  display:flex;flex-direction:column;min-width:0;
  border-right:1px solid #000;
  background:
    radial-gradient(ellipse 72% 58% at 50% 40%, rgba(111,179,196,.16), transparent 72%),
    linear-gradient(180deg, #161d20 0%, #101618 100%);
  box-shadow:inset 0 0 110px rgba(0,0,0,.72);
}/* floor line under the figure,
so it is standing somewhere */
.bay::after{
  content:"";position:absolute;left:12%;right:12%;bottom:86px;height:1px;
  background:linear-gradient(90deg,transparent,rgba(111,179,196,.30),transparent);
}.bay-view{flex:1;min-height:0;position:relative;z-index:1}.bay-view canvas{display:block;width:100%;height:100%}/* Sized for a screen you sit back from,
not a document you lean into. The
   old values were body-copy scale and made the lobby read as a web page. */
/* #14181a against a #0a0c0d page is a 4-value difference: a filled panel and
   empty background look identical,
which is why the lobby read as a small
   card floating in black. The working surface has to be a surface. */
.pane{
  padding:30px 40px 52px;min-width:0;
  background:
    radial-gradient(ellipse 120% 80% at 50% 0%, rgba(111,179,196,.045), transparent 60%),
    linear-gradient(180deg, #212a2e 0%, #192023 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}.pane h2{
  margin:0 0 6px;font-family:var(--disp);font-weight:500;font-size:27px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--bone);
}/* The copy is worth keeping,
the presentation was not: a 70ch measure at
   14px with 1.65 leading is an article. Same words,
delivered as a briefing
   line clipped to the top of the screen. */
.pane .intro{
  position:relative;margin:0 0 20px;padding:7px 12px 7px 13px;
  color:var(--bone-dim);font-family:var(--mono);font-size:11.5px;
  line-height:1.5;max-width:86ch;letter-spacing:.01em;
  background:linear-gradient(90deg,rgba(111,179,196,.07),transparent 72%);
  border-left:2px solid var(--cold-deep);
}.sec{margin-top:24px}/* A section header with a tick mark and a rule that fades out,
rather than a
   full-width underline — the underline is what makes a screen read as a page
   of headings and body copy. */
.sec>h3{
  position:relative;margin:0 0 12px;padding:0 0 8px 12px;
  font-family:var(--disp);font-size:11.5px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--bone);
  border-bottom:1px solid transparent;
  background-image:linear-gradient(90deg,var(--fog-2),rgba(56,67,71,0) 78%);
  background-size:100% 1px;background-position:0 100%;background-repeat:no-repeat;
}.sec>h3::before{
  content:"";position:absolute;left:0;top:1px;width:4px;height:11px;
  background:var(--amber-deep);
}/* --- selectable cards (weapons,
contracts,
gear) --- */
.grid{display:grid;gap:10px}.g2{grid-template-columns:repeat(auto-fill,minmax(270px,1fr))}.g3{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}/* .card carries 30 places across every pane,
so it is the single highest
   leverage surface in the lobby. It was a 1px outline on a barely-there fill —
   which is what a documentation site does. Now it is a physical plate: lit
   top edge,
dark base,
a shadow it casts,
and a left spine that goes amber
   when chosen. */
.card{
  position:relative;text-align:left;padding:13px 15px 14px;
  border:1px solid #0b0e0f;border-left:3px solid #2f3a3f;
  background:linear-gradient(180deg,#232c30 0%,#1a2225 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055), 0 2px 6px rgba(0,0,0,.4);
  display:flex;flex-direction:column;gap:7px;transition:none;
}.card:hover{
  background:linear-gradient(180deg,#2b363a 0%,#212a2e 100%);
  border-left-color:var(--cold-deep);
}.card.sel{
  border-left-color:var(--amber);
  background:linear-gradient(180deg,rgba(240,160,60,.17) 0%,rgba(240,160,60,.05) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 2px 10px rgba(240,160,60,.13);
}.card.locked{opacity:.4;cursor:not-allowed;box-shadow:none}.card.locked:hover{
  border-left-color:#2f3a3f;
  background:linear-gradient(180deg,#232c30 0%,#1a2225 100%);
}.card-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px}.card-top .nm{font-family:var(--disp);font-size:14px;letter-spacing:.1em;text-transform:uppercase}.card-top .px{font-family:var(--mono);font-size:12px;color:var(--amber)}.card-top .px.owned{color:var(--bone-dim)}.card p{margin:0;font-size:12px;color:var(--bone-dim);line-height:1.5}.specs{display:flex;flex-wrap:wrap;gap:4px 12px;font-family:var(--mono);font-size:11px;color:var(--bone-dim)}.specs b{color:var(--bone);font-weight:500}.locknote{font-family:var(--disp);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--amber)}/* stat meters inside cards */
.meters{display:flex;flex-direction:column;gap:4px;margin-top:2px}.meter{display:grid;grid-template-columns:76px 1fr 30px;gap:8px;align-items:center}/* 52px fitted Oswald; the stencil face is wider and t-layout caught
   HANDLING 19px over the column across every loadout permutation --
   the one-window eye sweep missed it. 76px fits the longest label (HANDLING, 2px shy at 72) with
   the tracking eased. */.meter span:first-child{font-family:var(--mono);font-size:9px;letter-spacing:.04em;text-transform:uppercase;color:var(--bone-dim)}.meter i{height:3px;background:rgba(56,67,71,.6);display:block;position:relative}.meter i::after{content:"";position:absolute;left:0;top:0;height:100%;width:var(--p,0%);background:var(--bone-dim)}.card.sel .meter i::after{background:var(--amber)}.meter u{font-family:var(--mono);font-size:10px;text-decoration:none;color:var(--bone-dim);text-align:right}/* contract cards */
.contract{border-left:2px solid var(--cold)}.contract.sel{border-left-color:var(--cold);border-color:var(--cold);background:rgba(111,179,196,.08)}.contract .payline{display:flex;gap:18px;font-family:var(--mono);font-size:12px;margin-top:3px}.contract .payline .i{color:var(--cold)}.contract .payline .c{color:var(--amber)}/* loadout summary bar */
.sumbar{
  display:flex;gap:26px;flex-wrap:wrap;align-items:center;
  padding:14px 18px;border:1px solid var(--fog);background:rgba(20,24,26,.75);margin-top:22px;
}.sumbar .g{display:flex;flex-direction:column;gap:2px}.sumbar .g .v{font-family:var(--mono);font-size:15px}.sumbar .g .v.warn{color:var(--red)}/* Auto-arrange and Sell-all were landing on the same pixel — one had picked
   up position:absolute and printed straight through the other. Laid out
   explicitly as a row,
and pinned to static so nothing can lift them out of
   flow again. */
.sumbar .risk{
  margin-left:auto;display:flex;flex-direction:row;align-items:center;
  gap:9px;flex-wrap:wrap;justify-content:flex-end;
}.sumbar .risk>.btn{position:static;white-space:nowrap}/* stash table */
.tbl{width:100%;border-collapse:collapse;font-size:13px}.tbl th{
  text-align:left;font-family:var(--disp);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--bone-dim);font-weight:500;padding:8px 10px;border-bottom:1px solid var(--fog);
}.tbl td{padding:8px 10px;border-bottom:1px solid rgba(38,45,48,.55)}.tbl td.n{font-family:var(--mono);text-align:right;font-variant-numeric:tabular-nums}.tbl td.n.amber{color:var(--amber)}.tbl tr:hover td{background:rgba(255,255,255,.025)}/* ==================== AFTER-ACTION ==================== */
.aar{max-width:min(940px,100%);margin:0 auto;padding:24px 30px 60px;width:100%}/* A verdict,
not a hero headline: boxed against a colour bar and sized to sit
   on top of the ledger instead of taking the fold to itself. */
.aar-head{display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;
  border-left:3px solid currentColor;padding:9px 0 9px 15px;margin-bottom:20px}.aar-head.ok{color:var(--cold)}.aar-head.ko{color:var(--red)}.aar-stamp{
  font-family:var(--disp);font-size:clamp(21px,2.9vw,31px);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;line-height:1;margin:0;color:inherit;
}.aar-sub{margin:0;color:var(--bone-dim);font-size:12px;max-width:54ch;line-height:1.55;flex:1 1 300px}.ledger{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--fog);border:1px solid var(--fog)}.led{background:var(--void);padding:18px 20px;display:flex;flex-direction:column;gap:12px}.led-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px}.led-h h4{margin:0;font-family:var(--disp);font-size:11px;letter-spacing:.18em;text-transform:uppercase}.led-h .fate{font-family:var(--mono);font-size:10px}.led.perm h4{color:var(--cold)}.led.perm .fate{color:var(--cold)}.led.dur h4{color:var(--amber)}.led.dur .fate{color:var(--amber)}.led.vol h4{color:var(--red)}.led.vol .fate{color:var(--red)}.led-total{font-family:var(--mono);font-size:26px;font-weight:600;line-height:1}.led-total.struck{color:var(--bone-dim);text-decoration:line-through;text-decoration-thickness:2px}.led-lines{display:flex;flex-direction:column;gap:5px;font-size:12px}.led-lines div{display:flex;justify-content:space-between;gap:12px;color:var(--bone-dim)}.led-lines div span:last-child{font-family:var(--mono);color:var(--bone)}.led-note{font-size:11px;color:var(--bone-dim);line-height:1.5;margin:0;padding-top:10px;border-top:1px solid var(--fog)}.levelup{
  margin-top:20px;padding:18px 22px;border:1px solid var(--cold);
  background:linear-gradient(90deg,rgba(111,179,196,.13),transparent);
  display:flex;gap:22px;align-items:center;flex-wrap:wrap;
}.levelup .big{font-family:var(--disp);font-size:22px;letter-spacing:.16em;text-transform:uppercase;color:var(--cold)}.levelup ul{margin:0;padding-left:18px;font-size:13px;display:flex;flex-direction:column;gap:3px}.aar-foot{display:flex;gap:12px;margin-top:30px;align-items:center;flex-wrap:wrap}/* ==================== BRIEFING / CONTROLS ==================== */
.brief{max-width:min(820px,100%);margin:0 auto;padding:52px 30px 60px;width:100%}.brief .kicker{font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--amber);margin:0 0 12px}.brief h1{
  margin:0 0 16px;font-family:var(--disp);font-weight:300;font-size:clamp(26px,4.4vw,50px);
  letter-spacing:.14em;text-transform:uppercase;line-height:1.05;text-wrap:balance;
}.brief h1 b{font-weight:600;color:var(--amber)}.brief .lede{font-size:15px;line-height:1.7;color:#b9c0bd;max-width:60ch;margin:0 0 30px}.keys{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:1px;background:var(--fog);border:1px solid var(--fog);margin-bottom:26px}.keys div{background:var(--void);padding:9px 13px;display:flex;gap:11px;align-items:center;font-size:12px}.keys kbd{
  font-family:var(--mono);font-size:10px;background:var(--steel-2);border:1px solid var(--fog-2);
  padding:2px 6px;color:var(--bone);min-width:26px;text-align:center;flex:none;
}.warnbox{
  border-left:2px solid var(--amber);padding:12px 16px;background:rgba(240,160,60,.06);
  font-size:13px;line-height:1.6;color:#c9cfcc;margin-bottom:26px;
}.warnbox b{color:var(--amber)}/* Narrow the bay before dropping it — the character is the thing that makes
   this read as a game,
so it is the last element to go,
not the first. */
@media (max-width:1240px){
  .work{grid-template-columns:190px minmax(190px,230px) 1fr}
  .nav button{font-size:13.5px;padding:13px 14px 13px 16px;letter-spacing:.13em}
  .pane{padding:26px 28px 44px}
}
/* Keep the operator on screen as long as there is any room for him. A narrow
   bay still reads as a game;a hidden one leaves a page of lists. */
@media (max-width:1000px){
  .work{grid-template-columns:156px minmax(150px,190px) 1fr}
  .nav button{font-size:12.5px;padding:12px 10px 12px 13px;letter-spacing:.1em}
  .nav button .n{margin-right:6px}
  .bay-plate{padding:9px 11px 11px}
  .bay-name{font-size:12px} .bay-sub,.bay-cost{font-size:9.5px}
  .pane{padding:22px 20px 40px}
}.bay is the only 3D on the screen,
so killing it
   kills the last thing that says this is a game and not a form. */
@media (max-width:700px){
  .work{grid-template-columns:52px 124px 1fr}
  .bay-plate{padding:7px 8px 9px}
  .bay-name{font-size:10.5px}
  .bay-sub,.bay-cost{font-size:8.5px}
}/* Below this there genuinely is no room left,
and the pane has to win. */
@media (max-width:520px){
  .work{grid-template-columns:52px 1fr}
  .bay{display:none}
}/* A horizontal tab strip is the single most website-like thing a game lobby
   can do,
so the rail stays vertical all the way down and only loses its
   labels — numbers and the accent bar still say where you are. */
@media (max-width:700px){
  .nav button{padding:14px 0;text-align:center;font-size:0;letter-spacing:0}
  .nav button .n{font-size:12px;margin:0;opacity:.9}
  .nav .deploy{margin:0 6px}
  .nav .deploy .btn{font-size:0;padding:12px 0}
  .nav .deploy .btn::after{content:"GO";font-size:12px;letter-spacing:.1em}
  .pane{padding:20px 16px 36px}
  .pane h2{font-size:21px}
}

/* The strip is compact enough to stay three-across well below the old 900px
   breakpoint;stacking it was costing three times the height for the same
   three numbers and pushing the game below the fold. */
@media (max-width:900px){
  /* The three tiers only mean anything read against each other, so they
     stay three-across and get denser instead of stacking. */
  .led{padding:13px 13px;gap:9px}
  .led-total{font-size:20px}
  .led-h{flex-direction:column;align-items:flex-start;gap:2px}
  .led-h h4{font-size:10px;letter-spacing:.13em}
  .led-h .fate{font-size:9px}
  .led-lines{font-size:10.5px;gap:4px}
  .led-lines div{gap:6px}
  .led-note{font-size:10px;padding-top:8px}
  .rail{padding:8px 12px 10px}
  .rail-head h4{font-size:10.5px;letter-spacing:.14em}
  .rail-head .risk{display:none}
  .rail-val b{font-size:15px}
}@media (max-width:620px){
  .rails{grid-template-columns:1fr}
  .ledger{grid-template-columns:1fr}
  .rail{border-right:none;border-bottom:1px solid rgba(0,0,0,.6)}
  .rail-head .risk{display:inline}
}@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ==================== LOADOUT CONSOLE ====================
   Kit strip pinned on top;categories,
options and detail side by side,
so gear is compared in place instead of by scrolling a wall of cards. */
.lo{display:flex;flex-direction:column;gap:0;border:1px solid var(--fog);background:rgba(16,20,22,.6)}/* --- kit totals bar --- */
/* Was a six-column grid of equipment slots with the totals spanning the end of
   it. The slots duplicated the nav below and are gone, so this is just the bar
   now and the column sizing that used to fight the widest weapon name with it
   is gone too. */
.lo-kit{border-bottom:1px solid var(--fog);background:rgba(20,24,26,.9)}.kfin{display:flex;gap:20px;padding:11px 16px;align-items:center;justify-content:flex-end;flex-wrap:wrap}.kfin>div{display:flex;flex-direction:column;gap:2px;align-items:flex-end}
/* This column is narrow and everything in it can break in the middle.
   Measured with white-space toggled off: the LABELS are the live offenders --
   "Rig weight" and "Funds after" each fall to two lines, 1.25 -> 2.5 line
   boxes. The values matter too because U.cash separates thousands with a
   space, so "₡414 352" splits into "₡414" and "352" and reads as two
   numbers;that one was visible before the armoury rack stopped padding this
   column out,
and nowrap keeps it from coming back at any width. Same failure
   the ledger rows already guard against,
different element. */
.kfin .v{font-family:var(--mono);font-size:14px;font-variant-numeric:tabular-nums;white-space:nowrap}.kfin .lbl{white-space:nowrap}.kfin .v.amber{color:var(--amber)}.kfin .v.warn{color:var(--red)}/* --- three columns --- */
/* slots need room for the fitted item and its stat,
not just a tab label */
.lo-body{display:grid;grid-template-columns:186px minmax(230px,1fr) minmax(265px,1.05fr);min-height:370px}/* --- equipment slots (paper doll) --- */
.lo-slots{
  display:flex;flex-direction:column;gap:3px;padding:7px;
  border-right:1px solid #000;background:linear-gradient(180deg,#1b2225,#151b1d);
}.lslot{
  position:relative;display:flex;flex-direction:column;gap:2px;
  text-align:left;padding:8px 10px 9px 12px;min-width:0;
  border:1px solid #0c0f10;border-left:3px solid #313d42;
  background:linear-gradient(180deg,#232c30,#1a2225);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}.lslot:hover{background:linear-gradient(180deg,#2b363a,#212a2e);border-left-color:var(--cold-deep)}.lslot.sel{
  border-left-color:var(--amber);
  background:linear-gradient(180deg,rgba(240,160,60,.20),rgba(240,160,60,.05));
}/* an empty slot should look empty — hatched,
not just labelled "None" */
.lslot.empty{
  background:
    repeating-linear-gradient(45deg,rgba(255,255,255,.028) 0 5px,transparent 5px 10px),
    linear-gradient(180deg,#1c2427,#161c1f);
  border-left-color:#2a3338;
}.ls-lbl{
  font-family:var(--disp);font-size:9.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--bone-dim);
}.ls-val{
  font-family:var(--disp);font-size:12.5px;letter-spacing:.06em;color:var(--bone);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;
}.lslot.sel .ls-val{color:var(--amber)}.lslot.empty .ls-val{color:var(--bone-dim);font-style:italic}.ls-note{font-family:var(--mono);font-size:9.5px;color:var(--bone-dim);opacity:.8}.lo-list{border-right:1px solid var(--fog);padding:8px 0;overflow-y:auto;max-height:440px}.lo-row{
  width:100%;display:grid;grid-template-columns:1fr auto;gap:2px 12px;
  padding:9px 14px;text-align:left;align-items:center;
  border-left:2px solid transparent;transition:background .1s;
}button.lo-row:hover{background:rgba(255,255,255,.04)}.lo-row.on{border-left-color:var(--amber);background:rgba(240,160,60,.08)}.lo-row.lk{opacity:.42;cursor:not-allowed}.lo-nm{font-family:var(--disp);font-size:13px;letter-spacing:.1em;text-transform:uppercase}.lo-st{grid-column:1;font-family:var(--mono);font-size:11px;color:var(--bone-dim)}.lo-px{
  grid-row:1/3;grid-column:2;font-family:var(--mono);font-size:11px;color:var(--amber);
  text-align:right;align-self:center;
}.lo-px.own{color:var(--bone-dim)}.lo-row.on .lo-px{color:var(--amber)}.lo-step{grid-row:1/3;grid-column:2;display:flex;align-items:center;gap:8px;align-self:center}.lo-step b{font-family:var(--mono);font-size:13px;min-width:16px;text-align:center;font-weight:500}.sbtn{
  width:24px;height:24px;border:1px solid var(--fog-2);color:var(--bone-dim);
  font-size:15px;line-height:1;display:flex;align-items:center;justify-content:center;
}.sbtn:hover{border-color:var(--amber);color:var(--amber)}/* --- detail --- */
.lo-detail{padding:16px 18px;overflow-y:auto;max-height:440px}.lo-dh{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:6px}.lo-dh h3{margin:0;font-family:var(--disp);font-size:15px;letter-spacing:.13em;text-transform:uppercase;font-weight:500}.lo-dh .px{font-family:var(--mono);font-size:12px;color:var(--amber);flex:none}.lo-sub{margin:0 0 14px;font-size:12.5px;line-height:1.6;color:var(--bone-dim);max-width:46ch}.lo-specs{display:grid;grid-template-columns:auto 1fr;gap:5px 16px;margin:14px 0 0;font-size:12px}.lo-specs dt{font-family:var(--disp);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--bone-dim)}.lo-specs dd{margin:0;font-family:var(--mono);font-size:12px;text-align:right}.lo-note{margin:14px 0 0;font-size:11.5px;line-height:1.6;color:var(--bone-dim);
  padding-top:11px;border-top:1px solid var(--fog);max-width:46ch}.lo-lock{margin:12px 0 0;font-family:var(--disp);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--amber)}.lo-detail .meters{margin-top:12px}/* --- penetration matrix: the entire armour system on one screen --- */
.matrix{border-collapse:collapse;margin-top:16px;font-family:var(--mono);font-size:11px}.matrix th{
  font-family:var(--disp);font-size:10px;letter-spacing:.1em;color:var(--bone-dim);
  font-weight:500;padding:4px 9px;text-align:center;
}.matrix thead th{border-bottom:1px solid var(--fog)}.matrix tbody th{text-align:left;padding-right:12px}.matrix th.hi{color:var(--amber)}.matrix tr.hi th{color:var(--amber)}.matrix td{padding:4px 9px;text-align:center;color:var(--fog-2);font-size:13px}.matrix td.pen{color:var(--good)}.matrix td.stop{color:var(--red)}.matrix tr.hi td,
.matrix td.hic{background:rgba(255,255,255,.05)}.matrix-key{margin:8px 0 0;font-size:10.5px;color:var(--bone-dim)}.matrix-key b{font-size:12px}.matrix-key b:first-of-type{color:var(--good)}.matrix-key b:last-of-type{color:var(--red)}@media (max-width:1040px){
  .lo-kit{grid-template-columns:repeat(2,1fr)}
  .kfin{grid-column:1/-1;justify-content:flex-start;border-top:1px solid var(--fog)}
  .lo-body{grid-template-columns:1fr}
  /* Slots wrap into a grid rather than becoming a scrolling tab strip — a
     strip that runs off the edge with its own scrollbar is the web-page tell,
     and it hides half the kit. */
  .lo-slots{
    display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));
    gap:3px;border-right:none;border-bottom:1px solid #000;padding:6px;
  }
  .lslot{padding:6px 8px 7px 10px}
  /* The note used to be dropped here to keep the tiles short. It is the only
     place a slot states what it is worth -- head armour, hearing range,
     armour class, carry capacity -- so hiding it left "Ballistic helmet" and
     "Helmet + headset" looking identical despite 24,000 between them.
     Measured at 904px: showing it costs 45px of column height, nothing
     overflows and nothing clips. The longest note any slot can produce is
     "+12 head - +25% hearing" at 131px, which fits every column wider than
     the 132px grid minimum and wraps to a second line at exactly that
     minimum, which is survivable. */
  .lo-list{border-right:none;border-bottom:1px solid var(--fog);max-height:290px}
  .lo-detail{max-height:none}
}/* attachment category headings inside the option list */
.lo-group{
  font-family:var(--disp);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--bone-dim);padding:12px 14px 5px;border-bottom:1px solid var(--fog);
  margin-bottom:3px;
}.lo-group:first-child{padding-top:6px}/* free-look notice: shown only when the browser refuses to capture the cursor */
/* centred and narrow: the long version spanned the full width and clipped
   both HUD corners,
which is worse than not showing the hint at all */
#freeLookHint{
  position:absolute;left:50%;bottom:16px;transform:translateX(-50%);
  z-index:4;pointer-events:none;
  font-size:11px;color:var(--bone-dim);background:rgba(10,12,13,.86);
  border:1px solid var(--fog);padding:4px 12px;white-space:nowrap;
  max-width:min(440px,52vw);overflow:hidden;text-overflow:ellipsis;
}#freeLookHint b{
  font-family:var(--disp);letter-spacing:.12em;text-transform:uppercase;
  color:var(--amber);font-weight:500;
}/* ---- operator preview beside the loadout console ---- */
.lo-wrap{display:grid;grid-template-columns:260px 1fr;gap:14px;align-items:start}/* the figure column is gone — the operator bay carries it now */
.lo-wrap.nofigure{grid-template-columns:1fr}@media (max-width:1180px){
  .lo-wrap{grid-template-columns:1fr}
  .lo-figure{position:static;max-width:320px}
  .lo-figure-view{height:300px}
}/* ============================================================
   UI POLISH PASS
   The HUD had the right information in the right corners but read
   flat. Depth comes from edge scrims,
a consistent panel language
   and restraint with the accent — not from more chrome.
   ============================================================ */

/* --- corner scrims so HUD text always has ground under it --- */
#hud::before,
#hud::after{
  content:"";position:absolute;left:0;right:0;height:130px;pointer-events:none;
}#hud::before{top:0;background:linear-gradient(180deg,rgba(6,8,9,.72),transparent)}#hud::after{bottom:0;background:linear-gradient(0deg,rgba(6,8,9,.68),transparent)}#topbar{background:none}/* z-index only. Setting position:relative here overrode the corner
   anchoring on #bl/#br and threw both HUD blocks to the top of the screen. */
#bl,
#br{z-index:1}/* --- carried medical,
with hotkeys --- */
/* compact enough that four fit a row — the block must never grow tall
   enough to climb into the contract line at the top of the screen */
/* follows the column rather than carrying its own fixed width,
which had
   drifted 6px wider than the parent it sits in */
#medRow{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px;width:100%}.med{
  display:inline-flex;align-items:center;gap:3px;
  font-family:var(--mono);font-size:9.5px;color:var(--bone-dim);
  border:1px solid rgba(56,67,71,.7);padding:1px 4px 1px 1px;
  background:rgba(10,13,14,.6);line-height:1.5;
}.med kbd{
  font-family:var(--mono);font-size:8.5px;background:var(--fog-2);color:var(--bone);
  padding:0 3px;line-height:1.5;
}.med b{color:var(--amber);font-weight:500}/* --- weapon block gets a hairline and better hierarchy --- */
#br{padding-left:18px;border-left:1px solid rgba(56,67,71,.45)}#wpnName{color:var(--bone);text-shadow:0 1px 2px rgba(0,0,0,.6)}#ammoCur{text-shadow:0 2px 6px rgba(0,0,0,.7)}/* --- vitals: label column aligns,
bars get an inner shadow --- */
.track{box-shadow:inset 0 1px 2px rgba(0,0,0,.55)}#bodyRig .z{box-shadow:inset 0 0 0 1px rgba(0,0,0,.35)}/* --- objective reads as a briefing line,
not a debug string --- */
#objText{color:var(--bone);text-shadow:0 1px 2px rgba(0,0,0,.6)}#objProg{letter-spacing:.02em}#objProg::before{content:"› ";color:var(--amber)}/* --- loot panel: value density column --- */
.item{grid-template-columns:1fr auto auto auto auto}.item-dens{
  font-family:var(--mono);font-size:11px;color:var(--bone-dim);
  min-width:56px;text-align:right;
}/* --- panels get a top accent so they read as deliberate objects --- */
#lootPanel,
#invPanel{border-top:2px solid var(--amber)}.panel-head{background:linear-gradient(180deg,rgba(240,160,60,.07),transparent)}/* --- menu: masthead sits on a subtle plate --- */
.mast{background:linear-gradient(180deg,rgba(255,255,255,.022),transparent)}.rails{background:rgba(255,255,255,.012)}/* --- cards lift slightly on hover so the menu feels responsive --- */
.card{transition:border-color .12s,background .12s,transform .12s}button.card:hover{transform:translateY(-1px)}.lo-row{transition:background .1s,box-shadow .12s}.lo-row.on{box-shadow:inset 3px 0 0 var(--amber)}/* --- tables: zebra the rows so long stash lists stay readable --- */
.tbl tbody tr:nth-child(even) td{background:rgba(255,255,255,.015)}/* --- primary action gets a glow so Deploy is unmistakable --- */
.btn.primary{box-shadow:0 0 0 1px rgba(240,160,60,.35),0 6px 18px rgba(240,160,60,.12)}.btn.primary:hover{box-shadow:0 0 0 1px rgba(255,180,87,.5),0 8px 22px rgba(240,160,60,.2)}/* --- extraction bar reads as urgent --- */
#extractBar{
  background:rgba(10,13,14,.72);border:1px solid var(--fog-2);
  padding:10px 16px 12px;
}#extractBar .lbl{color:var(--cold)}#extractFill{box-shadow:0 0 10px rgba(111,179,196,.6)}/* --- alerts sit on a stronger plate --- */
.alert{border-left-width:3px;box-shadow:0 4px 14px rgba(0,0,0,.4)}@media (max-width:820px){
  /* shrink the COLUMN, not the med row: the row follows its parent now, and
     setting it directly here would put it back to disagreeing with the block
     it sits in, which is what made the chips wrap in the first place. 170
     still fits three chips on one line. */
  #vitals{width:158px}
  #br{padding-left:10px}
  .bar-row .lbl{width:46px;font-size:9px}
}
@media (max-width:560px){
  /* the corners are edge-anchored and content-sized; the stylesheet has
     always admitted there is a width where they meet. At 480 they overlapped
     by 66px, so below 560 both corners simply shrink. */
  #bl{transform:scale(.78);transform-origin:left bottom}
  #br{transform:scale(.78);transform-origin:right bottom}
}/* The two bottom corners are anchored to opposite edges at 20 px and sized by
   their contents,
so there is a width at which they meet in the middle. There
   is nothing in the layout that stops it -- they are absolutely positioned and
   simply overlap,
the vitals bars printing through the ammunition count.
   Measured at 480 px with the longest weapon name in the game: they overlap by
   15 px. Pulling both insets in and tightening the body rig's gap recovers 30,
which clears it with room for a longer name than any weapon currently has. */
@media (max-width:560px){
  #bl{left:10px;bottom:14px;gap:8px}
  #br{right:10px;bottom:14px}
  #vitals{width:148px}
}/* ============================================================
   GRID INVENTORY
   Items are blocks that occupy their real footprint. Shape is the
   information here,
so cells stay square and nothing is cropped.
   ============================================================ */
.twogrid{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--fog)}.gcol{background:rgba(14,18,20,.9);padding:12px 14px 16px;min-width:0}.gtitle{
  font-family:var(--disp);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--bone-dim);margin-bottom:9px;
}.gridwrap{position:relative;--cell:44px;display:inline-block}.gridbg{display:grid;gap:0}.gridbg i{
  width:var(--cell);height:var(--cell);
  border:1px solid rgba(56,67,71,.55);margin:-1px 0 0 -1px;
  background:rgba(255,255,255,.012);
}.gitem{
  position:absolute;margin:1px;
  background:linear-gradient(160deg,rgba(38,46,50,.97),rgba(22,27,30,.97));
  border:1px solid var(--fog-2);border-left:3px solid var(--bone-dim);
  display:flex;flex-direction:column;justify-content:space-between;
  padding:4px 5px;text-align:left;overflow:hidden;
  transition:background .1s,border-color .1s,transform .08s;
}.gitem:hover{
  background:linear-gradient(160deg,rgba(240,160,60,.18),rgba(30,36,40,.97));
  border-color:var(--amber);transform:scale(1.02);z-index:2;
}/* names must wrap on word boundaries — clipping mid-word turned
   "Bullion bar" into "Bullik bar",
which reads as a rendering fault */
.gname{
  font-size:9px;line-height:1.1;color:var(--bone);
  word-break:break-word;overflow-wrap:anywhere;hyphens:auto;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
}
/* a single cell cannot hold a two-word name;shrink it and lean on the tooltip.
   This selector used to be [style*="1 * var(--cell)"],
which matches the WIDTH
   and the HEIGHT alike,
so it fired on anything one cell in either direction. */
.gitem[style*="width:calc(1 * var(--cell)"] .gname{font-size:8px}/* One row of cells is 22 px,
which leaves the label 12 px -- one line at this
   size. A two-word name on a 2x1 item wrapped and lost its second line to
   overflow:hidden with nothing to show it had: the watch cap and the field cap
   both read "Watch" and "Field" on the grid,
and the missing word was invisible
   rather than elided.

   Fixed with nowrap and an ellipsis rather than -webkit-line-clamp,
because
   that property does nothing here and never did. It only applies to a
   -webkit-box,
and .gname is a flex item inside .gitem,
so its display
   blockifies -- the computed value is flow-root,
and the clamp is inert. The
   three-line look on taller items comes from the box height,
not the clamp.

   A 2x1 label has 32 px to work in,
so this reads "Watch c..." -- which is
   what fits. The full name is on the item's title. */
.gitem[style*="height:calc(1 * var(--cell)"] .gname{
  font-size:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  word-break:normal;overflow-wrap:normal;
}.gval{font-family:var(--mono);font-size:9px;color:var(--amber);align-self:flex-end}

/* Bigger cells on a small screen are right for a stash you browse, but the
   loot panel's two grids are a drag PAIR inside a body that scrolls at 62vh:
   stacking them there put the pack out of reach of the container it was being
   filled from. Clicking an item also sends it across, so this degraded rather
   than broke — but the drag is the point, and it is happening on a clock with
   people shooting. The columns hold;the cells give way instead. */
@media (max-width:660px){
  .gridwrap{--cell:38px}
  .twogrid .gridwrap{--cell:26px}
}@media (max-width:520px){
  .twogrid{grid-template-columns:1fr}
  .twogrid .gridwrap{--cell:32px}
}

/* --- nav grew to seven sections;keep it tidy when it goes horizontal --- */
@media (max-width:900px){
  .nav button{padding:10px 14px;font-size:12px}
  .nav button .n{display:none}
  .nav{scrollbar-width:thin}
  .nav::-webkit-scrollbar{height:4px}
  .nav::-webkit-scrollbar-thumb{background:var(--fog-2)}
  .nav::-webkit-scrollbar-track{background:transparent}
}/* --- drag ghost: shows the drop footprint before you commit --- */
.drag-ghost{
  position:absolute;pointer-events:none;z-index:3;border:2px dashed var(--fog-2);
  background:rgba(255,255,255,.05);
}/* WAS .ghost — which ALSO matched .btn.ghost, absolutely positioning and
   de-clicking every ghost button in every panel for two days. Peter's
   'UI glitches': one selector collision. */
.drag-ghost.ok{border-color:var(--amber);background:rgba(240,160,60,.14)}.drag-ghost.no{border-color:var(--red);background:rgba(224,72,58,.14)}.gitem.dragging{opacity:.32}.is-dragging .gitem{cursor:grabbing}.gitem{cursor:grab;touch-action:none}/* --- equipment board on the stash screen --- */
/* These are jump-to-tab shortcuts,
not the kit readout — the bay plate beside
   them already says what you are wearing. So they pack tight: three across
   instead of two,
which lifts the stash grid a row and a half up the screen. */
.equip{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));
  gap:1px;background:var(--fog);border:1px solid var(--fog);margin-top:4px;
}.eslot{
  background:rgba(20,24,26,.85);padding:7px 10px;text-align:left;
  display:flex;flex-direction:column;gap:2px;border-top:2px solid transparent;
  transition:background .12s,border-color .12s;
}.eslot:hover{background:rgba(240,160,60,.09);border-top-color:var(--amber)}.eslot .v{
  font-family:var(--disp);font-size:11px;letter-spacing:.07em;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}/* --- stash grid gets its own scroll box --- */
.stashcol{
  padding:14px;border:1px solid var(--fog);background:rgba(14,18,20,.6);
  overflow:auto;max-height:min(58vh,560px);
}.stashcol .gridwrap{--cell:42px}/* --- paper doll: slots you drag gear onto ---------------------------------
   The drag engine is the one that already moves loot in a raid,
so the
   equipment slots are simply small grids. These styles give them the look of
   mounts rather than of another inventory. */
.doll{
  display:grid;grid-template-columns:minmax(230px,320px) 1fr;gap:16px;
  margin:0 0 20px;align-items:start;
}.doll-slots{display:flex;flex-direction:column;gap:10px}.dslot{
  padding:8px 10px 10px;border:1px solid #0b0e0f;border-left:3px solid #313d42;
  background:linear-gradient(180deg,#212a2e,#18201f);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}.dslot:hover{border-left-color:var(--cold-deep)}.ds-lbl{
  display:block;margin-bottom:6px;font-family:var(--disp);font-size:9.5px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--bone-dim);
}.doll-armoury{
  padding:10px 12px 12px;border:1px solid #0b0e0f;
  background:linear-gradient(180deg,#1d2529,#151b1e);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
}.da-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:8px}.da-head .lbl{font-family:var(--mono);font-size:10px;color:var(--bone-dim);opacity:.8}/* an empty slot reads as empty,
the same hatch the equipment list uses */
.dslot .gridbg i{background:rgba(255,255,255,.022)}.doll .gridwrap{--cell:30px}/* The armoury is the drag SOURCE and the slots are the targets. Stacking them
   into one column pushed the armoury past the fold,
which did not make the
   loadout awkward — it made it impossible,
because you cannot drag to a target
   that is not on screen with the source. So when there is no room for two
   columns the slots compress into a horizontal rail above the armoury instead
   of a tall stack that displaces it. */
@media (max-width:1000px){
  .doll{grid-template-columns:1fr;gap:10px}
  .doll-slots{flex-direction:row;flex-wrap:wrap;gap:8px}
  .dslot{flex:0 0 auto;padding:6px 8px 8px;border-left-width:2px}
  .ds-lbl{font-size:9px;letter-spacing:.14em;margin-bottom:4px}
  .doll .gridwrap{--cell:24px}
}/* a rail that is also a button: offline is a fixable state,
so it invites a click */
.rail.dur{text-align:left;width:100%;font:inherit;color:inherit;cursor:pointer}.rail.dur:hover{background:rgba(255,255,255,.04)}.rail.alarm{
  background:linear-gradient(180deg,rgba(224,72,58,.14),rgba(224,72,58,.04));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}.rail.alarm .risk{color:var(--red);opacity:.9}/* --- sound toggle in the masthead ---------------------------------------
   Deliberately quiet: it sits beside the three numbers that matter and must
   not compete with them,
so it reads as a label until you point at it. */
.mutebtn{
  align-self:center;margin-left:4px;
  /* was 9.5 — it is a small-caps label like every other .lbl on the masthead,
     and those are 10. Half a pixel between two things doing the same job is
     the difference nobody can see and everybody feels. */
  font-family:var(--disp);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--bone-dim);background:none;border:1px solid var(--fog);
  padding:5px 9px;cursor:pointer;
  transition:color .12s,border-color .12s,background .12s;
}.mutebtn:hover{color:var(--bone);border-color:var(--fog-2);background:rgba(255,255,255,.04)}.mutebtn.off-state{color:var(--red);border-color:rgba(158,42,32,.5)}.mutebtn.off-state:hover{color:#c8483a;border-color:var(--red)}/* ==========================================================================
   LOBBY — direction A: the operator is the room
   --------------------------------------------------------------------------
   The old lobby was a document: masthead,
nav column,
content column,
with an
   h2 and an explanatory paragraph at the top of every pane and the operator
   boxed off in a gutter. That structure is what made it read as a website,
so
   it is gone rather than restyled. The figure now fills the screen and every
   other element floats over him at an edge. Selectors are .lobby-prefixed so
   they beat the surviving rules on specificity rather than on file order.
   ========================================================================== */
.lobby{position:fixed;inset:0;overflow:hidden}.lobby .bay{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;
  z-index:0;border:none;background:none;
  box-shadow:none;max-height:none;display:block;flex:none}.lobby .bay-view{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;flex:none}.lobby .bay-view canvas{display:block}/* one graded wash doing three jobs: a cold key behind the figure,
a warm
   bounce off the floor,
and a vignette that keeps text off his silhouette */
.lobby .grade{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(56% 52% at 13% 86%,rgba(4,6,7,.93),transparent 72%),
    radial-gradient(50% 48% at 87% 87%,rgba(4,6,7,.90),transparent 72%),
    radial-gradient(58% 70% at 46% 50%,rgba(111,179,196,.10),transparent 70%),
    radial-gradient(120% 90% at 50% 122%,rgba(240,160,60,.13),transparent 62%),
    radial-gradient(92% 82% at 50% 45%,transparent 34%,rgba(4,6,7,.82) 100%);}/* --- masthead: a line of facts,
not a bar --- */
.lobby .mast{position:absolute;top:0;left:0;right:0;z-index:3;
  display:flex;align-items:flex-start;justify-content:space-between;gap:24px;
  padding:20px 28px;background:none;border:none}.lobby .mast-id h1{margin:0;font-family:var(--disp);font-size:15px;
  letter-spacing:.34em;font-weight:500;text-transform:uppercase;color:var(--bone)}.lobby .mast-id h1 b{color:var(--amber);font-weight:500}
/* was 10.5, a size used nowhere else on this screen;10 is the label size
   the masthead stats beside it already use */
.lobby .mast-id .sub{display:block;margin-top:4px;font-family:var(--mono);
  font-size:10px;color:var(--bone-dim);letter-spacing:.04em}.lobby .mast-stats{display:flex;align-items:flex-start;gap:24px;background:none;border:none}.lobby .mast-stats .stat{text-align:right;background:none;border:none;padding:0}.lobby .mast-stats .stat .v{display:block;margin-top:3px;font-family:var(--mono);font-size:16px}/* --- nav: bare words down the left edge --- */
/* anchored under the masthead rather than centred: the brief grows upward
   from the bottom-left corner and a centred nav collided with it on any
   short window */
.lobby .nav{position:absolute;left:28px;top:92px;z-index:3;
  display:flex;flex-direction:column;gap:0;background:none;border:none;padding:0;width:auto}.lobby .nav button{all:unset;display:flex;align-items:center;gap:11px;
  padding:7px 0;cursor:pointer;
  font-family:var(--disp);font-size:13px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--bone-dim);transition:color .14s}.lobby .nav button::before{content:'';width:14px;height:1px;background:var(--fog-2);
  transition:width .18s,background .18s;flex:none}.lobby .nav button:hover{color:var(--bone);background:none}.lobby .nav button.sel{color:var(--bone);background:none}.lobby .nav button.sel::before{width:30px;background:var(--amber)}.lobby .nav button .n{display:none}/* the numbers were filing-cabinet furniture */

/* --- the three tiers,
right edge,
hub only --- */
.lobby .tiers{position:absolute;right:28px;top:50%;transform:translateY(-50%);z-index:3;
  display:flex;flex-direction:column;gap:20px;text-align:right;width:172px}.lobby.working .tiers{display:none}.lobby .tier{all:unset;display:block;text-align:right;cursor:default}.lobby .tier[data-nav]{cursor:pointer}.lobby .tier b{display:block;margin-top:2px;font-family:var(--mono);font-size:21px;font-weight:600}
/* was 10;the identical thing in the contract pane (.bl-facts i -- a dim mono
   line explaining the label above it) is 9.5,
and two sizes half a pixel apart
   for one role is not a hierarchy. 9.5 is now the secondary-line size
   everywhere,
which leaves the lobby three sizes at the small end doing three
   different jobs: 11 body,
10 label,
9.5 secondary. */
.lobby .tier i{display:block;margin-top:1px;font-family:var(--mono);font-size:9.5px;
  font-style:normal;color:var(--bone-dim)}.lobby .tier .tk{display:block;height:2px;margin-top:7px;background:rgba(255,255,255,.07)}.lobby .tier .tk u{display:block;height:100%;text-decoration:none;background:var(--cold)}.lobby .tier.perm b{color:var(--cold)}.lobby .tier.dur b{color:var(--amber)}.lobby .tier.vol b{color:var(--red)}.lobby .tier.dur.alarm b{color:var(--red)}.lobby .tier[data-nav]:hover i{color:var(--bone)}/* --- kit + deploy,
bottom right --- */
.lobby .kitfoot{position:absolute;right:28px;bottom:26px;z-index:3;text-align:right}.lobby .kitfoot .kf-kit{font-family:var(--mono);font-size:11px;line-height:1.75;color:var(--bone-dim)}.lobby .kitfoot .kf-kit b{color:var(--bone);font-weight:500}.lobby .kitfoot .amber{color:var(--amber)}.lobby .kitfoot .btn{margin-top:12px;font-size:13px;letter-spacing:.3em;padding:13px 34px}/* --- the content itself ---
   On the hub it is a caption in the bottom-left corner. On a working screen it
   becomes a panel on the right that can actually hold a 120-cell stash grid —
   direction A's language,
with the density the data needs. */
.lobby .pane{position:absolute;z-index:3;padding:0;background:none;max-width:none}.lobby.hub .pane{left:28px;bottom:26px;width:min(360px,38vw)}.lobby.working .pane{right:0;top:0;bottom:0;width:min(620px,58vw);
  padding:74px 28px 26px;overflow-y:auto;
  background:linear-gradient(90deg,rgba(6,8,9,0),rgba(6,8,9,.86) 12%,rgba(6,8,9,.94) 100%)}.lobby.working .kitfoot{display:none}

/* prose belonged to the document version;the screen shows the numbers */
/* Peter's call (2026-09-30): the briefing line is SHOWN -- it is the only place the three tiers are explained in words */.lobby .pane .intro{display:block;margin:0 0 14px;padding:6px 10px 6px 11px;font-size:11px;max-width:92ch}.lobby .pane h2{font-family:var(--disp);font-size:13px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--bone-dim);font-weight:500;margin:0 0 16px}@media (max-width:900px){
  .lobby .tiers{display:none}
  .lobby.working .pane{width:auto;left:132px}
  .lobby.hub .pane{width:min(300px,52vw)}
}@media (max-width:620px){
  .lobby .nav{left:14px} .lobby .mast{padding:14px 16px}
  .lobby.working .pane{left:116px;padding:64px 16px 20px}
  .lobby .kitfoot{right:16px;bottom:16px}
}/* --- the hub brief: a caption,
bottom left --- */
.hub-brief .lbl{display:block;margin-bottom:5px}.hub-brief h1{margin:0 0 7px;font-family:var(--disp);font-size:25px;font-weight:500;
  letter-spacing:.05em;line-height:1.1;color:var(--bone)}/* was 11.5 here and 11 in the kit footer -- the same job at two sizes half a
   pixel apart. One body size for the lobby,
which is 11. */
.hub-brief .bl-brief{margin:0 0 9px;font-family:var(--mono);font-size:11px;
  line-height:1.65;color:var(--bone-dim)}.hub-brief .bl-pay{margin:0;display:flex;flex-wrap:wrap;gap:14px;
  font-family:var(--mono);font-size:11px}.hub-brief .bl-pay .dim{color:var(--bone-dim)}.hub-brief .bl-facts{display:flex;gap:22px;margin-top:18px;flex-wrap:wrap}.hub-brief .bl-facts b{display:block;margin-top:2px;font-family:var(--disp);font-size:13px;
  letter-spacing:.09em;text-transform:uppercase;font-weight:500;color:var(--bone)}.hub-brief .bl-facts i{display:block;margin-top:2px;font-family:var(--mono);font-size:9.5px;
  font-style:normal;color:var(--bone-dim)}.hub-brief .bl-warn{margin:16px 0 0;font-family:var(--mono);font-size:11px;
  color:var(--red);border-left:2px solid var(--red);padding-left:9px;line-height:1.55}/* --- working-screen panel corrections ---
   The masthead and the panel both sat at z-index 3,
so the panel — later in
   the DOM — painted over the three figures that are supposed to be readable
   from every screen. And the loadout is a two-column board inside a panel
   narrower than its content,
which produced a horizontal scrollbar. */
.lobby .mast{z-index:5}.lobby.working .pane{width:min(760px,62vw);overflow-x:hidden}/* The doll's own breakpoints key off the viewport,
but what constrains it
   here is the panel. Inside the lobby it always takes the compact form:
   slots as a rail,
armoury beneath,
so the pair can never be split. */
.lobby .pane .doll{grid-template-columns:1fr;gap:10px}.lobby .pane .doll-slots{flex-direction:row;flex-wrap:wrap;gap:8px}.lobby .pane .dslot{flex:0 0 auto;padding:6px 8px 8px;border-left-width:2px}.lobby .pane .ds-lbl{font-size:9px;letter-spacing:.14em;margin-bottom:4px}.lobby .pane .doll .gridwrap{--cell:24px}@media (max-width:900px){
  .lobby.working .pane{width:auto;left:132px}
}/* On a working screen the panel owns the right 60% of the frame,
and a figure
   centred in the bay ends up behind it — on the loadout screen you could see
   one glove. He steps left instead,
into the space the panel leaves,
so you
   can still watch the kit you are changing appear on the man wearing it. */
.lobby .bay{transition:transform .32s cubic-bezier(.4,0,.2,1)}.lobby.working .bay{transform:translateX(-27%)}@media (max-width:900px){
  .lobby.working .bay{transform:translateX(-34%)}
}/* --- the remaining panes,
in the new language ---------------------------
   Contracts,
Holding,
Traders and Skills still build themselves from .sec and
   .card,
which were designed as raised plates laid down a page — lit top edge,
cast shadow,
10px gutters. That is the card rhythm that made the lobby read
   as a document. Inside the panel they become rows in a list instead: butted
   together on a single seam,
name left,
number right,
note under it in mono.
   Restyling the two shared primitives converts all four panes at once and
   leaves their builders,
and every event binding on them,
untouched. */
.lobby .pane .sec{margin-top:18px}.lobby .pane .sec:first-child{margin-top:0}.lobby .pane .sec>h3{
  margin:0 0 1px;padding:6px 11px;border:none;
  font-family:var(--disp);font-size:9.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--bone-dim);
  background:rgba(255,255,255,.04);
}.lobby .pane .sec>h3::before{display:none}/* one column of rows,
not a masonry of tiles */
.lobby .pane .grid{gap:1px}.lobby .pane .g2,
.lobby .pane .g3{grid-template-columns:1fr}.lobby .pane .card{
  border:none;border-left:2px solid transparent;
  border-top:1px solid rgba(255,255,255,.05);
  background:rgba(13,18,20,.72);
  box-shadow:none;padding:9px 12px 10px;
  transition:background .12s,border-color .12s;
}.lobby .pane .card:hover{background:rgba(21,28,31,.88)}.lobby .pane .card.sel{border-left-color:var(--amber);background:rgba(26,31,29,.9)}.lobby .pane .card-top .nm{font-size:12.5px;letter-spacing:.08em}.lobby .pane .card-top .px{font-size:11.5px}.lobby .pane .card p{margin-top:3px;font-family:var(--mono);font-size:10.5px;line-height:1.55}.lobby .pane .specs{font-size:10px}.lobby .pane .meter{grid-template-columns:48px 1fr 28px}/* the summary strip reads as instrumentation,
not a footer */
.lobby .pane .sumbar{
  margin-top:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));
  gap:1px;background:rgba(255,255,255,.05);border:none;padding:0}.lobby .pane .sumbar .g{background:rgba(13,18,20,.8);padding:9px 11px}.lobby .pane .sumbar .v{font-family:var(--mono);font-size:14px;display:block;margin-top:2px}/* Armed deploy: red,
because the next press is the irreversible one. It also
   widens slightly so the cost fits without the corner jumping around. */
.lobby .kitfoot .btn.primary.armed{
  background:var(--red);color:#1a0705;
  box-shadow:0 0 0 1px rgba(224,72,58,.45),0 6px 18px rgba(224,72,58,.18);
  letter-spacing:.18em;padding:13px 22px;
}.lobby .kitfoot .btn.primary.armed:hover{background:#ef5949;color:#1a0705}

/* The three facts are a set and should read as one line of instrumentation.
   Flex-wrap broke them 2 + 1 at the hub's width, which made the clock look
   like an afterthought;a fixed three-column grid keeps them level. */
.lobby.hub .pane{width:min(430px,42vw)}.hub-brief .bl-facts{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.hub-brief .bl-pay{gap:12px}.hub-brief .bl-pay .dim{flex:1 1 100%;margin-top:1px}@media (max-width:900px){
  .lobby.hub .pane{width:min(320px,52vw)}
  .hub-brief .bl-facts{grid-template-columns:repeat(2,1fr);row-gap:12px}
}/* A ledger line is a label and a figure,
and the label is the part that must
   stay intact — a wrapped "Kit written / off" reads as two rows that do not
   exist. The label holds its line and the figure takes the slack. */
.led-lines div{align-items:baseline}.led-lines div span:first-child{white-space:nowrap;flex:0 1 auto;min-width:0}.led-lines div span:last-child{text-align:right;flex:1 1 auto}/* The contracts pane's own selections sit ~1200 px down a 2150 px scroll,
so
   this strip repeats them at the top. Reads as a status line,
not a card:
   no border box,
just the amber edge the selected cards already use. */
.consel{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  margin:0 0 14px;padding:9px 13px;
  border-left:2px solid var(--amber);
  background:rgba(26,31,29,.72);
}.consel b{font-family:var(--mono);font-size:13px;color:var(--bone);white-space:nowrap}.consel .lbl{font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--bone-dim)}/* was var(--fog),
which measured a 1.19 contrast ratio against the strip --
   a separator nobody can see is just markup. --bone-dim is what the labels
   beside it already use. */
.consel .sep{color:var(--bone-dim)}.consel .pay{margin-left:auto;font-family:var(--mono);font-size:12px;color:var(--amber);white-space:nowrap}

/* --- being hit ---------------------------------------------------------
   Taking a round used to produce a small colour change on a body diagram in
   the corner and, if a plate stopped it, one tone. In a firefight nobody is
   looking at the corner. You could be shot through the chest and the only
   thing that changed was a square you were not watching.

   So: the whole frame takes it. A red wash from the edges, and an arc at the
   bearing the shot came from so you know which way to turn. Both are pure
   CSS animations on elements that are otherwise invisible and cost nothing. */
#hurt{
  position:absolute;inset:0;pointer-events:none;z-index:7;opacity:0;
  background:radial-gradient(ellipse at center,transparent 38%,rgba(150,16,16,.62) 100%);
}
#hurt.on{animation:hurtpulse .42s ease-out}
#hurt.hard.on{animation:hurtpulse .62s ease-out}
@keyframes hurtpulse{0%{opacity:0}12%{opacity:1}100%{opacity:0}}

#hurtDir{
  position:absolute;inset:0;pointer-events:none;z-index:8;opacity:0;
  display:flex;align-items:center;justify-content:center;
}
#hurtDir.on{animation:hurtdir .9s ease-out}
#hurtDir i{
  display:block;width:min(46vmin,420px);height:min(46vmin,420px);
  border-radius:50%;
  border:3px solid transparent;border-top-color:rgba(226,60,48,.92);
  transform:rotate(var(--bearing,0deg));
}
@keyframes hurtdir{0%{opacity:0}10%{opacity:1}100%{opacity:0}}

/* The side a round came from: that edge of the frame goes dark for a
   moment (raid.js onPlayerHit builds #hitEdge, sets --edge-ang and the
   element's opacity, which is the strength). Blood-dark when it went in,
   plain dark when the plate held -- red means wounded, nothing else does.
   The gradient runs from the struck side about a third of the way in, so
   the middle of the screen, where you are aiming, is never touched. */
#hitEdge{position:absolute;inset:0;pointer-events:none;z-index:7;opacity:0}
#hitEdge i{
  position:absolute;inset:0;opacity:0;
  background:linear-gradient(var(--edge-ang,0deg),rgba(62,4,3,.92) 0%,rgba(62,4,3,.42) 13%,rgba(62,4,3,0) 34%);
}
#hitEdge.stop i{background:linear-gradient(var(--edge-ang,0deg),rgba(0,0,0,.85) 0%,rgba(0,0,0,.34) 12%,rgba(0,0,0,0) 30%)}
#hitEdge.on i{animation:hitedge .75s ease-out}
#hitEdge.stop.on i{animation:hitedge .5s ease-out}
@keyframes hitedge{0%{opacity:0}7%{opacity:1}100%{opacity:0}}
/* #hitmark is no longer driven (no hit markers: a hit is confirmed by its
   sound). The element stays in index.html, invisible, until that file's
   owner removes it. */

/* --- the item itself, in the cell ---------------------------------------
   Rendered from the real thing where there is a real thing: a weapon cell is
   the gun you built, with the optic and the can you paid for on it. The name
   sits under it rather than instead of it. */
/* A dark object on a dark cell is a dark cell. The backdrop is barely there
   -- a lift of three per cent at the centre -- but it is the difference
   between a rifle silhouette and nothing. */
.gitem::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse at 50% 42%,rgba(190,205,210,.075),transparent 68%)}
.gicon{
  position:absolute;inset:1px 1px 11px 1px;width:calc(100% - 2px);height:calc(100% - 12px);
  object-fit:contain;pointer-events:none;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.55));
}
.gitem .gname{
  position:absolute;left:3px;right:3px;bottom:1px;
  font-size:8.5px;letter-spacing:.02em;line-height:1.1;
  color:var(--bone-dim);text-align:left;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  text-shadow:0 1px 2px rgba(0,0,0,.8);
}
.gitem:hover .gname{color:var(--bone)}
.doll .gicon{inset:1px 1px 10px 1px;height:calc(100% - 11px)}

/* The magnified-optic view: past 2x the weapon model gives way at the eye
   and the scope owns the screen -- an unmagnified receiver over a 3.4x world
   hides half the man being aimed at, whatever the pose does (t-ads.html).
   This is the genre answer and the honest one. */
#scope{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .1s}
#scope.on{opacity:1}
#scope::before{content:"";position:absolute;inset:0;background:radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 0 32vmin, rgba(4,5,5,.99) 33vmin)}
#scope::after{content:"";position:absolute;left:50%;top:50%;width:64vmin;height:64vmin;transform:translate(-50%,-50%);border-radius:50%;background:linear-gradient(#0a0c0c,#0a0c0c) 50% 0/2px 100% no-repeat,linear-gradient(#0a0c0c,#0a0c0c) 0 50%/100% 2px no-repeat}

/* The equipment view: named slots beside the carried grids. The secure
   container is the volatile tier one exception, so it reads amber. */
.inv-tarkov{display:flex;gap:18px;align-items:flex-start;padding:14px}
.eqcol{display:flex;flex-direction:column;gap:8px;min-width:190px}
.eqslot{border:1px solid var(--line,#3a464c);border-left-width:3px;padding:7px 10px;background:rgba(16,20,22,.6)}
.eqlbl{display:block;font-family:var(--disp);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--bone-dim,#8a9691)}
.eqval{display:block;font-size:12.5px;color:var(--bone,#cfd8d3);font-weight:500}
.eqsub{display:block;font-family:var(--mono);font-size:10.5px;color:var(--bone-dim,#8a9691)}
.gstack{display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start}
.gstack-side{display:flex;flex-direction:column;gap:10px}
.gcol.secure{border:1px solid var(--amber,#e0a51e);padding:6px;background:rgba(224,165,30,.05)}
.securenote{display:block;text-align:center;margin-top:4px;color:var(--amber,#e0a51e);font-size:10px;letter-spacing:.1em;text-transform:uppercase}
@media (max-width:820px){.inv-tarkov{flex-direction:column}}

/* The loot split: the find on the left, the player on the right, a hard
   visual boundary between them -- reported as "looks weird" when the
   grids sat side by side undifferentiated. */
.loot-split{display:flex;align-items:stretch;gap:0}
.loot-theirs{flex:0 0 38%;padding:12px 14px;background:rgba(120,60,40,.07);border-right:2px solid var(--fog,#2a3438)}
.loot-yours{flex:1;padding:12px 14px}
.loot-side-h{font-family:var(--disp);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:#c98f5f;margin-bottom:8px}
.loot-side-h.yours{color:var(--amber,#e0a51e)}
.loot-yours .gstack{display:flex;gap:14px;flex-wrap:wrap;align-items:flex-start}

/* --- the gear rail inside the loot screen: a narrow left column, the
   grids keep the floor --- */
.loot-yours{display:flex;flex-wrap:wrap;gap:0 14px}
.loot-yours .loot-side-h{flex:0 0 100%}
.loot-yours .eqcol{flex:0 0 186px;max-height:352px;overflow-y:auto;margin:0}
.loot-yours .eqcol .eqslot{padding:5px 8px}
.loot-yours .gstack{flex:1;min-width:0}

/* --- doll slot cards --- */
.eqslot.filled{border-left:2px solid var(--amber);background:rgba(240,160,60,.05)}
.eqslot[data-unequip]{cursor:pointer}
.eqslot[data-unequip]:hover{background:rgba(240,160,60,.12)}

/* --- item context menu --- */
#ctxMenu{
  position:fixed;z-index:60;min-width:190px;background:rgba(12,15,16,.97);
  border:1px solid var(--fog-2);border-top:2px solid var(--amber);
  box-shadow:0 10px 30px rgba(0,0,0,.55);
}
#ctxMenu .ctx-head{display:flex;flex-direction:column;gap:2px;padding:9px 12px;border-bottom:1px solid var(--fog)}
#ctxMenu .ctx-head b{font-size:13px}
#ctxMenu .ctx-head span{font-family:var(--mono);font-size:11px;color:var(--bone-dim)}
#ctxMenu .ctx-verb{
  display:block;width:100%;text-align:left;padding:8px 12px;font:inherit;font-size:12px;
  background:none;border:0;color:var(--bone);cursor:pointer;letter-spacing:.04em;
}
#ctxMenu .ctx-verb:hover{background:rgba(240,160,60,.14);color:var(--amber)}

/* --- progressive search --- */
.gitem.hiddenitem{
  background:repeating-linear-gradient(135deg,rgba(255,255,255,.035) 0 6px,rgba(0,0,0,.18) 6px 12px);
  border:1px dashed var(--fog-2);cursor:default;display:flex;align-items:center;justify-content:center;
}
.gitem.hiddenitem .gq{font-family:var(--disp);font-size:16px;color:var(--bone-dim);animation:gq 1s ease-in-out infinite}
@keyframes gq{0%,100%{opacity:.35}50%{opacity:.9}}
.loot-side-h .searching{color:var(--amber);letter-spacing:.12em}

/* --- the grade overlay: vignette + fine animated grain --- */
#gradeOverlay{
  position:absolute;inset:0;pointer-events:none;z-index:1;
  background-size:100% 100%, 160px 160px;
  mix-blend-mode:normal;
  /* no keyframe hop: main.js drifts the grain with the view (parallax) */
}

/* --- controls on the pause screen --- */
.pause-controls{max-width:min(760px,92vw);margin-top:6px;text-align:left}
.pause-controls .keys{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 22px}
.pause-controls .keys div{display:flex;gap:10px;align-items:baseline;font-size:12px;color:var(--bone-dim)}
.pause-controls kbd{min-width:74px;text-align:center}
@media (max-width:640px){.pause-controls .keys{grid-template-columns:1fr}}

/* --- the context-fading HUD --- */
#bl,#br,#topbar .tb-block{transition:opacity .45s ease}

/* --- mag check: the estimate, not a count --- */
#ammoCur.est{font-family:var(--disp);font-size:17px;font-weight:600;letter-spacing:.12em;text-transform:uppercase}

/* --- pace dial readout --- */
#paceInd{display:flex;align-items:center;gap:3px;margin-top:6px;font-family:var(--disp);font-size:10px;letter-spacing:.14em;color:var(--bone-dim)}
#paceInd span{margin-right:5px}
#paceInd i{display:inline-block;width:9px;height:4px;background:rgba(200,196,184,.18)}
#paceInd i.on{background:var(--bone)}
#paceInd b{margin-left:6px;font-weight:600;color:var(--bone)}

/* --- pain: a red, pulsing edge --- */
#painFx{position:fixed;inset:0;pointer-events:none;z-index:4;opacity:0;transition:opacity .35s linear;
  background:radial-gradient(ellipse at center,rgba(0,0,0,0) 52%,rgba(90,8,6,.55) 88%,rgba(60,0,0,.8) 100%)}

/* --- night vision: the tube's edge --- */
#gradeOverlay.nv{box-shadow:inset 0 0 18vmin 9vmin rgba(0,0,0,.92)}

/* --- the raid log --- */
.aar-killed{margin:4px 0 10px;padding:8px 12px;border-left:3px solid var(--red);background:rgba(160,40,30,.12);font-size:13px}
.aar-killed b{color:var(--red);letter-spacing:.08em;text-transform:uppercase;font-size:11px;margin-right:6px}

/* --- the extract list (hold O) --- */
#exList{position:absolute;top:84px;right:20px;min-width:300px;padding:10px 14px;background:rgba(10,12,13,.72);
  border-left:2px solid rgba(200,196,184,.35);font-family:var(--disp);font-size:11px;letter-spacing:.08em;
  opacity:0;transition:opacity .2s;pointer-events:none;z-index:6}
#exList.on{opacity:1}
#exList .exl-h{color:var(--bone-dim);letter-spacing:.2em;margin-bottom:6px}
#exList .exl-r{display:grid;grid-template-columns:1fr auto auto;gap:12px;padding:3px 0;align-items:baseline}
#exList .exl-n{color:var(--bone)}
#exList .exl-r.ok .exl-s{color:#8fcf8a}
#exList .exl-r.no .exl-s{color:var(--amber, #d9a441)}
#exList .exl-r.no .exl-n{color:var(--bone-dim)}
#exList .exl-d{color:var(--bone-dim);text-align:right;min-width:64px}

/* --- raid intro: black, the place, then the world --- */
#raidIntro{position:fixed;inset:0;z-index:40;pointer-events:none;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;opacity:0;background:#050607}
#raidIntro.go{animation:riBg 3.6s ease-out forwards}
#raidIntro .ri-map{font-family:var(--disp);font-size:28px;letter-spacing:.42em;color:var(--bone);text-indent:.42em}
#raidIntro .ri-sub{font-family:var(--disp);font-size:12px;letter-spacing:.24em;color:var(--bone-dim);text-transform:uppercase}
#raidIntro.go .ri-map,#raidIntro.go .ri-sub{animation:riTx 3.6s ease-out forwards}
@keyframes riBg{0%{opacity:1;background:rgba(5,6,7,1)}30%{opacity:1;background:rgba(5,6,7,1)}62%{opacity:1;background:rgba(5,6,7,0)}100%{opacity:0;background:rgba(5,6,7,0)}}
@keyframes riTx{0%{opacity:0;transform:translateY(4px)}15%{opacity:1;transform:none}72%{opacity:1}100%{opacity:0}}

/* --- tank farm vapour --- */
#vapFx{position:fixed;inset:0;pointer-events:none;z-index:4;opacity:0;transition:opacity .6s linear;
  background:radial-gradient(ellipse at 50% 48%, rgba(150,148,96,.16) 20%, rgba(118,116,70,.42) 70%, rgba(84,82,48,.72) 100%)}
#vapFx.sting{-webkit-backdrop-filter:blur(1.4px);backdrop-filter:blur(1.4px)}

/* --- grain: over the world only (Peter, 2026-09-30) ---
   #scene is its own stacking layer, so the overlays inside it can no longer
   climb over the menus, the inventory or the HUD panels. */
#scene{z-index:0}
#grainOverlay{position:absolute;inset:0;pointer-events:none;z-index:1;background-size:160px 160px;opacity:var(--grain-op,1)}
.lobby .bay::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background-image:var(--grain-url);background-size:160px 160px;opacity:var(--grain-op,1)}
.setwrap{position:relative;display:inline-block}
.setpop{position:absolute;right:0;top:calc(100% + 6px);z-index:20;padding:10px 12px;min-width:220px;
  background:rgba(12,15,16,.96);border:1px solid rgba(200,196,184,.18)}
.setpop.off{display:none}
.grainset{display:flex;align-items:center;gap:10px;white-space:nowrap}
.grainset input{flex:1;accent-color:var(--amber,#d9a441)}
.pause-settings{min-width:260px}
/* the post-processing toggle, under the grain slider in both settings spots */
.postset{display:flex;align-items:center;gap:10px;white-space:nowrap;margin-top:8px;cursor:pointer}
.postset input{margin:0;accent-color:var(--amber,#d9a441)}
