/* ── Galaxy map view ───────────────────────────── */

.galaxy-body{
  padding:0 !important;
  gap:0 !important;
  flex-direction:row;
  background:#01030a;
}

.galaxy-wrap{
  position:relative;
  flex:1;
  overflow:hidden;
  /* Subtle vignette so the canvas blends into the chrome edges. */
  box-shadow:inset 0 0 80px rgba(0,0,0,.7);
}

/* Scoped to the galaxy canvas only — the trade overlay lives inside the same
   `.galaxy-wrap` and contains portrait / silhouette canvases that must keep
   their own declared dimensions. A descendant-combinator rule here would
   override their `width:48px` etc and let flex resolve their basis to 100%. */
#galaxyCanvas{
  display:block;
  width:100%;
  height:100%;
  cursor:default;
}

/* ── Side rail (sector detail) ─────────────────── */

.sec-card{
  display:flex;flex-direction:column;gap:10px;
  padding:12px;
  background:rgba(4,14,32,.7);
  border:1px solid rgba(40,100,180,.35);
  border-radius:8px;
  box-shadow:0 0 18px rgba(0,80,160,.08) inset;
}

.sec-name{
  font-family:'Orbitron',sans-serif;
  font-size:13px;letter-spacing:1.5px;
  color:#e6f1ff;
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;
}

.sec-meta{font-size:11px;color:var(--dim)}
.sec-meta b{color:var(--gold)}

.sec-desc{font-size:11px;line-height:1.5;color:#a0c0d8}

.sec-bdg{font-size:9px;padding:2px 6px;border-radius:3px;letter-spacing:.5px;text-transform:uppercase;border:1px solid transparent}
.sec-bdg.locked  {background:rgba(80,30,40,.5);color:#ff8aa0;border-color:rgba(180,60,80,.4)}
.sec-bdg.open    {background:rgba(0,80,140,.4);color:#9fe5ff;border-color:rgba(80,180,255,.4)}
.sec-bdg.cleared {background:rgba(20,70,40,.5);color:#a8ffce;border-color:rgba(60,200,140,.4)}
.sec-bdg.active  {background:rgba(80,60,10,.5);color:#ffd844;border-color:rgba(255,200,60,.5);box-shadow:0 0 8px rgba(255,200,60,.25)}

.sec-section{display:flex;flex-direction:column;gap:5px}

.prereq-list{display:flex;flex-direction:column;gap:4px}
.prereq{
  font-size:11px;
  padding:5px 8px;
  border-radius:4px;
  border:1px solid #1a2a3a;
  display:flex;align-items:center;gap:7px;
}
.prereq-mark{font-family:'Orbitron',sans-serif;font-size:10px;width:14px;text-align:center}
.prereq.ok{
  color:#a8ffce;
  border-color:rgba(60,200,140,.35);
  background:rgba(20,60,40,.35);
}
.prereq.ok .prereq-mark{color:#3cd87a}
.prereq.pending{
  color:#88aacc;
  border-color:rgba(40,90,160,.3);
  background:rgba(10,25,50,.3);
}
.prereq.pending .prereq-mark{color:#5a7090}

.locked-msg{
  font-size:11px;color:#88aacc;
  padding:9px 10px;
  border:1px dashed rgba(60,80,120,.45);
  border-radius:5px;
  text-align:center;
  background:rgba(10,18,32,.4);
}

/* ── Contact detail (sector column + popup) ─────
   The facts a contact states wherever it is read: its weapon list, a salvage
   pile's amount, and the gate's own line. */
.enemy-wpns{display:flex;flex-direction:column;gap:2px;margin-top:4px}
.enemy-wpn{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 6px;font-size:10px}
/* Wraps rather than clips: a narrow popup must not turn a weapon's name into
   "Pulse Las…" (UI-REDESIGN.md §6). */
.enemy-wpn .nm{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.enemy-wpn .dmg{flex:none;font-variant-numeric:tabular-nums;color:#5a7790}
.enemy-wpn .shots{flex:none;font-variant-numeric:tabular-nums;color:#88aacc}
.enemy-wpn .rar{flex:none}

.bdg-money{background:rgba(255,200,68,.12);color:var(--gold);border:1px solid rgba(255,200,68,.4)}
.poi-money-amt{
  font-size:18px;font-weight:600;color:var(--gold);
  font-variant-numeric:tabular-nums;
}
.poi-money-amt.is-scrap{color:var(--u-scrap)}
.poi-money-amt.is-silicon-ore{color:var(--u-silicon-ore)}
.poi-money-amt .cur{font-size:13px;opacity:.8}

/* The gate's own copy — amber, so the sector's last test reads as a threat tier
   of its own rather than as one more contact. */
.poi-gate-msg{
  font-size:11px;font-weight:600;
  color:#ffc89a;letter-spacing:.3px;
}

/* ── Galactic projection ──────────────────────────
   The sector graph is DOM over the canvas: the canvas paints the void and the
   prerequisite edges, each sector is a kit hex node (`.u-hex` in css/ui.css)
   positioned by the layout in views/map.js. Text stays crisp at any DPR and the
   pointer hits a real element instead of a hit-tested circle. */
.gx-strip{position:absolute;top:0;left:0;right:0;z-index:var(--z-pins)}
.gx-nodes{position:absolute;inset:0;z-index:var(--z-pins)}

/* A node is positioned by its hexagon's centre, so edges drawn between node
   coordinates meet the hexagons and not the plates hanging under them. The
   kit shrinks `.u-hex-shape` at the narrow and short breakpoints, so the
   half-hexagon this column is lifted by is measured, not assumed:
   `renderHexNodes` writes `--gx-hex-h` from the rendered hexagon and
   `rebuildLayout` spaces the nodes from the same measurement. */
.gx-node{
  position:absolute;
  /* Cap the column at a hexagon and a bit, so a long "Needs …" line wraps
     inside its plate instead of stretching the node over its neighbour. */
  width:max-content;max-width:190px;
  transform:translate(-50%,calc(-1 * var(--gx-hex-h,132px) / 2));
  cursor:pointer;
}
.gx-node.is-selected .u-hex-shape{filter:drop-shadow(0 0 24px rgba(79,216,255,.7))}
.gx-node.is-selected .u-hex-plate{border-color:var(--u-line)}
/* A sector the scanner has banked something in since the player last looked at
   it. The hexagon pulses until the drill-down opens and the sweep plays those
   contacts in, so a find made while the projection is on screen still says
   where to go. */
.gx-node.has-find .u-hex-shape{animation:gx-find 1.7s ease-in-out infinite}
@keyframes gx-find{
  0%,100%{filter:drop-shadow(0 0 5px rgba(79,216,255,.25))}
  50%    {filter:drop-shadow(0 0 22px rgba(79,216,255,.8))}
}

/* What the passive scanner has banked in a sector, at a glance. An unrevealed
   contact stays grey: the server has not rolled it, so the client must not
   imply it knows what is there. */
/* One palette for a contact wherever it is read — the hexagon's dot on the
   projection, its marker on a ring, its line in the sector column. Each kind
   names its colour once; the three surfaces decide what to paint with it. */
.gx-dot.is-unknown, .rc-marker.is-unknown{--poi-color:#7f9ab4}
.gx-dot.is-enemy,   .rc-marker.is-enemy  {--poi-color:var(--u-bad)}
.gx-dot.is-money,   .rc-marker.is-money  {--poi-color:var(--gold)}
.gx-dot.is-scrap,   .rc-marker.is-scrap  {--poi-color:var(--u-scrap)}
/* A seam is scrap you cannot pocket — same family as a pile, cooler and dimmer
   so a contact needing a drone reads apart from one a click finishes. */
.gx-dot.is-deposit, .rc-marker.is-deposit{--poi-color:#b9763c}
.gx-dot.is-deposit.is-silicon-ore, .rc-marker.is-deposit.is-silicon-ore{--poi-color:var(--u-silicon-ore)}
.gx-dot.is-station, .rc-marker.is-station{--poi-color:var(--u-line)}
.gx-dot.is-gate,    .rc-marker.is-gate   {--poi-color:#c07bff}

.gx-dots{display:flex;flex-wrap:wrap;gap:5px;justify-content:center;align-items:center;width:70%}
.gx-dot{
  width:7px;height:7px;border-radius:50%;
  background:var(--poi-color,#41597a);
  box-shadow:0 0 5px rgba(0,0,0,.6);
}
.gx-dot.is-fixed  {width:9px;height:9px;border:1px solid rgba(255,255,255,.35)}

/* ── Recon: the sector drill-down ─────────────────
   Takes the stage over the projection, and the orbital scene is the whole of
   it: rings on a canvas, contacts as DOM markers over them, the sector's own
   facts as captions in the corner and the middle, and one contact's full detail
   as a popup anchored to its marker. Nothing is restated in a column beside. */
.rc-layer{
  /* Isolated: the captions, the markers and the popup stack against each other
     inside the drill-down, not against the projection's own strip and nodes. */
  position:absolute;inset:0;z-index:var(--z-bay);isolation:isolate;
  display:flex;flex-direction:column;
  background:radial-gradient(120% 90% at 50% 45%,#081228 0%,#04091a 55%,#01030a 100%);
}
.rc-layer[hidden]{display:none}
/* The scene is the drill-down: the rings on the canvas, the captions and the
   contacts over it. Nothing sits beside it. */
.rc-space{position:relative;flex:1;min-height:0;min-width:0;overflow:hidden}
#reconCanvas{position:absolute;inset:0;width:100%;height:100%;display:block}

/* ── Captions over the scene ────────────────────
   What the sector is, in its top corner, and — when the rings have nothing on
   them — why, in the middle where they would be. Both are inert: every click in
   the scene belongs to a contact. */
.rc-info{
  position:absolute;top:0;left:0;right:0;z-index:var(--z-pins);
  display:flex;flex-direction:column;gap:4px;
  padding:14px 18px;
  background:linear-gradient(180deg,rgba(4,10,24,.92),rgba(4,10,24,0));
  pointer-events:none;
}
.rc-info-name{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  font:700 20px/1.2 var(--u-font-ui);color:var(--u-value);
}
.rc-info-meta{font-size:11px;color:var(--u-label)}
.rc-info-meta b{color:var(--gold)}
/* Clamped, not truncated by the box: a long designer description must not push
   the rings down the screen, and the popup is where detail lives anyway. */
.rc-info-desc{
  max-width:80ch;font-size:11px;line-height:1.5;color:var(--u-body);
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3;overflow:hidden;
}
.rc-info-scan{font-size:11px;color:var(--u-label)}
.rc-info-scan b{color:var(--u-value)}
.rc-info-warn{color:var(--gold)}

.rc-note{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  z-index:var(--z-pins);
  display:flex;flex-direction:column;align-items:center;gap:8px;
  max-width:min(460px,80%);text-align:center;
  pointer-events:none;
}
.rc-note:empty{display:none}
.rc-note-title{font:700 12px/1 var(--u-font-ui);letter-spacing:.18em;color:var(--u-label)}
.rc-note-body{font:400 12px/1.5 var(--u-font-ui);color:var(--u-mute)}
.rc-note-prereqs{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}
.rc-note-prereqs .prereq{display:inline-flex}

/* Contacts: one marker per point of interest, on its ring. */
.rc-markers{position:absolute;inset:0;z-index:var(--z-panel)}
/* Anchored by its circle, the way `.gx-node` is anchored by its hexagon: the
   name and the meta line hang under the ring point instead of sharing it, so a
   contact that gains or loses its meta line on reveal keeps its dot exactly
   where it was. The circle's size therefore belongs on the marker, never on the
   circle itself — a breakpoint that sets `.rc-dot{width}` desyncs the anchor. */
.rc-marker,.rc-centre{
  position:absolute;transform:translate(-50%,calc(-1 * var(--rc-anchor) / 2));
  display:flex;flex-direction:column;align-items:center;gap:4px;
  background:none;border:0;padding:0;cursor:pointer;color:var(--poi-color,var(--u-label));
}
.rc-marker{--rc-anchor:34px}
.rc-centre{--rc-anchor:54px}
.rc-dot{
  width:var(--rc-anchor);height:var(--rc-anchor);border-radius:50%;
  display:grid;place-items:center;
  border:2px solid currentColor;
  background:radial-gradient(circle at 50% 35%,rgba(18,38,68,.95),rgba(3,9,20,.96));
  font-size:15px;line-height:1;
  box-shadow:0 0 12px rgba(0,0,0,.6);
  transition:transform .12s,box-shadow .15s;
}
.rc-marker:hover .rc-dot{transform:scale(1.12)}
.rc-name{font:600 12px/1.2 var(--u-font-ui);white-space:nowrap;text-shadow:0 0 6px rgba(0,0,0,.8)}
/* The one fact a contact states on its own marker — what its popup leads with. */
.rc-meta{font:400 11px/1.2 var(--u-font-ui);color:var(--u-label);white-space:nowrap;text-shadow:0 0 6px rgba(0,0,0,.8)}
.rc-marker.is-active .rc-dot,.rc-centre.is-active .rc-core{box-shadow:0 0 0 3px rgba(79,216,255,.35),0 0 18px currentColor}

/* A contact the radar sweep has not reached yet is not on the scene at all —
   it is in the markup so the arm has something to light up, and nothing else.
   When the arm crosses it, it blips in: the marker fades up and its dot pops.
   Both animations fill backwards only, so the moment they end the marker is an
   ordinary one again and its hover scale is its own. Neither states a closing
   frame for what it borrows (the `uFlash` idiom, css/ui.css): the pop resolves
   back to whatever shadow the marker itself carries, so an open contact's lit
   ring survives being found. */
.rc-marker.is-unfound{opacity:0;pointer-events:none}
.rc-marker.is-found{animation:rc-found .45s ease-out backwards}
.rc-marker.is-found .rc-dot{animation:rc-found-pop .5s cubic-bezier(.2,1.5,.35,1) backwards}
@keyframes rc-found{from{opacity:0}}
@keyframes rc-found-pop{
  0%  {transform:scale(.3);box-shadow:0 0 0 10px rgba(79,216,255,.35),0 0 26px currentColor}
  60% {transform:scale(1.16)}
  100%{transform:scale(1)}
}

/* The gate at the centre of its own sector. */
.rc-centre{color:var(--gold)}
.rc-centre.is-sealed{color:#7f9ab4}
.rc-core{
  width:var(--rc-anchor);height:var(--rc-anchor);border-radius:50%;
  display:grid;place-items:center;font-size:24px;line-height:1;
  border:2px solid currentColor;
  background:radial-gradient(circle at 50% 40%,rgba(60,44,10,.9),rgba(3,9,20,.96));
  box-shadow:0 0 26px rgba(255,200,68,.25);
}
.rc-centre.is-sealed .rc-core{background:radial-gradient(circle at 50% 40%,rgba(24,34,52,.95),rgba(3,9,20,.96));box-shadow:none}
.rc-core-state{font:700 10px/1 var(--u-font-ui);letter-spacing:.16em}
.rc-core-name{font:600 11px/1.2 var(--u-font-ui);color:var(--u-label)}

/* ── Contact popup ─────────────────────────────
   One contact's full detail and the actions it accepts, anchored to the marker
   that opened it (placed by `placePop` in views/map.js). It shares the markers'
   stacking level and follows them in DOM order, so it reads over them without
   inventing a z-index; the bays above it own --z-bay. */
.rc-pop{
  position:absolute;z-index:var(--z-panel);
  width:max-content;max-width:min(320px,calc(100% - 16px));
  max-height:calc(100% - 16px);overflow-y:auto;
  display:flex;flex-direction:column;gap:6px;
  padding:10px 12px;
  border:1px solid var(--u-line-dim);border-radius:var(--u-r);
  background:var(--u-glass-flat);
  box-shadow:0 10px 30px rgba(0,0,0,.6),0 0 0 1px rgba(79,216,255,.10);
}
.rc-pop[hidden]{display:none}
.rc-pop-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.rc-pop-name{
  flex:1 1 auto;min-width:0;overflow-wrap:anywhere;
  font:700 14px/1.25 var(--u-font-ui);color:var(--u-value);
}
.rc-pop-note{font:400 12px/1.4 var(--u-font-ui);color:var(--u-body)}

/* ══ Reflow ═══════════════════════════════════════
   The kit's three breakpoints, doing the kit's three jobs (css/ui.css, and
   UI-REDESIGN.md §4 Phase 7). The design target is a phone held in landscape —
   740×390 — so width is what the projection and the orbital display need, and
   height is the axis there is least of. */

/* A strip's declared height is a floor here, not a ceiling: "Scanner — <a long
   sector name>" wraps onto a second line rather than being clipped, and
   `rebuildLayout` measures whatever height that leaves. */
.gx-strip .u-strip,.rc-layer .u-strip{height:auto;min-height:56px}

/* Narrow: a node's plate stops out-measuring its hexagon, and the caption gives
   the scene back the height its description was spending. */
@media (max-width:900px){
  .gx-strip .u-strip,.rc-layer .u-strip{min-height:48px}
  .gx-node{max-width:150px}
  .rc-info{padding:10px 12px}
  .rc-info-name{font-size:17px}
  .rc-info-desc{-webkit-line-clamp:2;line-clamp:2}
}

/* Short: the landscape phone. Height is the scarce axis and the rings are drawn
   in it, so the caption keeps only what names the sector — the strip's chip
   already carries the scanner counters, and a locked sector's prerequisites are
   named on its projection plate. */
@media (max-height:520px){
  .gx-strip .u-strip,.rc-layer .u-strip{min-height:48px}
  .gx-node{max-width:132px}
  /* The plate's own box is what a second row of nodes has to fit between, so
     it tightens along with the hexagon the kit already shrank. */
  .gx-node .u-hex{gap:5px}
  .gx-node .u-hex-plate{padding:3px 8px}
  .rc-info{padding:7px 10px;gap:2px}
  .rc-info-name{font-size:15px}
  .rc-info-desc{display:none}
  .rc-name{font-size:11px}
  .rc-meta{font-size:10px}
  .rc-centre{--rc-anchor:44px}
  .rc-core{font-size:20px}
}

/* Touch: hit areas a finger can land on, and an `:active` wherever a hover
   state was the only feedback. */
@media (pointer:coarse){
  .rc-marker{--rc-anchor:44px;min-width:44px}
  .rc-dot{font-size:19px}
  .rc-marker:active .rc-dot{transform:scale(1.12)}
  /* Every contact action is a finger target — the popup's own `.btn-xs` is
     about 20px tall. */
  .rc-pop .btn{min-height:44px}
}
