/* VATDS-specific overrides (layered on top of CHub's main.css).
   Keep this file minimal -- prefer reusing tokens/components from main.css. */

/* ---------------------------------------------
   POSITION IDS waiting state (no live connection)
   --------------------------------------------- */
.position-ids-waiting {
  padding: 0.5rem 0.85rem 0.75rem;
}

.position-ids-waiting-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--sidebar-muted-foreground);
  font-size: 0.8rem;
}

.position-ids-spinner {
  width: 12px;
  height: 12px;
  border: 2px solid var(--sidebar-border);
  border-top-color: var(--brand);
  border-radius: 50%;
  flex-shrink: 0;
  animation: vatds-spin 0.9s linear infinite;
}

@keyframes vatds-spin {
  to { transform: rotate(360deg); }
}

.position-ids-waiting-label {
  font-weight: 500;
}

.position-ids-waiting-sub {
  font-size: 0.7rem;
  color: var(--sidebar-muted-foreground);
  margin: 0.3rem 0 0 1.75rem;
  line-height: 1.35;
}


/* =============================================================
   === IDS dashboards ===
   Layouts for views/ids/{cab,tracon,enroute,tmu}.ejs + shared
   runway-card and ATIS-cell partials. Builds on .card, .badge,
   .btn, and tokens from variables.css. Keep additions here so
   individual templates stay structural.
   ============================================================= */

/* ---- Header strip ----
   Transparent, title-like. No card chrome — reads as a page heading with
   a live-pulse badge on the right, consistent across all IDS dashboards. */
.ids-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0 0 0.65rem;
  margin: 0 0 1rem;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
}
.ids-header-main { min-width: 0; flex: 1 1 auto; }
.ids-header-top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.ids-title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.ids-header-sub {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 0.35rem;
  color: var(--muted-foreground);
  font-size: 0.82rem;
}
.ids-header-callsign {
  font-weight: 700;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.ids-header-freq {
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
}
.ids-header-sector,
.ids-header-facility {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  font-size: 0.72rem;
}
.ids-header-meta {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
}
.ids-view-only-badge { text-transform: none; }

/* Group-type badges (LED-style pills) */
.ids-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
  background: var(--secondary);
  color: var(--foreground);
  box-shadow: inset 0 0 0 1px var(--border);
}
.ids-badge-cab     { background: rgba(249, 115, 22, 0.15); color: #fdba74; box-shadow: inset 0 0 0 1px rgba(249, 115, 22, 0.45); }
.ids-badge-tracon  { background: rgba(59, 130, 246, 0.15); color: #93c5fd; box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.45); }
.ids-badge-enroute { background: rgba(168, 85, 247, 0.15); color: #c4b5fd; box-shadow: inset 0 0 0 1px rgba(168, 85, 247, 0.45); }
.ids-badge-tmu     { background: rgba(234, 179, 8, 0.15);  color: #fde68a; box-shadow: inset 0 0 0 1px rgba(234, 179, 8, 0.45); }

.ids-live-pulse {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
  animation: ids-pulse 2.2s ease-in-out infinite;
  display: inline-block;
}
@keyframes ids-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(0.88); }
}

/* ---- Shared section/card headers ---- */
.ids-section-head {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.ids-section-eyebrow {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin: 1.25rem 0 0.5rem;
}
.ids-section { margin-bottom: 1.25rem; }
.ids-updated-label {
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
}

/* ---- ATIS strip ----
   Compact per-airport ATIS grid. Each cell shows ICAO + ATIS code in a tight
   header row, then a single combined runway row (landing pills are green,
   departing pills are orange — no labels needed) and an optional approaches
   row. Adjacent airports get a slightly darker tint instead of a dashed
   border to keep the grid visually quiet at 10+ cells. */
.ids-atis-card { margin-bottom: 0.75rem; }
.ids-atis-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.5rem 0.75rem 0.25rem;
}
.ids-atis-eyebrow {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.ids-atis-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.4rem;
  padding: 0.25rem 0.5rem 0.5rem;
}
.ids-atis-cell {
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.35rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}
.ids-atis-cell-adjacent {
  background: rgba(255, 255, 255, 0.012);
  border-color: rgba(255, 255, 255, 0.06);
}
.ids-atis-cell.is-empty {
  opacity: 0.55;
  gap: 0;
}
.ids-atis-cell-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  min-height: 1.3rem;
}
.ids-atis-icao {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--foreground);
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ids-atis-code {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--brand-muted);
  color: var(--brand);
  box-shadow: inset 0 0 0 1px rgba(249, 115, 22, 0.3);
  min-width: 1.75rem;
  text-align: center;
  flex-shrink: 0;
}
.ids-atis-code.offline {
  background: transparent;
  color: var(--muted-foreground);
  box-shadow: inset 0 0 0 1px var(--border);
}
.ids-atis-cell-body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}
.ids-atis-runways {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.45rem;
  min-width: 0;
}
.ids-atis-pills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  min-width: 0;
}
.ids-atis-pills:empty { display: none; }
.ids-atis-approaches { gap: 0.2rem; }
.ids-atis-empty {
  font-size: 0.78rem;
  color: var(--muted-foreground);
  line-height: 1;
}
.ids-atis-cell-body.is-empty {
  /* Collapse body content to just the dim em-dash so the cell shrinks to
     header height. The empty marker is the only visible child. */
  flex-direction: row;
  align-items: center;
  min-height: 0;
}
.ids-atis-cell-body.is-empty .ids-atis-runways,
.ids-atis-cell-body.is-empty .ids-atis-approaches { display: none; }
.ids-atis-cell-body:not(.is-empty) .ids-atis-empty { display: none; }

/* ---- Active logins row ----
   Sits directly under the IDS title; lists every controller on VATSIM whose
   callsign parses to this screen's (facility_prefix, group_type). Live-
   updated on each 3s poll via the [data-active-logins] anchor. */
.ids-active-logins {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: -0.5rem 0 1rem;
  padding: 0.35rem 0 0;
  font-size: 0.82rem;
  color: var(--muted-foreground);
}
.ids-active-logins-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-right: 0.3rem;
}
.ids-active-login {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ids-active-login-callsign {
  font-weight: 700;
  color: var(--foreground);
  letter-spacing: 0.02em;
}
.ids-active-login-cid {
  color: var(--muted-foreground);
  font-size: 0.78rem;
}
.ids-active-login-name {
  color: var(--muted-foreground);
  font-size: 0.78rem;
}
.ids-active-login-sep { color: var(--muted-foreground); margin-right: 0.1rem; }
.ids-active-logins-empty { font-style: italic; font-size: 0.8rem; }

/* "Control" badge marking the controller currently holding active position
   responsibility per the VATDS active-controller table. Sits between the cid
   and the tag pills. Hue follows the brand token so it visually outranks the
   per-user tag pills. */
.ids-active-login-badge {
  margin-left: 0.2rem;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.08rem 0.45rem;
  border-radius: 999px;
  background: var(--success);
  color: var(--success-foreground);
  border-color: var(--success);
}
.ids-active-login-badge--cic {
  background: var(--warning);
  color: #000;
  border-color: var(--warning);
}
.ids-active-login-badge--cc {
  background: var(--info, #3b82f6);
  color: #fff;
  border-color: var(--info, #3b82f6);
}
.ids-active-login.is-active-controller .ids-active-login-callsign {
  color: var(--success);
}

/* Tag pill rendered next to a login's (cid). Tinted with the tag's color; the
   color is passed via --tag-color so hover states can reference it. Sizing
   matches the runway-active chip family but a touch smaller so a stack of
   tags reads as meta-information, not a primary action. */
.ids-active-login-tag {
  display: inline-flex;
  align-items: center;
  padding: 0.08rem 0.4rem;
  margin-left: 0.2rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  line-height: 1.25;
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}

/* Small × button on a runway chip in the admin runways panel. */
.rwy-chip-remove {
  background: transparent;
  border: 0;
  color: var(--muted-foreground);
  cursor: pointer;
  padding: 0 0.1rem;
  font-size: 0.95rem;
  line-height: 1;
  border-radius: 3px;
}
.rwy-chip-remove:hover { color: var(--danger, #e11d48); background: rgba(225, 29, 72, 0.08); }

/* CID/name autocomplete dropdown for the Tags assignment form. */
.tag-search-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
  max-height: 240px;
  overflow-y: auto;
}
.tag-search-row {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  padding: 0.5rem 0.7rem;
  color: var(--foreground);
  cursor: pointer;
  font-size: 0.85rem;
}
.tag-search-row:hover { background: var(--muted); }

/* ---- Current Weather strip (Cab only) ----
   One thin transparent row above the Runway Status / ATIS grid. Wind and
   altimeter per primary airport on the left in large white mono-font; Zulu
   clock on the right. No card chrome — reads as HUD text.
   Feeds from api.weather.gov via services/metar; public/js/ids.js updates
   [data-wx-readout] per-airport and ticks [data-ids-zulu] once per second. */
.ids-wx-strip {
  display: grid;
  /* auto | 1fr | auto — the middle column absorbs all free space between the
     real left/right content, so the timer sits exactly centered between the
     altimeter's relative-time stamp and the left edge of the Zulu clock.
     align-items: start so the timers and Zulu clock pin to the top row even
     when the left column stacks multiple airport readouts vertically. */
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 2rem;
  padding: 0.5rem 0.25rem 0.85rem;
  margin: 0 0 1rem;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
}
.ids-wx-strip-center {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}
/* Stack multiple airport readouts vertically — keeps the left column narrow
   so the timers stay centered in the 1fr middle column instead of being
   pushed right by a wide horizontal airport list. */
.ids-wx-strip-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  min-width: 0;
}
/* Each airport's readout: ICAO label, large wind value, LOTS of horizontal
   space, large altimeter value, tiny relative-time stamp. */
.ids-wx-readout {
  display: inline-flex;
  align-items: baseline;
  gap: 3.5rem;
  font-family: var(--font-mono);
  font-size: 3rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
  white-space: nowrap;
}
.ids-wx-readout-icao {
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  align-self: center;
  margin-right: -2rem; /* pull the big value closer to the ICAO label */
}
.ids-wx-readout-wind { color: #fff; font-weight: 800; }
.ids-wx-readout-alt {
  color: #6b7280; /* darker gray — mirrors the Zulu clock below */
  font-weight: 800;
}
/* Per-field wrapper — stacks the big value on top and a small "Wind 24m"
   / "Alt 24m" age badge underneath when that specific field had to be
   sourced from an older observation than the strip's main timestamp. */
.ids-wx-readout-field {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.05;
}
.ids-wx-readout-age {
  font-family: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #f59e0b; /* amber — draws the eye to the "this part is older" hint */
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
}
.ids-wx-readout-age[hidden] { display: none; }
.ids-wx-readout-stamp {
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--muted-foreground);
  align-self: center;
  margin-left: -1.5rem;
}
.ids-wx-strip-right {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: 0.75rem;
}
.ids-wx-timers {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.ids-wx-timer-btn {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 2.8rem;
  height: 2.8rem;
  padding: 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  color: var(--foreground);
  font-family: var(--font-mono);
  font-size: 1.1rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast);
}
.ids-wx-timer-btn:hover {
  border-color: var(--brand);
  color: var(--brand);
}
.ids-wx-timer-btn.is-active {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
}
.ids-wx-timer-unit {
  font-size: 0.48rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  margin-top: 0.15rem;
  opacity: 0.75;
}
.ids-wx-countdown {
  font-family: var(--font-mono);
  font-size: 3rem;
  font-weight: 800;
  color: var(--foreground);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
  padding: 0 0.5rem;
  border: 0;
  background: transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-mono); /* override button default */
}
.ids-wx-countdown:hover { background: rgba(255, 255, 255, 0.06); }
.ids-wx-countdown:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ids-wx-countdown[hidden] { display: none; }
/* When a timer is running, hide the 2/3/5 MIN buttons so only the countdown
   sits between the altimeter and the clock. */
[data-timer-group].is-timer-running .ids-wx-timers { display: none; }
.ids-wx-countdown.is-warn { color: #f97316; }
.ids-wx-countdown.is-done {
  animation: ids-timer-flash 0.6s steps(1, end) infinite;
}
@keyframes ids-timer-flash {
  0%, 100% { color: #ef4444; background: transparent; }
  50% { color: #fff; background: #ef4444; }
}
.ids-wx-zulu {
  font-family: var(--font-mono);
  font-size: 3rem;
  font-weight: 800;
  color: #6b7280; /* darker gray — matches the altimeter on the left */
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}
@media (max-width: 900px) {
  .ids-wx-readout,
  .ids-wx-zulu,
  .ids-wx-countdown { font-size: 2.25rem; }
  .ids-wx-readout { gap: 2rem; }
  .ids-wx-strip-left { gap: 2rem; }
}
@media (max-width: 640px) {
  .ids-wx-readout,
  .ids-wx-zulu,
  .ids-wx-countdown { font-size: 1.7rem; }
  .ids-wx-readout { gap: 1.25rem; }
  .ids-wx-strip-left { gap: 1.25rem; }
  .ids-wx-readout-icao { margin-right: -0.75rem; }
}

/* ---- Runway Status (left) + ATIS & Flow (right) two-column layout ----
   Mirrors the facility dashboard's .facility-grid ratio. The ATIS sidecard
   on the right uses the shared .atis-flow-row / .atis-badge primitives from
   vatds-restore.css so it matches the facility dashboard exactly. */
.ids-rwy-atis-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(320px, 1fr);
  gap: 1.25rem;
  margin-bottom: 1.5rem;
  align-items: start;
}
.ids-rwy-atis-main { min-width: 0; }
.ids-rwy-atis-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}
.ids-rwy-atis-side .card { margin-bottom: 0; }
@media (max-width: 900px) {
  .ids-rwy-atis-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Runway flag cards ---- */
.ids-airport-card { margin-bottom: 1rem; }

/* Unified runway-status card: one .card wraps every primary airport
   (stacked top to bottom) plus a collapsible adjacent dropdown at the
   bottom. Primaries are separated by a subtle border; adjacents are
   native <details> elements that slide below the primary list. */
.ids-rwy-card-body {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}

.ids-rwy-primary {
  padding: 0.9rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.ids-rwy-primary.has-divider {
  border-top: 1px solid var(--border);
}
.ids-rwy-primary-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.ids-rwy-card-icao {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  margin: 0;
  color: var(--foreground);
}

/* "Locked" indicator on a primary ICAO header — appears when the
   owning Cab controller is online. Small amber pill so users at other
   screens see at a glance that the runway status is write-gated. */
.ids-rwy-lock {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  background: rgba(245, 158, 11, 0.14);
  color: #f59e0b;
  border: 1px solid rgba(245, 158, 11, 0.35);
  white-space: nowrap;
}
.ids-card-adj-lock {
  font-size: 0.8rem;
  color: #f59e0b;
  line-height: 1;
}

/* Adjacent-airport list lives at the bottom of the same card. Each
   adjacent airport is a <details> block: ICAO + count + "Adjacent"
   tag in the summary; small readonly runway-pair stack in the body. */
.ids-card-adj-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
}
.ids-card-adj {
  border-top: 1px dashed rgba(255, 255, 255, 0.06);
}
.ids-card-adj:first-child { border-top: none; }
.ids-card-adj-summary {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.55rem 1rem;
  cursor: pointer;
  user-select: none;
  list-style: none;
  transition: background 0.12s;
}
.ids-card-adj-summary:hover { background: rgba(255, 255, 255, 0.03); }
.ids-card-adj-summary::-webkit-details-marker { display: none; }
.ids-card-adj-icao {
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
}
.ids-card-adj-count {
  font-size: 0.74rem;
  color: var(--muted-foreground);
}
.ids-card-adj-note {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: var(--secondary);
  color: var(--muted-foreground);
  margin-right: auto;
}
.ids-card-adj-caret {
  font-size: 0.85rem;
  color: var(--muted-foreground);
  transition: transform 0.15s;
}
.ids-card-adj[open] .ids-card-adj-caret { transform: rotate(180deg); }
.ids-card-adj-body {
  padding: 0 1rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
/* Flush variant — used inside cards whose content area has no padding
   (e.g. the ATIS & Flow card, whose inner atis-flow-row carries its own
   horizontal padding). Keeps the adjacent row visually aligned with
   the primary rows above. */
.ids-card-adj-body-flush {
  padding: 0;
  gap: 0;
}

/* Bordered, muted card footer used by IDS cards that want a clearly-
   demarcated "about this card" line at the bottom. Overrides the global
   .card-footer's content-tail look with a top border, slightly
   distinguished background, smaller type, and rounded bottom corners
   matching the parent .card's radius. */
.ids-card-footer {
  padding: 0.45rem 0.9rem;
  margin-top: 0;
  font-size: 0.7rem;
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--muted-foreground);
  background: rgba(255, 255, 255, 0.025);
  border-top: 1px solid var(--border);
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
}
/* Cancel the default spacing the global .card-footer applies so our
   bordered version sits flush against the content above it. */
.ids-card-footer.card-footer {
  padding: 0.45rem 0.9rem;
}
.card-content + .ids-card-footer.card-footer { padding-top: 0.45rem; }
.ids-card-adj-empty {
  font-size: 0.78rem;
  color: var(--muted-foreground);
  padding: 0.25rem 0;
}
.ids-flow-strip {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--foreground);
  background: var(--secondary);
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius-sm);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Airport card internal split: runways stack on the left, ATIS cell on the right. */
.ids-airport-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 280px);
  gap: 1rem;
  padding: 1rem;
  align-items: start;
}
/* Stack of horizontal runway-strip cards, one per runway pair. */
.ids-rwy-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}
.ids-airport-atis { min-width: 0; }
.ids-airport-atis .ids-atis-cell {
  margin: 0;
  height: 100%;
}

/* =============================================================
   === Horizontal runway strip (pair) ===
   Reads like a physical runway: left ident · central status band ·
   right ident. Clicking anywhere on the strip opens the shared
   #rwy-flag-modal (see below) to toggle status flags.
   ============================================================= */
.rwy-strip {
  display: grid;
  grid-template-columns: minmax(62px, 92px) minmax(0, 1fr) minmax(62px, 92px);
  align-items: stretch;
  background:
    linear-gradient(90deg,
      rgba(255, 255, 255, 0.03) 0%,
      rgba(255, 255, 255, 0.015) 50%,
      rgba(255, 255, 255, 0.03) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  min-height: 72px;
  cursor: pointer;
  overflow: hidden;
  transition:
    border-color var(--transition-fast),
    box-shadow var(--transition-fast),
    opacity var(--transition-fast),
    transform var(--transition-fast);
}
.rwy-strip:hover,
.rwy-strip:focus-visible {
  border-color: rgba(249, 115, 22, 0.45);
  box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.2);
  outline: none;
}
.rwy-strip:focus-visible {
  box-shadow: 0 0 0 2px var(--brand);
}
.rwy-strip:active {
  transform: translateY(1px);
}

/* Small variant used on TRACON (read-only, denser). */
.rwy-strip-sm {
  min-height: 60px;
  grid-template-columns: minmax(52px, 72px) minmax(0, 1fr) minmax(52px, 72px);
}
.rwy-strip-sm .rwy-strip-center { padding: 0.6rem 0.6rem 0.25rem; }
.rwy-strip-sm .rwy-strip-status { padding: 0.1rem 0.45rem; }

/* Inactive runway (neither end appears in ATIS): muted, darker. Still clickable. */
.rwy-strip.is-inactive {
  background: rgba(255, 255, 255, 0.008);
  border-color: rgba(255, 255, 255, 0.06);
  opacity: 0.72;
}
/* Flagged inactive runway — status indicator must stay legible, so we
   restore full opacity and let the flag color read through the dim chrome. */
.rwy-strip.is-inactive.has-flags {
  opacity: 1;
}
.rwy-strip.is-inactive .rwy-strip-ident { color: var(--muted-foreground); }
.rwy-strip.is-inactive.has-flags .rwy-strip-ident { color: var(--foreground); }

/* End caps — left/right ident panels. Look like runway threshold markers. */
.rwy-strip-end {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.4rem 0.55rem;
  background: rgba(0, 0, 0, 0.25);
  border-right: 1px dashed rgba(255, 255, 255, 0.08);
  min-width: 0;
}
.rwy-strip-end-right {
  border-right: 0;
  border-left: 1px dashed rgba(255, 255, 255, 0.08);
}
.rwy-strip.is-inactive .rwy-strip-end {
  background: rgba(0, 0, 0, 0.35);
  border-color: rgba(255, 255, 255, 0.04);
}
.rwy-strip-ident {
  font-family: var(--font-mono);
  font-size: 1.55rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}
.rwy-strip-sm .rwy-strip-ident {
  font-size: 1.25rem;
}

/* Central status band — the "runway surface". Dominated by the active flag
   label(s) when any are on; shows ACTIVE (when in ATIS) or INACTIVE otherwise. */
.rwy-strip-center {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 0.2rem;
  padding: 1.4rem 0.75rem 0.35rem;
  min-width: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.35));
  transition: background-color var(--transition-fast);
}
/* Dashed runway centerline — thin horizontal stripe across the middle,
   like the painted centerline of a physical runway. Sits behind the status
   label via z-index; the flex-stacked status content paints over it. */
.rwy-strip-center::before {
  content: "";
  position: absolute;
  left: 4%;
  right: 4%;
  top: 50%;
  height: 1.5px;
  background-image: linear-gradient(
    to right,
    rgba(255, 255, 255, 0.55) 50%,
    transparent 50%
  );
  background-size: 48px 100%;
  background-repeat: repeat-x;
  transform: translateY(-0.75px);
  pointer-events: none;
  z-index: 0;
}
.rwy-strip-meta { position: relative; z-index: 1; }
/* Status chip — pinned to the top border of the card, overlapping it like a
   stitched-on tab. Background swaps to the flag color when any flag is on. */
.rwy-strip-status {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: 0.15rem 0.6rem;
  background: var(--card, #161616);
  border: 1px solid var(--border);
  border-radius: 9999px;
  max-width: calc(100% - 1rem);
  white-space: nowrap;
}
.rwy-strip.has-flags .rwy-strip-status {
  background: #000;
  border-color: var(--flag-color, #d14b3a);
  box-shadow: 0 0 0 1px var(--flag-color, #d14b3a);
}
.rwy-strip.is-inactive:not(.has-flags) .rwy-strip-status {
  background: rgba(0, 0, 0, 0.7);
}

/* Crossing alert — a CROSSING flag held longer than 60s flashes the whole
   card border and the status chip using the flag's own color. Applied via
   JS (ids.js::evaluateCrossingAlert). */
.rwy-strip.is-crossing-alert {
  animation: rwy-crossing-alert-card 0.8s steps(1, end) infinite;
}
.rwy-strip.is-crossing-alert .rwy-strip-status {
  animation: rwy-crossing-alert-chip 0.8s steps(1, end) infinite;
}
@keyframes rwy-crossing-alert-card {
  0%, 100% {
    border-color: var(--alert-color, #ef4444);
    box-shadow: 0 0 0 2px var(--alert-color, #ef4444), 0 0 18px -2px var(--alert-color, #ef4444);
  }
  50% {
    border-color: var(--border);
    box-shadow: none;
  }
}
@keyframes rwy-crossing-alert-chip {
  0%, 100% {
    background: var(--alert-color, #ef4444);
    border-color: var(--alert-color, #ef4444);
    color: #fff;
  }
  50% {
    background: #000;
    border-color: var(--alert-color, #ef4444);
    color: var(--alert-color, #ef4444);
  }
}
.rwy-strip.has-flags .rwy-strip-center {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--flag-color, #d14b3a) 45%, #000),
      color-mix(in srgb, var(--flag-color, #d14b3a) 30%, #000));
}
.rwy-strip.is-inactive .rwy-strip-center {
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.45));
}
/* When a runway is inactive AND flagged, the flag color MUST dominate the
   status surface — safety information (CLOSED, CROSSING, etc.) outranks the
   "runway not in current ATIS" hint. Higher-specificity selector wins. */
.rwy-strip.is-inactive.has-flags .rwy-strip-center {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--flag-color, #d14b3a) 50%, #000),
      color-mix(in srgb, var(--flag-color, #d14b3a) 35%, #000));
}
.rwy-strip-status {
  display: inline-flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  gap: 0.45rem;
  text-align: center;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}
.rwy-strip-label {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  line-height: 1.05;
  color: var(--flag-color, #fff);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
  /* Keep each label on one line; ellipsize if a label is too long. Multiple
     labels share the row via the parent flex's gap; the first ones take
     priority so a single long label can't push a short one off-screen. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  max-width: 100%;
}
.rwy-strip-sm .rwy-strip-label { font-size: 1rem; letter-spacing: 0.08em; }
.rwy-strip-label.rwy-strip-ok {
  color: var(--success);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  font-weight: 700;
  opacity: 0.9;
}
.rwy-strip-label.rwy-strip-inactive {
  color: var(--muted-foreground);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  font-weight: 700;
  opacity: 0.75;
}

/* Meta row below the status band: airport ICAO + last-updated stamp. */
.rwy-strip-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  opacity: 0.85;
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
}
.rwy-strip-icao {
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.rwy-strip-meta-right {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 0;
}
/* Until-alert countdown — shown only when a CROSSING flag is active and
   the 60s threshold hasn't been reached yet. JS toggles the [hidden]
   attribute and sets --crossing-color from the flag. */
.rwy-strip-crossing {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--crossing-color, #f97316);
  text-transform: none;
  padding: 0 0.35rem;
  border-radius: 9999px;
  border: 1px solid color-mix(in srgb, var(--crossing-color, #f97316) 55%, transparent);
  background: color-mix(in srgb, var(--crossing-color, #f97316) 14%, transparent);
  line-height: 1.2;
}
.rwy-strip-crossing[hidden] { display: none; }
.rwy-strip-stamp {
  font-variant-numeric: tabular-nums;
  text-transform: none;
  letter-spacing: 0.01em;
  font-weight: 500;
  white-space: nowrap;
}

/* =============================================================
   === Departures / Arrivals traffic cards ===
   Two-column grid below the Runway Status / ATIS section on the Cab.
   Borrows the facility dashboard's .st-unified-table visual language:
   airport header strip with dir-chip counts, tabular-nums, subtle hover.
   Feeds from /ids/:id/traffic.json (polled every 30s).
   ============================================================= */
.ids-traffic-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.25rem;
  margin-top: 1.25rem;
  margin-bottom: 1.5rem;
  align-items: start;
}
@media (max-width: 900px) {
  .ids-traffic-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Keep the two cards visually balanced — identical internal rhythm. */
.ids-traffic-card { display: flex; flex-direction: column; min-width: 0; margin-bottom: 0; }
.ids-traffic-card .card-header.ids-section-head { min-height: 64px; }
.ids-traffic-card .card-content { padding: 0; flex: 1 1 auto; min-width: 0; }
.ids-traffic-card .card-footer { min-height: 40px; }

.ids-traffic-body {
  /* Grow the card to fit its rows — no internal scroll. */
  min-width: 0;
}
.ids-traffic-body .empty-state { padding: 2rem 1rem; }

/* Table uses the shared .st-unified-table language from the facility dashboard. */
.ids-traffic-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  table-layout: auto;
}
.ids-traffic-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--card);
  text-align: left;
  padding: 0.5rem 0.65rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.ids-traffic-table thead th.num { text-align: right; }
.ids-traffic-table td {
  /* Fixed row height so Arrivals rows (plain text) match Departures rows
     (which contain the taller .ids-edct-cell buttons). `height` on a td
     acts as a min-height in table layout. */
  height: 2.25rem;
  padding: 0.3rem 0.65rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  white-space: nowrap;
}
.ids-traffic-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.ids-traffic-table .ids-traffic-cs {
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* Arrival sequencing badge — small yellow chip rendered next to a
   callsign on the arrivals card when a TRACON has assigned an order
   (1-5). Always visible regardless of who is viewing; only clickable
   for TRACON-or-equivalent (see .ids-arr-cs-assignable + trigger). */
.ids-arr-order-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 0.3rem;
  margin-left: 0.35rem;
  border-radius: var(--radius-sm);
  background: #f59e0b;                /* amber/yellow */
  color: #1b1b1f;                      /* dark on amber for contrast */
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  vertical-align: baseline;
}

/* Clickable callsign wrapper (arrivals card) — present only when the
   viewer can assign. Styled as a flat button that inherits the cell's
   typography, with a subtle hover ring to signal interactivity. */
.ids-arr-cs-assignable { padding: 0; }
.ids-arr-order-trigger {
  display: inline-flex;
  align-items: baseline;
  gap: 0.15rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  padding: 0.15rem 0.4rem;
  cursor: pointer;
  text-align: left;
}
.ids-arr-order-trigger:hover,
.ids-arr-order-trigger:focus-visible {
  background: rgba(245, 158, 11, 0.08);
  border-color: rgba(245, 158, 11, 0.4);
  outline: none;
}

/* Floating assign menu. Appended to <body>, positioned with inline
   left/top relative to the trigger. Five option buttons + a Clear row. */
.ids-arr-order-menu {
  position: fixed;
  z-index: 9998;
  min-width: 11rem;
  padding: 0.5rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  color: var(--foreground);
  font-size: 0.82rem;
}
.ids-arr-order-header {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted-foreground);
  font-weight: 700;
  padding: 0 0.15rem 0.4rem;
}
.ids-arr-order-options {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.3rem;
  margin-bottom: 0.4rem;
}
.ids-arr-order-opt {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 1.9rem;
  padding: 0;
  background: var(--secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--foreground);
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.ids-arr-order-opt:hover {
  background: #f59e0b;
  color: #1b1b1f;
  border-color: #f59e0b;
}
.ids-arr-order-opt.is-active {
  background: #f59e0b;
  color: #1b1b1f;
  border-color: #f59e0b;
  box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.3);
}
.ids-arr-order-clear {
  width: 100%;
  padding: 0.4rem 0.6rem;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--muted-foreground);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.ids-arr-order-clear:hover {
  color: var(--danger, #e11d48);
  border-color: var(--danger, #e11d48);
  background: rgba(239, 68, 68, 0.08);
}

/* Zebra + hover affordance on real rows. */
.ids-traffic-row { transition: background-color var(--transition-fast); }
.ids-traffic-row:nth-of-type(even) { background: rgba(255, 255, 255, 0.015); }
.ids-traffic-row:hover { background: rgba(255, 255, 255, 0.04); }

/* Airport header strip — chip-style, spans full width of the table. */
.ids-traffic-airport-header th {
  background: rgba(255, 255, 255, 0.045);
  padding: 0.5rem 0.65rem;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-transform: none;
  letter-spacing: 0.02em;
  font-weight: 600;
  color: var(--foreground);
  position: sticky;
  top: 30px;
  z-index: 1;
}
.ids-traffic-airport-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  min-width: 0;
}
.ids-traffic-airport-icao {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--foreground);
}
.ids-traffic-airport-name {
  font-size: 0.78rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 14rem;
}
.ids-traffic-airport-counts {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

/* SimTraffic / Manual status chip on the airport strip. */
.st-airport-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.5rem;
  border-radius: var(--radius-full);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted-foreground);
}
.st-airport-chip-live {
  color: var(--brand);
  border-color: color-mix(in srgb, var(--brand) 50%, transparent);
  background: var(--brand-subtle);
}
.st-airport-chip-muted {
  color: var(--muted-foreground);
}

/* Direction chips (A / D). Shared with the facility dashboard's dir-chip class
   so both surfaces speak the same visual language. */
.dir-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0;
  line-height: 1;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.04);
  color: var(--muted-foreground);
}
.dir-chip.dir-dep {
  color: var(--brand);
  border-color: color-mix(in srgb, var(--brand) 45%, transparent);
  background: var(--brand-subtle);
}
.dir-chip.dir-arr {
  color: var(--info);
  border-color: color-mix(in srgb, var(--info) 45%, transparent);
  background: var(--info-muted);
}
.ids-traffic-dir-cell { width: 1px; padding-right: 0.35rem; }

/* Empty-state row inside a table section. */
.ids-traffic-empty-row td {
  padding: 0.9rem 0.65rem;
  background: transparent;
}
.ids-traffic-empty { text-align: center; font-style: italic; color: var(--muted-foreground); }

/* ---- Drag handle + DnD visual states ---- */
.ids-traffic-drag-cell {
  width: 1px;
  padding: 0 0.25rem 0 0.55rem !important;
  color: var(--muted-foreground);
}
.ids-traffic-drag-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem;
  height: 1.1rem;
  cursor: grab;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  line-height: 1;
  letter-spacing: -0.15em;
  user-select: none;
  color: var(--muted-foreground);
  opacity: 0.55;
  transition: opacity var(--transition-fast), color var(--transition-fast);
}
.ids-traffic-row:hover .ids-traffic-drag-handle { opacity: 1; color: var(--foreground); }
.ids-traffic-drag-handle:active { cursor: grabbing; }
.ids-traffic-row.is-dragging {
  opacity: 0.4;
  background: var(--brand-subtle);
}
.ids-traffic-row.drop-before { box-shadow: inset 0 2px 0 0 var(--brand); }
.ids-traffic-row.drop-after  { box-shadow: inset 0 -2px 0 0 var(--brand); }

/* Legacy aliases retained for back-compat with any other callers. */
.ids-traffic-airport th { background: rgba(255, 255, 255, 0.045) !important; }
.ids-traffic-airport-icao { font-family: var(--font-mono); font-weight: 800; }

/* Departures table column widths — keep the Proposed column narrow (it only
   ever shows "HH:MMz") so the Gate Hold + EDCT buttons don't get clipped at
   the right edge of the card. Columns are counted from the end so the rule
   stays valid if the Gate Hold column is ever removed. */
.ids-traffic-card[data-traffic-direction="departures"] .ids-traffic-table thead th:nth-last-child(3),
.ids-traffic-card[data-traffic-direction="departures"] .ids-traffic-table tbody td:nth-last-child(3) {
  width: 4.25rem;
  max-width: 4.25rem;
  white-space: nowrap;
}
.ids-traffic-card[data-traffic-direction="departures"] .ids-traffic-table thead th:nth-last-child(1),
.ids-traffic-card[data-traffic-direction="departures"] .ids-traffic-table thead th:nth-last-child(2),
.ids-traffic-card[data-traffic-direction="departures"] .ids-traffic-table tbody td:nth-last-child(1),
.ids-traffic-card[data-traffic-direction="departures"] .ids-traffic-table tbody td:nth-last-child(2) {
  white-space: nowrap;
  padding-left: 0.35rem;
  padding-right: 0.35rem;
}

/* EDCT cell button — renders inline like a numeric value but is clickable
   (SimTraffic slot request, or manual-edit menu on non-metered fields). */
.ids-edct-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 5.2rem;
  padding: 0.2rem 0.55rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.1;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}
.ids-edct-cell:hover {
  border-color: var(--brand);
  color: var(--brand);
}
.ids-edct-cell.is-set.is-simtraffic {
  background: color-mix(in srgb, var(--brand) 18%, transparent);
  border-color: color-mix(in srgb, var(--brand) 45%, transparent);
  color: var(--foreground);
}
.ids-edct-cell.is-empty {
  color: var(--muted-foreground);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.72rem;
}
.ids-edct-cell.is-set.is-manual {
  background: rgba(59, 130, 246, 0.15);
  border-color: rgba(59, 130, 246, 0.45);
}
/* Read-only variant used when the viewer can't edit (e.g. a TRACON looking
   at a departure airport whose Cab is online). Keeps the visual value but
   removes hover, cursor, and interaction affordance. */
.ids-edct-cell.is-readonly {
  cursor: default;
}
.ids-edct-cell.is-readonly:hover {
  border-color: var(--border);
  color: var(--foreground);
}

/* Temporal states — override the is-set.is-simtraffic / is-set.is-manual
   backgrounds. Placed after those rules so equal-specificity selectors win.
   Green once the EDCT or Gate Hold time passes; red once an EDCT is more
   than 10 min past (new slot must be requested). */
.ids-edct-cell.is-set.is-past {
  background: rgba(34, 197, 94, 0.22);
  border-color: rgba(34, 197, 94, 0.55);
  color: var(--foreground);
}
.ids-edct-cell.is-set.is-stale {
  background: rgba(239, 68, 68, 0.22);
  border-color: rgba(239, 68, 68, 0.6);
  color: var(--foreground);
}
.ids-edct-cell.is-set.is-past:hover,
.ids-edct-cell.is-set.is-stale:hover {
  color: var(--foreground);
}

/* Single-letter badge inside the cell ("E" for EDCT, "G" for Gate Hold).
   Sits flush-left of the time, slightly faded so the number reads first. */
.ids-edct-prefix {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1em;
  margin-right: 0.35rem;
  padding: 0 0.3rem;
  border-right: 1px solid currentColor;
  font-weight: 800;
  letter-spacing: 0.04em;
  opacity: 0.75;
}

/* Gate Hold cell overrides — purple family for both SimTraffic and manual
   "set" states so the column is instantly distinguishable from EDCT. */
.ids-gh-cell.is-set.is-simtraffic,
.ids-gh-cell.is-set.is-manual {
  background: rgba(168, 85, 247, 0.18);  /* purple-500 @ 18% */
  border-color: rgba(168, 85, 247, 0.55);
  color: var(--foreground);
}
.ids-gh-cell:hover {
  border-color: #a855f7;
  color: #a855f7;
}

/* Manual-EDCT context menu (shared singleton, positioned by JS on click). */
.edct-menu {
  position: fixed;
  z-index: 1000;
  min-width: 220px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.35);
  padding: 0.6rem 0.7rem;
}
.edct-menu[hidden] { display: none; }
.edct-menu-head {
  margin-bottom: 0.5rem;
  font-size: 0.82rem;
}
.edct-menu-form input[type="text"] {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.03);
  color: var(--foreground);
  font-family: var(--font-mono);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.edct-menu-form input[type="text"]:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 30%, transparent);
}
.edct-menu-actions {
  margin-top: 0.5rem;
  display: flex;
  gap: 0.4rem;
  justify-content: space-between;
}

/* =============================================================
   === Runway-flag context menu ===
   Anchored dropdown that appears next to the clicked runway strip.
   Positioned absolutely by public/js/ids.js (Modal._position).
   ============================================================= */
.rwy-context-menu {
  position: fixed;
  z-index: 1000;
  min-width: 260px;
  max-width: 360px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow:
    0 10px 24px -8px rgba(0, 0, 0, 0.55),
    0 2px 6px rgba(0, 0, 0, 0.35);
  padding: 0.5rem 0;
  color: var(--foreground);
  font-size: 0.85rem;
}
.rwy-context-menu[hidden] { display: none; }
.rwy-context-menu-head {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.4rem 0.75rem 0.5rem;
  border-bottom: 1px solid var(--border);
}
.rwy-context-menu-title-row {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  min-width: 0;
}
.rwy-context-menu-icao {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--brand);
  background: var(--brand-muted);
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px rgba(249, 115, 22, 0.3);
}
.rwy-context-menu-title {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.rwy-context-menu-sub {
  font-size: 0.72rem;
  color: var(--muted-foreground);
}
.rwy-context-menu-telemetry {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  min-height: 0.85rem;
}
.rwy-context-menu-telemetry-ok,
.rwy-context-menu-telemetry.rwy-modal-telemetry-ok { color: var(--success); }
.rwy-context-menu-telemetry-err,
.rwy-context-menu-telemetry.rwy-modal-telemetry-err { color: var(--danger, #d14b3a); }
.rwy-context-menu-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.5rem 0.75rem;
}
.rwy-context-menu-hint {
  font-size: 0.75rem;
  color: var(--muted-foreground);
  padding: 0.35rem 0.5rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
}
.rwy-context-menu-end { display: flex; flex-direction: column; gap: 0.3rem; }
.rwy-context-menu-end + .rwy-context-menu-end {
  border-top: 1px solid var(--border);
  padding-top: 0.45rem;
  margin-top: 0.15rem;
}
.rwy-context-menu-end-head {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
}
.rwy-context-menu-end-label {
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.rwy-context-menu-end-ident {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.rwy-context-menu-end-atis {
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
/* Options list: dropdown-style vertical stack. The button element itself is
   still class .rwy-modal-btn (reused); we just re-flow the container. */
.rwy-context-menu-options {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: 0.1rem;
}
.rwy-context-menu-options .rwy-modal-btn {
  width: 100%;
  justify-content: flex-start;
  padding: 0.35rem 0.6rem;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.rwy-context-menu-foot {
  padding: 0.35rem 0.75rem 0.5rem;
  border-top: 1px solid var(--border);
}
.rwy-context-menu-foot-hint {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  font-style: italic;
  opacity: 0.9;
}
.rwy-context-menu-foot-hint.rwy-modal-error { color: var(--danger, #d14b3a); font-style: normal; }

/* =============================================================
   === Runway-flag modal (legacy; kept for button reuse) ===
   Uses the shared .modal-overlay/.modal-content primitives from
   vatds-restore.css. This layer adds runway-specific formatting.
   ============================================================= */
.rwy-modal-content {
  max-width: 560px;
}
.rwy-modal-head-meta { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.rwy-modal-title-row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  min-width: 0;
}
.rwy-modal-icao {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--brand);
  background: var(--brand-muted);
  padding: 0.15rem 0.45rem;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px rgba(249, 115, 22, 0.3);
}
.rwy-modal-title {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rwy-modal-sub {
  font-size: 0.78rem;
  color: var(--muted-foreground);
  letter-spacing: 0.02em;
}

.rwy-modal-body {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.rwy-modal-readonly-hint {
  padding: 0.5rem 0.7rem;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
}
.rwy-modal-empty {
  padding: 0.85rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
}

.rwy-modal-end {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.7rem 0.8rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.rwy-modal-end-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.rwy-modal-end-label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.rwy-modal-end-ident {
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.rwy-modal-end-atis {
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.rwy-modal-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.rwy-modal-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem;
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.1;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--foreground);
  cursor: pointer;
  font-family: inherit;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    box-shadow var(--transition-fast);
}
.rwy-modal-btn:hover:not(:disabled):not(.is-readonly) {
  border-color: var(--flag-color, var(--border));
  box-shadow: 0 0 0 1px var(--flag-color, transparent);
}
.rwy-modal-btn:focus-visible {
  outline: 2px solid var(--flag-color, var(--brand));
  outline-offset: 2px;
}
.rwy-modal-btn:disabled,
.rwy-modal-btn.is-readonly {
  cursor: not-allowed;
  opacity: 0.85;
}
.rwy-modal-btn.is-on {
  background: var(--flag-color, var(--brand));
  color: #fff;
  border-color: var(--flag-color, var(--brand));
  box-shadow: 0 0 10px -2px var(--flag-color, var(--brand));
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
}
.rwy-modal-btn.is-on.is-readonly { box-shadow: none; }
.rwy-modal-btn-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--flag-color, var(--muted-foreground));
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.3);
  flex-shrink: 0;
}
.rwy-modal-btn.is-on .rwy-modal-btn-dot {
  background: #fff;
  box-shadow: none;
}
.rwy-modal-btn-label { white-space: nowrap; }
.rwy-modal-footer-hint {
  flex: 1;
  min-width: 0;
  font-style: italic;
  opacity: 0.85;
}
.rwy-modal-footer-hint.rwy-modal-error {
  color: var(--destructive, #ef4444);
  font-style: normal;
  font-weight: 600;
  opacity: 1;
}

/* ---- Panel grids (placeholders + real panels) ---- */
.ids-panel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}
.ids-two-col {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem;
  margin-bottom: 1rem;
}
@media (max-width: 768px) {
  .ids-two-col { grid-template-columns: minmax(0, 1fr); }
}
.ids-placeholder-card {
  background:
    repeating-linear-gradient(
      135deg,
      transparent 0 12px,
      rgba(255, 255, 255, 0.02) 12px 24px
    ),
    var(--card);
  opacity: 0.94;
}
.ids-placeholder-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  text-align: center;
  gap: 0.35rem;
}
.ids-placeholder-value {
  font-size: 2rem;
  font-weight: 700;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.ids-placeholder-note {
  margin: 0;
  font-style: italic;
  opacity: 0.85;
}

/* ---- Arrival / Departure rates (TRACON + TMU) ----
   Row-based table. One row per primary airport with the configured rate
   shown inline next to the live 60-min projection (cfg / live), per-direction
   number inputs (with reset-to-flow + auto pill), the metering toggle, and
   an expand row that reveals an inline SVG line graph (per-hour rate). */
.ids-rates-card { margin-bottom: 1rem; }
.ids-rates-status {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
}
.ids-rates-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
}
.ids-rates-table thead th {
  padding: 0.4rem 0.6rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  background: var(--secondary);
  border-bottom: 1px solid var(--border);
  text-align: left;
}
/* Even percentage distribution so the columns share the card width on
   any screen. table-layout:fixed makes the browser honor these as the
   actual column widths instead of treating them as hints. The Edit and
   Meter columns are sized equally on either side of Flow so the
   dropdown sits with matching gutters left and right. */
.ids-rates-table .ids-rates-col-icao   { width: 9%;  min-width: 4.5rem; }
.ids-rates-table .ids-rates-col-demand { width: 18%; min-width: 9rem; }
.ids-rates-table .ids-rates-col-edit   { width: 23%; min-width: 11rem; }
.ids-rates-table .ids-rates-col-flow   { width: 18%; min-width: 9rem; }
.ids-rates-table .ids-rates-col-meter  { width: 23%; min-width: 6rem; text-align: center; }
.ids-rates-table .ids-rates-col-expand { width: 9%;  min-width: 2.25rem; text-align: right; }
/* Center the metering toggle in its cell so the gutter to the flow
   dropdown matches the gutter to the expand chevron. */
.ids-rates-meter { text-align: center; }
.ids-rates-row td {
  padding: 0.45rem 0.6rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  font-size: 0.85rem;
}
.ids-rates-row:last-of-type td { border-bottom: 0; }
.ids-rates-icao {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
}
.ids-rates-pair {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  margin-right: 0.85rem;
  font-variant-numeric: tabular-nums;
}
.ids-rates-pair:last-child { margin-right: 0; }
.ids-rates-mini-label {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  width: 0.85rem;
  display: inline-block;
}
.ids-rates-mini-label.dir-arr { color: #22c55e; }
.ids-rates-mini-label.dir-dep { color: #3b82f6; }
.ids-rates-cfg-num {
  color: var(--muted-foreground);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
}
.ids-rates-live-num {
  font-weight: 700;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
  color: var(--foreground);
}
.ids-rates-live-num.is-over { color: #facc15; }
.ids-rates-edit {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: nowrap;
}
.ids-rates-input-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.ids-rates-input {
  width: 3.5rem;
  height: 1.9rem;
  padding: 0 0.35rem;
  font-size: 0.85rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: center;
  background: var(--background);
  color: var(--foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  appearance: textfield;
  -moz-appearance: textfield;
}
.ids-rates-input::-webkit-outer-spin-button,
.ids-rates-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.ids-rates-input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand-muted);
}
/* Auto state: tracking the active flow (no operator override). Subtle
   dashed border + muted color so it's distinguishable from a hard set. */
.ids-rates-input.is-auto {
  border-style: dashed;
  color: var(--muted-foreground);
}
.ids-rates-input.is-override {
  border-color: var(--border);
  color: var(--foreground);
}
.ids-rates-auto-pill {
  position: absolute;
  top: -0.45rem;
  right: -0.4rem;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.05rem 0.3rem;
  background: var(--secondary);
  color: var(--muted-foreground);
  border: 1px solid var(--border);
  border-radius: 999px;
  pointer-events: none;
  font-family: var(--font-mono);
}
.ids-rates-reset {
  position: absolute;
  top: -0.45rem;
  right: -0.4rem;
  width: 1rem;
  height: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  line-height: 1;
  background: var(--popover);
  color: var(--muted-foreground);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.ids-rates-reset:hover {
  color: var(--brand);
  border-color: var(--brand);
  background: var(--secondary);
}
.ids-rates-sep { color: var(--muted-foreground); font-weight: 700; }
/* Switch toggle for metering — pure CSS, no extra deps. */
.ids-rates-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  cursor: pointer;
  user-select: none;
}
.ids-rates-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.ids-rates-toggle-track {
  position: relative;
  width: 2rem;
  height: 1.1rem;
  background: var(--secondary);
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: background 0.12s, border-color 0.12s;
}
.ids-rates-toggle-knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 50%;
  background: var(--muted-foreground);
  transition: left 0.12s, background 0.12s;
}
.ids-rates-toggle input:checked ~ .ids-rates-toggle-track {
  background: var(--brand-muted);
  border-color: var(--brand);
}
.ids-rates-toggle input:checked ~ .ids-rates-toggle-track .ids-rates-toggle-knob {
  left: calc(100% - 0.95rem);
  background: var(--brand);
}
.ids-rates-toggle-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--muted-foreground);
  font-family: var(--font-mono);
}
.ids-rates-toggle input:checked ~ .ids-rates-toggle-label { color: var(--brand); }
.ids-rates-expand-btn {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--muted-foreground);
  width: 1.9rem;
  height: 1.9rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s, transform 0.12s;
}
.ids-rates-expand-btn:hover { color: var(--foreground); border-color: var(--border); }
.ids-rates-expand-btn.is-open { color: var(--brand); transform: rotate(180deg); }

/* Expand row with inline load graph. */
.ids-rates-graph-row td.ids-rates-graph-cell {
  padding: 0.5rem 0.9rem 1rem;
  background: rgba(255, 255, 255, 0.015);
  border-bottom: 1px solid var(--border);
}
.ids-rates-graph-empty {
  padding: 0.75rem 0;
  color: var(--muted-foreground);
  font-size: 0.85rem;
  font-style: italic;
}
.ids-rates-graph-svg {
  width: 100%;
  height: 240px;
  display: block;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.ids-rates-graph-legend {
  display: flex;
  gap: 1rem;
  padding: 0 0 0.4rem;
  font-size: 0.75rem;
  color: var(--muted-foreground);
}
.ids-rates-graph-legend > span { display: inline-flex; align-items: center; gap: 0.35rem; }
.ids-rates-graph-swatch {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  display: inline-block;
}
.ids-rates-graph-meta { margin-left: auto; font-variant-numeric: tabular-nums; }

.ids-rates-graph-hit { cursor: crosshair; }
.ids-rates-graph-hit:hover { fill: rgba(255, 255, 255, 0.04); }

/* Floating tooltip for the load graph. Stays out of the table flow so
   the row height isn't disturbed when it appears. */
.ids-rates-graph-tooltip {
  position: fixed;
  z-index: 9999;
  max-width: 360px;
  min-width: 200px;
  padding: 0.55rem 0.7rem;
  background: rgba(15, 18, 24, 0.96);
  color: var(--foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
  font-size: 0.78rem;
  line-height: 1.35;
  pointer-events: none;
  font-family: var(--font-mono);
}
.ids-rates-tt-head {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.3rem;
  margin-bottom: 0.4rem;
}
.ids-rates-tt-section + .ids-rates-tt-section {
  margin-top: 0.5rem;
  padding-top: 0.45rem;
  border-top: 1px solid var(--border);
}
.ids-rates-tt-section-head {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-bottom: 0.3rem;
}
.ids-rates-tt-row {
  display: grid;
  grid-template-columns: minmax(4.5rem, auto) 1fr auto;
  gap: 0.35rem 0.55rem;
  align-items: baseline;
  padding: 0.15rem 0;
  font-variant-numeric: tabular-nums;
}
.ids-rates-tt-cs   { font-weight: 700; color: var(--foreground); }
.ids-rates-tt-route { color: var(--muted-foreground); font-size: 0.72rem; }
.ids-rates-tt-time  { color: var(--brand); font-weight: 700; }
.ids-rates-tt-status {
  grid-column: 1 / -1;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-style: italic;
}
.ids-rates-tt-empty { color: var(--muted-foreground); font-style: italic; }

/* Flow column — dropdown when not ATIS-locked, badge + runway summary when locked. */
.ids-rates-flow {
  font-size: 0.8rem;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.ids-rates-flow-empty {
  color: var(--muted-foreground);
  font-style: italic;
  font-size: 0.75rem;
}
.ids-rates-flow-select {
  width: 100%;
  height: 1.9rem;
  padding: 0 0.4rem;
  font-size: 0.78rem;
  font-family: var(--font-mono);
  background: var(--background);
  color: var(--foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  appearance: auto;
}
.ids-rates-flow-select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand-muted);
}
.ids-rates-flow-locked {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.4rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
  white-space: nowrap;
}
.ids-rates-flow-lock-pill {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 0.05rem 0.35rem;
  background: var(--brand-muted);
  color: var(--brand);
  border-radius: 999px;
  font-family: var(--font-mono);
}
.ids-rates-flow-lock-rwys {
  font-size: 0.78rem;
  color: var(--foreground);
}
.ids-rates-flow-lock-dir {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.ids-rates-flow-lock-dir.dir-arr { color: #22c55e; }
.ids-rates-flow-lock-dir.dir-dep { color: #3b82f6; }

/* ---- Live rates panel (panel_rates_live) ---- */
.ids-rates-live-card { margin-bottom: 1rem; }
.ids-rates-live-status {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.ids-rates-live-primary {
  padding: 0.85rem 1rem 0.75rem;
}
.ids-rates-live-primary.has-divider { border-top: 1px solid var(--border); }
.ids-rates-live-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.65rem;
}
.ids-rates-live-row.is-primary .ids-rates-live-icao {
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--foreground);
}
.ids-rates-live-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}
.ids-rates-live-stat {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.015);
}
.ids-rates-live-stat-label {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.ids-rates-live-stat-pair {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-variant-numeric: tabular-nums;
}
.ids-rates-live-row.is-primary .ids-rates-live-num {
  font-size: 1.6rem;
  font-weight: 800;
  color: var(--foreground);
  line-height: 1;
}
.ids-rates-live-row.is-adj .ids-rates-live-num {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--foreground);
  line-height: 1;
}
.ids-rates-live-num.is-over { color: #facc15; }
.ids-rates-live-cfg {
  font-size: 1rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.ids-rates-live-row.is-adj .ids-rates-live-cfg { font-size: 0.9rem; }
.ids-rates-live-slash {
  color: var(--muted-foreground);
  font-weight: 700;
}
.ids-rates-live-stat-key {
  display: flex;
  justify-content: space-between;
  font-size: 0.6rem;
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.75;
}
.ids-rates-live-stat-key span:first-child { padding-left: 0.05rem; }
.ids-rates-live-stat-key span:last-child  { padding-right: 1.4rem; }
.ids-rates-live-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  align-items: center;
}
.ids-rates-live-meta-row {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
}
.ids-rates-live-meta-label {
  font-size: 0.65rem;
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  flex: 0 0 auto;
}
.ids-rates-live-flow {
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  min-width: 0;
}
.ids-rates-live-flow.is-empty { color: var(--muted-foreground); font-style: italic; }
.ids-rates-live-flow.is-flow strong { color: var(--foreground); }
.ids-rates-live-flow-pill {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
  border: 1px solid rgba(34, 197, 94, 0.4);
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
}
.ids-rates-live-flow-rwys {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  letter-spacing: 0.04em;
  font-weight: 600;
}
.ids-rates-live-flow-rwys .dir-arr { color: #22c55e; font-weight: 700; }
.ids-rates-live-flow-rwys .dir-dep { color: #3b82f6; font-weight: 700; }
.ids-rates-live-meter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--muted-foreground);
}
.ids-rates-live-meter.is-on {
  background: rgba(250, 204, 21, 0.14);
  border-color: rgba(250, 204, 21, 0.45);
  color: #facc15;
}
.ids-rates-live-meter.is-off {
  color: var(--muted-foreground);
  opacity: 0.7;
}

/* ---- Online neighbors list ---- */
.ids-neighbors-card { margin-bottom: 1rem; }
.ids-neighbors-body {
  padding: 0;
  min-height: 56px;
}
.ids-neighbor-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 1rem;
  border-top: 1px solid var(--border);
  transition: background var(--transition-fast, 120ms);
}
.ids-neighbor-row:first-child { border-top: 0; }
.ids-neighbor-row:hover { background: rgba(255, 255, 255, 0.02); }
.ids-neighbor-main {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex-wrap: wrap;
}
.ids-neighbor-callsign {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.ids-neighbor-group {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.62rem;
  font-weight: 600;
}
.ids-neighbor-freq {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-variant-numeric: tabular-nums;
  color: var(--muted-foreground);
  font-size: 0.85rem;
  flex-shrink: 0;
  text-align: right;
  white-space: nowrap;
}
.ids-empty-row {
  padding: 0.85rem 1rem;
  font-style: italic;
}

/* Grouped sections: ARTCC vs External cross-ARTCC neighbors.
   Header band uses the same eyebrow rhythm as .ids-section-eyebrow
   (uppercase, tracked, muted) so it reads as a typographic divider
   rather than a one-off pattern. */
.ids-neighbor-section + .ids-neighbor-section { border-top: 1px solid var(--border); }
.ids-neighbor-section-head {
  padding: 0.45rem 1rem 0.3rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  background: rgba(255, 255, 255, 0.02);
}
/* Cross-ARTCC label rendered as a left-anchored prefix tag, not a
   pill. Reads like a column gutter — present without competing with
   the callsign's visual weight. */
.ids-neighbor-scope {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  padding: 0.05rem 0.35rem;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
}

/* ---- Quick actions ---- */
.ids-quick-card { margin-bottom: 1rem; }
.ids-quick-row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* ---- TMU grid (IDS variant) ---- */
.ids-tmu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}
.ids-tmu-card .ids-tmu-metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
  padding: 1rem;
}
.ids-tmu-metric { min-width: 0; }
.ids-tmu-metric-wide { grid-column: 1 / -1; }
.ids-tmu-metric-label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-bottom: 0.25rem;
}
.ids-tmu-metric-value {
  font-size: 1.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.ids-tmu-metric-sub {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
}
.ids-tmu-flow-row {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}
.ids-tmu-flow-label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  width: 1.8rem;
}
.ids-tmu-flow-val {
  font-weight: 600;
  color: var(--foreground);
}

/* =============================================================
   === Arrivals Ladder card ===
   Row-based table mirroring the Arrival/Departure Rates card. One summary
   row per opted-in airport (active flow, metering-fix list, inbound count,
   unmapped diagnostic, expand chevron) plus a paired hidden detail row
   that reveals one independent 3-column ladder per metering fix when the
   chevron is opened. Time axis is now-relative (bottom = now, top = +45 min).
   ETA chips color-coded for slot pressure (on-slot / behind / ahead).
   ============================================================= */
.ids-ladder-card { margin-bottom: 1rem; }
.ids-ladder-status {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.ids-ladder-table {
  width: 100%;
  table-layout: fixed;
  margin: 0;
}
.ids-ladder-table thead th {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  color: var(--muted-foreground);
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
.ids-ladder-col-icao    { width: 18%; }
.ids-ladder-col-flow    { width: 22%; }
.ids-ladder-col-fixes   { width: 26%; }
.ids-ladder-col-inbound { width: 10%; text-align: right; }
.ids-ladder-col-unmapped{ width: 12%; text-align: right; }
.ids-ladder-col-expand  { width: 12%; text-align: right; }
.ids-ladder-table thead th.ids-ladder-col-inbound,
.ids-ladder-table thead th.ids-ladder-col-unmapped,
.ids-ladder-table thead th.ids-ladder-col-expand { text-align: right; }

.ids-ladder-summary-row td {
  padding: 0.55rem 0.75rem;
  border-top: 1px solid var(--border);
  vertical-align: middle;
  font-size: 0.86rem;
}
.ids-ladder-icao strong {
  font-size: 0.96rem;
  letter-spacing: 0.04em;
}
.ids-ladder-airport-name {
  margin-top: 0.1rem;
  color: var(--muted-foreground);
  font-size: 0.72rem;
}
.ids-ladder-flow {
  font-weight: 600;
  color: var(--foreground);
}
.ids-ladder-flow.is-empty {
  font-weight: 400;
  color: var(--muted-foreground);
  font-style: italic;
}
.ids-ladder-fixes {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--foreground);
  word-break: break-word;
}
.ids-ladder-inbound {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
}
.ids-ladder-unmapped-cell { text-align: right; }
.ids-ladder-unmapped {
  display: inline-block;
  background: rgba(220, 160, 0, 0.16);
  color: rgb(200, 140, 0);
  border-radius: 999px;
  padding: 0.1rem 0.55rem;
  font-weight: 600;
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
}
.ids-ladder-unmapped-zero {
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
}
.ids-ladder-expand { text-align: right; }
.ids-ladder-expand-btn {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 0.25rem;
  padding: 0.2rem 0.35rem;
  cursor: pointer;
  color: var(--muted-foreground);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 120ms ease;
}
.ids-ladder-expand-btn:hover {
  border-color: var(--border);
  color: var(--foreground);
}
.ids-ladder-expand-btn.is-open { transform: rotate(180deg); color: var(--foreground); }

.ids-ladder-detail-row td.ids-ladder-detail-cell {
  padding: 0.5rem 0.75rem 1rem;
  background: rgba(0, 0, 0, 0.02);
  border-top: 1px solid var(--border);
}

/* The detail cell stacks toolbar above the widget row so the filter
   chips read as a top-of-section toolbar, not a sibling of the cards. */
.ids-ladder-detail-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
/* The widget row keeps the original horizontal flex layout for the
   per-(airport, runway) cards. Lives INSIDE the detail-stack now. */
.ids-ladder-row {
  display: flex;
  flex-direction: row;
  gap: 0.75rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
  scrollbar-width: thin;
}
.ids-ladder-empty {
  font-size: 0.78rem;
  color: var(--muted-foreground);
  padding: 1rem 0;
}

.ids-ladder-widget {
  flex: 0 0 auto;
  /* Single uniform width across every ladder card — per-(airport, runway)
     and combined "All STARs / RWYs" alike. 320px keeps the per-side chip
     column at ~128px, enough room for "SWA1234-AE →KABC" without cutting
     off, while keeping cards skinny enough that 4-5 fit side-by-side on
     a typical 1440-px IDS canvas. */
  min-width: 320px;
  max-width: 320px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.ids-ladder-widget-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border);
  background: var(--muted, rgba(0, 0, 0, 0.04));
}
.ids-ladder-fix-name {
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--foreground);
}
.ids-ladder-airport-tag {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--brand);
  color: var(--brand-foreground);
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-sm, 0.25rem);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ids-ladder-rwy-badge {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  background: var(--brand, #3b82f6);
  color: #fff;
  padding: 0.05rem 0.4rem;
  border-radius: 0.25rem;
}

/* Per-sector ladder filter toolbar — sits above the ladder widgets in the
   detail row, lets the controller toggle which (airport, runway) ladders
   show. One coherent chip shape; the .is-combined variant carries a small
   inline dot marker so it reads as an aggregate view without competing
   for color attention. */
.ids-ladder-filter-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  padding: 0.5rem 0.75rem;
  margin: 0 0 0.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--muted, rgba(0, 0, 0, 0.04));
}
.ids-ladder-filter-label {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-right: 0.35rem;
}
.ids-ladder-filter-chip {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted-foreground);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius-full, 999px);
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ids-ladder-filter-chip:hover {
  border-color: var(--brand);
  color: var(--foreground);
}
.ids-ladder-filter-chip.is-active {
  background: var(--brand);
  color: var(--brand-foreground);
  border-color: var(--brand);
}
/* The aggregate-view chip uses an inline dot marker rather than a
   separate accent color — same shape and active treatment as the
   per-(airport, runway) chips. Inactive: muted dot; active: filled. */
.ids-ladder-filter-chip-dot {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: var(--radius-full, 999px);
  border: 1px solid currentColor;
  background: transparent;
  flex: 0 0 auto;
  display: inline-block;
}
.ids-ladder-filter-chip.is-active .ids-ladder-filter-chip-dot {
  background: currentColor;
}
/* Reset: quiet ghost button on the right edge. Disabled when nothing is
   hidden so it doesn't compete visually with the active chips. */
.ids-ladder-filter-chip.is-reset {
  margin-left: auto;
  border-style: dashed;
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
}
.ids-ladder-filter-chip.is-reset:disabled {
  opacity: 0.4;
  cursor: default;
}
.ids-ladder-filter-chip.is-reset:disabled:hover {
  border-color: var(--border);
  color: var(--muted-foreground);
}
/* Combined ladder's widget-head tag mirrors the chip treatment: same
   pill shape with the inline dot marker, brand-tinted background to
   match the active chip state. */
.ids-ladder-airport-tag.is-combined {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--brand);
  color: var(--brand-foreground);
  letter-spacing: 0.06em;
}

/* Footer items — count · runway · STAR. Inline-flex with center
   alignment + dot separators. Each item is allowed to truncate so a
   long STAR list never breaks the card width. */
.ids-ladder-widget-foot-item {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.ids-ladder-widget-foot-sep {
  font-size: 0.66rem;
  color: var(--muted-foreground);
  opacity: 0.6;
  flex-shrink: 0;
}
.ids-ladder-spacing-hint {
  margin-left: auto;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

/* =============================================================
   === Arrivals Ladder body (per metering-fix widget) ===
   Body is a single scrollable container whose inner "strip" is taller
   than the visible window. Three columns + a tick layer share the same
   coordinate space inside the strip, so chips and tick lines scroll
   together. Bottom of the strip is "now"; up = into the future.
   ============================================================= */
.ids-ladder-widget {
  --ladder-px-per-min: 22px;        /* must match PX_PER_MIN in JS */
  --ladder-tick-color: rgba(255,255,255,0.06);
  --ladder-tick-major-color: rgba(255,255,255,0.18);
  --ladder-blue: #3b82f6;
  --ladder-yellow: #ffd84d;
  --ladder-green: rgb(34, 160, 80);
}

.ids-ladder-body {
  position: relative;
  height: 460px;
  overflow-y: auto;
  overflow-x: hidden;
  /* Trap the scrollwheel inside the ladder — when the user reaches the
     top or bottom of the strip, the page itself must not scroll. */
  overscroll-behavior: contain;
  background: linear-gradient(to top,
    rgba(0,0,0,0.18) 0%,
    rgba(0,0,0,0) 14%);
  /* Hide the scrollbar across browsers; scroll still works via wheel
     / touch / keyboard. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.ids-ladder-body::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* The strip is taller than the body and holds all three columns plus
   the tick layer. Its height is set inline in JS to WINDOW_MIN *
   PX_PER_MIN so the JS and CSS agree on the coordinate space. */
.ids-ladder-strip {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 4rem 1fr;
}

.ids-ladder-col {
  position: relative;
  height: 100%;
  min-width: 0;
}
.ids-ladder-col-axis {
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
}

/* Tick layer overlays all three columns. Only the major (clock-aligned)
   ticks render here as full-width lines; minor (interim) minute ticks
   live inside the axis column itself as short edge marks. Pointer-events
   disabled so chips remain hoverable. */
.ids-ladder-ticks {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.ids-ladder-tick {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px solid var(--ladder-tick-color);
}
.ids-ladder-tick.is-major {
  border-top: 1px solid var(--ladder-tick-major-color);
}

/* Minor (interim) minute marks rendered inside the axis column. Two
   short ticks straddle the column's left and right borders so the body
   reads cleaner — no full horizontal line spanning the chip area. */
.ids-ladder-tick-axis {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  pointer-events: none;
}
.ids-ladder-tick-axis::before,
.ids-ladder-tick-axis::after {
  content: "";
  position: absolute;
  top: 0;
  width: 6px;
  border-top: 1px solid var(--ladder-tick-color);
}
.ids-ladder-tick-axis::before { left: -3px; }
.ids-ladder-tick-axis::after  { right: -3px; }

/* Clock-aligned :MM labels. Live inside the axis column so they sit
   centered between the STA / ETA tracks. */
.ids-ladder-axis-labels {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.ids-ladder-tick-label {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 0.62rem;
  background: var(--card);
  padding: 0 0.25rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted-foreground);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* Chip groups live inside their respective columns at top:Npx so they
   share the strip's coordinate space with the tick lines. The group
   itself has no box (no border, no background, no padding); each
   callsign is rendered as colored text only. translateY(-50%) centers
   the group vertically on its minute. When two or more flights land in
   the same minute bucket they stack vertically inside the same group,
   centered on the shared anchor. */
.ids-ladder-chip {
  position: absolute;
  left: 0.25rem;
  right: 0.25rem;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  pointer-events: auto;
  cursor: default;
  z-index: 2;
  line-height: 1;
}
.ids-ladder-chip-sta {
  text-align: right;
  align-items: flex-end;
}
.ids-ladder-chip-eta {
  text-align: left;
  align-items: flex-start;
}

/* Leader tick marks linking each callsign to the time axis. STA chips
   live in the left column and project a short tick rightward into the
   axis column edge; ETA chips do the mirror. Anchored at the chip's
   vertical center, which is the bucket's anchor minute. */
.ids-ladder-chip-sta::after,
.ids-ladder-chip-eta::before {
  content: "";
  position: absolute;
  top: 50%;
  width: 10px;
  height: 0;
  border-top: 1px solid var(--ladder-tick-major-color);
  pointer-events: none;
}
.ids-ladder-chip-sta::after { right: -10px; }
.ids-ladder-chip-eta::before { left: -10px; }

.ids-ladder-chip-callsign {
  font-weight: 400;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  line-height: 1;
  white-space: nowrap;
  /* Subtle text-shadow keeps callsigns readable when a tick line
     happens to pass directly under them (no chrome to fall back on). */
  text-shadow:
    0 0 3px var(--card),
    0 0 3px var(--card);
}
/* Stacked groups (2+ flights at the same minute): tight inter-line
   spacing so both callsigns read as a unit anchored to the minute. */
.ids-ladder-chip.is-stack .ids-ladder-chip-callsign + .ids-ladder-chip-callsign {
  margin-top: 1px;
}

/* STA chip callsign coloring:
   - default (pending): blue, signaling "we have a slot but ETA not
     yet on it"
   - on-slot: green, signaling "ETA matches STA within tolerance" */
.ids-ladder-chip-sta .ids-ladder-chip-callsign.is-pending {
  color: var(--ladder-blue);
}
.ids-ladder-chip-sta .ids-ladder-chip-callsign.is-on-slot {
  color: var(--ladder-green);
}

/* ETA chip callsign: yellow. Background stays card-colored - only the
   text picks up the color. */
.ids-ladder-chip-eta .ids-ladder-chip-callsign.is-eta {
  color: var(--ladder-yellow);
}

.ids-ladder-widget-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-size: 0.66rem;
  color: var(--muted-foreground);
  border-top: 1px solid var(--border);
  padding: 0.3rem 0.5rem;
  background: var(--muted, rgba(0, 0, 0, 0.03));
  min-width: 0;
}

@media (max-width: 640px) {
  .ids-ladder-row { gap: 0.5rem; }
  .ids-ladder-widget { min-width: 280px; max-width: 280px; }
  .ids-ladder-body { height: 380px; }
}

/* =============================================================
   === Arrivals ladder — interactive STA controls ===
   Click/drag affordances on chips, the floating popover, the
   drag ghost + time badge, and the locked-STA visual indicator.
   ============================================================= */

/* Interactive chips: subtle hover hint. STA chips with write authority
   advertise drag with a grab cursor. Read-only viewers (no TRACON/Enroute/
   TMU position, or out-of-scope airport) still get a click cursor — the
   popover opens for read-only inspection. */
.ids-ladder-chip.is-interactive { cursor: pointer; }
.ids-ladder-chip-sta.is-interactive:not(.is-readonly) { cursor: grab; }
.ids-ladder-chip-sta.is-interactive.is-dragging { cursor: grabbing; }
.ids-ladder-chip.is-interactive .ids-ladder-chip-callsign:hover {
  text-decoration: underline;
  text-decoration-color: rgba(255,255,255,0.35);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

/* Cumulative status suffix appended after the callsign (e.g. "SWA1234-AE").
   Same color family as the parent callsign — slightly dimmer so the
   callsign itself remains the primary read at a glance. The hyphen is
   part of the textContent so it copies cleanly. */
.ids-ladder-chip-suffix {
  margin-left: 0;
  opacity: 0.75;
  font-weight: 400;
  letter-spacing: 0.04em;
}

/* Met-on-slot green — STA-side callsign chip turns green when the
   aircraft is practically meeting the slot (ETA within 1 min of STA).
   Stronger green than the routine is-on-slot to signal "no further
   action needed". */
.ids-ladder-chip-sta .ids-ladder-chip-callsign.is-on-slot-met {
  background: rgba(34, 160, 80, 0.18);
  color: rgb(34, 160, 80);
  border-color: rgba(34, 160, 80, 0.55);
}

/* "Corrections required" card on the STA popover. Color by kind:
   speed = blue (informational adjustment), hold = orange (operational
   decision), unmeetable = red (escalate to GDP).

   Built on the same dark-theme tokens as the popover itself: each variant
   defines a single --correction-accent token and the rules below derive
   tinted background, left accent bar, header tint, and primary-line text
   color from it. That keeps theming centralized and survives any future
   palette refresh.

   Visual hierarchy inside the card:
     .is-primary    — headline action, largest, full foreground
     .is-detail     — supporting fact, popover meta size, dimmed
     .is-procedure  — mechanical detail (ramp/absorption), monospace, dim
     .is-recommend  — escalation, accent-tinted + bold
*/
.ids-ladder-correction-card {
  --correction-accent: var(--ladder-blue, #3b82f6);
  position: relative;
  border: 1px solid color-mix(in srgb, var(--correction-accent) 55%, transparent);
  border-left: 3px solid var(--correction-accent);
  border-radius: 0.4rem;
  padding: 0.5rem 0.7rem 0.55rem 0.75rem;
  margin: 0.4rem 0 0.5rem;
  font-size: 0.78rem;
  line-height: 1.4;
  background:
    linear-gradient(
      to right,
      color-mix(in srgb, var(--correction-accent) 16%, transparent),
      color-mix(in srgb, var(--correction-accent) 6%, transparent) 60%,
      transparent
    ),
    var(--card);
  color: var(--foreground);
}
.ids-ladder-correction-card.is-speed       { --correction-accent: var(--ladder-blue,   #3b82f6); }
.ids-ladder-correction-card.is-hold        { --correction-accent: var(--ladder-yellow, #ffd84d); }
.ids-ladder-correction-card.is-unmeetable  { --correction-accent: #ef4444; }

/* Header: small caps label with a leading glyph that reinforces the
   variant beyond color alone (info / warning / stop). The glyph is a
   plain Unicode mark so it inherits color and needs no icon font. */
.ids-ladder-correction-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 700;
  margin-bottom: 0.35rem;
  text-transform: uppercase;
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  color: var(--correction-accent);
}
.ids-ladder-correction-head::before {
  content: '';
  display: inline-block;
  width: 0.95em;
  height: 0.95em;
  border-radius: 50%;
  background: var(--correction-accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--correction-accent) 25%, transparent);
  flex: 0 0 auto;
}
.ids-ladder-correction-card.is-speed      .ids-ladder-correction-head::before { content: 'i'; background: transparent; color: var(--correction-accent); border: 1.5px solid var(--correction-accent); font-family: ui-serif, Georgia, serif; font-style: italic; font-weight: 700; line-height: 0.9em; text-align: center; box-shadow: none; }
.ids-ladder-correction-card.is-hold       .ids-ladder-correction-head::before { content: '!'; background: transparent; color: var(--correction-accent); border: 1.5px solid var(--correction-accent); font-weight: 900; line-height: 0.9em; text-align: center; box-shadow: none; }
.ids-ladder-correction-card.is-unmeetable .ids-ladder-correction-head::before { content: '\00d7'; background: transparent; color: var(--correction-accent); border: 1.5px solid var(--correction-accent); font-weight: 900; line-height: 0.85em; text-align: center; box-shadow: none; }

/* Lines. Default to the popover's body type; .is-primary lifts the
   headline action; .is-procedure dims and monospaces ramp/absorption
   detail so it reads as a footnote. */
.ids-ladder-correction-line {
  margin: 0.15rem 0;
  font-variant-numeric: tabular-nums;
  color: var(--foreground);
}
.ids-ladder-correction-line.is-primary {
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin: 0.1rem 0 0.25rem;
  color: var(--foreground);
}
.ids-ladder-correction-line.is-detail {
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--foreground) 78%, transparent);
}
.ids-ladder-correction-line.is-procedure {
  font-size: 0.72rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0;
  color: var(--muted-foreground);
  padding-left: 0.05rem;
}
.ids-ladder-correction-line.is-recommend {
  margin-top: 0.35rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--correction-accent);
}

/* Suffix-code legend at the bottom of the popover. Lists each letter
   that appears on the row's status_suffix and what it means in plain
   English. Renders as a tight 2-column grid. */
.ids-ladder-suffix-legend {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(255,255,255,0.10);
  font-size: 0.78rem;
}
.ids-ladder-suffix-legend-head {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.7rem;
  opacity: 0.7;
  margin-bottom: 0.25rem;
}
.ids-ladder-suffix-legend-row {
  display: grid;
  grid-template-columns: 1.4em 1fr;
  gap: 0.4em;
  align-items: baseline;
  margin: 0.1rem 0;
}
.ids-ladder-suffix-legend-letter {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700;
  text-align: center;
  background: rgba(255,255,255,0.08);
  border-radius: 3px;
  padding: 0 0.15em;
}
.ids-ladder-suffix-legend-text { opacity: 0.85; }

/* Drag ghost — a small chip that follows the cursor. */
.ids-ladder-drag-ghost {
  position: fixed;
  pointer-events: none;
  z-index: 10000;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ladder-blue, #3b82f6);
  background: var(--card);
  border: 1px solid var(--ladder-blue, #3b82f6);
  border-radius: 0.25rem;
  padding: 0.1rem 0.35rem;
  box-shadow: 0 4px 14px rgba(0,0,0,0.35);
}

/* Time badge during drag — shows the STA the drop will commit to. */
.ids-ladder-drag-badge {
  position: fixed;
  pointer-events: none;
  z-index: 10000;
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  background: var(--ladder-yellow, #ffd84d);
  color: #111;
  border-radius: 0.2rem;
  padding: 0.05rem 0.3rem;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}

/* In-axis ghost: a translucent chip rendered inside the STA column at the
   drop target's minute. It moves with the cursor and shows the controller
   exactly where the row will land alongside existing chips. */
.ids-ladder-chip-axis-ghost {
  pointer-events: none;
  z-index: 3;
}
.ids-ladder-chip-axis-ghost .ids-ladder-chip-callsign {
  color: var(--ladder-yellow, #ffd84d);
  opacity: 0.85;
  font-weight: 600;
  font-style: italic;
  background: rgba(0, 0, 0, 0.55);
  padding: 0 0.25rem;
  border-radius: 0.15rem;
  border: 1px dashed var(--ladder-yellow, #ffd84d);
  text-shadow: none;
  font-variant-numeric: tabular-nums;
}

/* Source chip while it's being dragged — semi-transparent so the user
   sees the original slot is "lifted" and follow the in-axis ghost. */
.ids-ladder-chip.is-dragging .ids-ladder-chip-callsign {
  opacity: 0.35;
}

/* Conflict styling: when the drop target is within the spacing minimum of
   another chip, both the dragged ghost and the offending real chips light
   up red. Shows the controller they're about to crowd a slot before they
   commit. The drop still works (the controller may want this), but the
   warning is visible while the cursor is in the conflict zone. */
.ids-ladder-chip-axis-ghost.is-conflict .ids-ladder-chip-callsign {
  color: #fff;
  background: rgba(239, 68, 68, 0.85);
  border-color: #ef4444;
}
.ids-ladder-drag-ghost.is-conflict {
  color: #fff;
  background: #ef4444;
  border-color: #ef4444;
}
.ids-ladder-drag-badge.is-conflict {
  background: #ef4444;
  color: #fff;
}
.ids-ladder-chip-sta.is-conflict-target .ids-ladder-chip-callsign {
  outline: 1px solid #ef4444;
  outline-offset: 1px;
  border-radius: 0.15rem;
}

/* Popover: anchored under the clicked chip (or above when there's no
   space below). Keeps the IDS look — card background, border, shadow. */
.ids-ladder-popover {
  position: fixed;
  z-index: 10001;
  min-width: 240px;
  max-width: 320px;
  background: var(--card);
  color: var(--foreground);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.6rem 0.7rem;
  box-shadow: 0 10px 30px rgba(0,0,0,0.45);
  font-size: 0.78rem;
}
.ids-ladder-popover-title {
  font-weight: 700;
  letter-spacing: 0.04em;
  font-size: 0.82rem;
  margin-bottom: 0.25rem;
}
.ids-ladder-popover-meta {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.72rem;
  color: var(--muted-foreground);
  margin-bottom: 0.5rem;
  font-variant-numeric: tabular-nums;
}
.ids-ladder-popover-meta strong { color: var(--foreground); font-weight: 600; }

/* Status overview: two-column grid of label / value pairs. Borders top
   + bottom so it visually separates from the meta line above and the
   form below. Empty when the aircraft has nothing notable to report. */
.ids-ladder-popover-status {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 0.6rem;
  font-size: 0.72rem;
  margin: 0.4rem 0;
  padding: 0.35rem 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.ids-ladder-popover-status:empty {
  display: none;
}
.ids-ladder-popover-status-label {
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.62rem;
  align-self: center;
}
.ids-ladder-popover-status-value {
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.ids-ladder-popover-status-value.is-met    { color: var(--ladder-green, rgb(34, 160, 80)); }
.ids-ladder-popover-status-value.is-behind { color: var(--ladder-yellow, #ffd84d); }
.ids-ladder-popover-status-value.is-error  { color: #ef4444; }
.ids-ladder-popover-status-value.is-stale  { color: var(--muted-foreground); font-style: italic; }
.ids-ladder-popover-form { display: flex; flex-direction: column; gap: 0.35rem; }
.ids-ladder-popover-form label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.7rem;
  color: var(--muted-foreground);
}
.ids-ladder-popover-form input,
.ids-ladder-popover-form select {
  width: 100%;
  font-variant-numeric: tabular-nums;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  padding: 0.3rem 0.4rem;
  background: var(--background);
  color: var(--foreground);
  border: 1px solid var(--border);
  border-radius: 0.3rem;
}
/* Runway-override block sits between the STA form and the action row.
   The source pill clarifies where the current runway came from (override
   / flow_pref / active_flow / common_segment / fallback). */
.ids-ladder-popover-rwy {
  border-top: 1px solid var(--border);
  padding-top: 0.5rem;
  margin-top: 0.4rem;
  gap: 0.4rem;
}
.ids-ladder-popover-rwy-head {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.7rem;
  color: var(--muted-foreground);
  letter-spacing: 0.04em;
}
.ids-ladder-popover-rwy-source {
  display: inline-flex;
  align-items: center;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  background: var(--muted);
  border: 1px solid var(--border);
  padding: 0.05rem 0.4rem;
  border-radius: var(--radius-full, 999px);
}
.ids-ladder-popover-rwy-select {
  text-transform: uppercase;
}
/* Action row at the bottom of the runway picker — sits at the same
   visual scale as the popover's primary Cancel/Release actions row so
   the popover reads as one button hierarchy, not two. */
.ids-ladder-popover-rwy-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.4rem;
}
.ids-ladder-popover-rwy-actions .ids-ladder-popover-primary {
  margin-top: 0;
  padding: 0.25rem 0.7rem;
  font-size: 0.72rem;
  border-radius: var(--radius-sm, 0.3rem);
}
.ids-ladder-popover-rwy-actions .ids-ladder-popover-release {
  margin-left: auto;
}
.ids-ladder-popover-primary {
  align-self: flex-start;
  margin-top: 0.25rem;
  padding: 0.3rem 0.7rem;
  background: var(--brand);
  color: var(--brand-foreground);
  border: none;
  border-radius: var(--radius-sm, 0.3rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.ids-ladder-popover-primary:hover { filter: brightness(1.1); }
.ids-ladder-popover-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-top: 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.45rem;
}
.ids-ladder-popover-release {
  background: transparent;
  color: var(--ladder-yellow, #ffd84d);
  border: 1px solid var(--ladder-yellow, #ffd84d);
  border-radius: 0.3rem;
  padding: 0.2rem 0.55rem;
  font-size: 0.72rem;
  cursor: pointer;
}
.ids-ladder-popover-cancel {
  background: transparent;
  color: var(--muted-foreground);
  border: 1px solid var(--border);
  border-radius: 0.3rem;
  padding: 0.2rem 0.55rem;
  font-size: 0.72rem;
  cursor: pointer;
}
.ids-ladder-popover-sanity {
  margin-top: 0.5rem;
  font-size: 0.7rem;
  color: var(--muted-foreground);
  min-height: 1em;
}
.ids-ladder-popover-sanity.is-warn { color: var(--ladder-yellow, #ffd84d); }
.ids-ladder-popover-sanity.is-error { color: #ef4444; }
.ids-ladder-popover-readonly-banner {
  margin: 0 0 0.5rem 0;
  padding: 0.4rem 0.5rem;
  font-size: 0.7rem;
  line-height: 1.3;
  color: var(--muted-foreground);
  background: rgba(255, 216, 77, 0.08);
  border-left: 2px solid var(--ladder-yellow, #ffd84d);
  border-radius: 0.2rem;
}

/* Toast for drag-drop feedback (success / warning / failure). Bottom-
   center of the viewport so it doesn't cover the ladder. Auto-dismiss
   after 3 s on success, 6 s on error (longer dwell so the operator
   actually reads the failure reason). */
.ids-ladder-toast {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10002;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  background: var(--card);
  color: var(--foreground);
  border: 1px solid var(--border);
  border-radius: 0.35rem;
  padding: 0.4rem 0.7rem;
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.45);
  max-width: 70vw;
  pointer-events: none;
}
.ids-ladder-toast.is-warn {
  background: rgba(255, 216, 77, 0.95);
  color: #111;
  border-color: var(--ladder-yellow, #ffd84d);
}
.ids-ladder-toast.is-error {
  background: #ef4444;
  color: #fff;
  border-color: #ef4444;
}

/* =============================================================
   === Arrival Sequencing admin card ===
   STAR -> metering fix mappings, per flow. Lives on /admin/airports/:icao.
   Replaces the older `.star-mapping-*` block.
   ============================================================= */
.star-seq-card .card-content { padding-bottom: 0.75rem; }

/* ---- Tab strip ---- */
.star-seq-tabs {
  display: flex;
  gap: 0.15rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.85rem;
}
.star-seq-tab {
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 0.5rem 0.85rem;
  cursor: pointer;
  font-size: 0.86rem;
  color: var(--muted-foreground);
  border-radius: 0;
  margin-bottom: -1px;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.star-seq-tab:hover { color: var(--foreground); background: var(--muted, rgba(255,255,255,0.03)); }
.star-seq-tab.is-active {
  border-bottom-color: var(--brand, #3b82f6);
  color: var(--foreground);
  font-weight: 600;
}
.star-seq-tab-name { line-height: 1; }
.star-seq-tab-badge {
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brand, #3b82f6);
  background: var(--brand-soft, rgba(59,130,246,0.12));
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  line-height: 1;
}

.star-seq-pane[hidden] { display: none; }

/* ---- Active flow context strip (arrival runway chips) ---- */
.star-seq-context {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 0.5rem 0.65rem;
  margin-bottom: 0.55rem;
  background: var(--muted, rgba(255,255,255,0.02));
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  font-size: 0.78rem;
}
.star-seq-context-label {
  color: var(--muted-foreground);
  margin-right: 0.15rem;
}
.star-seq-context-rwys {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.star-seq-context-warn {
  color: var(--warning, #eab308);
  font-style: normal;
  font-size: 0.78rem;
}
.star-seq-rwy-chip {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  background: var(--brand-soft, rgba(59,130,246,0.12));
  color: var(--brand, #3b82f6);
  border-radius: 4px;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}

/* ---- Table ---- */
.star-seq-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.85rem;
}
.star-seq-table thead th {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  text-align: left;
  padding: 0.4rem 0.55rem;
  border-bottom: 1px solid var(--border);
  background: transparent;
}
.star-seq-table .col-star     { width: 22%; }
.star-seq-table .col-fix      { width: 22%; }
.star-seq-table .col-rwy      { width: 18%; }
.star-seq-table .col-spacing  { width: 14%; }
.star-seq-table .col-status   { width: 14%; }
.star-seq-table .col-actions  { width: 10%; text-align: right; }

.star-seq-row > .star-seq-cell {
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.star-seq-row:last-child > .star-seq-cell { border-bottom: 0; }
.star-seq-row:hover > .star-seq-cell { background: var(--muted, rgba(255,255,255,0.02)); }
.star-seq-row.is-fallback > .star-seq-cell {
  background: var(--muted, rgba(255,255,255,0.025));
  border-left: 2px solid var(--brand, #3b82f6);
}
.star-seq-row.is-fallback:first-child > .star-seq-cell:first-child {
  border-top-left-radius: var(--radius-sm, 6px);
}

.star-seq-star-name {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-weight: 600;
  font-size: 0.84rem;
  color: var(--foreground);
  letter-spacing: 0.02em;
}
.star-seq-fallback-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brand, #3b82f6);
  font-style: normal;
}
.star-seq-fallback-badge::before {
  content: '';
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--brand, #3b82f6);
}

/* ---- Inputs inside the table (compact form-control variant) ---- */
.star-seq-input.form-control,
.star-seq-input.form-control-sm {
  font-size: 0.82rem;
  padding: 0.3rem 0.45rem;
  height: auto;
  width: 100%;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.star-seq-input.form-control:hover,
.star-seq-input.form-control-sm:hover {
  border-color: var(--border);
  background: var(--background, rgba(0,0,0,0.15));
}
.star-seq-input.form-control:focus,
.star-seq-input.form-control-sm:focus {
  border-color: var(--brand, #3b82f6);
  background: var(--background, rgba(0,0,0,0.25));
  outline: none;
  box-shadow: 0 0 0 1px var(--brand, #3b82f6);
}
.star-seq-rwy-select { padding-right: 1.4rem; cursor: pointer; }
.star-seq-rwy-select:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* ---- Save state pill ---- */
.star-seq-status {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 500;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  white-space: nowrap;
  min-width: 1px;
  transition: opacity 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.star-seq-status-idle { color: transparent; background: transparent; padding: 0; }
.star-seq-status-saving {
  color: var(--muted-foreground);
  background: var(--muted, rgba(255,255,255,0.05));
}
.star-seq-status-saved {
  color: var(--success, #22c55e);
  background: var(--success-muted, rgba(34, 197, 94, 0.15));
}
.star-seq-status-error {
  color: var(--danger, #ef4444);
  background: var(--danger-muted, rgba(239, 68, 68, 0.15));
  cursor: help;
}

/* ---- Action icon buttons ---- */
.star-seq-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: var(--muted-foreground);
  cursor: pointer;
  transition: color 0.12s ease, background 0.12s ease, border-color 0.12s ease;
  padding: 0;
}
.star-seq-icon-btn:hover {
  color: var(--foreground);
  background: var(--muted, rgba(255,255,255,0.04));
  border-color: var(--border);
}
.star-seq-icon-btn.star-seq-delete:hover {
  color: var(--danger, #ef4444);
  background: var(--danger-muted, rgba(239, 68, 68, 0.12));
  border-color: var(--danger-muted, rgba(239, 68, 68, 0.3));
}

/* ---- Inline delete confirm ---- */
.star-seq-confirm-prompt {
  font-size: 0.75rem;
  color: var(--danger, #ef4444);
  font-weight: 500;
}
.star-seq-confirm-actions {
  display: inline-flex;
  gap: 0.3rem;
  align-items: center;
  justify-content: flex-end;
}
.star-seq-confirm-yes {
  background: var(--danger, #ef4444);
  color: var(--danger-foreground, #fff);
  border: 1px solid var(--danger, #ef4444);
  padding: 0.2rem 0.55rem;
  font-size: 0.74rem;
}
.star-seq-confirm-yes:hover { filter: brightness(1.05); }
.star-seq-confirm-no { padding: 0.2rem 0.55rem; font-size: 0.74rem; }

/* ---- Add-row footer button ---- */
.star-seq-add-row td {
  padding: 0.35rem 0 0;
  border: 0;
}
.star-seq-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.7rem;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--brand, #3b82f6);
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
  width: 100%;
  justify-content: center;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.star-seq-add-btn:hover {
  background: var(--brand-soft, rgba(59,130,246,0.08));
  border-color: var(--brand, #3b82f6);
  border-style: solid;
}
.star-seq-add-plus {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
}

/* ---- Draft (new) row ---- */
.star-seq-draft-row > .star-seq-cell {
  background: var(--brand-soft, rgba(59,130,246,0.06));
}
.star-seq-draft-row > .star-seq-cell:first-child {
  border-left: 2px solid var(--brand, #3b82f6);
}


/* ---- EDCT create form ---- */
.ids-edct-form .form-group { margin-bottom: 0.75rem; }
.ids-edct-form .form-group:last-of-type { margin-bottom: 1rem; }
.ids-edct-form .form-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-bottom: 0.3rem;
}

/* ---- Responsive ---- */
@media (max-width: 900px) {
  .ids-airport-split {
    grid-template-columns: minmax(0, 1fr);
  }
  .ids-airport-atis .ids-atis-cell { height: auto; }
}
@media (max-width: 640px) {
  .ids-header { padding: 0.75rem; }
  .ids-title { font-size: 1rem; }
  .ids-atis-grid,
  .ids-rate-strip,
  .ids-panel-grid,
  .ids-tmu-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .ids-tmu-card .ids-tmu-metrics { grid-template-columns: minmax(0, 1fr); }
  .rwy-strip {
    grid-template-columns: minmax(48px, 64px) minmax(0, 1fr) minmax(48px, 64px);
    min-height: 60px;
  }
  .rwy-strip-ident { font-size: 1.2rem; }
  .rwy-strip-label { font-size: 1rem; letter-spacing: 0.06em; }
  .rwy-strip-meta { display: none; }
  .rwy-modal-end-ident { font-size: 1.1rem; }
  .rwy-modal-btn { font-size: 0.74rem; padding: 0.35rem 0.55rem; }
}


/* =============================================================
   === Sidebar: IDS screen switcher ===
   Applies to the #positionIdsSection block in views/layout.ejs.
   Renders a sub-list of reachable IDS screens below the main
   "Open IDS" link, with HOME / group pills on each row. Layers
   onto the .sidebar-item base from main.css; only adds layout and
   meta-row styling here.
   ============================================================= */

/* Live-connection dot in the section heading (green, pulsing). */
.sidebar-heading .sidebar-live-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 6px var(--success);
  margin-right: 0.5rem;
  vertical-align: middle;
  animation: vatds-pulse 2s ease-in-out infinite;
}

@keyframes vatds-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* Container holding the fetched switcher rows. Sits flush under
   the "Open IDS" link and the admin "Browse IDS Screens" toggle. */
.ids-switcher-list {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  margin: 0.125rem 0 0.25rem 0.75rem;
  padding-left: 0.35rem;
  border-left: 1px solid var(--sidebar-border, var(--border));
}

.ids-switcher-loading,
.ids-switcher-empty {
  padding: 0.4rem 0.5rem;
  font-size: 0.75rem;
}

/* Each screen row. Keeps .sidebar-item base, adds a meta slot. */
.ids-switcher-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.35rem 0.5rem;
  font-size: 0.78rem;
  min-height: 0;
}

.ids-switcher-item-body {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  flex: 1 1 auto;
}

.ids-switcher-item-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.ids-switcher-view-hint {
  font-size: 0.68rem;
  font-style: italic;
  opacity: 0.75;
  flex-shrink: 0;
}

.ids-switcher-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

/* Group-pill inside a switcher row. Inherits tints from the
   .ids-badge-{cab,tracon,enroute,tmu} rules above, but dials the
   size down so it fits a sidebar row. */
.ids-switcher-meta .ids-group-badge {
  padding: 0.1rem 0.35rem;
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  line-height: 1;
}

/* HOME badge — brand-accented, signals the user's own screen. */
.ids-home-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.35rem;
  border-radius: var(--radius-sm);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--brand);
  background: var(--brand-muted, rgba(249, 115, 22, 0.15));
  box-shadow: inset 0 0 0 1px rgba(249, 115, 22, 0.45);
}

/* The user's own home screen gets a subtle brand tint on the row
   itself so it's scannable even when not currently viewed. */
.ids-switcher-item.is-home:not(.active) {
  color: var(--sidebar-accent-foreground);
}

/* Active screen (the one currently being viewed) reuses the
   standard .sidebar-item.active affordance via the .active class
   set in the switcher JS — no extra rule needed. */

/* Admin-only "Browse IDS Screens" collapsible (shown when not live). */
.ids-browse-admin {
  margin-top: 0.25rem;
}
.ids-browse-toggle .sidebar-menu-chevron {
  margin-left: auto;
}
.ids-browse-toggle[aria-expanded="true"] .sidebar-menu-chevron {
  transform: rotate(90deg);
}

/* =============================================================
   === Runway modal: head actions + POST telemetry ===
   The modal header now holds a live "last POST: 200 OK at hh:mm:ss"
   chip next to the close button so a controller can quickly tell
   whether a failing visual update is a POST failure or a render bug.
   ============================================================= */
.rwy-modal-head-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}
.rwy-modal-telemetry {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  padding: 0.2rem 0.45rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  color: var(--muted-foreground);
  background: rgba(255, 255, 255, 0.02);
  white-space: nowrap;
  min-width: 0;
  opacity: 0.85;
  transition: all var(--transition-fast);
}
.rwy-modal-telemetry:empty {
  display: none;
}
.rwy-modal-telemetry-ok {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 45%, var(--border));
  background: color-mix(in srgb, var(--success) 10%, transparent);
  opacity: 1;
}
.rwy-modal-telemetry-err {
  color: var(--destructive, #ef4444);
  border-color: color-mix(in srgb, var(--destructive, #ef4444) 45%, var(--border));
  background: color-mix(in srgb, var(--destructive, #ef4444) 10%, transparent);
  opacity: 1;
}

/* =============================================================
   === Dedicated ATIS section card (Phase 9b) ===
   ATIS no longer lives inside each airport's runway card. It gets
   its own dedicated card above the runway section, styled like the
   facility dashboard's ATIS/Flow card. Each primary airport renders
   as a tile in a responsive grid.
   ============================================================= */
.ids-atis-section-card {
  margin-bottom: 1rem;
}
.ids-atis-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.75rem;
  padding: 1rem;
}
.ids-atis-section-card .ids-atis-cell {
  margin: 0;
  height: 100%;
}

/* Runway section card with full-width strips (no side ATIS aside). */
.ids-airport-card .ids-airport-full {
  padding: 1rem;
}

@media (max-width: 640px) {
  .ids-atis-tile-grid { grid-template-columns: minmax(0, 1fr); padding: 0.75rem; }
}


/* Suppress the global a:hover underline (main.css) inside admin pages and
   on anchor-styled buttons — the dense admin UI looks noisy with every
   link flashing an underline on hover. */
.admin-shell a,
.admin-shell a:hover,
.admin-shell a:focus,
.btn,
.btn:hover,
.btn:focus,
a.btn,
a.btn:hover,
a.btn:focus {
  text-decoration: none;
}

/* =============================================================================
   === Admin shell (sidebar + breadcrumb + section frame) ===
   Scoped styles for /admin/* pages. Each section view wraps itself in the
   `.admin-shell` grid so the user always sees the same left-rail nav + sticky
   header, independent of which resource they're editing. All `admin-*`
   classes are unique to this section — they don't collide with site-wide
   tokens from variables.css.
   ============================================================================= */

.admin-shell {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 1.5rem;
  align-items: flex-start;
}

@media (max-width: 900px) {
  .admin-shell {
    grid-template-columns: minmax(0, 1fr);
  }
}

.admin-sidebar {
  position: sticky;
  top: 1rem;
  align-self: start;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 0.75rem 0.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

@media (max-width: 900px) {
  .admin-sidebar {
    position: static;
  }
}

.admin-sidebar-heading {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  padding: 0.35rem 0.65rem 0.5rem;
}

.admin-sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.admin-nav-item {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-md);
  color: var(--muted-foreground);
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

.admin-nav-item:hover {
  background: var(--muted);
  color: var(--foreground);
}

.admin-nav-item.is-active {
  background: var(--brand-muted);
  color: var(--brand);
  border-color: var(--brand);
}

.admin-nav-label {
  font-weight: 600;
  font-size: 0.88rem;
  line-height: 1.2;
}

.admin-nav-desc {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  line-height: 1.2;
}

.admin-nav-item.is-active .admin-nav-desc {
  color: color-mix(in srgb, var(--brand) 70%, var(--muted-foreground));
}

.admin-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.admin-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  color: var(--muted-foreground);
  margin-bottom: 0.5rem;
}

.admin-breadcrumb a {
  color: var(--muted-foreground);
  text-decoration: none;
  border-bottom: 1px dashed transparent;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}

.admin-breadcrumb a:hover {
  color: var(--foreground);
  border-bottom-color: var(--border);
}

.admin-breadcrumb [aria-current="page"] {
  color: var(--foreground);
  font-weight: 500;
}

.admin-breadcrumb-sep {
  color: var(--muted-foreground);
  opacity: 0.6;
}

.admin-section-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}

.admin-section-header-text {
  min-width: 0;
  flex: 1 1 280px;
}

.admin-section-title {
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 0.2rem;
  color: var(--foreground);
}

.admin-section-description {
  font-size: 0.88rem;
  color: var(--muted-foreground);
  margin: 0;
  line-height: 1.45;
}

.admin-primary-action {
  white-space: nowrap;
  flex: 0 0 auto;
}

.admin-content {
  min-width: 0;
}

/* In-page anchor nav used by detail views (airport, screen, tags). */
.admin-subnav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.25rem;
  margin-bottom: 1rem;
  padding: 0.3rem 0;
  border-bottom: 1px dashed var(--border);
}

.admin-subnav a {
  font-size: 0.8rem;
  color: var(--muted-foreground);
  text-decoration: none;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.admin-subnav a:hover {
  background: var(--muted);
  color: var(--foreground);
}

/* Overview-page KPI tiles (link cards rendered as clickable cards). */
.admin-kpi {
  text-decoration: none;
  color: inherit;
  transition: transform var(--transition-fast), border-color var(--transition-fast);
  display: flex;
}

.admin-kpi:hover {
  transform: translateY(-1px);
  border-color: var(--brand);
}

.admin-quick-link {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.admin-quick-link:hover {
  border-color: var(--brand);
  background: var(--brand-muted);
}

.admin-quick-link strong {
  color: var(--foreground);
  font-size: 0.95rem;
}

.admin-related-list {
  list-style: none;
  padding: 0;
  margin: 0.35rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
}

.admin-related-list a {
  color: var(--foreground);
  text-decoration: none;
  border-bottom: 1px dashed transparent;
}

.admin-related-list a:hover {
  border-bottom-color: var(--border);
}



/* =============================================================================
   === Airport workspace (two-column edit page) ===
   Integrated editor replacing the anchor-navigated scroll layout. Left column
   is "the runway board" (runways + visual flow diagrams). Right column holds
   metadata, FAA sync, QRG, and related entities.
   ============================================================================= */

.airport-workspace {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: stretch;
}

.airport-workspace-left,
.airport-workspace-right {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

/* --- Runway board --- */

.rwy-board-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  padding: 0.5rem 0;
  min-height: 2.25rem;
}

.rwy-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.28rem 0.55rem 0.28rem 0.7rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  border-radius: var(--radius-md);
  background: var(--secondary);
  border: 1px solid var(--border);
  color: var(--foreground);
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--transition-fast),
    border-color var(--transition-fast),
    color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.rwy-chip:hover { border-color: var(--brand-ring); }

.rwy-chip.is-selected {
  background: var(--brand-muted);
  border-color: var(--brand);
  color: var(--brand);
}

.rwy-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  margin-left: 0.1rem;
  border: none;
  background: transparent;
  color: var(--muted-foreground);
  border-radius: var(--radius-full);
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.rwy-chip-x:hover {
  background: var(--danger-muted);
  color: var(--danger);
}

.rwy-add-form {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  margin-top: 0.25rem;
}

.rwy-add-form .form-control { max-width: 140px; }

.rwy-add-btn {
  min-width: 2.25rem;
  padding: 0.45rem 0.7rem;
  font-size: 0.95rem;
  line-height: 1;
}

.rwy-err {
  display: none;
  color: var(--danger);
  font-size: 0.78rem;
  margin-top: 0.35rem;
}

.rwy-err.is-visible { display: block; }

/* --- Flow diagrams --- */

.flow-list {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.flow-diagram {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.02);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.flow-diagram:hover { border-color: var(--brand-ring); }

.flow-diagram.is-active {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px var(--brand-muted);
}

.flow-diagram-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.flow-diagram-name {
  font-weight: 600;
  font-size: 0.92rem;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.flow-diagram-star {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0.15rem 0.3rem;
  font-size: 1rem;
  line-height: 1;
  color: var(--muted-foreground);
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast), background-color var(--transition-fast);
}

.flow-diagram-star.is-default { color: var(--brand); }

.flow-diagram-star:hover { background: var(--secondary); }

.flow-diagram-actions {
  display: flex;
  gap: 0.35rem;
  flex-shrink: 0;
}

.flow-rwy-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-items: center;
  font-size: 0.72rem;
}

.flow-rwy-row-label {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-right: 0.25rem;
  min-width: 3.25rem;
}

.flow-rwy-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.14rem 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--secondary);
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
  cursor: default;
  user-select: none;
}

.flow-rwy-pill.state-arrival {
  color: var(--success);
  background: var(--success-muted);
  border-color: rgba(34, 197, 94, 0.4);
}

.flow-rwy-pill.state-departure {
  color: var(--brand);
  background: var(--brand-muted);
  border-color: rgba(249, 115, 22, 0.4);
}

.flow-rwy-pill.state-both {
  color: var(--warning);
  background: var(--warning-muted);
  border-color: rgba(234, 179, 8, 0.45);
}

.flow-rwy-pill.state-off {
  color: var(--muted-foreground);
  background: transparent;
  border-style: dashed;
}

.flow-diagram.is-editing .flow-rwy-pill { cursor: pointer; }

.flow-diagram.is-editing .flow-rwy-pill:hover { border-color: var(--brand-ring); }

.flow-diagram.is-editing .flow-rwy-pill:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 2px;
}

.flow-editor {
  display: none;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.35rem;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--border);
}

.flow-diagram.is-editing .flow-editor { display: flex; }

.flow-editor-hint {
  font-size: 0.72rem;
  color: var(--muted-foreground);
}

.flow-editor-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  font-size: 0.7rem;
  color: var(--muted-foreground);
}

.flow-add-btn-row {
  display: flex;
  justify-content: flex-start;
  margin-top: 0.35rem;
}

/* Flow wind-direction range (paired inputs in the editor) */
.flow-wind-range-inputs {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.flow-wind-range-inputs .form-control {
  flex: 1 1 0;
  min-width: 0;
}
.flow-wind-range-sep {
  color: var(--muted-foreground);
  font-weight: 600;
  flex: 0 0 auto;
}

/* Wind-rule badges on the flow list card (under the header) */
.flow-diagram-windpills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: -0.1rem;
  margin-bottom: 0.15rem;
}

/* --- Consolidated runways & flows card --- */

.rwyflows-section {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.rwyflows-section + .rwyflows-section {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px dashed var(--border);
}
.rwyflows-section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.65rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}

/* --- Flow-preset metadata list (name + wind + default star + edit/delete) --- */

.flow-meta-list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.flow-meta-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.02);
  flex-wrap: nowrap;
  min-width: 0;
}
.flow-meta-row > .flow-diagram-star { flex-shrink: 0; }
.flow-meta-wind {
  white-space: nowrap;
  flex-shrink: 0;
}
.flow-meta-row.is-default { border-color: var(--brand); }
.flow-meta-name {
  font-weight: 600;
  font-size: 0.9rem;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.flow-meta-wind {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}
.flow-meta-actions {
  display: flex;
  gap: 0.35rem;
  flex-shrink: 0;
}
.flow-meta-editor {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

/* --- Runway pair list --- */

.pair-add-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.pair-add-form .form-control {
  max-width: 120px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.pair-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.pair-row {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.02);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.pair-row:hover { border-color: var(--brand-ring); }
.pair-row.is-dragging { opacity: 0.55; }
.pair-row.is-drop-target {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px var(--brand-muted);
}
.pair-row.is-expanded { border-color: var(--brand-ring); }

.pair-row-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  cursor: pointer;
  user-select: none;
  flex-wrap: nowrap;
  min-width: 0;
}

.pair-row-handle {
  color: var(--muted-foreground);
  cursor: grab;
  font-size: 0.85rem;
  line-height: 1;
  padding: 0 0.15rem;
  letter-spacing: -0.2em;
  flex-shrink: 0;
}
.pair-row-handle:active { cursor: grabbing; }

.pair-row-idents {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  min-width: 5.5rem;
  flex-shrink: 0;
}
.pair-row-sep {
  color: var(--muted-foreground);
  font-weight: 500;
}

.pair-row-summary {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.25rem;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}
.pair-row-flowchip {
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-full);
  background: var(--secondary);
  border: 1px solid var(--border);
  color: var(--muted-foreground);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex-shrink: 1;
}
.pair-row-flowchip.is-default {
  color: var(--brand);
  border-color: var(--brand);
}

.pair-row-chevron {
  color: var(--muted-foreground);
  transition: transform var(--transition-fast);
  font-size: 0.7rem;
  flex-shrink: 0;
}
.pair-row.is-expanded .pair-row-chevron { transform: rotate(180deg); }

.pair-row-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--muted-foreground);
  border-radius: var(--radius-full);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  flex-shrink: 0;
}
.pair-row-remove:hover {
  background: var(--danger-muted);
  color: var(--danger);
}

.pair-row-body {
  padding: 0.4rem 0.7rem 0.7rem;
  border-top: 1px dashed var(--border);
}

/* --- Pair × flow matrix (transposed editor) --- */

.pair-matrix {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.pair-matrix-row {
  display: grid;
  grid-template-columns: minmax(9rem, 1.2fr) repeat(2, minmax(5.5rem, 1fr));
  gap: 0.45rem;
  align-items: center;
  padding: 0.3rem 0.1rem;
  border-bottom: 1px solid var(--border);
}
.pair-matrix-row:last-child { border-bottom: none; }
.pair-matrix-head {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.3rem;
}
.pair-matrix-flowname {
  font-size: 0.82rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.pair-matrix-head .pair-matrix-flowname { font-weight: 700; letter-spacing: 0.1em; }
.pair-matrix-endhead {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.78rem;
  text-align: center;
}
.pair-matrix-cell {
  display: flex;
  justify-content: center;
}
.pair-matrix-cell .flow-rwy-pill {
  cursor: pointer;
  min-width: 4.75rem;
  justify-content: center;
}
.pair-matrix-cell .flow-rwy-pill:hover { border-color: var(--brand-ring); }

/* Collapsible card (QRG) */
.admin-collapse {
  display: flex;
  flex-direction: column;
}

.admin-collapse-toggle {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  background: transparent;
  border: none;
  text-align: left;
  padding: 0;
  color: inherit;
  font: inherit;
  width: 100%;
}

.admin-collapse-body { margin-top: 0.75rem; }

.admin-collapse[aria-expanded="false"] .admin-collapse-body { display: none; }

.admin-collapse-chevron {
  transition: transform var(--transition-fast);
  color: var(--muted-foreground);
  flex-shrink: 0;
}

.admin-collapse[aria-expanded="true"] .admin-collapse-chevron {
  transform: rotate(90deg);
}


/* =============================================================================
   === Admin positions — drag-and-drop consolidation tree ===
   Interactive replacement for the read-only nested UL tree. Uses native HTML5
   DnD. See `public/js/admin-positions-tree.js` for behavior.
   ============================================================================= */

.admin-tree-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.admin-tree-hint {
  font-size: 0.78rem;
  color: var(--muted-foreground);
}

.admin-tree-root-drop {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.2rem;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
  font-size: 0.78rem;
  color: var(--muted-foreground);
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  background: transparent;
  transition: border-color var(--transition-fast), background-color var(--transition-fast), color var(--transition-fast);
}

.admin-tree-root-drop.is-drag-over {
  border-color: var(--brand);
  background: var(--brand-muted);
  color: var(--brand);
}

.admin-tree {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.admin-tree .admin-tree {
  margin-top: 0.25rem;
  margin-left: 1.1rem;
  padding-left: 0.85rem;
  border-left: 1px dashed var(--border);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.admin-tree-item {
  list-style: none;
  display: flex;
  flex-direction: column;
}

.admin-tree-node {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  cursor: grab;
  min-width: 0;
  transition:
    border-color var(--transition-fast),
    background-color var(--transition-fast),
    box-shadow var(--transition-fast),
    opacity var(--transition-fast);
}

.admin-tree-node:hover {
  border-color: var(--brand-ring);
}

.admin-tree-node:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 2px;
}

.admin-tree-node.is-dragging {
  opacity: 0.45;
  cursor: grabbing;
}

.admin-tree-node.is-drag-over {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px var(--brand-muted);
  background: var(--brand-subtle);
}

.admin-tree-node.is-invalid-drop {
  border-color: var(--danger);
  border-style: dashed;
  background: var(--danger-muted);
}

/* Before/after drop indicators — a horizontal brand-colored line above or
   below the target node signals "drop here as a sibling of this node". The
   ring stays off to avoid visual conflict with the 'into' highlight. */
.admin-tree-node {
  position: relative;
}
.admin-tree-node.is-drop-before::before,
.admin-tree-node.is-drop-after::after {
  content: '';
  position: absolute;
  left: -0.35rem;
  right: -0.35rem;
  height: 3px;
  background: var(--brand);
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.35), 0 0 8px rgba(249, 115, 22, 0.45);
  pointer-events: none;
}
.admin-tree-node.is-drop-before::before { top: -4px; }
.admin-tree-node.is-drop-after::after { bottom: -4px; }

.admin-tree-node strong {
  font-weight: 600;
  font-size: 0.88rem;
}

.admin-tree-node-main {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
}

.admin-tree-node-label {
  color: var(--muted-foreground);
  font-size: 0.8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.admin-tree-node-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  flex-shrink: 0;
}

.admin-tree-grip {
  color: var(--muted-foreground);
  font-size: 0.9rem;
  line-height: 1;
  padding: 0 0.15rem;
  cursor: grab;
  user-select: none;
}

.admin-tree-empty {
  padding: 1rem;
  text-align: center;
  color: var(--muted-foreground);
  font-size: 0.85rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
}

/* Inline toast used by DnD error surfaces. */
.admin-toast {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: var(--z-toast);
  padding: 0.65rem 0.95rem;
  font-size: 0.82rem;
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--foreground);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  max-width: 340px;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity var(--transition-normal), transform var(--transition-normal);
}

.admin-toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.admin-toast.is-error {
  border-color: var(--danger);
  color: var(--danger);
}

.admin-toast.is-success {
  border-color: var(--success);
  color: var(--success);
}

/* Modal helper for keyboard parent picker. */
.admin-parent-picker-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-height: 55vh;
  overflow-y: auto;
}

.admin-parent-picker-list button {
  width: 100%;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--foreground);
  border-radius: var(--radius-md);
  padding: 0.5rem 0.7rem;
  cursor: pointer;
  font: inherit;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.admin-parent-picker-list button:hover {
  border-color: var(--brand);
  background: var(--brand-subtle);
}

/* ---- Traffic card: Gate Hold cell + scoped subheader/footer tightening ---- */
/* Gate Hold cell inherits the full .ids-edct-cell visual family; the alias
   class is a semantic hook for targeted tweaks without touching the EDCT
   column. Keeps state variants (is-set/is-manual/is-simtraffic/is-empty)
   working identically to EDCT. */
.ids-gh-cell { /* inherits .ids-edct-cell; alias retained for future scoping */ }

/* Smaller, dense typography inside traffic cards only — scoped so other
   cards on the IDS page keep their default card-description / card-footer
   sizing. Targets CHub's muted-foreground token for consistency. */
.ids-traffic-card .card-description {
  font-size: 0.72rem;
  color: var(--muted-foreground);
}
.ids-traffic-card .card-footer {
  font-size: 0.72rem;
  color: var(--muted-foreground);
  justify-content: center;
  text-align: center;
}

/* =============================================================================
   === Airport picker (chip-list ICAO selector) ===
   Upgraded from `<select multiple>` by /public/js/admin-airport-picker.js.
   Reuses the global `.chip` pill primitive from vatds-restore.css.
   ============================================================================= */
.airport-picker {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.airport-picker-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-height: 1.75rem;
  align-items: center;
}

.airport-picker-chip {
  padding-right: 0.3rem;
}

.airport-picker-chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  padding: 0;
  margin-left: 0.15rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted-foreground);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color var(--transition-fast),
    color var(--transition-fast);
}

.airport-picker-chip-remove:hover {
  background: rgba(225, 29, 72, 0.08);
  color: var(--danger, #e11d48);
}

.airport-picker-chip-remove:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 1px;
}

.airport-picker-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}

.airport-picker-input {
  flex: 0 1 10rem;
  max-width: 12rem;
}

.airport-picker-empty {
  font-style: italic;
}

.airport-picker-error {
  color: var(--danger, #e11d48);
  font-size: 0.78rem;
}

/* =============================================================
   === IDS screen layout — single 12-column grid across all rows ===
   Every block sets `grid-column: col / span N` and `grid-row:
   rowIdx / span row_span` inline, which lets a card grow
   vertically into spacer-covered rows below. Rows collapse to a
   single column on narrow widths.
   ============================================================= */
.ids-layout-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: min-content;
  gap: 1rem;
  margin-bottom: 1rem;
  /* align-items: start so a tall block in one column doesn't force the
     other blocks in the same grid row to stretch to match its height.
     Tracks still size to accommodate the tallest item (required for
     row_span expansion to work), but individual items sit at their
     natural height inside each track. */
  align-items: start;
}
.ids-layout-block { min-width: 0; display: flex; flex-direction: column; }
/* Blocks whose row_span > 1 stretch across the multiple grid rows
   they occupy so their .card fills the reserved vertical space
   (this is the "grow into the spacer below" effect). Everything
   else sits at natural height and doesn't influence its neighbors. */
.ids-layout-block.is-row-expanded { align-self: stretch; }
.ids-layout-block.is-row-expanded > .card:first-child:last-child {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  margin-bottom: 0;
  height: 100%;
}
.ids-layout-block.is-row-expanded > .card:first-child:last-child > .card-content {
  flex: 1 1 auto;
}
@media (max-width: 900px) {
  .ids-layout-grid { grid-template-columns: minmax(0, 1fr); }
  .ids-layout-block {
    grid-column: 1 / -1 !important;
    grid-row: auto !important;
  }
}


/* =============================================================
   === Admin layout editor (page-style composer) ===
   /admin/layouts/:group. A top toolbar of category-grouped card
   chips sits above a single continuous 12-column canvas. Row
   boundaries are implicit visual cues (row handle on the leading
   edge, thin insert bar between rows). Blocks resize by dragging
   their right edge (pointer events). All tokens come from
   public/css/variables.css.
   ============================================================= */

/* Responsive advisory - hidden on desktop, shown on narrow viewports. */
.le-mobile-banner {
  display: none;
  margin: 0 0 0.85rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius-sm);
  background: var(--brand-subtle);
  color: var(--foreground);
  font-size: 0.8rem;
}
@media (max-width: 900px) {
  .le-mobile-banner { display: block; }
}

/* ----- Screen-type tabs (Cab / TRACON / Enroute / TMU) ------ */
.le-tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.85rem;
  padding: 0.25rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: fit-content;
}
.le-tab {
  padding: 0.4rem 0.9rem;
  border-radius: var(--radius-sm);
  color: var(--muted-foreground);
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: background 0.15s, color 0.15s;
}
.le-tab:hover { background: var(--secondary); color: var(--foreground); }
.le-tab.is-active {
  background: var(--brand);
  color: var(--brand-foreground);
}

/* ----- Menubar palette (File / Edit / … style) ---------------
   A thin menubar across the top of the editor. Each category is a
   single button that toggles a dropdown panel of draggable chips.
   Standard File-Edit-Window conventions: only one panel open at a
   time, hover moves the open state across siblings, Esc / click-out
   closes. Chips inside the panel remain `draggable="true"` for HTML5
   DnD onto the canvas. */
.le-menubar {
  position: sticky;
  top: 0;
  z-index: 12;
  display: flex;
  gap: 0.1rem;
  margin: 0 0 0.85rem;
  padding: 0.25rem 0.35rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: visible;
}
.le-menubar-group {
  position: relative;
}
.le-menubar-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.7rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--foreground);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.1s, border-color 0.1s, color 0.1s;
  white-space: nowrap;
}
.le-menubar-btn:hover,
.le-menubar-btn:focus-visible {
  background: var(--secondary);
  outline: none;
}
.le-menubar-group.is-open .le-menubar-btn,
.le-menubar-btn[aria-expanded="true"] {
  background: var(--brand-muted);
  color: var(--brand);
  border-color: var(--brand-ring);
}
.le-menubar-caret {
  font-size: 0.7rem;
  opacity: 0.7;
}

/* Dropdown panel — anchored below its menubar button, floats over the
   canvas. Chips are stacked vertically for readable menu listings, one
   row per card with the label + default-span pill on the far right. */
.le-menu-panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  min-width: 15rem;
  max-width: 22rem;
  padding: 0.3rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.le-menu-panel[hidden] { display: none; }

.le-menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.4rem 0.55rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--foreground);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  text-align: left;
  cursor: grab;
  user-select: none;
  white-space: nowrap;
  transition: background 0.1s, border-color 0.1s;
}
.le-menu-item:hover,
.le-menu-item:focus-visible {
  background: var(--brand-subtle);
  border-color: var(--brand-ring);
  outline: none;
}
.le-menu-item:active { cursor: grabbing; }
.le-menu-item.is-dragging { opacity: 0.45; cursor: grabbing; }
.le-menu-item.is-spacer {
  border-style: dashed;
  border-color: var(--border);
  color: var(--muted-foreground);
  font-style: italic;
}
.le-menu-item-label {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1 1 auto;
}
.le-menu-item-span {
  font-size: 0.65rem;
  padding: 0.05rem 0.35rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.le-menu-item:hover .le-menu-item-span { background: var(--brand-muted); color: var(--brand); }

/* ----- Canvas frame - evokes the live IDS device ------------ */
.le-frame {
  /* Translucent gray wash so gray cards sit on a surface that's
     a sibling of their own color, not a stark near-black. */
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 1rem 0.75rem;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.02) inset;
}
.le-frame-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0 0.25rem 0.55rem;
  border-bottom: 1px dashed var(--border);
  margin-bottom: 0.4rem;
}
.le-frame-chip {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--brand-muted);
  color: var(--brand);
  font-weight: 600;
}
.le-frame-hint {
  font-size: 0.72rem;
  color: var(--muted-foreground);
}

.le-canvas {
  display: flex;
  flex-direction: column;
  min-height: 220px;
  padding: 0.25rem 0;
}
.le-canvas.is-drop-active .le-cell:not(.is-occupied) {
  background: rgba(249, 115, 22, 0.05);
  border-color: var(--brand-ring);
}

.le-canvas-footer {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  padding: 0.6rem 0.25rem 0.1rem;
  border-top: 1px dashed var(--border);
  margin-top: 0.35rem;
}

/* Empty state */
.le-empty {
  padding: 2rem 1.25rem;
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  color: var(--muted-foreground);
}
.le-empty-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--foreground);
  margin-bottom: 0.35rem;
}
.le-empty-desc {
  margin: 0;
  font-size: 0.82rem;
}

/* ----- Inter-row insertion bar ------------------------------
   Zero layout height so rows sit directly on top of each other.
   The "+" control pokes into the adjacent rows on hover via
   overflow: visible + absolute positioning — hovering the thin
   seam between two rows reveals it, but idle it takes no space. */
.le-insert {
  position: relative;
  height: 0;
  margin: 0;
  overflow: visible;
}
.le-insert-btn {
  position: absolute;
  left: 0;
  right: 0;
  /* Poke into both rows' bottom/top padding so the hover hit
     zone is 20px tall while contributing 0 to flow layout. */
  top: -10px;
  height: 20px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.35rem;
  background: transparent;
  border: none;
  color: var(--muted-foreground);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s;
  padding: 0 0.5rem;
  z-index: 4;
}
.le-insert:hover .le-insert-btn,
.le-insert-btn:focus-visible { opacity: 1; }
.le-insert-line {
  display: block;
  height: 1px;
  background: var(--brand-ring);
}
.le-insert-plus {
  font-size: 0.9rem;
  line-height: 1;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: var(--brand);
  color: var(--brand-foreground);
  font-weight: 700;
}

/* ----- Row ----------------------------------------------------
   The row handle floats in the left gutter (absolute) so the 12-col
   grid below occupies the full canvas width — visually matching the
   live IDS layout one-to-one. Reserve ~1.8rem on the left for the
   handle and hover-controls. */
.le-row {
  position: relative;
  padding: 0 0 0 1.9rem;
}

.le-row-handle {
  position: absolute;
  top: 0;
  left: 0;
  width: 1.65rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  color: var(--muted-foreground);
  z-index: 3;
}
.le-row-num {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  background: var(--secondary);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
  transition: background 0.12s, color 0.12s;
}
.le-row:hover .le-row-num {
  background: var(--brand-muted);
  color: var(--brand);
  border-color: var(--brand-ring);
}
.le-row-ctl {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin-top: 0.3rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s;
}
.le-row:hover .le-row-ctl,
.le-row:focus-within .le-row-ctl {
  opacity: 1;
  pointer-events: auto;
}
.le-row-btn {
  width: 1.4rem;
  height: 1.4rem;
  border-radius: var(--radius-sm);
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--muted-foreground);
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: color 0.1s, border-color 0.1s, background 0.1s;
  font-family: inherit;
}
.le-row-btn:hover:not(:disabled) {
  color: var(--foreground);
  border-color: var(--brand-ring);
  background: var(--secondary);
}
.le-row-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.le-row-btn.is-danger:hover:not(:disabled) {
  color: var(--danger);
  border-color: var(--danger);
}

/* ----- 12-column grid + cells + blocks ----------------------
   Every cell and block is explicitly pinned to `grid-row: 1`, and
   we disable any implicit grid tracks (`grid-auto-rows: 0`,
   `row-gap: 0`) so the grid can never create a phantom second
   track that would add vertical whitespace inside the row.
   column-gap matches the live .ids-layout-grid (1rem). */
.le-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: auto;
  grid-auto-rows: 0;
  column-gap: 1rem;
  row-gap: 0;
  min-height: 120px;
  padding: 0;
  align-items: stretch;
}

.le-cell {
  position: relative;
  grid-row: 1;
  min-height: 120px;
  border: 1px dashed transparent;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  transition: background 0.1s, border-color 0.1s, color 0.1s;
}
.le-canvas.is-drop-active .le-cell:not(.is-occupied) { border-color: var(--border); }
.le-cell:not(.is-occupied):hover {
  background: rgba(255, 255, 255, 0.02);
  border-color: var(--border);
  color: var(--muted-foreground);
}
.le-cell.is-occupied {
  pointer-events: none;
  border: none;
}
.le-cell-label {
  font-size: 0.6rem;
  letter-spacing: 0.05em;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.le-cell.is-drag-over {
  background: var(--brand-muted);
  border-color: var(--brand);
  color: var(--brand);
  border-style: solid;
}
.le-cell.is-invalid {
  background: rgba(239, 68, 68, 0.1);
  border-color: var(--danger);
  color: var(--danger);
  border-style: solid;
}

/* A placed block. Sits in the same grid via explicit grid-column on an
   overlay row. Keeps a subtle hover ring and a clearly-handled right edge
   for resize. */
.le-block {
  position: relative;
  grid-row: 1;
  min-height: 120px;
  /* Equal padding on both sides to reserve space for the left and
     right resize handles. */
  padding: 0.65rem 1.1rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  cursor: grab;
  user-select: none;
  outline: none;
  transition: border-color 0.1s, box-shadow 0.1s, background 0.1s;
  z-index: 2;
}
.le-block:hover { border-color: var(--brand-ring); }
.le-block:focus-visible {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px var(--brand-subtle);
}
.le-block.is-dragging { opacity: 0.45; cursor: grabbing; }
.le-block.is-spacer {
  background: transparent;
  border-style: dashed;
  color: var(--muted-foreground);
}
.le-block.is-drop-target {
  border-color: var(--danger);
  background: rgba(239, 68, 68, 0.08);
  cursor: not-allowed;
}
.le-block.is-resizing {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px var(--brand-muted);
  cursor: ew-resize;
}
.le-block.is-resize-max {
  border-color: #f59e0b;
  box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.18);
}

.le-block-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1;
}
.le-block-title {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--foreground);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.le-block.is-spacer .le-block-title { color: var(--muted-foreground); font-style: italic; }
.le-block-meta {
  font-size: 0.68rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}

.le-block-del {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted-foreground);
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  transition: color 0.1s, background 0.1s, border-color 0.1s;
  font-family: inherit;
}
.le-block-del:hover {
  color: var(--danger);
  border-color: var(--danger);
  background: rgba(239, 68, 68, 0.1);
}

/* Edge resize handles (left + right). Invisible until block hover
   or during an active resize; both edges drag to change span — the
   left edge keeps the right edge fixed and shifts col accordingly. */
.le-block-resize {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 8px;
  cursor: ew-resize;
  touch-action: none;
  background: transparent;
  transition: background 0.12s, opacity 0.12s;
  opacity: 0;
}
.le-block-resize-right {
  right: 0;
  border-top-right-radius: var(--radius-sm);
  border-bottom-right-radius: var(--radius-sm);
}
.le-block-resize-left {
  left: 0;
  border-top-left-radius: var(--radius-sm);
  border-bottom-left-radius: var(--radius-sm);
}
.le-block:hover .le-block-resize,
.le-block:focus-within .le-block-resize {
  background: var(--brand);
  opacity: 0.55;
}
.le-block.is-resizing .le-block-resize { opacity: 1; }
.le-block.is-resizing .le-block-resize-left,
.le-block.is-resizing .le-block-resize-right {
  background: var(--brand);
}

/* Floating live span readout during resize. */
.le-resize-tip {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-sm);
  background: var(--foreground);
  color: var(--background);
  font-variant-numeric: tabular-nums;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.le-resize-tip.is-warn {
  background: #f59e0b;
  color: #1b1b1f;
}

/* ----- Narrow viewports -------------------------------------- */
@media (max-width: 900px) {
  .le-menubar { position: static; flex-wrap: wrap; }
  .le-menu-panel { left: 0; right: auto; max-width: 100%; }
  .le-grid { gap: 0.5rem; min-height: 80px; }
  .le-cell { min-height: 80px; }
  .le-block { padding: 0.5rem 0.9rem; min-height: 80px; }
  .le-row { padding-left: 1.5rem; }
  .le-row-handle { width: 1.3rem; }
}

/* -------------------------------------------------------------------------
 * CFR (Call For Release) card — TMU-only operational panel.
 * ---------------------------------------------------------------------- */
.ids-cfr-card .ids-cfr-controls { display: flex; flex-direction: column; gap: 1rem; }

/* Step containers — number-prefixed sections that walk the TMO through the
 * inputs in the order their mental model expects: aircraft → route → spacing.
 * The number chip + connecting border give a subtle wizard feel without
 * forcing a true multi-step UI. */
.ids-cfr-step { display: flex; flex-direction: column; gap: 0.45rem; }
.ids-cfr-step-head { display: flex; align-items: center; gap: 0.55rem; }
.ids-cfr-step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem;
  border-radius: var(--radius-full);
  background: var(--brand-muted);
  border: 1px solid var(--brand-ring);
  color: var(--brand);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1;
}
.ids-cfr-step-label {
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--foreground);
}
.ids-cfr-step-hint {
  margin: 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--muted-foreground);
}

/* Route (from → to). Two equal-flex inputs straddling a directional arrow.
 * On narrow widths the arrow rotates 90° and the legs stack. */
.ids-cfr-route {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 0.55rem;
  align-items: end;
}
.ids-cfr-route-leg { margin: 0; }
.ids-cfr-route-input {
  font-family: var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
}
.ids-cfr-route-arrow {
  display: flex; align-items: center; justify-content: center;
  padding-bottom: 0.55rem;
  color: var(--muted-foreground);
}
@media (max-width: 520px) {
  .ids-cfr-route { grid-template-columns: 1fr; }
  .ids-cfr-route-arrow { transform: rotate(90deg); padding: 0; }
}

/* Spacing rule: segmented mode picker on top, value-with-unit on the
 * bottom. Mode + value are tightly coupled so they share one section
 * rather than two stacked form-groups. */
.ids-cfr-spacing { display: flex; flex-direction: column; gap: 0.55rem; }
.ids-cfr-segmented {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--secondary);
  padding: 0.2rem;
  gap: 0.2rem;
  width: fit-content;
}
.ids-cfr-seg-btn {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--muted-foreground);
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 0.4rem 0.85rem;
  border-radius: calc(var(--radius-sm) - 2px);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.ids-cfr-seg-btn:hover { color: var(--foreground); }
.ids-cfr-seg-btn.is-active {
  background: var(--brand);
  color: var(--brand-foreground);
}
.ids-cfr-seg-btn:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 2px;
}

.ids-cfr-spacing-value { margin: 0; max-width: 14rem; }
/* Number input with a unit suffix glued to the right edge. The suffix is
 * absolutely positioned so the underlying <input> stays a real number
 * field (spinners, validation, autofill) — we just nudge its right pad. */
.ids-cfr-value-wrap { position: relative; }
.ids-cfr-value-input { padding-right: 2.6rem; font-variant-numeric: tabular-nums; }
.ids-cfr-value-unit {
  position: absolute;
  right: 0.6rem; top: 50%;
  transform: translateY(-50%);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
  pointer-events: none;
  text-transform: uppercase;
}

/* Override defaults disclosure. Cruise GS lives here because it's
 * auto-filled — 99% of the time the TMO won't open this. The summary
 * shows a chip with the current effective GS so confirming doesn't
 * require a click. */
.ids-cfr-advanced {
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
}
.ids-cfr-advanced-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.75rem;
  cursor: pointer;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted-foreground);
  list-style: none;
  user-select: none;
}
.ids-cfr-advanced-summary::-webkit-details-marker { display: none; }
.ids-cfr-advanced-summary:hover { color: var(--foreground); }
.ids-cfr-advanced-caret {
  transition: transform 140ms ease;
  flex-shrink: 0;
}
.ids-cfr-advanced[open] > .ids-cfr-advanced-summary .ids-cfr-advanced-caret {
  transform: rotate(90deg);
}
.ids-cfr-advanced-meta {
  margin-left: auto;
  padding: 0.15rem 0.55rem;
  border-radius: var(--radius-full);
  background: var(--brand-subtle);
  border: 1px solid var(--brand-ring);
  color: var(--brand);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-family: var(--font-mono);
}
.ids-cfr-advanced-meta.is-override {
  background: rgba(250, 204, 21, 0.12);
  border-color: rgba(250, 204, 21, 0.5);
  color: #facc15;
}
.ids-cfr-advanced-body {
  padding: 0 0.75rem 0.75rem;
}

/* Primary action anchored at the bottom of the input area, full width. */
.ids-cfr-actions {
  display: flex;
  margin-top: 0.2rem;
}
.ids-cfr-submit {
  flex: 1;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding-top: 0.65rem;
  padding-bottom: 0.65rem;
}
.ids-cfr-error {
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--danger, #e11d48);
  border-radius: var(--radius-sm);
  background: rgba(225, 29, 72, 0.08);
  color: var(--danger, #e11d48);
  font-size: 0.85rem;
}
.ids-cfr-result {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px dashed var(--border);
  display: flex; flex-direction: column; gap: 0.85rem;
}
.ids-cfr-edct {
  display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap;
}
.ids-cfr-edct-time {
  font-family: var(--font-mono);
  font-size: 2.6rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.03em;
  color: var(--brand, #f59e0b);
  font-variant-numeric: tabular-nums;
}
.ids-cfr-edct-meta { display: flex; flex-direction: column; gap: 0.2rem; }
.ids-cfr-flow { border: 1px solid var(--border); border-radius: var(--radius-sm); }
.ids-cfr-flow-head {
  padding: 0.4rem 0.75rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  background: var(--secondary);
  border-bottom: 1px solid var(--border);
}
.ids-cfr-flow-table th, .ids-cfr-flow-table td { padding: 0.4rem 0.6rem; }
.ids-cfr-flow-table .num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.ids-cfr-row-candidate {
  background: rgba(245, 158, 11, 0.12);
  font-weight: 700;
}
.ids-cfr-spacing-ok { color: #16a34a; }
.ids-cfr-spacing-bad { color: #dc2626; }

/* Inline tag shown next to a callsign when the aircraft was matched into
 * the snapshot via SID/STAR expansion rather than a literal route token. */
.ids-cfr-via {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  background: rgba(250, 204, 21, 0.15);
  border: 1px solid rgba(250, 204, 21, 0.4);
  border-radius: 999px;
  color: #facc15;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
  cursor: help;
}

/* Browsers render <option> / <optgroup> with a system-default light list
 * even on dark themes. Force a fully dark popup on the CFR card's
 * dropdowns and color the optgroup labels yellow so the wake-category
 * headers stand out from the type rows. Chromium and Firefox both honor
 * these declarations on option/optgroup; Safari is more restrictive but
 * at minimum picks up the background. */
.ids-cfr-card select,
.ids-cfr-card select option,
.ids-cfr-card select optgroup {
  background-color: #1b1b1f;
  color: #fafafa;
}
.ids-cfr-card select optgroup {
  color: #facc15;
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ids-cfr-card select option {
  font-weight: 500;
  padding: 0.25rem 0.5rem;
}
.ids-cfr-card select option:checked,
.ids-cfr-card select option:hover {
  background-color: #2a2a2e;
  color: #facc15;
}

/* Aircraft type combobox — searchable replacement for the native <select>.
 * Wake-grouped items, full dark theme, instant typing-to-filter. */
.ids-cfr-combo { position: relative; }
.ids-cfr-combo-input { font-family: var(--font-mono); letter-spacing: 0.04em; text-transform: uppercase; }
.ids-cfr-combo-list {
  position: absolute;
  top: calc(100% + 0.25rem);
  left: 0; right: 0;
  z-index: 50;
  max-height: 18rem;
  overflow-y: auto;
  background: #1b1b1f;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  padding: 0.25rem 0;
}
.ids-cfr-combo-group {
  padding: 0.35rem 0.75rem 0.2rem;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  color: #facc15;
  background: rgba(250, 204, 21, 0.06);
  border-top: 1px solid rgba(250, 204, 21, 0.15);
}
.ids-cfr-combo-group:first-child { border-top: 0; }
.ids-cfr-combo-item {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem;
  padding: 0.35rem 0.75rem;
  cursor: pointer;
  color: #fafafa;
}
.ids-cfr-combo-item:hover,
.ids-cfr-combo-item.is-active {
  background: #2a2a2e;
  color: #facc15;
}
.ids-cfr-combo-ident {
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.ids-cfr-combo-meta {
  font-size: 0.78rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}
.ids-cfr-combo-empty {
  padding: 0.6rem 0.75rem;
  color: var(--muted-foreground);
  font-size: 0.85rem;
}

/* Recommendation header: large EDCT readout next to a structured math grid. */
.ids-cfr-edct-label {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted-foreground);
  margin-bottom: 0.2rem;
}
.ids-cfr-math {
  flex: 1;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 0.9rem;
  align-items: baseline;
  font-size: 0.85rem;
}
.ids-cfr-math-row {
  display: contents;
}
.ids-cfr-math-label {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted-foreground);
  white-space: nowrap;
}
.ids-cfr-math-value {
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
}
.ids-cfr-math-total .ids-cfr-math-label,
.ids-cfr-math-total .ids-cfr-math-value {
  padding-top: 0.35rem;
  border-top: 1px dashed var(--border);
  margin-top: 0.15rem;
}
.ids-cfr-math-total .ids-cfr-math-value { font-weight: 700; color: #facc15; }
.ids-cfr-math-formula .ids-cfr-math-label { color: #facc15; }
.ids-cfr-math-formula .ids-cfr-math-value { font-style: italic; }
.ids-cfr-math-meta {
  grid-column: 1 / -1;
  margin-top: 0.4rem;
  padding-top: 0.4rem;
  border-top: 1px dashed var(--border);
  color: var(--muted-foreground);
  font-size: 0.75rem;
}

/* ============================================================
   Corrections Required panel (enroute / TRACON)
   - Visual density mirrors .ids-rates-live-card / .ids-ladder-table.
   - Action chips use semantic --info / --warning / --danger tokens
     from variables.css so they track theme changes automatically.
   ============================================================ */
.ids-corrections-card { margin-bottom: 1rem; }
.ids-corrections-status {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.ids-corrections-table {
  width: 100%;
  margin: 0;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}
.ids-corrections-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--card);
  color: var(--muted-foreground);
  font-weight: 600;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.ids-corrections-table tbody td {
  padding: 0.45rem 0.75rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  white-space: nowrap;
}
.ids-corrections-table tbody tr:last-child td { border-bottom: 0; }
.ids-corrections-callsign,
.ids-corrections-fix,
.ids-corrections-dest,
.ids-corrections-sta,
.ids-corrections-detail {
  font-family: var(--font-mono);
}
.ids-corrections-detail {
  color: var(--muted-foreground);
  font-size: 0.78rem;
}
.ids-corrections-type {
  color: var(--muted-foreground);
  font-size: 0.78rem;
}
.ids-corrections-sta { text-align: right; }

/* Action chip — small uppercase pill, monospace number readout. */
.ids-corrections-action {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1.4;
  white-space: nowrap;
  border: 1px solid transparent;
}
.ids-corrections-action--speed {
  color: var(--info);
  background: var(--info-muted);
  border-color: var(--info-muted);
}
.ids-corrections-action--hold {
  color: var(--warning);
  background: var(--warning-muted);
  border-color: var(--warning-muted);
}
/* Unachievable: speed correction whose target falls outside the
   150–600 kt envelope. Striped + danger color so it's unmistakable. */
.ids-corrections-action--unachievable {
  color: var(--danger);
  background: var(--danger-muted);
  border-color: var(--danger);
  background-image: repeating-linear-gradient(
    135deg,
    transparent 0,
    transparent 4px,
    rgba(239, 68, 68, 0.18) 4px,
    rgba(239, 68, 68, 0.18) 8px
  );
}

/* Detail-cell line roles. Mirrors the popover correction card so the
   IDS table reads with the same hierarchy: primary action prominent,
   supporting GS detail dimmed, procedural ramp/absorption lines in
   monospace. */
.ids-corrections-detail-line {
  font-size: 0.78rem;
  line-height: 1.3;
  margin: 0.05rem 0;
}
.ids-corrections-detail-line.is-primary {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--foreground);
}
.ids-corrections-detail-line.is-detail {
  color: var(--muted-foreground);
}
.ids-corrections-detail-line.is-procedure {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--muted-foreground);
}
.ids-corrections-detail-line.is-recommend {
  font-weight: 600;
  color: var(--danger);
}

.ids-corrections-empty td {
  color: var(--muted-foreground);
  text-align: center;
  font-style: italic;
  padding: 1rem 0.75rem !important;
}

/* ---------------------------------------------
   QRG structured sections (popup + list page)
   Shared by views/position/_qrg-sections.ejs
   --------------------------------------------- */
.qrg-section .card-header { padding-bottom: 0.5rem; }
.qrg-section-title { font-size: 0.95rem; margin: 0; }
.qrg-section .card-description {
  margin: 0.15rem 0 0;
  font-size: 0.8rem;
  color: var(--muted-foreground);
}
.qrg-section-content { padding-top: 0.5rem; }

.qrg-table-wrap { width: 100%; overflow-x: auto; }
.qrg-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.83rem;
  color: var(--foreground);
}
.qrg-table thead th {
  text-align: left;
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  padding: 0.45rem 0.6rem;
  border-bottom: 1px solid var(--border);
  background: transparent;
  vertical-align: bottom;
  white-space: nowrap;
}
.qrg-table tbody td,
.qrg-table tbody th {
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.qrg-table tbody tr:last-child td,
.qrg-table tbody tr:last-child th { border-bottom: 0; }

.qrg-table-runways th.qrg-col-rwy {
  width: 4.5rem;
  vertical-align: middle;
}
.qrg-rwy-id {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--foreground);
  letter-spacing: 0.02em;
}
.qrg-half-ga {
  border-left: 1px solid var(--border);
}
.qrg-table-runways thead tr:first-child th.qrg-half-initial,
.qrg-table-runways thead tr:first-child th.qrg-half-ga {
  text-align: center;
  font-size: 0.7rem;
  color: var(--muted-foreground);
  padding-bottom: 0.25rem;
}
.qrg-table-runways thead tr:first-child th.qrg-half-ga {
  color: var(--brand);
}

.qrg-mono {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.82rem;
}
.qrg-notes {
  color: var(--muted-foreground);
  font-size: 0.8rem;
  max-width: 22rem;
}
.qrg-route {
  word-break: break-word;
  white-space: normal;
  max-width: 28rem;
  line-height: 1.4;
}
.qrg-sid-name { font-weight: 600; color: var(--foreground); }

.qrg-dash { color: var(--muted-foreground); opacity: 0.5; }

.qrg-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm, 6px);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.2;
  white-space: nowrap;
}
.qrg-badge-success {
  background: var(--success-muted);
  color: var(--success);
  border: 1px solid var(--success-muted);
}
.qrg-badge-muted {
  background: var(--muted);
  color: var(--muted-foreground);
  border: 1px solid var(--border);
}

.qrg-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-sm, 6px);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-family: var(--font-sans);
}
.qrg-pill-wild {
  background: var(--brand-subtle);
  color: var(--brand);
  border: 1px solid var(--brand-muted);
}

.qrg-mini-empty {
  padding: 1rem 0.5rem;
  text-align: left;
}
.qrg-mini-empty .empty-state-description {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted-foreground);
}

/* QRG list-page right pane — stack sections, no extra outer card chrome */
.qrg-sections-stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@media (max-width: 720px) {
  .qrg-table { font-size: 0.78rem; }
}

/* Row-grouping (vectors/altitudes/missed): bold left-column header,
   thicker top border at start of each group. */
.qrg-flow-name {
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--foreground);
  background: var(--card-muted, transparent);
  vertical-align: middle !important;
  text-align: center !important;
  border-right: 1px solid var(--border);
  padding: 0.5rem 0.6rem !important;
  white-space: nowrap;
  text-transform: none;
  letter-spacing: 0;
}
/* Group-start row separator: matches the standard cell border so the
   merged-cell block reads as the same table fabric as everything else. */
.qrg-table tbody tr.qrg-flow-start > td,
.qrg-table tbody tr.qrg-flow-start > th {
  border-top: 1px solid var(--border);
}

.qrg-secondary {
  color: var(--muted-foreground);
  font-style: italic;
}
.qrg-heading-cell {
  white-space: nowrap;
}
/* Allow multi-line altitude strings ("N: 9,000', S: 8,000'") to wrap. */
.qrg-multi {
  white-space: pre-line;
  line-height: 1.35;
}
.qrg-table-initial th.qrg-col-flow,
.qrg-table-missed  th.qrg-col-class { width: 6rem; }
.qrg-table-initial th.qrg-col-rwy,
.qrg-table-missed  th.qrg-col-rwy,
.qrg-table-initial th.qrg-col-dir { width: 3.5rem; }

/* LOA / pref-routing column proportions: arrival + notes squeezed,
   route given the lion's share. table-layout:fixed so column widths
   are honored against long route strings. */
.qrg-table-loa { table-layout: fixed; }
.qrg-table-loa .qrg-flow-name {
  white-space: normal !important;
  word-break: break-word;
}
.qrg-table-loa th:nth-child(1) { width: 4.5rem; }   /* Arrival */
.qrg-table-loa th:nth-child(2) { width: 5rem; }     /* Departure */
.qrg-table-loa th:nth-child(3) { width: 5.5rem; }   /* Aircraft */
.qrg-table-loa th:nth-child(4) { width: auto; }     /* Route — flexes */
.qrg-table-loa th:nth-child(5) { width: 5rem; }     /* Altitude */
.qrg-table-loa th:nth-child(6) { width: 9rem; }     /* Notes */
.qrg-table-loa td { word-break: break-word; overflow-wrap: anywhere; }
.qrg-table-loa .qrg-route { max-width: none; white-space: normal; }
.qrg-table-loa .qrg-notes { max-width: none; }

.qrg-runway-name {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--foreground);
  vertical-align: middle !important;
  text-align: center !important;
  border-right: 1px solid var(--border);
  padding: 0.5rem 0.6rem !important;
  white-space: nowrap;
  background: rgba(255, 255, 255, 0.02);
}
/* New runway block within a flow gets the same separator as a row break. */
.qrg-table tbody tr.qrg-runway-start > td,
.qrg-table tbody tr.qrg-runway-start > th {
  border-top: 1px solid var(--border);
}

/* Special "override" row (e.g. NOT AUTHORIZED, COORDINATION REQUIRED). */
.qrg-override {
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.78rem;
  color: var(--warning, #f59e0b);
  background: rgba(245, 158, 11, 0.06);
  text-align: center;
}

/* =========================================================================
   LOA / pref-routing badge + popover
   -------------------------------------------------------------------------
   Inline pill rendered next to a destination ICAO. Two states:
     .is-match    — filed route matches expected (success/green)
     .is-mismatch — filed route differs from expected (warning/yellow)
   Hover/focus reveals .loa-pr-popover with expected vs filed routes.
   Anchored above-left of the badge (bottom: 100%, left: 0) so long routes
   wrap to the right without clipping inside the IDS row's right edge. CSS-
   only — no JS positioning. Rendered by loaPrBadgeHtml() in ids.js and
   facility-dashboard.js.
   ========================================================================= */
.loa-pr-badge {
  position: relative;
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  font-family: var(--font-sans, inherit);
  font-size: 10px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  vertical-align: baseline;
  cursor: help;
  border: 1px solid transparent;
  /* keep the badge from breaking the row's vertical rhythm */
  white-space: nowrap;
}
.loa-pr-badge:focus { outline: none; }
.loa-pr-badge:focus-visible {
  outline: 2px solid var(--ring, var(--brand));
  outline-offset: 1px;
}
.loa-pr-badge.is-match {
  color: var(--success);
  background: var(--success-muted);
  border-color: var(--success-muted);
}
.loa-pr-badge.is-mismatch {
  color: var(--warning, #f59e0b);
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.35);
}
/* Multi-option (flow-tagged or aircraft-disambiguated): purple. The
   popover lists every applicable LOA so the controller picks. */
.loa-pr-badge.is-multi {
  color: #c084fc;
  background: rgba(168, 85, 247, 0.14);
  border-color: rgba(168, 85, 247, 0.4);
}

/* Popover option rows + dots */
.loa-pop-option {
  padding: 0.35rem 0;
  border-bottom: 1px dashed var(--border);
  display: block;
}
.loa-pop-option:last-of-type { border-bottom: 0; }
.loa-pop-dot {
  display: inline-block;
  width: 0.5rem; height: 0.5rem;
  border-radius: 50%;
  margin-right: 0.4rem;
  vertical-align: middle;
}
.loa-pop-dot--green  { background: var(--success); }
.loa-pop-dot--yellow { background: var(--warning, #f59e0b); }
.loa-pop-arrival {
  color: var(--foreground);
  font-weight: 600;
  font-size: 0.78rem;
}
.loa-pop-flow {
  color: #c084fc;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.7rem;
}
.loa-pop-notes {
  margin-top: 0.2rem;
  font-size: 0.72rem;
  color: var(--muted-foreground);
  font-style: italic;
}
.loa-pop-ac, .loa-pop-alt {
  color: var(--muted-foreground);
  font-size: 0.72rem;
  margin-left: 0.25rem;
}
.loa-pop-route {
  margin-top: 0.2rem;
  word-break: break-word;
  white-space: normal;
  font-size: 0.74rem;
}
.loa-pop-filed {
  margin-top: 0.4rem;
  padding-top: 0.35rem;
  border-top: 1px solid var(--border);
}

/* Popover surface — dark .card-like, anchored above the badge. */
.loa-pr-popover {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  z-index: 50;
  width: 320px;
  max-width: 90vw;
  padding: 0.6rem 0.7rem;
  background: var(--card);
  color: var(--card-foreground, var(--foreground));
  border: 1px solid var(--border);
  border-radius: var(--radius, 0.5rem);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45),
              0 2px 6px rgba(0, 0, 0, 0.3);
  font-family: var(--font-sans, inherit);
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  line-height: 1.45;
  text-align: left;
  /* Hidden by default; shown on hover/focus of the badge. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(2px);
  transition: opacity 120ms ease, transform 120ms ease, visibility 120ms;
  pointer-events: none;
}
.loa-pr-badge:hover .loa-pr-popover,
.loa-pr-badge:focus-within .loa-pr-popover {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}

/* If the badge sits near the right edge of the viewport, allow callers to
   add .loa-pr-popover-right on the parent to flip horizontal anchoring.
   Default left:0 is fine for the typical IDS table layout. */
.loa-pr-badge.anchor-right .loa-pr-popover {
  left: auto;
  right: 0;
}

.loa-pop-title {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted-foreground);
  margin-bottom: 0.4rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--border);
}
.loa-pop-row {
  display: grid;
  grid-template-columns: 70px 1fr;
  gap: 0.4rem;
  align-items: start;
  margin: 0.2rem 0;
}
.loa-pop-row > span:first-child {
  color: var(--muted-foreground);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-top: 0.05rem;
}
.loa-pop-row .qrg-mono {
  word-break: break-word;
  max-width: 100%;
  white-space: normal;
  color: var(--foreground);
}

/* ---- Corrections Required: LOA/route mismatch chip ----
   Same striped treatment as --unachievable but in danger-red for routing
   problems. Distinguished from --unachievable (also red) by being a route
   problem rather than an envelope-violating speed; the chip text "ROUTE"
   carries the semantic load. */
.ids-corrections-action--loa {
  color: var(--danger);
  background: var(--danger-muted);
  border-color: var(--danger);
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0,
    transparent 4px,
    rgba(239, 68, 68, 0.18) 4px,
    rgba(239, 68, 68, 0.18) 8px
  );
}

/* Consider-flow chip: softer purple matching the LOA/PR multi badge.
   Used when an alternate flow option WOULD be green for this filed
   route — controller verifies which flow the local controller is
   running before issuing a route change. Dismissable per-callsign. */
.ids-corrections-action--loa-consider {
  color: #c084fc;
  background: rgba(168, 85, 247, 0.14);
  border-color: rgba(168, 85, 247, 0.4);
}

.ids-corrections-dismiss {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted-foreground);
  width: 1.5rem; height: 1.5rem;
  border-radius: 50%;
  font-size: 0.95rem; line-height: 1;
  cursor: pointer;
  padding: 0;
}
.ids-corrections-dismiss:hover {
  color: var(--foreground);
  background: var(--muted);
  border-color: var(--foreground);
}

/* ============================================================
   Enroute Notices card (PIREPs + general operational notices)
   - Card body is a list of rows; each row leads with a kind
     badge, optional SimTraffic forward-status pill, and a
     compact title/body/meta block. Urgent (UUA) PIREPs get a
     danger-tinted left rail so they pop out of the stream.
   - Companion modal (ids-enroute-notice-modal-*) uses a real
     two-tab control instead of plain ghost buttons.
   ============================================================ */
.ids-enroute-notices-card { margin-bottom: 1rem; }

.ids-enroute-notices-add-btn { white-space: nowrap; }

.ids-enroute-notices-body { padding: 0; }

.ids-enroute-notices-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ---- Empty / loading state ---- */
.ids-enroute-notices-empty {
  padding: 1.25rem 1.25rem;
  text-align: center;
  color: var(--muted-foreground);
  font-size: 0.875rem;
  border-top: 1px solid var(--border);
}
.ids-enroute-notices-list > .ids-enroute-notices-empty:first-child {
  border-top: 0;
}
.ids-enroute-notices-empty--loading { font-style: italic; }
.ids-enroute-notices-empty-title {
  font-weight: 600;
  color: var(--foreground);
  margin-bottom: 0.2rem;
}
.ids-enroute-notices-empty-desc { font-size: 0.82rem; }

/* ---- Row ---- */
.ids-enroute-notices-row {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--border);
  border-left: 3px solid transparent;
  transition: background var(--transition-fast);
}
.ids-enroute-notices-row:first-child { border-top: 0; }
.ids-enroute-notices-row:hover { background: rgba(255, 255, 255, 0.02); }
.ids-enroute-notices-row.is-urgent {
  border-left-color: var(--danger);
  background: var(--danger-muted);
}
.ids-enroute-notices-row.is-urgent:hover { background: rgba(239, 68, 68, 0.22); }

.ids-enroute-notices-row-main { flex: 1; min-width: 0; }

.ids-enroute-notices-row-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin-bottom: 0.3rem;
}

/* ---- Kind badge ---- */
.ids-enroute-notices-kind {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.4;
  font-family: var(--font-mono);
  border: 1px solid transparent;
  white-space: nowrap;
}
.ids-enroute-notices-kind--pirep {
  color: var(--brand);
  background: var(--brand-muted);
  border-color: var(--brand-muted);
}
.ids-enroute-notices-kind--urgent {
  color: var(--danger-foreground);
  background: var(--danger);
  border-color: var(--danger);
}
.ids-enroute-notices-kind--notice {
  color: var(--muted-foreground);
  background: transparent;
  border-color: var(--border);
}

/* ---- SimTraffic status pill ---- */
.ids-enroute-notices-st {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-sm);
  font-size: 0.7rem;
  font-weight: 600;
  font-family: var(--font-mono);
  border: 1px solid transparent;
  white-space: nowrap;
}
.ids-enroute-notices-st.is-ok {
  color: var(--success);
  background: var(--success-muted);
  border-color: var(--success-muted);
}
.ids-enroute-notices-st.is-fail {
  color: var(--danger);
  background: var(--danger-muted);
  border-color: var(--danger-muted);
}
.ids-enroute-notices-st-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  display: inline-block;
}

/* ---- Title / body ---- */
.ids-enroute-notices-title {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--foreground);
  word-break: break-word;
}
.ids-enroute-notices-body-text {
  font-size: 0.82rem;
  color: var(--foreground);
  line-height: var(--leading-normal);
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0.15rem 0 0.35rem;
}
.ids-enroute-notices-row.is-pirep .ids-enroute-notices-body-text {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted-foreground);
}

/* ---- Meta line ---- */
.ids-enroute-notices-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  font-size: 0.74rem;
  color: var(--muted-foreground);
  font-variant-numeric: tabular-nums;
}
.ids-enroute-notices-meta-sep { opacity: 0.5; }
.ids-enroute-notices-meta-author { color: var(--foreground); }
.ids-enroute-notices-meta-posted { font-family: var(--font-mono); }
.ids-enroute-notices-meta-ttl { font-family: var(--font-mono); }
.ids-enroute-notices-meta-ttl.is-soon {
  color: var(--warning);
  font-weight: 600;
}
.ids-enroute-notices-meta-ttl.is-expired {
  color: var(--danger);
  font-weight: 600;
}

/* ---- Per-row delete ---- */
.ids-enroute-notices-delete {
  flex: 0 0 auto;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted-foreground);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color var(--transition-fast),
              background var(--transition-fast),
              border-color var(--transition-fast);
}
.ids-enroute-notices-delete:hover {
  color: var(--danger);
  background: var(--danger-muted);
  border-color: var(--danger-muted);
}
.ids-enroute-notices-delete:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 2px;
}

/* ============================================================
   Enroute Notice modal
   - Two-tab control (PIREP vs General Notice) styled like CHub
     segmented tabs: equal-width buttons, sliding active state,
     hint subtext under each label.
   - Optional weather-fields <details> looks like a real
     collapsible card rather than raw HTML.
   ============================================================ */
/* [hidden] must beat .modal-overlay's display:flex. Browser UA rule
   ([hidden]{display:none}) loses on specificity to a class selector. */
.ids-enroute-notice-modal[hidden] { display: none !important; }

.ids-enroute-notice-modal-content {
  max-width: 680px;
  width: 100%;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 2rem);
}

.ids-enroute-notice-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}
.ids-enroute-notice-modal-title { margin: 0; }
.ids-enroute-notice-modal-subtitle {
  margin: 0.15rem 0 0;
  font-size: 0.78rem;
}
.ids-enroute-notice-modal-close {
  font-size: 1.25rem;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  flex: 0 0 auto;
}

/* ---- Tabs ---- */
.ids-enroute-notice-modal-tabs {
  display: flex;
  gap: 0.4rem;
  padding: 0.35rem;
  margin: 0.5rem 1.25rem 0;
  background: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.ids-enroute-notice-modal-tab {
  flex: 1 1 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 0.45rem 0.75rem;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  text-align: left;
  color: var(--muted-foreground);
  transition: background var(--transition-fast),
              color var(--transition-fast),
              border-color var(--transition-fast),
              box-shadow var(--transition-fast);
}
.ids-enroute-notice-modal-tab:hover {
  color: var(--foreground);
  background: rgba(255, 255, 255, 0.04);
}
.ids-enroute-notice-modal-tab.is-active {
  background: var(--card);
  color: var(--foreground);
  border-color: var(--border);
  box-shadow: var(--shadow-xs);
}
.ids-enroute-notice-modal-tab:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: 2px;
}
.ids-enroute-notice-modal-tab-label {
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
}
.ids-enroute-notice-modal-tab-hint {
  font-size: 0.7rem;
  color: var(--muted-foreground);
  font-weight: 500;
}
.ids-enroute-notice-modal-tab.is-active .ids-enroute-notice-modal-tab-hint {
  color: var(--brand);
}

/* ---- Form body / scroll ---- */
.ids-enroute-notice-modal-body {
  overflow-y: auto;
  padding-top: 1rem;
}

/* ---- Section heading inside PIREP form ---- */
.ids-enroute-notice-modal-section-title {
  margin: 0.25rem 0 0.5rem;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
}

/* ---- Auto-built raw report textarea (readonly preview) ---- */
.ids-enroute-notice-modal-raw {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.8rem;
  background: rgba(255, 255, 255, 0.03);
  color: var(--foreground);
  cursor: text;
  resize: vertical;
}
.ids-enroute-notice-modal-raw:read-only {
  opacity: 1;
}

/* ---- Optional weather-fields <details> ---- */
.ids-enroute-notice-modal-details {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.02);
  margin-bottom: 1rem;
  overflow: hidden;
}
.ids-enroute-notice-modal-details[open] {
  background: rgba(255, 255, 255, 0.03);
}
.ids-enroute-notice-modal-details-summary {
  cursor: pointer;
  list-style: none;
  padding: 0.6rem 0.85rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--foreground);
  user-select: none;
  transition: background var(--transition-fast);
}
.ids-enroute-notice-modal-details-summary::-webkit-details-marker { display: none; }
.ids-enroute-notice-modal-details-summary:hover {
  background: rgba(255, 255, 255, 0.04);
}
.ids-enroute-notice-modal-details-summary:focus-visible {
  outline: 2px solid var(--brand-ring);
  outline-offset: -2px;
}
.ids-enroute-notice-modal-details-caret {
  font-size: 0.85rem;
  color: var(--muted-foreground);
  transition: transform var(--transition-fast);
}
.ids-enroute-notice-modal-details[open] .ids-enroute-notice-modal-details-caret {
  transform: rotate(180deg);
}
.ids-enroute-notice-modal-details-body {
  padding: 0.85rem 0.85rem 0.25rem;
  border-top: 1px solid var(--border);
}

/* ---- Status line (success / warning / error / pending) ---- */
.ids-enroute-notice-modal-status {
  margin-top: 0.5rem;
  min-height: 1.25rem;
  font-variant-numeric: tabular-nums;
}
.ids-enroute-notice-modal-status.is-pending { color: var(--muted-foreground); }
.ids-enroute-notice-modal-status.is-success { color: var(--success); }
.ids-enroute-notice-modal-status.is-warning { color: var(--warning); }
.ids-enroute-notice-modal-status.is-error { color: var(--danger); }
