/* ClawUX admin console
   Register: product. Strategy: restrained, tinted-neutral light surface with one
   committed accent and a deliberate dark inset for code. All neutrals tint toward
   the accent hue; no pure black or white. */

:root {
  color-scheme: light dark;

  --hue: 262;

  /* Surfaces: app bg, content surface, and a cooler second layer for chrome. */
  --bg: oklch(0.968 0.006 var(--hue));
  --surface: oklch(0.995 0.003 var(--hue));
  --surface-2: oklch(0.945 0.008 var(--hue));
  --surface-inset: oklch(0.932 0.01 var(--hue));

  --line: oklch(0.9 0.012 var(--hue));
  --line-strong: oklch(0.83 0.016 var(--hue));

  --ink: oklch(0.29 0.03 var(--hue));
  --ink-soft: oklch(0.42 0.028 var(--hue));
  --muted: oklch(0.54 0.024 var(--hue));

  --accent: oklch(0.55 0.15 var(--hue));
  --accent-strong: oklch(0.46 0.16 var(--hue));
  --accent-tint: oklch(0.95 0.035 var(--hue));
  --accent-ring: oklch(0.55 0.15 var(--hue) / 0.35);
  /* Text/icon color that sits on a filled accent surface (primary button). */
  --on-accent: oklch(0.99 0.01 var(--hue));

  --good: oklch(0.58 0.13 150);
  --good-tint: oklch(0.95 0.04 150);
  --warn: oklch(0.62 0.13 75);
  --warn-tint: oklch(0.95 0.05 75);
  --bad: oklch(0.55 0.18 27);
  --bad-tint: oklch(0.95 0.04 27);

  /* Chip ink: darker, chroma-matched state colors that measure >= 4.5:1 on their
     tints (WCAG AA). Verified computationally in admin-console-contrast.test.ts:
     good 6.19:1, warn 6.46:1, bad 6.71:1 against the tints above. */
  --good-ink: oklch(0.45 0.11 150);
  --warn-ink: oklch(0.45 0.09 75);
  --bad-ink: oklch(0.45 0.15 27);

  --code-bg: oklch(0.24 0.022 var(--hue));
  --code-ink: oklch(0.9 0.018 var(--hue));
  --code-dim: oklch(0.66 0.02 var(--hue));

  --shadow-sm: 0 1px 2px oklch(0.29 0.03 var(--hue) / 0.06);
  --shadow-md: 0 6px 20px -8px oklch(0.29 0.03 var(--hue) / 0.18);

  --r-sm: 7px;
  --r-md: 10px;
  --r-lg: 14px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Dark theme for operators running the gateway after hours. Same committed
   violet identity, inverted surfaces. Every chip ink/tint pair here is held to
   the same WCAG AA 4.5:1 bar as the light palette, verified for both themes in
   admin-console-contrast.test.ts. Opt-in via the OS setting; no toggle, no JS. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: oklch(0.185 0.012 var(--hue));
    --surface: oklch(0.215 0.014 var(--hue));
    --surface-2: oklch(0.255 0.012 var(--hue));
    --surface-inset: oklch(0.28 0.016 var(--hue));

    --line: oklch(0.34 0.014 var(--hue));
    --line-strong: oklch(0.44 0.018 var(--hue));

    --ink: oklch(0.93 0.014 var(--hue));
    --ink-soft: oklch(0.8 0.02 var(--hue));
    --muted: oklch(0.66 0.02 var(--hue));

    --accent: oklch(0.68 0.13 var(--hue));
    --accent-strong: oklch(0.8 0.085 var(--hue));
    --accent-tint: oklch(0.3 0.05 var(--hue));
    --accent-ring: oklch(0.68 0.13 var(--hue) / 0.4);
    --on-accent: oklch(0.2 0.02 var(--hue));

    --good: oklch(0.72 0.13 150);
    --good-tint: oklch(0.3 0.05 150);
    --warn: oklch(0.78 0.12 75);
    --warn-tint: oklch(0.31 0.045 75);
    --bad: oklch(0.68 0.17 27);
    --bad-tint: oklch(0.31 0.055 27);

    --good-ink: oklch(0.86 0.14 150);
    --warn-ink: oklch(0.88 0.1 75);
    --bad-ink: oklch(0.78 0.125 27);

    --code-bg: oklch(0.16 0.016 var(--hue));
    --code-ink: oklch(0.9 0.018 var(--hue));
    --code-dim: oklch(0.6 0.02 var(--hue));

    --shadow-sm: 0 1px 2px oklch(0.1 0.02 var(--hue) / 0.5);
    --shadow-md: 0 8px 24px -8px oklch(0.08 0.02 var(--hue) / 0.6);
  }
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family:
    Inter,
    ui-sans-serif,
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

::selection {
  background: var(--accent-tint);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute;
  left: 16px;
  top: -48px;
  z-index: 20;
  background: var(--surface);
  color: var(--accent-strong);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 8px 12px;
  box-shadow: var(--shadow-md);
  transition: top 160ms var(--ease);
}

.skip-link:focus {
  top: 16px;
}

/* Buttons: a secondary default and a committed primary. */
button {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  min-height: 36px;
  padding: 0 14px;
  border-radius: var(--r-sm);
  font-weight: 550;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition:
    background 140ms var(--ease),
    border-color 140ms var(--ease),
    color 140ms var(--ease),
    transform 80ms var(--ease);
}

button:hover {
  background: var(--surface-2);
  border-color: var(--muted);
}

button:active {
  transform: translateY(1px);
}

button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  box-shadow: none;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.btn-primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}

button.danger {
  color: var(--bad);
  border-color: color-mix(in oklch, var(--bad) 28%, var(--line-strong));
  box-shadow: none;
  min-height: 32px;
  padding: 0 10px;
}

button.danger:hover {
  background: var(--bad-tint);
  border-color: var(--bad);
}

.shell {
  width: min(1180px, calc(100vw - 40px));
  margin: 0 auto;
  padding: 32px 0 64px;
}

/* Top bar */
.topbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  margin-bottom: 4px;
}

.eyebrow {
  margin: 0 0 6px;
  color: var(--accent-strong);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  margin-bottom: 4px;
  font-size: 26px;
  font-weight: 680;
  letter-spacing: -0.015em;
}

.app-subtitle {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
}

h2 {
  margin-bottom: 0;
  font-size: 16px;
  font-weight: 620;
  letter-spacing: -0.01em;
}

/* Status pill with a state dot, so meaning is not carried by color alone. */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  padding: 7px 13px 7px 11px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 550;
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
}

.status-pill::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--muted);
}

.status-pill.ok {
  color: var(--good-ink);
  border-color: color-mix(in oklch, var(--good) 40%, var(--line));
  background: var(--good-tint);
}

.status-pill.ok::before {
  background: var(--good-ink);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--good) 22%, transparent);
}

/* Tabs grouped into labeled clusters, wrapping onto rows rather than a single
   long scroll strip, so 10 sections stay scannable. */
.tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  padding: 6px 8px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin-bottom: 26px;
}

.tab-group {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.tab-group + .tab-group {
  padding-left: 10px;
  border-left: 1px solid var(--line);
}

.tab-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  padding-right: 4px;
  white-space: nowrap;
}

.tab {
  flex: 0 0 auto;
  border: 1px solid transparent;
  background: transparent;
  box-shadow: none;
  color: var(--ink-soft);
  min-height: 34px;
  padding: 0 14px;
  border-radius: var(--r-sm);
  font-weight: 550;
}

.tab:hover {
  background: color-mix(in oklch, var(--surface) 70%, transparent);
  border-color: transparent;
  color: var(--ink);
}

.tab.active {
  background: var(--surface);
  border-color: var(--line);
  color: var(--accent-strong);
  box-shadow: var(--shadow-sm);
}

/* Panels */
.panel {
  display: none;
  animation: panel-in 200ms var(--ease);
}

.panel.active {
  display: block;
}

/* The panel is focusable so the skip link and tab clicks can move focus into
   the region, but a full-box ring around it is noise. Selection is already
   shown by the active tab, and inner controls keep their own focus rings. */
.panel:focus,
.panel:focus-visible {
  outline: none;
}

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

@media (prefers-reduced-motion: reduce) {
  .panel {
    animation: none;
  }
  * {
    transition-duration: 0.01ms !important;
  }
}

/* Overview: one banded surface, not five identical cards. */
.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  margin-bottom: 24px;
}

.metric {
  padding: 16px 18px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.metric span {
  display: block;
  color: var(--muted);
  font-size: 12px;
  font-weight: 550;
  letter-spacing: 0.01em;
  margin-bottom: 6px;
}

.metric strong {
  font-size: 22px;
  font-weight: 640;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 26px 0 14px;
}

.section-head:first-child {
  margin-top: 0;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-end;
}

/* Code + JSON: deliberate dark inset */
.code,
textarea {
  width: 100%;
  min-height: 260px;
  overflow: auto;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--code-bg);
  color: var(--code-ink);
  padding: 16px;
  line-height: 1.55;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12.5px;
  tab-size: 2;
}

.code {
  white-space: pre-wrap;
  word-break: break-word;
}

textarea#mappingsEditor {
  resize: vertical;
}

/* Card collections */
.channel-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
}

.channel-card,
.backend-card,
.device-card,
.preview-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px;
  box-shadow: var(--shadow-sm);
  transition:
    border-color 140ms var(--ease),
    box-shadow 140ms var(--ease);
}

.channel-card:hover,
.backend-card:hover,
.device-card:hover,
.preview-card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-md);
}

.channel-card header,
.backend-card header,
.device-card header,
.preview-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.channel-card h3,
.backend-card h3,
.device-card h3,
.preview-card h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 620;
  text-transform: capitalize;
  letter-spacing: -0.005em;
}

.channel-card label,
.backend-card label,
.device-card label,
.device-actions label,
.form-grid label {
  display: grid;
  gap: 6px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 550;
  margin-top: 12px;
}

/* Form controls: one vocabulary, full state set */
input,
select,
.channel-card input,
.channel-card select,
.backend-card input,
.backend-card select,
.device-actions input,
.form-grid input,
.form-grid select,
.form-grid textarea {
  width: 100%;
  min-height: 38px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  padding: 0 11px;
  transition:
    border-color 140ms var(--ease),
    box-shadow 140ms var(--ease);
}

input::placeholder,
textarea::placeholder {
  color: color-mix(in oklch, var(--muted) 75%, transparent);
}

input:hover,
select:hover,
.form-grid textarea:hover {
  border-color: var(--muted);
}

input:focus-visible,
select:focus-visible,
.form-grid textarea:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}

input:disabled,
select:disabled {
  background: var(--surface-2);
  color: var(--muted);
  cursor: not-allowed;
}

.form-grid textarea {
  min-height: 110px;
  padding: 11px;
  resize: vertical;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.5;
}

.switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 550;
  margin: 0;
}

.switch input {
  width: auto;
  min-height: 0;
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
}

/* Secret + status chips: dot carries state alongside color */
.secret {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 26px;
  border-radius: 999px;
  padding: 0 11px 0 9px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 550;
}

/* Backend health badge: last probe outcome from the status API. */
.health-badge {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  border-radius: 999px;
  padding: 0 10px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}

.health-badge.ok {
  color: var(--good-ink);
  background: var(--good-tint);
  border-color: color-mix(in oklch, var(--good) 45%, var(--line));
}

.health-badge.bad {
  color: var(--bad-ink);
  background: var(--bad-tint);
  border-color: color-mix(in oklch, var(--bad) 45%, var(--line));
}

/* Operator-supplied backend info line (label, description, owner). */
.backend-info {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
}

.secret::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.85;
}

.secret.ok {
  color: var(--good-ink);
  background: var(--good-tint);
  border-color: color-mix(in oklch, var(--good) 30%, var(--line));
}

.secret.missing {
  color: var(--warn-ink);
  background: var(--warn-tint);
  border-color: color-mix(in oklch, var(--warn) 30%, var(--line));
}

/* Channel instances: divided rows on the second surface, not nested cards. */
.instance-list {
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  overflow: hidden;
}

.instance-list:empty {
  display: none;
}

.instance-row {
  padding: 10px 12px 12px;
  border-bottom: 1px solid var(--line);
}

.instance-row:last-child {
  border-bottom: none;
}

.instance-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.instance-name {
  font-size: 13px;
  font-weight: 620;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

.heartbeat {
  margin-left: auto;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.heartbeat.bad {
  color: var(--bad-ink);
  font-weight: 600;
}

.instance-fields,
.instance-routing {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

.channel-card .instance-row label {
  margin-top: 8px;
}

.channel-card .instance-row input,
.channel-card .instance-row select {
  background: var(--surface);
}

.add-instance {
  margin-top: 10px;
  min-height: 32px;
  padding: 0 10px;
  font-size: 12.5px;
}

.hint {
  color: var(--muted);
  font-size: 13px;
  max-width: 72ch;
  margin: 0 0 14px;
}

.hint.ok {
  color: var(--good-ink);
}

.hint.bad {
  color: var(--bad-ink);
  font-weight: 600;
}

/* Wire a Bot: numbered steps with progressive checks, ending in a live heartbeat. */
.wire-steps {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: wire-step;
  display: grid;
  gap: 14px;
}

.wire-step {
  counter-increment: wire-step;
  padding: 14px 16px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}

.wire-step > h3 {
  margin: 0 0 10px;
  font-size: 14px;
}

.wire-step > h3::before {
  content: counter(wire-step) ". ";
  color: var(--accent-strong);
}

.wire-step .hint:last-child {
  margin-bottom: 0;
}

button.linklike {
  display: inline;
  min-height: 0;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent-strong);
  font-size: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.wire-heartbeat {
  margin-top: 14px;
  padding: 12px 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
}

.wire-heartbeat header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.wire-heartbeat .hint {
  margin: 6px 0 0;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-bottom: 16px;
}

.test-message-field {
  grid-column: 1 / -1;
}

.device-actions {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) auto;
  gap: 12px;
  align-items: end;
  margin-bottom: 14px;
}

.device-actions label {
  margin-top: 0;
}

.device-card .meta {
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px;
  margin: 12px 0 16px;
}

.preview-card .meta {
  color: var(--muted);
  font-size: 13px;
  margin-top: 6px;
}

.device-card .danger {
  color: var(--bad);
}

/* UI decision engine card */
.ui-planner-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 18px;
  margin-bottom: 18px;
  box-shadow: var(--shadow-sm);
}

/* Guided backend creation card, with one-tap prefill chips for discovered services. */
.backend-create {
  background: var(--surface);
  border: 1px solid var(--accent-ring);
  border-radius: var(--r-md);
  padding: 16px 18px;
  margin-bottom: 18px;
  box-shadow: var(--shadow-sm);
}

.backend-create h3 {
  margin: 0 0 4px;
}

.backend-create .actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.backend-create #backendCreateStatus {
  margin: 10px 0 0;
}

.discovered-list {
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
}

.discovered-list:empty {
  display: none;
}

.discovered-chip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: 13px;
}

.discovered-chip button {
  margin-left: auto;
  min-height: 30px;
  padding: 0 12px;
  font-size: 12.5px;
}

.discovered-configured {
  margin-left: auto;
  color: var(--good-ink);
  font-size: 12px;
  font-weight: 600;
}

.ui-planner-card h3 {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 620;
}

.ui-planner-card .form-grid {
  margin-bottom: 0;
}

/* Activity table */
.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  font-size: 13px;
}

.data-table thead th {
  text-align: left;
  font-weight: 600;
  color: var(--muted);
  font-size: 12px;
  background: var(--surface-2);
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}

.data-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

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

.data-table .mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  color: var(--muted);
  white-space: nowrap;
}

.quality,
.outcome {
  display: inline-block;
  border-radius: 999px;
  padding: 1px 9px;
  font-size: 12px;
  font-weight: 550;
  border: 1px solid var(--line);
}

.quality-native,
.outcome-ok {
  color: var(--good-ink);
  background: var(--good-tint);
  border-color: color-mix(in oklch, var(--good) 30%, var(--line));
}

.quality-degraded,
.outcome-warnings {
  color: var(--warn-ink);
  background: var(--warn-tint);
  border-color: color-mix(in oklch, var(--warn) 30%, var(--line));
}

.quality-fallback {
  color: var(--ink-soft);
  background: var(--surface-2);
}

/* Preview: rendered but not sent (no live sender / no credentials). Neutral, not a success green. */
.outcome-preview {
  color: var(--ink-soft);
  background: var(--surface-2);
  border-style: dashed;
}

/* Failed deliveries are the loudest row state: error tokens, heavier than warnings. */
.outcome-failed {
  color: var(--bad-ink);
  background: var(--bad-tint);
  border-color: color-mix(in oklch, var(--bad) 45%, var(--line));
  font-weight: 650;
}

.metric strong.bad {
  color: var(--bad);
}

/* Per-panel inline status live region: where action failures and save
   confirmations land, next to the control that caused them. */
.panel-status {
  margin: 0 0 14px;
  min-height: 0;
  color: var(--ink-soft);
  font-size: 13px;
}

.panel-status:empty {
  display: none;
}

.panel-status.ok {
  color: var(--good-ink);
}

.panel-status.bad {
  color: var(--bad-ink);
  font-weight: 600;
}

/* Inline field validation (mappings JSON parse errors). */
.field-error {
  color: var(--bad-ink);
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 10px;
}

/* Gateway-down state on initial load: explicit and retryable, never a blank shell. */
.load-error {
  border: 1px solid color-mix(in oklch, var(--bad) 45%, var(--line));
  border-radius: var(--r-md);
  background: var(--bad-tint);
  color: var(--bad-ink);
  padding: 18px 20px;
  margin-bottom: 22px;
  font-size: 13px;
}

.load-error strong {
  display: block;
  font-size: 15px;
  margin-bottom: 6px;
}

.load-error p {
  margin: 0 0 8px;
}

/* Wide tables scroll inside their own container instead of stretching the page. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.table-scroll .data-table {
  min-width: 720px;
}

/* UI Decisions: screen-reader-only table captions, breathing room between the
   stacked breakdown tables, and a narrower floor for the 3–4 column tables. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

#decisionMetrics .table-scroll {
  margin-bottom: 16px;
}

#decisionMetrics .data-table {
  min-width: 480px;
}

/* Activity filters sit in one row above the delivery table. */
.delivery-filters {
  margin-bottom: 16px;
}

/* Contacts: one row per mapping — recipient, name, remove. */
.contact-row {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) minmax(140px, 1fr) auto;
  gap: 12px;
  align-items: end;
  margin-bottom: 10px;
}

.contact-row label {
  display: grid;
  gap: 6px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 550;
}

#addContactButton {
  margin-top: 4px;
}

@media (max-width: 640px) {
  .contact-row {
    grid-template-columns: 1fr;
    align-items: stretch;
  }
}

/* Delivery warnings: inline second line under the outcome, clamped to one line;
   tap/click or Enter expands the full text. No hover-only tooltip. */
.delivery-warnings {
  margin-top: 4px;
  max-width: 260px;
  color: var(--warn-ink);
  font-size: 12px;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.delivery-warnings.expanded {
  white-space: normal;
  overflow: visible;
}

/* Policy tab: effective per-channel allowlists */
.subsection-title {
  margin: 22px 0 4px;
  font-size: 14px;
  font-weight: 620;
}

.allowlist-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px;
  box-shadow: var(--shadow-sm);
}

.allowlist-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.allowlist-card h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 620;
  text-transform: capitalize;
}

.allowlist-card label {
  display: grid;
  gap: 6px;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 550;
  margin-top: 12px;
}

.allowlist-card textarea {
  min-height: 72px;
  padding: 11px;
  resize: vertical;
  background: var(--surface);
  color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12.5px;
  line-height: 1.5;
}

.allowlist-state {
  border-radius: 999px;
  border: 1px solid var(--line);
  padding: 1px 9px;
  font-size: 12px;
  font-weight: 550;
}

.allowlist-state.restricted {
  color: var(--good-ink);
  background: var(--good-tint);
  border-color: color-mix(in oklch, var(--good) 30%, var(--line));
}

.allowlist-state.open {
  color: var(--ink-soft);
  background: var(--surface-2);
}

.allowlist-entries {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.allowlist-entries li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
}

.allowlist-entries .mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  overflow-wrap: anywhere;
}

.badge {
  flex: 0 0 auto;
  border-radius: 999px;
  border: 1px solid var(--line);
  padding: 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.badge-global {
  color: var(--accent-strong);
  background: var(--accent-tint);
  border-color: color-mix(in oklch, var(--accent) 30%, var(--line));
}

.badge-channel {
  color: var(--good-ink);
  background: var(--good-tint);
  border-color: color-mix(in oklch, var(--good) 30%, var(--line));
}

.badge-derived {
  color: var(--warn-ink);
  background: var(--warn-tint);
  border-color: color-mix(in oklch, var(--warn) 30%, var(--line));
}

/* Empty + teaching states */
.empty-state {
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--muted);
  padding: 28px 20px;
  text-align: center;
  font-size: 13px;
}

.empty-state strong {
  display: block;
  color: var(--ink-soft);
  font-weight: 600;
  margin-bottom: 4px;
}

/* Responsive: structural, not fluid type */
@media (max-width: 720px) {
  .shell {
    width: calc(100vw - 28px);
    padding-top: 24px;
  }

  .topbar,
  .section-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .metrics,
  .form-grid {
    grid-template-columns: 1fr;
  }

  .metric {
    border-right: none;
  }

  .device-actions {
    grid-template-columns: 1fr;
  }

  /* WCAG 44px minimum touch targets on small screens; desktop keeps its density. */
  button,
  .tab,
  .btn-primary,
  button.danger,
  .add-instance {
    min-height: 44px;
  }

  input,
  select {
    min-height: 44px;
  }

  /* Switch checkboxes get a 44px hit area via label padding (compensated with
     a negative margin so card layout is unchanged). */
  .switch {
    padding: 14px 0;
    margin: -14px 0;
  }

  .delivery-warnings {
    max-width: 200px;
  }
}

/* Login overlay: a full-surface sign-in shown when the server enforces the
   admin token. Uses the shared tokens so it themes light and dark for free. */
.admin-login {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 24px;
  background: color-mix(in oklch, var(--bg) 78%, transparent);
  backdrop-filter: blur(3px);
}

.admin-login-card {
  width: min(420px, 100%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  padding: 24px;
}

.admin-login-card h2 {
  margin: 0;
}

.admin-login-card label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  font-weight: 550;
  color: var(--ink-soft);
}

.admin-login-card input {
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--ink);
}

/* Wired bots roster on the Wire a Bot tab: a compact read-only summary of every
   configured bot and where it routes, distinct from the editable Channels tab. */
.wired-bots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin-top: 8px;
}

.wired-bot {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 14px;
  box-shadow: var(--shadow-sm);
}

.wired-bot-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.wired-bot-head strong {
  font-size: 14px;
  letter-spacing: -0.01em;
}

.wired-bot-head .heartbeat {
  margin-left: auto;
}

.wired-bot-facts {
  margin: 0;
  display: grid;
  gap: 6px;
}

.wired-bot-facts > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
}

.wired-bot-facts dt {
  color: var(--muted);
}

.wired-bot-facts dd {
  margin: 0;
  font-weight: 550;
  font-variant-numeric: tabular-nums;
}

.wired-bot-facts dd.bad {
  color: var(--bad-ink);
}
