* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #05060f;
  font-family: 'Press Start 2P', monospace;
  touch-action: manipulation;
}

/* the pixel banner behind the stage — seen only where the window is wider
   than the phone-proportioned #start-screen. A small pixflux image
   (tools/gen-backdrop.py) scaled up nearest-neighbour so it stays crisp. */
body {
  background: #05060f url('../assets/ui/page-backdrop.png') center / cover no-repeat;
  image-rendering: pixelated;
}

/* the stage keeps a phone's proportions on any window: full height, at most
   390/844 of it wide, centred — js/core/stage.mjs computes the same width */
#start-screen {
  position: fixed;
  inset: 0;
  width: min(100vw, calc(100vh * 390 / 844));
  margin: 0 auto;
  overflow: hidden;
  background: #05060f;
  box-shadow: 0 0 0 1px #1e2450, 0 0 40px #000;
  image-rendering: auto; /* body's pixelated is for the banner only */
}

#audio-hint {
  z-index: 2;
  position: absolute;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  font-size: calc(8px * var(--fs, 1));
  color: #555f7f;
  letter-spacing: 1px;
  pointer-events: none;
}

#player {
  z-index: 1;
  position: absolute;
  width: 64px;
  height: 64px;
  image-rendering: pixelated;
}

#game-over {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 3;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  font-size: calc(32px * var(--fs, 1));
  letter-spacing: 4px;
  color: #f33;
  background: rgba(0, 0, 0, 0.7);
  cursor: pointer;
}

#game-over span {
  font-size: calc(12px * var(--fs, 1));
  letter-spacing: 2px;
  color: #fff;
}

/* clear overlay box — content built by js/ui/clear.overlay.mjs (M007) */
#win-screen {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 3;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.7);
  cursor: pointer;
}

.collision-box {
  position: absolute;
  border: 1px solid;
  box-sizing: border-box;
  z-index: 2;
  pointer-events: none;
}

#stars {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.star {
  position: absolute;
  background: #9fc3e8;
}

.enemy {
  position: absolute;
  image-rendering: pixelated;
  z-index: 1;
}

/* pooled bullets (bullets.mjs) — positioned via transform, sized inline */
.pool-bullet {
  position: absolute;
  left: 0;
  top: 0;
  image-rendering: pixelated;
  z-index: 1;
}

.blast-ring {
  position: absolute;
  left: 0;
  top: 0;
  border: 2px solid rgba(255, 136, 0, 0.45);
  border-radius: 50%;
  pointer-events: none;
  z-index: 1;
}

.enemy.hit {
  filter: brightness(0.6) sepia(1) saturate(6) hue-rotate(-45deg);
}

/* absorbed while entering (invulnerable phase) — white tell, no damage */
.enemy.hit-white {
  filter: brightness(0) invert(1);
}

/* boss phase 2 (rageTell state live) — the warden burns hot: tint + aura.
   Persistent (unlike .hit); hit-flash filters override it for 120ms only. */
.enemy.rage {
  filter: sepia(1) saturate(5) hue-rotate(-40deg) brightness(1.15)
          drop-shadow(0 0 14px rgba(255, 64, 48, 0.85));
}
/* ---- HUD: parallelogram health pips ---- */
#hud {
  position: absolute;
  top: 14px;
  left: 14px;
  width: auto;
  height: auto;
  z-index: 5;
  pointer-events: none;
}

.hud-pip {
  fill: #f87171;
  stroke: #fbbf24;
  stroke-width: 1;
  filter: drop-shadow(0 0 3px rgba(248, 113, 113, 0.6));
  transition: fill 120ms;
}

.hud-pip.empty {
  fill: rgba(255, 255, 255, 0.06);
  stroke: rgba(255, 255, 255, 0.25);
  filter: none;
}

/* blink while invulnerable */
#player.invuln {
  animation: blink 150ms linear infinite;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* shield halo — cyan circle at 25% opacity around the ship */
.shield-ring {
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: rgba(34, 211, 238, 0.10);
  border: 2px solid rgba(34, 211, 238, 0.25);
  box-shadow: 0 0 14px rgba(34, 211, 238, 0.25), inset 0 0 10px rgba(34, 211, 238, 0.15);
  z-index: 0;
  pointer-events: none;
  display: none;
}

/* ---- Cores meter (bottom edge) ---- */
#core-hud {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 10px;
  z-index: 5;
  pointer-events: none;
}

.hud-core-track {
  fill: rgba(255, 255, 255, 0.08);
  stroke: rgba(255, 255, 255, 0.18);
  stroke-width: 1;
}

.hud-core-fill {
  fill: #fbbf24;
  filter: drop-shadow(0 0 5px rgba(251, 191, 36, 0.8));
  transition: width 120ms linear;
}

.hud-core-fill.full {
  fill: #fff7d6;
}

.hud-core-label {
  font-family: 'Press Start 2P', monospace;
  font-size: calc(8px * var(--fs, 1));
  fill: rgba(255, 255, 255, 0.75);
  text-anchor: end;
}

/* ---- pixel particles ---- */
.particle {
  position: absolute;
  z-index: 4;
  pointer-events: none;
}

/* ---- in-run upgrade panel (U to toggle, pauses the run) ---- */
#upgrade-panel {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* never wider than the play column: 460 on desktop, screen - 16 on phones */
  width: min(460px, calc(100% - 16px));
  box-sizing: border-box;
  background: rgba(6, 10, 24, 0.92);
  border: 2px solid rgba(251, 191, 36, 0.6);
  box-shadow: 0 0 24px rgba(0, 0, 0, 0.8), 0 0 14px rgba(251, 191, 36, 0.25);
  padding: 14px 12px;
  z-index: 20;
  font-family: 'Press Start 2P', monospace;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  color: #fbbf24;
  font-size: calc(11px * var(--fs, 1));
  margin-bottom: 12px;
  letter-spacing: 1px;
}

#panel-points {
  color: #fff7d6;
}

.panel-row {
  display: grid;
  /* label | pip strip (shrinks with the panel) | value | buy */
  grid-template-columns: 84px minmax(0, 1fr) 40px max-content; /* fixed label + value columns keep every pip strip aligned */
  align-items: center;
  gap: 8px;
  padding: 5px 4px;
  font-size: calc(9px * var(--fs, 1));
  color: #e5e7eb;
  cursor: pointer;
}

.panel-row:hover {
  background: rgba(251, 191, 36, 0.08);
}

.panel-row.maxed {
  opacity: 0.45;
  cursor: default;
}

.panel-label {
  width: auto;
}

.panel-pips {
  display: flex;
  gap: 3px;
}

.panel-pips i {
  display: block;
  flex: 0 1 9px;
  min-width: 3px;
  height: 14px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
  transform: skewX(-12deg);
}

.panel-pips i.on {
  background: #fbbf24;
  border-color: #fde68a;
  box-shadow: 0 0 4px rgba(251, 191, 36, 0.7);
}

.panel-val {
  width: auto;
  text-align: right;
  color: #9ca3af;
}

.panel-buy {
  color: #6b7280;
  border: 1px solid rgba(255, 255, 255, 0.15);
  padding: 4px 8px;
}

.panel-buy.afford {
  color: #fbbf24;
  border-color: rgba(251, 191, 36, 0.7);
}

.panel-buy.maxed {
  color: #4b5563;
  border-color: transparent;
  cursor: default;
}

/* the run offer — shape · cadence · passive on ONE line, equal widths,
   shrinking with the panel (the section rows are display: contents).
   Run-scoped buys; state derives from the live fireDef. */
.panel-offer {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}
.panel-fire, .panel-passive { display: contents; }

.panel-firebtn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  color: #6b7280;
  border: 1px solid rgba(255, 255, 255, 0.15);
  padding: 6px 4px;
  cursor: pointer;
}

.panel-firebtn i {
  font-style: normal;
  font-size: calc(10px * var(--fs, 1));
  color: #9ca3af;
}

.panel-firebtn.afford {
  color: #fbbf24;
  border-color: rgba(251, 191, 36, 0.7);
}

.panel-firebtn i.afford, .panel-firebtn.afford i { color: #fbbf24; }

.panel-firebtn.owned {
  color: #34d399;
  border-color: rgba(52, 211, 153, 0.7);
  cursor: default;
}

.panel-firebtn.owned i { color: #34d399; }

.panel-firebtn.locked {
  color: #374151;
  border-color: transparent;
  cursor: default;
}

/* run-offer PASSIVE buttons (P014) — the fire buttons' shape, purple
   afford: the passive accent (fire buttons keep theirs) */

.panel-passivebtn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  color: #6b7280;
  border: 1px solid rgba(255, 255, 255, 0.15);
  padding: 6px 4px;
  cursor: pointer;
}

.panel-passivebtn i {
  font-style: normal;
  font-size: calc(10px * var(--fs, 1));
  color: #9ca3af;
}

.panel-passivebtn.afford {
  color: #a78bfa;
  border-color: rgba(167, 139, 250, 0.7);
}

.panel-passivebtn.afford i { color: #a78bfa; }

.panel-passivebtn.owned {
  color: #34d399;
  border-color: rgba(52, 211, 153, 0.7);
  cursor: default;
}

.panel-passivebtn.owned i { color: #34d399; }

.panel-passivebtn.locked {
  color: #374151;
  border-color: transparent;
  cursor: default;
}

.panel-footer {
  margin-top: 12px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16px;
}

.panel-play {
  font-size: calc(10px * var(--fs, 1));
  color: #0b1020;
  background: #fbbf24;
  padding: 6px 14px;
  cursor: pointer;
}

.panel-play:hover {
  background: #fde68a;
}

.panel-hint {
  font-size: calc(8px * var(--fs, 1));
  color: #6b7280;
}

/* pending points blink next to the rank label */
.hud-core-label.pending {
  fill: #fbbf24;
  animation: core-pending 1s steps(2) infinite;
}

@keyframes core-pending {
  50% { fill: #fff7d6; }
}

/* ---- key drop banner — "+1 key (tier)" flash on boss payout (T008) ---- */
.up-banner {
  z-index: 5;
  position: absolute;
  top: 18%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: calc(16px * var(--fs, 1));
  color: #fbbf24;
  letter-spacing: 2px;
  text-shadow: 0 0 12px rgba(251, 191, 36, 0.6);
  opacity: 0;
  pointer-events: none;
}

.up-banner.show {
  animation: up-banner-pop 2.2s ease-out forwards;
}

@keyframes up-banner-pop {
  0%   { opacity: 0; transform: translate(-50%, -30%) scale(0.6); }
  15%  { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  30%  { transform: translate(-50%, -50%) scale(1); }
  75%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -80%); }
}

/* ---- upgrade tree — Motherload-style panel (proposal §3), built by
   js/ui/tree.panel.mjs and hosted by the SHIPS screen's TREE sub-tab ---- */
.up-viewport {
  flex: 1;
  position: relative;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
}

.up-canvas {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
}

.up-edges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.up-edge {
  stroke-width: 3;
}

.edge-wpn { stroke: #f87171; }
.edge-hul { stroke: #34d399; }
.edge-sup { stroke: #22d3ee; }
.up-edge.dim {
  stroke: #2a3040;
}

.up-node {
  position: absolute;
  width: 96px;
  height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-size: calc(8px * var(--fs, 1));
  letter-spacing: 1px;
  background: #0d1120;
  border: 2px solid #2a3040;
  color: #6b7280;
  user-select: none;
}

.up-node.root {
  border-color: #66e0d0;
  color: #66e0d0;
  width: 112px;
  background: #0a1a1c;
  cursor: default;
}

.up-node i {
  font-style: normal;
  font-size: calc(9px * var(--fs, 1));
  color: #9ca3af;
}

.up-pips {
  display: flex;
  flex-direction: row;
  gap: 3px;
}

.up-node b {
  width: 6px;
  height: 6px;
  background: #1c2233;
  border: 1px solid #2a3040;
}

.up-node b.on {
  background: #fbbf24;
  border-color: #fbbf24;
}

/* buyable — lit by branch color, invites the click */
.up-node.buyable { cursor: pointer; }
.up-node.buyable.wpn { border-color: #f87171; color: #fca5a5; box-shadow: 0 0 10px rgba(248, 113, 113, 0.25); }
.up-node.buyable.hul { border-color: #34d399; color: #6ee7b7; box-shadow: 0 0 10px rgba(52, 211, 153, 0.25); }
.up-node.buyable.sup { border-color: #22d3ee; color: #67e8f9; box-shadow: 0 0 10px rgba(34, 211, 238, 0.25); }
.up-node.buyable i { color: #fbbf24; }

/* owned — filled */
.up-node.owned { cursor: pointer; }
.up-node.owned.wpn { background: #2a1215; border-color: #f87171; color: #fecaca; }
.up-node.owned.hul { background: #0d2418; border-color: #34d399; color: #a7f3d0; }
.up-node.owned.sup { background: #0c2029; border-color: #22d3ee; color: #a5f3fc; }
.up-node.owned i { color: #fbbf24; }

/* poor — req met, wallet can't pay (T005): the glow stays off until it can */
.up-node.buyable.poor { border-color: #2a3040; color: #6b7280; box-shadow: none; cursor: default; }
.up-node.owned.poor { background: #0d1120; border-color: #2a3040; color: #6b7280; cursor: default; }
.up-node.poor i { color: #9ca3af; }

/* maxed — filled, quiet */
.up-node.maxed {
  background: #131a2a;
  border-color: #4b5563;
  color: #d1d5db;
  cursor: default;
}
.up-node.maxed i { color: #6b7280; }

.up-tip {
  position: absolute;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 10px 14px;
  background: #131a2a;
  border: 1px solid #66e0d0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s;
  z-index: 2;
  white-space: nowrap;
}

.up-tip b {
  font-size: calc(9px * var(--fs, 1));
  letter-spacing: 2px;
  color: #66e0d0;
}

.up-tip span {
  font-size: calc(9px * var(--fs, 1));
  color: #d1d5db;
}

.up-tip i {
  font-style: normal;
  font-size: calc(9px * var(--fs, 1));
  color: #fbbf24;
}

/* ---- workshop rows — js/ui/weapons.panel.mjs and js/ui/passives.panel.mjs
   build these inside the SHIPS screen's WORKSHOP sub-tab ---- */
.weapon-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: calc(10px * var(--fs, 1));
  letter-spacing: 2px;
  color: #d1d5db;
  border: 2px solid #2a3040;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 10px;
}

/* PASSIVES tab (P013) — the rows wear the weapon-row construction; the cap
   line + the owned row's EQUIP toggle are the tab's only extras (P017) */
.passive-cap {
  font-size: calc(10px * var(--fs, 1));
  letter-spacing: 2px;
  color: #4b5563;
  margin-bottom: 10px;
}

.passive-row.equipped { border-color: #a78bfa; }

.weapon-state { color: #4b5563; }
.weapon-state.owned { color: #55ff88; }
.weapon-row.affordable { border-color: #66e0d0; cursor: pointer; }
.weapon-state.affordable { color: #66e0d0; }
