  /* ─── self-hosted type · Operations Atelier ───────────────────────
     Hanken Grotesk (UI) + Geist Mono (codes / dates / money) — variable
     woff2, latin + latin-ext subsets. Self-hosted (no CDN / no FOUT);
     the font-family stacks fall back to the system stack if a fetch ever
     fails, so type degrades gracefully. */
  @font-face {
    font-family: "Hanken Grotesk"; font-style: normal; font-weight: 400 700;
    font-display: swap;
    src: url("fonts/hanken-grotesk-latin.a6b899943e31.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: "Hanken Grotesk"; font-style: normal; font-weight: 400 700;
    font-display: swap;
    src: url("fonts/hanken-grotesk-latin-ext.a3a0917757d7.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: "Geist Mono"; font-style: normal; font-weight: 400 600;
    font-display: swap;
    src: url("fonts/geist-mono-latin.075226e68ad0.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: "Geist Mono"; font-style: normal; font-weight: 400 600;
    font-display: swap;
    src: url("fonts/geist-mono-latin-ext.c2bc2ad5f509.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }

  /* ─── design tokens · Apollo (warm calm palette) ─── */
  :root {
    /* Surfaces — cool light canvas + pure-white cards ("canvas & card"). */
    --bg: #f4f6f8;
    --surface: #ffffff;
    --surface-2: #f1f4f7;
    --surface-3: #e9edf1;

    /* Borders — whisper-light cool grey. */
    --border: #e2e7ec;
    --border-soft: #edf0f3;

    /* Text — charcoal ink; hierarchy carried by weight, not colour. */
    --text: #172029;
    --text-muted: #55606c;
    --text-subtle: #6b7684;

    /* One vibrant, trustworthy blue — the only accent. */
    --accent: #2563eb;
    --accent-deep: #1d4ed8;
    --accent-soft: #eef3ff;

    /* Semantic colours — kept separate from the accent. */
    --success: #15803d;
    --success-soft: #e7f5ec;
    --warning: #b45309;
    --warning-soft: #fbf0e1;
    --danger: #dc2626;
    --danger-soft: #fceceb;
    --bad: var(--danger);  /* alias: 12 templates use var(--bad) for danger/warning glyphs */
    --purple: #7c3aed;
    --purple-soft: #f1ebfe;

    /* Brand — J Navi identity colours (j-navi-website assets/css/style.css:
       --color-sunset-orange / --color-jade-green). The mark itself ships as
       static/dashboards/brand/favicon.svg with its colours baked in; these
       tokens tint what sits around it (the sign-in tile's shadow). The product
       accent above is deliberately NOT the brand orange. */
    --brand-orange: #f8573e;
    --brand-jade: #134245;

    /* Geometry & shadows — ultra-soft, diffuse, cool-tinted. */
    --radius: 10px;
    --radius-sm: 6px;
    --shadow-sm: 0 1px 0 rgba(16, 32, 53, 0.04);
    --shadow: 0 1px 4px rgba(16, 32, 53, 0.06);
    --shadow-md: 0 6px 20px rgba(16, 32, 53, 0.10);
    --shadow-lg: 0 18px 50px rgba(16, 32, 53, 0.22);
    --ring: 0 0 0 3px var(--accent-soft);     /* focus ring */
  }
  main > h1:empty { display: none; }
  .visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  :root {

    /* Shell geometry — the redesigned chrome reads these. */
    --sidebar-w: 234px;
    --sidebar-rail-w: 60px;
    --topbar-h: 50px;
    --ease: cubic-bezier(.4, 0, .2, 1);

    --font: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

    /* Spacing scale — one rhythm for padding, gaps and margins.
       Retuned tighter (density pass) — every token-referencing rule inherits
       this, so the whole app tightens from one source of truth. */
    --space-1: 3px;
    --space-2: 6px;
    --space-3: 10px;
    --space-4: 12px;
    --space-5: 14px;
    --space-6: 18px;
    --leading: 1.4;   /* global line-height token */
    --table-font-size: 13px;   /* dense data tables — titles/body stay larger */
  }

  /* ─── dark theme · "deep slate" cool navy ──────────────────────────
     Toggled by data-theme="dark" on <html> (persisted, restored pre-paint
     in the no-flash IIFE below). Overrides the SAME tokens the whole app
     reads, so every screen re-skins from here. Deep slate (never pure
     black); cards lift to a lighter slate; the blue accent is brightened &
     slightly desaturated so it glows and stays accessible. Tinted
     "soft+ink" component pairs that hard-code an ink colour get explicit
     dark overrides further down (search "dark component overrides"). */
  [data-theme="dark"] {
    --bg: #0f172a;
    --surface: #1e293b;
    --surface-2: #24314a;
    --surface-3: #2c3a54;
    --border: #2a3850;
    --border-soft: #233047;
    --text: #e8edf4;
    --text-muted: #94a3b8;
    --text-subtle: #8b97a8;   /* clears WCAG AA (~5:1) on the deep-slate ground */
    --accent: #5b93ff;
    --accent-deep: #7da9ff;
    --accent-soft: #1b2942;
    --success: #4ade80;
    --success-soft: #14301f;
    --warning: #fbbf24;
    --warning-soft: #3a2a09;
    --danger: #f87171;
    --danger-soft: #3a1c1c;
    --purple: #a78bfa;
    --purple-soft: #2a2440;
    --shadow-sm: 0 1px 0 rgba(0, 0, 0, 0.30);
    --shadow: 0 1px 4px rgba(0, 0, 0, 0.42);
    --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.52);
    --shadow-lg: 0 18px 50px rgba(0, 0, 0, 0.66);
    color-scheme: dark;
  }

  * { box-sizing: border-box; }
  html, body { background: var(--bg); }
  body {
    font-family: var(--font);
    color: var(--text);
    margin: 0;
    line-height: var(--leading);
    font-size: 15px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: background-color .25s var(--ease), color .25s var(--ease);
  }
  code, kbd, pre, .mono, .tour-code { font-family: var(--font-mono); }

  /* ════════════════════════════════════════════════════════════════
     SHELL · "Operations Atelier" — sidebar (3-state) + top bar + chrome
     The sidebar has three desktop states driven by html[data-sidebar]:
       full (default) · rail (60px icons) · hidden (off-canvas).
     On <900px it becomes an off-canvas drawer toggled by body.nav-open.
     ════════════════════════════════════════════════════════════════ */
  body { padding-left: var(--sidebar-w); transition: padding-left .26s var(--ease); }
  html[data-sidebar="rail"]   body { padding-left: var(--sidebar-rail-w); }
  html[data-sidebar="hidden"] body { padding-left: 0; }

  .sidebar {
    position: fixed; inset: 0 auto 0 0;
    width: var(--sidebar-w);
    background:
      linear-gradient(180deg, var(--surface) 0%, var(--bg) 140%);
    border-right: 1px solid var(--border);
    z-index: 50;
    box-shadow: var(--shadow-sm);
    display: flex; flex-direction: column;
    overflow: hidden;
    transition: width .26s var(--ease), transform .26s var(--ease);
  }
  html[data-sidebar="rail"]   .sidebar { width: var(--sidebar-rail-w); }
  html[data-sidebar="hidden"] .sidebar { transform: translateX(-100%); }

  /* faint grain/atmosphere on the rail — restraint, not drama */
  .sidebar::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(120% 60% at 0% 0%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 60%);
    opacity: .6;
  }
  .sidebar > * { position: relative; z-index: 1; }

  /* — head: brand lockup + collapse — */
  .sidebar__head {
    display: flex; align-items: center; gap: 8px;
    padding: 14px 12px 12px 16px;
    border-bottom: 1px solid var(--border-soft);
  }
  .brand {
    display: flex; align-items: center; gap: 10px; min-width: 0;
    text-decoration: none; color: var(--text); flex: 1;
  }
  .brand:hover { text-decoration: none; }
  .brand__mark {
    flex: none; width: 26px; height: 26px; border-radius: 8px;
    display: grid; place-items: center;
    background: linear-gradient(150deg, var(--accent), var(--accent-deep));
    box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 45%, transparent);
    color: #fff;
  }
  .brand__mark svg { display: block; }
  .brand__text {
    display: flex; flex-direction: column; line-height: 1.1; min-width: 0;
    font-weight: 700; font-size: 16px; letter-spacing: -0.02em;
  }
  .brand__text small {
    font-weight: 500; font-size: 10px; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--text-subtle);
  }
  .sidebar__collapse {
    flex: none; width: 26px; height: 26px; padding: 0;
    background: transparent; color: var(--text-subtle);
    border: 1px solid transparent; border-radius: 6px;
    display: grid; place-items: center; cursor: pointer;
    transition: background .12s, color .12s, border-color .12s;
  }
  .sidebar__collapse:hover { background: var(--surface-2); color: var(--text); }
  .sidebar__collapse svg { transition: transform .26s var(--ease); }

  /* — search launcher (opens ⌘K palette) — */
  .nav-search {
    margin: 12px 12px 6px; padding: 7px 10px;
    display: flex; align-items: center; gap: 8px;
    background: var(--surface-2); color: var(--text-subtle);
    border: 1px solid var(--border-soft); border-radius: 8px;
    font: inherit; font-size: 12.5px; font-weight: 500; cursor: text;
    transition: border-color .14s, color .14s, background .14s;
  }
  .nav-search:hover { border-color: var(--accent); color: var(--text); background: var(--surface); }
  .nav-search svg { flex: none; }
  .nav-search .nav-search__txt { flex: 1; text-align: left; }
  .nav-search kbd {
    font-family: var(--font-mono); font-size: 10px; color: var(--text-subtle);
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 4px; padding: 1px 5px;
  }

  /* — scrolling nav body — */
  .sidebar__nav {
    flex: 1; overflow-y: auto; overflow-x: hidden;
    padding: 4px 10px 10px; scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
  }
  .sidebar__nav::-webkit-scrollbar { width: 8px; }
  .sidebar__nav::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }

  /* collapsible group */
  .nav-group { margin-top: 6px; }
  .nav-group > summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: center; gap: 6px;
    padding: 8px 8px 4px; user-select: none;
    font-size: 10px; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--text-subtle);
  }
  .nav-group > summary::-webkit-details-marker { display: none; }
  .nav-group > summary:hover { color: var(--text-muted); }
  .nav-group__chev {
    margin-left: auto; transition: transform .2s var(--ease); flex: none;
    color: var(--text-subtle);
  }
  .nav-group[open] > summary .nav-group__chev { transform: rotate(90deg); }
  .nav-subgroup {
    font-size: 9px; text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--text-subtle); padding: 8px 10px 2px; font-weight: 700; opacity: .75;
  }

  /* nav link */
  .sidebar a {
    position: relative;
    color: var(--text-muted); text-decoration: none;
    padding: 6px 10px; border-radius: 7px;
    font-weight: 500; font-size: 13px;
    display: flex; align-items: center; gap: 10px; white-space: nowrap;
    transition: background-color .13s, color .13s;
  }
  .sidebar a > .nav-ic {
    flex: none; width: 17px; height: 17px; color: var(--text-subtle);
    transition: color .13s, transform .13s;
  }
  /* Monoline icon set — stroke styling inherits into <use> symbol content. */
  .nav-ic, .brand__mark > svg { fill: none; stroke: currentColor;
    stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
  .sidebar a > .nav-tx { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .sidebar a:hover { background: var(--surface-2); color: var(--text); }
  .sidebar a:hover > .nav-ic { color: var(--accent); }
  .sidebar a.active { background: var(--accent-soft); color: var(--accent-deep); font-weight: 600; }
  .sidebar a.active > .nav-ic { color: var(--accent); }
  /* animated "you are here" bar */
  .sidebar a.active::before {
    content: ""; position: absolute; left: -10px; top: 50%;
    width: 3px; height: 17px; transform: translateY(-50%);
    background: var(--accent); border-radius: 0 3px 3px 0;
    animation: navbar-in .28s var(--ease);
  }
  @keyframes navbar-in { from { height: 0; opacity: 0; } to { height: 17px; opacity: 1; } }

  /* — foot: theme + system — */
  .sidebar__foot {
    border-top: 1px solid var(--border-soft);
    padding: 8px 10px; display: flex; flex-direction: column; gap: 2px;
  }
  .sidebar__foot a { font-size: 12px; color: var(--text-subtle); padding: 5px 10px; }
  .sidebar__foot a:hover { color: var(--text); }
  /* "Signed in as …" — a fact, not a link; same row shape as the links. */
  .sidebar__who {
    display: flex; align-items: center; gap: 10px; white-space: nowrap; min-width: 0;
    padding: 5px 10px; font-size: 12px; color: var(--text-subtle);
  }
  .sidebar__who > .nav-ic { flex: none; width: 17px; height: 17px; }
  .sidebar__who > .nav-tx { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .sidebar__who-label { color: var(--text-subtle); opacity: .8; }
  /* Sign out is a POST (Django 5 LogoutView), so it is a <button> styled as the
     nav links are — not the global filled button. */
  .sidebar__signout { margin: 0; }
  .sidebar__signout button {
    position: relative; width: 100%; background: transparent; border: 0; text-align: left;
    color: var(--text-subtle); padding: 5px 10px; border-radius: 7px;
    font-weight: 500; font-size: 12px; line-height: inherit;
    display: flex; align-items: center; gap: 10px; white-space: nowrap;
    transition: background-color .13s, color .13s;
  }
  .sidebar__signout button > .nav-ic { flex: none; width: 17px; height: 17px; color: var(--text-subtle); }
  .sidebar__signout button:hover { background: var(--surface-2); color: var(--text); transform: none; }
  .sidebar__signout button:hover > .nav-ic { color: var(--accent); }

  /* ── RAIL (icon-only) state ── */
  html[data-sidebar="rail"] .sidebar__head { padding: 14px 0 12px; justify-content: center; }
  html[data-sidebar="rail"] .brand { justify-content: center; gap: 0; flex: none; }
  html[data-sidebar="rail"] .brand__text,
  html[data-sidebar="rail"] .sidebar__collapse,
  html[data-sidebar="rail"] .nav-search__txt,
  html[data-sidebar="rail"] .nav-search kbd,
  html[data-sidebar="rail"] .nav-group > summary,
  html[data-sidebar="rail"] .nav-subgroup,
  html[data-sidebar="rail"] .sidebar a > .nav-tx,
  html[data-sidebar="rail"] .sidebar__foot a,
  html[data-sidebar="rail"] .sidebar__who { display: none; }
  html[data-sidebar="rail"] .sidebar__signout button { justify-content: center; padding: 8px; gap: 0; }
  html[data-sidebar="rail"] .sidebar__signout button > .nav-tx { display: none; }
  html[data-sidebar="rail"] .nav-search { justify-content: center; padding: 8px; margin: 12px 10px 4px; }
  html[data-sidebar="rail"] .sidebar__nav { padding: 6px 8px; }
  html[data-sidebar="rail"] .nav-group[open] > .nav-group__items,
  html[data-sidebar="rail"] .nav-group:not([open]) > .nav-group__items { display: flex; flex-direction: column; gap: 2px; }
  html[data-sidebar="rail"] .sidebar a { justify-content: center; padding: 8px; gap: 0; }
  html[data-sidebar="rail"] .sidebar a > .nav-ic { width: 18px; height: 18px; }
  html[data-sidebar="rail"] .sidebar a.active::before { left: -8px; }
  /* tooltip on hover in rail mode */
  html[data-sidebar="rail"] .sidebar a::after {
    content: attr(data-tip); position: absolute; left: calc(100% + 10px); top: 50%;
    transform: translateY(-50%) scale(.96); transform-origin: left center;
    background: var(--text); color: var(--bg); font-size: 12px; font-weight: 600;
    padding: 4px 9px; border-radius: 6px; white-space: nowrap;
    opacity: 0; pointer-events: none; box-shadow: var(--shadow-md); z-index: 60;
    transition: opacity .12s, transform .12s;
  }
  html[data-sidebar="rail"] .sidebar a:hover::after { opacity: 1; transform: translateY(-50%) scale(1); }
  html[data-sidebar="rail"] .sidebar__signout button::after {
    content: attr(data-tip); position: absolute; left: calc(100% + 10px); top: 50%;
    transform: translateY(-50%) scale(.96); transform-origin: left center;
    background: var(--text); color: var(--bg); font-size: 12px; font-weight: 600;
    padding: 4px 9px; border-radius: 6px; white-space: nowrap;
    opacity: 0; pointer-events: none; box-shadow: var(--shadow-md); z-index: 60;
    transition: opacity .12s, transform .12s;
  }
  html[data-sidebar="rail"] .sidebar__signout button:hover::after { opacity: 1; transform: translateY(-50%) scale(1); }

  main { max-width: 1180px; margin: 0 auto; padding: 16px 28px 64px; }

  /* ── top bar (slim utility chrome, sticky) ── */
  .topbar {
    position: sticky; top: 0; z-index: 30;
    height: var(--topbar-h);
    margin: -16px -28px 18px; padding: 0 22px 0 16px;
    display: flex; align-items: center; gap: 8px;
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: saturate(1.4) blur(10px);
    -webkit-backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid var(--border-soft);
  }
  .topbar__crumb {
    font-size: 13px; color: var(--text-muted); font-weight: 500;
    display: flex; align-items: center; gap: 7px; min-width: 0;
  }
  .topbar__crumb b { color: var(--text); font-weight: 600; }
  .topbar__crumb .sep { color: var(--text-subtle); }
  .topbar__spacer { flex: 1; }
  .icon-btn {
    width: 32px; height: 32px; padding: 0; flex: none;
    background: transparent; color: var(--text-muted);
    border: 1px solid transparent; border-radius: 8px;
    display: grid; place-items: center; cursor: pointer;
    transition: background .13s, color .13s, border-color .13s;
  }
  .icon-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-soft); }
  .icon-btn svg { display: block; }
  .icon-btn--lang { width: auto; min-width: 32px; padding: 0 8px; white-space: nowrap; font-size: 12px; }
  .topbar__bell { position: relative; text-decoration: none; margin-left: 8px; }
  .topbar__bell-badge {
    position: absolute; top: -3px; right: -3px; min-width: 15px; height: 15px;
    border-radius: 8px; background: var(--danger); color: #fff;
    font-size: 9px; line-height: 15px; text-align: center; padding: 0 4px;
    border: 1.5px solid var(--surface);
  }
  .topbar .kbd-hint {
    display: inline-flex; align-items: center; gap: 6px;
    height: 32px; padding: 0 10px; border-radius: 8px;
    background: var(--surface); border: 1px solid var(--border);
    color: var(--text-subtle); font-size: 12.5px; cursor: pointer;
    transition: border-color .13s, color .13s;
  }
  .topbar .kbd-hint:hover { border-color: var(--accent); color: var(--text); }
  .topbar .kbd-hint kbd {
    font-family: var(--font-mono); font-size: 10px; color: var(--text-subtle);
    background: var(--surface-2); border: 1px solid var(--border-soft);
    border-radius: 4px; padding: 1px 5px;
  }
  body:not(:has(.toc-rail)) .topbar__toc { display: none; }
  /* theme toggle: show the icon for the CURRENT theme (sun/moon).
     The restore IIFE always sets data-theme explicitly, so key both. */
  .theme-toggle .t-sun, .theme-toggle .t-moon { display: none; }
  [data-theme="light"] .theme-toggle .t-sun { display: block; }
  [data-theme="dark"] .theme-toggle .t-moon { display: block; }
  @media (max-width: 760px) { .kbd-hint__txt, .topbar .kbd-hint kbd { display: none; }
    .kbd-hint { width: 32px; padding: 0; justify-content: center; } }

  /* ── mobile drawer (<900px) ── */
  .nav-backdrop {
    position: fixed; inset: 0; z-index: 49;
    background: rgba(20,16,12,.42); opacity: 0; pointer-events: none;
    transition: opacity .2s var(--ease);
  }
  @media (max-width: 900px) {
    body, html[data-sidebar] body { padding-left: 0; }
    .sidebar, html[data-sidebar="rail"] .sidebar, html[data-sidebar="hidden"] .sidebar {
      width: min(86vw, 300px); transform: translateX(-100%); box-shadow: var(--shadow-lg);
    }
    body.nav-open .sidebar { transform: translateX(0); }
    body.nav-open .nav-backdrop { opacity: 1; pointer-events: auto; }
    /* rail-only cosmetics never apply on mobile — always full text */
    html[data-sidebar="rail"] .brand__text,
    html[data-sidebar="rail"] .nav-search__txt,
    html[data-sidebar="rail"] .nav-group > summary,
    html[data-sidebar="rail"] .sidebar a > .nav-tx { display: revert; }
    html[data-sidebar="rail"] .sidebar a { justify-content: flex-start; padding: 6px 10px; gap: 10px; }
    .topbar { margin: -16px -16px 16px; padding: 0 12px; }
    main { padding: 16px 16px 56px; }
  }
  @media (min-width: 901px) { .topbar__menu { display: none; } }

  /* ── staggered page-load reveal ── */
  @keyframes shell-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
  .nav-group { animation: shell-rise .4s var(--ease) both; }
  .sidebar__nav .nav-group:nth-child(1) { animation-delay: .02s; }
  .sidebar__nav .nav-group:nth-child(2) { animation-delay: .05s; }
  .sidebar__nav .nav-group:nth-child(3) { animation-delay: .08s; }
  .sidebar__nav .nav-group:nth-child(4) { animation-delay: .11s; }
  .sidebar__nav .nav-group:nth-child(5) { animation-delay: .14s; }
  .sidebar__nav .nav-group:nth-child(n+6) { animation-delay: .17s; }
  main > h1 { animation: shell-rise .42s var(--ease) both; animation-delay: .06s; }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .001ms !important; animation-delay: 0s !important; transition-duration: .001ms !important; }
  }

  /* ─── headings ─── */
  h1 {
    margin: 0 0 6px;
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--text);
  }
  h1 small { font-weight: 400; color: var(--text-muted); font-size: 14px; letter-spacing: 0; }
  h2 {
    margin: var(--space-5) 0 var(--space-2);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border-soft);
  }
  h2 small { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--text-subtle); }
  h3 { margin: var(--space-3) 0 var(--space-1); font-size: 14px; font-weight: 600; color: var(--text); }

  /* ─── flash messages ─── */
  .flash {
    background: var(--accent-soft);
    border: 1px solid #cdddfb;
    color: var(--accent-deep);
    padding: 10px 16px;
    border-radius: var(--radius);
    list-style: none;
    margin: 0 0 18px;
  }
  .flash li { padding: 2px 0; }
  .flash--danger {
    background: var(--danger-soft);
    border-color: color-mix(in srgb, var(--danger) 35%, transparent);
    color: var(--danger);
  }

  /* ─── sign-in page · accounts/login.html ───────────────────────────
     Standalone (no shell): the page overrides the body's sidebar gutter and
     main's content width, and otherwise reuses the tokens, type and the
     shared card / input / button rules as they are. The header repeats the
     sidebar's lockup grammar — a tile beside "Apollo / OPERATIONS" — with the
     J Navi mark (brand/favicon.svg, its white tile and orange J baked in) in
     place of the compass, so the first screen and the shell read as one
     product. The tile stays white in both themes, as an app icon does. */
  body.login-page { padding-left: 0; min-height: 100vh; display: grid; place-items: center; }
  .login {
    max-width: none; width: 100%; margin: 0; padding: 32px 16px;
    display: flex; flex-direction: column; align-items: center; gap: 18px;
  }
  .login__card { width: 100%; max-width: 380px; margin: 0; padding: 28px 28px 22px; box-shadow: var(--shadow-md); }
  .login__lockup { display: flex; align-items: center; gap: 12px; margin: 0 0 16px; }
  .login__mark {
    flex: none; width: 44px; height: 44px; display: block;
    border-radius: 9px;   /* matches the rx baked into the SVG at this size */
    box-shadow: 0 1px 0 rgba(16, 32, 53, 0.06), 0 4px 14px color-mix(in srgb, var(--brand-orange) 22%, transparent);
  }
  [data-theme="dark"] .login__mark { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 4px 14px rgba(0, 0, 0, 0.45); }
  .login__wordmark {
    margin: 0; display: flex; flex-direction: column; line-height: 1.1; min-width: 0;
    font-weight: 700; font-size: 20px; letter-spacing: -0.02em; color: var(--text);
  }
  .login__wordmark small {
    font-weight: 500; font-size: 10px; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--text-subtle); margin-top: 3px;
  }
  .login__lede { margin: 0 0 18px; color: var(--text-muted); font-size: 14px; }
  .login__form { display: flex; flex-direction: column; gap: 14px; }
  .login__field { display: flex; flex-direction: column; gap: 5px; }
  .login__submit { width: 100%; padding: 9px 15px; font-weight: 600; margin-top: 4px; }
  .login__help { margin: 16px 0 0; color: var(--text-subtle); font-size: 12px; }
  .login__lang { display: flex; gap: 6px; margin: 0; }
  .login__lang .is-current { font-weight: 700; color: var(--accent-deep); border-color: var(--accent); }

  /* ─── tables ─── */
  table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    margin: 0 0 var(--space-4);
  }
  th, td {
    padding: 4px var(--space-3);
    font-size: var(--table-font-size);
    line-height: 1.35;
    text-align: left;
    vertical-align: top;
    white-space: nowrap;          /* dense single-line rows; wrap exceptions below */
    border-bottom: 1px solid var(--border-soft);
  }
  /* Smart wrap: cells holding free-form or block content keep wrapping so a long
     value never forces the whole table into horizontal scroll. `.wrap` is a
     manual opt-out for plain long-text columns with no wrapping child element. */
  td.wrap, th.wrap,
  td:has(textarea), td:has(details), td:has(ul), td:has(p) { white-space: normal; }
  th {
    background: var(--surface-2);
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
  }
  tr:last-child td { border-bottom: none; }
  tr:hover td { background: var(--bg); }
  td.right, th.right { text-align: right; }
  td.num, th.num { font-variant-numeric: tabular-nums; }
  .empty {
    color: var(--text-subtle);
    font-style: italic;
    text-align: center;
    padding: 32px 14px !important;
  }

  /* ─── pills (status badges) ─── */
  .pill {
    display: inline-block;
    padding: 3px 11px;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 500;
    border: 1px solid var(--border-soft);
    line-height: 1.45;
  }
  /* Tinted status pills carry a darker "ink" text than the matching semantic
     token so the LABEL meets AA contrast on its soft background — the status is
     legible by text, not hue alone (matters for low-vision / colour-blind ops). */
  .pill.ok, .pill.success {
    background: var(--success-soft); color: #1a6b3a; border-color: #c3e3ce; font-weight: 600;
  }
  .pill.warn {
    background: var(--warning-soft); color: #92590a; border-color: #f2d9ae; font-weight: 600;
  }
  .pill.bad, .pill.danger {
    background: var(--danger-soft); color: #b42318; border-color: #f3c5c0; font-weight: 600;
  }
  .pill.info {
    background: var(--accent-soft); color: var(--accent-deep); border-color: #cdddfb;
  }
  .pill.muted {
    background: var(--surface-2); color: var(--text-subtle);
  }
  .pill.purple {
    background: var(--purple-soft); color: var(--purple); border-color: #ddd0f5;
  }
  /* Cancelled lifecycle: a louder red than .pill.bad — operators must
     notice this at a glance because cancellation triggers downstream
     supplier-cancellation work. */
  .pill.cancelled {
    background: #c1281d; color: #fff; border-color: #c1281d; font-weight: 600;
    letter-spacing: 0.02em;
  }

  /* Sticky context bar — persistent code+state companion when scrolling the
     long command center. Quiet at rest; reads as a thin pinned strip. */
  .cc-bar { position: sticky; top: var(--topbar-h); z-index: 19;
    display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
    padding: 6px var(--space-3); margin: 0 0 var(--space-4);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: saturate(1.3) blur(8px); -webkit-backdrop-filter: saturate(1.3) blur(8px);
    border: 1px solid var(--border-soft);
    border-radius: 999px; box-shadow: var(--shadow-sm); }
  .cc-bar__code { font-weight: 600; letter-spacing: 0.01em; font-family: var(--font-mono); font-size: 13px; }
  .cc-bar__metric { font-size: 12.5px; text-decoration: none; padding: 2px 9px; border-radius: 999px; }
  .cc-bar__metric--risk { color: var(--danger); background: var(--danger-soft); }
  .cc-bar__metric--pending { color: var(--accent-deep); background: var(--accent-soft); }
  .cc-bar__metric--ok { color: var(--success); }
  @media print { .cc-bar { position: static; box-shadow: none; } }
  .section-group { font-size: 11px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--accent-deep);
    margin: var(--space-5) 0 var(--space-2); padding-top: var(--space-2);
    border-top: 2px solid var(--accent-soft); }
  .cc-group:first-of-type .section-group { border-top: 0; padding-top: 0; margin-top: var(--space-3); }
  /* Responsive table container — every wide table in <main> is auto-wrapped in
     this (see the wrapTables() script) so columns scroll horizontally instead of
     squishing or clipping. The CSS scroll-shadow gives a clear "more →" affordance
     that appears only while there's content to scroll to. */
  .table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0 0 var(--space-4);
    border-radius: var(--radius);
    background:
      radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.10), rgba(0,0,0,0)),
      radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.10), rgba(0,0,0,0)) 100% 0;
    background-repeat: no-repeat;
    background-size: 16px 100%, 16px 100%;
    background-attachment: scroll, scroll;
  }
  .table-wrap > table { margin-bottom: 0; }
  /* Headers never wrap — they pin each column's minimum width, so a table whose
     columns can't all fit overflows the wrapper (→ scroll) rather than clipping. */
  table th { white-space: nowrap; }
  /* ── Tour command-center "cockpit" header ─────────────────────────
     Identity lives in the page heading; this section is the lifecycle spine,
     a scannable key-facts grid, the PAX cluster, and the Advance action. */
  .cc-metaline { font-size: 11px; color: var(--text-subtle); margin: 0 0 12px; }
  .cc-metaline a { color: var(--text-muted); }
  .cc-head__band { padding: 4px 0 14px; margin-bottom: 16px;
    border-bottom: 1px solid var(--border-soft); }
  .cc-head__band .lc-stepper { margin: 0; }
  .cc-head__grid { display: grid; grid-template-columns: minmax(0,2.2fr) minmax(220px,1fr);
    gap: 12px 24px; align-items: start; }
  @media (max-width: 980px) { .cc-head__grid { grid-template-columns: 1fr; gap: 18px; } }
  /* key-facts: one tight inline bar — label sits beside its value, pairs
     separated by hairlines; people-facts take a slim full row each. */
  .cc-facts--bar { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 0; }
  .fact {
    display: flex; align-items: baseline; gap: 6px; min-width: 0;
    padding: 2px 14px 2px 0; margin-right: 14px;
    border-right: 1px solid var(--border);
  }
  .fact:last-child, .fact--row { border-right: none; margin-right: 0; }
  .fact--row { flex-basis: 100%; padding: 2px 0; }
  .fact__k { font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--text-subtle); font-weight: 700; white-space: nowrap; }
  .fact__v { font-size: 13px; color: var(--text); display: flex; align-items: center;
    gap: 6px; flex-wrap: wrap; line-height: 1.3; min-width: 0; }
  .fact__v .pill { font-size: 11.5px; }
  /* Next-actions panel: one accent container, dense scannable rows. */
  .next-actions {
    border-left: 4px solid var(--accent); background: var(--accent-soft);
    border-radius: var(--radius); padding: 8px 12px; margin-bottom: 14px;
  }
  .next-actions__head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 3px; }
  .next-actions__title { color: var(--accent-deep); font-size: 13px; font-weight: 700; }
  .next-actions__count { color: var(--text-muted); font-size: 11px; }
  .next-actions__list { list-style: none; margin: 0; padding: 0; }
  .next-actions__item {
    display: flex; align-items: center; gap: 8px;
    padding: 1px 0; font-size: 12.5px; line-height: 1.35;
  }
  .next-actions__item .pill {
    min-width: 56px; text-align: center; font-size: 10.5px; padding: 1px 6px; flex: none;
  }
  .next-actions__fix { margin-left: auto; white-space: nowrap; font-size: 11.5px; flex: none; }
  /* PAX cluster */
  .cc-pax__title { margin: 0 0 6px; }
  .cc-pax__table { margin: 0; }
  .cc-pax__table th, .cc-pax__table td { padding: 4px 10px; }
  .cc-pax__table th { width: 1%; white-space: nowrap; background: var(--surface-2);
    font-size: 11px; color: var(--text-muted); }
  .cc-pax__table td { font-variant-numeric: tabular-nums; }
  .cc-pax__table small { color: var(--text-subtle); }
  /* Advance action — the page's primary CTA, lifted out of the facts. */
  .cc-advance { margin-top: 18px; padding: 12px 14px;
    border: 1px solid var(--border); border-left: 3px solid var(--accent);
    border-radius: var(--radius); background: var(--surface-2);
    display: flex; flex-direction: column; gap: 9px; }
  .cc-advance__title { font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--text-subtle); font-weight: 700; }
  .cc-advance__row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
  .cc-advance__go { margin-left: auto; }
  @media (max-width: 600px) { .cc-advance__go { margin-left: 0; } }
  /* Force override — collapsed by default (2026-08-15): forcing is the rare
     exception, and rendering its reason row always doubled the block's height
     for every normal advance. */
  .cc-advance__force > summary { cursor: pointer; font-size: 12px; color: var(--text-muted);
    list-style: none; width: fit-content; }
  .cc-advance__force > summary::-webkit-details-marker { display: none; }
  .cc-advance__force > summary::before { content: "▸ "; }
  .cc-advance__force[open] > summary::before { content: "▾ "; }
  .cc-advance__force[open] > summary { color: var(--warning); font-weight: 500; }
  .cc-advance__force > .cc-advance__row { margin-top: 8px; }
  /* ── Command-center polish (2026-09-11) ──
     Key facts: one aligned label/value grid. The pairs used to sit inline
     behind hairline separators while the people-facts took a full row each —
     two rhythms in one block. `display: contents` lets every .fact's label
     and value land in the shared two columns without touching the markup. */
  .cc-facts--bar { display: grid; gap: 2px 14px; align-items: center;
    grid-auto-rows: minmax(34px, auto);
    grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr); }
  /* Every row is the height of a pill, whether its value is a pill or plain
     text, so the eight facts sit on one rhythm; the label column centres on it. */
  .cc-facts--bar .fact__k { padding-top: 0; line-height: 1; }
  .cc-facts--bar .fact__v { min-height: 26px; align-items: center; }
  /* The popover summaries keep their dashed cue on the action word only
     (.fact__action); a rule under the whole pill read as a stray underline. */
  .cc-facts--bar .info-pop > summary { border-bottom: none; padding: 0; }
  .cc-facts--bar .fact:nth-of-type(odd) .fact__k { padding-left: 0; }
  .cc-facts--bar .fact:nth-of-type(even) .fact__k { padding-left: 12px;
    border-left: 1px solid var(--border-soft); line-height: 1.6; }
  @media (max-width: 760px) {
    .cc-facts--bar { grid-template-columns: max-content minmax(0, 1fr); }
    .cc-facts--bar .fact:nth-of-type(even) .fact__k { padding-left: 0; border-left: 0; }
  }
  .cc-facts--bar > .fact { display: contents; }
  .cc-facts--bar .fact__k { padding-top: 2px; }
  /* Anchored headings land below the sticky topbar + status bar, not under them. */
  [id^="section-"], #staff-overnights, #grp-status, #grp-bookings, #grp-ground, #grp-admin {
    scroll-margin-top: calc(var(--topbar-h) + 60px); }
  /* Section headings carry their tools on one line: the legend popover beside
     the title, any action button pushed to the right edge. */
  .cc-group h2 { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; }
  .cc-group h2 > .btn, .cc-group h2 > button { margin-left: auto; }
  /* An empty section used to render its full column header over a tall
     italic "No X." row — ten times on a fresh tour. Keep the one-line message,
     drop the header row it describes nothing for, and tighten the padding. */
  .cc-group table:has(td.empty) tr:first-child:not(:has(td.empty)) { display: none; }
  .cc-group .empty { padding: 12px 14px !important; text-align: left; font-size: 12.5px; }
  /* The destructive action sits under the primary one; it reads as a quiet
     right-aligned row with a text-red ghost button, not a second red CTA. */
  .cc-quiet-danger { margin: 12px 0 16px; padding: 0 2px; display: flex; align-items: center;
    gap: 16px; justify-content: space-between; flex-wrap: wrap; }
  .cc-quiet-danger .muted { font-size: 12px; line-height: 1.4; flex: 1 1 320px; }
  .cc-quiet-danger > button { order: 2; }
  button.danger-ghost { background: transparent; color: var(--danger); border: 1px solid var(--border); }
  button.danger-ghost:hover { background: var(--danger-soft); border-color: var(--danger); }

  /* Departure GO/no-GO (SiC/Series) — rides the .info-pop popover: the fact
     shows the answer, the form opens over the page instead of pushing it
     down. `guaranteed` is the same fact, so there is only ONE control. */
  .departure-decision > summary { border-bottom: none; display: inline-flex;
    gap: 6px; align-items: center; }
  .departure-decision .info-pop-panel { min-width: 320px; }
  /* An action word inside a fact — pills alone read as a static label, which
     is how the GO/No-Go action became invisible (reported 2026-08-15). */
  .fact__action { font-size: 11px; color: var(--accent); font-weight: 500;
    border-bottom: 1px dashed currentColor; }
  details[open] > summary .fact__action { color: var(--text-muted); }
  /* Lifecycle stepper — "you are here" across the tour lifecycle. */
  .lc-stepper { display: flex; flex-wrap: wrap; list-style: none; margin: 4px 0 10px; padding: 0; }
  .lc-step { display: flex; align-items: center; gap: 5px; font-size: 11px;
    color: var(--text-subtle); position: relative; padding-right: 16px; margin-bottom: 4px; }
  .lc-step:not(:last-child)::after { content: ""; position: absolute; right: 1px; top: 50%;
    width: 14px; height: 1px; background: var(--border); }
  .lc-step__dot { width: 9px; height: 9px; border-radius: 50%; flex: none;
    background: var(--surface); border: 1px solid var(--border); }
  .lc-step--done { color: var(--text-muted); }
  .lc-step--done .lc-step__dot { background: var(--success); border-color: var(--success); }
  .lc-step--current { color: var(--accent-deep); font-weight: 700; }
  .lc-step--current .lc-step__dot { background: var(--accent); border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft); }
  .lc-cancelled { margin: 4px 0 10px; font-size: 12px; color: var(--text-muted);
    display: flex; align-items: center; gap: 8px; }
  /* Inline operator quick-add (New-Tour drawer). */
  .op-quick-add { margin-top: 6px; }
  .op-quick-add > summary { font-size: 11px; color: var(--accent); cursor: pointer; }
  .op-quick-add__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
    margin-top: 6px; align-items: end; }
  .op-quick-add__grid input, .op-quick-add__grid select { width: 100%; }
  .op-quick-add__btn { grid-column: 1 / -1; }
  .op-quick-add__err { color: #b42318; font-size: 11px; margin-top: 4px; }

  /* status row tints (used on whole rows) */
  .severity-Warning { background: var(--warning-soft) !important; }
  .severity-Critical { background: var(--danger-soft) !important; }

  /* ─── buttons ─── */
  button, .btn {
    font: inherit;
    background: var(--accent);
    color: white;
    border: none;
    border-radius: var(--radius-sm);
    padding: 7px 15px;
    cursor: pointer;
    font-weight: 500;
    transition: background-color .15s, transform .15s;
  }
  button:hover, .btn:hover { background: var(--accent-deep); }
  button:active, .btn:active { transform: translateY(1px); }
  button.ghost, .btn.ghost {
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
  }
  button.ghost:hover, .btn.ghost:hover { background: var(--surface-2); border-color: var(--accent); color: var(--accent-deep); }
  button.danger { background: var(--danger); }
  button.danger:hover { background: #b91c1c; }
  button.small, .btn.small { padding: 4px 11px; font-size: 12px; }

  /* ─── inputs ───
     A type-less <input> IS a text input (the HTML default), and type="search"
     is a text input with clear-button semantics — both take the same shared
     control look as type="text". They are matched through :where() so the
     rule carries zero specificity for them: a page's own class rule
     (.guide-search, .hotel-picker__search, …) keeps winning on width,
     padding and font, exactly as it does today. */
  input[type="text"], input[type="date"], input[type="number"], input[type="time"], input[type="email"],
  input[type="password"], input:where(:not([type]), [type="search"]),
  select, textarea {
    font: inherit;
    padding: 7px 11px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    width: 100%;
    transition: border-color .15s, box-shadow .15s;
  }
  input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
  }
  /* Numeric fields hold 1–7 digits — they should never fill a whole grid cell.
     Caps the oversized PAX / price / lead-time / qty boxes app-wide. Opt a field
     back to full width with class="num-wide" if it genuinely needs it. */
  input[type="number"] { width: auto; max-width: 110px; min-width: 64px; }
  input[type="number"].num-wide { width: 100%; max-width: none; }
  /* Reusable pickers size to content, not the full cell. */
  .city-picker { display: inline-flex; gap: 6px; flex-wrap: wrap; align-items: center; }
  .city-picker select, .currency-select, .time-15 { width: auto; }
  .city-picker__city { min-width: 130px; }
  .currency-select { min-width: 92px; }
  .city-country-filter { min-width: 84px; }
  label { color: var(--text-muted); font-size: 12px; font-weight: 500; }

  /* ─── cards ─── */
  .card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--space-3) var(--space-4);
    box-shadow: var(--shadow-sm);
    margin: 0 0 var(--space-3);
  }
  .card .meta { color: var(--text-muted); font-size: 13px; }

  .grid { display: grid; gap: 14px; }
  .grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
  .grid-3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

  .stat {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 16px;
    box-shadow: var(--shadow-sm);
  }
  .stat .label { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
  .stat .value { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; margin-top: 4px; font-variant-numeric: tabular-nums; }
  .stat .sub { color: var(--text-subtle); font-size: 12px; margin-top: 2px; }

  /* ─── routing-sheet day cards ─── */
  .routing { display: grid; gap: 12px; margin: 8px 0 28px; }
  .day-card {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
    box-shadow: var(--shadow-sm);
  }
  .day-head {
    background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface-3) 100%);
    padding: 12px 18px;
    display: flex; align-items: baseline; gap: 14px;
    border-bottom: 1px solid var(--border-soft);
  }
  .day-head .num { font-weight: 700; font-size: 13px; color: var(--accent-deep); min-width: 60px; letter-spacing: 0.02em; }
  .day-head .date { color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: 13px; }
  .day-head .loc { color: var(--text); font-weight: 600; margin-left: auto; font-size: 14px; }
  .day-items { list-style: none; padding: 0; margin: 0; }
  .day-items li {
    display: grid;
    grid-template-columns: 64px 110px 1fr auto;
    gap: 14px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--border-soft);
    align-items: baseline;
    transition: background-color .12s;
  }
  .day-items li:last-child { border-bottom: none; }
  .day-items li:hover { background: var(--surface-2); }
  .day-items .time { color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: 13px; }
  .day-items .dept {
    font-size: 11px;
    color: var(--text-muted);
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--border-soft);
    font-weight: 500;
    white-space: nowrap;
    width: max-content;
  }
  .day-items .dept.Hotel { background: var(--accent-soft); color: var(--accent-deep); }
  .day-items .dept.Bus { background: #e7ebef; color: #475569; }
  .day-items .dept.Transport { background: #e7ebef; color: #475569; }
  .day-items .dept.Guide { background: var(--success-soft); color: var(--success); }
  .day-items .dept.Extras { background: var(--purple-soft); color: var(--purple); }
  .day-items .dept.Operations { background: var(--border-soft); color: var(--text-muted); }
  .day-items .svc { color: var(--text); }
  .day-items .svc small { color: var(--text-subtle); display: block; margin-top: 2px; font-size: 12px; }
  .day-items .badge {
    font-size: 11px; padding: 1px 7px; border-radius: 4px;
    background: var(--warning-soft); color: var(--warning);
    margin-left: 6px; font-weight: 500;
  }
  .day-items .badge.RESERVE { background: var(--accent-soft); color: var(--accent-deep); }
  .day-items .badge.TAXI { background: #e7ebef; color: #475569; }
  .day-items .badge.AUDIO { background: var(--purple-soft); color: var(--purple); }

  /* ─── inline action drawers (<details>) ─── */
  details.card {
    transition: border-color .15s, background .15s;
  }
  details.card > summary {
    list-style: none;
    cursor: pointer;
    color: var(--accent-deep) !important;
    background: var(--accent-soft);
    transition: background .15s, color .15s;
    user-select: none;
  }
  details.card > summary::-webkit-details-marker { display: none; }
  details.card > summary::before {
    content: "›";
    display: inline-block;
    transform: rotate(90deg);
    transition: transform .2s;
    margin-right: 6px;
    font-weight: 700;
    color: var(--accent);
  }
  details.card[open] > summary::before { transform: rotate(180deg); }
  details.card:hover > summary {
    background: var(--accent-soft);
  }
  details.card[open] {
    border-color: var(--accent);
  }
  details.card[open] > summary {
    border-bottom: 1px solid var(--accent-soft);
  }

  /* ─── reservation board / option list ─── */
  .option-list { display: grid; gap: 10px; }
  .option-row {
    display: grid;
    grid-template-columns: 36px 1fr auto auto;
    gap: 14px;
    align-items: center;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    box-shadow: var(--shadow-sm);
  }
  .option-row.confirmed { border-color: #c3e3ce; background: var(--success-soft); }
  .option-row.rejected { opacity: 0.65; }
  .option-row .priority {
    background: var(--accent);
    color: white;
    font-weight: 700;
    font-size: 13px;
    width: 32px; height: 32px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
  }
  .option-row.confirmed .priority { background: var(--success); }
  .option-row.rejected .priority { background: var(--text-subtle); }
  .option-row .hotel-name { font-weight: 600; font-size: 14px; }
  .option-row .meta { color: var(--text-muted); font-size: 12px; margin-top: 2px; }
  .option-row .price { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 500; }

  /* ─── misc ─── */
  a { color: var(--accent); text-decoration: none; }
  a:hover { text-decoration: underline; }
  .row { display: flex; gap: 16px; flex-wrap: wrap; }
  .between { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
  hr { border: none; border-top: 1px solid var(--border-soft); margin: 24px 0; }

  /* Flatpickr: keep its inputs consistent with our other inputs. */
  .flatpickr-input[readonly] { background: var(--surface); cursor: pointer; }

  /* Create-form polish: every "+ Add X" drawer on the tour command center
     uses `<details class="card"><form …>` with a grid layout. These rules
     make inputs fill their grid cells consistently so forms stop looking
     like a scatter of mismatched widths. */
  /* The canonical dashboard form layout: fields auto-pack into as many
     ~210px columns as the container width allows. A form needs only
     class="form-grid" — no per-form grid-template-columns. */
  .form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 10px 14px;
    align-items: end;
  }
  /* Shared filter-bar pattern — one consistent look for the GET filter controls
     across Tours / Statistics / At-risk / boards (previously each rolled its own
     inline styles). Labels stack above their control; the bar wraps on narrow
     screens. */
  .filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 14px;
    align-items: end;
    margin: 0 0 16px;
  }
  .filter-bar > label {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 12px;
    color: var(--text-muted);
  }
  .filter-bar .filter-actions { display: flex; gap: 8px; align-items: end; }

  .routing-form label,
  .form-grid label,
  details.card > form label { display: flex; flex-direction: column; gap: 4px; }
  .routing-form label > input,
  .routing-form label > select,
  .routing-form label > textarea,
  .form-grid label > input,
  .form-grid label > select,
  .form-grid label > textarea,
  details.card > form > label > input,
  details.card > form > label > select,
  details.card > form > label > textarea { width: 100%; box-sizing: border-box; }
  /* Checkbox rows inside a .form-grid stay horizontal (box beside the label). */
  .form-grid label.check { flex-direction: row; align-items: center; gap: 6px; }
  .form-grid label.check > input { width: auto; }

  /* Inline-edit expander: the edit form lives in a full-width accordion row
     below the read-only row instead of squeezed into the last table cell. */
  tr.edit-expander > td {
    background: var(--accent-soft);
    border-bottom: 1px solid var(--border);
    padding: 10px 14px;
  }
  .edit-expander__actions {
    grid-column: 1 / -1;
    display: flex; gap: 8px; align-items: center;
  }
  /* Dense form variant for wide expander rows with mostly small fields. */
  .form-grid--dense {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 6px 10px;
  }
  .form-grid--dense label { font-size: 11.5px; }
  /* Keep logically linked inputs together in one two-column cell. */
  .field-pair { display: flex; gap: 6px; min-width: 0; grid-column: span 2; }
  .field-pair > label { flex: 1; min-width: 0; }

  /* Routing badges: linked dept-workspace records appear next to the service. */
  .routing-badge { display: inline-block; padding: 1px 6px; font-size: 11px;
    border-radius: 3px; background: var(--surface); border: 1px solid var(--border);
    color: var(--text-muted); margin-left: 4px; }
  .routing-badge.ok { background: var(--success-soft); color: var(--success); border-color: var(--success); }
  .task-badge-ok          { background: var(--success-soft); color: var(--success); border-color: var(--success); }
  .task-badge-pending     { background: #fef3e2; color: #92590a; border-color: #f0cf8f; }
  .task-badge-needs_action{ background: #fceceb; color: #b42318; border-color: #f2c1bc; }
  .task-badge-wrap        { display: inline; margin-left: 4px; }
  .task-badge-wrap[open] > summary { background: var(--surface); }
  .task-badge-list { list-style: none; padding: 8px; margin: 6px 0 0; background: var(--surface);
    border: 1px solid var(--border); border-radius: 4px; max-width: 480px; }
  .task-badge-row { display: grid; grid-template-columns: 1fr auto; gap: 4px;
    padding: 4px 0; border-bottom: 1px solid var(--border-soft); }
  .task-badge-row:last-child { border-bottom: none; }
  .task-badge-row small { grid-column: 1; color: var(--text-muted); font-size: 11px; }
  .task-badge-row-done .task-badge-title { text-decoration: line-through; color: var(--text-muted); }
  .day-card.planning { border-left: 3px solid var(--border); }
  .day-card.field { border-left: 3px solid var(--accent); }

  /* ─── Staff overnights grid ─── */
  .staff-grid-wrap { overflow-x: auto; margin: 8px 0 14px; }
  table.staff-grid { border-collapse: separate; border-spacing: 0; min-width: 720px; }
  table.staff-grid th, table.staff-grid td {
    padding: 4px 6px; font-size: 12px;
    border-bottom: 1px solid var(--border-soft); vertical-align: top;
  }
  table.staff-grid th { background: var(--surface-2); color: var(--text-muted);
    font-weight: 600; text-align: center; white-space: nowrap; }
  table.staff-grid th.staff-grid-row-header { text-align: left; min-width: 200px; }
  table.staff-grid td.staff-grid-row-header { font-weight: 500; min-width: 200px;
    white-space: nowrap; }
  .staff-row-kind { display: inline-block; font-size: 10px; padding: 1px 4px;
    border-radius: 2px; background: var(--surface); color: var(--text-muted);
    margin-right: 4px; text-transform: uppercase; letter-spacing: 0.05em; }
  .staff-row-guide   { background: var(--success-soft); color: var(--success); }
  .staff-row-driver  { background: #fdefdc; color: #92590a; }
  .staff-row-shadowing { background: #e1ecfe; color: #1d4ed8; }
  .staff-cell { min-width: 64px; text-align: center; cursor: default; }
  .staff-cell-off          { background: transparent; color: var(--text-subtle); }
  .staff-cell-local        { background: #eef1f4; color: var(--text-muted); font-style: italic; }
  .staff-cell-ok           { background: var(--success-soft); }
  .staff-cell-pending      { background: #fef3e2; }
  .staff-cell-needs_action { background: #fceceb; }
  .staff-cell-external_no_ref { background: #e8f0fe; }
  .staff-cell-popover { position: relative; }
  .staff-cell-popover > summary { list-style: none; cursor: pointer;
    display: block; padding: 2px 4px; border-radius: 2px;
    overflow: hidden; text-overflow: ellipsis; max-width: 80px; }
  .staff-cell-popover[open] > summary { background: var(--surface); }
  .staff-cell-form { position: absolute; top: 100%; left: 0; z-index: 30;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 4px; padding: 10px; box-shadow: 0 4px 14px rgba(0,0,0,0.12);
    display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px;
    min-width: 360px; text-align: left; }
  .staff-cell-form label { display: flex; flex-direction: column; gap: 2px;
    font-size: 11px; color: var(--text-muted); }
  .staff-cell-form label > input,
  .staff-cell-form label > select,
  .staff-cell-form label > textarea { width: 100%; box-sizing: border-box;
    font-size: 12px; }
  .staff-cell-channel { grid-column: 1/-1; display: flex; flex-direction: column;
    gap: 2px; padding: 4px; background: var(--surface-2); border-radius: 3px; }
  .staff-cell-channel label { flex-direction: row; align-items: center; gap: 6px;
    color: var(--text); font-size: 12px; }
  .staff-grid-bulk { white-space: nowrap; }

  /* ─── Tour command center: sticky in-page TOC ─── */
  /* A flush docked rail (not a floating card): full-height, page-coloured,
     with a single hairline divider — so it reads as a quiet third column and
     never looks orphaned when the global sidebar is collapsed/hidden. */
  .toc-rail { position: fixed; top: var(--topbar-h); left: var(--sidebar-w);
    width: 184px; bottom: 0; overflow-y: auto;
    background: var(--bg); border: none; border-right: 1px solid var(--border-soft);
    border-radius: 0; padding: 16px 16px 24px; font-size: 12px;
    box-shadow: none; z-index: 10; scrollbar-width: thin; }
  .toc-rail-title { font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--text-subtle); margin-bottom: 8px;
    font-weight: 700; }
  .toc-rail ul { list-style: none; padding: 0; margin: 0; }
  .toc-rail li { margin: 0; }
  .toc-rail a { display: flex; align-items: center; justify-content: space-between;
    gap: 6px; padding: 3px 4px; border-radius: 3px; color: var(--text);
    text-decoration: none; line-height: 1.4; }
  .toc-rail a:hover { background: var(--surface-2); text-decoration: none; }
  .toc-rail small { color: var(--text-muted); font-weight: normal; }
  .toc-pip { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    flex: 0 0 8px; }
  .pip-ok           { background: var(--success); }
  .pip-pending      { background: #e0982a; }
  .pip-needs_action { background: #dc5656; }
  .pip-none         { background: var(--border); }
  /* Reserve room on the left edge ONLY when a TOC rail is present.
     Without :has(), every page would get the padding (and look weird). */
  @media (min-width: 1240px) {
    body:has(.toc-rail) main { padding-left: 200px; }
  }
  /* Hide the rail on narrow viewports — operators on small screens scroll. */
  @media (max-width: 1239px) { .toc-rail { display: none; } }
  .task-filter-chips { display: flex; gap: 6px; margin: 6px 0 12px; }
  .task-filter-chips .chip { padding: 4px 10px; border: 1px solid var(--border);
    border-radius: 999px; font-size: 12px; color: var(--text-muted);
    text-decoration: none; }
  .task-filter-chips .chip-active { background: var(--accent); color: white;
    border-color: var(--accent); }
  .bulk-action-bar { position: sticky; bottom: 0; display: none;
    background: var(--surface); border-top: 1px solid var(--border);
    padding: 10px 14px; gap: 10px; align-items: center;
    box-shadow: 0 -4px 14px rgba(0,0,0,0.05); }
  .bulk-action-bar input[type="text"] { flex: 1; max-width: 320px; padding: 4px 8px; }

  /* ─── Tour search (lives in the top bar) ────────────────────────────
     Type a tour code (e.g. NAVGIN-01) → pick a result → jump to that
     tour's command center. Compact by default; expands on focus. */
  .tour-search { position: relative; display: flex; align-items: center; }
  .tour-search__icon {
    display: grid; place-items: center;
    width: 32px; height: 32px; flex: none; cursor: text;
    color: var(--text-muted); border-radius: 8px;
    border: 1px solid transparent;
    transition: background .13s, color .13s, border-color .13s;
  }
  .tour-search__icon:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-soft); }
  .tour-search:focus-within .tour-search__icon { color: var(--accent); }
  #tour-search-input {
    width: 0; opacity: 0; border: none; background: transparent;
    font: inherit; font-size: 13px; color: var(--text);
    padding: 5px 0; outline: none;
    transition: width .2s var(--ease), opacity .16s ease, padding .2s var(--ease);
  }
  .tour-search:focus-within #tour-search-input {
    width: 170px; opacity: 1; padding: 5px 4px 5px 2px;
  }
  #tour-search-input::placeholder { color: var(--text-subtle); }
  .tour-search__results {
    position: absolute; top: calc(100% + 8px); right: 0;
    min-width: 260px; max-height: 340px; overflow-y: auto;
    list-style: none; margin: 0; padding: 5px;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 10px; box-shadow: var(--shadow-lg); z-index: 200;
  }
  .tour-search__results[hidden] { display: none; }
  .tour-search__item {
    padding: 7px 10px; border-radius: var(--radius-sm); cursor: pointer;
    display: flex; flex-direction: column; gap: 1px;
  }
  .tour-search__item.sel, .tour-search__item:hover { background: var(--accent-soft); }
  .tour-search__code { font-weight: 600; font-size: 13px; color: var(--text); font-family: var(--font-mono); }
  .tour-search__meta { font-size: 11px; color: var(--text-subtle); }
  .tour-search__empty { padding: 9px; font-size: 12px; color: var(--text-subtle); }
  @media (max-width: 620px) { .tour-search { display: none; } }

  /* ── TOC rail offset tracks the sidebar state ── */
  .toc-rail { left: var(--sidebar-w); transition: left .26s var(--ease); }
  html[data-sidebar="rail"]   .toc-rail { left: var(--sidebar-rail-w); }
  html[data-sidebar="hidden"] .toc-rail { left: 0; border-radius: 0 6px 6px 0; }
  body.toc-hidden .toc-rail { display: none; }
  @media (min-width: 1240px) {
    body.toc-hidden:has(.toc-rail) main { padding-left: 0; }
  }
  @media (max-width: 900px) { html[data-sidebar] .toc-rail { left: 0; } }

  /* ─── Click-to-reveal info popover (native <details>) ─────────────
     Trigger is an inline dashed-underline "summary" link. Expanded
     panel is absolutely positioned so opening it never reflows the
     surrounding line. Used wherever a small "what is this?" needs
     to be tucked next to a label. */
  .info-pop { position: relative; display: inline-block;
              vertical-align: baseline; font-size: 11px; font-weight: 400; }
  .info-pop > summary { cursor: pointer; color: var(--text-muted);
                        list-style: none;
                        border-bottom: 1px dashed var(--border);
                        padding: 0 1px; }
  .info-pop > summary::-webkit-details-marker { display: none; }
  .info-pop > summary:hover,
  .info-pop[open] > summary { color: var(--text);
                              border-bottom-color: var(--text-muted); }
  .info-pop-panel { position: absolute; top: calc(100% + 6px); left: 0;
                    z-index: 20; min-width: 260px; max-width: 460px;
                    padding: 10px 12px; background: var(--surface);
                    border: 1px solid var(--border); border-radius: 4px;
                    box-shadow: 0 4px 14px rgba(0,0,0,0.08);
                    color: var(--text); font-size: 12px; line-height: 1.5;
                    white-space: normal; }
  .info-pop-panel strong { color: var(--text); font-weight: 600; }

  /* ─── command palette (Cmd+K) ─── */
  .cmdk-overlay { position: fixed; inset: 0; background: color-mix(in srgb, var(--bg) 30%, rgba(20,16,12,.5));
    backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
    z-index: 200; display: flex; align-items: flex-start; justify-content: center;
    padding-top: 12vh; }
  .cmdk-overlay[hidden] { display: none; }
  .cmdk-panel { background: var(--surface); border: 1px solid var(--border);
    border-radius: 14px; box-shadow: var(--shadow-lg);
    width: 92%; max-width: 580px; overflow: hidden;
    animation: cmdk-pop .16s var(--ease); }
  @keyframes cmdk-pop { from { opacity: 0; transform: translateY(-8px) scale(.98); } to { opacity: 1; transform: none; } }
  #cmdk-input { width: 100%; border: none; border-bottom: 1px solid var(--border);
    padding: 15px 18px; font-size: 15px; outline: none; background: var(--surface);
    color: var(--text); }
  #cmdk-input::placeholder { color: var(--text-subtle); }
  .cmdk-results { list-style: none; margin: 0; padding: 7px;
    max-height: 54vh; overflow-y: auto; }
  .cmdk-item { padding: 9px 11px; border-radius: 8px;
    cursor: pointer; display: flex; align-items: baseline; gap: 8px; }
  .cmdk-item.sel { background: var(--accent-soft); color: var(--accent-deep); }
  .cmdk-sub { color: var(--text-subtle); font-size: 12px; }
  .cmdk-group { padding: 9px 11px 3px; font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.09em; color: var(--text-subtle); font-weight: 700; }
  .cmdk-empty { padding: 14px 11px; color: var(--text-subtle); font-size: 13px; }

  /* ─── callouts · emphasized inline banners ──────────────────────────
     Same visual weight as the .next-actions / day-warnings family: an
     accent-edged soft container. Base = neutral surface (informational);
     --warn = warning tint for "needs a human" banners (handover awaiting
     acceptance, JCT step-down, kalk warnings). */
  .callout {
    border-left: 4px solid var(--text-subtle);
    background: var(--surface-2);
    border-radius: var(--radius);
    padding: 8px 12px;
    margin: 0 0 var(--space-4);
    font-size: 13px;
    line-height: 1.45;
  }
  .callout--warn {
    border-left-color: var(--warning);
    background: var(--warning-soft);
    color: #92590a;   /* warn ink, matches .pill.warn — dark override below */
  }
  .callout--warn a { color: inherit; text-decoration: underline; }

  /* ─── key/value facts + intro paragraph ───
     `<dl class="kv">` is the compact facts list a detail page opens with
     (product, template, agreement, purchasing board …) and `<p class="lead">`
     its one-line intro. Both were used by a dozen templates before they were
     defined here, so they rendered as the browser's indented <dd> and a plain
     paragraph. */
  .kv {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    gap: 6px 18px; margin: 0; font-size: 13px;
  }
  .kv dt {
    color: var(--text-muted); font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.04em; padding-top: 2px;
  }
  .kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
  @media (max-width: 560px) {
    .kv { grid-template-columns: 1fr; gap: 2px; }
    .kv dd { margin-bottom: 8px; }
  }
  .lead { font-size: 14px; line-height: 1.5; color: var(--text-muted);
    margin: 0 0 var(--space-4); max-width: 76ch; }

  /* ─── rate matrix (Client agreements & rates) ───
     Packages down, room types across; each cell is one agreed per-person
     rate or a blank that means "not agreed". The inline form is the same
     save endpoint as before — the grid just puts every combination, agreed
     or not, in front of the desk instead of listing only the agreed ones. */
  .rate-matrix th[scope="row"] { font-weight: 600; text-transform: none;
    letter-spacing: 0; font-size: 13px; color: var(--text); white-space: nowrap; }
  .rate-matrix td { vertical-align: middle; }
  .rate-cell { display: inline-flex; align-items: center; gap: 6px; }
  .rate-cell input[type="number"] { width: 112px; max-width: 112px; text-align: right; }
  .rate-cell input[type="number"]::placeholder { color: var(--text-subtle); font-style: italic; }
  .rate-matrix .rate-blank { color: var(--text-subtle); font-style: italic; }
  .rate-matrix .rate-value { font-variant-numeric: tabular-nums; font-weight: 600; }
  .rate-matrix .rate-unit { color: var(--text-subtle); font-size: 11px; margin-left: 3px; }

  /* ─── small text helpers ─── */
  .muted { color: var(--text-muted); }
  .note { font-size: 12px; color: var(--text-muted); }

  /* ─── page scaffolding: heading row + breadcrumb ─── */
  .page-head {
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; gap: 8px 14px;
    margin: 0 0 var(--space-5);
  }
  .page-head h1 { margin: 0; }
  .breadcrumb {
    display: flex; align-items: center; gap: 6px;
    font-size: 12px; color: var(--text-muted);
    margin: 0 0 var(--space-2);
  }
  .breadcrumb a { color: var(--text-muted); text-decoration: none; }
  .breadcrumb a:hover { color: var(--accent-deep); text-decoration: underline; }

  /* ─── notifications: unread emphasis + pager ─────────────────────────
     Unread rows carry weight AND a left accent bar (never hue alone);
     the bar reads var(--accent) so it re-skins in dark mode. */
  tr.is-unread td { font-weight: 600; }
  tr.is-unread td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
  .pager {
    display: flex; align-items: center; gap: 10px;
    margin: var(--space-3) 0;
    font-size: 12.5px; color: var(--text-muted);
  }
  .pager a {
    padding: 2px 9px; border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-muted); text-decoration: none;
    transition: border-color .13s, color .13s;
  }
  .pager a:hover { color: var(--accent-deep); border-color: var(--accent); text-decoration: none; }

  /* ─── skip-to-content (a11y) — hidden until keyboard focus, then a
     floating button over the top-left corner ─── */
  .skip-link {
    position: fixed; top: 10px; left: 10px; z-index: 300;
    width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
    padding: 9px 15px; border-radius: 8px;
    background: var(--accent); color: #fff;
    font-size: 13px; font-weight: 600; text-decoration: none;
    box-shadow: var(--shadow-md);
  }
  .skip-link:focus {
    width: auto; height: auto; clip-path: none;
    outline: none; text-decoration: none;
    box-shadow: var(--shadow-md), var(--ring);
  }

  /* ════════════════════════════════════════════════════════════════
     DARK COMPONENT OVERRIDES
     The token swap re-skins everything that reads --var. These rules
     fix the handful of tinted "soft background + hard-coded ink" pairs
     (pills, dept tags, staff cells, badges, severity rows) whose inline
     ink colours were tuned for the light theme and would fall below AA
     on a dark tint. Each just lifts the ink to a light-on-dark hue.
     ════════════════════════════════════════════════════════════════ */

  /* ════════════════════════════════════════════════════════════════
     PEOPLE & ACCESS — the administration workspace (/dashboard/access/)
     Permission data is dense; the job of this section is to keep it
     readable without a second visual language. Everything below is
     built from the existing tokens, .card, .table-wrap and .pill.
     Two rules carry the accessibility weight: every state also says
     its word (colour is reinforcement, never the message), and edit
     mode looks different from view mode at a glance.
     ════════════════════════════════════════════════════════════════ */
  .pa-head { align-items: flex-start; }
  .pa-lede { margin: 4px 0 0; max-width: 70ch; color: var(--text-muted); font-size: 13.5px; }

  /* Workspace tabs — the four destinations, one row, wrapping on narrow. */
  .pa-tabs {
    display: flex; flex-wrap: wrap; gap: 2px;
    border-bottom: 1px solid var(--border); margin: 0 0 var(--space-5);
  }
  .pa-tab {
    padding: 7px 13px; font-size: 13px; font-weight: 500; color: var(--text-muted);
    text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  }
  .pa-tab:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
  .pa-tab.is-active {
    color: var(--accent-deep); border-bottom-color: var(--accent); font-weight: 650;
  }
  .pa-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* Filter bar — a card that becomes one column on a phone. */
  .pa-filters {
    display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-4); align-items: flex-end;
    margin-bottom: var(--space-4);
  }
  .pa-filters > label { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 190px; }
  .pa-filters > label.pa-check { flex-direction: row; align-items: center; gap: 7px; flex: 0 0 auto; }
  .pa-filters > label.pa-check input { width: auto; }
  .pa-filters__actions { display: flex; gap: 7px; align-items: center; flex: 0 0 auto; }
  .pa-filters .note { flex: 1 1 100%; margin: 0; }
  .pa-count { margin: 0 0 var(--space-3); font-size: 13px; color: var(--text-muted); }

  /* Tables. Row headers are the subject, so they read as text, not as a
     column heading; free-form cells wrap, identifiers do not. */
  .pa-table th[scope="row"] {
    font-weight: 600; text-transform: none; letter-spacing: 0;
    font-size: var(--table-font-size); background: transparent;
    white-space: normal; color: var(--text); max-width: 34ch;
  }
  .pa-table th[scope="row"] small { display: block; font-weight: 400; font-size: 11.5px; }
  .pa-table td { white-space: normal; }
  .pa-table td.num, .pa-table th.num { white-space: nowrap; }
  .pa-person a { font-weight: 600; }

  /* Seats and capabilities as chips: many per cell, wrapping, each readable. */
  .pa-seat {
    display: inline-flex; align-items: baseline; gap: 5px; margin: 1px 4px 1px 0;
    padding: 2px 9px; border-radius: 999px; font-size: 12px; text-decoration: none;
    background: var(--accent-soft); color: var(--accent-deep); border: 1px solid transparent;
  }
  .pa-seat:hover { text-decoration: none; border-color: var(--accent); }
  .pa-seat small { color: inherit; opacity: .78; font-size: 11px; }
  .pa-cap {
    display: inline-block; margin: 1px 4px 1px 0; padding: 2px 8px; border-radius: var(--radius-sm);
    background: var(--surface-2); color: var(--text-muted); font-size: 11.5px;
    border: 1px solid var(--border-soft);
  }
  .pa-cap--gain { background: var(--success-soft); color: #1a6b3a; border-color: #c3e3ce; font-weight: 600; }
  .pa-cap--lose { background: var(--danger-soft); color: #b42318; border-color: #f3c5c0; font-weight: 600; }
  .pa-cap--keep { background: var(--accent-soft); color: var(--accent-deep); border-color: #cdddfb; }
  .pa-cap-more { font-size: 11.5px; }
  .pa-keep__row { margin-bottom: 3px; }
  .pa-keep__row small { display: block; font-size: 11px; }

  /* Team evidence badges. Each says its own word; the tint only groups them. */
  .pa-badge {
    display: inline-block; margin: 1px 4px 1px 0; padding: 1px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 600; letter-spacing: .01em;
    background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border-soft);
  }
  .pa-badge--access   { background: var(--accent-soft); color: var(--accent-deep); border-color: #cdddfb; }
  .pa-badge--staffed  { background: var(--success-soft); color: #1a6b3a; border-color: #c3e3ce; }
  .pa-badge--standard { background: var(--surface-3); color: var(--text); }
  .pa-badge--routing  { background: var(--purple-soft); color: var(--purple); border-color: #ddd0f5; }
  .pa-badge--uncovered{ background: var(--warning-soft); color: #92590a; border-color: #f2d9ae; }
  .pa-badge--review   { background: var(--danger-soft); color: #b42318; border-color: #f3c5c0; }

  /* Detail pages — a single readable column of cards. */
  /* A grid item defaults to min-width:auto, so one unbreakable run of text
     anywhere in the column widens EVERY card and pushes the page sideways on
     a phone. min-width:0 lets the column shrink to the viewport; the things
     that genuinely cannot shrink are tables, and each of those already sits
     in its own scrolling .table-wrap. */
  .pa-detail { display: grid; gap: var(--space-5); min-width: 0; }
  .pa-detail > * { min-width: 0; }
  .pa-detail > .card { margin: 0; }
  .pa-section-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--space-3); flex-wrap: wrap;
  }
  .pa-section-head h2 { margin: 0; }
  .pa-group-title {
    font-size: 11px; text-transform: uppercase; letter-spacing: .07em; font-weight: 700;
    color: var(--text-subtle); margin: var(--space-5) 0 var(--space-2);
  }
  .pa-group-title:first-of-type { margin-top: var(--space-3); }

  /* The four questions. The mark is decorative; the sentence is the answer. */
  .pa-four__lede { margin: 2px 0 var(--space-3); font-size: 13px; max-width: 74ch; }
  .pa-answers { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
  .pa-answer {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 8px 11px; border-radius: var(--radius-sm);
    border: 1px solid var(--border-soft); background: var(--surface-2);
  }
  .pa-answer.is-yes { border-left: 3px solid var(--success); }
  .pa-answer.is-no  { border-left: 3px solid var(--border); }
  .pa-answer__mark { font-size: 13px; line-height: 1.5; flex: none; color: var(--text-subtle); }
  .pa-answer.is-yes .pa-answer__mark { color: var(--success); }
  .pa-answer__body { min-width: 0; overflow-wrap: anywhere; }
  .pa-answer__body strong { display: block; font-size: 13.5px; }
  .pa-answer__body small { display: block; margin-top: 2px; font-size: 12px; line-height: 1.4; }

  /* Technical codes are available, not in the way. */
  .pa-code { display: inline-block; margin-top: 3px; }
  .pa-code > summary {
    cursor: pointer; font-size: 11px; color: var(--text-subtle); font-weight: 400; list-style: none;
  }
  .pa-code > summary::-webkit-details-marker { display: none; }
  .pa-code > summary::before { content: "▸ "; }
  .pa-code[open] > summary::before { content: "▾ "; }
  .pa-code code { font-size: 11px; color: var(--text-muted); }

  /* Permission matrix — the subject is the row, the roles are the columns. */
  .pa-matrix th.num, .pa-matrix td.num { text-align: center; min-width: 92px; }
  .pa-yes { color: var(--success); font-weight: 700; }
  .pa-no  { color: var(--text-subtle); }
  .pa-tick { display: inline-flex; padding: 6px; cursor: pointer; }
  .pa-tick input { margin: 0; width: 17px; height: 17px; cursor: pointer; }
  .pa-tick input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .pa-matrix--edit tbody tr:hover { background: var(--surface-2); }

  /* Edit and review modes must not look like a read-only page. */
  .pa-mode-banner {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 13px; margin: 0 0 var(--space-4);
    border: 1px solid var(--accent); border-left-width: 3px;
    border-radius: var(--radius-sm); background: var(--accent-soft);
    color: var(--accent-deep); font-size: 13px; font-weight: 500;
  }
  .pa-mode-banner--review {
    border-color: var(--warning); background: var(--warning-soft); color: #92590a;
  }
  .pa-editor > .card, .pa-editor .table-wrap { margin-bottom: var(--space-4); }
  .pa-edit-table select { width: auto; min-width: 160px; }
  .pa-edit-table tr.pa-is-member { background: var(--accent-soft); }
  .pa-actions {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: var(--space-3) 0 var(--space-6);
  }
  .pa-actions__note { font-size: 12px; }
  .pa-actions--confirm {
    padding: var(--space-4); border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface); box-shadow: var(--shadow-sm);
  }
  .pa-primary { font-weight: 600; }

  /* The reviewed diff. */
  .pa-diff { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; gap: 5px; }
  .pa-diff__item {
    display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
    padding: 6px 10px; border-radius: var(--radius-sm); background: var(--surface-2);
    border-left: 3px solid var(--border); font-size: 13px;
  }
  .pa-diff--added   { border-left-color: var(--success); }
  .pa-diff--removed { border-left-color: var(--danger); }
  .pa-diff--role_changed { border-left-color: var(--accent); }
  .pa-diff__tag {
    flex: none; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
    font-weight: 700; color: var(--text-subtle);
  }
  .pa-blocked {
    border-color: var(--danger); border-left: 3px solid var(--danger);
  }
  .pa-blocked h2 { color: var(--danger); margin-top: 0; }

  /* Lists used on the rules and report pages. */
  .pa-steps { margin: 0 0 var(--space-3); padding-left: 1.2em; display: grid; gap: 7px; }
  .pa-steps span, .pa-exceptions span { display: block; font-size: 12.5px; }
  .pa-exceptions { margin: 0; padding-left: 1.2em; display: grid; gap: 5px; font-size: 13px; }
  .pa-refs, .pa-desk-list { margin: 0 0 var(--space-3); padding-left: 1.2em; font-size: 13px; }
  .pa-refs-cell { font-size: 12px; }
  .pa-history .pa-when { white-space: nowrap; font-size: 12px; }
  .pa-change { font-size: 12px; }
  .pa-old { color: var(--text-subtle); text-decoration: line-through; }
  .pa-new { color: var(--text); font-weight: 600; }
  .pa-empty { text-align: left; font-style: normal; padding: var(--space-5) !important; }
  .pa-empty p { margin: 0 0 8px; }
  .pa-note { max-width: 80ch; }

  .pa-candidate-search {
    display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0 0 var(--space-3);
  }
  .pa-candidate-search label { flex: none; }
  .pa-candidate-search input { flex: 1 1 220px; min-width: 0; }
  .pa-candidate-search button { flex: none; }

  /* Keyboard focus. Buttons and links inherit the UA ring elsewhere in
     Apollo; this workspace is keyboard-heavy (a long matrix of checkboxes and
     a review step nobody should be able to trigger blind), so the ring is
     declared rather than inherited. */
  .pa-tab:focus-visible,
  .pa-seat:focus-visible,
  .pa-table a:focus-visible,
  .pa-filters button:focus-visible,
  .pa-filters a:focus-visible,
  .pa-actions a:focus-visible,
  .pa-actions button:focus-visible,
  .pa-editor a:focus-visible,
  .pa-editor button:focus-visible,
  .pa-candidate-search button:focus-visible,
  .pa-code > summary:focus-visible,
  .pa-section-head a:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm);
  }

  /* Narrow widths: filters and heads stack, nothing overflows the page. */
  @media (max-width: 760px) {
    .pa-filters { flex-direction: column; align-items: stretch; }
    .pa-filters > label { flex: 1 1 auto; }
    .pa-section-head { flex-direction: column; align-items: flex-start; }
    .pa-answer { flex-direction: row; }
    .pa-actions--confirm { position: sticky; bottom: 0; z-index: 5; }
  }

  [data-theme="dark"] .pill { border-color: var(--border); }
  [data-theme="dark"] .pill.ok, [data-theme="dark"] .pill.success { color: #7ee0a0; border-color: #1e4a30; }
  [data-theme="dark"] .pill.warn { color: #fbbf24; border-color: #4a3a12; }
  [data-theme="dark"] .pill.bad, [data-theme="dark"] .pill.danger { color: #f8a99b; border-color: #4e2626; }
  [data-theme="dark"] .pill.info { color: var(--accent-deep); border-color: #2b3b5c; }
  [data-theme="dark"] .pill.purple { color: #c6b6e6; border-color: #3a3450; }
  [data-theme="dark"] .pill.cancelled { background: #d1382c; border-color: #d1382c; }
  [data-theme="dark"] .flash { border-color: #2b3b5c; color: var(--accent-deep); }
  [data-theme="dark"] .flash--danger { border-color: color-mix(in srgb, var(--danger) 40%, transparent); color: var(--danger); }
  [data-theme="dark"] .day-items .dept.Bus,
  [data-theme="dark"] .day-items .dept.Transport { background: #263349; color: #9db4d6; }
  [data-theme="dark"] .day-items .badge.TAXI { background: #263349; color: #9db4d6; }
  [data-theme="dark"] .option-row.confirmed { background: #16301f; border-color: #1e4a30; }
  [data-theme="dark"] .severity-Warning { background: #3a2a09 !important; }
  [data-theme="dark"] .severity-Critical { background: #3a1c1c !important; }
  [data-theme="dark"] .task-badge-pending { background: #3a2a09; color: #fbbf24; border-color: #5a4412; }
  [data-theme="dark"] .task-badge-needs_action { background: #3a1c1c; color: #f8a99b; border-color: #5a2929; }
  [data-theme="dark"] .staff-row-driver { background: #3a2a12; color: #e0a960; }
  [data-theme="dark"] .staff-row-shadowing { background: #1f2a3c; color: #88b1e2; }
  [data-theme="dark"] .staff-cell-local { background: #24314a; }
  [data-theme="dark"] .staff-cell-pending { background: #3a2a09; }
  [data-theme="dark"] .staff-cell-needs_action { background: #3a1c1c; }
  [data-theme="dark"] .staff-cell-external_no_ref { background: #1f2a3c; }
  [data-theme="dark"] .pip-pending { background: var(--warning); }
  [data-theme="dark"] .pip-needs_action { background: var(--danger); }
  [data-theme="dark"] details.card:hover > summary { background: color-mix(in srgb, var(--accent) 22%, var(--surface)); }
  [data-theme="dark"] .task-filter-chips .chip-active { color: #0f172a; }
  [data-theme="dark"] .callout--warn { color: #fbbf24; }
  [data-theme="dark"] .skip-link { color: #0f172a; }
  [data-theme="dark"] .info-pop-panel,
  [data-theme="dark"] .staff-cell-form { box-shadow: var(--shadow-md); }
  /* flatpickr calendar inherits warm-dark surfaces */
  [data-theme="dark"] .flatpickr-calendar { background: var(--surface); color: var(--text); box-shadow: var(--shadow-lg); border: 1px solid var(--border); }
  [data-theme="dark"] .flatpickr-months .flatpickr-month,
  [data-theme="dark"] .flatpickr-weekday,
  [data-theme="dark"] .flatpickr-current-month input.cur-year,
  [data-theme="dark"] .flatpickr-day { color: var(--text); fill: var(--text); }
  [data-theme="dark"] .flatpickr-day:hover { background: var(--surface-2); border-color: var(--surface-2); }

  /* People & Access — dark component overrides (tinted pairs that hard-code
     an ink colour must be restated here, as everywhere else in this file). */
  [data-theme="dark"] .pa-cap--gain { background: #16301f; color: #7ee0a0; border-color: #1e4a30; }
  [data-theme="dark"] .pa-cap--lose { background: #3a1c1c; color: #f8a99b; border-color: #4e2626; }
  [data-theme="dark"] .pa-cap--keep { background: #1b2942; color: var(--accent-deep); border-color: #2b3b5c; }
  [data-theme="dark"] .pa-badge--access { background: #1b2942; color: var(--accent-deep); border-color: #2b3b5c; }
  [data-theme="dark"] .pa-badge--staffed { background: #16301f; color: #7ee0a0; border-color: #1e4a30; }
  [data-theme="dark"] .pa-badge--routing { background: #2a2440; color: #c6b6e6; border-color: #3a3450; }
  [data-theme="dark"] .pa-badge--uncovered { background: #3a2a09; color: #fbbf24; border-color: #5a4412; }
  [data-theme="dark"] .pa-badge--review { background: #3a1c1c; color: #f8a99b; border-color: #5a2929; }
  [data-theme="dark"] .pa-mode-banner { background: #1b2942; color: var(--accent-deep); }
  [data-theme="dark"] .pa-mode-banner--review { background: #3a2a09; color: #fbbf24; border-color: var(--warning); }
  [data-theme="dark"] .pa-edit-table tr.pa-is-member { background: #1b2942; }
  [data-theme="dark"] .flatpickr-day.selected { background: var(--accent); border-color: var(--accent); color: #0f172a; }

  /* TOC rail polish */
  .toc-rail a { transition: background .12s, color .12s; }
  .toc-rail a.active-section { background: var(--accent-soft); color: var(--accent-deep); }
  /* Global htmx-failure toast (listener wired near </body>). */
  .htmx-error-toast {
    position: fixed; right: 16px; bottom: 16px; z-index: 200;
    max-width: 380px; padding: 10px 14px; border-radius: 8px;
    background: var(--danger); color: #fff;
    font-size: 0.85rem; line-height: 1.35;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
    opacity: 0; transform: translateY(6px);
    transition: opacity 0.25s ease, transform 0.25s ease;
  }
  .htmx-error-toast.show { opacity: 1; transform: none; }

  /* ── Print ──────────────────────────────────────────────────────────────
     Templates have long marked editor chrome with .no-print, but the class
     was never defined anywhere — so Ctrl+P (and the routing "Print" button
     that used to call window.print()) printed the entire app shell, nav and
     all. Defined here so ad-hoc printing of any dashboard page produces the
     content, not the furniture. The dedicated print documents render through
     their own _print_base.html and are unaffected. */
  @media print {
    .no-print,
    .sidebar,
    .topbar,
    .toc-rail,
    .htmx-error-toast { display: none !important; }
    main, body { margin: 0; padding: 0; background: #fff; }
    a[href]::after { content: ""; }  /* no URL footnotes on every link */
    .card, .table-wrap { break-inside: avoid; }
  }

  /* Departure navigation — a product's departures are siblings, not unrelated
     tours; stepping between them must not require tour search. */
  .departure-nav { display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
    margin: 8px 0; padding: 6px 10px; border-radius: var(--radius);
    background: var(--surface-2); border: 1px solid var(--border-soft);
    font-size: 12px; }
  .departure-nav__product { font-weight: 600; }

  /* ── "Which status am I looking at?" legend ──────────────────────────────
     Apollo shows five independent state machines on a tour and used to label
     every one of them "Status". This is the vocabulary panel that names them;
     it rides the existing .info-pop popover so it costs nothing closed. */
  .status-legend { margin-left: 6px; font-weight: normal; }
  .status-legend > summary { font-size: 11px; }
  .status-legend__panel { min-width: 340px; max-width: 420px; }
  .status-legend__intro { margin: 0 0 8px; }
  .status-legend__list { margin: 0; display: grid; gap: 2px 0; }
  .status-legend__list dt { font-weight: 600; color: var(--text); margin-top: 6px; }
  .status-legend__list dt:first-child { margin-top: 0; }
  /* The row the current screen is actually about. */
  .status-legend__list dt.is-here { color: var(--accent); }
  .status-legend__list dt.is-here::after { content: " ←"; }
  .status-legend__list dd { margin: 0; color: var(--text-muted); }

  /* A status label that names WHICH state machine it belongs to. Used where a
     bare pill sat next to other bare pills with different meanings. */
  .status-field { display: inline-flex; align-items: baseline; gap: 5px; }
  .status-field__k { font-size: 10px; text-transform: uppercase;
    letter-spacing: .04em; color: var(--text-subtle); white-space: nowrap; }

  /* Sales availability — rides .info-pop, like the departure decision on the
     same fact bar. Wider panel: it explains four enum values before asking
     anyone to pick one. */
  .sales-availability__panel { min-width: 340px; max-width: 420px; }
  .sales-availability__help { margin: 0; }
  .sales-availability__help dt { font-weight: 600; color: var(--text); margin-top: 6px; }
  .sales-availability__help dt:first-child { margin-top: 0; }
  .sales-availability__help dt.is-current { color: var(--accent); }
  .sales-availability__help dt.is-current::after { content: " ← now"; font-weight: normal;
    font-size: 11px; }
  .sales-availability__help dd { margin: 0; color: var(--text-muted); }

  /* ── "Needs a catalogue product" — a control, not a diagnosis ────────────
     Replaced a red pill whose tooltip told the operator to go and find the
     picker inside an edit expander at the other end of the row. The warning
     was seen and the fix was not. */
  .bind-control { display: inline-block; }
  .bind-control > summary { cursor: pointer; list-style: none;
    display: inline-flex; align-items: center; gap: 5px; }
  .bind-control > summary::-webkit-details-marker { display: none; }
  .bind-control__action { font-size: 11px; color: var(--accent); }
  .bind-control__panel { margin: 6px 0 2px; padding: 8px 10px;
    border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface-2); max-width: 460px; }
  .bind-control__why,
  .bind-control__hint,
  .bind-control__alt { margin: 0 0 6px; font-size: 12px; color: var(--text-muted); }
  .bind-control__hint--warn { color: var(--warn, var(--text)); }
  .bind-control__panel select { max-width: 100%; margin-bottom: 6px; }
  .bind-control__alt { margin: 6px 0 0; font-size: 11px; }

  /* The bind control sits in a narrow name cell; keep its pill on one line so
     "needs a product" does not wrap into two stacked words. */
  .bind-control > summary .pill { white-space: nowrap; }

  /* Tour ownership. The Kyoto half used to be a printed fact editable only in
     Django admin, which is why the handover's own recipient could not be set
     by the people whose work waits on it. */
  .owner-fact { display: inline-flex; align-items: baseline; gap: 6px;
    flex-wrap: wrap; }
  .owner-fact__editor { display: inline-block; }
  .owner-fact__editor > summary { cursor: pointer; font-size: 11px;
    color: var(--accent); display: inline; }
  .owner-fact__editor > summary::-webkit-details-marker { display: none; }

  /* ── Bus board: seven columns, and the action stays on screen ────────────
     The thirteen-column version ran past 1280px, so app.js's horizontal
     scroll wrapper put Cost, Invoice and the edit button off the right edge.
     A work board's primary action must not be something you find sideways. */
  .bus-row__dates { white-space: nowrap; }
  .bus-row__arrow { color: var(--text-subtle); margin: 0 3px; }

  /* Secondary facts on a full-width line instead of unreachable columns.
     Visible, not hidden — and cost stays behind can_view_operational_cost. */
  .bus-row__detail > td { padding: 2px 10px 6px; font-size: 11px;
    color: var(--text-muted); display: flex; gap: 16px; flex-wrap: wrap; }
  .bus-row__k { text-transform: uppercase; letter-spacing: .04em;
    font-size: 9px; color: var(--text-subtle); margin-right: 3px; }

  /* Narrow screens: the row becomes a stacked card. Each cell keeps its own
     label so a value is never orphaned from its meaning, which is what makes
     a naively collapsed table unreadable rather than merely narrow. */
  @media (max-width: 720px) {
    .board-buses table,
    .board-buses tbody,
    .board-buses tr,
    .board-buses td { display: block; width: auto; }
    .board-buses thead,
    .board-buses table > tr:first-child { display: none; }
    .board-buses tr:not(.edit-expander) {
      border: 1px solid var(--border-soft); border-radius: var(--radius);
      margin-bottom: 8px; padding: 6px 8px; }
    .board-buses .bus-row__detail > td { display: flex; }
    .board-buses td[data-label]::before {
      content: attr(data-label) " "; text-transform: uppercase;
      letter-spacing: .04em; font-size: 9px; color: var(--text-subtle);
      display: block; }
  }

  /* "Why is my supplier not on this board?" — the vendor / product / on-a-tour
     distinction, as a closed popover for the person who is stuck. */
  .catalog-explainer { margin-left: 8px; }
  .catalog-explainer__panel { min-width: 380px; max-width: 460px; }
  .catalog-explainer__intro,
  .catalog-explainer__note { margin: 0 0 8px; }
  .catalog-explainer__note { margin: 8px 0 0; padding-top: 8px;
    border-top: 1px solid var(--border-soft); }
  .catalog-explainer__steps { margin: 0; padding-left: 18px; }
  .catalog-explainer__steps li { margin-bottom: 8px; }
  .catalog-explainer__steps strong { display: block; color: var(--text); }
  .catalog-explainer__steps span { display: block; color: var(--text-muted); }

  /* The status legend rides alongside the status bar but stays OUT of its
     role="status" region: a screen reader announces that region as the tour's
     status summary, and four paragraphs of vocabulary are not that. */
  .cc-bar__legend { margin: -6px 0 8px; padding-left: 2px; }

  /* ── Pipeline filters ────────────────────────────────────────────────────
     The board used to render every non-cancelled tour with no way to narrow
     it. Primary controls stay on one row; the rest fold away, but the fold
     opens itself when one of them is in use — a filter active while its
     control is hidden is how an operator ends up staring at an empty board. */
  .pipeline-filters { margin: 0 0 10px; }
  .pipeline-filters__row { display: flex; gap: 10px; align-items: flex-end;
    flex-wrap: wrap; }
  .pipeline-filters__field { display: flex; flex-direction: column; gap: 2px;
    font-size: 11px; }
  .pipeline-filters__field--grow { flex: 1 1 220px; }
  .pipeline-filters__field > span { color: var(--text-subtle);
    text-transform: uppercase; letter-spacing: .04em; font-size: 9px; }
  .pipeline-filters__field input,
  .pipeline-filters__field select { font-size: 12px; }
  .pipeline-filters__check { display: inline-flex; align-items: center; gap: 5px;
    font-size: 12px; padding-bottom: 4px; }
  .pipeline-filters__more { margin-top: 8px; }
  .pipeline-filters__more > summary { cursor: pointer; font-size: 11px;
    color: var(--accent); }

  /* The scope line. The default narrowing is stated, never silent. */
  .pipeline-scope { margin: 0 0 12px; font-size: 12px; color: var(--text-muted); }

  .kanban-col__empty { margin: 6px 4px; font-size: 11px; color: var(--text-subtle);
    font-style: italic; }
  .kanban-col__more { margin: 6px 4px 2px; font-size: 10px;
    color: var(--text-subtle); }

  /* Kanban cards. Moved out of an inline <style> in board_pipeline.html when
     the board gained filters: the rules are layout, not page-specific, and
     app.css is where the tokens they use are defined. Cards are divs, so the
     dense-table CSS does not reach them. */
  .kanban-board { display: flex; gap: var(--space-3); overflow-x: auto;
    padding-bottom: var(--space-2); align-items: flex-start; }
  .kanban-col { flex: 0 0 214px; background: var(--surface-2); border-radius: 8px;
    padding: var(--space-2); }
  .kanban-col__head { font-weight: 600; font-size: 11px; text-transform: uppercase;
    letter-spacing: .04em; color: var(--text-subtle); padding: 2px 5px; }
  .kanban-cards { min-height: 26px; }
  .kanban-card { background: var(--surface); border: 1px solid var(--border);
    border-radius: 6px; padding: 5px 7px; margin-top: 5px; cursor: grab;
    line-height: 1.3; }
  .kanban-card__title { display: block; font-weight: 600; font-size: 12px;
    text-decoration: none; color: inherit; }
  .kanban-card .meta { font-size: 10.5px; color: var(--text-subtle); }
  .kanban-card__tags { margin-top: 3px; display: flex; gap: 3px; flex-wrap: wrap; }
  .kanban-card__tags .pill { font-size: 9px; }

  /* ── The Apollo guide ────────────────────────────────────────────────────
     A landing page of entry points, walkthroughs, diagrams and a FAQ, in
     place of 1,052 lines of prose nobody could find an answer in. */
  .guide-search { width: 100%; max-width: 520px; margin: 0 0 18px;
    font-size: 13px; }

  .guide-cards { display: grid; gap: 12px; margin: 0 0 24px;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
  .guide-card { border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface-2); padding: 12px 14px; }
  .guide-card h3 { margin: 0 0 4px; font-size: 14px; }
  .guide-card p { margin: 0 0 8px; font-size: 12px; color: var(--text-muted); }
  .guide-card ul { margin: 0; padding-left: 16px; font-size: 12px; }
  .guide-card li { margin-bottom: 3px; }
  .guide-card__go { margin: 10px 0 0 !important; font-weight: 600; }

  .guide-figure { margin: 12px 0 20px; }
  .guide-svg { display: block; max-width: 100%; height: auto; }
  .guide-figure figcaption { margin-top: 8px; font-size: 12px;
    color: var(--text-muted); max-width: 68ch; }

  .guide-walks { margin: 0 0 24px; padding-left: 20px; }
  .guide-walks > li { margin-bottom: 20px; }
  .guide-walks h3 { margin: 0 0 6px; font-size: 14px; }
  .guide-walks p { margin: 0 0 6px; font-size: 13px; max-width: 72ch; }
  .guide-walks__recover { color: var(--text-muted); }

  .guide-faq > details { border-bottom: 1px solid var(--border-soft);
    padding: 8px 0; }
  .guide-faq > details > summary { cursor: pointer; font-weight: 600;
    font-size: 13px; }
  .guide-faq > details > p { margin: 8px 0 2px; font-size: 13px;
    color: var(--text-muted); max-width: 72ch; }

  .guide-status-table { width: 100%; font-size: 12.5px; }
  .guide-status-table td { vertical-align: top; }

  /* Available to screen readers, out of the visual flow. Used by the status
     diagram's <caption>, which a sighted reader gets from the figcaption. */
  .visually-hidden { position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
    white-space: nowrap; border: 0; }
