/* ===========================================================================
   Device Management — the one stylesheet.
   Served straight from public/ (see the <link> in layouts/application.html.erb),
   cache-busted on its own mtime, so editing this file changes every page on the
   next reload with no build step and no precompile.

   Tailwind is still loaded for LAYOUT utilities only (grid, flex, spacing,
   responsive prefixes). Anything that carries the design — colour, type, border,
   radius, elevation — belongs here, behind a token, so changing it once changes
   it everywhere. Do not reintroduce @apply component rules in the layout: they
   need the Tailwind runtime and split the system in two.
   =========================================================================== */

/* --- tokens ---------------------------------------------------------------
   Values are Tailwind's own defaults (slate for surfaces and text, blue-600 for
   the primary action, emerald/amber/red/sky for state), so the colour utilities
   still sitting in the layout and a few views line up with what is set here.   */
:root {
  color-scheme: light;

  --paper:      #f8fafc;   /* slate-50  */
  --panel:      #f1f5f9;   /* slate-100 */
  --surface:    #ffffff;
  --rule:       #e2e8f0;   /* slate-200 */
  --rule-soft:  #f1f5f9;   /* slate-100 */

  --ink:        #0f172a;   /* slate-900 */
  --ink-soft:   #475569;   /* slate-600 */
  --ink-faint:  #94a3b8;   /* slate-400 */

  --accent:      #2563eb;  /* blue-600 — primary action, links, current release */
  --accent-hover:#1d4ed8;  /* blue-700 */
  --accent-ink:  #ffffff;
  --accent-bg:   #eff6ff;  /* blue-50  */
  --accent-rule: #bfdbfe;  /* blue-200 */

  --good:      #059669; --good-bg:    #ecfdf5; --good-rule:    #a7f3d0;
  --info:      #0284c7; --info-bg:    #f0f9ff; --info-rule:    #bae6fd;
  --armed:     #b45309; --armed-bg:   #fffbeb; --armed-rule:   #fde68a;
  --refused:   #dc2626; --refused-bg: #fef2f2; --refused-rule: #fecaca;
  --stale:     #94a3b8;

  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, "JetBrains Mono", Menlo,
               Consolas, monospace;

  --text-xs:   0.75rem;
  --text-sm:   0.8125rem;
  --text-base: 0.875rem;
  --text-md:   0.9375rem;
  --text-lg:   1.125rem;
  --text-xl:   1.375rem;

  --radius:      0.5rem;
  --radius-sm:   0.375rem;
  --radius-pill: 999px;

  --shadow:    0 1px 2px 0 rgba(15, 23, 42, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(15, 23, 42, 0.08), 0 2px 4px -2px rgba(15, 23, 42, 0.06);
  --focus:     0 0 0 2px #ffffff, 0 0 0 4px var(--accent);
  --focus-ring:0 0 0 3px rgba(37, 99, 235, 0.18);
}

/* --- base ----------------------------------------------------------------- */
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img, svg, canvas { max-width: 100%; }

code, .mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
code {
  font-size: 0.875em;
  color: var(--ink);
  background: var(--panel);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.3em;
}

main a:not(.btn):not(.nav-link):not(.dropdown-item) {
  color: var(--accent);
  text-decoration: none;
}
main a:not(.btn):not(.nav-link):not(.dropdown-item):hover {
  color: var(--accent-hover);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- type ----------------------------------------------------------------- */
.h4 { font-size: var(--text-xl); font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.h5 { font-size: var(--text-lg); font-weight: 600; color: var(--ink); }
.h6 { font-size: var(--text-md); font-weight: 600; color: var(--ink); }

/* Column heads, section labels, field captions. */
.eyebrow {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Headline values are fixed-width tokens — a version, a DID, a byte count — so
   they stay in the mono face and the digits stay in column. */
.stat {
  display: block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.5rem, 4vw, 1.875rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0.45rem 0 0.3rem;
  color: var(--ink);
}
.stat-xl { font-size: clamp(2rem, 7vw, 3rem); letter-spacing: -0.03em; line-height: 1; }
.stat-lg { font-size: clamp(1.5rem, 4.5vw, 2.25rem); }

.sub { display: block; color: var(--ink-soft); font-size: var(--text-xs); }

/* --- sidebar / header ----------------------------------------------------- */
.nav-link {
  display: flex; align-items: center; gap: 0.625rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  font-size: var(--text-base); font-weight: 500;
  color: var(--ink-soft); text-decoration: none;
  transition: background-color 0.12s, color 0.12s;
}
.nav-link:hover { background: var(--panel); color: var(--ink); }
.nav-link.active, .nav-link-active {
  background: var(--accent-bg); color: var(--accent-hover); font-weight: 600;
}
.nav-link .bi { font-size: var(--text-lg); opacity: 0.75; }

.dropdown-item {
  display: block; width: 100%; text-align: left;
  padding: 0.5rem 1rem; font-size: var(--text-base);
  color: var(--ink); text-decoration: none;
}
.dropdown-item:hover { background: var(--panel); }

/* --- surfaces ------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.card-header {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.5rem 0.75rem;
  padding: 0.875rem 1.25rem;
  border-bottom: 1px solid var(--rule);
  font-weight: 600; color: var(--ink);
}
.card-body { padding: 1.25rem; }
.card-footer {
  padding: 0.875rem 1.25rem;
  border-top: 1px solid var(--rule);
  color: var(--ink-soft); font-size: var(--text-xs);
}

/* A card whose children stack with even spacing and whose footer sinks to the
   bottom, so a row of them lines their controls up however tall each one grows. */
.panel {
  display: flex; flex-direction: column; gap: 1rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem;
}
.panel-primary { border-color: var(--accent-rule); box-shadow: var(--shadow-md); }
.panel-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 0.35rem 0.75rem;
  padding-bottom: 0.875rem; border-bottom: 1px solid var(--rule);
}
.panel-grow { flex: 1 1 auto; }
.panel-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem;
  margin-top: auto; padding-top: 0.875rem; border-top: 1px solid var(--rule);
}

/* A callout that annotates the thing above it, as opposed to an alert, which
   announces the result of something you just did. */
.note {
  margin: 0; padding: 0.75rem 0.875rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--rule);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}
.note p { margin: 0 0 0.5rem; }
.note p:last-child { margin-bottom: 0; }
.note-armed   { background: var(--armed-bg);   border-color: var(--armed-rule);   border-left-color: var(--armed); }
.note-refused { background: var(--refused-bg); border-color: var(--refused-rule); border-left-color: var(--refused); color: var(--refused); }
.note-accent  { background: var(--accent-bg);  border-color: var(--accent-rule);  border-left-color: var(--accent); }

/* A row of counts that belong together. */
.strip {
  display: grid; gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}
.strip > * { background: var(--surface); padding: 1.125rem 1.25rem; }

/* --- buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  padding: 0.5rem 0.875rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm); font-weight: 500;
  line-height: 1.25rem;
  text-decoration: none; cursor: pointer;
  transition: background-color 0.12s, color 0.12s, border-color 0.12s;
}
.btn:hover { background: var(--panel); color: var(--ink); }
.btn:focus-visible { outline: none; box-shadow: var(--focus); }
.btn-sm { padding: 0.3rem 0.625rem; font-size: var(--text-xs); line-height: 1rem; }

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

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

.btn-outline-secondary { border-color: var(--rule); color: var(--ink-soft); }
.btn-outline-secondary:hover { background: var(--panel); color: var(--ink); }

.btn-outline-danger { border-color: var(--refused-rule); color: var(--refused); }
.btn-outline-danger:hover { background: var(--refused-bg); border-color: var(--refused); color: var(--refused); }
.btn-danger { background: var(--refused); border-color: var(--refused); color: #ffffff; }
.btn-danger:hover { background: #b91c1c; border-color: #b91c1c; color: #ffffff; }

.btn-link {
  border-color: transparent; background: none; box-shadow: none; color: var(--accent);
  padding-left: 0.25rem; padding-right: 0.25rem;
}
.btn-link:hover { background: none; color: var(--accent-hover); text-decoration: underline; }

.btn:disabled, .btn[disabled] {
  border-color: var(--rule); background: var(--panel);
  color: var(--ink-faint); cursor: not-allowed; box-shadow: none;
}
.btn:disabled:hover, .btn[disabled]:hover { background: var(--panel); color: var(--ink-faint); }

/* button_to emits a <form>; this keeps one sitting inline with its siblings. */
.btn-form { display: inline; }

/* --- badges --------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center;
  padding: 0.15rem 0.55rem;
  border-radius: var(--radius-pill);
  background: var(--panel); color: var(--ink-soft);
  font-size: var(--text-xs); font-weight: 500;
  white-space: nowrap;
}
.badge.bg-secondary { background: var(--panel);      color: var(--ink-soft); }
.badge.bg-success   { background: var(--good-bg);    color: var(--good); }
.badge.bg-danger    { background: var(--refused-bg); color: var(--refused); }
.badge.bg-warning   { background: var(--armed-bg);   color: var(--armed); }
.badge.bg-info      { background: var(--info-bg);    color: var(--info); }
.badge.bg-light     { background: var(--panel);      color: var(--ink-soft); }
.badge-amber        { background: var(--armed-bg);   color: var(--armed); }

/* A status word belonging to one row, rather than a count. */
.state {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border: 1px solid currentColor; border-radius: var(--radius-pill);
  color: var(--ink-soft);
  font-size: var(--text-xs); font-weight: 500;
  white-space: nowrap;
}
.state-ok, .state.is-up-to-date          { color: var(--good); }
.state-armed, .state.is-pending,
.state.is-ahead                          { color: var(--armed); }
.state-refused                           { color: var(--refused); }

/* --- tables --------------------------------------------------------------- */
.table-responsive {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.table thead th {
  padding: 0.625rem 0.875rem;
  text-align: left; white-space: nowrap;
  font-size: var(--text-xs); font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-soft);
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
}
.table thead th.text-end { text-align: right; }
.table tbody td {
  padding: 0.75rem 0.875rem; vertical-align: middle;
  border-bottom: 1px solid var(--rule-soft);
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover td { background: var(--panel); }
.table-sm thead th { padding: 0.5rem 0.625rem; }
.table-sm tbody td { padding: 0.5rem 0.625rem; }
.table .blank { color: var(--ink-faint); }
/* A hash or a DID must not wrap mid-token; the wrapper scrolls instead. */
.table .mono, .table code { white-space: nowrap; }

/* Cursor pagination footer: count on the left, "older" on the right. */
.table-page {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.5rem 0.75rem; padding-top: 0.875rem;
}

/* --- forms ---------------------------------------------------------------- */
.form-label {
  display: block; margin-bottom: 0.35rem;
  font-size: var(--text-sm); font-weight: 500;
  color: var(--ink);
}
.form-control {
  display: block; width: 100%;
  padding: 0.5rem 0.75rem;
  background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--radius);
  box-shadow: var(--shadow);
  color: var(--ink);
  font: inherit; font-size: var(--text-base);
}
.form-control::placeholder { color: var(--ink-faint); }
.form-control:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.form-control:disabled { background: var(--panel); color: var(--ink-faint); }
.form-control-sm { padding: 0.35rem 0.55rem; font-size: var(--text-sm); }
.form-control.mono, select.form-control, input.form-control[type="text"].mono {
  font-family: var(--font-mono);
}
textarea.form-control { resize: vertical; }
.form-check { display: flex; align-items: center; gap: 0.5rem; font-size: var(--text-base); }
.form-check input[type="checkbox"], .form-check input[type="radio"] { accent-color: var(--accent); width: 1rem; height: 1rem; }
.form-hint { margin: 0.35rem 0 0; font-size: var(--text-xs); color: var(--ink-soft); }

.field { display: flex; flex-direction: column; gap: 0.3rem; }
.field-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.field-row > .form-control, .field-grow { flex: 1 1 11rem; min-width: 0; }

.input-group { display: flex; align-items: stretch; min-width: 0; }
.input-group > .form-control { border-radius: 0; border-left: 0; border-right: 0; box-shadow: none; min-width: 0; }
.input-group > :first-child { border-radius: var(--radius) 0 0 var(--radius); border-left: 1px solid var(--rule); }
.input-group > :last-child  { border-radius: 0 var(--radius) var(--radius) 0; border-right: 1px solid var(--rule); }
.input-group-text {
  display: inline-flex; align-items: center; padding: 0 0.75rem;
  background: var(--panel); border: 1px solid var(--rule);
  color: var(--ink-soft); font-size: var(--text-sm); white-space: nowrap;
}

/* --- alerts --------------------------------------------------------------- */
.alert {
  padding: 0.75rem 1rem;
  border: 1px solid var(--rule); border-radius: var(--radius);
  font-size: var(--text-base);
}
.alert-success { background: var(--good-bg);    border-color: var(--good-rule);    color: #047857; }
.alert-danger  { background: var(--refused-bg); border-color: var(--refused-rule); color: #b91c1c; }
.alert-warning { background: var(--armed-bg);   border-color: var(--armed-rule);   color: var(--armed); }
.alert-info    { background: var(--info-bg);    border-color: var(--info-rule);    color: #0369a1; }

/* --- breadcrumb, spinner -------------------------------------------------- */
.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem;
  margin: 0; padding: 0; list-style: none;
  font-size: var(--text-base); color: var(--ink-soft);
  overflow-wrap: anywhere;
}
.breadcrumb-item { display: flex; align-items: center; gap: 0.25rem; }
.breadcrumb-item + .breadcrumb-item::before { content: "/"; margin-right: 0.25rem; color: var(--ink-faint); }
.breadcrumb-item.active { color: var(--ink); font-weight: 500; }
.breadcrumb-item a { color: var(--accent); }

.spinner-border {
  display: inline-block; width: 1rem; height: 1rem;
  border: 2px solid var(--rule); border-top-color: var(--accent);
  border-radius: var(--radius-pill);
  animation: dm-spin 0.7s linear infinite;
  vertical-align: -0.125em;
}
.spinner-border-sm { width: 0.875rem; height: 0.875rem; }
@keyframes dm-spin { to { transform: rotate(360deg); } }

/* --- modal ---------------------------------------------------------------- */
.modal {
  position: fixed; inset: 0; z-index: 50;
  display: none; place-items: center;
  padding: 1rem; background: rgba(15, 23, 42, 0.5);
}
.modal.is-open { display: grid; }
.modal-box {
  width: 100%; max-width: 34rem;
  max-height: calc(100dvh - 2rem); overflow: auto;
  background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.modal-box-wide { max-width: 60rem; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 1rem 1.25rem; border-bottom: 1px solid var(--rule);
  font-weight: 600;
}
.modal-body { padding: 1.25rem; display: flex; flex-direction: column; gap: 1rem; }

/* --- key/value lists ------------------------------------------------------ */
/* Metadata under a headline value. Each pair is its own wrapper element in the views, so a
   pair occupies one grid cell and a label never wraps away from its value. */
.meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
  gap: 0.2rem 1.25rem;
  margin: 0.7rem 0 0; font-size: var(--text-xs);
}
.meta dt {
  display: inline; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft);
}
.meta dd { display: inline; margin: 0 0 0 0.35rem; font-family: var(--font-mono); color: var(--ink); }

/* Two columns of pairs — a detail panel. */
.detail-list {
  display: grid; gap: 0.35rem 1.5rem; margin: 0 0 1rem; font-size: var(--text-sm);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.detail-list dt {
  display: inline; font-size: var(--text-xs);
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft);
}
.detail-list dd { display: inline; margin: 0 0 0 0.35rem; font-family: var(--font-mono); overflow-wrap: anywhere; }

/* Label left, number right, one per line. */
.tally { margin: 0.5rem 0 0; font-size: var(--text-xs); color: var(--ink-soft); }
.tally div { display: flex; justify-content: space-between; gap: 0.75rem; }
.tally dd { margin: 0; font-family: var(--font-mono); color: var(--ink); }

/* Rows of equal panels. They fold at whatever width the content stops fitting,
   rather than at one hard breakpoint, so the mid sizes are not a dead zone. */
.row { display: grid; gap: 1rem; margin-bottom: 1rem; }
.row-pair { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.row-trio { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }

.more summary { cursor: pointer; color: var(--ink-soft); }
.more[open] summary { margin-bottom: 0.6rem; }
.push-end { margin-left: auto; }

/* --- distribution band ----------------------------------------------------
   A proportional stripe: one segment per category, width by count. Used for the
   OTA fleet's version spread, and reusable for any "what is out there" split.  */
.band {
  display: flex; height: 3rem;
  border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden;
}
.band > * { min-width: 3px; border-right: 1px solid var(--surface); transform-origin: left center; }
.band > :last-child { border-right: 0; }

.seg-stale   { background: var(--stale); }
.seg-behind  { background: var(--info); }
.seg-live    { background: var(--accent); }
.seg-armed   { background: repeating-linear-gradient(135deg, var(--armed) 0 4px, #d97706 4px 8px); }
.seg-refused { background: repeating-linear-gradient(135deg, var(--refused) 0 4px, #ef4444 4px 8px); }
.seg-absent  {
  background: var(--panel);
  background-image: radial-gradient(var(--ink-faint) 1px, transparent 1px);
  background-size: 5px 5px;
}

/* The band's readout, and the only version of it a screen reader gets. Each row
   is banded in its segment's colour, so no separate swatch element is needed. */
.legend {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr));
  gap: 0.5rem 1.5rem; margin: 1rem 0 0; padding: 0; list-style: none;
}
.legend li {
  display: flex; align-items: baseline; gap: 0.5rem;
  padding: 0.5rem 0 0.5rem 0.7rem;
  border-left: 3px solid var(--rule);
  background: var(--panel);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.legend .key { font-family: var(--font-mono); font-weight: 500; }
.legend .num { margin-left: auto; padding-right: 0.6rem; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.legend small {
  display: block; font-size: var(--text-xs);
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft);
}
.legend .is-live    { border-left-color: var(--accent); }
.legend .is-behind  { border-left-color: var(--info); }
.legend .is-armed   { border-left-color: var(--armed); }
.legend .is-refused { border-left-color: var(--refused); }

/* Per-row miniature of the band: label, proportional track, count. */
.spread { list-style: none; margin: 0.5rem 0 0; padding: 0; }
.spread li {
  display: grid; grid-template-columns: minmax(4.5rem, 7rem) 1fr auto; align-items: center;
  gap: 0.6rem; padding: 0.25rem 0;
  font-size: var(--text-sm); color: var(--ink-soft);
}
.spread li.is-live { color: var(--ink); font-weight: 500; }
.track { height: 0.5rem; background: var(--panel); border-radius: var(--radius-pill); overflow: hidden; }
.track > i { display: block; height: 100%; background: var(--stale); }
.spread .is-live .track > i  { background: var(--accent); }
.spread .is-absent .track > i { background: var(--rule); }
.spread .num { min-width: 2.5rem; text-align: right; font-family: var(--font-mono); }

/* --- sequence gate --------------------------------------------------------
   Numbered steps for a genuine one-way sequence. Only use where the order is
   real and the reader needs it — not as decoration on an unordered list.       */
.gate { display: inline-flex; align-items: center; }
.gate span {
  display: grid; place-items: center;
  width: 1.5rem; height: 1.5rem;
  background: var(--surface); border: 1px solid var(--rule);
  color: var(--ink-faint);
  font-family: var(--font-mono); font-size: var(--text-xs);
}
.gate span + span { border-left: 0; }
.gate span:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.gate span:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.gate .is-done { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.gate .is-next { border-color: var(--armed); color: var(--armed); }
.gate .is-void { background: var(--panel); border-color: var(--rule); color: var(--ink-faint); }

/* An ordered precedence, drawn rather than described. */
.ladder {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  margin: 0 0 1.5rem; padding: 0; list-style: none;
  font-family: var(--font-mono); font-size: var(--text-sm);
}
.ladder li { display: flex; align-items: center; gap: 0.5rem; }
.ladder li::after { content: "\25B8"; color: var(--ink-faint); }
.ladder li:last-child::after { content: ""; }
.ladder b {
  padding: 0.2rem 0.6rem; border: 1px solid var(--rule); border-radius: var(--radius-pill);
  background: var(--surface); font-weight: 500;
}
.ladder li:first-child b { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* --- record lists --------------------------------------------------------- */
.records { list-style: none; margin: 0; padding: 0; }
.records > li { padding: 0.875rem 0; border-top: 1px solid var(--rule-soft); }
.records > li:first-child { border-top: 0; }
.records-compact > li {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.6rem; padding: 0.5rem 0;
}
/* A per-record control row: the select takes the slack but stops short of the full card width,
   so its buttons stay beside it rather than wrapping under. */
.records .field-row > .form-control { max-width: 22rem; }
.record-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.35rem 0.75rem;
}
.push { margin-left: auto; color: var(--ink-soft); }
.chips {
  display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.5rem;
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-soft);
}

/* --- page furniture ------------------------------------------------------- */
.page-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1.25rem;
  padding: 1.25rem 0 1rem; margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--rule);
}
.page-head h1 {
  margin: 0; font-size: var(--text-xl); font-weight: 600;
  letter-spacing: -0.01em; color: var(--ink);
}
.page-head nav { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; }
@media (min-width: 640px) { .page-head nav { margin-left: auto; } }

.section { margin-bottom: 2rem; }

/* The line above the OTA fleet band: what leads the fleet right now. */
.fleet-newest-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem;
  margin: 0 0 0.875rem;
}
.fleet-newest-line .mono { font-size: var(--text-lg); color: var(--accent); }
.orphans { margin-bottom: 1rem; }
.did { font-size: var(--text-base); font-weight: 500; overflow-wrap: anywhere; }

.section-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 0.35rem 0.75rem; padding-bottom: 0.6rem; margin-bottom: 1rem;
  border-bottom: 1px solid var(--rule);
}
.lede { margin: 0; color: var(--ink-soft); }
.lede-wide { max-width: 68ch; margin-bottom: 1.5rem; }
.empty { margin: 0; color: var(--ink-soft); }

/* --- Bootstrap-shaped aliases --------------------------------------------
   Names the existing views and their inline JS already emit. Kept so no page has
   to be rewritten to adopt this file; prefer the semantic names above in new work. */
.d-flex { display: flex; }
.d-none { display: none; }
.d-inline { display: inline; }
.d-block { display: block; }
.flex-column { flex-direction: column; }
.justify-content-between { justify-content: space-between; }
.align-items-center { align-items: center; }
.text-end { text-align: right; }
.text-muted, .text-secondary { color: var(--ink-soft); }
.text-danger { color: var(--refused); }
.text-warning { color: var(--armed); }
.text-success { color: var(--good); }
.text-dark { color: var(--ink); }
.fw-semibold { font-weight: 600; }
.small { font-size: var(--text-xs); }
.fs-3 { font-size: var(--text-xl); }
.border-bottom { border-bottom: 1px solid var(--rule); }
.position-relative { position: relative; }
.position-absolute { position: absolute; }
.me-1 { margin-right: 0.25rem; }
.me-2 { margin-right: 0.5rem; }
.ms-1 { margin-left: 0.25rem; }
.ms-auto { margin-left: auto; }
.ps-4 { padding-left: 1.5rem; }
.g-3 { gap: 1rem; }
.btn-secondary { background: var(--ink); border-color: var(--ink); color: #ffffff; }
.btn-secondary:hover { background: #1e293b; border-color: #1e293b; color: #ffffff; }
.badge-blue { background: var(--accent-bg); color: var(--accent-hover); }
/* page headers: wrap the title and its right-side note instead of cramping */
.d-flex.justify-content-between.border-bottom { flex-wrap: wrap; column-gap: 0.75rem; row-gap: 0.25rem; }

/* --- small screens --------------------------------------------------------- */
@media (max-width: 640px) {
  .card-body, .panel, .modal-body { padding: 1rem; }
  .card-header, .card-footer, .modal-head { padding-left: 1rem; padding-right: 1rem; }
  .strip > * { padding: 0.875rem 1rem; }
  .table thead th { padding: 0.5rem 0.625rem; }
  .table tbody td { padding: 0.625rem; }
  .fleet-newest { text-align: left; }
  .push-end, .push { margin-left: 0; }
  .btn { width: auto; }
}

/* --- motion --------------------------------------------------------------- */
/* One orchestrated moment, used by the fleet band: it fills left to right on
   load, oldest first, which is the direction the work moves it. */
@media (prefers-reduced-motion: no-preference) {
  .band > * { animation: dm-fill 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) backwards; }
  @keyframes dm-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}
