/* ============================================================================
   MiniCore driver station — the /control page only.

   Split out of style.css; every rule here is byte-for-byte its original. Loads
   after core.css, which owns the bezel, rail, buttons, notices and log.
   ========================================================================= */

/* ── Arm band: the one bold move ─────────────────────────────────────────── */

.arm {
  position: relative;
  padding: 1.5rem 1rem 1.1rem;
  text-align: center;
  background:
    repeating-linear-gradient(
      135deg,
      transparent 0 11px,
      color-mix(in srgb, var(--stop) 7%, transparent) 11px 22px
    ),
    var(--s-deck);
  border-bottom: 1px solid var(--line);
  transition: background 140ms linear;
}

body[data-armed="true"] .arm {
  background:
    repeating-linear-gradient(
      135deg,
      transparent 0 11px,
      color-mix(in srgb, var(--go) 10%, transparent) 11px 22px
    ),
    color-mix(in srgb, var(--go) 9%, var(--s-deck));
}

.arm__state {
  margin: 0;
  font-size: clamp(1.7rem, 6.5vw, 3.1rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.2em;
  text-indent: 0.2em; /* balance the trailing letter-space */
  text-transform: uppercase;
  color: var(--stop-lift);
}

body[data-armed="true"] .arm__state {
  color: var(--go-lift);
}

.arm__read {
  margin: 0.5rem 0 1rem;
  font-size: 0.78rem;
  color: var(--ink-dim);
}

.arm__switch {
  font: inherit;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  min-width: min(23rem, 100%);
  padding: 0.85rem 1.6rem;
  cursor: pointer;
  color: var(--go-text);
  background: color-mix(in srgb, var(--go) 26%, var(--s-rise));
  border: 2px solid var(--go);
  border-radius: var(--r);
  transition: background 100ms linear, transform 60ms ease-out;
}

.arm__switch:hover:not(:disabled) {
  background: color-mix(in srgb, var(--go) 40%, var(--s-rise));
}

.arm__switch:active:not(:disabled) {
  transform: translateY(1px);
}

body[data-armed="true"] .arm__switch {
  color: var(--stop-text-solid);
  background: color-mix(in srgb, var(--stop) 28%, var(--s-rise));
  border-color: var(--stop);
}

body[data-armed="true"] .arm__switch:hover:not(:disabled) {
  background: color-mix(in srgb, var(--stop) 42%, var(--s-rise));
}

.arm__switch:disabled {
  color: var(--ink-mute);
  background: var(--s-rise);
  border-color: var(--line-bright);
  cursor: not-allowed;
}

/* Global speed limit. Lives in the arm band because it is field state, and
   because a cap the driver has forgotten about is worse than no cap: it belongs
   where they are already looking when a robot feels wrong. */

.limit {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  margin: 1rem auto 0;
  max-width: min(23rem, 100%);
}

.limit__label {
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.limit__range {
  flex: 1 1 8rem;
  min-width: 6rem;
  height: 1.2rem;
  cursor: pointer;
  accent-color: var(--info);
  background: transparent;
}

.limit__read {
  min-width: 3ch;
  font-variant-numeric: tabular-nums;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
}

/* Capped is a state worth seeing at a glance, so the readout stops being
   ordinary ink once it is. */

.limit[data-capped="true"] .limit__read {
  color: var(--info);
}

.limit__note {
  flex: 1 0 100%;
  margin: 0;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  color: var(--warn);
}

.arm__panic {
  margin: 0.7rem 0 0;
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* ── Deck ───────────────────────────────────────────────────────────────── */

.deck {
  display: grid;
  grid-template-columns: 1fr 19rem;
  gap: 1px;
  background: var(--line);
  border-radius: 0 0 var(--r) var(--r);
  overflow: hidden;
}

.slots {
  background: var(--s-deck);
  padding: var(--gut);
}

.slots__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gut);
}

/* ── Slot cards: the primary work surface ───────────────────────────────── */

.slot {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.8rem;
  background: var(--s-card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-bright);
  border-radius: var(--r);
  transition: border-color 120ms linear;
}

.slot[data-live="true"] {
  border-left-color: var(--go);
}

.slot[data-paired="false"] {
  border-left-color: var(--line-bright);
}

.slot__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.slot__idx {
  font-size: 0.62rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.slot__name {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.slot[data-paired="false"] .slot__name {
  color: var(--ink-mute);
  font-weight: 400;
}

/* Status line — always a word, never colour alone */

.slot__status {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.slot__status .dot {
  background: var(--ink-mute);
}

.slot[data-state="live"] .slot__status {
  color: var(--go-lift);
}

.slot[data-state="live"] .slot__status .dot {
  background: var(--go);
  box-shadow: 0 0 6px color-mix(in srgb, var(--go) 70%, transparent);
}

.slot[data-state="stale"] .slot__status {
  color: color-mix(in srgb, var(--warn) 62%, var(--ink));
}

.slot[data-state="stale"] .slot__status .dot {
  background: var(--warn);
}

.slot[data-state="standby"] .slot__status {
  color: var(--ink-dim);
}

.slot__field {
  display: grid;
  gap: 0.25rem;
}

.slot__field > span {
  font-size: 0.6rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.slot__mac {
  margin: 0;
  font-size: 0.66rem;
  color: var(--ink-mute);
  letter-spacing: 0.03em;
}

/* ESC neutral trim. Two boxes plus Apply on one row, with the robot's own
   reported values on the line below — the boxes are what you intend to send,
   the readout is what the robot says it is running. */

.slot__calib {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: end;
  gap: 0.35rem;
  padding-top: 0.45rem;
  border-top: 1px solid var(--line);
}

.calib__title {
  grid-column: 1 / -1;
  font-size: 0.6rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.calib__field {
  display: grid;
  gap: 0.2rem;
}

.calib__field > span {
  font-size: 0.6rem;
  color: var(--ink-mute);
}

.calib__field input {
  font: inherit;
  font-size: 0.78rem;
  width: 100%;
  min-width: 0;
  padding: 0.35rem 0.4rem;
  color: var(--ink);
  background: var(--s-rise);
  border: 1px solid var(--line-bright);
  border-radius: var(--r);
}

.calib__field input:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.calib__read {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.66rem;
  color: var(--ink-mute);
}

/* Applied but not written to the robot's flash — a reset reverts it, so this
   is a warning, not a status. */

.calib__read[data-unsaved="true"] {
  color: var(--warn);
}

/* Stick telemetry: two mirrored bars, centre-anchored. Real axis values. */

.sticks {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  padding-top: 0.15rem;
}

.stick {
  display: grid;
  gap: 0.2rem;
}

.stick > span {
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.stick__track {
  position: relative;
  height: 5px;
  background: var(--s-rise);
  border-radius: 2px;
  overflow: hidden;
}

/* centre tick */

.stick__track::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line-bright);
}

.stick__fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 0;
  background: var(--info);
  border-radius: 2px;
  transition: none;
}

/* Robot + gamepad lists */

.rlist,

.glist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.3rem;
}

.rlist li,

.glist li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.45rem;
  font-size: 0.72rem;
  background: var(--s-rise);
  border: 1px solid var(--line);
  border-radius: var(--r);
  min-width: 0; /* let the flex child actually shrink so ellipsis applies */
}

.rlist .r-name,

.glist .g-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rlist .r-mac {
  margin-left: auto;
  font-size: 0.64rem;
  color: var(--ink-mute);
  flex: none;
}

.glist li[data-active="true"] {
  border-color: var(--go);
  background: color-mix(in srgb, var(--go) 17%, var(--s-rise));
}

.g-idx {
  flex: none;
  padding: 0.02rem 0.28rem;
  font-size: 0.62rem;
  color: var(--ink-dim);
  background: var(--s-card);
  border: 1px solid var(--line-bright);
  border-radius: 2px;
}

/* ── Responsive ─────────────────────────────────────────────────────────── */
/* The control half of the two breakpoint blocks in style.css. See core.css. */
@media (max-width: 62rem) {
  .deck {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 40rem) {
  .slots__grid {
    grid-template-columns: 1fr;
  }

  .arm {
    padding: 1.1rem 0.7rem 0.9rem;
  }

  /* Pointer-only hint: keyboard stop is unreachable without a keyboard */
  .arm__panic {
    display: none;
  }
}

/* ── Forced colours: state must survive with no palette at all ──────────── */
@media (forced-colors: active) {
  .slot,
  .rlist li,
  .glist li {
    border: 1px solid CanvasText;
  }
}

@media (hover: none) {
  .arm__panic {
    display: none;
  }
}
