  /* ─── 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;

    /* Tinted status pairs. A pill/badge/banner is `-soft` background +
       `-ink` text + `-line` border. The ink is darker than the semantic
       colour on purpose: the LABEL must meet WCAG AA on its soft ground, so a
       status reads by its words, not hue alone. Dark values are below. */
    --success-ink: #1a6b3a;  --success-line: #c3e3ce;
    --warning-ink: #92590a;  --warning-line: #f2d9ae;
    --danger-ink:  #b42318;  --danger-line:  #f3c5c0;
    --accent-line: #cdddfb;
    --purple-ink: var(--purple);  --purple-line: #ddd0f5;
    --danger-deep: #b91c1c;  /* danger button hover */
    /* Cancelled lifecycle — a solid red louder than any danger tint, because
       a cancellation starts supplier-cancellation work. */
    --cancelled: #c1281d;
    /* Neutral category chip (Bus / Transport departments, TAXI badge). */
    --chip-neutral: #e7ebef;  --chip-neutral-ink: #475569;

    /* 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 */
    --table-cell-padding: 4px var(--space-3);  /* a roomier surface overrides only this */
  }

  /* ─── 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 status
     components read the -soft / -ink / -line tokens, whose dark values are
     set here, so they need no override of their own; the few domain palettes
     that still hard-code a colour keep theirs in the [data-theme="dark"]
     rules further down. */
  [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;
    --success-ink: #7ee0a0;  --success-line: #1e4a30;
    --warning-ink: #fbbf24;  --warning-line: #4a3a12;
    --danger-ink:  #f8a99b;  --danger-line:  #4e2626;
    --accent-line: #2b3b5c;
    --purple-ink: #c6b6e6;   --purple-line: #3a3450;
    --cancelled: #d1382c;
    --chip-neutral: #263349; --chip-neutral-ink: #9db4d6;
    --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; }
  /* The `hidden` attribute wins over any component display rule (a
     `.form-grid label` is display:flex, which used to keep a hidden
     conditional field on screen — the agreement form's three scope fields). */
  [hidden] { display: none !important; }
  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; }
  /* A long label (German runs ~30% longer) wraps to a second line instead of
     losing its end to an ellipsis; the rail mode hides the label anyway. */
  .sidebar a > .nav-tx { min-width: 0; white-space: normal; line-height: 1.25; overflow-wrap: break-word; hyphens: auto; }
  .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"] .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; }
  /* The rail keeps the chevron (pointing right) under the brand mark, so the
     way back to the full sidebar is where the way in was. */
  html[data-sidebar="rail"] .sidebar__head { flex-direction: column; gap: 6px; }
  html[data-sidebar="rail"] .sidebar__collapse svg { transform: rotate(180deg); }
  /* Groups stay distinguishable without their labels: a hairline between them. */
  html[data-sidebar="rail"] .nav-group + .nav-group { border-top: 1px solid var(--border-soft); padding-top: 4px; margin-top: 4px; }
  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); }

  /* Content width. 1180px left a third of a desktop screen empty beside the
     sidebar + "On this page" rail (2026-10-02); the work pages are wide tables
     and day cards, so they get the room. Still capped so a 4K screen does not
     stretch a form across the whole display. */
  main { max-width: var(--content-max, 1640px); 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 var(--accent-line);
    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: var(--danger-line);
    color: var(--danger-ink);
  }
  /* The shell groups messages by severity (`flash_groups` in
     templatetags/apollo.py). The group is the box. Its label is the cue that
     does not rely on colour, and the ink tokens keep the text at ≥4.5:1 in
     both themes. */
  .flash-stack { display: grid; gap: 8px; margin: 0 0 18px; }
  .flash-group {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px;
    padding: 10px 16px; border: 1px solid var(--accent-line); border-radius: var(--radius);
    background: var(--accent-soft); color: var(--accent-deep);
  }
  .flash-group .flash { margin: 0; padding: 0; border: 0; background: none; color: inherit; flex: 1 1 20rem; min-width: 0; }
  .flash-group__label { margin: 0; font-weight: 700; flex: none; }
  .flash-group--danger { background: var(--danger-soft); border-color: var(--danger-line); color: var(--danger-ink); }
  .flash-group--warning { background: var(--warning-soft); border-color: var(--warning-line); color: var(--warning-ink); }
  .flash-group--success { background: var(--success-soft); border-color: var(--success-line); color: var(--success-ink); }

  /* ─── 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: var(--table-cell-padding);
    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: var(--success-ink); border-color: var(--success-line); font-weight: 600;
  }
  .pill.warn {
    background: var(--warning-soft); color: var(--warning-ink); border-color: var(--warning-line); font-weight: 600;
  }
  .pill.bad, .pill.danger {
    background: var(--danger-soft); color: var(--danger-ink); border-color: var(--danger-line); font-weight: 600;
  }
  .pill.info {
    background: var(--accent-soft); color: var(--accent-deep); border-color: var(--accent-line);
  }
  .pill.muted {
    background: var(--surface-2); color: var(--text-subtle);
  }
  .pill.purple {
    background: var(--purple-soft); color: var(--purple-ink); border-color: var(--purple-line);
  }
  /* 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: var(--cancelled); color: #fff; border-color: var(--cancelled); 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; } }
  .cc-bar__metric--todo { color: var(--warning-ink); background: var(--warning-soft); }
  /* The readiness read-out on the tour's own pages (Amendments, Finance, …),
     where the To do list is not computed. */
  .cc-bar__metric--blocked { color: var(--danger-ink); background: var(--danger-soft); }

  /* ─── Tour page tabs (2026-10-18 review) ───
     One job per tab; tour-page.js shows one panel at a time and unhides
     the bar. Without it every panel shows in order. */
  .cc-tabs { display: flex; flex-wrap: wrap; gap: 2px; margin: 0 0 var(--space-4);
    border-bottom: 1px solid var(--border); }
  .cc-tabs a { color: var(--text-muted); border-bottom: 2px solid transparent; padding: 8px 12px; font-weight: 500;
    margin-bottom: -1px; text-decoration: none; }
  .cc-tabs a:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
  .cc-tabs a[aria-current] { color: var(--accent-deep); border-bottom-color: var(--accent); font-weight: 600; }
  .cc-tabs a.cc-tabs__all { margin-left: auto; font-size: 12px; }
  /* The tour's own pages in the row (Amendments, Finance, …) leave this page. */
  .cc-tabs a.cc-tabs__page::after { content: " ↗"; font-size: 10px; opacity: .55; }
  .cc-panel-links { margin: 0 0 var(--space-2); font-size: 12.5px; }
  .cc-workspace { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--space-4); margin: 0 0 var(--space-4); }
  .cc-workspace__facts { grid-column: 1 / -1; }
  .cc-workspace h2 { font-size: 14px; margin: 0 0 8px; }
  .cc-workspace > section { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; min-width: 0; }
  .cc-ws-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px 16px; margin: 0; }
  .cc-ws-facts dt { font-size: 11px; color: var(--text-muted); }
  .cc-ws-facts dd { margin: 2px 0 0; font-size: 13px; }
  @media (max-width: 900px) { .cc-workspace { grid-template-columns: minmax(0, 1fr); } }
  .cc-tabs__count { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 999px;
    font-size: 11px; background: var(--warning-soft); color: var(--warning-ink); }
  .cc-tabs__count--muted { background: var(--surface-2); color: var(--text-muted); }
  .cc-tabs__count--bad { background: var(--danger-soft); color: var(--danger-ink); }
  .cc-panel[hidden] { display: none; }
  @media print { .cc-panel[hidden] { display: block !important; } .cc-tabs { display: none !important; } }

  /* Overview: what is open, and what each day has secured. */
  .cc-overview { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: var(--space-4);
    align-items: start; margin-bottom: var(--space-4); }
  .cc-overview h2 { font-size: 14px; margin: 0 0 8px; }
  .cc-todo, .cc-coverage { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 12px 14px; min-width: 0; }
  .cc-todo__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
  .cc-todo__item { display: flex; align-items: baseline; gap: 8px; font-size: 13px; }
  .cc-todo__title { flex: 1 1 auto; }
  .cc-todo__fix { white-space: nowrap; font-size: 12px; }
  .cc-coverage__scroll { overflow-x: auto; }
  .cc-coverage__grid { width: auto; box-shadow: none; border: 0; background: none; }
  .cc-coverage__grid th, .cc-coverage__grid td { padding: 3px 6px; text-align: center; font-size: 12px; border: 0; }
  .cc-coverage__grid tbody th { text-align: left; font-weight: 500; color: var(--text-muted); white-space: nowrap; }
  .cc-coverage__grid thead th { background: none; font-size: 11px; }
  .cc-coverage__grid th { text-transform: none; letter-spacing: 0; background: none; }
  .cc-coverage__grid tr:hover td { background: inherit; }
  .cc-coverage__grid td.cc-cov--none, .cc-coverage__grid td.cc-cov--ok { background: none; }
  .cc-cov--ok { color: var(--success); }
  .cc-cov--warn { color: var(--warning-ink); background: var(--warning-soft); }
  .cc-cov--bad { color: var(--danger-ink); background: var(--danger-soft); font-weight: 600; }
  .cc-cov--none { color: var(--text-subtle); }
  .cc-coverage__legend { font-size: 11px; margin: 6px 0 0; }
  @media (max-width: 900px) { .cc-overview { grid-template-columns: minmax(0, 1fr); } }

  /* Supplier sections with nothing in them fold into "Not started: …". */
  .cc-not-started { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 var(--space-3); font-size: 12.5px; }
  .cc-fold-empty [data-cc-empty]:not(.is-opened) { display: none; }

  /* A phone never scrolls the whole page sideways: wide tables scroll in
     place (staff overnights, group flights, ground services, the lines). */
  @media (max-width: 700px) {
    .cc-panel table, .day-card .lines-table { display: block; overflow-x: auto; max-width: 100%; position: relative; }
    .cc-bar { border-radius: var(--radius); }
  }
  .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-metaline > details { display: inline-block; vertical-align: baseline; }
  /* The attribution partial is a block; inline it so "· which status?" stays
     on the same line instead of wrapping alone underneath. */
  .cc-metaline > .meta { display: inline; margin: 0; }
  .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; }
  /* `start`, not `end`: the company-country cell carries a label and a line of
     help text, so an end-aligned row would drop its neighbour's control to the
     bottom of the taller cell instead of lining the two selects up. */
  .op-quick-add__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
    margin-top: 6px; align-items: start; }
  .op-quick-add__grid input, .op-quick-add__grid select { width: 100%; }
  .op-quick-add__grid label { display: block; font-size: 11px; color: var(--text-muted); }
  .op-quick-add__grid label select { margin-top: 2px; }
  .op-quick-add__grid label small { display: block; margin-top: 2px; line-height: 1.3; }
  .op-quick-add__btn { grid-column: 1 / -1; }
  .op-quick-add__err { color: var(--danger-ink); 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: var(--danger-deep); }
  button.small, .btn.small { padding: 4px 11px; font-size: 12px; }
  /* Bootstrap-style spellings some templates use: aliases of the three
     above, so a "btn-danger" never renders as the blue primary again. */
  .btn.btn-small { padding: 4px 11px; font-size: 12px; }
  .btn.btn-danger { background: var(--danger); }
  .btn.btn-danger:hover { background: var(--danger-deep); }
  button.danger-ghost.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="datetime-local"], 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);
  }
  /* Keyboard focus for everything that is NOT a text field — one ring, app-wide.
     Text fields (above) already show focus as an accent border + soft halo, so
     they are deliberately left out: an outline on top of that halo is a double
     ring. `:focus-visible` keeps the ring off mouse clicks. Wrapped in :where()
     so the rule weighs only as much as `:focus-visible` itself — a component
     with its own focus treatment (a picker option's highlight, the ⌘K input)
     keeps winning. */
  :where(a[href], button, .btn, summary, [role="button"], [tabindex]:not([tabindex="-1"]),
         input[type="checkbox"], input[type="radio"], input[type="file"],
         input[type="submit"], input[type="button"], input[type="reset"],
         input[type="range"], input[type="color"]):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
  /* 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; }

  /* ─── operator billing (one pre-invoice per operator on a departure) ─── */
  .ob-lead { margin: 0 0 var(--space-4); max-width: 72ch; }
  .ob-hint { margin: 0 0 var(--space-2); font-size: 12px; max-width: 72ch; }
  .ob-list { margin: var(--space-1) 0 0; padding-left: 1.2em; }
  .ob-callout-text { margin: var(--space-1) 0; }
  .ob-row--selected td { background: var(--accent-soft); }
  .ob-col-check { width: 2.5em; }
  .ob-wrap { white-space: normal; }
  .ob-ref { font-weight: 600; color: var(--text); font-size: 13px; }
  .ob-reason { font-size: 12px; max-width: 46ch; }
  .ob-actions { display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap;
    margin-top: var(--space-3); }
  .ob-card__head { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
    align-items: center; }
  .ob-card__head h4 { margin: 0; font-size: 15px; }
  .ob-card__amount { font-weight: 600; }
  .ob-card__links { margin-left: auto; display: flex; gap: var(--space-2); }
  .ob-card__bookings { margin: var(--space-2) 0; display: flex; flex-wrap: wrap; gap: var(--space-1); }
  .ob-card--cancelled { opacity: .75; }
  .ob-datev { margin: var(--space-3) 0; }
  .ob-inline { display: inline-flex; gap: var(--space-2); align-items: flex-end; flex-wrap: wrap;
    margin: 0 var(--space-2) var(--space-1) 0; }
  .ob-inline label { display: flex; flex-direction: column; gap: 2px; }
  .ob-inline input { width: auto; min-width: 9em; }
  .ob-fields { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-4); margin: var(--space-3) 0; }
  .ob-fields label { display: flex; flex-direction: column; gap: 2px; }
  .ob-fields input { width: auto; min-width: 11em; }
  .ob-fields .ob-notes { flex: 1 1 16em; }
  .ob-fields .ob-notes input { width: 100%; }
  .ob-record { margin-top: var(--space-3); }
  .ob-more { margin-top: var(--space-2); }
  @media (max-width: 720px) {
    .ob-card__links { margin-left: 0; }
    .ob-fields input, .ob-inline input { min-width: 0; width: 100%; }
  }
  /* ─── replacement hotels (proposal, PM review) ─── */
  .hr-lead { margin: 0 0 var(--space-4); max-width: 72ch; }
  .hr-col-check { width: 2.5em; }
  .hr-fields { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-4); margin: var(--space-3) 0; }
  .hr-fields label { display: flex; flex-direction: column; gap: 2px; }
  .hr-notes { flex: 1 1 18em; }
  .hr-notes input, .hr-notes textarea { width: 100%; }
  .hr-actions { display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap; margin-top: var(--space-3); }
  .hr-more { margin-top: var(--space-3); }
  .hr-inline { display: inline-flex; gap: var(--space-2); align-items: flex-end; flex-wrap: wrap; }
  .hr-inline label { display: flex; flex-direction: column; gap: 2px; }
  .hr-list { margin: var(--space-1) 0 0; padding-left: 1.2em; }

  /* ─── the product year's Hotels tab: one card per stay ─── */
  .stay-hotels__summary { display: flex; gap: var(--space-4); align-items: flex-start;
    justify-content: space-between; flex-wrap: wrap; margin: 0 0 var(--space-4); }
  .stay-hotels__summary p { margin: 0; max-width: 80ch; }
  .stay-card { scroll-margin-top: 80px; }
  .stay-card__anchor { display: block; position: relative; top: -90px; }
  .stay-card--open { border-left: 3px solid var(--warning); }
  .stay-card__head { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: center; }
  .stay-card__head h3 { margin: 0; font-size: 15px; }
  .stay-card__notes { display: grid; grid-template-columns: max-content 1fr; gap: 2px var(--space-3);
    margin: var(--space-2) 0 0; font-size: 12.5px; }
  .stay-card__notes dt { color: var(--text-muted); }
  .stay-card__notes dd { margin: 0; white-space: pre-line; }
  .stay-card__form { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
    gap: var(--space-3) var(--space-4); align-items: end; margin-top: var(--space-3); }
  .stay-card__pick { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
  .stay-card__label { font-size: 12px; color: var(--text-muted); display: flex; gap: 6px; align-items: center; }
  .stay-card__opt { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 5px;
    background: var(--accent-soft); color: var(--accent-deep); font-weight: 700; font-size: 11px; }
  .stay-card__read { display: grid; grid-template-columns: max-content 1fr; gap: 4px var(--space-3);
    margin: var(--space-3) 0 0; }
  .stay-card__read dd { margin: 0; }
  .stay-card__replacements { list-style: none; margin: var(--space-3) 0 0; padding: var(--space-2) 0 0;
    border-top: 1px solid var(--border); display: grid; gap: 4px; font-size: 13px; }
  .stay-card__replacements li { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
  @media (max-width: 900px) {
    .stay-card__form { grid-template-columns: 1fr; }
  }

  /* ─── the stay's hotels as one line in the day editor ─── */
  .overnight-hotels { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); align-items: center;
    padding: var(--space-2) var(--space-3); border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface-2); font-size: 13px; }
  .overnight-hotels__pick { display: inline-flex; gap: 6px; align-items: center; }
  .overnight-hotels a { margin-left: auto; }

  /* ─── hotel options A / B on an overnight (programme editor, day card) ─── */
  .hotel-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-2) var(--space-4); align-items: start; }
  .hotel-options__pick { display: flex; flex-direction: column; gap: 2px; }
  .hotel-options__help { grid-column: 1 / -1; }
  .hotel-pick .cat-pick__input { width: 100%; }
  .hotel-pick .cat-pick__chip { max-width: 100%; white-space: normal; }
  .hotel-pick .cat-pick__clear { min-width: 24px; min-height: 24px; }

  .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; }
  .stat .value.stat-value--small { font-size: 15px; font-weight: 600; }
  .stat .value.stat-value--pill { font-size: 18px; }

  /* ─── 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: var(--chip-neutral); color: var(--chip-neutral-ink); }
  .day-items .dept.Transport { background: var(--chip-neutral); color: var(--chip-neutral-ink); }
  .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: var(--chip-neutral); color: var(--chip-neutral-ink); }
  .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);
  }

  /* ─── side drawer (htmx partial rendered into a *-mount) ───────────
     `.drawer-backdrop` + `aside.drawer` with `__head` / `__close` / `__form` /
     `__row` / `__actions`. Closed by clearing the mount (backdrop click, ×, or
     the server's `HX-Trigger: closePanel`). This used to be copied into each
     drawer template, five times, so a drawer's look depended on which other
     drawer's <style> happened to be on the page — the experience CSV drawer
     shipped none and was unstyled unless another drawer had loaded first.
     A drawer that needs a different width sets only that (e.g.
     `.drawer--bulk-rooms`), in its own template. */
  .drawer-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.25); z-index: 50; }
  .drawer {
    position: fixed; right: 0; top: 0; bottom: 0; width: min(400px, 100vw);
    background: var(--surface); border-left: 1px solid var(--border);
    box-shadow: -4px 0 14px rgba(0, 0, 0, 0.08); z-index: 51;
    display: flex; flex-direction: column;
    animation: drawer-in 140ms ease-out;
  }
  @keyframes drawer-in {
    from { transform: translateX(20px); opacity: 0; }
    to   { transform: none; opacity: 1; }
  }
  @media (prefers-reduced-motion: reduce) { .drawer { animation: none; } }
  .drawer__head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 18px; border-bottom: 1px solid var(--border);
  }
  .drawer__head h3 { margin: 0; font-size: 16px; color: var(--accent-deep); }
  .drawer__close {
    background: none; border: none; font-size: 20px; cursor: pointer;
    color: var(--text-muted); line-height: 1;
  }
  /* background: the global button:hover would otherwise paint the × solid blue. */
  .drawer__close:hover { background: none; color: var(--text); }
  .drawer__form {
    flex: 1; overflow-y: auto; padding: 16px 18px;
    display: flex; flex-direction: column; gap: 14px;
  }
  .drawer__row {
    display: flex; flex-direction: column; gap: 4px;
    font-size: 12px; color: var(--text-muted);
  }
  .drawer__row--2col { display: grid; grid-template-columns: 1.2fr 1fr; gap: 10px; }
  .drawer__row--3col { display: grid; grid-template-columns: 1.2fr 0.7fr 0.7fr; gap: 10px; }
  .drawer__form input, .drawer__form select {
    padding: 6px 8px; font-size: 13px; color: var(--text);
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius-sm); width: 100%;
  }
  .drawer__form input:focus, .drawer__form select:focus {
    border-color: var(--accent); outline: none;
  }
  .drawer__form ul.errorlist {
    margin: 2px 0 0; padding: 0; list-style: none;
    font-size: 11px; color: var(--danger);
  }
  .drawer__error {
    padding: 8px 10px; background: var(--danger-soft); border: 1px solid var(--danger);
    border-radius: var(--radius-sm); font-size: 12px; color: var(--danger);
  }
  .drawer__actions {
    display: flex; gap: 8px; justify-content: flex-end;
    padding-top: 8px; border-top: 1px solid var(--border);
  }

  /* ─── page help · the "?" beside a page title and its side panel ───
     controltower/includes/page_help_{button,panel}.html. Every page with an
     entry in apps/controltower/explanations/ gets one: in the shared <h1> of
     dashboards/_base.html, or placed by hand where a page draws its own title. */
  /* The button FOLLOWS the <h1> (never inside it, or a screen reader reads
     the heading as "Hotel desk What does this page show?"); :has() keeps the
     two on one line without a wrapper, so `main > h1` rules still apply. */
  h1:has(+ .page-help-button) { display: inline-block; }
  /* Baseline alignment centres the 28px circle on the 26px title's capitals
     (both ~9px above the baseline, measured in Chrome); a raised offset left
     the "?" floating above the title. */
  h1 + .page-help-button { margin-left: 8px; vertical-align: baseline; }
  main > h1 + .page-help-button { animation: shell-rise .42s var(--ease) both; animation-delay: .06s; }
  .page-help-eyebrow {
    margin: 0 0 6px; color: var(--text-muted); font-size: 12px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
  }
  .page-help-notices { margin: 0; padding-left: 18px; }
  .page-help-notices li + li { margin-top: 6px; }
  /* A warning about a defect names it: docs/KNOWN_ISSUES.md ID. */
  .page-help-issue {
    display: inline-block; padding: 0 7px; border-radius: 999px;
    border: 1px solid var(--warning-line); background: var(--warning-soft);
    color: var(--warning-ink); font-size: 11px; font-weight: 600; white-space: nowrap;
  }
  .page-help-button {
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
  }

  .page-help-button svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
  }

  /* background: the global button:hover would otherwise fill the circle blue,
     hiding the blue "?" inside it. */
  .page-help-button:hover,
  .page-help-button:focus-visible {
    background: var(--surface);
    border-color: var(--accent);
    color: var(--accent);
  }

  /* Hidden unless open — also in a browser without popover support, which would
     otherwise render the panel inline at the top of the page. */
  .page-help-panel {
    display: none;
  }

  .page-help-panel:popover-open {
    display: block;
    position: fixed;
    inset: 0 0 0 auto;
    width: min(480px, 100vw);
    height: 100%;
    max-height: none;
    margin: 0;
    padding: 20px 22px 32px;
    overflow-y: auto;
    border: 0;
    border-left: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-lg);
    line-height: 1.5;
  }

  .page-help-panel::backdrop {
    background: rgba(16, 32, 53, 0.25);
  }

  .page-help-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
  }

  /* The global h2 is a small uppercase section label with a rule under it;
     this one is the panel's title. */
  .page-help-head h2 {
    margin: 2px 0 8px;
    padding: 0;
    border: 0;
    color: var(--text);
    font-size: 20px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
  }

  .page-help-close {
    padding: 0 6px;
    border: 0;
    background: none;
    color: var(--text-muted);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
  }

  .page-help-audience {
    color: var(--text-muted);
  }

  .page-help-panel h3 {
    margin: 22px 0 6px;
    font-size: 14px;
  }

  .page-help-list {
    margin: 0;
  }

  .page-help-list > div {
    padding: 10px 0;
    border-top: 1px solid var(--border-soft);
  }

  .page-help-list dt {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-weight: 600;
  }

  .page-help-list dd {
    margin: 4px 0 0;
    overflow-wrap: anywhere;
  }

  .page-help-list dd p {
    margin: 4px 0 0;
  }

  /* The shared pill capitalises each word; these labels are sentences. */
  .page-help-list .controltower-pill {
    text-transform: none;
  }

  /* ─── 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: var(--success-line); 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; }

  /* Flight desk (2026-10-08): the view tabs with the page's one action beside
     them, the everyday filters on one row, airport / airline filters behind a
     disclosure that opens itself when one is set. Dropdowns apply on change
     (form[data-autosubmit], app.js); the search applies on Enter or Apply. */
  .flight-desk-head {
    display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
    gap: 8px 16px; border-bottom: 1px solid var(--border); margin: 0 0 var(--space-3);
  }
  .flight-desk-head .page-tabs { border-bottom: 0; margin: 0; }
  .flight-desk-head > .btn { margin-bottom: 6px; }
  .flight-filters {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius-sm); padding: 12px 14px; margin: 0 0 8px;
  }
  .flight-filters__row {
    display: grid; gap: 10px 14px; align-items: end;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr));
  }
  .flight-filters label {
    display: flex; flex-direction: column; gap: 3px; min-width: 0;
    font-size: 12px; color: var(--text-muted);
  }
  .flight-filters label > select,
  .flight-filters label > input { width: 100%; min-width: 0; }
  .flight-filters__search { grid-column: span 2; }
  @media (min-width: 1100px) {
    .flight-filters__row--main {
      grid-template-columns: minmax(200px, 2fr) repeat(4, minmax(110px, 1fr)) auto;
    }
    .flight-filters__row--main .flight-filters__search { grid-column: auto; }
  }
  .flight-filters__actions { display: flex; gap: 8px; align-items: center; min-height: 34px; }
  .flight-filters__more { margin-top: 10px; }
  .flight-filters__more > summary {
    cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--accent-deep);
    width: fit-content;
  }
  .flight-filters__more[open] > summary { margin-bottom: 8px; }
  .flight-filters__summary { margin: 0 0 var(--space-3); font-size: 13px; }
  @media (max-width: 640px) {
    .flight-filters__search { grid-column: 1 / -1; }
    .flight-desk-head > .btn { margin-bottom: 8px; }
  }

  .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; }
  /* A checkbox row reads box-then-words wherever it sits. The selector list
     out-weighs every column-flex label rule above (`details.card > form label`
     is 0,1,3), so a `label.check` never stacks its box above its text. */
  label.check,
  :is(.form-grid, .form-row, .routing-form, details.card > form) label.check {
    display: inline-flex; flex-direction: row; align-items: center; gap: 6px;
  }
  label.check > input,
  :is(.form-grid, .form-row, .routing-form, details.card > form) label.check > input { width: auto; margin: 0; }
  /* A vertical list of checkbox rows (flight legs, flights to add to a tour). */
  fieldset.check-list { display: grid; gap: 4px; border: 0; margin: 0; padding: 0; min-width: 0; }
  fieldset.check-list > legend { font-size: 12px; color: var(--text-muted); padding: 0; margin-bottom: 4px; }
  fieldset.check-list label.check { font-size: 13px; color: var(--text); font-weight: 400; }
  /* A field or fieldset that takes the whole row of a .form-grid (reasons,
     notes, checkbox lists, small tables). */
  .form-grid > .span-2 { grid-column: 1 / -1; }
  .form-grid > fieldset.span-2 { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 8px 12px; margin: 0; min-width: 0; }
  .form-grid > fieldset.span-2.check-list { border: 0; padding: 0; }
  .form-grid > fieldset.span-2 > legend { font-size: 12px; color: var(--text-muted); padding: 0 4px; }
  /* A heading that opens a group of fields inside one .form-grid form. */
  .form-grid > p.form-section { grid-column: 1 / -1; margin: 4px 0 -2px; padding-top: 10px; border-top: 1px solid var(--border-soft);
    font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
  .form-grid > p.form-section:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
  .form-grid > p.form-section small { font-size: 11px; font-weight: 400; letter-spacing: 0; text-transform: none; }
  .form-grid > button, .form-grid > .form-actions { justify-self: start; }
  /* A small grid of inputs inside a form (cancellation steps): each column
     sized to what it holds, never squeezed to the header's width. */
  table.input-table { width: auto; }
  table.input-table td { padding: 3px 6px; }
  table.input-table input { width: 100%; min-width: 0; }
  table.input-table .col-days input { width: 6em; }
  table.input-table .col-amount input { width: 8em; }
  table.input-table .col-pct input { width: 5.5em; }
  table.input-table .col-note input { width: 18em; }

  /* 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; }
  /* Booking page passenger table: how a guest flies and is met, read-only
     chips with one edit control, and one flight per direction. */
  .pax-travel { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
  .pax-travel .pill { padding: 1px 8px; font-size: 11.5px; }
  .pax-travel__none, .pax-leg__none { color: var(--text-subtle); font-size: 12px; }
  .pax-travel__note { grid-column: span 2; margin: 0; align-self: end; color: var(--text-muted); font-size: 12px; }
  .pax-leg { white-space: nowrap; }
  .pax-leg__src { display: block; font-size: 11px; color: var(--text-muted); }
  /* Booking page: one guest's charges, one per line, amount aligned right. */
  .guest-charge { display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px; }
  .pre-invoice-new { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
  .pre-invoice-new__guests fieldset { border: 1px solid var(--border-soft); border-radius: 8px; padding: 6px 10px; margin: 0 0 6px; display: flex; flex-wrap: wrap; gap: 4px 16px; }
  .pre-invoice-new__guests legend { font-size: 12px; color: var(--text-muted); padding: 0 4px; }
  .pre-invoice-new__guests label.check { display: inline-flex; gap: 5px; align-items: center; font-size: 12.5px; }
  .pre-invoice-new__guests label.check > input { width: auto; }
  /* Private transfer guest picker: one row of checkboxes per booking. */
  .pt-guests { grid-column: 1 / -1; border: 1px solid var(--border-soft); border-radius: 8px; padding: 8px 10px; margin: 0; max-height: 220px; overflow-y: auto; }
  .pt-guests legend { font-size: 12px; font-weight: 600; padding: 0 4px; }
  .pt-guests__booking { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; padding: 3px 0; }
  .pt-guests__label { font-size: 11.5px; color: var(--text-muted); min-width: 150px; }
  .pt-guests label.check { display: inline-flex; flex-direction: row; gap: 5px; font-size: 12.5px; }
  .pt-guests label.check > input { width: auto; }
  /* 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) {
    /* The rail is fixed at the left of the content area, so the content
       starts right after it instead of centring away from it (which left an
       empty band between the two on wide screens). */
    body:has(.toc-rail) main { padding-left: 212px; margin-left: 0; }
  }
  /* Hide the rail on narrow viewports — operators on small screens scroll. */
  @media (max-width: 1239px) { .toc-rail { display: none; } }
  .task-filter-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 12px; }

  /* ─── notifications inbox: one card per notice, grouped by day ─── */
  .notice-bar { display: flex; gap: var(--space-3); align-items: center; justify-content: space-between;
    flex-wrap: wrap; margin-bottom: var(--space-3); }
  .notice-bar .task-filter-chips { margin: 0; }
  .notice-count { display: inline-block; min-width: 1.4em; padding: 0 5px; margin-left: 4px; border-radius: 9px;
    background: var(--surface-2); color: var(--text); font-size: 11px; text-align: center; }
  .chip-active .notice-count { background: var(--surface); color: var(--accent-deep); }
  .notice-day { margin: 0 0 var(--space-5); }
  .notice-day__title { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted);
    margin: 0 0 var(--space-2); border: none; padding: 0; }
  .notice-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
  .notice { background: var(--surface); border: 1px solid var(--border); border-left: 3px solid transparent;
    border-radius: var(--radius); padding: var(--space-3) var(--space-4); box-shadow: var(--shadow-sm); }
  .notice--unread { border-left-color: var(--accent); }
  .notice--unread.notice--warning { border-left-color: var(--warning); }
  .notice--unread.notice--critical { border-left-color: var(--danger); }
  .notice:not(.notice--unread) { opacity: .8; }
  .notice:not(.notice--unread) .notice__title { font-weight: 500; }
  .notice__head { display: flex; gap: var(--space-2) var(--space-3); align-items: baseline; }
  .notice__title { flex: 1 1 auto; font-size: 14px; line-height: 1.4; overflow-wrap: anywhere; }
  .notice__time { flex: none; color: var(--text-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
  .notice__body { color: var(--text-muted); font-size: 13px; line-height: 1.5; margin-top: var(--space-1);
    white-space: normal; overflow-wrap: anywhere; }
  .notice__body--clamped { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
  .notice__more > summary { list-style: none; cursor: pointer; }
  .notice__more > summary::-webkit-details-marker { display: none; }
  .notice__more[open] .notice__body--clamped { display: none; }
  .notice__toggle { display: inline-block; margin-top: 2px; font-size: 12px; color: var(--accent-deep); }
  .notice__more[open] .notice__toggle { display: none; }
  .notice__foot { display: flex; gap: var(--space-2) var(--space-3); align-items: center; flex-wrap: wrap;
    margin-top: var(--space-2); font-size: 12px; }
  .notice__foot form { margin: 0; }
  .notice__foot .muted:first-child { margin-right: auto; }
  .notice-empty { padding: var(--space-6); }
  @media (max-width: 560px) {
    .notice__head { flex-wrap: wrap; }
    .notice__time { order: -1; width: 100%; }
  }
  .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: 28px; margin-left: auto; }
  }
  @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: var(--warning-ink);
  }
  .callout--warn a { color: inherit; text-decoration: underline; }

  /* ─── Kalk (tour pricing) ─── assumptions grouped in fieldsets; one pin
     row per source currency reads "1 EUR = [175] JPY". */
  .kalk-fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 12px; margin: 12px 0; }
  .kalk-fieldset > legend { font-size: 12px; color: var(--text-muted); padding: 0 4px; }
  .kalk-pin { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0; font-size: 13px; }
  .kalk-pin input { width: 9em; }
  .kalk-scenarios tr.kalk-target th, .kalk-scenarios tr.kalk-sell th { white-space: nowrap; }
  .kalk-reasons { font-size: 12px; margin: 4px 0 12px; }
  .kalk-adopt { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; }

  /* ─── 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); }
  p.error, .field-error { color: var(--danger); }
  .field-error { display: block; font-size: 11px; font-weight: 400; margin-top: 2px; }
  [aria-invalid="true"] { border-color: var(--danger) !important; }

  /* ─── 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-editing td { background: var(--accent-soft); }
  tr.is-editing td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
  .impact-line { font-size: 12.5px; color: var(--text-muted); min-height: 1.4em; }
  .impact-line.warn { color: var(--warning); font-weight: 500; }
  .readiness { display: flex; flex-wrap: wrap; gap: 4px; }
  .price-cell { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
  .price-input { width: 8.5em; text-align: right; font-variant-numeric: tabular-nums; }
  .price-input.is-below-cost { border-color: var(--warning); box-shadow: 0 0 0 2px color-mix(in srgb, var(--warning) 25%, transparent); }
  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; }

  /* Page destinations (the product year's Programme · Costing · Prices …):
     the same treatment as the People & Access tabs below — separate padded
     items, a flex row that wraps on a narrow screen, the current one marked
     by weight and an underline as well as colour, a visible focus ring.
     Plain links, not an ARIA tab widget. */
  .page-tabs {
    display: flex; flex-wrap: wrap; gap: 4px 2px; align-items: flex-end;
    border-bottom: 1px solid var(--border); margin: 0 0 var(--space-3);
  }
  .page-tab {
    display: inline-block; padding: 8px 14px; font-size: 13.5px; font-weight: 500;
    color: var(--text-muted); text-decoration: none; white-space: nowrap;
    border-bottom: 2px solid transparent; margin-bottom: -1px;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  }
  .page-tab:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
  .page-tab.is-active, .page-tab[aria-current="page"] {
    color: var(--accent-deep); border-bottom-color: var(--accent); font-weight: 650;
    background: var(--surface);
  }
  .page-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; z-index: 1; }
  .page-tab-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 var(--space-3); }
  @media (max-width: 640px) {
    .page-tab { padding: 7px 10px; white-space: normal; }
  }

  /* Program operations (2026-10-07): a readable summary row per activity,
     its work in a panel below — never one very wide table. */
  .program-ops__detail {
    display: grid; gap: var(--space-3) var(--space-5);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
    padding: var(--space-2) 0;
  }
  .program-ops__detail section { min-width: 0; }
  .program-ops__detail h4 { margin: 0 0 6px; font-size: 13px; }
  .program-ops__brief { margin: 0 0 6px; white-space: normal; }
  .program-ops__cost { margin: 0 0 8px; }
  .program-ops__line { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin: 0 0 6px; }
  .program-ops__attendance { border: 0; padding: 0; margin: 0; display: grid; gap: 4px; }
  .program-ops__attendance legend { font-size: 12px; color: var(--text-muted); padding: 0; }
  .program-ops td { vertical-align: top; }

  /* 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: var(--success-ink); border-color: var(--success-line); font-weight: 600; }
  .pa-cap--lose { background: var(--danger-soft); color: var(--danger-ink); border-color: var(--danger-line); font-weight: 600; }
  .pa-cap--keep { background: var(--accent-soft); color: var(--accent-deep); border-color: var(--accent-line); }
  .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: var(--accent-line); }
  .pa-badge--staffed  { background: var(--success-soft); color: var(--success-ink); border-color: var(--success-line); }
  .pa-badge--standard { background: var(--surface-3); color: var(--text); }
  .pa-badge--routing  { background: var(--purple-soft); color: var(--purple-ink); border-color: var(--purple-line); }
  .pa-badge--uncovered{ background: var(--warning-soft); color: var(--warning-ink); border-color: var(--warning-line); }
  .pa-badge--review   { background: var(--danger-soft); color: var(--danger-ink); border-color: var(--danger-line); }

  /* 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: var(--warning-ink);
  }
  .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. The shared :focus-visible rule (inputs section) already
     draws this outline; this workspace is keyboard-heavy (a long matrix of
     checkboxes and a review step nobody should be able to trigger blind), so
     it also rounds the ring to the control's shape. */
  .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; }
  }

  /* Plain pills only: :where() drops this below `.pill.ok` & co., whose
     -line tokens already carry their dark border. */
  [data-theme="dark"] :where(.pill) { border-color: var(--border); }
  [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"] .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's tinted pairs read the -ink / -line tokens, so they
     need no dark overrides of their own. */
  [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; }

  /* ── Action row ─────────────────────────────────────────────────────────
     The same field layout as a filter bar, for a POST that changes data
     (assign the ticked rows, save lead times). Its submit stays the form's
     one primary button — a filter bar's is drawn as a ghost on purpose. */
  .action-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
    margin: 0 0 10px; }
  .action-row__field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; }
  .action-row__field > span { color: var(--text-subtle); text-transform: uppercase;
    letter-spacing: .04em; font-size: 9px; }
  .action-row__field input, .action-row__field select { font-size: 12px; width: auto; }
  .action-row__check { display: inline-flex; align-items: center; gap: 5px;
    font-size: 12px; color: var(--text-muted); padding-bottom: 6px; }
  .action-row__check input { width: auto; margin: 0; }
  .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; }

/* ── Compact forms (2026-10-02) ───────────────────────────────────────────
   Fields sized to what they hold, not to a grid cell. `.form-row` is the
   create-form sibling of `.filter-bar`: labels stack above their control,
   the row wraps, nothing stretches. Width utilities beat the `.form-grid`
   full-width rule so a 3-letter code or a 2-digit count stays small anywhere. */
.form-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  align-items: end;
}
/* The field that takes the row's remaining width (a note, a description). */
.form-row > label.grow { flex: 1 1 260px; }
.form-row > label.grow > :is(input, textarea) { width: 100%; box-sizing: border-box; }
.form-row > label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 12px;
  color: var(--text-muted);
}
.form-row + .form-row { margin-top: var(--space-4); }
:is(.form-row, .form-grid, .flight-legs) :is(input, select).input-code,
input.input-code { width: 6.5em; min-width: 0; text-transform: uppercase; }
input.input-code::placeholder { text-transform: none; }
:is(.form-row, .form-grid, .flight-legs) input.input-count,
input.input-count { width: 6.5em; min-width: 0; max-width: 6.5em; }
:is(.form-row, .form-grid, .flight-legs) input.input-short,
input.input-short { width: 8.5em; min-width: 0; }
:is(.form-row, .form-grid, .flight-legs) input.input-medium,
input.input-medium { width: 14em; min-width: 0; }
:is(.form-row, .form-grid, .flight-legs) input.input-date,
input.input-date { width: 10.5em; min-width: 0; }
:is(.form-row, .form-grid, .flight-legs) input.input-time,
input.input-time { width: 8em; min-width: 0; }
:is(.form-row, .form-grid) select.input-auto { width: auto; }

/* Record a requested allotment: one flight per row, every cell wide enough
   for what it holds (a 3-letter airport, a flight number, a date). */
table.allotment-legs-form td { padding: 3px 4px; }
table.allotment-legs-form :is(input, select) { padding: 6px 8px; }
table.allotment-legs-form select { width: auto; min-width: 7.5em; }
table.allotment-legs-form input.input-code { width: 4.6em; font-family: var(--font-mono); }
table.allotment-legs-form input.input-flight { width: 6.5em; font-family: var(--font-mono); text-transform: uppercase; }
table.allotment-legs-form input[type="number"] { width: 4.6em; min-width: 0; }
table.allotment-legs-form input[type="date"] { width: 9.5em; }
table.allotment-legs-form input[type="time"] { width: 7em; }

/* Tour flight status: one pill when the tour's record and the airline agree,
   two only when they differ (title carries both facts either way). */
.leg-status { display: inline-flex; flex-wrap: wrap; gap: 4px; vertical-align: middle; }
.allotment-leg-remove { margin-top: 6px; }

/* Booking lines: the description stays one readable line; where the price
   and commission come from opens on request (DESIGN §7.2 — rows stay short). */
.commercial-breakdown td.breakdown-desc { white-space: normal; max-width: 440px; }
.breakdown-note { font-size: 11px; color: var(--text-muted); }
.breakdown-source { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
details.more.breakdown-source > summary, details.more.breakdown-source[open] > summary { font-size: 11px; margin-bottom: 0; }
.breakdown-source > div { margin-top: 2px; }
.commercial-breakdown .pill.bad { font-size: 11px; }

/* Confirmation dialog (DESIGN §7.1/§7.7): the one confirmation step, a native
   <dialog> over a dimmed backdrop. Its title is a heading, not the global
   uppercase h2 label. */
.confirm-dialog {
  border: 1px solid var(--border); border-radius: var(--radius); padding: 0;
  background: var(--surface); color: var(--text); box-shadow: var(--shadow-lg);
  width: min(460px, calc(100vw - 32px));
}
.confirm-dialog::backdrop { background: rgba(15, 23, 42, .45); }
.confirm-dialog__form { padding: 18px 20px 16px; margin: 0; }
.confirm-dialog h2.confirm-dialog__title {
  margin: 0 0 8px; padding: 0; border: 0; font-size: 16px; font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--text);
}
.confirm-dialog__body { margin: 0 0 16px; font-size: 14px; line-height: 1.45; white-space: pre-line; color: var(--text); }
.confirm-dialog__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }

/* Booking page action bar: Confirm (the one primary), the deadline, and
   "More actions" — corrections and the cancellation behind one disclosure,
   opened as a panel across the page. */
.booking-actions { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 16px; }
.booking-actions > form { margin: 0; }
.booking-actions__more > summary { list-style: none; display: inline-flex; width: fit-content; }
.booking-actions__more > summary::-webkit-details-marker { display: none; }
.booking-actions__more > summary::after { content: "▾"; margin-left: 6px; font-size: 10px; }
.booking-actions__more[open] > summary::after { content: "▴"; }
/* The panel floats under the whole bar (a menu of forms), so opening it never
   moves the button that opened it. */
.booking-actions__panel {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-md); padding: 4px 14px;
}
.booking-actions__section { padding: 10px 0; }
.booking-actions__section + .booking-actions__section { border-top: 1px solid var(--border-soft); }
.booking-actions__section.callout { margin: 10px 0; padding: 10px 12px; }
.booking-actions__section > h3 { margin: 0 0 6px; font-size: 13px; }
.booking-actions__section > p { margin: 0 0 8px; font-size: 12.5px; }
.booking-actions__hint { font-size: 11px; margin: 0; }


/* Shared allotment page: the airline's answer for every flight in one form,
   the rules behind a read-more line, the terms that can be filled now. */
details.card.allotment-answer { padding: 0; margin: 10px 0; }
.allotment-answer > summary { padding: 8px 14px; cursor: pointer; font-weight: 600; color: var(--accent); }
.allotment-answer > form { padding: 0 14px 12px; }
table.allotment-answer__table { width: auto; box-shadow: none; margin: 0 0 10px; }
table.allotment-answer__table input[type="number"] { width: 5.5em; min-width: 0; padding: 4px 8px; }
.allotment-rules { margin: 4px 0 10px; }
.allotment-fillable { margin: 0 0 12px; }
.allotment-fillable .form-row { align-items: center; }
.terms-fieldset { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 8px 12px 10px; margin: 0; min-width: 0; }
.terms-fieldset > legend { font-size: 12px; font-weight: 600; color: var(--text-muted); padding: 0 4px; }

/* Tour page airport-option card: figures, then the legs as a compact table
   (walkthrough 6: each leg was a sentence of eight numbers). */
.option-figures { display: flex; flex-wrap: wrap; gap: 4px 22px; margin: 8px 0; }
.option-figures > div { display: flex; flex-direction: column; }
.option-figures dt { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; font-weight: 600; }
.option-figures dd { margin: 0; font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.option-figures__note dd { font-size: 13px; font-weight: 500; color: var(--text-muted); }
table.option-legs { margin: 6px 0; box-shadow: none; }
.option-city-warning { margin: 6px 0; font-size: 12.5px; }
.option-card__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 12.5px; }
.option-card__foot > form { margin: 0; }

/* Booking PAX: the explicit "put unassigned guests on an airport option". */
.pax-assign-options { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 12px 0 0; font-size: 13px; }
.pax-assign-options > form { margin: 0; }
.pax-own-flights { margin-top: 8px; }
.pax-own-flights h4 { margin: 6px 0 4px; font-size: 12px; color: var(--text-muted); }

/* Option deadline chips beside a deadline field. */
.deadline-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
@media (min-width: 720px) { .form-grid > .deadline-field { grid-column: span 2; } .deadline-field { flex-direction: row; flex-wrap: wrap; align-items: flex-end; gap: 6px 10px; } .deadline-presets { padding-bottom: 6px; } }
.deadline-field > label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--text-muted); }
.deadline-presets { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.chip-button {
  background: var(--surface); color: var(--accent-deep); border: 1px solid var(--accent-line);
  border-radius: 999px; padding: 2px 9px; font-size: 11.5px; font-weight: 500; line-height: 1.5; cursor: pointer;
}
.chip-button:hover { background: var(--accent-soft); }

/* New booking: places per airport option, as a small table with a live sum. */
.option-places { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 8px 12px; margin: 0; min-width: 0; }
.option-places > legend { font-size: 12px; color: var(--text-muted); padding: 0 4px; }
table.option-places__table { width: auto; box-shadow: none; }
table.option-places__table input[type="number"] { width: 5em; min-width: 0; padding: 4px 8px; }
.option-places__sum { margin: 6px 0 0; font-size: 12px; color: var(--success-ink); }
.option-places__sum.is-off { color: var(--warning-ink); font-weight: 600; }
.new-booking__prefill { margin: 0; font-size: 12.5px; }

/* Ops desk validation issues: the issue in words, its check code a small
   reference underneath; Info notices fold below the table. */
.validation-issues__code { display: block; font-size: 11px; color: var(--text-subtle); }
.validation-issues__info { margin: 6px 0 var(--space-5); }
.option-form__legs { margin-top: var(--space-3); }

/* Two journeys of a group flight, one compact row each. */
.flight-legs {
  display: grid;
  grid-template-columns: max-content repeat(5, max-content);
  gap: var(--space-3) var(--space-5);
  align-items: center;
  margin: var(--space-5) 0;
  font-size: 13px;
}
.flight-legs__head { font-size: 11px; color: var(--text-muted); text-transform: uppercase; }
@media (max-width: 720px) {
  .flight-legs { grid-template-columns: repeat(2, max-content); }
  .flight-legs__head { display: none; }
}

/* Per-guest additional-package rows: one guest per line. Without the
   doubled selector `details.card > form label` would stack every pill. */
details.card > form label.ap-guest-row,
label.ap-guest-row {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center;
  gap: var(--space-2) var(--space-3); font-size: 13px; color: var(--text);
  padding: var(--space-1) 0; border-bottom: 1px solid var(--border);
}
label.ap-guest-row:last-child { border-bottom: 0; }
.ap-guest-row__name { min-width: 14em; font-weight: 500; }

/* A flash shown after a save that kept the reading position
   (app.js "Keep the reading position across a save"): it floats in view
   instead of sitting at the top, off screen. Back in flow when dismissed. */
.flash-stack--floating {
  position: fixed; top: 64px; right: 24px; z-index: 60;
  width: min(32rem, calc(100vw - 32px)); margin: 0;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .18); border-radius: var(--radius);
}
.flash-stack__close { display: none; }
.flash-stack--floating .flash-stack__close {
  display: block; position: absolute; top: 4px; right: 6px;
  border: 0; background: none; font-size: 18px; line-height: 1; cursor: pointer;
  color: inherit; padding: 4px 6px;
}
.flash-stack--floating .flash-group { padding-right: 32px; }
@media (max-width: 640px) { .flash-stack--floating { top: 56px; right: 16px; } }

/* Small inline action chip on a routing line ("leave venue open"). It used
   to inherit the full primary-button style, which made a rarely-needed
   toggle the loudest thing on every line. */
.chip-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 8px; min-height: 0; border-radius: 999px;
  border: 1px solid var(--border); background: transparent;
  color: var(--text-muted); font-size: 11px; font-weight: 500; line-height: 18px;
  cursor: pointer; box-shadow: none;
}
.chip-btn:hover { border-color: var(--accent-line); color: var(--accent); background: var(--accent-soft); }

/* A day need that a routing line declares is a read-out of that line, not a
   switch (RoutingDay.line_declared_needs) — same pill, no pointer. */
.need-pill--locked { cursor: default; }

/* Product page: description beside its facts (product_detail.html). */
.product-head { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(260px, 1fr); gap: var(--space-4); align-items: start; margin: 0 0 var(--space-5); }
.product-head__text { padding: 18px 22px; }
.product-head__text > :first-child { margin-top: 0; }
.product-head__para { margin: 0 0 10px; line-height: 1.6; }
/* the global .lead caps at 76ch; the intro spans the card like the lists below it */
.product-head__para.lead { max-width: none; }
.product-head__heading { margin: 14px 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.product-head__list { margin: 0 0 6px; padding-left: 18px; columns: 2 280px; column-gap: 28px; line-height: 1.55; }
.product-head__list li { break-inside: avoid; margin: 0 0 4px; }
.product-head__facts { position: sticky; top: calc(var(--topbar-h, 56px) + 12px); }
@media (max-width: 900px) { .product-head { grid-template-columns: 1fr; } .product-head__facts { position: static; } }

/* Departure generation preview (season_departures_preview.html): one card per
   departure, collapsed after the first; the deadlines get the width. */
.gen-preview { padding: 0; margin: 0 0 var(--space-3, 12px); overflow: hidden; }
.gen-preview__head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding: 12px 16px; cursor: pointer; list-style: none; }
.gen-preview__head::-webkit-details-marker { display: none; }
.gen-preview__head::before { content: "▸"; color: var(--text-muted); transition: transform .15s; }
.gen-preview[open] > .gen-preview__head::before { transform: rotate(90deg); }
.gen-preview[open] > .gen-preview__head { border-bottom: 1px solid var(--border); }
.gen-preview__code { font-weight: 600; font-size: 15px; }
.gen-preview__dates { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.gen-preview__countries { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.gen-preview__unknown { margin-left: auto; }
.gen-preview__body { display: grid; grid-template-columns: minmax(240px, 1fr) minmax(0, 2.4fr); gap: 20px 28px; padding: 16px; align-items: start; }
.gen-preview__side { display: grid; gap: 16px; }
.gen-preview h3 { margin: 0 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.gen-preview__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; font-size: 13px; line-height: 1.45; }
.gen-preview__when { margin-left: 6px; font-variant-numeric: tabular-nums; }
.gen-preview__deadlines { font-size: 13px; }
.gen-preview__deadlines td { vertical-align: top; white-space: normal; }
.gen-preview__deadlines td:last-child { min-width: 220px; }
.gen-preview__deadlines td:nth-child(2), .gen-preview__deadlines td.gen-preview__date { white-space: nowrap; }
.gen-preview .pill { white-space: nowrap; }
.gen-preview__date { white-space: nowrap; font-weight: 600; font-variant-numeric: tabular-nums; }
.gen-preview__unresolved { margin: 0 16px 16px; }
.gen-preview__unresolved ul { margin: 6px 0; padding-left: 18px; }
.gen-preview__unresolved p { margin: 0; }
@media (max-width: 900px) { .gen-preview__body { grid-template-columns: 1fr; } .gen-preview__unknown { margin-left: 0; } }

/* Product description: the intro shows, the rest folds (product_detail.html);
   the edit page explains the format (_description_format_help.html). */
.product-head__more > summary { cursor: pointer; color: var(--accent); font-size: 13px; margin: 6px 0 2px; }
.product-head__more > summary .product-head__more-hide { display: none; }
.product-head__more[open] > summary .product-head__more-show { display: none; }
.product-head__more[open] > summary .product-head__more-hide { display: inline; }
.format-help > summary { cursor: pointer; color: var(--accent); font-size: 13px; }
.format-help__body { margin-top: 8px; padding: 10px 14px; background: var(--surface-2); border-radius: var(--radius); font-size: 13px; }
.format-help__body ul { margin: 0 0 8px; padding-left: 18px; }
.format-help__sample { margin: 4px 0 0; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px; white-space: pre-wrap; }

/* ── Filter bars (2026-10-20 audit) ─────────────────────────────────────
   A filter form's submit is a secondary action: the page's one primary is
   whatever creates or saves. Every GET filter bar's button reads as a ghost
   button from here, whichever markup variant the page uses, and a checkbox
   in a filter bar sits beside its label, not under it. */
.filter-bar > button:not(.danger), .filter-bar .filter-actions > button:not(.danger),
.filter-bar > .btn:not(.ghost):not(.danger), .filter-bar .filter-actions > .btn:not(.ghost):not(.danger),
.controltower-filters > button, .controltower-filter-actions > button,
.pa-filters__actions > button:not(.danger), .flight-filters__actions > button,
.pipeline-filters__row > button, form.card.filter-card > button {
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
}
.filter-bar > button:not(.danger):hover, .filter-bar .filter-actions > button:not(.danger):hover,
.filter-bar > .btn:not(.ghost):not(.danger):hover, .filter-bar .filter-actions > .btn:not(.ghost):not(.danger):hover,
.controltower-filters > button:hover, .controltower-filter-actions > button:hover,
.pa-filters__actions > button:not(.danger):hover, .flight-filters__actions > button:hover,
.pipeline-filters__row > button:hover, form.card.filter-card > button:hover {
  background: var(--surface-2); border-color: var(--accent); color: var(--accent-deep);
}
.filter-bar > label.check, .filter-bar label.check { flex-direction: row; align-items: center; gap: 6px; padding-bottom: 8px; }
.filter-bar > label.check > input, .filter-bar label.check > input { width: auto; margin: 0; }
/* A filter form drawn as a card (legs, operators, bus companies, guide roster). */
form.card.filter-card { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: end; padding: var(--space-3) var(--space-4); }
form.card.filter-card > label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--text-muted); }

/* ── Pagination (shared with the Control Tower; the rule lives here so the
   /dashboard/ lists that paginate read it too) ── */
.controltower-pagination {
  display: flex; justify-content: flex-end; align-items: center; gap: 14px;
  margin-top: 18px; font-size: 13px; color: var(--text-muted);
}
.controltower-pagination a {
  padding: 3px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-muted); text-decoration: none;
}
.controltower-pagination a:hover { color: var(--accent-deep); border-color: var(--accent); text-decoration: none; }

/* ── Empty state (2026-10-20 audit) ──
   One shape for "there is nothing here": a quiet dashed box with the fact,
   why it is empty or what the healthy state means, and the one next step.
   `td.empty` stays for a table with headers; this is for a page or section
   that would otherwise be a bare italic line. */
.empty-state {
  text-align: center; padding: 28px 16px; margin: 0 0 var(--space-4);
  border: 1px dashed var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text-subtle); font-size: 13px;
}
.empty-state__title { margin: 0; font-size: 14px; font-weight: 600; color: var(--text); }
.empty-state__hint { margin: 4px 0 0; max-width: 60ch; margin-left: auto; margin-right: auto; }
.empty-state .btn, .empty-state button { margin-top: 12px; }
.empty-state--ok .empty-state__title { color: var(--success-ink); }
/* The Control Tower's one-line empties take the same voice as `td.empty`. */
/* Duty Control's My work / All work switch: the current scope reads as a
   selected segment, the other as a link. */
.controltower-scope { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0 12px; font-size: 13px; color: var(--text-subtle); }
.controltower-scope > strong { background: var(--accent-soft); color: var(--accent-deep); border: 1px solid var(--accent-line); border-radius: 999px; padding: 2px 10px; font-weight: 600; }
.controltower-scope > a { padding: 2px 10px; border-radius: 999px; }
.controltower-scope > a:hover { background: var(--surface-2); }
.controltower-empty { margin: 20px 0 0; color: var(--text-subtle); font-style: italic; text-align: center; padding: 20px 14px; }

/* ── "More" disclosure (2026-10-20 audit) ──
   A native <details> whose summary is a plain link-coloured line with a
   triangle: how these numbers are defined, the lifecycle key, airports &
   airline. "+ Add X" forms are `details.card`; this is for reading more. */
details.more > summary {
  cursor: pointer; list-style: none; width: fit-content;
  color: var(--accent-deep); font-size: 13px; font-weight: 600;
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::before { content: "▸ "; }
details.more[open] > summary::before { content: "▾ "; }
details.more[open] > summary { margin-bottom: 8px; }

/* An htmx request in flight: the button that sent it dims until the swap
   lands, so "Edit plan" and its kin are never clicked twice. */
.btn.htmx-request, button.htmx-request { opacity: .55; pointer-events: none; }

/* Commission rule tables (policy page, agreement page): a rule's source note
   is a sentence, so the first two columns wrap; the table used to overflow
   its card and grow a scrollbar (2026-10-20 audit). */
.commission-rules td:nth-child(1), .commission-rules td:nth-child(2) { white-space: normal; min-width: 14ch; }
.commission-rules td:nth-child(1) small { display: block; max-width: 60ch; line-height: 1.35; }

/* A grouped reason inside a callout (Kalk's "needed by 27 services") opens
   its list from a plain summary line. */
.callout details > summary { cursor: pointer; font-size: 12px; color: var(--accent-deep); font-weight: 600; }
/* `.empty` outside a table cell (a section with nothing in it) keeps the
   voice but not a table cell's height. */
p.empty { padding: 10px 14px !important; margin: 0 0 var(--space-3); }

/* ── Add departures (season page, 2026-10-21) ──
   The dates list and a picker that appends to it, side by side; the one
   primary button under the field, with what it does not do beside it. */
.add-departures { padding: var(--space-4) var(--space-5); }
.add-departures__lead { margin: 0 0 var(--space-4); max-width: 70ch; }
.add-departures__grid {
  display: grid; grid-template-columns: minmax(220px, 300px) minmax(200px, 280px);
  gap: var(--space-4) var(--space-6); align-items: start;
}
.add-departures__dates { display: flex; flex-direction: column; gap: 4px; }
.add-departures__dates textarea {
  font-family: var(--font-mono); font-size: 13px; line-height: 1.55;
  min-height: 9.5em; resize: vertical; width: 100%;
}
.add-departures__pick { display: flex; flex-direction: column; gap: 8px; }
.add-departures__pick > label { display: flex; flex-direction: column; gap: 4px; }
.add-departures__pick input[type="date"] { width: 100%; }
.add-departures__pick .btn { align-self: flex-start; }
.add-departures__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; margin-top: var(--space-4); }
@media (max-width: 640px) { .add-departures__grid { grid-template-columns: 1fr; } }

/* Hotel planning rates: how a year's amount moved against the row before it. */
.rate-change { font-size: 11px; color: var(--text-subtle); margin-left: 4px; font-variant-numeric: tabular-nums; }
.rate-change.is-up { color: var(--danger-ink); }
.rate-change.is-down { color: var(--success-ink); }


/* The package library's participant ladder (decisions: package-resource-bands):
   group sizes 1..capacity as one strip, a segment per band, gap or size below
   the package's minimum. */
.band-strip { display: flex; gap: 2px; margin: 6px 0 10px; font-size: 11px; line-height: 20px; }
.band-strip__seg { min-width: 18px; text-align: center; border-radius: 3px; overflow: hidden; white-space: nowrap; }
.band-strip__seg--covered { background: var(--success-soft); color: var(--success-ink); border: 1px solid var(--success-line); }
.band-strip__seg--gap { background: var(--warning-soft); color: var(--warning-ink); border: 1px dashed var(--warning-line); }
.band-strip__seg--below_minimum { background: var(--surface-2); color: var(--text-subtle); border: 1px solid var(--border); }
.band-actions { white-space: nowrap; }
.band-actions .btn, .band-actions button { padding: 2px 8px; font-size: 12px; }

/* Product year Versions tab: what changed between two publications. */
.change-step { margin-bottom: var(--space-3); }
.change-step h3 { margin: 0 0 6px; font-size: 15px; }
.change-step h4 { margin: 10px 0 4px; font-size: 13px; }
.change-step details > summary { cursor: pointer; margin-top: 10px; font-size: 13px; font-weight: 600; }
.change-days { margin: 4px 0 0; padding-left: 18px; }
.change-days > li { margin: 6px 0; }
.change-days ul { margin: 2px 0 0; padding-left: 18px; font-size: 13px; }
.change-days .pill { padding: 0 6px; font-size: 11.5px; }

/* ── Segmented choice ─────────────────────────────────────────────────────
   A handful of exclusive options as one control: real radio buttons (the
   form posts and validates as before), drawn as segments. The radio covers
   its segment, so the whole segment is the click and focus target. */
.seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; }
.seg__opt { position: relative; display: inline-flex; align-items: center;
  min-height: 28px; padding: 0 12px; border-radius: 6px; border: 1px solid transparent;
  font-size: 12.5px; font-weight: 500; color: var(--text-muted); cursor: pointer;
  transition: background-color .15s ease, color .15s ease; }
.seg__opt input { position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer; }
.seg__opt:hover { color: var(--text); }
.seg__opt:has(input:checked) { background: var(--surface); color: var(--accent-deep);
  font-weight: 600; border-color: var(--accent-line); box-shadow: var(--shadow-sm); }
.seg__opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── New booking (decisions: new-booking-entry) ───────────────────────────
   The finder is one card: who and what on the first row, the narrowing
   fields and the submit on the second. Each result list has a head line
   (title, count, the way out to the full list), the table, then its notes. */
.nb-finder { display: flex; flex-direction: column; gap: var(--space-3);
  max-width: 880px; margin-top: var(--space-3); }
.nb-finder__row { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; }
.nb-finder__operator { flex: 0 1 300px; min-width: 220px; }
.nb-finder__operator select { width: 100%; }
.nb-finder__kind { border: 0; padding: 0; margin: 0; min-width: 0; }
.nb-finder__kind > legend { padding: 0; margin-bottom: 2px; color: var(--text-subtle);
  text-transform: uppercase; letter-spacing: .04em; font-size: 9px; }
.nb-finder__narrow { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; }
.nb-finder__narrow[hidden] { display: none; }
.nb-finder__narrow select, .nb-finder__narrow input { width: auto; }
.nb-finder__row > .btn { padding: 7px 14px; font-size: 13px; }
.nb-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 4px var(--space-3); margin: var(--space-5) 0 var(--space-2);
  padding-bottom: 8px; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; }
.nb-head h2 { margin: 0; padding: 0; border: 0; }
.nb-table td { vertical-align: middle; white-space: nowrap; }
.nb-table th.num, .nb-table td.num { text-align: right; }
.nb-table .nb-action { text-align: right; width: 1%; }
.nb-table tr.nb-full td { color: var(--text-subtle); }
.nb-empty { padding: var(--space-3) var(--space-4); }
.nb-foot { margin-top: var(--space-2); max-width: 100ch; }
.nb-foot .note { margin: 0 0 4px; }

/* A stay's two notes on every hotel-team surface (`_hotel_stay_notes.html`):
   the must-have the hotel is told, and the note for the hotel team, which is
   internal and stands out because it is the reason behind the ask. */
.hotel-note { font-size: 11.5px; margin-top: 3px; max-width: 320px; line-height: 1.35; }
.hotel-note--team { padding: 2px 6px; border-left: 2px solid var(--accent); background: var(--accent-soft, rgba(37, 99, 235, .06)); border-radius: 2px; }
.programme-day__hotel-note { cursor: help; }
