:root {
  --bg: #050508;
  --border: #0f1a14;
  --green: #00FF87;
  --text: #b8e6c8;
  --text-secondary: #7dba94;
  --muted: #3d6b4e;
  --input-bg: #050508;
  --font-head: 'JetBrains Mono', monospace;
  --font-body: 'JetBrains Mono', monospace;
  --radius: 2px;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  touch-action: manipulation;
  /* Charlie msg 6307 : no text in the game should be selectable. Kills
     the iOS / Android long-press selection + the desktop drag-to-
     highlight that distracted from the game's own gestures. Inputs +
     textareas (the feedback form, sprite editor target picker, dev
     code field, etc.) are opted back in below. */
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

input, textarea, [contenteditable="true"] {
  -webkit-user-select: text;
  -ms-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 0.5rem 0;
}

#root {
  width: 100%;
  max-width: 640px;
  padding: 0 0.25rem;
}

button {
  font-family: inherit;
  cursor: pointer;
  /* Charlie msg 6296 : kill the native long-press text selection (blue
     highlight) + the iOS long-press callout menu. Long-presses on
     game buttons must trigger the game's own gesture, not the OS. */
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

.bf-clickable {
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Charlie msg 6168/6172 — universal "this is interactive" feedback.
   Inline styles set background/border, but filter+transform stay free
   so the CSS hover/active states always land. Mobile gets the :active
   press feedback (no hover). */
.bf-clickable {
  transition: filter 120ms ease, transform 100ms ease;
}
.bf-clickable:hover {
  filter: brightness(1.15) drop-shadow(0 0 8px rgba(0, 255, 135, 0.35));
  transform: scale(1.02);
}
.bf-clickable:active {
  filter: brightness(0.92);
  transform: scale(0.97);
}

/* Charlie 2026-05-26 — desktop : hovering the goal bar was scaling
   the whole row, which pushed the inner Settings gear out from under
   the cursor right as the player tried to click it. Keep the
   filter/glow feedback so the bar still announces interactivity, but
   drop the transform so child buttons (Settings, OPEN) don't move
   under the pointer. Inner .bf-clickable children still scale on
   their own hover. */
.bf-goal-panel.bf-clickable:hover,
.bf-goal-panel.bf-clickable:active {
  transform: none;
}

/* Pulsing "▾" pill that surfaces the Goal panel as an openable card. */
@keyframes bfGoalChipPulse {
  0%, 100% { opacity: 0.78; box-shadow: 0 0 6px rgba(255, 204, 51, 0.35); }
  50%      { opacity: 1;    box-shadow: 0 0 12px rgba(255, 204, 51, 0.65); }
}
.bf-goal-chip {
  animation: bfGoalChipPulse 1.6s ease-in-out infinite;
}

canvas {
  touch-action: none;
}

/*
 * v0.30.286 — Desktop layout v2 (Charlie msg 5289).
 *
 * Mobile (default, < 1024px) is byte-identical to the tagged
 * stable-mobile-v0.30.284 baseline. Every desktop rule lives inside
 * @media (min-width: 1024px) below — if the query never fires, this
 * file is inert. Rollback path : `git checkout stable-mobile-v0.30.284`.
 *
 * Desktop layout :
 *
 *   ┌────────────────────────────────────────────────────────┐
 *   │  HUD ($, XP, AUTO, MOD/DEX/HUB)                         │
 *   │  Tier nav  ─  T1 T2 T3 ...                              │
 *   ├──────────┬──────────────────────────────────────────┤
 *   │   SHOP   │           CANVAS GRID                       │
 *   │   (left  │       (centre, takes the room)              │
 *   │   perm.) │                                              │
 *   │          │                                              │
 *   ├──────────┴──────────────────────────────────────────┤
 *   │                       GOAL                              │
 *   ├────────────────────────────────────────────────────────┤
 *   │      ⚡ POWER   ·   $/sec   ·   ψ AGENTS               │
 *   └────────────────────────────────────────────────────────┘
 *
 * 2-column grid on rows that need the side-by-side ; rows that go
 * full-width (HUD, tier, goal) span both columns. The right-side
 * library panel and the DEX/HUB tab-switch land in a follow-up
 * commit — for now MOD/DEX/HUB still pop as modal overlays.
 */
@media (min-width: 1024px) {
  body {
    align-items: center;
    /* Bottom padding = bottom-bar height + breathing so the goal
       panel sits above it cleanly. */
    padding: 1rem 1.5rem 4rem;
  }
  #root {
    max-width: 1500px;
    width: 100%;
    padding: 0;
  }
  /* v0.30.465 — Charlie msg 5838 (screenshot) : the grid layout was
     being applied to #root, but bot-factory.js wraps the whole UI in
     a `.bot-factory-root` div that sets inline `max-width: min(640px,
     100vw)` + `display: flex`. So #root could be grid all it wanted,
     the actual children all lived inside a 640-pixel flex column and
     desktop saw a mobile-shaped game shoved against the left edge.
     Move the grid layout (and the inline-style overrides) onto
     .bot-factory-root directly so the real container claims the
     viewport. !important is needed to beat inline styles. */
  /* v0.30.466 — Charlie msg 5840 : 3-column desktop. Shop expands into
     a permanent left rail with all machines visible (no scroll, bigger
     tiles), grid stays centred, HUD ($ + XP + AUTO + MOD/DEX/HUB)
     moves to a right rail. Tier nav stays on top, goal stays below.
     v0.30.467 — Charlie : page was scrolling on smaller viewports.
     Lock the root to exactly viewport-minus-body-padding and clip
     overflow ; the shop scrolls internally if it has more machines
     than the rail can show at once.
     v0.30.477 — Charlie msg 5880 : rails widen with viewport via
     clamp(), tiles + popups get more breathing room, bottom-bar
     slimmed visually on desktop so the right rail is the main read. */
  .bot-factory-root {
    max-width: 1500px !important;
    width: 100% !important;
    height: calc(100dvh - 5rem) !important;
    min-height: 0 !important;
    display: grid !important;
    grid-template-columns: clamp(280px, 22vw, 360px) minmax(0, 1fr) clamp(280px, 22vw, 360px);
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "tier   tier   tier"
      "shop   grid   hud"
      "goal   goal   goal";
    column-gap: 1.25rem;
    row-gap: 0.6rem;
    padding: 0 !important;
    overflow: hidden !important;
  }
  .bf-hud {
    grid-area: hud;
    min-width: 0;
    min-height: 0;
    align-self: stretch;
    overflow-y: auto;
    /* HUD on desktop = right side panel. */
    padding: 0.6rem 0.85rem !important;
    gap: 0.55rem !important;
  }
  .bf-tier-bar {
    grid-area: tier;
    min-width: 0;
  }
  .bot-factory-canvas-host {
    grid-area: grid;
    min-height: 0;
  }
  .bf-shop-wrap {
    grid-area: shop;
    min-width: 0;
    min-height: 0;
    /* Match the grid's vertical extent so the shop is a tall column
       on the left instead of a squat horizontal scroller. The wrap
       owns its own scroll so the page-level chrome never scrolls. */
    align-self: stretch;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .bf-goal-panel {
    grid-area: goal;
    min-width: 0;
  }

  /* SHOP on desktop : kill the horizontal-scroller layout. Override
     the inline styles bot-factory.js writes (display:grid with column
     auto-flow + JS-driven translateX) so all machines tile vertically
     in a 2-column grid. !important is required because every property
     here was set inline. */
  .bf-shop-wrap > div:first-child {  /* shopScroll */
    overflow: visible !important;
    height: 100%;
  }
  .bf-shop-wrap > div:first-child > div {  /* inner shop grid */
    grid-auto-flow: row !important;
    grid-template-rows: none !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    grid-auto-columns: auto !important;
    width: 100% !important;
    transform: none !important;
    gap: 0.35rem !important;
    padding: 0.4rem !important;
  }
  /* Edge arrows are siblings of shopScroll — useless without horizontal
     scroll. Hide on desktop. */
  .bf-shop-wrap > div:not(:first-child) {
    display: none !important;
  }
  /* Shop tiles : roomy enough to read the icon + label.
     v0.30.477 — Charlie msg 5880 : bumped to 80 px so tiles take up
     the rail's vertical real estate properly. On a 360-px rail the
     tiles are now ~110 wide × 80 tall. Internal scroll still catches
     a 768-px laptop if needed. */
  .bf-shop-wrap > div:first-child > div > button {
    min-height: 80px !important;
    width: auto !important;
    font-size: 0.7rem !important;
  }

  /* Footer (bottom-bar) — centred, cohesive, bigger.
   * Mobile keeps justify-content: space-between with gauges glued to
   * the edges. On desktop the three readouts (⚡ / $-drain / net $)
   * group in the middle with consistent gaps so they read as ONE
   * status row, not three scattered widgets. */
  #bf-bottom-bar {
    justify-content: center !important;
    gap: 2.5rem;
    height: 48px !important;
    font-size: 0.88rem !important;
    padding: 0 2rem !important;
  }
  #bf-bottom-bar > * {
    margin-left: 0 !important;
  }

  /* v0.30.466 — Charlie msg 5841 : popup panels (Goal, Modules,
     Codex, Hub, Settings, confirm dialogs, …) inherit makePanel's
     `min-width: min(260px, 80%) ; max-width: 90%`. On a phone that's
     the right framing ; on a 1500-px desktop it's a cramped little
     postage stamp surrounded by dead black. Roomy frame so the same
     content breathes.
     v0.30.477 — Charlie msg 5880 : bumped further — most popups now
     happily take 800-1080 px on a wide screen. */
  .bf-popup-panel {
    min-width: 640px !important;
    max-width: min(1080px, 90vw) !important;
    padding: 1.6rem 1.9rem !important;
    max-height: 88vh !important;
    overflow-y: auto !important;
  }

  /* v0.30.469 — Charlie msg 5846 : the circuit-edit instruction banner
     defaults to top-centred (under mobile, the dead space between the
     status bar and the grid). On desktop that lands smack on top of
     the centre grid. Park it in the right rail (above the HUD) so
     the player can still see the cells they're tapping. */
  .bf-circuit-banner {
    left: auto !important;
    right: 1rem !important;
    transform: none !important;
    width: clamp(300px, 22vw, 360px) !important;
    max-width: clamp(300px, 22vw, 360px) !important;
  }

  /* v0.30.477 — Charlie msg 5880 : on desktop the bottom-bar becomes
     a slim status strip. The right rail is the main HUD now ; the
     bar shouldn't compete. */
  #bf-bottom-bar {
    height: 40px !important;
    font-size: 0.78rem !important;
    background: rgba(5, 5, 8, 0.92) !important;
    backdrop-filter: blur(4px);
    border-top: 1px solid rgba(0, 255, 135, 0.18);
  }

  /* Charlie 2026-05-26 — Settings popup was a 440-px ribbon on a
     1500-px monitor. Widen to a roomy 880 px with extra padding ;
     the per-section tinted containers (added in the same pass) now
     do the structural grouping, so a single column with bigger rows
     reads cleanly on both mobile and desktop. */
  .bf-settings-panel {
    width: 880px !important;
    max-width: 94% !important;
    padding: 1.4rem 1.8rem !important;
  }
  .bf-settings-panel button {
    font-size: 0.85rem !important;
    padding: 0.7rem 1rem !important;
  }

  /* Charlie 2026-05-26 — Hub / Tech Tree window : the 440-px
     hub corridor squeezed every drawer into a horizontal scroll
     from the first column. Widen to 1100 px so a typical branch fits
     two or three depth columns at a glance, with extra padding for
     breathing. */
  .bf-hub-panel {
    width: 1100px !important;
    max-width: 94% !important;
    padding: 1.4rem 1.8rem !important;
  }
}
