/* ---------------------------------------------------------------------------
   Reusable components. Every screen composes from this file; screens.css only
   handles layout that is genuinely specific to one screen.
   --------------------------------------------------------------------------- */

/* ---- Typographic roles -------------------------------------------------
   Orbitron appears only here: small, uppercase, tracked. Anything dense or
   numeric stays on the UI face so it reads at 11-13px. */

.eyebrow {
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-3);
}

.section-title {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-2);
}

.page-title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.01em;
  color: var(--text);
}

.hint {
  font-size: var(--text-xs);
  color: var(--text-3);
  line-height: 1.5;
}

/* ---- Panel -------------------------------------------------------------
   The one card treatment in the app. Elevation and a hairline, no glass, no
   gradient, no glow. */

.panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.panel--flush {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

.panel--interactive {
  transition: border-color var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}

.panel--interactive:hover {
  border-color: var(--line-loud);
  transform: translateY(-1px);
}

.panel__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--panel-pad-tight) var(--panel-pad);
  border-bottom: 1px solid var(--line-soft);
  min-height: 42px;
}

.panel__head-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.panel__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

/* A flex column so stacked children get consistent spacing without every
   screen adding its own wrapper or margin. */
.panel__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--panel-pad);
  min-width: 0;
}

.panel__body--tight {
  padding: var(--panel-pad-tight);
}

/* Flush bodies hold a single list or table that draws its own row separators. */
.panel__body--flush {
  padding: 0;
  gap: 0;
}

.panel__body--fill {
  flex: 1;
  min-height: 0;
}

.panel__foot {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--panel-pad-tight) var(--panel-pad);
  border-top: 1px solid var(--line-soft);
}

/* ---- Buttons -----------------------------------------------------------
   `.btn` is the base; intent modifiers change colour only, size modifiers
   change height and padding only. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-4);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

.btn:hover:not(:disabled) {
  background: var(--surface-3);
  border-color: var(--line-loud);
}

.btn:active:not(:disabled) {
  background: var(--surface-2);
}

.btn--primary {
  background: var(--primary);
  border-color: var(--primary);
  color: #ffffff;
}

.btn--primary:hover:not(:disabled) {
  background: var(--primary-hi);
  border-color: var(--primary-hi);
}

.btn--primary:active:not(:disabled) {
  background: var(--primary-lo);
}

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-2);
}

.btn--ghost:hover:not(:disabled) {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--text);
}

.btn--danger {
  background: transparent;
  border-color: var(--bad-wash);
  color: var(--bad);
}

.btn--danger:hover:not(:disabled) {
  background: var(--bad-wash);
  border-color: var(--bad);
}

/* Second click of a two-step confirm. The colour shift is backed by the label
   changing to name the exact consequence, so this never depends on colour. */
.btn.is-armed {
  background: var(--warn-wash);
  border-color: var(--warn);
  color: var(--warn);
}

.btn.is-armed.btn--danger {
  background: var(--bad-wash);
  border-color: var(--bad);
  color: var(--bad);
}

.btn--sm {
  height: var(--control-h-sm);
  padding: 0 var(--space-3);
  font-size: var(--text-xs);
}

.btn--lg {
  height: var(--control-h-lg);
  padding: 0 var(--space-5);
  font-size: var(--text-md);
}

.btn--block {
  width: 100%;
}

.btn--icon {
  width: var(--control-h);
  padding: 0;
}

.btn--icon.btn--sm {
  width: var(--control-h-sm);
}

.btn__icon {
  width: 15px;
  height: 15px;
  flex: none;
}

/* ---- Segmented control ------------------------------------------------- */

.segmented {
  display: inline-flex;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  gap: 2px;
}

.segmented__option {
  height: 24px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  transition: background-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

.segmented__option:hover:not(:disabled):not(.is-active) {
  background: var(--surface-3);
  color: var(--text);
}

.segmented__option.is-active {
  background: var(--primary);
  color: #ffffff;
}

.segmented--fill {
  display: flex;
}

.segmented--fill .segmented__option {
  flex: 1;
}

/* ---- Toggle switch -----------------------------------------------------
   A real checkbox drives it, so keyboard, label association and the
   accessibility tree all work without extra wiring. */

.toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex: none;
  width: 34px;
  height: 19px;
}

.toggle input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
}

.toggle__track {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  border: 1px solid var(--line);
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
  pointer-events: none;
}

.toggle__track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--text-2);
  transition: transform var(--duration-fast) var(--ease),
              background-color var(--duration-fast) var(--ease);
}

.toggle input:checked + .toggle__track {
  background: var(--primary);
  border-color: var(--primary);
}

.toggle input:checked + .toggle__track::after {
  transform: translateX(15px);
  background: #ffffff;
}

.toggle input:focus-visible + .toggle__track {
  box-shadow: var(--focus-ring);
}

.toggle input:disabled + .toggle__track {
  opacity: 0.45;
}

/* ---- Field -------------------------------------------------------------
   Label, control, and an optional help line. Numeric settings always carry
   their range so no input is an unexplained box. */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.field__label {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text);
}

.field__range {
  margin-left: auto;
  font-size: var(--text-2xs);
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.field__help {
  font-size: var(--text-xs);
  color: var(--text-3);
  line-height: 1.5;
}

/* Label on the left, control on the right -- for toggles and compact rows. */
.field--inline {
  flex-direction: row;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-h);
}

.field--inline .field__label {
  flex: 1;
  min-width: 0;
}

.field--inline .field__help {
  flex-basis: 100%;
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4) var(--space-5);
}

/* ---- Stepper ----------------------------------------------------------- */

.stepper {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.stepper input {
  width: 84px;
  text-align: center;
}

.stepper__btn {
  width: var(--control-h);
  height: var(--control-h);
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  font-size: var(--text-lg);
  line-height: 1;
}

.stepper__btn:hover:not(:disabled) {
  background: var(--surface-3);
  color: var(--text);
}

/* ---- Metric ------------------------------------------------------------
   Small tracked label over a large tabular figure. The label is what makes
   the number legible, so it is never dropped to save space. */

.metric {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.metric__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-3);
}

.metric__value {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  line-height: 1.15;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.metric__value--lg {
  font-size: var(--text-3xl);
}

.metric__value--sm {
  font-size: var(--text-xl);
}

.metric__sub {
  font-size: var(--text-xs);
  color: var(--text-3);
}

.metric__icon {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--primary);
}

.metric-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-4);
}

/* ---- Meter -------------------------------------------------------------
   HP / shield / capacity bars. Tone is set by a modifier, and every meter is
   paired with a numeric readout so the colour is never the only signal. */

.meter {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.meter__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-xs);
}

.meter__label {
  color: var(--text-2);
  font-weight: var(--weight-medium);
}

.meter__value {
  margin-left: auto;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.meter__track {
  position: relative;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  overflow: hidden;
}

.meter__fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: inherit;
  background: var(--primary);
  transition: width var(--duration) var(--ease);
}

.meter--hp .meter__fill { background: linear-gradient(90deg, var(--primary-lo), var(--primary-hi)); }
.meter--shield .meter__fill { background: linear-gradient(90deg, #1d84c8, var(--info)); }
.meter--ok .meter__fill { background: var(--ok); }
.meter--warn .meter__fill { background: var(--warn); }
.meter--bad .meter__fill { background: var(--bad); }

.meter--sm .meter__track { height: 4px; }

/* ---- Badges and status dots -------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 19px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-xs);
  background: var(--surface-3);
  color: var(--text-2);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
}

.badge--brand { background: var(--primary-wash); color: var(--primary-hi); }
.badge--ok { background: var(--ok-wash); color: var(--ok); }
.badge--warn { background: var(--warn-wash); color: var(--warn); }
.badge--bad { background: var(--bad-wash); color: var(--bad); }
.badge--info { background: var(--info-wash); color: var(--info); }

/* Status is dot + text, always. The dot alone never carries the meaning. */
.status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-2);
  white-space: nowrap;
}

.status__dot {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--text-3);
}

.status--running .status__dot { background: var(--ok); }
.status--running { color: var(--ok); }
.status--pending .status__dot { background: var(--warn); }
.status--pending { color: var(--warn); }
.status--error .status__dot { background: var(--bad); }
.status--error { color: var(--bad); }
.status--stopped .status__dot { background: var(--text-3); }

/* A slow pulse on the live state only. Reduced motion removes it. */
.status--running .status__dot {
  animation: status-pulse 2.4s var(--ease) infinite;
}

@keyframes status-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.5); }
  50% { box-shadow: 0 0 0 4px rgba(52, 211, 153, 0); }
}

/* ---- Data table --------------------------------------------------------
   Dense rows, hairline separators, sticky header inside a scrolling wrapper. */

.table-wrap {
  overflow: auto;
  min-width: 0;
  overscroll-behavior: contain;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.table caption {
  text-align: left;
  padding: 0 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-3);
}

.table th {
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
}

.table td {
  height: var(--row-h);
  padding: var(--space-1) var(--space-3);
  border-bottom: 1px solid var(--line-soft);
  color: var(--text-2);
  vertical-align: middle;
}

.table tbody tr:last-child td {
  border-bottom: none;
}

.table tbody tr:hover td {
  background: var(--surface-2);
}

.table tbody tr.is-selected td {
  background: var(--primary-wash);
  color: var(--text);
}

.table__name {
  color: var(--text);
  font-weight: var(--weight-medium);
}

.table__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.table__empty td {
  height: auto;
  padding: var(--space-6) var(--space-3);
  text-align: center;
  color: var(--text-3);
}

.table--compact td {
  height: var(--row-h-tight);
}

/* ---- Category tabs ----------------------------------------------------- */

.tabs {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  min-width: 0;
}

.tabs__tab {
  height: var(--control-h-sm);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  transition: background-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}

.tabs__tab:hover:not(.is-active) {
  background: var(--surface-2);
  color: var(--text);
}

.tabs__tab.is-active {
  background: var(--primary-wash-strong);
  border-color: var(--primary-wash-strong);
  color: var(--primary-hi);
}

.tabs__count {
  margin-left: var(--space-2);
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}

/* ---- Feedback: status line, empty state, skeleton ----------------------- */

.state-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--text-xs);
  color: var(--text-2);
}

.state-line[data-tone="success"] { border-color: var(--ok-wash); background: var(--ok-wash); color: var(--ok); }
.state-line[data-tone="error"] { border-color: var(--bad-wash); background: var(--bad-wash); color: var(--bad); }
.state-line[data-tone="warn"] { border-color: var(--warn-wash); background: var(--warn-wash); color: var(--warn); }
.state-line[data-tone="info"] { border-color: var(--info-wash); background: var(--info-wash); color: var(--info); }

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  text-align: center;
  min-height: 120px;
}

.empty__icon {
  width: 24px;
  height: 24px;
  color: var(--text-3);
  margin-bottom: var(--space-1);
}

.empty__title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-2);
}

.empty__copy {
  font-size: var(--text-xs);
  color: var(--text-3);
  max-width: 42ch;
  line-height: 1.5;
}

.empty__action {
  margin-top: var(--space-2);
}

.skeleton {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: skeleton-sweep 1.4s var(--ease) infinite;
}

@keyframes skeleton-sweep {
  from { background-position: 100% 50%; }
  to { background-position: 0 50%; }
}

.skeleton--text { height: 11px; }
.skeleton--line { height: 30px; }
.skeleton--block { height: 72px; }

.skeleton-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--panel-pad);
}

/* ---- Key/value list ---------------------------------------------------- */

.kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  align-items: baseline;
}

.kv dt {
  color: var(--text-3);
  white-space: nowrap;
}

.kv dd {
  color: var(--text);
  text-align: right;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Modal -------------------------------------------------------------
   Focus is trapped by JS; this only handles presentation. */

.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  background: rgba(4, 3, 10, 0.72);
}

.modal__dialog {
  display: flex;
  flex-direction: column;
  width: min(620px, 100%);
  max-height: min(680px, calc(100vh - 96px));
  background: var(--surface-1);
  border: 1px solid var(--line-loud);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.modal__dialog--wide {
  width: min(860px, 100%);
}

.modal__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--line-soft);
}

.modal__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.modal__subtitle {
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--text-3);
}

.modal__close {
  margin-left: auto;
}

.modal__body {
  padding: var(--space-5);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.modal__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--line-soft);
}

/* ---- Toasts ------------------------------------------------------------ */

.toast-region {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: min(380px, calc(100vw - 40px));
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border: 1px solid var(--line-loud);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  pointer-events: auto;
  animation: toast-in var(--duration) var(--ease-out);
}

.toast[data-tone="success"] { border-left-color: var(--ok); }
.toast[data-tone="error"] { border-left-color: var(--bad); }
.toast[data-tone="warn"] { border-left-color: var(--warn); }

.toast__text {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--text);
  overflow-wrap: anywhere;
}

.toast__title {
  font-weight: var(--weight-semibold);
  margin-bottom: 2px;
}

.toast__close {
  flex: none;
  color: var(--text-3);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ---- Event feed -------------------------------------------------------- */

.feed {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.feed__list {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  min-height: 0;
}

.feed__row {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-2) var(--panel-pad);
  border-bottom: 1px solid var(--line-soft);
  font-size: var(--text-xs);
}

.feed__row:last-child {
  border-bottom: none;
}

.feed__time {
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.feed__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-3);
  align-self: center;
}

.feed__dot[data-tone="success"] { background: var(--ok); }
.feed__dot[data-tone="error"] { background: var(--bad); }
.feed__dot[data-tone="warn"] { background: var(--warn); }
.feed__dot[data-tone="info"] { background: var(--info); }

.feed__text {
  color: var(--text-2);
  overflow-wrap: anywhere;
}

/* ---- Card grid --------------------------------------------------------- */

.card-grid {
  display: grid;
  gap: var(--panel-gap);
  grid-template-columns: repeat(auto-fill, minmax(var(--card-min, 220px), 1fr));
}
