/* CRAFT Crew Pairing — same visual system as the ops wall (liquid glass, dark,
   IBM Plex Sans, validated tail colours). Since 2026-08-28 the Pairing Board IS
   the wall's four-quadrant stage at desk scale (operator-specified): schedule,
   pilot map, suggestions, duty & flight — the whole board fits the viewport and
   each quadrant scrolls itself. The Roster tab keeps normal page flow. */

:root {
  --page: #05070c;
  --surface: rgba(255, 255, 255, 0.045);
  --card: rgba(255, 255, 255, 0.05);
  --ink: #ffffff;
  --ink-2: #c9cdd7;
  --muted: #8b93a4;
  --grid: rgba(255, 255, 255, 0.07);
  --line: rgba(255, 255, 255, 0.15);
  --hair: rgba(255, 255, 255, 0.10);
  --glass-edge: rgba(255, 255, 255, 0.10);

  --blue: #3987e5;      /* POD1 */
  --orange: #d95926;    /* POD2 */
  --aqua: #199e70;      /* POD3 */
  --yellow: #c98500;    /* POD5 */
  --magenta: #d55181;   /* POD6 */

  --good: #0ca30c;
  --warn: #fab219;
  --serious: #ec835a;
  --crit: #d03b3b;
  --violet: #9085e9;

  --cat-live: #8ede9b;
  --cat-repo: #4ecdc4;
  --cat-owner: #bda6f5;

  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: var(--page); height: 100%; }
/* The page is a STAGE now: chrome row, the quadrant board filling what is
   left, a one-line footer. Nothing scrolls at page level — each quadrant
   (and the Roster tab) scrolls itself. */
body {
  font-family: var(--sans);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  height: 100vh; overflow: hidden;
  display: flex; flex-direction: column;
  background:
    radial-gradient(1100px 600px at 15% -10%, rgba(57, 135, 229, 0.10), transparent 60%),
    radial-gradient(900px 520px at 95% 5%, rgba(144, 133, 233, 0.07), transparent 55%),
    var(--page);
}

main { flex: 1; min-height: 0; width: 100%; padding: 8px 14px 0; }
.view { height: 100%; }
.view[hidden] { display: none; }
/* The roster keeps normal page flow inside its own scroller. */
#view-roster { overflow-y: auto; max-width: 1200px; margin: 0 auto; padding-bottom: 24px;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.18) transparent; }

/* ---- header: brand, tabs and feed status on ONE row — every strip of chrome
   height comes straight out of the quadrants ---- */
.top {
  flex: none;
  /* Clears the pinned application switch, which overlays the page rather than
     sitting in it — see the CRAFT application switch block. */
  padding: 50px 20px 4px;
  display: flex; align-items: center; gap: 18px;
}
.brand { font-weight: 700; font-size: 18px; letter-spacing: 0.06em; }
.brand span { color: var(--muted); font-weight: 500; }

/* ================= CRAFT application switch =================
   THIS BLOCK IS DUPLICATED VERBATIM IN craft-crew-pairing/css/pairing.css.
   The two applications are separate deployments with separate stylesheets, and
   the whole point of the control is that it does not move when you cross
   between them — so the rules have to be identical rather than merely similar.
   Change one, change the other.

   Pinned to the viewport, not to either page's layout: this board scales a
   3840x2160 stage to fit, and anything inside that scaling would have rendered
   at a different size on the other side of the link. Horizontally centred,
   which on the physical wall is the vertical bezel between the two upper TVs,
   so the split between the halves lands in the gap and each screen carries one
   whole label. */
.app-switch {
  position: fixed; top: 18px; left: 50%; transform: translateX(-50%); z-index: 60;
  /* EQUAL HALVES, via two 1fr columns rather than by letting each label size
     itself: "Crew Pairing" is a wider word than "Dashboard", so content-sized
     halves put the divider off the centre line. Grid gets it exact. */
  display: inline-grid; grid-template-columns: 1fr 1fr; gap: 3px; padding: 3px;
  border-radius: 999px;
  background: linear-gradient(158deg,
    rgba(255, 255, 255, 0.075) 0%, rgba(255, 255, 255, 0.025) 45%, rgba(255, 255, 255, 0.05) 100%);
  backdrop-filter: blur(26px) saturate(1.45);
  -webkit-backdrop-filter: blur(26px) saturate(1.45);
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 -1px 0 rgba(255, 255, 255, 0.04),
    0 7px 19px rgba(0, 0, 0, 0.42);
}
.app-tab {
  font: 700 11px/1 "IBM Plex Sans", system-ui, sans-serif;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.52); text-decoration: none;
  border: 1px solid transparent; border-radius: 999px;
  padding: 6px 20px; cursor: pointer; text-align: center; white-space: nowrap;
  transition: color 0.15s ease, background 0.2s ease;
}
/* The board you are on: a brighter piece of the same glass, lifted off the
   trough by its own highlight rather than by a flat fill. */
.app-tab.on {
  color: #fff; cursor: default;
  background: linear-gradient(158deg,
    rgba(255, 255, 255, 0.17) 0%, rgba(255, 255, 255, 0.08) 55%, rgba(255, 255, 255, 0.13) 100%);
  border-color: rgba(255, 255, 255, 0.10);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 1px 5px rgba(0, 0, 0, 0.30);
}
@media (hover: hover) { .app-tab:not(.on):hover { color: rgba(255, 255, 255, 0.82); } }
/* No narrow-screen override any more: at half size the control already fits a
   375px phone with room to spare, and a second set of numbers is a second
   thing to keep in step across two repositories. */
/* Hidden while the board is full screen. That is the wall's unattended state —
   four TVs with nobody in front of them — and the switch would be the only
   chrome left floating over an otherwise edge-to-edge board. Harmless on Crew
   Pairing, which never sets the flag. */
:root[data-fs="on"] .app-switch { display: none; }
/* ================= end CRAFT application switch ================= */

.feedchip {
  margin-left: auto; font-family: var(--mono); font-size: 12px;
  padding: 5px 10px; border-radius: 8px; border: 1px solid var(--line);
  color: var(--muted); background: var(--surface); white-space: nowrap;
}
.feedchip.is-live { color: #7fd18a; border-color: rgba(127, 209, 138, 0.4); }
.feedchip.is-err { color: var(--serious); border-color: rgba(236, 131, 90, 0.45); }

/* ---- tabs (inside .top now) ---- */
.tabs { display: flex; gap: 4px; }
.tab {
  font: 600 13.5px var(--sans); color: var(--muted); background: none;
  border: none; border-bottom: 2px solid transparent;
  padding: 5px 12px; cursor: pointer;
}
.tab:hover { color: var(--ink-2); }
.tab.is-on { color: var(--ink); border-bottom-color: var(--blue); }

/* ================= the four quadrants ================= */
#view-board.quads {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* The top row runs slightly deep: the schedule must seat all five tails at
     once in week view (operator-specified 2026-08-29), and the map enjoys the
     height; the bottom quadrants scroll comfortably. */
  grid-template-rows: 8fr 7fr;
  gap: 12px;
  min-height: 0;
}
#view-board.quads[hidden] { display: none; }
.quad {
  background: linear-gradient(158deg,
    rgba(255, 255, 255, 0.055) 0%,
    rgba(255, 255, 255, 0.02) 42%,
    rgba(255, 255, 255, 0.04) 100%);
  border: 1px solid var(--glass-edge);
  border-radius: 16px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 -1px 0 rgba(255, 255, 255, 0.03),
    0 14px 34px rgba(0, 0, 0, 0.35);
  padding: 0 12px 10px;
  display: flex; flex-direction: column;
  overflow: hidden; min-height: 0;
  position: relative;
}
.qhead {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 2px 6px;
  border-bottom: 1px solid var(--grid);
  flex: none;
}
.qhead h2 {
  font: 700 12.5px var(--sans); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-2); white-space: nowrap;
}
.qhead-note { font-size: 11px; color: var(--muted); margin-left: auto; }
/* A quadrant's scrolling body. */
.q-scroll {
  flex: 1; min-height: 0; overflow-y: auto; padding: 6px 2px 2px;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
/* Below a desk-sized window the grid stacks and the page scrolls again —
   quadrants keep a working height instead of becoming letterbox slits. */
@media (max-width: 1020px) {
  body { overflow: auto; height: auto; }
  #view-board.quads { display: flex; flex-direction: column; }
  .quad { min-height: 430px; }
}

/* ---- schedule rail (ported from the ops wall's schedule quadrant; same
   classes, same geometry, same tones — the svg viewBox is the wall's 1810×920,
   scaled to its quadrant, so it reads identically at any width) ---- */
.sched-head .dateline { white-space: nowrap; font: 700 11.5px var(--sans); letter-spacing: 0.1em; color: var(--ink-2); }
.rail-range { font: 12px var(--sans); color: var(--muted); white-space: nowrap; flex: none; }
.rail-group { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.rail-btn {
  font: 700 11px var(--sans); letter-spacing: 0.08em;
  color: var(--ink-2); background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 3px 9px; cursor: pointer; white-space: nowrap; flex: none;
}
.rail-live { min-width: 64px; }
.rail-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.12); }
.rail-live.on { color: #0d1117; background: var(--good); border-color: var(--good); }
.rail-btn.on:not(.rail-live) { color: var(--ink); background: rgba(57, 135, 229, 0.30); border-color: rgba(57, 135, 229, 0.55); }
.hint-sug { color: var(--warn); font-weight: 700; }
/* The schedule fills its quadrant: the SVG keeps the wall's aspect and
   letterboxes; the week grid scrolls inside the same box. */
.sched-wrap { position: relative; flex: 1; min-height: 0; }
#schedsvg { width: 100%; height: 100%; display: block; cursor: grab; touch-action: pan-y; }
#schedsvg.dragging { cursor: grabbing; }
.tailpills { display: inline-flex; gap: 6px; flex: none; }
.tp {
  display: inline-flex; align-items: center; gap: 5px;
  font: 700 11px var(--sans); letter-spacing: 0.05em; color: var(--ink-2);
  background: rgba(255, 255, 255, 0.06); border: 1px solid var(--line);
  border-radius: 999px; padding: 2.5px 10px; cursor: pointer; white-space: nowrap;
}
.tp i { width: 8px; height: 8px; border-radius: 50%; }
.tp:hover { background: rgba(255, 255, 255, 0.12); }
.tp.off { opacity: 0.38; }
.tp.off i { background: var(--muted) !important; }
.gut-card { fill: url(#gut-card); stroke: var(--hair); stroke-width: 1; }
.gut-sheen { fill: rgba(255, 255, 255, 0.10); }
.ax-line { stroke: rgba(255, 255, 255, 0.055); stroke-width: 1; }
.ax-label { fill: var(--muted); font: 600 19px var(--sans); }
.lane-sep { stroke: rgba(255, 255, 255, 0.09); stroke-width: 1; }
.g-pod { font: 700 28px var(--sans); fill: var(--ink); }
.g-reg { font: 22px var(--sans); fill: var(--ink-2); }
.g-crew { font: 600 21px var(--sans); fill: var(--ink); }
.g-crew .g-sep { fill: var(--muted); }
.g-nocrew { font: 600 19px var(--sans); fill: var(--muted); letter-spacing: 0.04em; }
.bar-label { font: 600 24px var(--sans); fill: var(--ink); }
.bar-cat { font: 700 15px var(--sans); letter-spacing: 0.1em; }
.bar-trip { font: 600 13px var(--sans); letter-spacing: 0.06em; }
.bar-crew { font: 600 15px var(--sans); }
.day-line { stroke: rgba(255, 255, 255, 0.30); stroke-width: 2; stroke-dasharray: 2 7; }
.day-lbl { font: 700 17px var(--sans); fill: var(--muted); letter-spacing: 0.12em; }
.day-crew { font: 600 15px var(--sans); fill: var(--muted); }
.day-crew.short { fill: #ff9a9a; font-weight: 700; }
.mx-band { stroke-width: 1.5; }
.mx-text { font: 600 21px var(--sans); fill: var(--ink-2); }
.mx-text .mx-aog { fill: var(--ink); font-weight: 700; }
.swap-label { font-weight: 700; fill: #cbd3e0; letter-spacing: 0.12em; }
.now-line { stroke: #ffffff; stroke-width: 2; opacity: 0.55; }
.now-pill { fill: rgba(16, 22, 36, 0.85); stroke: var(--glass-edge); stroke-width: 1.5; }
.now-text { font: 600 20px var(--sans); fill: var(--ink); }
.bar-hit { fill: transparent; cursor: pointer; }
.trip.is-flash { outline: 2px solid var(--blue); outline-offset: 2px; }

/* ---- week grid: Jet Insight's weekly layout — day columns, trips stacked
   vertically per tail per day. Category colours the chip; a dashed amber
   border marks a suggested pairing, same convention as the day strips. ---- */
.week-grid {
  border: 1px solid var(--hair); border-radius: 12px;
  background: rgba(255, 255, 255, 0.015);
  overflow-x: auto; overscroll-behavior-x: contain;
  height: 100%; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
.week-grid[hidden] { display: none; }
.wk-inner { display: grid; width: max-content; min-width: 100%; height: 100%; }
/* If the grid does scroll vertically (short window), the day headers hold
   still. Sticky needs OPAQUE paint — same lesson as the tail column. */
.wk-head { position: sticky; top: 0; z-index: 2; background: #141822; }
.wk-corner { top: 0; z-index: 4; }
/* The tail column holds still while the days scroll under it. Sticky needs an
   OPAQUE ground — the translucent surface let columns show through it — so
   these two carry the page/card colours pre-composited. */
.wk-corner, .wk-gut { position: sticky; left: 0; z-index: 3; }
.wk-corner, .wk-head { padding: 5px 8px; background: var(--surface); border-bottom: 1px solid var(--line); }
/* Opaque grounds, and they must WIN the cascade: the shared rules above and
   below paint the translucent surface, which let scrolled columns ghost
   through the pinned tail cards. */
.wk-corner { background: #141822; }
.wk-head { border-left: 1px solid var(--hair); }
.wk-head .wk-day { font: 700 11px var(--sans); letter-spacing: 0.06em; color: var(--ink); }
.wk-head.wk-today .wk-day { color: #7fd18a; }
.wk-head .wk-counts { display: block; font: 600 9.5px var(--sans); color: var(--muted); margin-top: 1px; }
.wk-head .wk-counts.short { color: #ff9a9a; }
.wk-gut { padding: 6px 8px; border-top: 1px solid var(--hair); background: #141822; border-right: 1px solid var(--line); }
.wk-gut .wk-pod { font: 700 12.5px var(--sans); }
.wk-gut .wk-pod .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }
.wk-gut .wk-reg { font-size: 10px; color: var(--ink-2); margin: 1px 0 3px; }
.wk-gut .wk-gcrew { font: 600 10.5px var(--sans); color: var(--ink); }
.wk-gut .wk-gnone { font-size: 10px; color: var(--muted); }
/* DENSE cells — all five tails and three days share the quadrant (operator-
   specified 2026-08-29): one-line leg pills, the crew once per day under them. */
.wk-cell {
  border-left: 1px solid var(--hair); border-top: 1px solid var(--hair);
  padding: 3px 4px; display: flex; flex-direction: column; gap: 2px;
  /* the row's share of the quadrant is the ceiling; a stacked day scrolls
     inside its own cell rather than stretching every tail's row */
  min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}
.wk-sub, .wk-mx, .wk-clean, .wk-stby, .wk-idle { flex: none; }
.wk-gut { min-height: 0; overflow: hidden; }
/* One crew segment: legs stacked on the left, the crew BOX on the right — the
   two halves split the cell width, and the box runs the exact height of the
   strip stack it crews (operator-specified 2026-08-29). A mid-day crew swap
   is simply a second segment below. Pressing the crew box edits the DAY crew. */
.wk-seg { display: flex; gap: 4px; align-items: stretch; }
.wk-seg + .wk-seg { margin-top: 2px; }
/* strips take 3/4 of the cell, the crew box 1/4 (operator-specified
   2026-08-29) — the extra strip width carries the broker name */
.wk-seg-legs { flex: 3 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wk-pill .wk-pill-bk {
  margin-left: auto; padding-left: 6px; min-width: 0;
  overflow: hidden; text-overflow: ellipsis;
  font: 600 9px var(--sans); font-style: normal; color: var(--ink-2); opacity: 0.85;
}
.wk-seg-crew {
  flex: 1 1 0; min-width: 0; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center;
  border: 1px solid var(--line); border-radius: 6px;
  background: rgba(255, 255, 255, 0.04);
  padding: 0 5px; cursor: pointer;
  font: 600 10px/1.2 var(--sans); color: var(--ink-2); white-space: nowrap;
}
.wk-seg-crew span, .wk-seg-crew i { overflow: hidden; text-overflow: ellipsis; }
.wk-seg-crew:hover { background: rgba(255, 255, 255, 0.11); }
.wk-seg-crew.sug { color: var(--warn); border: 1.5px dashed rgba(250, 178, 25, 0.6); }
.wk-seg-crew.accw { color: #7fd18a; border: 1.5px dashed rgba(127, 209, 138, 0.55); }
.wk-seg-crew i { color: var(--muted); font-style: normal; }
.wk-cell.wk-today-c { background: rgba(127, 209, 138, 0.03); }
/* Strips GROW with their segment: 2–3 trips fill the cell height, more legs
   split the same space into thinner strips (min 13px, never fatter than 30). */
.wk-pill {
  flex: 1 1 auto; min-height: 13px; max-height: 30px; min-width: 0;
  display: flex; align-items: center; overflow: hidden;
  font: 600 9.5px var(--mono); letter-spacing: -0.01em; white-space: nowrap;
  border-radius: 5px; padding: 0 5px; cursor: pointer;
  border: 1px solid; color: var(--ink);
}
.wk-pill:hover { filter: brightness(1.3); }
.wk-pill.cat-live { background: rgba(147, 212, 126, 0.13); border-color: rgba(147, 212, 126, 0.5); }
.wk-pill.cat-repo { background: rgba(78, 205, 196, 0.13); border-color: rgba(78, 205, 196, 0.5); }
.wk-pill.cat-owner { background: rgba(165, 170, 240, 0.13); border-color: rgba(165, 170, 240, 0.5); }
.wk-pill.is-sug { border: 1.5px dashed var(--warn); }
.wk-pill.is-acc { border: 1.5px dashed #7fd18a; }
/* A repo sold with the trip that will NOT be flown: hollow, dashed, faint —
   on the board because Jet Insight carries it, never mistakable for a flight
   somebody is crewing (operator rule, 2026-08-29). */
.wk-pill.is-ghost {
  background: none; border-style: dashed; border-color: var(--line);
  color: var(--muted); opacity: 0.7;
}
/* crew and flags on one wrapping line */
.wk-sub { display: flex; flex-wrap: wrap; align-items: baseline; gap: 1px 7px;
  font: 600 10.5px var(--sans); color: var(--ink-2); }
.wk-sub i { font-style: normal; color: var(--muted); }
.wk-sub .sug { color: var(--warn); }
.wk-sub .accw { color: #7fd18a; }
.wk-bk { font: 600 9.5px var(--sans); letter-spacing: 0.05em; color: #f5c76a; margin-top: 1px; }
.wk-mx {
  border-radius: 6px; padding: 2px 6px; font-size: 10px; color: var(--ink-2);
  background: rgba(232, 131, 126, 0.12); border: 1px dashed rgba(232, 131, 126, 0.55);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wk-mx b { color: var(--ink); }
.week-grid { cursor: grab; touch-action: pan-y; user-select: none; }
.week-grid:active { cursor: grabbing; }
.wk-head[data-day] { cursor: pointer; }
.wk-head[data-day]:hover .wk-day { color: var(--blue); }
.wk-caret { color: var(--muted); font-size: 10px; }
.day-hit { fill: transparent; cursor: pointer; }

/* day roster popup rows */
.dp-list { margin-top: 10px; }
.dp-sec {
  font: 700 11px var(--sans); letter-spacing: 0.12em; color: var(--muted);
  margin: 10px 0 4px; border-bottom: 1px solid var(--hair); padding-bottom: 3px;
}
.dp-row { display: flex; align-items: baseline; gap: 8px; padding: 2.5px 0; font-size: 13px; }
.dp-name { flex: none; width: 86px; font-weight: 600; color: var(--ink); }
.dp-loc { flex: 1; color: var(--ink-2); }
.dp-pod { font-weight: 700; }
.dp-sug { color: var(--warn); font-size: 11px; font-weight: 600; }
.dp-st { flex: none; font: 700 10.5px var(--sans); letter-spacing: 0.06em; color: var(--muted); }
.dp-st.dp-on, .dp-st.dp-sby { color: #7fd18a; }
.dp-st.dp-onh { color: #7fd18a; opacity: 0.75; }
.dp-st.dp-off, .dp-st.dp-ovt { color: var(--warn); }
.dp-st.dp-tvl, .dp-st.dp-trntvl { color: #4ecdc4; }
.dp-st.dp-vac, .dp-st.dp-trn { color: var(--serious); }
.dp-st.dp-onhabroad { color: var(--serious); opacity: 0.8; }

.hint-acc { color: #7fd18a; font-weight: 700; }
.wk-stby {
  border-radius: 6px; padding: 2px 6px; font-size: 10px; font-weight: 600;
  color: var(--ink-2); background: rgba(139, 147, 164, 0.12);
  border: 1px solid rgba(139, 147, 164, 0.45);
}
.wk-stby span { font-size: 9.5px; font-weight: 500; color: var(--muted); }

/* one-line suggestion rows */
.suglist { display: flex; flex-direction: column; gap: 4px; }
#suglist .sug {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--hair); border-radius: 10px; background: var(--surface);
  padding: 6px 12px; cursor: pointer; font-size: 13px;
}
#suglist .sug:hover { background: var(--hair); }
#suglist .sug.is-acc { border-color: rgba(127, 209, 138, 0.45); }
.sug-when { font-weight: 600; color: var(--muted); width: 48px; flex: none; }
.sug-route { color: var(--ink); font-weight: 600; }
/* ---- morning briefing: today's crews at a glance ---- */
.briefing { max-width: 1080px; margin: 18px auto; padding: 0 10px; }
.bf-top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 14px; margin-bottom: 14px; }
.bf-date { font: 700 16px var(--sans); letter-spacing: 0.06em; color: var(--ink); }
.bf-ct { font: 600 12.5px var(--sans); color: var(--ink-2); }
.bf-ct b { color: var(--ink); font-size: 14px; }
/* One vertical card per aeroplane, the whole fleet side by side. */
.bf-cards { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; align-items: start; }
@media (max-width: 1150px) { .bf-cards { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); } }
.bf-card {
  border: 1px solid var(--hair); border-radius: 12px; padding: 12px 14px;
  background: rgba(255, 255, 255, 0.025);
}
.bf-seg { border-top: 1px solid var(--hair); margin-top: 10px; padding-top: 9px; }
.bf-crew2 { font: 600 13px var(--sans); color: var(--ink); }
.bf-crew2.sug { color: var(--warn); }
.bf-crew2.acc { color: #7fd18a; }
/* The numbers the card exists for — big and bright (operator, 2026-08-28). */
.bf-k {
  font: 700 9.5px var(--sans); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); margin-right: 2px; flex: none;
}
.bf-duty {
  margin-top: 7px; display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 13px; color: var(--ink-2);
}
.bf-duty b { font: 700 15px "IBM Plex Mono", var(--sans); color: var(--ink); letter-spacing: 0.01em; }
.bf-len {
  font: 700 14px var(--sans); color: var(--ink);
  background: rgba(255, 255, 255, 0.10); border: 1px solid var(--line);
  border-radius: 6px; padding: 1px 9px;
}
.bf-len.is-amber { color: #0d1117; background: #f5c76a; border-color: #f5c76a; }
.bf-len.is-red { color: #0d1117; background: #ff8f7d; border-color: #ff8f7d; }
.bf-sub { margin-top: 3px; font-size: 12px; color: var(--ink-2); }
.bf-lim {
  margin-top: 6px; display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-2);
}
.bf-lim b { font: 700 14.5px "IBM Plex Mono", var(--sans); color: var(--ink); }
.bf-lim.is-amber, .bf-lim.is-amber b { color: #f5c76a; }
.bf-lim.is-red, .bf-lim.is-red b { color: #ff8f7d; font-weight: 700; }
.bf-card.is-idle { opacity: 0.75; }
.bf-head { display: flex; align-items: baseline; gap: 8px; font-size: 15px; }
.bf-head .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; align-self: center; }
.bf-reg { color: var(--muted); font-size: 12px; }
.bf-crew { margin-left: auto; font: 600 13px var(--sans); color: var(--ink); }
.bf-crew.sug { color: var(--warn); }
.bf-crew.acc { color: #7fd18a; }
.bf-idle { margin-top: 6px; font-size: 12.5px; color: var(--muted); }
.bf-route { margin-top: 6px; font: 600 13px var(--mono, monospace); color: var(--ink-2); }
.bf-duty, .bf-flt { margin-top: 5px; font-size: 12.5px; color: var(--ink-2); }
.bf-duty b, .bf-flt b { color: var(--ink); }
.bf-live { color: #7fd18a; }
.bf-alert { margin-top: 6px; font: 600 12.5px var(--sans); border-radius: 7px; padding: 4px 9px; }
.bf-alert.is-amber { color: #f5c76a; background: rgba(250, 178, 25, 0.10); border: 1px solid rgba(250, 178, 25, 0.35); }
.bf-alert.is-red { color: #ff8f7d; background: rgba(255, 122, 100, 0.10); border: 1px solid rgba(255, 122, 100, 0.45); }
.bf-note { margin-top: 14px; font-size: 11.5px; color: var(--muted); opacity: 0.8; }

.sug-bk {
  flex: none; font: 600 10.5px var(--sans); letter-spacing: 0.03em;
  color: var(--ink-2); background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line); border-radius: 5px; padding: 1.5px 7px;
}
.sug-bk.has-min { color: #f5c76a; border-color: rgba(250, 178, 25, 0.45); }
.sug-bk.is-fail { color: #ff8f7d; border-color: rgba(255, 122, 100, 0.6); }
/* the gantt's fictional repo: faint label, tagged NOT FLOWN */
.bar-ghost { opacity: 0.42; }
.bar-ghost-tag { font: 700 15px var(--sans); letter-spacing: 0.14em; fill: var(--ink-2); }
.tr-ghost {
  margin: 0 0 12px; padding: 7px 10px; font-size: 12.5px; line-height: 1.45;
  color: var(--ink-2); border-radius: 8px;
  background: rgba(139, 147, 164, 0.10); border: 1px dashed rgba(139, 147, 164, 0.5);
}
.tr-ghost b { color: var(--ink); letter-spacing: 0.08em; }
.bar-swap { font: 700 13px var(--sans); letter-spacing: 0.06em; }
.bar-chsw { font: 700 13px var(--sans); letter-spacing: 0.06em; fill: #aeb6c4; opacity: 0.85; }
.wk-swap { font: 700 9.5px var(--sans); letter-spacing: 0.05em; color: #ff8f7d; margin-top: 1px; }
.wk-swap.ok { color: #7fd18a; }
.wk-chsw { font: 700 9.5px var(--sans); letter-spacing: 0.05em; color: #aeb6c4; margin-top: 1px; }
.sug-chsw {
  flex: none; font: 700 10px var(--sans); letter-spacing: 0.05em;
  color: #aeb6c4; background: rgba(174, 182, 196, 0.10);
  border: 1px solid rgba(174, 182, 196, 0.35);
  border-radius: 5px; padding: 1.5px 7px; white-space: nowrap;
}
.sug-swap {
  flex: none; font: 700 10px var(--sans); letter-spacing: 0.05em;
  color: #ff8f7d; background: rgba(255, 122, 100, 0.10);
  border: 1px solid rgba(255, 122, 100, 0.45);
  border-radius: 5px; padding: 1.5px 7px; white-space: nowrap;
}
.sug-swap.ok { color: #7fd18a; background: rgba(127, 209, 138, 0.10); border-color: rgba(127, 209, 138, 0.4); }
.sug-x {
  flex: none; font: 700 10.5px var(--sans); letter-spacing: 0.04em;
  color: var(--ink-2); background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 2px 8px; cursor: pointer; white-space: nowrap;
}
.sug-x:hover { background: rgba(255, 255, 255, 0.12); }
.sug-x.open { color: var(--ink); border-color: rgba(57, 135, 229, 0.55); background: rgba(57, 135, 229, 0.25); }
.sug-ov { color: var(--muted); font-weight: 500; font-size: 11px; }
/* legs sold with the trip that will not be flown */
.sug-ghost {
  flex: none; font: 600 10px var(--sans); letter-spacing: 0.04em;
  color: var(--muted); background: rgba(139, 147, 164, 0.10);
  border: 1px dashed rgba(139, 147, 164, 0.45);
  border-radius: 5px; padding: 1.5px 7px; white-space: nowrap;
}
.sug-leg.is-ghost { opacity: 0.55; }
.lg-ghost { color: var(--muted); font-size: 10.5px; font-style: normal; letter-spacing: 0.04em; }
/* GRID, not wrapping flex: the two seats must sit level on one line, and the
   selects share what is left over so they line up column-wise down the trip
   (operator-specified 2026-08-27 — in the narrow split panel the SIC pair was
   dropping onto a second row). */
.sug-leg {
  display: grid;
  grid-template-columns: auto minmax(84px, auto) auto minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center; gap: 4px 8px;
  margin: 0 0 3px 26px; padding: 5px 10px;
  border-left: 2px solid var(--line); background: rgba(255, 255, 255, 0.02);
  border-radius: 0 8px 8px 0; font-size: 12.5px;
}
.lg-route { font: 600 12.5px var(--sans); color: var(--ink); }
.lg-lab { font: 700 10px var(--sans); letter-spacing: 0.08em; color: var(--muted); }
.lg-sel {
  font: 600 12px var(--sans); color: var(--ink);
  width: 100%; min-width: 0; max-width: 210px; justify-self: start;
  background: rgba(255, 255, 255, 0.06); border: 1px solid var(--line);
  border-radius: 6px; padding: 2.5px 6px;
}
.lg-fixed { font: 600 12px var(--sans); color: var(--ink-2); min-width: 0; }
.lg-fixed i { color: var(--muted); font-size: 10.5px; }
/* Too narrow for six columns (small windows): FOUR columns — time and route
   share the first line, and the second line places label, select, label,
   select into exactly those four cells, level and separate. (A fifth phantom
   column here once dropped the PIC select into an auto column and ran the SIC
   label into it.) */
@media (max-width: 900px) {
  .sug-leg { grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr); }
  .sug-leg > .lg-route { grid-column: 2 / -1; }
}
.sug-crew { color: var(--warn); font-weight: 600; margin-left: auto; }
.sug-crew.acc { color: #7fd18a; }
.sug-warn { color: var(--warn); }
.sug-st { font: 700 10.5px var(--sans); letter-spacing: 0.06em; color: var(--warn); flex: none; }
.sug-st.acc { color: #7fd18a; }
.btn-appr { border-color: rgba(127, 209, 138, 0.5); color: #7fd18a; }
.btn-appr:hover { background: rgba(127, 209, 138, 0.15); color: #fff; }

/* popup pairing controls */
.pp { margin-top: 12px; border-top: 1px solid var(--hair); padding-top: 10px; }
.pp-head { font: 700 11px var(--sans); letter-spacing: 0.12em; color: var(--muted); margin-bottom: 6px; }
.pp-st { color: var(--warn); }
.pp-st.acc { color: #7fd18a; }
.pp-row { display: flex; align-items: center; gap: 10px; padding: 3px 0; }
.pp-row .pp-sel { flex: 1; font-size: 13px; padding: 4px 6px; }
.pp-warn { margin-top: 6px; font-size: 12px; color: var(--warn); }

/* tell the board — the input rides the bottom of the suggestions quadrant;
   the log renders under the suggestion rows in the same scroller */
.talk-row { flex: none; display: flex; gap: 8px; padding: 8px 2px 2px; border-top: 1px solid var(--grid); }
.talk-row input { flex: 1; font-size: 13px; padding: 6px 10px; }
.talk-log { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.tk {
  display: flex; align-items: baseline; gap: 10px; font-size: 12.5px;
  border: 1px solid var(--hair); border-radius: 8px; padding: 5px 10px;
}
.tk-text { color: var(--ink); }
.tk-label { color: #7fd18a; font-size: 12px; }
.tk-held .tk-label { color: var(--muted); font-style: italic; }
.tk-x { margin-left: auto; background: none; border: none; color: var(--muted); cursor: pointer; font-size: 15px; }
.tk-x:hover { color: var(--crit); }

.wk-idle {
  border-radius: 6px; padding: 2px 6px; font-size: 10px; font-weight: 600;
  color: var(--warn); background: rgba(250, 178, 25, 0.07);
  border: 1px dashed rgba(250, 178, 25, 0.45);
}
.wk-clean {
  border-radius: 6px; padding: 2px 6px; font-size: 10px; color: var(--ink-2);
  background: rgba(111, 176, 212, 0.12); border: 1px dashed rgba(111, 176, 212, 0.6);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Trip details popup — the wall's trip-pop, sized for this page. Anchored to
   .sched-wrap and positioned against the strip that was pressed. */
.trip-pop {
  position: absolute; z-index: 40;
  width: 340px; max-width: calc(100% - 24px);
  max-height: calc(100% - 24px); overflow-y: auto;
  padding: 14px 18px 16px;
  border-radius: 16px;
  background: linear-gradient(158deg,
    rgba(255, 255, 255, 0.075) 0%,
    rgba(255, 255, 255, 0.035) 45%,
    rgba(255, 255, 255, 0.055) 100%), rgba(12, 17, 27, 0.90);
  backdrop-filter: blur(30px) saturate(1.5);
  -webkit-backdrop-filter: blur(30px) saturate(1.5);
  border: 1px solid var(--glass-edge);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 -1px 0 rgba(255, 255, 255, 0.04),
    0 20px 55px rgba(0, 0, 0, 0.55);
}
.trip-pop[hidden] { display: none; }
.trip-x {
  position: absolute; top: 8px; right: 10px;
  width: 32px; height: 32px; font: 400 24px/1 var(--sans);
  color: var(--ink-2); background: none; border: none; border-radius: 8px; cursor: pointer;
}
.trip-x:hover { color: var(--ink); background: rgba(255, 255, 255, 0.10); }
.tr-head { display: flex; align-items: baseline; gap: 9px; padding-right: 32px; }
.tr-dot { width: 10px; height: 10px; border-radius: 50%; align-self: center; flex: none; }
.tr-pod { font: 700 20px var(--sans); color: var(--ink); letter-spacing: 0.04em; }
.tr-tail { font: 15px var(--sans); color: var(--ink-2); }
.tr-cat { margin-left: auto; font: 700 11px var(--sans); letter-spacing: 0.12em; }
.tr-cat.cat-live { color: var(--cat-live); }
.tr-cat.cat-repo { color: var(--cat-repo); }
.tr-cat.cat-owner { color: var(--cat-owner); }
.tr-route { font: 600 23px var(--sans); color: var(--ink); margin: 10px 0 12px; }
.tr-route span { color: var(--muted); }
.tr-rows { display: flex; flex-direction: column; gap: 1px; }
.tr-row { display: flex; align-items: baseline; gap: 10px; padding: 4.5px 0; }
.tr-k { flex: none; width: 96px; font-size: 11px; letter-spacing: 0.1em; color: var(--muted); text-transform: uppercase; }
.tr-v { flex: 1; font: 14.5px var(--sans); color: var(--ink); min-width: 0; }
.tr-note { color: var(--muted); font-size: 12.5px; }
.tr-seat { font: 700 10.5px var(--sans); color: var(--muted); letter-spacing: 0.1em; }
.tr-crew { display: block; }
.tr-crew + .tr-crew { margin-top: 2px; }
.tr-loc { font-weight: 600; letter-spacing: 0.06em; color: var(--blue); }
.tr-foot { margin-top: 12px; }
@media (max-width: 760px) {
  .sched-head { grid-template-columns: 1fr auto; }
  .sched-meta { display: none; }
}

/* ---- toolbar / stats ---- */
.toolbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
  padding: 16px 0 14px;
}
.stats { display: flex; gap: 10px; flex-wrap: wrap; }
.stat {
  border: 1px solid var(--hair); background: var(--surface);
  border-radius: 10px; padding: 6px 12px; font-size: 13px; color: var(--ink-2);
}
.stat b { color: var(--ink); font-size: 15px; margin-right: 4px; }
.stat.warn b { color: var(--warn); }
.tools { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.daysel { font-size: 13px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
select, input, textarea {
  font: 500 14px var(--sans); color: var(--ink);
  background: #0d1220; border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 8px;
}
/* the OVT divider in crew pickers: a muted heading over the off-but-callable
   names, never mistakable for the on-duty list above it */
optgroup { font: 700 11px var(--sans); font-style: normal; letter-spacing: 0.06em;
  color: var(--warn); background: #0d1220; }
optgroup option { font: 500 13px var(--sans); color: var(--ink-2); }
select:focus, input:focus, textarea:focus { outline: 1px solid var(--blue); }

.btn {
  font: 600 14px var(--sans); color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 9px; padding: 8px 14px; cursor: pointer;
}
.btn:hover:not(:disabled) { color: var(--ink); background: var(--hair); }
.btn:disabled { opacity: 0.35; cursor: default; }
.foot .is-stale { color: #f5c76a; font-weight: 700; }
.btn-primary { background: rgba(57, 135, 229, 0.30); color: var(--ink); border-color: rgba(57, 135, 229, 0.55); }
.btn-primary:hover { background: rgba(57, 135, 229, 0.45); }
.btn-danger { border-color: rgba(208, 59, 59, 0.5); color: #f0a0a0; }
.btn-danger:hover { background: rgba(208, 59, 59, 0.18); color: #fff; }
.btn-sm { padding: 5px 10px; font-size: 13px; }

.msg { font-size: 13px; color: var(--muted); }
.msg.err { color: var(--serious); }
.msg.ok { color: #7fd18a; }

/* ---- trip cards ---- */
.trips { display: flex; flex-direction: column; gap: 14px; }
.day-head {
  font: 600 13px var(--sans); color: var(--muted); letter-spacing: 0.08em;
  text-transform: uppercase; margin: 14px 0 0; padding-bottom: 4px;
  border-bottom: 1px solid var(--hair);
}
.day-head2 {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  margin: 14px 0 0; padding: 7px 12px;
  border: 1px solid var(--hair); border-radius: 10px; background: var(--surface);
}
.day-head2 .dh-date {
  font: 600 13px var(--sans); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink);
}
.day-head2 .dh-demand { font-size: 12.5px; color: var(--ink-2); }
.day-head2 .dh-crew { font-size: 12.5px; color: var(--muted); }
.day-head2 .dh-crew b { color: var(--ink-2); }
.day-head2 .dh-short {
  margin-left: auto; font: 700 12px var(--sans); letter-spacing: 0.05em;
  color: #ff9a9a;
}
.day-head2.day-short {
  border-color: rgba(208, 59, 59, 0.65); background: rgba(208, 59, 59, 0.10);
}
.day-head2.day-short .dh-date { color: #ffb3b3; }
.day-head2.day-quiet { opacity: 0.55; padding: 4px 12px; }
.flag-broker { color: var(--blue); border-color: rgba(57, 135, 229, 0.45); font-weight: 700; }
.trip {
  border: 1px solid var(--glass-edge); border-radius: 14px;
  background: var(--card); padding: 14px 16px;
}
.trip.is-accepted { border-color: rgba(12, 163, 12, 0.55); }
.trip.is-crewed { opacity: 0.62; }

.trip-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pod {
  font: 700 12px var(--mono); padding: 3px 8px; border-radius: 7px;
  color: #05070c;
}
.pod-POD1 { background: var(--blue); color: #fff; }
.pod-POD2 { background: var(--orange); color: #fff; }
.pod-POD3 { background: var(--aqua); color: #fff; }
.pod-POD5 { background: var(--yellow); color: #fff; }
.pod-POD6 { background: var(--magenta); color: #fff; }
.cat {
  font: 600 11px var(--sans); letter-spacing: 0.06em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 7px; border: 1px solid var(--hair);
}
.cat-live { color: var(--cat-live); }
.cat-repo { color: var(--cat-repo); }
.cat-owner { color: var(--cat-owner); }
.trip-code { font-family: var(--mono); font-size: 13px; color: var(--muted); }
.trip-when { font-size: 14px; color: var(--ink-2); }
.trip-flags { margin-left: auto; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.flag {
  font: 600 11px var(--sans); padding: 3px 8px; border-radius: 7px;
  border: 1px solid var(--hair); color: var(--muted);
}
.flag-warn { color: var(--warn); border-color: rgba(250, 178, 25, 0.4); }
.broker-sel { font-size: 12.5px; padding: 4px 6px; }
.req-line {
  margin-top: 8px; font-size: 12px; color: var(--ink-2); line-height: 1.5;
  border-left: 2px solid var(--line); padding-left: 8px;
}
.req-line b { color: var(--ink); }
.req-note { color: var(--muted); }
.flag-ok { color: #7fd18a; border-color: rgba(127, 209, 138, 0.35); }
.flag-crewed { color: var(--violet); border-color: rgba(144, 133, 233, 0.4); }

.route { margin: 8px 0 4px; font-family: var(--mono); font-size: 14px; color: var(--ink); }
.route .arr { color: var(--muted); padding: 0 3px; }
.legs { font-size: 12.5px; color: var(--muted); line-height: 1.6; }

.seats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.seat {
  border: 1px solid var(--hair); border-radius: 10px; padding: 10px 12px;
  background: var(--surface);
}
.seat-label { font: 700 11px var(--sans); letter-spacing: 0.1em; color: var(--muted); margin-bottom: 6px; }
.seat select { width: 100%; }
.seat-why { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.why {
  font-size: 11.5px; color: var(--ink-2); background: var(--hair);
  border-radius: 6px; padding: 2px 7px;
}
.why.neg { color: #f2b8a2; }
.why.pos { color: #a9e2b0; }
.score { font-family: var(--mono); font-size: 12px; color: var(--muted); margin-left: 6px; }

.trip-actions { display: flex; gap: 8px; margin-top: 12px; align-items: center; }
.trip-status { font: 600 12px var(--sans); letter-spacing: 0.05em; }
.st-open { color: var(--warn); }
.st-proposed { color: var(--blue); }
.st-accepted { color: #7fd18a; }

.empty {
  text-align: center; color: var(--muted); padding: 40px 20px;
  border: 1px dashed var(--line); border-radius: 14px; font-size: 14px;
}

/* ---- banner / importer ---- */
.banner {
  border: 1px solid rgba(250, 178, 25, 0.4); background: rgba(250, 178, 25, 0.07);
  color: var(--ink-2); border-radius: 12px; padding: 12px 14px; font-size: 13.5px;
  margin-bottom: 14px; display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
}
/* display:flex above would defeat the hidden attribute — never show a hidden banner */
.banner[hidden] { display: none; }
.importer {
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
  padding: 14px; margin-bottom: 14px; font-size: 13.5px; color: var(--ink-2);
}
.importer code { font-family: var(--mono); font-size: 12px; color: var(--ink); }
.importer textarea { width: 100%; margin: 10px 0; font-family: var(--mono); font-size: 12.5px; }

/* ---- roster ---- */
.roster { overflow-x: auto; border: 1px solid var(--glass-edge); border-radius: 14px; background: var(--card); }
.roster table { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 980px; }
.roster th {
  text-align: left; font: 600 11px var(--sans); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); padding: 10px 10px;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.roster td { padding: 8px 10px; border-bottom: 1px solid var(--hair); color: var(--ink-2); white-space: nowrap; }
.roster tr:last-child td { border-bottom: none; }
.roster td.name { color: var(--ink); font-weight: 600; }
.tag {
  font: 600 10.5px var(--sans); letter-spacing: 0.05em; padding: 2px 7px;
  border-radius: 6px; border: 1px solid var(--hair); color: var(--muted); margin-left: 6px;
}
.tag-sample { color: var(--warn); border-color: rgba(250, 178, 25, 0.4); }
.tag-ca { color: var(--violet); border-color: rgba(144, 133, 233, 0.45); }
.tag-pri { color: var(--serious); border-color: rgba(236, 131, 90, 0.45); }
.pill-yes { color: #7fd18a; }
.pill-no { color: var(--muted); }
.rot-now { color: #7fd18a; }
.rot-off { color: var(--muted); }
.home-unknown { color: var(--warn); }

/* ---- pilot editor ---- */
.editor {
  border: 1px solid var(--line); border-radius: 12px; background: #0b101c;
  padding: 14px; margin-bottom: 14px;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
}
.editor label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.editor .full { grid-column: 1 / -1; }
.editor .checks { display: flex; gap: 16px; align-items: center; grid-column: 1 / -1; }
.editor .checks label { flex-direction: row; align-items: center; font-size: 13.5px; color: var(--ink-2); }
.editor .actions { grid-column: 1 / -1; display: flex; gap: 8px; align-items: center; }

.foot {
  flex: none; padding: 5px 20px 7px;
  color: var(--muted); font-size: 11px; border-top: 1px solid var(--hair);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

@media (max-width: 760px) {
  .seats { grid-template-columns: 1fr; }
  .editor { grid-template-columns: 1fr 1fr; }
  .tools { margin-left: 0; }
  .feedchip { display: none; }
}

/* ================= quadrant specifics ================= */

/* TL · schedule: the DAY/WEEK/‹/LIVE/›/RE-PAIR cluster sits on the panel's
   CENTRE LINE (operator-specified 2026-08-29). Title and tail pills plus the
   date readouts measure ~1030px together, which does not share a row with the
   controls until the quadrant is very wide — so the controls take a centred
   line of their own, and only claim the middle column of row one on a screen
   with the width to hold all three. Padding is trimmed to pay for the row. */
.q-sched .qhead { padding: 4px 2px 5px; }
.q-sched .sched-head {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  align-items: center; gap: 2px 10px;
}
/* Row one names the panel and says what is on screen; the tail pills are
   controls, so this cell sizes to its content and is never clipped. */
.sched-title {
  grid-row: 1; grid-column: 1;
  display: flex; align-items: center; gap: 8px;
}
.sched-read {
  grid-row: 1; grid-column: 2; justify-self: end;
  display: flex; align-items: baseline; gap: 8px;
  min-width: 0; overflow: hidden; white-space: nowrap;
}
/* Row two is the controls, centred on the panel across its whole width. */
.q-sched .rail-group { grid-row: 2; grid-column: 1 / -1; justify-self: center; margin-left: 0; }

/* BL · suggestions */
.q-sug .rail-group { margin-left: 0; }
.q-tools { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.q-tools .btn { padding: 4px 10px; font-size: 12px; border-radius: 8px; }
.q-tools .daysel { font-size: 11.5px; }
.q-tools select { padding: 2.5px 6px; font-size: 12px; }
.q-sug .stats { flex: none; padding: 6px 0 2px; gap: 6px; }
.q-sug .stat { padding: 2.5px 9px; font-size: 11.5px; border-radius: 8px; }
.q-sug .stat b { font-size: 13px; }

/* BR · duty & flight: the briefing's five vertical cards, quadrant-sized */
.q-brief .briefing { max-width: none; margin: 0; padding: 0 0 6px; }
.q-brief .bf-top { margin: 2px 0 8px; gap: 10px; }
.q-brief .bf-cards { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 1500px) {
  .q-brief .bf-cards { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
}
.q-brief .bf-card { padding: 9px 10px; }
.q-brief .bf-duty b { font-size: 13px; }
.q-brief .bf-len { font-size: 12.5px; padding: 1px 7px; }
.q-brief .bf-lim b { font-size: 12.5px; }
.q-brief .bf-note { margin-top: 8px; }

/* ================= TR · pilot & fleet map ================= */
/* Darker pane so the chart reads through it — the wall's map quadrant. */
.quad-map {
  padding: 0;
  background: linear-gradient(158deg,
    rgba(10, 15, 26, 0.72) 0%, rgba(7, 11, 19, 0.55) 50%, rgba(10, 15, 26, 0.68) 100%);
}
.q-map .qhead {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  padding: 8px 12px 6px; border-bottom: none;
  pointer-events: none;               /* never blocks a map drag… */
}
.q-map .qhead .rail-btn { pointer-events: auto; }   /* …but its buttons do work */
.map-note { font-size: 10.5px; color: var(--muted); margin-left: auto; }
.map-wrap { position: absolute; inset: 0; cursor: grab; overflow: hidden; }
.map-wrap.grabbing { cursor: grabbing; }
#pilotmap { width: 100%; height: 100%; display: block; }
#pm-view { will-change: transform; }
.gratic { stroke: rgba(255, 255, 255, 0.04); stroke-width: 1; fill: none; vector-effect: non-scaling-stroke; }
.land { fill: #121927; stroke: rgba(160, 180, 215, 0.22); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.states { fill: none; stroke: rgba(255, 255, 255, 0.09); stroke-width: 1; vector-effect: non-scaling-stroke; }
.map-ctl {
  position: absolute; left: 10px; bottom: 10px; z-index: 2;
  display: flex; flex-direction: column; gap: 6px;
}
.map-btn {
  width: 30px; height: 30px; border-radius: 9px;
  font: 600 16px/1 var(--sans); color: var(--ink-2);
  background: rgba(16, 22, 36, 0.8); border: 1px solid var(--line); cursor: pointer;
}
.map-btn:hover { background: rgba(255, 255, 255, 0.14); color: var(--ink); }
.map-btn.on { color: var(--blue); border-color: rgba(57, 135, 229, 0.55); }
/* routes: the airborne leg solid in the tail colour, the rest of today faint */
.pm-route { fill: none; stroke-width: 2.5; vector-effect: non-scaling-stroke; opacity: 0.85; }
.pm-route.later { opacity: 0.28; stroke-dasharray: 6 7; }
/* symbols counter-scale on zoom (data-x/data-y + scale(1/k), the wall's way) */
.pm-apt-dot { fill: #8b93a4; stroke: #0a0f1a; stroke-width: 2; }
.pm-apt { fill: var(--muted); font: 600 19px var(--sans); letter-spacing: 0.04em; }
.pm-name { font: 600 23px var(--sans); }
.pm-fld { font: 600 19px var(--sans); fill: var(--muted); }   /* field code beside a merged-list name */
.pm-more { font: 600 20px var(--sans); fill: var(--muted); }
.pm-plane-label { font: 700 24px var(--sans); fill: var(--ink); }
.pm-plane-crew { font: 600 21px var(--sans); fill: var(--ink-2); }
.pm-plane-mx { fill: var(--serious); font-weight: 700; }
/* duty-state tints, shared by map names and the abroad box */
.st-on, .st-sby { fill: #7fd18a; color: #7fd18a; }
.st-onh, .st-onhabroad { fill: #5fae6c; color: #5fae6c; }
.st-tvl, .st-trntvl { fill: #4ecdc4; color: #4ecdc4; }
.st-trn { fill: #ec835a; color: #ec835a; }
.st-off { fill: #9aa2b4; color: #9aa2b4; }
.st-vac { fill: #9085e9; color: #9085e9; }
.st-ovt { fill: #fab219; color: #fab219; }
.st-x { fill: #6b7383; color: #6b7383; }
/* Pilots whose spot is outside the chart (based abroad — LLBG and friends):
   a pinned list so nobody silently falls off the edge of the projection. */
.pm-abroad {
  position: absolute; right: 10px; bottom: 10px; z-index: 2; max-width: 250px;
  background: rgba(12, 17, 27, 0.87); border: 1px solid var(--glass-edge);
  border-radius: 10px; padding: 7px 10px; font-size: 11.5px; color: var(--ink-2);
}
.pm-abroad[hidden] { display: none; }
.pm-abroad h4 { font: 700 9.5px var(--sans); letter-spacing: 0.12em; color: var(--muted); margin-bottom: 3px; }
.pm-ab-row { display: flex; gap: 8px; align-items: baseline; padding: 1px 0; }
.pm-ab-row b { color: var(--ink); font-weight: 600; }
.pm-ab-loc { color: var(--muted); }
.pm-ab-st { margin-left: auto; font: 700 9.5px var(--sans); letter-spacing: 0.06em; }

/* A sold-but-not-flown leg keeps its place in the week cell; the space where
   its crew would go says plainly that nobody is on it. */
.wk-seg-crew.is-ghost {
  cursor: default; border-style: dashed; border-color: rgba(139, 147, 164, 0.4);
  background: none; color: var(--muted); opacity: 0.75;
}
.wk-seg-crew.is-ghost:hover { background: none; }
/* the struck-through hop in an approval row's route */
.rt-ghost { font-style: normal; color: var(--muted); }

/* Standby: the crew the engine put with an aeroplane that is not flying.
   An idle serviceable tail is for sale (ASAP trips appear with no notice), so
   it carries a crew like any other — amber dashed while it is a suggestion,
   green once approved, plain when the crew is simply still with the aircraft. */
.wk-stby.is-sug { border: 1px dashed var(--warn); color: var(--warn); background: rgba(250, 178, 25, 0.07); }
.wk-stby.is-sug span { color: var(--warn); opacity: 0.8; }
.wk-stby.is-acc { border: 1px dashed rgba(127, 209, 138, 0.6); color: #7fd18a; background: rgba(127, 209, 138, 0.07); }
.wk-stby.is-acc span { color: #7fd18a; opacity: 0.8; }
.wk-stby[data-sby], .wk-idle[data-sby] { cursor: pointer; }

/* Crew boxes are DRAGGABLE: pick one up and drop it on another to swap the
   two crews (operator-specified 2026-09-02). A standby box presses open just
   like a flying day's crew box. */
.week-grid.is-crewdrag, .week-grid.is-crewdrag [data-cb] { cursor: grabbing; }
[data-cb].is-dragging { opacity: 0.35; }
[data-cb].is-drop {
  outline: 2px solid var(--blue); outline-offset: 1px;
  background: rgba(57, 135, 229, 0.2) !important;
}
.wk-drag-ghost {
  position: fixed; z-index: 60; pointer-events: none; white-space: nowrap;
  padding: 5px 9px; border-radius: 7px;
  background: rgba(12, 17, 27, 0.95); border: 1px solid var(--blue);
  color: var(--ink); font: 600 11px var(--sans);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
/* a seat the scheduler set by hand reads solid where a suggestion is dashed */
.wk-seg-crew.is-hand, .wk-stby.is-hand { border-style: solid; }
.sched-toast {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 45;
  padding: 7px 14px; border-radius: 9px; white-space: nowrap;
  max-width: calc(100% - 24px); overflow: hidden; text-overflow: ellipsis;
  background: rgba(12, 17, 27, 0.95); border: 1px solid var(--line);
  color: var(--ink); font: 600 12px var(--sans);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
.sched-toast[hidden] { display: none; }

/* ---------- the gate ----------
   Ops and admin only (operator's, 2026-09-09). The server refuses everybody
   else; this is what stops the tool painting first and disappearing after, and
   what turns the refusal into a sentence. */
html[data-access="pending"] body > *:not(.cp-gate),
html[data-access="denied"] body > *:not(.cp-gate) { visibility: hidden; }
.cp-gate {
  position: fixed; inset: 0; z-index: 9000;
  display: flex; align-items: center; justify-content: center;
  background: #0b0d11;
}
/* Load-bearing, exactly as on the dashboard: `display: flex` on a class beats
   the browser's `[hidden] {display:none}`, so without this the gate would stay
   over the tool for the ops users it had just let in. */
.cp-gate[hidden] { display: none; }
.cp-gate-card {
  width: min(420px, 88vw); padding: 34px 32px; text-align: center;
  background: #12151b; border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 14px; box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
}
.cp-gate-head { display: flex; align-items: center; justify-content: center; gap: 8px; }
.cp-gate-brand { font: 700 21px var(--sans, system-ui); letter-spacing: 0.34em; color: #e9edf3; }
.cp-gate-sign {
  padding: 2px 7px; border-radius: 5px; background: rgba(250, 178, 25, 0.16);
  font: 700 12px var(--sans, system-ui); letter-spacing: 0.16em; color: #fab219;
}
.cp-gate-card h2 {
  margin: 16px 0 10px; font: 600 17px var(--sans, system-ui);
  letter-spacing: 0.14em; text-transform: uppercase; color: #aab3c0;
}
.cp-gate-sub { margin: 0 0 20px; font: 400 14px var(--sans, system-ui); line-height: 1.55; color: #8b93a4; }
.cp-gate-sub b { color: #e9edf3; font-weight: 600; }
#cp-gsi { display: flex; justify-content: center; min-height: 44px; }
.cp-gate-err { margin: 14px 0 0; font: 500 13px var(--sans, system-ui); color: #fab219; }
.cp-gate-err.err { color: #d64545; }
/* Says what the rule is, so a refusal never reads as a fault. */
.cp-gate-fine {
  margin: 18px 0 0; padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, 0.07);
  font: 400 12px var(--sans, system-ui); color: #6b7280;
}
