/* ==========================================================================
   The two week boards

   The Fleet Board (our own trucks and their runs across the week) is the
   Scheduler tab of Deliveries, right of By Road (deliveries.html); the client pickup
   Slot Board, with its `pk-` names, is the Calendar tab of Pickups
   (orders-pickups-calendar.html). They were one page until the owner split
   them, 2026-10-12. The hub strip, the readings and the gear are
   css/pages/orders.css's and are not restated here. The fleet's own is `sch-`.
   ========================================================================== */

/* ---------- A board's header ----------------------------------------------------------
   The week's name with the way to turn it on the left, the board's actions on
   the right. Both boards draw the same header (the `.pk-week` words). */
.sch-head,
.pk-board-head { gap: 16px; }
.pk-week { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* The two arrows, and This Week under them (user, 2026-10-13). */
.pk-week__nav { display: inline-grid; grid-template-columns: auto auto; justify-items: center; gap: 4px 2px; flex: none; }
.pk-week__today { grid-column: 1 / -1; font-size: 12px; font-weight: 500; color: var(--color-primary); text-decoration: none; }
.pk-week__today:hover { color: var(--color-primary-700); }
.pk-week__title { font-weight: 500; color: var(--color-text-muted); margin-left: 6px; }
.sch-acts { display: inline-flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; justify-content: flex-end; }
/* The layout icons with "Trucks" under them, as This Week sits under the arrows. */
.sch-axis { display: inline-flex; flex-direction: column; align-items: center; gap: 4px; }
.sch-axis__cap { font-size: 12px; font-weight: 500; color: var(--color-text-muted); }

/* ---------- The fleet board -------------------------------------------------------------
   A truck a row, a day a column, and over the trucks one row of the deliveries
   that have no truck yet. Every cell draws its own hairline so the grid reads
   as one board, as the Slot Board's does. */
/* The board and, on its right, To Schedule. The board takes what the list
   leaves, and all of it when the list is folded. */
.sch-board { display: flex; align-items: stretch; gap: 12px; }
.sch-board-wrap { flex: 1 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden; }
.sch-grid {
  display: grid;
  grid-template-columns: 112px repeat(6, minmax(100px, 1fr));
  gap: 2px;
  min-width: 724px;
  font-size: 12px;
}
/* Trucks across: a narrow day column, then a column a truck. More trucks than
   the board holds scroll sideways inside the wrap. */
.sch-grid.is-across {
  grid-template-columns: 96px repeat(var(--sch-trucks), minmax(112px, 1fr));
  min-width: calc(96px + var(--sch-trucks) * 114px);
}
.sch-grid.is-across .sch-day { white-space: normal; display: flex; flex-direction: column; justify-content: center; gap: 2px; }
.sch-grid.is-across .sch-day__today { margin-left: 0; }
.sch-grid.is-across .sch-truck { padding: 6px 8px; background: var(--color-table-head); border-radius: var(--radius); }
.sch-corner,
.sch-day {
  padding: 6px 8px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--color-text-muted);
  background: var(--color-table-head);
  border-radius: var(--radius);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sch-day.is-today { color: var(--color-primary-700); }
.sch-day.is-past { color: var(--color-text-subtle); }
/* A delivery in the hand lights the day its client asked for. */
.sch-day.is-asked { color: var(--color-warn-ink); background: var(--color-warn-50); }
.sch-day__today { font-size: 10px; font-weight: 600; letter-spacing: 0.04em; color: var(--color-primary-700); margin-left: 4px; }

/* The truck: what it is on the first line, who drives it, what it carries and
   where it lives on the second, one step smaller (memory.md §4). */
.sch-rowhead { display: flex; flex-direction: column; justify-content: center; gap: 1px; padding: 6px 8px 6px 2px; min-width: 0; }
.sch-rowhead .main { font-size: 12px; font-weight: 600; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A truck reads its number and weight; its eye holds the kind, the driver and the yard. */
.sch-truck { flex-direction: row; align-items: center; justify-content: flex-start; gap: 4px; }
.sch-truck .main { min-width: 0; }
.sch-eye {
  display: inline-flex; flex: none;
  padding: 3px; border-radius: 4px;
  color: var(--color-text-subtle);
  cursor: help;
}
.sch-eye:hover,
.sch-eye:focus-visible { color: var(--color-primary-700); background: var(--color-control); outline: none; }
.sch-eye svg { width: 14px; height: 14px; }
.sch-eye-card {
  position: fixed; z-index: 1500;
  display: grid; grid-template-columns: auto auto; gap: 3px 10px;
  padding: 8px 10px;
  font-size: 12px; color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.14);
  pointer-events: none;
  white-space: nowrap;
}
.sch-eye-card[hidden] { display: none; }
.sch-eye-card .k { text-align: right; color: var(--color-text-muted); font-size: 11px; line-height: 18px; }

/* A FREE DAY IS WHITE, the panel's own ground bounded by a hairline: it is the
   room, not a thing in the room. What is placed in it takes the control ground
   (memory.md §13). Today is tinted, a day gone is greyed. */
.sch-cell {
  min-height: 58px;
  padding: 3px;
  display: flex; flex-direction: column; gap: 3px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  min-width: 0;
  transition: border-color 120ms, background 120ms, box-shadow 120ms;
}
.sch-cell.is-today { border-color: var(--color-primary-50); background: color-mix(in oklab, var(--color-primary-50) 45%, var(--color-surface)); }
.sch-cell.is-past { background: var(--color-surface-alt); }
/* A truck off the road that day: greyed, dashed, the reason as a word. Nothing
   can be dropped on it. */
.sch-cell--off { background: var(--color-surface-alt); border-style: dashed; align-items: center; justify-content: center; }
.sch-off { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--color-text-muted); }
.sch-off svg { width: 12px; height: 12px; }
/* Where the dragged thing would land: the primary edge for a place that takes
   it, the danger edge for one that does not. */
.sch-cell.is-asked { border-color: color-mix(in oklab, var(--color-warn) 55%, var(--color-border)); }
.sch-cell.is-drop { border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); background: var(--color-primary-50); }
.sch-cell.is-nodrop { border-color: var(--color-danger); box-shadow: inset 0 0 0 1px var(--color-danger); }

/* A RUN: one truck's day. Its number and state, its deliveries in the order
   they drop, and how much of the truck's weight they use. */
.sch-run {
  display: flex; flex-direction: column; gap: 3px;
  padding: 4px;
  background: var(--color-control);
  border: 1px solid var(--color-control-border);
  border-radius: var(--radius);
  min-width: 0;
}
/* A run's state is its ground: Scheduled keeps the control grey and can still
   move; Out takes the warn wash, Delivered the success wash, both locked. */
.sch-run.is-out { background: var(--color-warn-50); border-color: color-mix(in oklab, var(--color-warn) 55%, var(--color-control-border)); }
.sch-run.is-done { background: var(--color-success-50); border-color: color-mix(in oklab, var(--color-success) 55%, var(--color-control-border)); }
.sch-run.is-over { border-color: color-mix(in oklab, var(--color-danger) 55%, var(--color-control-border)); }
.sch-run__head { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--color-text-muted); min-width: 0; white-space: nowrap; }
.sch-run__grip {
  display: inline-flex; flex: none;
  padding: 2px; margin: -2px 0 -2px -2px;
  border-radius: 4px;
  color: var(--color-text-subtle);
  cursor: grab; touch-action: none;
}
.sch-run__grip:hover,
.sch-run__grip:focus-visible { color: var(--color-primary-700); background: var(--color-surface); outline: none; }
.sch-run__grip svg { width: 14px; height: 14px; }
.sch-run__lock { width: 12px; height: 12px; flex: none; color: var(--color-text-subtle); }
.sch-run__no { font-weight: 600; color: var(--color-text); }
.sch-run__state { display: inline-flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; }
/* On a narrow day the state word ends in an ellipsis, never cut mid-letter. */
.sch-run__word { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* A DELIVERY sits white on the run's control ground — a tinted row's own cells
   go white (memory.md §13) — and is what the hand picks up. */
.sch-stop {
  display: flex; flex-direction: column;
  padding: 3px 6px;
  background: var(--color-surface);
  border: 1px solid var(--color-control-border);
  border-radius: 5px;
  min-width: 0;
  cursor: grab; touch-action: none; user-select: none;
}
.sch-stop:hover,
.sch-stop:focus-visible { border-color: var(--color-primary); outline: none; }
.sch-stop.is-locked { cursor: default; }
.sch-stop.is-locked:hover { border-color: var(--color-control-border); }
/* The name's line carries the arrow that opens the order: the one place a
   click leaves the board, so the rest of the box is free to drag. */
.sch-stop__top { display: flex; align-items: center; gap: 4px; min-width: 0; }
.sch-stop__top .sch-stop__who { flex: 1 1 auto; min-width: 0; }
.sch-stop__open {
  display: inline-flex; flex: none;
  padding: 3px; margin: -3px -4px -3px 0;
  border-radius: 4px;
  color: var(--color-text-subtle);
  cursor: pointer;
}
.sch-stop__open:hover,
.sch-stop__open:focus-visible { color: var(--color-primary-700); background: var(--color-control); outline: none; }
.sch-stop__open svg { width: 14px; height: 14px; }
.sch-stop__who { font-size: 11px; font-weight: 500; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sch-stop__sub { font-size: 10px; color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Dropped on a day other than the one the client asked for: the asked day is
   said on a line of its own, in the waiting ink, so a narrow day never cuts it. */
.sch-stop__asked { font-size: 10px; color: var(--color-warn-ink); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The weight the run carries against the truck's limit: a thin bar, the
   figures after it. Over the limit, both turn to the danger ink. */
.sch-load { display: flex; align-items: center; gap: 6px; min-width: 0; }
.sch-load__bar { flex: 1 1 auto; min-width: 24px; height: 4px; border-radius: 2px; background: var(--color-control-border); overflow: hidden; }
.sch-load__bar > span { display: block; height: 100%; width: 0; background: var(--color-primary); }
.sch-load__txt { font-size: 10px; color: var(--color-text-muted); white-space: nowrap; }
.sch-run.is-over .sch-load__bar > span { background: var(--color-danger); }
.sch-run.is-over .sch-load__txt { color: var(--color-danger-ink); font-weight: 600; }

/* The search: what does not match steps back, what does is ringed. The Slot
   Board's bookings answer their page's search the same way. */
.sch-stop.is-dim,
.pk-block.is-dim,
.pk-off.is-dim { opacity: 0.3; }
.sch-stop.is-hit,
.sch-run.is-hit,
.pk-block.is-hit { box-shadow: 0 0 0 2px var(--color-primary); }
.pk-off.is-hit { color: var(--color-primary-700); font-weight: 600; }

/* Dragging: the thing in the hand follows the pointer, its place stays faint. */
.sch-ghost {
  position: fixed; z-index: 2000;
  pointer-events: none;
  opacity: 0.92;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
.sch-board .is-dragging { opacity: 0.35; }
body.sch-dragging { cursor: grabbing; user-select: none; }

/* ---------- To Schedule ---------------------------------------------------------------------
   NO TRUCK YET is a waiting state, so the list takes the warn family's lightest
   wash and a dashed edge: deliveries in a queue, not runs. Narrow, the day the
   client asked for over each group; folded, a strip with its count. */
.sch-queue {
  flex: 0 0 168px;
  display: flex; flex-direction: column; gap: 8px;
  min-width: 0;
  padding: 8px;
  border: 1px dashed color-mix(in oklab, var(--color-warn) 35%, var(--color-border));
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--color-warn-50) 55%, var(--color-surface));
  transition: border-color 120ms, background 120ms, box-shadow 120ms;
}
.sch-queue.is-drop { border-color: var(--color-primary); border-style: solid; box-shadow: inset 0 0 0 1px var(--color-primary); background: var(--color-primary-50); }
.sch-queue__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 6px; }
.sch-queue__title { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sch-queue__title .main { font-size: 12px; font-weight: 600; color: var(--color-warn-ink); white-space: nowrap; }
.sch-queue__title .sub { font-size: 11px; color: var(--color-text-muted); }
.sch-queue__fold { flex: none; margin: -4px -4px 0 0; }
.sch-queue__fold-close { display: inline-flex; }
.sch-queue__fold-open { display: none; }
.sch-queue__list { display: flex; flex-direction: column; gap: 10px; }
.sch-queue__day { display: flex; flex-direction: column; gap: 3px; }
.sch-queue__dayname { font-size: 11px; font-weight: 600; color: var(--color-text-muted); }
.sch-queue__empty { margin: 0; font-size: 11px; color: var(--color-text-muted); }
.sch-board.is-folded .sch-queue { flex-basis: 40px; padding: 6px 4px; align-items: center; }
.sch-board.is-folded .sch-queue__head { flex-direction: column-reverse; align-items: center; }
.sch-board.is-folded .sch-queue__fold { margin: 0; }
.sch-board.is-folded .sch-queue__fold-close { display: none; }
.sch-board.is-folded .sch-queue__fold-open { display: inline-flex; }
.sch-board.is-folded .sch-queue__word,
.sch-board.is-folded .sch-queue__title .sub,
.sch-board.is-folded .sch-queue__list { display: none; }

/* ---------- The Slot Board (moved from orders-pickups.css) ---------------------------------
   The Calendar's one card: the client pickups, a half-hour slot a row. */
.pk-board-wrap { overflow-x: auto; overflow-y: hidden; }
/* Six days across after a time column; a header row, then a row per half-hour.
   Every cell draws its own hairline so the grid reads as one board. */
.pk-grid {
  display: grid;
  grid-template-columns: 48px repeat(6, minmax(0, 1fr));
  gap: 2px;
  min-width: 640px;
  font-size: 12px;
}
.pk-corner,
.pk-day {
  padding: 6px 8px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--color-text-muted);
  background: var(--color-table-head);
  border-radius: var(--radius);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pk-day.is-today { color: var(--color-primary-700); }
.pk-day.is-past { color: var(--color-text-subtle); }
.pk-day__today {
  font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--color-primary-700);
  margin-left: 4px;
}
.pk-time {
  font-size: 11px; color: var(--color-text-subtle);
  text-align: right; padding: 4px 6px 0 0;
  white-space: nowrap;
}
/* A FREE SLOT IS WHITE — the panel's own ground, bounded by a hairline — because
   it is the room, not a thing in the room. Everything placed in it takes the
   control ground (memory.md §13). */
.pk-slot {
  min-height: 34px;
  padding: 2px;
  display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 120ms, background 120ms;
}
.pk-slot:hover,
.pk-slot:focus-visible { border-color: var(--color-primary); outline: none; }
.pk-slot--today { border-color: var(--color-primary-50); background: color-mix(in oklab, var(--color-primary-50) 45%, var(--color-surface)); }
.pk-slot--past { background: var(--color-surface-alt); cursor: default; }
.pk-slot--past:hover { border-color: var(--color-border); }
/* A blocked slot (the forklift's service, our own truck loading) takes no
   pickup: greyed and dashed like a truck off the fleet board, its reason as
   a word with an icon (`.sch-off`), no block in it. */
.pk-slot--blocked { background: var(--color-surface-alt); border-style: dashed; border-color: var(--color-control-border); align-items: center; justify-content: center; }
.pk-slot--blocked:hover { border-color: var(--color-control-border); }
.pk-off { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pk-off svg { flex: none; }
/* Hours the yard is shut: greyed, no border of their own, not clickable. */
.pk-slot--closed {
  background: var(--color-surface-alt);
  border-color: transparent;
  cursor: default;
}
.pk-slot--closed:hover { border-color: transparent; }
/* A booking: the client's name over the word that says how it got there, on
   the control ground. A collected one carries a success dot; a blocked slot is
   dashed and muted, because nothing is going to be handed over in it. */
.pk-block {
  display: flex; flex-direction: column; gap: 0;
  padding: 3px 6px;
  background: var(--color-control);
  border: 1px solid var(--color-control-border);
  border-radius: var(--radius);
  min-width: 0;
}
.pk-block__name { font-size: 11px; font-weight: 500; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pk-block__sub { font-size: 10px; color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pk-block--done { background: var(--color-success-50); border-color: color-mix(in oklab, var(--color-success) 55%, var(--color-control-border)); }
.pk-block--done .pk-block__name { color: var(--color-success-ink); }

/* The legend under either board reads as words with a swatch each, in the muted ink. */
.pk-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin-top: 12px; font-size: 12px; color: var(--color-text-muted); }
.pk-legend__item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.pk-legend__note { flex-basis: 100%; font-size: 11px; color: var(--color-text-subtle); }
.pk-swatch { width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--color-border); display: inline-block; }
.pk-swatch--free { background: var(--color-surface); }
.pk-swatch--booked { background: var(--color-control); border-color: var(--color-control-border); }
.pk-swatch--done { background: var(--color-success-50); border-color: color-mix(in oklab, var(--color-success) 55%, var(--color-control-border)); }
.pk-swatch--blocked { background: var(--color-surface-alt); border-style: dashed; border-color: var(--color-control-border); }
.pk-swatch--closed { background: var(--color-surface-alt); border-color: transparent; }
.sch-swatch--todo { border-style: dashed; border-color: color-mix(in oklab, var(--color-warn) 35%, var(--color-border)); background: color-mix(in oklab, var(--color-warn-50) 55%, var(--color-surface)); }
.sch-swatch--out { background: var(--color-warn-50); border-color: color-mix(in oklab, var(--color-warn) 55%, var(--color-control-border)); }
.sch-swatch--done { background: var(--color-success-50); border-color: color-mix(in oklab, var(--color-success) 55%, var(--color-control-border)); }
.sch-swatch--over { background: var(--color-control); border-color: var(--color-danger); }

/* ---------- Narrow screens -----------------------------------------------------------------
   Both boards keep their columns and scroll sideways inside their wraps; the
   page itself never does. Four tiles fold to two by two, then one to a line. */
@media (max-width: 1100px) {
  .kpi-summary .kpi-summary__cards > .kpi { flex: 1 1 calc(50% - 8px); }
}
@media (max-width: 640px) {
  .kpi-summary .kpi-summary__cards > .kpi { flex-basis: 100%; }
}
@media (max-width: 768px) {
  .sch-head,
  .pk-board-head { flex-wrap: wrap; align-items: flex-start; }
  /* The action row takes the header's full width and wraps inside it. */
  .sch-acts { justify-content: flex-start; flex: 1 1 100%; max-width: 100%; }
  .sch-acts .btn { min-height: 40px; }
  .pk-week__today { padding: 8px 6px; }
  /* The Fleet Board's yard chips may shrink to the row and wrap a chip down. */
  .sch-acts .subtabs { flex: 0 1 auto; max-width: 100%; }
  /* To Schedule goes under the board, its day groups side by side. */
  .sch-board { flex-direction: column; }
  .sch-queue,
  .sch-board.is-folded .sch-queue { flex-basis: auto; padding: 8px; align-items: stretch; }
  .sch-board.is-folded .sch-queue__head { flex-direction: row; align-items: flex-start; }
  .sch-board.is-folded .sch-queue__word { display: inline; }
  .sch-queue__list { flex-direction: row; flex-wrap: wrap; }
  .sch-queue__day { flex: 1 1 160px; min-width: 0; }
}
@media (max-width: 480px) {
  .pk-week { flex-wrap: wrap; }
  .sch-acts { gap: 6px; }
  .pk-legend { gap: 6px 12px; }
}
