/* ==========================================================================
   LFX Fleet — Brand styles
   Matches the LFX Tracker / Quoting visual identity.
   ========================================================================== */

:root {
  --lfx-red:         #D6001C;
  --lfx-red-dark:    #B00017;
  --lfx-red-light:   #FCE4E7;
  --lfx-white:       #FFFFFF;
  --lfx-grey:        #6C757D;
  --lfx-grey-light:  #F1F3F5;
  --lfx-grey-dark:   #343A40;
  --lfx-black:       #000000;

  --bs-primary:           var(--lfx-red);
  --bs-primary-rgb:       214, 0, 28;
  --bs-body-color:        var(--lfx-black);
  --bs-body-bg:           var(--lfx-white);
  --bs-border-color:      var(--lfx-grey);
  --bs-link-color:        var(--lfx-red);
  --bs-link-hover-color:  var(--lfx-red-dark);
}

/* ---- Buttons ---- */
.btn-primary {
  background-color: var(--lfx-red);
  border-color: var(--lfx-red);
  color: var(--lfx-white);
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
  background-color: var(--lfx-red-dark) !important;
  border-color: var(--lfx-red-dark) !important;
  color: var(--lfx-white) !important;
}
.btn-outline-primary {
  color: var(--lfx-red);
  border-color: var(--lfx-red);
}
.btn-outline-primary:hover {
  background-color: var(--lfx-red);
  color: var(--lfx-white);
}

/* Dispatch (#18): the pickup tick wears the module's amber — white on
   amber, distinct from the drop tick's green, no Bootstrap cyan. */
.btn-pickup {
  background-color: #B45309;
  border-color: #B45309;
  color: var(--lfx-white);
}
.btn-pickup:hover,
.btn-pickup:focus,
.btn-pickup:active {
  background-color: #92400E !important;
  border-color: #92400E !important;
  color: var(--lfx-white) !important;
}
.badge-picked-up {
  background-color: #B45309;
  color: var(--lfx-white);
}
/* A settled receipt: quiet grey fill, nothing dimmed — the coloured
   pill stays at full strength to say which way the machine went. */
.card-done {
  background-color: var(--lfx-grey-light);
}

/* ---- Navbar ---- */
.navbar-lfx {
  background-color: var(--lfx-white);
  border-bottom: 3px solid var(--lfx-red);
  padding: 0.75rem 1.25rem;
}
/* ---- The hub tile ----
   A square in the red chrome at the very edge of the page, running the
   full height of the bar: top of the viewport down to the red rule.

   BOTH DIMENSIONS ARE EXPLICIT, from one variable. The first version
   used `aspect-ratio: 1` with `height: 100%` to avoid hardcoding the
   height — and that is exactly what broke it. aspect-ratio needs one
   DEFINITE dimension to compute from, and a flex child stretched by its
   parent has no definite height, so the box collapsed to content height
   and the icon was clipped by the overflow rule below. One variable used
   twice cannot drift, which was the only thing the clever version was
   protecting against. */
.navbar-lfx {
  --lfx-header-h: 4.5rem;   /* 72px, the handoff's number */
  /* No horizontal padding: the tile has to reach the edge, so the inner
     sections carry their own padding instead. */
  padding: 0;
}
.navbar-lfx > .container-fluid {
  align-items: center;
  min-height: var(--lfx-header-h);
  padding-left: 0;          /* nothing before the tile */
  padding-right: 1.25rem;
}
.navbar-lfx .lfx-home {
  display: flex;
  align-items: center;
  height: var(--lfx-header-h);
  background-color: var(--lfx-red);
  color: var(--lfx-white);
  border-radius: 0;         /* part of the frame, not a button in it */
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
}
.navbar-lfx .lfx-home:hover,
.navbar-lfx .lfx-home:focus-visible {
  background-color: var(--lfx-red-dark);
  color: var(--lfx-white);
}
.navbar-lfx .lfx-home-icon {
  display: grid;
  place-items: center;
  width: var(--lfx-header-h);    /* square, explicitly */
  height: var(--lfx-header-h);
  flex: 0 0 auto;               /* never squeezed by the label */
}
.navbar-lfx .lfx-home-icon svg {
  width: 1.5rem;
  height: 1.5rem;
}
.navbar-lfx .lfx-home-label {
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  font-weight: 600;
  font-size: 0.9375rem;
  padding-right: 0;
  transition: max-width 0.22s ease, opacity 0.18s ease, padding-right 0.22s ease;
}

/* Pointer devices only. On a touch screen `:hover` can latch after a tap
   and then stick, so the label would open and never close — there the
   tile stays a square, which is the whole reason it carries an
   aria-label rather than relying on this text. */
@media (hover: hover) and (pointer: fine) {
  .navbar-lfx .lfx-home:hover .lfx-home-label,
  .navbar-lfx .lfx-home:focus-visible .lfx-home-label {
    max-width: 8rem;
    opacity: 1;
    padding-right: 1rem;
  }
}

/* Keyboard users get the label at any width: a focus ring around an
   unlabelled square says nothing about where it goes. */
.navbar-lfx .lfx-home:focus-visible .lfx-home-label {
  max-width: 8rem;
  opacity: 1;
  padding-right: 1rem;
}

@media (prefers-reduced-motion: reduce) {
  .navbar-lfx .lfx-home-label { transition: none; }
}

.navbar-lfx .navbar-brand {
  /* The padding the bar gave up so the tile could reach the edge. */
  padding-left: 1.25rem;
  color: var(--lfx-black);
  font-weight: 700;
  letter-spacing: 0.5px;
}
.navbar-lfx .navbar-brand .brand-accent {
  color: var(--lfx-red);
}
.navbar-lfx .nav-link {
  color: var(--lfx-black);
}
.navbar-lfx .nav-link:hover,
.navbar-lfx .nav-link.active {
  color: var(--lfx-red);
}

/* ---- Forms ---- */
.form-control:focus,
.form-select:focus {
  border-color: var(--lfx-red);
  box-shadow: 0 0 0 0.2rem rgba(214, 0, 28, 0.2);
}

/* ---- Auth pages ---- */
.auth-page {
  min-height: 80vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* On phones, stack the heading above the sign-in widget instead of
   letting them sit side-by-side and get cramped. */
@media (max-width: 575.98px) {
  .auth-page {
    flex-direction: column;
  }
}
.auth-card {
  background: var(--lfx-white);
  border-top: 5px solid var(--lfx-red);
  border-radius: 4px;
  box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08);
  padding: 2.5rem;
  width: 100%;
  max-width: 420px;
}
.auth-card h1 {
  color: var(--lfx-black);
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}
.auth-card .subtitle {
  color: var(--lfx-grey);
  margin-bottom: 1.5rem;
}

/* ---- Home page verb cards (the navigation pattern, #27 — quoting's) ---- */
.verb-card {
  display: block;
  background: var(--lfx-white);
  border: 2px solid var(--lfx-grey);
  border-radius: 8px;
  padding: 2rem 1.5rem;
  text-decoration: none;
  color: var(--lfx-black);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
  height: 100%;
}
.verb-card:hover,
.verb-card:focus {
  border-color: var(--lfx-red);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  color: var(--lfx-black);
  transform: translateY(-2px);
}
.verb-card .verb-title {
  color: var(--lfx-red);
  font-weight: 700;
  font-size: 1.15rem;
  margin-bottom: 0.5rem;
}
.verb-card .verb-desc {
  color: var(--lfx-grey);
  font-size: 0.925rem;
}

/* ---- Touch targets (phones/tablets — the request flow is mobile-first) ---- */
@media (max-width: 1024px) {
  .verb-card { padding: 1.5rem 1.25rem; }
}

/* ---- Money & percent formatting ---- */
.money, .percent {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ==========================================================================
   Request form (#2) — phone first, iPad second, desktop last.

   The person filling this in is standing on a job holding a phone in one
   hand. Everything below follows from that: one column, thumb-sized
   targets, the submit button pinned where a thumb already is, and 16px
   text in every input because anything smaller makes iOS zoom the page
   on focus and the user has to pinch back out.
   ========================================================================== */

.form-shell {
  max-width: 32rem;
  margin: 0 auto;
  /* Room for the pinned submit bar so the last field is never under it. */
  padding-bottom: 1rem;
}

/* ---- Page heading ---- */
.form-heading {
  margin-bottom: 1.25rem;
}
.form-heading h1 {
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: .15rem;
}
.form-heading p {
  color: var(--lfx-grey);
  font-size: .9rem;
  margin-bottom: 0;
}

/* ---- Section cards ---- */
.form-card {
  background: var(--lfx-white);
  border: 1px solid #E3E6EA;
  border-radius: .9rem;
  padding: 1.1rem 1rem 1.25rem;
  margin-bottom: 1rem;
}
.form-card + .form-card {
  margin-top: 0;
}
.form-card-title {
  display: flex;
  align-items: center;
  gap: .55rem;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--lfx-grey);
  margin-bottom: .9rem;
}
.form-card-title .step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  flex: 0 0 1.6rem;
  border-radius: 50%;
  background: var(--lfx-red-light);
  color: var(--lfx-red);
  font-size: .8rem;
  letter-spacing: 0;
}
.form-card-title .optional {
  margin-left: auto;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--lfx-grey);
}

.form-shell .form-label {
  font-weight: 600;
  font-size: .95rem;
  margin-bottom: .3rem;
}
.form-shell .form-text {
  font-size: .82rem;
}

/* 16px minimum, or iOS zooms the whole page when the field takes focus.
   Height is comfortably past the 44px Apple touch-target floor. */
.form-shell .form-control,
.form-shell .form-select {
  /* 16px literal, not 1rem: below 16 iOS zooms the page on focus, and
     stating it in px means no later type-scale change can trip that. */
  font-size: 16px;
  min-height: 3rem;
  border-radius: .6rem;
}
.form-shell textarea.form-control {
  min-height: 4.5rem;
}
/* Safari renders a bare date input as tiny centred text; force it to
   fill the control and sit left like every other field. */
.form-shell input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  text-align: left;
}

/* ---- Delivery / pickup windows: three cards, not a dropdown ---- */
.window-group {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .5rem;
}
.window-choice input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.window-choice label {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: 100%;
  height: 100%;
  min-height: 3.1rem;
  padding: .5rem .35rem;
  border: 1.5px solid #DDE1E6;
  border-radius: .6rem;
  cursor: pointer;
  font-weight: 600;
  font-size: .9rem;
  line-height: 1.15;
  transition: background-color .12s ease, border-color .12s ease;
}
.window-choice label:active {
  transform: scale(.98);
}
.window-choice input:checked + label {
  background-color: var(--lfx-red);
  border-color: var(--lfx-red);
  color: var(--lfx-white);
}
.window-choice input:focus-visible + label {
  outline: 2px solid var(--lfx-red);
  outline-offset: 2px;
}

/* ---- Type-ahead picker ---- */
.lfx-picker {
  position: relative;
}
.lfx-picker-results {
  position: absolute;
  z-index: 30;
  width: 100%;
  margin-top: .3rem;
  max-height: 16rem;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: .6rem;
  box-shadow: 0 .75rem 1.5rem rgba(0, 0, 0, .18);
  /* The panel owns the background, because the padding below would
     otherwise show the page through the gap above the first row. */
  background: var(--lfx-white);
  padding: .3rem 0;
}
/* Rows carry their own padding rather than inheriting Bootstrap's
   .py-2 from picker.js: at .5rem a two-line match (job site name over
   its address) reads as two loose lines instead of one item. Separators
   run between rows only — the panel's shadow and radius are the outer
   edge, so a full border on each row draws a box inside a box. */
.lfx-picker-results .list-group-item {
  cursor: pointer;
  min-height: 3rem;
  padding: .65rem 1rem;
  line-height: 1.35;
  border-left: 0;
  border-right: 0;
  border-color: #EDEFF2;
}
.lfx-picker-results .list-group-item:first-child {
  border-top: 0;
}
.lfx-picker-results .list-group-item:last-child {
  border-bottom: 0;
}
/* Gap between a match's name and its grey second line (address for job
   sites, kind for equipment) — enough to group them, not enough to make
   a single-line row look padded out. */
.lfx-picker-results .list-group-item > * + * {
  margin-top: .2rem;
}
.lfx-picker-results .list-group-item.is-active {
  background-color: var(--lfx-red-light);
}
.lfx-picker-results mark {
  padding: 0;
  background: transparent;
  font-weight: 700;
  color: var(--lfx-red);
}
/* Scoped to beat the row padding above, which is two classes deep — the
   "add it in Monday first" message is a sentence, not a match, and wants
   the roomier box. */
.lfx-picker-results .list-group-item.lfx-picker-empty {
  padding: .9rem 1rem;
  font-size: .88rem;
  color: var(--lfx-grey);
  cursor: default;
}
/* Chosen state: the input goes read-only until cleared, so a picked
   value can't be edited into something that matches no real record. */
.lfx-picker.is-chosen .form-control {
  background-color: #F6F8FA;
  font-weight: 600;
  color: var(--lfx-black);
}
.lfx-picker.is-chosen .form-control:focus {
  box-shadow: none;
}

/* ---- Pinned submit ---- */
.submit-bar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  margin: 1.25rem -.75rem 0;
  padding: .75rem .75rem calc(.75rem + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(8px);
  border-top: 1px solid #E3E6EA;
}
.submit-bar .btn {
  min-height: 3.25rem;
  font-size: 1.05rem;
  font-weight: 600;
  border-radius: .6rem;
}

/* ---- iPad and up ----------------------------------------------------
   More width, and the two halves of the schedule sit side by side —
   on a landscape iPad a single 32rem column is a stripe of content in a
   field of grey. Still one column of *thought*, just wider. */
@media (min-width: 768px) {
  .form-shell {
    max-width: 44rem;
  }
  .form-card {
    padding: 1.35rem 1.5rem 1.5rem;
  }
  .schedule-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
  }
  .schedule-grid .form-card {
    margin-bottom: 0;
  }
  .submit-bar {
    position: static;
    margin: 1.5rem 0 0;
    padding: 0;
    background: none;
    backdrop-filter: none;
    border-top: 0;
  }
  .submit-bar .btn {
    max-width: 20rem;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ---- Confirmation ---- */
.confirm-mark {
  width: 4rem;
  height: 4rem;
  margin: 0 auto .75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #E8F6EC;
  color: #1B7F3B;
  font-size: 2rem;
}
.confirm-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: .8rem 1rem;
  border-bottom: 1px solid #EDEFF2;
}
.confirm-row:last-child {
  border-bottom: 0;
}
.confirm-row .label {
  color: var(--lfx-grey);
  font-size: .85rem;
  flex: 0 0 auto;
}
.confirm-row .value {
  font-weight: 600;
  text-align: right;
}
.confirm-row .value .sub {
  display: block;
  font-weight: 400;
  font-size: .85rem;
  color: var(--lfx-grey);
}
.confirm-block {
  padding: .8rem 1rem;
  border-bottom: 1px solid #EDEFF2;
}
.confirm-block .label {
  color: var(--lfx-grey);
  font-size: .85rem;
  margin-bottom: .15rem;
}

/* ---- Active / All toggle ---- */
.filter-toggle {
  display: flex;
  gap: .25rem;
  padding: .25rem;
  margin-bottom: .9rem;
  border-radius: .6rem;
  background: var(--lfx-grey-light);
}
.filter-toggle a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  min-height: 2.5rem;
  border-radius: .45rem;
  text-decoration: none;
  font-size: .9rem;
  font-weight: 600;
  color: var(--lfx-grey);
}
.filter-toggle a.is-on {
  background: var(--lfx-white);
  color: var(--lfx-black);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}
.filter-toggle .count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.35rem;
  padding: 0 .35rem;
  border-radius: 1rem;
  background: rgba(0, 0, 0, .07);
  font-size: .78rem;
}
.filter-toggle a.is-on .count {
  background: var(--lfx-red-light);
  color: var(--lfx-red-dark);
}

/* ---- Request list rows ---- */
.request-row {
  transition: border-color .12s ease, background-color .12s ease;
}
.request-row:hover,
.request-row:focus-visible {
  border-color: var(--lfx-red);
  background-color: #FCFCFD;
}
.request-row:active {
  background-color: var(--lfx-red-light);
}

/* ==========================================================================
   Request progress — the route a request takes, with today's position.
   A vertical rail so it reads the same on a phone as on an iPad; a
   horizontal stepper would either wrap or shrink to unreadable on a
   375px screen.
   ========================================================================== */

.progress-rail {
  list-style: none;
  margin: 0;
  padding: 0;
}
.progress-step {
  position: relative;
  display: flex;
  gap: .9rem;
  padding-bottom: 1.15rem;
}
.progress-step:last-child {
  padding-bottom: 0;
}
/* The connecting line, drawn from each marker down to the next. */
.progress-step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 1.09rem;
  top: 2.35rem;
  bottom: .35rem;
  width: 2px;
  background: #E3E6EA;
}
.progress-step.is-done:not(:last-child)::before {
  background: #9DD5AE;
}
.progress-marker {
  flex: 0 0 2.25rem;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  border: 2px solid #E3E6EA;
  background: var(--lfx-white);
  color: var(--lfx-grey);
  z-index: 1;
}
.progress-step.is-done .progress-marker {
  border-color: #1B7F3B;
  background: #1B7F3B;
  color: var(--lfx-white);
}
.progress-step.is-current .progress-marker {
  border-color: var(--lfx-red);
  background: var(--lfx-red);
  color: var(--lfx-white);
  box-shadow: 0 0 0 .3rem var(--lfx-red-light);
}
.progress-step.is-stopped .progress-marker {
  border-color: var(--lfx-red);
  background: var(--lfx-white);
  color: var(--lfx-red);
}
.progress-body {
  padding-top: .15rem;
}
.progress-title {
  font-weight: 600;
  line-height: 1.3;
}
.progress-detail {
  font-size: .88rem;
  color: var(--lfx-grey);
}
.progress-step.is-current .progress-title {
  color: var(--lfx-red);
}
.progress-step.is-current .progress-detail {
  color: var(--lfx-black);
  font-weight: 600;
}
.progress-step.is-upcoming .progress-title,
.progress-step.is-upcoming .progress-detail {
  color: #A6ADB4;
}

/* Delivery's two substates (#101). "Waiting for the Hauler" is the normal
   current-step look; "Hauler on the way" is the one moment on this page
   where something is actively happening, so it gets the only motion in
   the rail — a slow pulse on the marker, and the distance in full black.
   Deliberately restrained: a foreman checks this page repeatedly, and
   anything faster would read as an alert rather than as progress. */
.progress-step.sub-on_the_way .progress-marker {
  animation: hauler-pulse 2.4s ease-in-out infinite;
}
.progress-step.sub-on_the_way .progress-detail {
  color: var(--lfx-black);
  font-weight: 700;
}

@keyframes hauler-pulse {
  0%, 100% { box-shadow: 0 0 0 .3rem var(--lfx-red-light); }
  50%      { box-shadow: 0 0 0 .55rem var(--lfx-red-light); }
}

/* Respect a stated preference for less motion — the pulse is decoration,
   and the wording already carries the whole message without it. */
@media (prefers-reduced-motion: reduce) {
  .progress-step.sub-on_the_way .progress-marker {
    animation: none;
  }
}

/* The headline answer, above the rail. */
.waiting-banner {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .8rem 1rem;
  border-radius: .6rem;
  background: var(--lfx-red-light);
  color: var(--lfx-red-dark);
  font-weight: 600;
  margin-bottom: 1rem;
}

/* ---- Multi-select chips (attachments) ---- */
.picker-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-bottom: .5rem;
}
.picker-chip:has(> span:only-child) {
  padding-right: .7rem;
}
.picker-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .35rem .5rem .35rem .7rem;
  border-radius: 2rem;
  background: var(--lfx-red-light);
  color: var(--lfx-red-dark);
  font-size: .88rem;
  font-weight: 600;
  line-height: 1.2;
}
.picker-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(214, 0, 28, .12);
  color: var(--lfx-red-dark);
  font-size: .8rem;
  cursor: pointer;
}
.picker-chip-x:hover,
.picker-chip-x:focus-visible {
  background: var(--lfx-red);
  color: var(--lfx-white);
}

/* ---- Phone: tighten everything except the tap targets ---------------
   The iPad layout is right, so this only narrows the gap below it. Type
   and padding come down; input height stays at 44px (Apple's floor) and
   input type stays at 16px, because shrinking either is what makes a
   form annoying rather than compact. */
@media (max-width: 767.98px) {
  .form-heading {
    margin-bottom: 1rem;
  }
  .form-heading h1 {
    font-size: 1.2rem;
  }
  .form-heading p {
    font-size: .85rem;
  }

  .form-card {
    padding: .85rem .9rem 1rem;
    margin-bottom: .7rem;
    border-radius: .75rem;
  }
  .form-card-title {
    font-size: .72rem;
    margin-bottom: .7rem;
    gap: .45rem;
  }
  .form-card-title .step {
    width: 1.35rem;
    height: 1.35rem;
    flex: 0 0 1.35rem;
    font-size: .72rem;
  }

  .form-shell .form-label {
    font-size: .85rem;
    margin-bottom: .25rem;
  }
  .form-shell .form-text {
    font-size: .76rem;
  }
  .form-shell .form-control,
  .form-shell .form-select {
    min-height: 2.75rem;   /* 44px — still a comfortable thumb target */
  }
  .form-shell textarea.form-control {
    min-height: 3.6rem;
  }
  .form-shell .mb-3 {
    margin-bottom: .75rem !important;
  }

  .window-group {
    gap: .4rem;
  }
  .window-choice label {
    min-height: 2.75rem;
    font-size: .82rem;
    padding: .4rem .25rem;
  }

  .submit-bar {
    margin-top: 1rem;
    padding: .6rem .75rem calc(.6rem + env(safe-area-inset-bottom));
  }
  .submit-bar .btn {
    min-height: 2.9rem;
    font-size: 1rem;
  }

  .lfx-picker-results .list-group-item {
    min-height: 2.75rem;
    font-size: .9rem;
  }

  /* Progress rail */
  .progress-step {
    gap: .7rem;
    padding-bottom: .95rem;
  }
  .progress-marker {
    flex: 0 0 1.9rem;
    width: 1.9rem;
    height: 1.9rem;
    font-size: .85rem;
  }
  .progress-step:not(:last-child)::before {
    left: .93rem;
    top: 2rem;
  }
  .progress-title {
    font-size: .93rem;
  }
  .progress-detail {
    font-size: .82rem;
  }
  .waiting-banner {
    padding: .65rem .85rem;
    font-size: .92rem;
    margin-bottom: .8rem;
  }

  /* Confirmation / list rows */
  .confirm-row,
  .confirm-block {
    padding: .65rem .85rem;
  }
  .confirm-row .label,
  .confirm-block .label {
    font-size: .8rem;
  }
  .confirm-row .value {
    font-size: .93rem;
  }
  .confirm-mark {
    width: 3.25rem;
    height: 3.25rem;
    font-size: 1.6rem;
  }
}

/* ==========================================================================
   Approval queue (#12) — the whole request on one card, then two
   buttons. Desktop or tablet: the approver is at a desk, not on a job.
   ========================================================================== */

.approval-what {
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.25;
}
.approval-when {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1.5rem;
  margin-top: .75rem;
  font-size: .9rem;
}
.approval-when .label,
.approval-note .label {
  color: var(--lfx-grey);
  font-size: .8rem;
  margin-right: .25rem;
}
.approval-note {
  margin-top: .5rem;
  padding: .5rem .7rem;
  border-radius: .5rem;
  background: var(--lfx-grey-light);
  font-size: .9rem;
}
.approval-note .label {
  display: block;
}

.approval-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: .5rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid #EDEFF2;
}
.approval-actions form {
  margin: 0;
}
.approval-actions .btn {
  min-height: 2.75rem;
  font-weight: 600;
}

.approval-decision {
  margin-top: 1rem;
  padding-top: .75rem;
  border-top: 1px solid #EDEFF2;
  font-size: .9rem;
  color: var(--lfx-grey);
}
.approval-reason {
  margin-top: .35rem;
  padding: .5rem .7rem;
  border-left: 3px solid var(--lfx-red);
  background: var(--lfx-red-light);
  color: var(--lfx-black);
  border-radius: 0 .4rem .4rem 0;
}

/* ==========================================================================
   Fleet board (#22) — desktop-focused, per the issue's own criterion.

   The page is a long vertical scroll of site cards, so the one thing that
   genuinely helps on a wide screen is keeping the filters reachable after
   the first screenful. Sticky from lg up only: on a phone a pinned bar
   would eat a third of the viewport, and this page is not built for
   phones anyway (the request flow is the mobile-first one).
   ========================================================================== */

@media (min-width: 992px) {
  .fleet-controls {
    position: sticky;
    /* Clear of the navbar, which is not itself sticky — this is just
       breathing room from the top of the viewport. */
    top: .5rem;
    z-index: 20;
    /* Opaque: rows scroll underneath it. */
    background: var(--lfx-white);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .06);
  }
}

/* ==========================================================================
   Inventory page (#14) — "What we have"
   Phone and tablet keep the stacked type cards; from lg up each kind
   section reads as a table (Type / Units header, flat white rows) because
   a desktop screen of chunky cards wastes the width it has. Same DOM both
   ways — the <details> expansion still opens the unit list inline.
   ========================================================================== */

.inv-type {
  margin-bottom: .5rem;
}
.inv-head {
  display: none;
}

@media (min-width: 992px) {
  .inv-shell {
    max-width: 52rem;
  }
  .inv-table {
    background: var(--lfx-white);
    border: 1px solid #E3E6EA;
    border-radius: .9rem;
    overflow: hidden;
  }
  .inv-head {
    display: flex;
    justify-content: space-between;
    padding: .6rem .9rem .5rem;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--lfx-grey);
  }
  .inv-table .inv-type {
    border: 0;
    border-top: 1px solid #E3E6EA;
    border-radius: 0;
    margin-bottom: 0;
    padding: .6rem .9rem;
  }
  .inv-table .inv-type:hover,
  .inv-table .inv-type[open] {
    background: #F6F8FA;
  }
}

/* ==========================================================================
   Dispatch map (#121) — the run drawn live, tablet-first like the rest
   of the run view. The pins are divIcons so route numbers, the done
   check, and the Hauler read at truck-cab distance.
   ========================================================================== */

#run-map {
  height: 65vh;
  min-height: 420px;
  border-radius: .75rem;
  border: 1px solid #E3E6EA;
}
.map-pin {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: .95rem;
  color: #fff;
  background: #1F2937;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
}
.map-pin-next   { background: var(--lfx-red); }
.map-pin-done   { background: #9CA3AF; }
.map-pin-hauler { background: #B45309; }  /* the Dispatch amber */
.map-pin-depot  { background: #15803D; }

/* Legend swatches under the map. */
.map-key {
  display: inline-block;
  width: 22px;
  height: 4px;
  border-radius: 2px;
  vertical-align: middle;
}
.map-key-next  { background: var(--lfx-red); }
.map-key-route { background: #6B7280; }
.map-key-pin {
  display: inline-flex;
  width: 22px;
  height: 22px;
  font-size: .75rem;
}

/* ==========================================================================
   Dispatch map, full-bleed (#121 piece 6) — the map IS the page, the
   canonical mobile-maps idiom. The sheet and strip float over it; the
   body never scrolls, the queue scrolls inside the expanded sheet.
   ========================================================================== */

.map-shell {
  padding: 0 !important;
  max-width: none !important;
}

#run-map {
  position: fixed;
  top: 63px;               /* under the navbar (0.75rem pad ×2 + line + 3px border) */
  left: 0;
  right: 0;
  bottom: 0;
  height: auto;            /* the fixed inset wins over the old 65vh */
  min-height: 0;
  border: 0;
  border-radius: 0;
  z-index: 0;
}

.map-strip {
  position: fixed;
  top: 71px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1001;           /* above Leaflet panes (max ~1000) */
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .35rem .6rem;
  background: rgba(255, 255, 255, .92);
  border: 1px solid #E3E6EA;
  border-radius: .75rem;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
  max-width: calc(100vw - 1rem);
}

.map-banner {
  position: fixed;
  top: 130px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1001;
  max-width: min(92vw, 480px);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
}

/* ---- The bottom sheet ---- */
.map-sheet {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1002;
  height: 24vh;
  min-height: 205px;
  background: var(--lfx-white);
  border-top: 1px solid #E3E6EA;
  border-radius: 1rem 1rem 0 0;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, .12);
  transition: height .25s ease;
  display: flex;
  flex-direction: column;
}
.map-sheet.is-open {
  height: 85vh;
}
/* Wide screens: the sheet FLOATS bottom-left — same gap below as
   beside (Brendan, 2026-08-31), all corners rounded since no edge
   touches the viewport any more. Same one layout otherwise. */
@media (min-width: 992px) {
  .map-sheet {
    left: 1rem;
    right: auto;
    bottom: 1rem;
    width: 480px;
    border-radius: 1rem;
    border: 1px solid #E3E6EA;
  }
  .map-sheet.is-open {
    height: calc(85vh - 1rem);
  }
}

.map-sheet-grab {
  border: 0;
  background: none;
  padding: .1rem 0 0;
  width: 100%;
  color: var(--lfx-grey);
  font-size: 1.25rem;
  line-height: 1.2;
  flex-shrink: 0;
}

.map-sheet-body {
  padding: 0 1rem 1rem;
  display: flex;
  flex-direction: column;
  min-height: 0;           /* lets the queue actually shrink+scroll */
}

/* The queue is invisible while collapsed and scrolls when open. */
.map-queue {
  margin-top: .75rem;
  overflow-y: auto;
  min-height: 0;
  display: none;
}
.map-sheet.is-open .map-queue {
  display: block;
}

.map-queue-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem 0;
  border-top: 1px solid #EDEFF2;
}
.map-queue-row.is-done {
  opacity: .55;
}

.min-width-0 {
  min-width: 0;
}

/* ---- Count stepper (#141) ----

   For a number picked with a thumb, in a truck. The buttons carry the
   work; the field between them stays editable for the rare exact
   number, and narrow, because the values are single digits. */
.lfx-stepper {
  display: flex;
  align-items: stretch;
  gap: .5rem;
}
.lfx-stepper input {
  width: 4.5rem;
  flex: 0 0 auto;
  /* The spinner arrows are a second, tiny control doing the same job as
     the buttons either side — and unusable with gloves on. */
  -moz-appearance: textfield;
  appearance: textfield;
}
.lfx-stepper input::-webkit-outer-spin-button,
.lfx-stepper input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.lfx-stepper .btn {
  flex: 0 0 auto;
  min-width: 3rem;
}
