/*
 * fra-schedule.css — the FRA dispatch board.
 *
 * FRA-OWNED FORK of schedule.css, by way of its Fire Stopping twin. Fire risk assessment is a
 * separate app surface and must not depend on fire-door module CSS: app/Views/layout/app.php
 * swaps ONE of the three files in by page key, so this file has to be complete on its own.
 *
 * ⚠ THE FORK IS DELIBERATE. Do not propose deduplicating the three boards into a shared file —
 * fix all three sides.
 *
 * ⛔ WHAT WAS ACTUALLY REMOVED, AND NOTHING ELSE (corrected 2026-09-22 — an earlier version of
 * this comment claimed two removals that had not happened, which is the one thing a re-sync reads
 * this header for): the twin's own "Fire Stopping only" block at the end of the file, i.e.
 * `.sched--fs .sched-blk[data-module="fire_doors"]` / `.sched-chip[...]`, its `__grip` rule,
 * `.sched--combined .sched-lane__cap--muted`, `.sched-combine:hover` and the ≤900px
 * `.sched-combine` rule. Everything else is the twin's board section verbatim, and PLUS nothing.
 *
 * ⚠ SO `.sched-combine` (4 rules) AND `.sched-typecheck*` (20 selectors) ARE STILL HERE, MATCHING
 * NOTHING — the FRA board renders neither control. They are kept so the three files stay
 * line-comparable for a future re-sync; see the note at the end of this file.
 *
 * ⛔ NO DARK MODE. Out of scope permanently, and every customer-facing surface is hard
 * light-locked.
 *
 * ⛔ NO OVERRIDES OF SHARED PRIMITIVES. `.ipi-page-header`, `.ipi-ph-*`, `.ipi-filter-rail`,
 * `.ipi-stats-strip` and `.tnt-filter-drawer` are owned by inspections_shell.css /
 * fire-stopping-shell.css / fra-shell.css and tnt-filter-drawer.css. The page root carries
 * `.inspections-page` and `.fra-page`, which is what makes their fallback-free `--ipi-*` tokens
 * resolve — 24 override rules existed in the FS twin before its root class was fixed.
 *
 * Breakpoint: 900px, the app standard. No new ones.
 */

/* ═══════════════════════════════════════════════════════════════════════════
   Tokens. Page-scoped, with fallbacks, so nothing silently resolves to nothing.
   ═══════════════════════════════════════════════════════════════════════════ */

.page-section--schedule {
  /* Event colours, unchanged from the calendar so the app stays consistent. */
  --sch-type-inspection: #2563a8;
  --sch-type-prebooking: #c49510;
  --sch-type-firedoor: #6b46c1;
  --sch-type-remedial: #1e7a45;
  --sch-type-survey: #2563a8;
  --sch-type-defect: #b45309;

  --sch-ink: var(--ink, var(--ink));
  --sch-ink-2: var(--ink-2, var(--ink-2));
  --sch-ink-3: var(--ink-3, var(--ink-3));
  --sch-ink-4: var(--ink-4, var(--ink-4));
  --sch-card: var(--surface-card, #ffffff);
  --sch-canvas: var(--canvas, var(--canvas));
  --sch-subtle: var(--surface-subtle, var(--surface-subtle));
  --sch-inset: var(--surface-inset, var(--surface-inset));
  --sch-rule: color-mix(in srgb, var(--ink) 9%, transparent);
  --sch-rule-2: color-mix(in srgb, var(--ink) 16%, transparent);
  --sch-accent: var(--accent, #c49510);
  --sch-accent-ink: var(--accent-ink, #7a5c05);
  --sch-accent-soft: rgba(196, 149, 16, 0.12);
  --sch-ok: var(--success, #1e7a45);
  --sch-bad: var(--danger, #b03030);
  --sch-bad-soft: rgba(176, 48, 48, 0.09);
  --sch-shadow: 0 1px 4px color-mix(in srgb, var(--ink) 6%, transparent), 0 0 0 1px color-mix(in srgb, var(--ink) 5%, transparent);
  --sch-shadow-lift: 0 14px 34px color-mix(in srgb, var(--ink) 12%, transparent), 0 2px 6px color-mix(in srgb, var(--ink) 6%, transparent);

  --sch-lane-who: 168px;
  --sch-lane-min-h: 78px;
  --sch-radius: 10px;
}

.page-section--schedule .schedule-workspace {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.page-section--schedule .schedule-shell {
  min-width: 0;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Shell
   ═══════════════════════════════════════════════════════════════════════════ */

.sched {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  padding: 0 var(--ipi-page-gutter, 28px) 22px;
  position: relative;
}

/* Expand: a CLASS, not a DOM transplant. The old "Enlarge" appended the whole
   calendar card into a modal and the modal into the page section, then restored
   both with insertBefore — so any re-render between open and close left the card
   parented in the wrong place. */
.sched--expanded {
  position: fixed;
  inset: 0;
  /* ⛔ ABOVE THE TOPBAR (z-index 100), or "expand" is a trap: the board covered
     the page but the topbar painted over its command bar, so the Expand button
     that leaves the mode was itself unclickable. */
  z-index: 120;
  background: var(--sch-canvas);
  overflow: auto;
  padding: 14px 18px 18px;
}

body.schedule-expanded {
  overflow: hidden;
}

body.schedule-expanded .ipi-page-header,
body.schedule-expanded .sched-filters .ipi-filter-rail {
  display: none;
}

/* ⚠ Only the RAIL goes in Expand at <=900px. The filter drawer lives inside
   .sched-filters, so hiding the whole block left the command bar's Filters
   button opening nothing. Above 900px the filters are an inline row and Expand
   is for screen space, so they go. */
@media (min-width: 901px) {
  body.schedule-expanded .sched-filters {
    display: none;
  }
}

/* The popover is a sibling of .sched, not a child, so in Expand it is lifted
   over the expanded layer (z-index 120) or a tapped block opens nothing visible. */
body.schedule-expanded .sched-pop {
  z-index: 130;
}

/* ── command bar ────────────────────────────────────────────────────────── */

.sched-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 0 12px;
  min-width: 0;
}

.sched-bar__title {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--sch-ink);
}

.sched-bar__spacer {
  flex: 1 1 auto;
  min-width: 0;
}

.sched-bar__tools {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  min-width: 0;
}

.sched-nav {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--sch-rule-2);
  border-radius: 9px;
  overflow: hidden;
  background: var(--sch-card);
  flex: 0 0 auto;
}

.sched-nav__btn,
.sched-nav__today {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sch-ink-2);
  font: 600 12.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  padding: 9px 11px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
}

.sched-nav__btn svg {
  width: 15px;
  height: 15px;
}

.sched-nav__today {
  border-inline: 1px solid var(--sch-rule);
  padding-inline: 13px;
}

.sched-nav__btn:hover,
.sched-nav__today:hover {
  background: var(--sch-subtle);
  color: var(--sch-ink);
}

.sched-when {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--sch-ink);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  flex: 0 1 auto;
}

.sched-views {
  display: inline-flex;
  background: var(--sch-inset);
  border: 1px solid var(--sch-rule);
  border-radius: 9px;
  padding: 3px;
  gap: 2px;
  flex: 0 0 auto;
}

.sched-view {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sch-ink-3);
  font: 600 12.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  padding: 7px 13px;
  border-radius: 6px;
  cursor: pointer;
  min-height: 30px;
}

.sched-view.is-active {
  background: var(--sch-card);
  color: var(--sch-ink);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--ink) 10%, transparent);
}

/* buttons. Black/white only — never brand-colour a button. */
.sched-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--sch-rule-2);
  background: var(--sch-card);
  color: var(--sch-ink);
  border-radius: 9px;
  padding: 8px 12px;
  font: 600 12.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  cursor: pointer;
  min-height: 36px;
  white-space: nowrap;
  text-decoration: none;
}

.sched-btn svg {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}

.sched-btn:hover {
  background: var(--sch-subtle);
}

.sched-btn--primary {
  background: var(--button-primary, var(--ink));
  border-color: var(--button-primary, var(--ink));
  color: var(--button-primary-text, #ffffff);
}

.sched-btn--primary:hover {
  background: var(--button-primary-dark, var(--ink-2));
  border-color: var(--button-primary-dark, var(--ink-2));
}

.sched-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--sch-ink-3);
}

.sched-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.sched-btn__count,
.ipi-filter-railbtn__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--sch-accent);
  color: #241c00;
  font: 700 10.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
}

.sched-combine {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--sch-rule-2);
  background: var(--sch-card);
  border-radius: 9px;
  padding: 8px 12px;
  font: 600 12.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink-2);
  min-height: 36px;
  cursor: pointer;
}

.sched-combine input {
  width: 15px;
  height: 15px;
  margin: 0;
}

/* ── filters ────────────────────────────────────────────────────────────── */

.sched-filters {
  margin-bottom: 12px;
  min-width: 0;
}

.sched-filter-bar {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.sched-filter-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sched-filter-group__label,
.sched-field__label,
.sched-field > span {
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
  margin: 0;
}


.sched-typecheck {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid transparent;
  font-size: 13.5px;
  color: var(--sch-ink-2);
  cursor: pointer;
  min-height: 40px;
}

.sched-typecheck:hover {
  background: var(--sch-subtle);
}

.sched-typecheck input {
  width: 16px;
  height: 16px;
  margin: 0;
  flex: 0 0 auto;
}

.sched-typecheck__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--sch-ink-4);
}

.sched-typecheck__dot--inspection,
.sched-typecheck__dot--survey,
.sched-typecheck__dot--assessment { background: var(--sch-type-inspection); }
.sched-typecheck__dot--remedial { background: var(--sch-type-remedial); }
.sched-typecheck__dot--fire_door { background: var(--sch-type-firedoor); }
.sched-typecheck__dot--pre_booking { background: var(--sch-type-prebooking); }
.sched-typecheck__dot--defect { background: var(--sch-type-defect); }

.sched-typecheck__label {
  flex: 1 1 auto;
  min-width: 0;
}

/* The hint was only a `title` tooltip, which a touch screen never shows. It is
   printed under the label inside the phone sheet instead. */
.sched-typecheck__hint {
  display: none;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--sch-ink-3);
}

.sched-typecheck__count {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
  color: var(--sch-ink-4);
}

.sched-filter-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.sched-filter-field select,
.sched-filter-field input {
  min-height: 40px;
  padding: 10px 13px;
  border-radius: 9px;
  border: 1px solid var(--sch-rule-2);
  background: var(--sch-card);
  font-size: 13.5px;
  color: var(--sch-ink);
  width: 100%;
  box-sizing: border-box;
}

.sched-filter-field.ipi-filter-search {
  position: relative;
  flex-direction: row;
  align-items: center;
}

.sched-filter-field.ipi-filter-search svg {
  position: absolute;
  left: 12px;
  width: 15px;
  height: 15px;
  color: var(--sch-ink-4);
  pointer-events: none;
}

.sched-filter-field.ipi-filter-search input {
  padding-left: 34px;
  padding-right: 34px;
}

.sched-search-clear {
  position: absolute;
  right: 8px;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sch-ink-3);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
}

.sched-filter-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.sched-filter-actions .sched-btn {
  justify-content: center;
}

.sched-typechecks {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* ⚠ ABOVE 900px THE CANONICAL DRAWER UNWRAPS ITSELF.
   tnt-filter-drawer.css sets `.tnt-filter-drawer { display: contents }` on
   desktop and hides its own head, foot and overlay, so the controls inside
   render INLINE on the page — that is the primitive's design, not a bug, and it
   is why clients, team and analytics all show their filters as a row up here.
   The first build of this board assumed the drawer stayed shut on desktop and
   got a full-height column of filters shoving the lanes below the fold.
   So: a compact row here, a column inside the sheet at <=900px. */
@media (min-width: 901px) {
  /* The rail card and the command bar's Filters button are both mobile
     affordances — the controls are already on screen up here. */
  .sched-filters .ipi-filter-rail,
  .sched-bar [data-sched-filters-open],
  .sched-filter-actions {
    display: none;
  }

  .sched-filter-bar {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding: 10px 14px;
    background: var(--sch-card);
    border: 1px solid var(--sch-rule);
    border-radius: 12px;
    box-shadow: var(--sch-shadow);
  }

  .sched-filter-group {
    flex-direction: row;
    align-items: center;
    gap: 10px;
    min-width: 0;
  }

  .sched-typechecks {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 2px;
  }

  .sched-typecheck {
    min-height: 32px;
    padding: 5px 9px;
    font-size: 12.5px;
  }

  .sched-filter-field {
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }

  .sched-filter-field > span:not(.sr-only) {
    flex: 0 0 auto;
  }

  .sched-filter-field select {
    min-height: 34px;
    padding: 7px 11px;
    font-size: 12.5px;
    width: auto;
    min-width: 132px;
  }

  .sched-filter-field.ipi-filter-search {
    flex: 1 1 200px;
    max-width: 320px;
  }

  .sched-filter-field.ipi-filter-search input {
    min-height: 34px;
    padding-block: 7px;
    font-size: 12.5px;
  }
}


/* ═══════════════════════════════════════════════════════════════════════════
   Body: tray + board
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-body {
  display: grid;
  grid-template-columns: 262px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  min-width: 0;
}

.sched-body:not(:has(.sched-tray)) {
  grid-template-columns: minmax(0, 1fr);
}

/* ⛔ :has(.sched-tray) IS LOAD-BEARING — see the fire-door twin in schedule.css.
   A role that cannot create work gets no tray, .sched--tray-open is never set, and
   without this guard the board is squeezed into a 52px column. */
.sched:not(.sched--tray-open) .sched-body:has(.sched-tray) {
  grid-template-columns: 52px minmax(0, 1fr);
}

/* ── tray ───────────────────────────────────────────────────────────────── */

.sched-tray {
  background: var(--sch-card);
  border: 1px solid var(--sch-rule);
  border-radius: 14px;
  box-shadow: var(--sch-shadow);
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  position: sticky;
  top: 12px;
  max-height: calc(100vh - 140px);
  /* dvh, so iPad Safari's toolbars do not cut the bottom of the list off. */
  max-height: calc(100dvh - 140px);
}

/* The whole head is the toggle. The 26px button alone was the only way to open
   the phone sheet, and "Need help?" sat on top of it. */
.sched-tray__head {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 13px 14px 11px;
  border-bottom: 1px solid var(--sch-rule);
  min-width: 0;
  cursor: pointer;
}

.sched-tray__head > div {
  flex: 1 1 auto;
  min-width: 0;
}

.sched-tray__title {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0;
  color: var(--sch-ink);
}

.sched-tray__hint {
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--sch-ink-3);
  margin: 3px 0 0;
}

.sched-tray__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--sch-inset);
  color: var(--sch-ink-2);
  font: 700 11.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}

.sched-tray__collapse {
  appearance: none;
  border: 1px solid var(--sch-rule-2);
  background: var(--sch-card);
  color: var(--sch-ink-3);
  border-radius: 7px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: 0 0 auto;
}

.sched-tray__collapse svg {
  width: 13px;
  height: 13px;
}

.sched-tray__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  overflow-y: auto;
  min-height: 0;
  /* On a phone the list is a scroller inside a fixed sheet over the scrolling
     board. Contained, so a swipe that reaches either end does not hand the
     gesture to the board behind and leave the list looking stuck. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.sched-tray__empty {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--sch-ink-3);
  margin: 0;
  padding: 6px 2px;
}

.sched:not(.sched--tray-open) .sched-tray__list,
.sched:not(.sched--tray-open) .sched-tray__head > div {
  display: none;
}

.sched:not(.sched--tray-open) .sched-tray {
  max-height: none;
}

.sched:not(.sched--tray-open) .sched-tray__collapse svg {
  transform: rotate(180deg);
}

/* tray cards */
.sched-card {
  border: 1px solid var(--sch-rule);
  border-left: 3px solid var(--sch-ink-4);
  border-radius: 9px;
  background: var(--sch-card);
  padding: 9px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  box-shadow: var(--sch-shadow);
  cursor: grab;
  min-width: 0;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.sched-card--inspection, .sched-card--survey, .sched-card--assessment { border-left-color: var(--sch-type-inspection); }
.sched-card--remedial { border-left-color: var(--sch-type-remedial); }
.sched-card--fire_door { border-left-color: var(--sch-type-firedoor); }
.sched-card--pre_booking { border-left-color: var(--sch-type-prebooking); }
.sched-card--defect { border-left-color: var(--sch-type-defect); }

.sched-card:focus-visible,
.sched-blk:focus-visible,
.sched-chip:focus-visible {
  outline: 2px solid var(--sch-accent);
  outline-offset: 2px;
}

.sched-card__title {
  font: 600 12.5px/1.35 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink);
  overflow-wrap: anywhere;
}

.sched-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--sch-ink-3);
}

.sched-card__type {
  font-style: normal;
  font-weight: 600;
  color: var(--sch-ink-2);
}

.sched-card__mins {
  font-variant-numeric: tabular-nums;
  margin-left: auto;
}

.sched-card__due {
  font-size: 11px;
  color: var(--sch-accent-ink);
  font-weight: 600;
}

.sched-card--armed {
  border-color: var(--sch-accent);
  box-shadow: 0 0 0 2px var(--sch-accent-soft), var(--sch-shadow);
}

.sched-card.is-dragging,
.sched-chip.is-dragging,
.sched-blk.is-dragging {
  opacity: 0.5;
  cursor: grabbing;
}

/* ── board ──────────────────────────────────────────────────────────────── */

.sched-board {
  background: var(--sch-card);
  border: 1px solid var(--sch-rule);
  border-radius: 14px;
  box-shadow: var(--sch-shadow);
  overflow: hidden;
  min-width: 0;
}

.sched-board__loading,
.sched-board__empty {
  margin: 0;
  padding: 40px 22px;
  text-align: center;
  font-size: 13.5px;
  color: var(--sch-ink-3);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Day view — people × hours
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-day {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sched-ruler {
  display: grid;
  grid-template-columns: var(--sch-lane-who) minmax(0, 1fr);
  border-bottom: 1px solid var(--sch-rule);
  background: var(--sch-subtle);
}

.sched-ruler__who {
  padding: 9px 14px;
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
  border-right: 1px solid var(--sch-rule);
}

.sched-ruler__track {
  position: relative;
  min-height: 30px;
  min-width: 0;
}

.sched-ruler__tick {
  position: absolute;
  top: 9px;
  font: 600 10px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink-4);
  font-variant-numeric: tabular-nums;
  padding-left: 5px;
  border-left: 1px solid var(--sch-rule);
  padding-bottom: 2px;
}

/* "No time yet" strip. Work whose start the server FABRICATED from a date must
   not be drawn as a confident block at 09:00 — see meta.time_confirmed. */
.sched-notime {
  border-bottom: 1px solid var(--sch-rule);
  background: color-mix(in srgb, var(--sch-accent-soft) 55%, var(--sch-card));
  padding: 10px 14px 12px;
}

.sched-notime__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}

.sched-notime__label {
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-accent-ink);
}

.sched-notime__hint {
  font-size: 11.5px;
  color: var(--sch-ink-3);
}

.sched-notime__items {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.sched-lane {
  display: grid;
  grid-template-columns: var(--sch-lane-who) minmax(0, 1fr);
  border-bottom: 1px solid var(--sch-rule);
  min-height: var(--sch-lane-min-h);
}

.sched-lane:last-child {
  border-bottom: 0;
}

.sched-lane--unassigned {
  background: color-mix(in srgb, var(--sch-subtle) 60%, var(--sch-card));
}

.sched-lane__who {
  border-right: 1px solid var(--sch-rule);
  padding: 11px 14px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  justify-content: center;
  min-width: 0;
}

.sched-lane__name {
  font: 600 12.5px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink);
  overflow-wrap: anywhere;
}

.sched-lane__cap,
.sched-lane__needs {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 10.5px;
  color: var(--sch-ink-3);
  font-variant-numeric: tabular-nums;
}

.sched-lane__cap--muted {
  color: var(--sch-ink-4);
  font-style: italic;
}

.sched-lane__needs {
  color: var(--sch-bad);
  font-weight: 600;
}

.sched-lane__bar {
  display: block;
  width: 58px;
  height: 4px;
  border-radius: 2px;
  background: var(--sch-inset);
  overflow: hidden;
  flex: 0 0 auto;
}

.sched-lane__bar i {
  display: block;
  height: 100%;
  background: var(--sch-ok);
}

.sched-lane__bar.is-near i { background: var(--sch-accent); }
.sched-lane__bar.is-over i { background: var(--sch-bad); }

.sched-slots {
  position: relative;
  min-width: 0;
  min-height: var(--sch-lane-min-h);
  /* ⛔ NO touch-action HERE, nor on the week and month cells. They are drop
     TARGETS, not drag handles, and between them they cover most of the board:
     `none` on them meant a swipe starting anywhere on the board could not scroll
     the page. Draggable items carry `manipulation`, and the module stops native
     scrolling itself only once a long-press has lifted the item. */
}

.sched-slots__line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--sch-rule);
  opacity: 0.8;
}

.sched-slots--target {
  background: var(--sch-accent-soft);
}

.sched--drag-clash .sched-slots--target {
  background: var(--sch-bad-soft);
}

/* blocks */
.sched-blk {
  position: absolute;
  top: 8px;
  bottom: 8px;
  border-radius: 7px;
  padding: 6px 9px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  cursor: grab;
  min-width: 0;
  background: var(--sch-card);
  border: 1px solid var(--sch-rule-2);
  border-left: 3px solid var(--sch-ink-4);
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.sched-blk--inspection, .sched-blk--survey, .sched-blk--assessment {
  border-left-color: var(--sch-type-inspection);
  background: color-mix(in srgb, var(--sch-type-inspection) 10%, var(--sch-card));
  border-color: color-mix(in srgb, var(--sch-type-inspection) 32%, var(--sch-card));
}
.sched-blk--remedial {
  border-left-color: var(--sch-type-remedial);
  background: color-mix(in srgb, var(--sch-type-remedial) 10%, var(--sch-card));
  border-color: color-mix(in srgb, var(--sch-type-remedial) 32%, var(--sch-card));
}
.sched-blk--fire_door {
  border-left-color: var(--sch-type-firedoor);
  background: color-mix(in srgb, var(--sch-type-firedoor) 10%, var(--sch-card));
  border-color: color-mix(in srgb, var(--sch-type-firedoor) 32%, var(--sch-card));
}
.sched-blk--pre_booking {
  border-left-color: var(--sch-type-prebooking);
  background: color-mix(in srgb, var(--sch-type-prebooking) 12%, var(--sch-card));
  border-color: color-mix(in srgb, var(--sch-type-prebooking) 34%, var(--sch-card));
}
.sched-blk--defect {
  border-left-color: var(--sch-type-defect);
  background: color-mix(in srgb, var(--sch-type-defect) 10%, var(--sch-card));
  border-color: color-mix(in srgb, var(--sch-type-defect) 32%, var(--sch-card));
}

.sched-blk__title {
  font: 600 11.5px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sched-blk__when {
  font-size: 10.5px;
  color: var(--sch-ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sched-blk__grip {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 8px;
  cursor: ew-resize;
  border-radius: 0 6px 6px 0;
  background: currentColor;
  opacity: 0.16;
}

.sched-blk--readonly {
  cursor: default;
  opacity: 0.72;
  border-style: dashed;
}

.sched-blk--clash {
  outline: 2px dashed var(--sch-bad);
  outline-offset: 1px;
}

.sched-blk--highlight {
  outline: 2px solid var(--sch-accent);
  outline-offset: 2px;
}

/* overflow gutters — work outside 07:00–19:00 is counted, never lost */
.sched-gutter {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  appearance: none;
  border: 1px dashed var(--sch-rule-2);
  background: var(--sch-subtle);
  color: var(--sch-ink-3);
  font: 600 10px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  padding: 5px 7px;
  border-radius: 6px;
  cursor: pointer;
  z-index: 2;
}

.sched-gutter--before { left: 3px; }
.sched-gutter--after { right: 3px; }

/* the live drop verdict */
.sched-drop-hint {
  position: absolute;
  left: 8px;
  bottom: 4px;
  z-index: 5;
  padding: 3px 8px;
  border-radius: 999px;
  font: 600 10.5px/1.5 var(--font-sans, "Inter", system-ui, sans-serif);
  background: var(--sch-card);
  border: 1px solid var(--sch-rule-2);
  color: var(--sch-ink-2);
  pointer-events: none;
  white-space: nowrap;
  max-width: calc(100% - 16px);
  overflow: hidden;
  text-overflow: ellipsis;
}

.sched-drop-hint--fits { border-color: var(--sch-ok); color: var(--sch-ok); }
.sched-drop-hint--clash { border-color: var(--sch-bad); color: var(--sch-bad); }
.sched-drop-hint--over { border-color: var(--sch-accent); color: var(--sch-accent-ink); }

/* ═══════════════════════════════════════════════════════════════════════════
   Week view — people × days
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-week {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sched-week__head,
.sched-week__lane {
  display: grid;
  grid-template-columns: var(--sch-lane-who) repeat(7, minmax(0, 1fr));
  border-bottom: 1px solid var(--sch-rule);
}

.sched-week__head {
  background: var(--sch-subtle);
}

.sched-week__who {
  padding: 9px 14px;
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
  border-right: 1px solid var(--sch-rule);
}

.sched-week__day {
  padding: 8px 6px;
  border-left: 1px solid var(--sch-rule);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
}

.sched-week__day.is-today {
  background: var(--sch-accent-soft);
}

.sched-week__dow {
  font: 600 9.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
}

.sched-week__dnum {
  font: 700 13px/1 var(--font-display, "Space Grotesk", system-ui, sans-serif);
  color: var(--sch-ink-2);
  font-variant-numeric: tabular-nums;
}

.sched-week__lane:last-child {
  border-bottom: 0;
}

.sched-week__lane--unassigned {
  background: color-mix(in srgb, var(--sch-subtle) 60%, var(--sch-card));
}

.sched-week__cell {
  border-left: 1px solid var(--sch-rule);
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 72px;
  min-width: 0;
}

.sched-week__cell.is-today {
  background: color-mix(in srgb, var(--sch-accent-soft) 40%, transparent);
}

.sched-week__cell--target {
  background: var(--sch-accent-soft);
  position: relative;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Month view — a normal calendar grid, kept because it is what people scan
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-month {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sched-month__head {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--sch-subtle);
  border-bottom: 1px solid var(--sch-rule);
}

.sched-month__head span {
  padding: 9px 10px;
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
  border-left: 1px solid var(--sch-rule);
}

.sched-month__head span:first-child {
  border-left: 0;
}

.sched-month__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-auto-rows: minmax(96px, auto);
}

.sched-month__cell {
  position: relative;
  border-left: 1px solid var(--sch-rule);
  border-bottom: 1px solid var(--sch-rule);
  padding: 6px 6px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.sched-month__cell:nth-child(7n + 1) {
  border-left: 0;
}

.sched-month__cell.is-outside {
  background: var(--sch-subtle);
}

.sched-month__cell.is-today .sched-month__num {
  background: var(--sch-accent);
  color: #241c00;
  border-radius: 999px;
  width: 21px;
  height: 21px;
  display: grid;
  place-items: center;
  font-weight: 700;
}

.sched-month__cell--target {
  background: var(--sch-accent-soft);
}

.sched-month__num {
  font: 600 12px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink-3);
  font-variant-numeric: tabular-nums;
}

.sched-month__cell.is-outside .sched-month__num {
  color: var(--sch-ink-4);
}

.sched-month__add {
  position: absolute;
  right: 5px;
  top: 5px;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  border: 1px dashed var(--sch-rule-2);
  background: var(--sch-card);
  color: var(--sch-ink-4);
  display: grid;
  place-items: center;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.14s ease;
}

.sched-month__cell:hover .sched-month__add,
.sched-month__add:focus-visible {
  opacity: 1;
}

/* A touch screen has no hover, so the `+` must not depend on one. */
@media (hover: none) {
  .sched-month__add {
    opacity: 1;
  }
}

/* The phone month cell: dots and a count, and the whole cell opens that day.
   Hidden above 900px, where the chips are readable. */
.sched-month__peek {
  display: none;
}

/* chips — used in week, month and the no-time strip */
.sched-chip {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 6px;
  border: 0;
  border-left: 3px solid var(--sch-ink-4);
  border-radius: 5px;
  background: var(--sch-subtle);
  padding: 4px 7px;
  font: 500 11.5px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  color: var(--sch-ink);
  cursor: grab;
  text-align: left;
  min-width: 0;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.sched-chip--inspection, .sched-chip--survey, .sched-chip--assessment {
  border-left-color: var(--sch-type-inspection);
  background: color-mix(in srgb, var(--sch-type-inspection) 9%, var(--sch-card));
}
.sched-chip--remedial {
  border-left-color: var(--sch-type-remedial);
  background: color-mix(in srgb, var(--sch-type-remedial) 9%, var(--sch-card));
}
.sched-chip--fire_door {
  border-left-color: var(--sch-type-firedoor);
  background: color-mix(in srgb, var(--sch-type-firedoor) 9%, var(--sch-card));
}
.sched-chip--pre_booking {
  border-left-color: var(--sch-type-prebooking);
  background: color-mix(in srgb, var(--sch-type-prebooking) 11%, var(--sch-card));
}
.sched-chip--defect {
  border-left-color: var(--sch-type-defect);
  background: color-mix(in srgb, var(--sch-type-defect) 9%, var(--sch-card));
}

.sched-chip__time {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--sch-ink-3);
  flex: 0 0 auto;
}

.sched-chip__title {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sched-chip__who {
  font-size: 10.5px;
  color: var(--sch-ink-3);
  flex: 0 0 auto;
}

.sched-chip--readonly {
  cursor: default;
  opacity: 0.72;
}

.sched-chip--armed {
  box-shadow: 0 0 0 2px var(--sch-accent);
}

.sched-more {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sch-ink-3);
  font: 600 11px/1.4 var(--font-sans, "Inter", system-ui, sans-serif);
  padding: 2px 6px;
  text-align: left;
  cursor: pointer;
  border-radius: 4px;
}

.sched-more:hover {
  background: var(--sch-subtle);
  color: var(--sch-ink);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Foot
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 11px 2px 0;
  min-width: 0;
}

.sched-foot__hint {
  font-size: 12px;
  line-height: 1.5;
  color: var(--sch-ink-3);
  flex: 1 1 260px;
  min-width: 0;
}

.sched-foot__totals {
  font-size: 12px;
  font-weight: 600;
  color: var(--sch-ink-2);
  font-variant-numeric: tabular-nums;
}

.sched--offline .sched-foot__hint::before {
  content: "Offline — read only. ";
  font-weight: 600;
  color: var(--sch-bad);
}

/* One hint per way of using the board — a mouse, a touch tablet on the time
   axis, and a phone, where lanes are stacked and nothing has an edge to drag.
   Exactly one shows. */
.sched-foot__hint-touch,
.sched-foot__hint-phone {
  display: none;
}

@media (min-width: 901px) and (pointer: coarse) {
  .sched-foot__hint-fine {
    display: none;
  }

  .sched-foot__hint-touch {
    display: inline;
  }
}

/* Placing: a tapped tray card is armed. This bar says so and carries the only
   way out a touch screen has — there is no Escape key there. */
.sched-placing {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  padding: 8px 8px 8px 14px;
  background: var(--sch-card);
  border: 1px solid var(--sch-accent);
  border-radius: 12px;
  box-shadow: 0 0 0 3px var(--sch-accent-soft), var(--sch-shadow);
  min-width: 0;
}

.sched-placing__label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--sch-ink-2);
  overflow-wrap: anywhere;
}

.sched--placing .sched-slots,
.sched--placing .sched-week__cell,
.sched--placing .sched-month__cell {
  cursor: copy;
  box-shadow: inset 0 0 0 1px var(--sch-accent-soft);
}

/* ═══════════════════════════════════════════════════════════════════════════
   The popover
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-pop {
  position: fixed;
  z-index: 70;
  width: min(320px, calc(100vw - 24px));
  background: var(--sch-card);
  border: 1px solid var(--sch-rule-2);
  border-radius: 12px;
  box-shadow: var(--sch-shadow-lift);
  padding: 13px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.sched-pop__head {
  display: flex;
  align-items: flex-start;
  gap: 9px;
}

.sched-pop__ident {
  flex: 1 1 auto;
  min-width: 0;
}

.sched-pop__type {
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-accent-ink);
}

.sched-pop__title {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 0.94rem;
  font-weight: 600;
  margin: 3px 0 0;
  color: var(--sch-ink);
  overflow-wrap: anywhere;
}

.sched-pop__meta {
  font-size: 11.5px;
  color: var(--sch-ink-3);
  margin: 3px 0 0;
}

/* Why the fields are disabled. It was a `title` tooltip on the block, which a
   touch screen never shows. */
.sched-pop__note {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--sch-ink-3);
  margin: 6px 0 0;
}

.sched-pop__close {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sch-ink-3);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 5px;
  flex: 0 0 auto;
}

.sched-pop__form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* The global bare-tag `form` rule styles a form as a card. This form is not
     inside a .modal, so the canonical `.modal form` neutraliser does not reach
     it — hence the explicit reset. */
  background: transparent;
  padding: 0;
  border-radius: 0;
  margin: 0;
}

.sched-pop__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.sched-pop__actions {
  display: flex;
  align-items: center;
  gap: 7px;
  padding-top: 3px;
  border-top: 1px solid var(--sch-rule);
}

.sched-pop__spacer {
  flex: 1 1 auto;
}

.sched-pop__alert,
.sched-alert {
  background: var(--sch-bad-soft);
  border: 1px solid color-mix(in srgb, var(--sch-bad) 35%, transparent);
  color: var(--sch-bad);
  border-radius: 8px;
  padding: 9px 11px;
  font-size: 12.5px;
  line-height: 1.5;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Fields, shared by the popover and the drawer
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.sched-field--span {
  grid-column: 1 / -1;
}

.sched-field input,
.sched-field select,
.sched-field textarea {
  min-height: 40px;
  padding: 10px 13px;
  border-radius: 9px;
  border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent);
  background: var(--sch-card);
  font-size: 13.5px;
  font-family: inherit;
  color: var(--sch-ink);
  width: 100%;
  box-sizing: border-box;
}

/* iOS Safari sizes a native time/date control from its own intrinsic width and
   centres the value inside it, so in the popover's two-column Start | Minutes
   row the Start field ran into Minutes. Drawn as a plain field, it takes the
   grid track's width like the number input beside it; tapping it still opens
   the native picker. */
.sched-field input[type="time"],
.sched-field input[type="date"],
.sched-field input[type="datetime-local"] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  min-width: 0;
  max-width: 100%;
}

.sched-field input::-webkit-date-and-time-value {
  text-align: left;
  margin: 0;
}

.sched-field textarea {
  min-height: 62px;
  resize: vertical;
  line-height: 1.5;
}
.sched-field input:focus-visible,
.sched-field select:focus-visible,
.sched-field textarea:focus-visible {
  outline: 0;
  border-color: var(--accent-strong, #a97807);
  box-shadow: 0 0 0 3px var(--sch-accent-soft);
}

.sched-hint {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--sch-ink-3);
  margin: 0;
}

.sched-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.sched-grid--stack {
  grid-template-columns: minmax(0, 1fr);
}

.sched-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sched-section__title {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--sch-ink);
  margin: 0;
}

.sched-inline {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.sched-inline select {
  flex: 1 1 180px;
  min-width: 0;
}

.sched-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.sched-chip-token {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--sch-inset);
  border-radius: 999px;
  padding: 4px 6px 4px 11px;
  font-size: 12px;
  color: var(--sch-ink-2);
  max-width: 100%;
}

.sched-chip-token > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sched-chip-token__x {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--sch-ink-3);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0 4px;
}

.sched-summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  background: var(--sch-subtle);
  border: 1px solid var(--sch-rule);
  border-radius: 10px;
  padding: 12px 14px;
  flex-wrap: wrap;
}

.sched-summary__label {
  font: 600 10px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
  margin: 0;
}

.sched-summary__title {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--sch-ink);
  margin: 4px 0 0;
  overflow-wrap: anywhere;
}

.sched-summary__meta {
  font-size: 12px;
  color: var(--sch-ink-3);
  margin: 3px 0 0;
}

.sched-summary__badge {
  text-align: right;
  flex: 0 0 auto;
}

.sched-summary__badge span {
  display: block;
  font: 600 9.5px/1.3 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
}

.sched-summary__badge strong {
  font-size: 13px;
  color: var(--sch-ink);
}

.sched-quote-summary {
  background: var(--sch-subtle);
  border: 1px solid var(--sch-rule);
  border-radius: 9px;
  padding: 11px 13px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.sched-quote-summary p {
  margin: 0;
  font-size: 12.5px;
  color: var(--sch-ink-2);
  display: flex;
  gap: 8px;
}

.sched-quote-summary strong {
  font: 600 10px/1.5 var(--font-sans, "Inter", system-ui, sans-serif);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sch-ink-4);
  flex: 0 0 68px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   The drawer + the delete + sync dialogs.

   Canonical modal values. Mobile full-screen behaviour at <=900px is owned by
   style.css and MUST NOT be re-declared here.
   ═══════════════════════════════════════════════════════════════════════════ */

.sched-modal__dialog {
  width: min(680px, calc(100vw - 32px));
  max-height: min(90vh, 960px);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.18), 0 4px 16px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.sched-modal__dialog--stable {
  height: min(85vh, 760px);
  min-height: min(60vh, 520px);
}

.sched-modal__header {
  padding: 20px 22px 16px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  border-bottom: 1px solid var(--sch-rule);
  flex-shrink: 0;
}

.sched-modal__body {
  padding: 20px 22px 22px;
  background: var(--sch-canvas);
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.sched-modal__footer {
  padding: 13px 22px 14px;
  border-top: 1px solid var(--sch-rule);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  background: var(--sch-card);
  flex-shrink: 0;
}

.sched-modal__footer-copy strong {
  display: block;
  font-size: 12.5px;
  color: var(--sch-ink);
}

.sched-modal__footer-copy p {
  margin: 2px 0 0;
  font-size: 11.5px;
  color: var(--sch-ink-3);
}

.sched-modal__footer-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* ⛔ The form wraps body AND footer, so it has to be the flex column or the
   body's `flex: 1; overflow-y: auto` has no constrained parent and the modal
   cannot scroll. */
.sched-modal form,
.sched-drawer__form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  width: 100%;
  background: transparent;
  padding: 0;
  border-radius: 0;
}

.sched-drawer__types {
  display: flex;
  gap: 3px;
  padding: 10px 22px 0;
  background: var(--sch-card);
  flex-shrink: 0;
}

.sched-drawer__type {
  appearance: none;
  border: 0;
  background: var(--sch-inset);
  color: var(--sch-ink-3);
  font: 600 12.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
  padding: 9px 14px;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  min-height: 36px;
}

.sched-drawer__type.is-active {
  background: var(--sch-canvas);
  color: var(--sch-ink);
}

.sched-modal--danger .sched-modal__dialog {
  width: min(520px, calc(100vw - 32px));
}

/* sync */
.sched-sync__body {
  gap: 14px;
}

.sched-sync__tabs {
  flex-shrink: 0;
}

.sched-sync__panel {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.sched-sync__section {
  background: var(--sch-card);
  border: 1px solid var(--sch-rule);
  border-radius: 10px;
  padding: 14px 15px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.sched-sync__section h4 {
  font-family: var(--font-display, "Space Grotesk", system-ui, sans-serif);
  font-size: 0.88rem;
  font-weight: 600;
  margin: 0;
  color: var(--sch-ink);
}

.sched-sync__section--guide ul {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.sched-sync__section--guide li {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--sch-ink-2);
}

.sched-sync__url {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.sched-sync__url input {
  flex: 1 1 220px;
  min-width: 0;
  min-height: 40px;
  padding: 10px 13px;
  border-radius: 9px;
  border: 1px solid var(--sch-rule-2);
  background: var(--sch-subtle);
  font-size: 12.5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--sch-ink-2);
}

.sched-sync__flash {
  margin: 0;
  font-size: 12px;
  color: var(--sch-ok);
  font-weight: 600;
}

.sched-sync__notice {
  margin: 0;
}

.sched-sync__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Tablet — 1024 and 810px are the field devices.

   ⛔ NOT in desktop.css. That file is linked media="(min-width: 1367px)" and is
   inert at 360, 390, 810 and 1024px; a fix placed there reads as applied and
   does nothing. This cost a full verification cycle on 2026-08-24.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ⚠ 1200 and 1024 are NOT layout breakpoints — the page still switches at 900.
   They only narrow the tray and name columns so the 12-hour axis keeps usable
   width on landscape tablets (1024/1180), where tray and lanes sit side by side. */
@media (max-width: 1200px) {
  .page-section--schedule {
    --sch-lane-who: 138px;
  }

  .sched-body {
    grid-template-columns: 226px minmax(0, 1fr);
  }
}

@media (max-width: 1024px) {
  .sched-body {
    grid-template-columns: 196px minmax(0, 1fr);
    gap: 12px;
  }

  .page-section--schedule {
    --sch-lane-who: 124px;
    --sch-lane-min-h: 72px;
  }

  .sched-btn__label {
    display: none;
  }

  /* The week grid stops being readable with a 7-day track this narrow, so it
     scrolls in its own container rather than crushing every column. The page
     body must never scroll sideways. */
  .sched-board--week .sched-week,
  .sched-board--month .sched-month {
    overflow-x: auto;
  }

  .sched-board--week .sched-week__head,
  .sched-board--week .sched-week__lane {
    min-width: 720px;
  }

  /* The names stay put while the days scroll, or a row is anonymous by Thursday. */
  .sched-board--week .sched-week__who,
  .sched-board--week .sched-week__lane > .sched-lane__who {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--sch-card);
  }

  .sched-board--week .sched-week__head > .sched-week__who {
    background: var(--sch-subtle);
  }

  .sched-board--week .sched-week__lane--unassigned > .sched-lane__who {
    background: color-mix(in srgb, var(--sch-subtle) 60%, var(--sch-card));
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Mobile — 900px, the app standard
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  /* The shell's own gutter token (16px here), so the board lines up with the
     header text above it instead of sitting 2px inside it. */
  .sched {
    padding: 0 var(--ipi-page-gutter, 16px) 18px;
  }

  .sched-bar {
    gap: 8px;
    padding: 10px 0;
  }

  .sched-when {
    order: -1;
    flex: 1 1 100%;
    font-size: 1.02rem;
  }

  /* Nav and views share a row when they fit and wrap when they do not. This
     replaces a separate 420px query. */
  .sched-nav {
    flex: 0 0 auto;
  }

  .sched-views {
    flex: 1 1 210px;
  }

  .sched-view {
    flex: 1 1 auto;
    text-align: center;
  }

  .sched-nav__btn,
  .sched-nav__today,
  .sched-view,
  .sched-btn,
  .sched-combine {
    min-height: 44px;
  }

  .sched-nav__btn {
    min-width: 44px;
  }

  .sched-bar__spacer {
    display: none;
  }

  .sched-bar__tools {
    flex: 1 1 100%;
  }

  .sched-bar__tools .sched-btn {
    flex: 1 1 auto;
    justify-content: center;
  }

  /* The primary action gets its own full-width row so it is never the thing
     that wraps off the end. */
  .sched-bar__tools .sched-btn--primary {
    flex: 1 1 100%;
  }

  /* The rail is the mobile entry point to the drawer. */
  .sched-filters .ipi-filter-rail {
    display: flex;
  }

  /* …so the command bar's own Filters button was a second copy of it one row
     up. It comes back only in Expand, where the rail is hidden. */
  .sched-bar [data-sched-filters-open] {
    display: none;
  }

  body.schedule-expanded .sched-bar [data-sched-filters-open] {
    display: inline-flex;
  }

  /* One column: the tray becomes a sheet at the bottom, the board takes the
     screen. */
  .sched-body {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  /* ⛔ :has(.sched-tray) HERE TOO. The collapsed-tray rule above is
     `.sched:not(.sched--tray-open) .sched-body:has(.sched-tray)` — one class
     more specific than this override used to be — so it won at <=900px as well
     and squeezed the board into a 52px column on every phone and iPad portrait.
     The same selector, later in the file, is what lets this one win. */
  .sched:not(.sched--tray-open) .sched-body:has(.sched-tray) {
    grid-template-columns: minmax(0, 1fr);
  }

  .sched-tray {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 55;
    border-radius: 18px 18px 0 0;
    border: 1px solid var(--sch-rule);
    border-bottom: 0;
    box-shadow: 0 -14px 40px color-mix(in srgb, var(--ink) 16%, transparent);
    max-height: min(56vh, 460px);
    max-height: min(56dvh, 460px);
    top: auto;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  /* Closed, the sheet is a 58px bar the board can sit above. Open, it takes
     over half the screen — which is why it does not start open on a phone. */
  .sched:not(.sched--tray-open) .sched-tray {
    max-height: none;
  }

  .sched:not(.sched--tray-open) .sched-tray__head {
    border-bottom: 0;
    align-items: center;
  }

  .sched-tray__collapse {
    width: 44px;
    height: 44px;
  }

  /* A sheet opens upward, so the chevron points up when closed, down when open. */
  .sched-tray__collapse svg {
    transform: rotate(-90deg);
  }

  .sched:not(.sched--tray-open) .sched-tray__collapse svg {
    transform: rotate(90deg);
  }

  .sched:not(.sched--tray-open) .sched-tray__count::after {
    /* \00a0, not a space: the count is a flex box, which strips a pseudo's
       leading whitespace and rendered "7to schedule". */
    content: "\00a0to schedule";
    font-weight: 500;
  }

  .sched:not(.sched--tray-open) .sched-tray__count {
    border-radius: 999px;
    padding: 0 11px;
    height: 30px;
    margin-right: auto;
  }

  .sched-body:has(.sched-tray) .sched-board {
    /* clear of the collapsed sheet + the safe area */
    margin-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
  }

  /* Day view stacks: each lane becomes a card with its blocks listed, because a
     12-hour axis inside 390px is 32px an hour and unusable with a finger. The
     tap-to-place gesture is what schedules here. */
  .sched-ruler {
    display: none;
  }

  .sched-lane {
    grid-template-columns: minmax(0, 1fr);
    padding: 0;
  }

  /* Day lanes only. Week rows reuse .sched-lane__who inside a 124px column,
     where this row layout crushed the name and the load onto one line. */
  .sched-lane > .sched-lane__who {
    border-right: 0;
    border-bottom: 1px solid var(--sch-rule);
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 14px;
    background: var(--sch-subtle);
  }

  .sched-slots {
    position: static;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 12px;
    min-height: 64px;
  }

  /* An empty stacked lane was a 20px blank strip — too thin to tap and silent
     about what a tap does. The module writes the sentence. */
  .sched-slots:not(:has(.sched-blk, .sched-gutter))::after {
    content: attr(data-empty-hint);
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 4px;
    font-size: 12.5px;
    color: var(--sch-ink-4);
  }

  .sched-slots__line {
    display: none;
  }

  /* ⛔ THE GUTTERS STAY. They were hidden here together with the gridlines, but
     they are not decoration: renderDay() draws only the events inside the
     07:00-19:00 window, so with the gutters gone an 06:30 visit was counted in
     the lane's load and shown nowhere at all — on the width where the field team
     actually works. Stacked, they read as a row in the list. */
  .sched-gutter {
    position: static;
    transform: none;
    align-self: flex-start;
    width: auto;
    height: auto;
    min-height: 44px;
    padding: 8px 12px;
    writing-mode: horizontal-tb;
  }

  .sched-blk {
    position: static;
    top: auto;
    bottom: auto;
    left: auto !important;
    width: auto !important;
    min-height: 52px;
    padding: 10px 12px;
    gap: 3px;
  }

  .sched-blk__title {
    white-space: normal;
    font-size: 13px;
  }

  .sched-blk__when {
    white-space: normal;
    font-size: 11.5px;
  }

  /* A resize handle is not a usable finger target, and the popover's Minutes
     field does the same job. */
  .sched-blk__grip {
    display: none;
  }

  .sched-drop-hint {
    position: static;
    align-self: flex-start;
    max-width: 100%;
  }

  .sched-week__cell {
    min-height: 62px;
  }

  .sched-chip,
  .sched-more {
    min-height: 44px;
  }

  /* Seven columns of about 50px cannot hold a chip with a time in it — they ran
     into the next day. A phone month is dots and a count, and the whole cell
     opens that day (or, while placing, books the armed work onto it). */
  .sched-month__grid {
    grid-auto-rows: minmax(58px, auto);
  }

  .sched-month__head span {
    padding: 8px 2px;
    text-align: center;
    letter-spacing: 0.02em;
  }

  .sched-month__cell {
    padding: 5px 3px 6px;
    align-items: center;
  }

  .sched-month__cell .sched-chip,
  .sched-month__cell .sched-more,
  .sched-month__add {
    display: none;
  }

  .sched-month__peek {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 3px;
    padding: 0 2px 6px;
    appearance: none;
    border: 0;
    background: transparent;
    cursor: pointer;
    font: 700 10.5px/1 var(--font-sans, "Inter", system-ui, sans-serif);
    color: var(--sch-ink-3);
    font-variant-numeric: tabular-nums;
  }

  .sched-month__dots {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 2px;
    max-width: 100%;
  }

  .sched-month__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--sch-ink-4);
  }

  .sched-month__dot--inspection,
  .sched-month__dot--survey,
  .sched-month__dot--assessment { background: var(--sch-type-inspection); }
  .sched-month__dot--remedial { background: var(--sch-type-remedial); }
  .sched-month__dot--fire_door { background: var(--sch-type-firedoor); }
  .sched-month__dot--pre_booking { background: var(--sch-type-prebooking); }
  .sched-month__dot--defect { background: var(--sch-type-defect); }

  .sched-pop {
    /* Anchored positioning is meaningless on a phone: it becomes a sheet. */
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: 0 !important;
    width: 100% !important;
    border-radius: 18px 18px 0 0;
    padding: 14px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 75;
    /* The keyboard and the time wheel take the bottom half of the screen, so
       the sheet scrolls rather than pushing Save out of reach. */
    max-height: 88vh;
    max-height: 88dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .sched-pop__close {
    min-width: 44px;
    min-height: 44px;
    margin: -8px -8px 0 0;
  }

  .sched-pop__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Page CSS may set these inside the 900px query: header/body/footer padding,
     footer layout, and form-grid collapse. It must NOT set dialog width,
     height, margin, border, radius, shadow or any slide-up transform. */
  .sched-modal .sched-modal__header {
    padding: 14px 16px 12px;
  }

  .sched-modal .sched-modal__body {
    padding: 14px 16px 16px;
    gap: 14px;
  }

  .sched-modal .sched-modal__footer-copy {
    display: none;
  }

  .sched-modal .sched-modal__footer-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    width: 100%;
  }

  .sched-modal .sched-modal__footer-actions .btn {
    justify-content: center;
    width: 100%;
  }

  .sched-grid,
  .sched-pop__row {
    grid-template-columns: minmax(0, 1fr);
  }

  .sched-pop__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sched-drawer__types {
    padding: 10px 16px 0;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .sched-drawer__types::-webkit-scrollbar {
    display: none;
  }

  .sched-drawer__type {
    min-height: 44px;
    flex: 0 0 auto;
  }

  /* iOS zooms a focused input under 16px. The canonical rule in style.css
     already covers inputs inside .modal--sheet; the popover is not a modal, so
     it needs its own. */
  .sched-pop input,
  .sched-pop select,
  .sched-filter-field select,
  .sched-filter-field input {
    min-height: 44px;
    font-size: 16px;
  }

  .sched-typecheck {
    min-height: 44px;
    align-items: flex-start;
  }

  .sched-typecheck__hint {
    display: block;
  }

  .sched-search-clear {
    min-width: 44px;
    min-height: 44px;
    right: 0;
  }

  .sched-chip-token {
    min-height: 44px;
    padding-right: 0;
  }

  .sched-chip-token__x {
    min-width: 44px;
    min-height: 44px;
  }

  .sched-foot__hint {
    font-size: 11.5px;
  }

  .sched-foot__hint-fine,
  .sched-foot__hint-touch {
    display: none;
  }

  .sched-foot__hint-phone {
    display: inline;
  }

  /* Placing, on a phone: pinned above the collapsed tray bar, so Cancel stays in
     reach while the lanes scroll underneath. */
  .sched-placing {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    z-index: 60;
    margin: 0;
  }

  /* "Need help?" is fixed bottom-right at z-index 1300. It sat on the tray bar's
     toggle and on the popover sheet's Save, so here it steps up above the bar
     and leaves while a sheet is open. Scoped to this page by :has(). */
  body:has(.sched-body .sched-tray) .support-fab {
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
  }

  body:has(.sched--tray-open) .support-fab,
  body:has(.sched--placing) .support-fab,
  body:has(.sched-pop:not([hidden])) .support-fab {
    display: none !important;
  }

  /* Toasts sit bottom-right at z-index 9999, over the tray and popover sheets.
     While one of those is up they move to the top of the screen. */
  body:has(.sched--tray-open) .toast-stack,
  body:has(.sched-pop:not([hidden])) .toast-stack {
    top: calc(12px + env(safe-area-inset-top, 0px));
    bottom: auto;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Touch tablets above 900px — the time axis stays, fingers do not shrink.
   A media FEATURE, not a width: an iPad at 1024 or 1180 is this, a laptop at
   the same width is not.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 901px) and (pointer: coarse) {
  .sched-nav__btn,
  .sched-nav__today,
  .sched-view,
  .sched-btn,
  .sched-combine,
  .sched-drawer__type,
  .sched-typecheck,
  .sched-filter-field select,
  .sched-filter-field.ipi-filter-search input {
    min-height: 44px;
  }

  .sched-nav__btn {
    min-width: 44px;
  }

  .sched-tray__collapse,
  .sched-pop__close,
  .sched-search-clear,
  .sched-chip-token__x {
    min-width: 44px;
    min-height: 44px;
  }

  .sched-chip,
  .sched-more,
  .sched-gutter {
    min-height: 44px;
  }

  .sched-month__add {
    width: 44px;
    height: 44px;
    top: 2px;
    right: 2px;
  }

  /* A 15-minute block at 1024px was a 12px sliver. */
  .sched-blk {
    min-width: 44px;
  }

  /* The grip was 8px wide and is the only resize control a tablet has. */
  .sched-blk__grip {
    width: 22px;
    opacity: 1;
    background: transparent;
  }

  .sched-blk__grip::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 7px;
    width: 4px;
    height: 22px;
    transform: translateY(-50%);
    border-radius: 2px;
    background: currentColor;
    opacity: 0.28;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sched-month__add,
  .sched-card,
  .sched-blk,
  .sched-chip {
    transition: none !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   WHAT THE FIRE STOPPING TWIN HAS HERE, AND THIS DOES NOT

   Its "Fire Stopping only" block is gone: it styled
   `.sched--fs .sched-blk[data-module="fire_doors"]`, the read-only treatment
   for the "Show fire doors" overlay. This board has no combine toggle
   (FraScheduleController records why), so no foreign block can ever appear on
   it and the rules could never match.

   ⚠ WHAT IS DELIBERATELY STILL HERE, MATCHING NOTHING: `.sched-combine` (the
   toggle's own control, four rules in the shared toolbar section above) and
   `.sched-typecheck*` (the type-filter chips — one event type makes a filter
   that can only empty the board). Both are kept because they are the FD/FS
   twins' verbatim blocks, and editing them out would make the three files
   diverge in a way a future re-sync has to rediscover line by line.
   Dead-but-identical beats edited-and-different. What was removed above is the
   one block the twin itself marks as its own.
   ════════════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════════════
   Ported from schedule.css, 2026-09-13.

   The FS drawer, delete and sync dialogs use the same .sched-modal shell as
   the fire-door board, but this fork never carried the block that styles it:
   at <=900px a three-button footer left Save in a half-width cell, footer
   buttons had no 44px floor, the delete eyebrow stayed gold instead of red,
   and above 900px the dialogs were 680px against the fire-door 880px. Copied
   verbatim — keep the two in step.
   ════════════════════════════════════════════════════════════════════════ */

/* ============================================================================
   Schedule canonical modal primitives — `.sched-modal*`
   ----------------------------------------------------------------------------
   Canonical umbrella chrome block for all Schedule/pre-bookings modals. Every
   schedule modal shares the same shell, inputs, footer slots and mobile
   bottom-sheet behaviour. Values lifted from settings-shell.css `.set-modal`
   block (~line 6320).
   ============================================================================ */

.sched-modal {
    --sched-accent: var(--accent, #c49510);
    --sched-accent-soft: var(--accent-soft, rgba(196, 149, 16, 0.1));
    --sched-accent-strong: rgba(196, 149, 16, 0.34);
    --sched-ink: var(--ink, var(--ink));
    --sched-ink-muted: var(--ink-3, var(--ink-3));
    --sched-ink-faint: var(--ink-4, var(--ink-4));
    --sched-border: var(--rule, color-mix(in srgb, var(--ink) 8%, transparent));
    --sched-border-rule: color-mix(in srgb, var(--ink) 7%, transparent);
    --sched-border-input: color-mix(in srgb, var(--ink) 14%, transparent);
    --sched-bg-warm: var(--canvas);
    --sched-surface: var(--surface-card, #ffffff);
    --sched-surface-soft: color-mix(in srgb, var(--canvas) 57%, var(--surface-card));

    /* --ipi-* token aliases so canonical primitives (.ipi-tabs, .ipi-tab,
       .ipi-filter-search) render correctly inside the modal scope. */
    --ipi-bg: var(--canvas, var(--canvas));
    --ipi-bg-inset: var(--surface-inset, var(--surface-inset));
    --ipi-bg-card: var(--surface-card, #ffffff);
    --ipi-bg-hover: color-mix(in srgb, var(--ink) 4%, transparent);
    --ipi-rule: var(--rule, color-mix(in srgb, var(--ink) 8%, transparent));
    --ipi-rule-h: color-mix(in srgb, var(--ink) 11%, transparent);
    --ipi-ink: var(--ink, var(--ink));
    --ipi-ink-2: var(--ink-2);
    --ipi-ink-3: var(--ink-3, var(--ink-3));
    --ipi-ink-4: var(--ink-4, var(--ink-4));
    --ipi-accent: var(--accent, #c49510);
    --ipi-accent-bg: rgba(196, 149, 16, 0.08);
    --ipi-accent-border: rgba(196, 149, 16, 0.34);
    --ipi-shadow-sm: 0 1px 3px color-mix(in srgb, var(--ink) 6%, transparent), 0 1px 2px color-mix(in srgb, var(--ink) 4%, transparent);
    --ipi-shadow-card: 0 1px 4px color-mix(in srgb, var(--ink) 6%, transparent), 0 0 0 1px color-mix(in srgb, var(--ink) 5%, transparent);
}

/* Default dialog: content-driven height. Use --stable on tabbed/multi-state modals. */
.sched-modal .sched-modal__dialog {
    width: min(880px, calc(100vw - 32px));
    max-height: min(90vh, 960px);
    border-radius: 16px;
    border: 1px solid var(--sched-border);
    background: var(--sched-surface);
    box-shadow:
        0 20px 60px rgba(0, 0, 0, 0.18),
        0 4px 16px rgba(0, 0, 0, 0.08);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
}

/* Higher-specificity --stable rule so it wins over the legacy
   .page-section--schedule .modal.schedule-sync-modal .schedule-sync-modal__dialog
   and .prebooking-capture-modal__dialog rules (specificity 0,4,0) which both
   set min-height: 0. */
.modal.sched-modal .sched-modal__dialog--stable,
.page-section--schedule .modal.sched-modal .sched-modal__dialog--stable.schedule-sync-modal__dialog,
.page-section--schedule .modal.sched-modal .sched-modal__dialog--stable.prebooking-capture-modal__dialog {
    height: min(85vh, 760px);
    min-height: min(60vh, 520px);
    max-height: min(90vh, 960px);
}

.sched-modal .sched-modal__dialog--narrow {
    width: min(560px, calc(100vw - 32px));
}

.sched-modal .sched-modal__dialog--wide {
    width: min(1280px, calc(100vw - 32px));
}

/* Fullscreen variant — full viewport canvas takeover (e.g. schedule planner).
   !important required to override the canonical .modal--sheet mobile rule
   in style.css which otherwise forces standard full-screen dialog chrome. */
.sched-modal .sched-modal__dialog--fullscreen {
    width: 100vw !important;
    max-width: none !important;
    height: 100dvh !important;
    max-height: none !important;
    min-height: 100dvh !important;
    border-radius: 0 !important;
    border: 0 !important;
    box-shadow: none !important;
    margin: 0 !important;
    background: var(--canvas);
    overflow: auto;
    padding: 0;
}

.sched-modal .sched-modal__dialog--fullscreen .modal__body.sched-modal__body {
    padding: 0;
    overflow: hidden;
    flex: 1 1 auto;
    min-height: 0;
    background: transparent;
}

.modal.sched-modal.schedule-fullscreen-modal {
    align-items: stretch;
    justify-content: stretch;
    padding: 0;
}

/* Form wrapping body+footer must be flex so body's overflow-y:auto has a
   constrained parent. */
.sched-modal form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    margin: 0;
    width: 100%;
}

.sched-modal .sched-modal__header {
    padding: 20px 22px 16px;
    border-bottom: 1px solid var(--sched-border-rule);
    flex-shrink: 0;
    background: var(--sched-surface);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.sched-modal .sched-modal__header > div:first-child {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1 1 auto;
}

.sched-modal .sched-modal__header-tools {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
}

.sched-modal .sched-modal__header .eyebrow {
    margin: 0;
    color: var(--sched-accent);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.sched-modal .sched-modal__header .modal__title,
.sched-modal .sched-modal__header h3 {
    margin: 0;
    font-family: var(--font-display, 'Space Grotesk', system-ui, sans-serif);
    font-size: 1.28rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    color: var(--sched-ink);
}

.sched-modal .sched-modal__header .text-muted,
.sched-modal .sched-modal__header > div > p:not(.eyebrow) {
    margin: 4px 0 0;
    max-width: 60ch;
    color: var(--sched-ink-muted);
    font-size: 13px;
    font-weight: 400;
    line-height: 1.45;
}

.sched-modal .modal__close {
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--surface-inset, var(--surface-inset));
    border: none;
    color: var(--sched-ink-muted);
    font-size: 18px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
}

.sched-modal .modal__close:hover {
    background: color-mix(in srgb, var(--ink) 10%, transparent);
    color: var(--sched-ink);
}

/* 28px is a mouse target. tablet.css gives the app's modal close 44px at
   769-1366px and this rule used to undo it on every touch tablet. */
@media (pointer: coarse) {
    .sched-modal .modal__close {
        width: 44px;
        height: 44px;
    }
}

.sched-modal .sched-modal__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: 20px 22px 22px;
    background: var(--sched-bg-warm);
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.sched-modal .sched-modal__footer {
    padding: 13px 22px 14px;
    border-top: 1px solid var(--sched-border-rule);
    background: var(--sched-surface);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

.sched-modal .sched-modal__footer-copy {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.sched-modal .sched-modal__footer-copy strong {
    font-family: var(--font-display, 'Space Grotesk', system-ui, sans-serif);
    font-size: 13px;
    font-weight: 700;
    color: var(--sched-ink);
}

.sched-modal .sched-modal__footer-copy p {
    margin: 0;
    font-size: 12px;
    color: var(--sched-ink-faint);
}

.sched-modal .sched-modal__footer-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

.sched-modal .sched-modal__footer .btn {
    min-height: 40px;
    padding: 8px 18px;
}

/* --------------------------------------------------------------------------
   .sched-modal--danger — destructive action modifier (Delete booking)
   `!important` on color required to beat canonical eyebrow rule per css-standards gotcha #10.
   -------------------------------------------------------------------------- */
.modal.sched-modal.sched-modal--danger .sched-modal__header .eyebrow {
    color: var(--danger, #b03030) !important;
}

.modal.sched-modal.sched-modal--danger .sched-modal__footer-actions .btn-danger {
    background: var(--danger, #b03030);
    color: #ffffff;
    border: none;
    font-weight: 600;
}

.modal.sched-modal.sched-modal--danger .sched-modal__footer-actions .btn-danger:hover {
    background: #952828;
}




/* Form controls */
.sched-modal :where(input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="tel"], input[type="url"], input[type="search"], input[type="date"], input[type="time"], input[type="datetime-local"], select, textarea) {
    min-height: 40px;
    padding: 10px 13px;
    border-radius: 9px;
    border: 1px solid var(--sched-border-input);
    background: var(--sched-surface);
    font-family: var(--font-sans, inherit);
    font-size: 13.5px;
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
    color: var(--sched-ink);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    box-sizing: border-box;
    width: 100%;
}

.sched-modal :where(input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="tel"], input[type="url"], input[type="search"], input[type="date"], input[type="datetime-local"], select, textarea):focus {
    border-color: var(--sched-accent-strong);
    box-shadow: 0 0 0 3px var(--sched-accent-soft);
    outline: none;
}

.sched-modal textarea {
    min-height: 72px;
    resize: vertical;
    line-height: 1.5;
}

.sched-modal select {
    padding-right: 34px;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%239a9188' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5l3 3 3-3'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 12px;
    cursor: pointer;
}

/* Mobile modal behaviour (≤900px) — canonical full-screen rule lives in
   style.css; header/body/footer chrome owned by gold-spec there too.
   Schedule-specific content layout below. */
@media (max-width: 900px) {
    .sched-modal .sched-modal__body {
        gap: 12px;
    }

    .sched-modal .sched-modal__footer-actions {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
        width: 100%;
    }

    /* When the last button would sit alone on its row (odd count), span full width. */
    .sched-modal .sched-modal__footer-actions > *:last-child:nth-child(odd) {
        grid-column: 1 / -1;
    }

    .sched-modal .sched-modal__footer-actions .btn {
        width: 100%;
        justify-content: center;
        min-height: 44px;
        font-size: 13px;
        padding-left: 6px;
        padding-right: 6px;
    }

}
