/* css/components.css - SHARED UI COMPONENTS. One recipe per component, every colour from css/theme.css roles.
 * Plan: .claude/PLAN_color_system.md. Loaded after every other stylesheet. The GL map HUD (CSS injected by
 * js/gl_map_c4.js) reads the same --btn-* tones, so map HUD buttons and command buttons are one style.
 *
 * BUTTON (owner 2026-10-04: map HUD buttons and every command button unified; uppercase; two sizes)
 *   .btn          26px, the HUD button look              .btn.sm   compact, text height (table rows, sentences)
 *   .btn.xs       17px squares (combat card actions)     .btn.icon square, icon only
 *   tones         .danger .warn .ok .info .armed .accent  states    .on (selected / pressed), .disabled, :disabled
 *   .btn.primary  filled with its tone (save, confirm)
 * Old class names are ALIASES in the selector lists below, so markup and JS state classes keep working.
 * A tone only sets --btn-tone / --btn-fg / --btn-fg-hi; the recipe reads them with fallbacks (never declare
 * defaults on the button itself: ID-scoped aliases would out-rank the tone classes).
 */

/* ---------------- base (26px) + shared recipe ---------------- */
.btn, .tac-btn, .dialogButton,
.btn_cmd_simple, .btn_cmd_simple_disabled, .btn_cmd_simple_todo, .btn_cmd_simple_red, .btn_cmd_simple_yellow,
.cmd_color-rental_btn, .c4_gcmd_go, .c4_gcmd_cancel,
.btn_clear, .btn_clear_left, .btn_clear_red_left, .btn_clear_white, .btn_clear_white_left, .btn_export, .btn_interact_left, .btn_ge_simple,
.dialogButton_s, .dialogButton_slim,
.ops_btn, .ml_iconbtn, .le_btn, #ops_loop_editor button, .le_mvpop button,
.glcs-act {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 26px;
  padding: 0 12px;
  font-family: EEMfont, ui-monospace, monospace;
  font-size: 10px;
  font-weight: normal;
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--btn-fg, var(--c-btn-text));
  background: var(--c-btn-fill);
  border: 1px solid color-mix(in srgb, var(--btn-tone, var(--c-btn-tone)) 40%, transparent);
  border-radius: 5px;
  opacity: 1;
  cursor: pointer;
  user-select: none;
  transition: background-color .12s, color .12s, border-color .12s;
}
.btn:hover, .tac-btn:hover, .dialogButton:hover,
.btn_cmd_simple:hover, .btn_cmd_simple_red:hover, .btn_cmd_simple_yellow:hover,
.cmd_color-rental_btn:hover, .c4_gcmd_go:hover, .c4_gcmd_cancel:hover,
.btn_clear:hover, .btn_clear_left:hover, .btn_clear_red_left:hover, .btn_clear_white:hover, .btn_clear_white_left:hover, .btn_export:hover, .btn_interact_left:hover, .btn_ge_simple:hover,
.dialogButton_s:hover, .dialogButton_slim:hover,
.ops_btn:hover, .ml_iconbtn:hover, .le_btn:hover, #ops_loop_editor button:hover, .le_mvpop button:hover,
.glcs-act:hover {
  color: var(--btn-fg-hi, var(--c-btn-text-hi));
  background: color-mix(in srgb, var(--btn-tone, var(--c-btn-tone)) 14%, var(--c-btn-fill));
  border-color: color-mix(in srgb, var(--btn-tone, var(--c-btn-tone)) 65%, transparent);
}

/* ---------------- placeholder in a button-styled input (owner 2026-10-18) ----------------
 * Same font, size, case and spacing as the button text, in the button's own text colour, dimmed. Beats the global
 * input::placeholder in basic-ui.css (other font size, no uppercase). */
:is(.btn, .tac-btn, .dialogButton, .btn_cmd_simple, .btn_cmd_simple_disabled, .btn_cmd_simple_todo, .btn_cmd_simple_red, .btn_cmd_simple_yellow, .cmd_color-rental_btn, .c4_gcmd_go, .c4_gcmd_cancel, .btn_clear, .btn_clear_left, .btn_clear_red_left, .btn_clear_white, .btn_clear_white_left, .btn_export, .btn_interact_left, .btn_ge_simple, .dialogButton_s, .dialogButton_slim, .ops_btn, .ml_iconbtn, .le_btn, #ops_loop_editor button, .le_mvpop button, .glcs-act)::placeholder {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--btn-fg, var(--c-btn-text));
  opacity: .45;
}

/* ---------------- compact: text height, for table rows and sentences ---------------- */
.btn.sm,
.btn_cmd_simple, .btn_cmd_simple_disabled, .btn_cmd_simple_todo, .btn_cmd_simple_red, .btn_cmd_simple_yellow,
.cmd_color-rental_btn, .c4_gcmd_go, .c4_gcmd_cancel,
.btn_clear, .btn_clear_left, .btn_clear_red_left, .btn_clear_white, .btn_clear_white_left, .btn_export, .btn_interact_left, .btn_ge_simple,
.dialogButton_s, .dialogButton_slim,
.ops_btn, .ml_iconbtn, .le_btn, #ops_loop_editor button, .le_mvpop button {
  display: inline-block;
  height: auto;
  line-height: 1.7;
  padding: 0 .6em;
  font-size: .85rem;
  letter-spacing: .06em;
  border-radius: 3px;
}

/* ---------------- xs: 17px squares ---------------- */
.btn.xs, .glcs-act { height: 17px; padding: 0 4px; font-size: 11px; letter-spacing: 0; border-radius: 3px; }

/* ---------------- icon-only ---------------- */
.btn.icon { width: 26px; padding: 0; }
.btn.sm.icon { width: auto; min-width: 1.9em; padding: 0 .3em; }

/* ---------------- tones ---------------- */
.btn.danger, .btn_cmd_danger, .c4_gcmd_cancel, .btn_clear_red_left, .ops_btn_stop, .le_btn_stop, .tac-btn.attack, .glcfg-abandon {
  --btn-tone: var(--c-status-danger); --btn-fg: var(--c-status-danger); --btn-fg-hi: color-mix(in srgb, var(--c-status-danger) 70%, var(--p-white));
}
.btn.warn, .btn_cmd_simple_red, .btn_clear, .btn_clear_left, .btn_ge_simple, .tac-btn.intercept, .tac-btn.follow, .tac-btn.reload {
  --btn-tone: var(--c-status-warn); --btn-fg: var(--c-status-warn); --btn-fg-hi: color-mix(in srgb, var(--c-status-warn) 70%, var(--p-white));
}
.btn.ok, .ops_btn_launch, .le_launch {
  --btn-tone: var(--c-status-ok); --btn-fg: var(--c-status-ok); --btn-fg-hi: color-mix(in srgb, var(--c-status-ok) 70%, var(--p-white));
}
.btn.info, .tac-btn.repair, .tac-btn.selfrep, .ml_stop_armed {
  --btn-tone: var(--c-status-info); --btn-fg: var(--c-status-info); --btn-fg-hi: color-mix(in srgb, var(--c-status-info) 70%, var(--p-white));
}
.btn.accent { /* main call to action in the scheme accent colour (RYDN Billboards: verify wallet, place bid, ...) */
  --btn-tone: var(--c-accent); --btn-fg: var(--c-accent); --btn-fg-hi: color-mix(in srgb, var(--c-accent) 70%, var(--p-white));
}
.btn.armed, .btn_cmd_simple_yellow, .glbtm-mv.armed, .glcs-act.armed, .le_revert {
  --btn-tone: var(--c-armed); --btn-fg: var(--c-armed); --btn-fg-hi: var(--c-armed);
}
.btn.armed, .glbtm-mv.armed { box-shadow: 0 0 8px color-mix(in srgb, var(--c-armed) 40%, transparent); }
/* rentals keep their own meaning colour (own = rent-list lavender, borrowed = rent-borrowed) */
.cmd_color-rental_btn, .cmd_color-rental { --btn-tone: var(--c-rent-list); --btn-fg: var(--c-rent-list); --btn-fg-hi: color-mix(in srgb, var(--c-rent-list) 70%, var(--p-white)); }
.cmd_color-rental_borrowed_btn, .cmd_color-rental_borrowed { --btn-tone: var(--c-rent-borrowed); --btn-fg: var(--c-rent-borrowed); --btn-fg-hi: color-mix(in srgb, var(--c-rent-borrowed) 70%, var(--p-white)); }

/* ---------------- states ---------------- */
.btn.on, .ops_btn.on {
  color: var(--btn-fg-hi, var(--c-btn-text-hi));
  background: color-mix(in srgb, var(--btn-tone, var(--c-btn-tone)) 28%, transparent);
}
/* filled call-to-action (save, confirm, build) */
.btn.primary, #le_save.dirty, .cj_done, .stkb_build_btn {
  color: var(--c-text-on-accent);
  background: var(--btn-tone, var(--c-btn-tone));
  border-color: var(--btn-tone, var(--c-btn-tone));
  font-weight: 600;
}
#le_save.dirty { --btn-tone: var(--c-armed); }
.cj_done { --btn-tone: var(--c-armed); }
.stkb_build_btn { --btn-tone: var(--c-status-warn); }
.btn.primary:hover, #le_save.dirty:hover, .cj_done:hover, .stkb_build_btn:hover {
  color: var(--c-text-on-accent);
  background: color-mix(in srgb, var(--btn-tone, var(--c-btn-tone)) 82%, var(--p-white));
}
/* disabled: ONE look. Clickability is left to each family (some stay clickable so the click can say why) */
.btn.disabled, .btn:disabled, .btn_cmd_simple_disabled, .btn_cmd_simple_todo, .c4_gcmd_disabled, .c4_gcmd_soon,
.ops_btn.dim, .le_dis, .tac-btn.disabled, .glbtm-mv.disabled, .glcs-act.disabled, #ops_loop_editor button:disabled,
.cmd_color-rental-disabled, .cmd_color-rental_btn-disabled {
  opacity: .35;
  cursor: not-allowed;
}
.btn.disabled:hover, .btn:disabled:hover, .btn_cmd_simple_disabled:hover, .btn_cmd_simple_todo:hover, .ops_btn.dim:hover,
.tac-btn.disabled:hover, .glcs-act.disabled:hover, #ops_loop_editor button:disabled:hover {
  color: var(--btn-fg, var(--c-btn-text));
  background: var(--c-btn-fill);
  border-color: color-mix(in srgb, var(--btn-tone, var(--c-btn-tone)) 40%, transparent);
}

/* ---------------- GLASS PANES = the right-click menu look (#mnu_map, .ui-mnu) ----------------
 * Owner 2026-10-05: on-map panes AND the ops loop editor / list view become glass: --c-pane-bg (5% black) over a
 * blurred backdrop, --c-pane-frame hairline, 8px radius. The GL map panes carry the blur in their own injected CSS.
 * Blur goes on each PANE, never on #ops_container: its popups are position:fixed children, and a backdrop-filter on
 * an ancestor would re-anchor them. */
:root { --pane-blur: 12px; }
#ops_loop_editor .le_bar, #ops_loop_editor .le_flow, #ops_loop_editor .le_stage, #ops_loop_editor .le_side,
#ops_container .ops_setups, #ops_simple_list .ml_root,
.le_menu, .le_mvpop, .ml_combopop, .ml_respop {
  backdrop-filter: blur(var(--pane-blur));
  -webkit-backdrop-filter: blur(var(--pane-blur));
}

/* MAP OFF / BACKGROUND MODE (2026-10-09): every looping CSS animation (pulsing ops dots, blinkers, spinners) keeps
 * Chrome rendering ~60 frames/s, and the GPU process composites each one. Measured with the map OFF: GPU process 94% ->
 * 3.7% CPU, tab 64% -> 20% once animations stop. body.map-off is set by mapMode_ui() (index.html GL boot block). Dots
 * keep their colour, they only stop pulsing. Nothing in the app listens for animationend (checked), so none is cut short. */
body.map-off *, body.map-off *::before, body.map-off *::after { animation: none !important; }

/* GL MAP NOT RUNNING (LIGHT / OFF, 2026-10-09): the GL map builds its HUD, callout cards, own-fleet markers, labels,
 * radar and fx layers as children of #content-map-canvas and glMap_stop() hides only some of them, so the tactical HUD,
 * cards and markers stayed over the 2D map. body.gl-off (mapMode_ui, index.html) hides EVERY child except the 2D map
 * canvases, the 2D system preview (canvas_map.js) and the map-paused placeholder. glMap_start removes the class. */
body.gl-off #content-map-canvas > :not(#heatView):not(#dataView):not(#galaxyView):not(#fleetView):not(#systemPreview):not(#map_off_placeholder) { display: none !important; }

/* A button inside an ACTIVE settings row (.opt_on = --c-selected background, e.g. the PUSH "Enable" row with its
   TEST button): use the row's own dark text role so it reads on the highlight instead of the pale default. */
.opt_on .btn {
  --btn-fg: var(--c-text-inverse);
  --btn-tone: var(--c-text-inverse);
  background: transparent;
}
