/* Bring The Truck — owner portal design system.
   One stylesheet for every authenticated screen, so the portal reads as a
   single product rather than six pages that happen to share a colour.

   Read one-handed, outdoors, between jobs: mobile-first, generous tap targets,
   real contrast. Separate bundle from app.css — the public site carries none of
   this and this carries none of the marketing chrome.

   The CSP has no style-src 'unsafe-inline', so a style="" attribute is dropped
   by the browser outright. Everything visual therefore has to live here, which
   is why there are utility classes rather than one-off inline rules. */

:root {
  /* Core palette. Navy leads, orange is an accent that has to earn its place —
     it marks the primary action and the current thing, nothing else. */
  --a-navy:      #0F2A4A;
  --a-navy-deep: #0A1F3A;
  --a-navy-soft: #1B3E63;
  --a-orange:    #F26B21;
  --a-orange-dk: #D9550F;

  --a-ink:    #142433;
  --a-body:   #3D4F60;
  --a-muted:  #6B7C8D;
  --a-line:   #E4EAF1;
  --a-line-2: #EEF2F7;

  --a-page:    #F7F8FA;
  --a-surface: #FFFFFF;

  --a-ok:   #15803D;
  --a-warn: #B45309;
  --a-bad:  #B42318;

  --a-ok-wash:     #ECFAF1;
  --a-warn-wash:   #FFF8ED;
  --a-bad-wash:    #FEF3F2;
  --a-blue-wash:   #EEF4FC;
  --a-orange-wash: #FEF0E7;
  --a-violet-wash: #F1EEFC;

  --a-r-sm: 10px;
  --a-r:    14px;
  --a-r-lg: 18px;

  --a-shadow:    0 1px 2px rgba(15, 42, 74, .05), 0 6px 16px rgba(15, 42, 74, .05);
  --a-shadow-lg: 0 2px 4px rgba(15, 42, 74, .06), 0 14px 30px rgba(15, 42, 74, .10);

  --a-tap: 48px;
  --a-bar: 56px;
}

*, *::before, *::after { box-sizing: border-box; }

body.admin {
  margin: 0;
  background: var(--a-page);
  color: var(--a-ink);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}

/* The bottom navigation is fixed, so the page has to end above it or the last
   control sits underneath and cannot be tapped. */
.a-wrap {
  max-width: 760px;
  margin: 0 auto;
  padding: 18px 16px calc(var(--a-tap) + env(safe-area-inset-bottom, 0px) + 48px);
}

/* ---- App bar ------------------------------------------------------------ */
.a-bar {
  position: sticky; top: 0; z-index: 40;
  background: var(--a-navy-deep);
  color: #fff;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 14px 10px;
  display: flex; align-items: center; gap: 10px;
  min-height: var(--a-bar);
}
.a-bar__name { font-weight: 800; font-size: .98rem; letter-spacing: -.01em; white-space: nowrap; }
.a-bar__name em { font-style: normal; color: var(--a-orange); }
.a-bar__tag {
  margin-left: 7px; padding: 2px 7px; border-radius: 6px;
  background: rgba(255, 255, 255, .12); color: #DCE7F3;
  font-size: .66rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  vertical-align: 2px;
}
/* color:inherit is load-bearing — the generic h2 rule sets dark ink, which on
   the navy bar renders the title invisible. */
.a-bar__title { font-weight: 700; font-size: 1.02rem; margin: 0 auto; color: inherit; }
.a-bar__spacer { flex: 1; }

/* Back chevron and the two right-hand controls share one round target so the
   bar keeps its rhythm at every width. */
.a-bar__btn {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%; color: #fff; text-decoration: none;
  background: transparent; border: 0; cursor: pointer;
  position: relative;
}
.a-bar__btn:hover { background: rgba(255, 255, 255, .10); }
.a-bar__btn svg { width: 21px; height: 21px; }
.a-bar__dot {
  position: absolute; top: 3px; right: 3px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--a-orange); color: #fff;
  font-size: .64rem; font-weight: 800; line-height: 17px; text-align: center;
  border: 2px solid var(--a-navy-deep);
}
.a-bar__avatar {
  width: 36px; height: 36px; flex: none;
  border-radius: 50%; display: grid; place-items: center;
  background: #fff; color: var(--a-navy);
  font-size: .78rem; font-weight: 800; letter-spacing: .02em;
  text-decoration: none;
  cursor: pointer; list-style: none;
}
.a-bar__avatar::-webkit-details-marker { display: none; }
.a-bar__avatar:hover { background: #E9F0F8; }

/* Account menu. Anchored to the bar's right edge, never the avatar's centre,
   so at 320px it cannot hang off-screen; z-index above the sticky bar so no
   page content covers it. */
.a-menu { position: relative; flex: none; }
.a-menu__panel {
  position: absolute; right: 0; top: calc(100% + 8px);
  z-index: 60;
  min-width: 220px; max-width: calc(100vw - 24px);
  background: #fff; border: 1px solid var(--a-line);
  border-radius: var(--a-r); box-shadow: var(--a-shadow-lg);
  padding: 6px; overflow: hidden;
}
.a-menu__who {
  display: flex; flex-direction: column; gap: 1px;
  margin: 0 0 4px; padding: 10px 12px 9px;
  border-bottom: 1px solid var(--a-line-2);
}
.a-menu__who span:first-child { font-weight: 800; font-size: .9rem; color: var(--a-ink); }
.a-menu__who span:last-child { font-size: .78rem; color: var(--a-muted); overflow-wrap: anywhere; }
.a-menu__item {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--a-tap); padding: 10px 12px;
  border-radius: 9px;
  font-size: .9rem; font-weight: 600;
  text-decoration: none; color: var(--a-ink);
}
.a-menu__item svg { width: 18px; height: 18px; flex: none; color: var(--a-navy-soft); }
.a-menu__item:hover { background: var(--a-line-2); }
.a-menu__item--out { color: var(--a-bad); }
.a-menu__item--out svg { color: var(--a-bad); }
.a-menu__item--out:hover { background: var(--a-bad-wash); }

/* At 320 the wordmark, the Ops tag, the bell and the avatar are 3px wider than
   the viewport. Tighten the bar rather than dropping a control — the avatar is
   the only route to account settings, so it has to stay. */
@media (max-width: 359px) {
  .a-bar { padding-left: 10px; padding-right: 10px; gap: 4px; }
  .a-bar__name { font-size: .86rem; }
  .a-bar__tag { margin-left: 5px; padding: 2px 5px; font-size: .6rem; }
  .a-bar__btn { width: 34px; height: 34px; }
  .a-bar__btn svg { width: 19px; height: 19px; }
  .a-bar__avatar { width: 32px; height: 32px; font-size: .72rem; }
}

/* ---- Bottom navigation --------------------------------------------------
   Left as it was by request: same four destinations, same labels, same
   text-only markup. Only the colours were brought into the new palette. */
.a-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: #fff; border-top: 1px solid var(--a-line);
  padding-bottom: env(safe-area-inset-bottom);
}
.a-nav a {
  min-height: var(--a-tap); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
  font-size: .72rem; font-weight: 700; text-decoration: none;
  color: var(--a-muted); padding: 8px 4px;
}
.a-nav a[aria-current="page"] { color: var(--a-navy); box-shadow: inset 0 3px 0 var(--a-orange); }
.a-nav a:focus-visible { outline: 3px solid var(--a-orange); outline-offset: -3px; }

/* ---- Page header --------------------------------------------------------- */
.ui-head { margin: 4px 0 18px; }
.ui-head__eyebrow {
  margin: 0 0 3px; font-size: .76rem; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; color: var(--a-orange);
}
/* Headings wrap anywhere. A quote reference like qt_7779db357baec5a5d420 has no
   space, no hyphen and no other break opportunity, so without this it renders
   as one 490px word and pushes the whole page sideways on a phone. */
h1, .ui-head__h {
  margin: 0; font-size: clamp(1.42rem, 6vw, 1.72rem); line-height: 1.2;
  font-weight: 800; letter-spacing: -.022em; color: var(--a-ink);
  overflow-wrap: anywhere;
}
.ui-head__sub { margin: 6px 0 0; color: var(--a-muted); font-size: .92rem; }

/* Section heading with an optional trailing link. */
.ui-sec { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 26px 0 10px; }
h2, .ui-sec__t { margin: 0; font-size: 1.05rem; font-weight: 800; letter-spacing: -.015em; color: var(--a-ink); overflow-wrap: anywhere; }
.a-card__title, .ui-tl__t, .ui-acc__t, .ui-grp__t { overflow-wrap: anywhere; }

/* A quote reference is one unbroken 23-character token — no space, no hyphen,
   nothing for overflow-wrap to grab. break-all is the only thing that reliably
   breaks it, and it needs to be smaller than a normal h1 to sit on two lines
   rather than four on a 320px screen. */
.ui-ref {
  font-size: clamp(1.15rem, 5.4vw, 1.4rem);
  /* `break-all` was right when this headline was the long qt_ identifier: it
     had no break opportunities and would have pushed the card sideways. The
     headline is now "Quote #482", and break-all split it mid-number at 320px.
     `anywhere` only breaks when there is genuinely no other option, so a short
     label stays whole and a long one still cannot overflow. */
  overflow-wrap: anywhere;
  letter-spacing: -.01em;
}
.ui-sec__link { font-size: .84rem; font-weight: 700; color: var(--a-navy-soft); text-decoration: none; white-space: nowrap; }
.ui-sec__link:hover { text-decoration: underline; }

/* ---- Surfaces ------------------------------------------------------------ */
.a-card, .ui-card {
  background: var(--a-surface);
  border: 1px solid var(--a-line);
  border-radius: var(--a-r);
  box-shadow: var(--a-shadow);
  padding: 15px;
  margin-bottom: 12px;
}
.ui-card--flush { padding: 0; overflow: hidden; }
.a-card--tight { padding: 13px 15px; }
.a-card__row { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; }
.a-card__title { font-weight: 700; margin: 0 0 2px; }
.a-card__meta { color: var(--a-muted); font-size: .85rem; margin: 0; overflow-wrap: anywhere; }

a.ui-card, a.a-card { display: block; text-decoration: none; color: inherit; }
a.ui-card:hover, a.a-card:hover { border-color: #D3DEEA; box-shadow: var(--a-shadow-lg); }

/* ---- Needs attention ----------------------------------------------------
   One panel, not one card per problem. A stack of near-identical amber boxes
   reads as noise; a single list with a count reads as a to-do. */
.ui-attn {
  background: var(--a-warn-wash);
  border: 1px solid #F6E0BC;
  border-radius: var(--a-r);
  padding: 14px 15px;
  margin-bottom: 16px;
}
.ui-attn__h { display: flex; align-items: center; gap: 9px; margin: 0 0 8px; font-size: .98rem; font-weight: 800; color: #7C4A0B; }
.ui-attn__h svg { width: 19px; height: 19px; flex: none; }
.ui-attn__list { list-style: none; margin: 0; padding: 0; }
.ui-attn__list li + li { border-top: 1px solid #F3E2C6; }
.ui-attn__row {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--a-tap); padding: 9px 0;
  text-decoration: none; color: #7C4A0B; font-size: .9rem; font-weight: 600;
}
.ui-attn__row svg { width: 17px; height: 17px; flex: none; color: #C2790F; }
.ui-attn__row span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.ui-attn__row .ui-attn__go { width: 16px; height: 16px; color: #B0854A; }
.ui-attn__row:hover { color: #5F3808; }
.ui-attn--blocker { background: var(--a-bad-wash); border-color: #F5CFCB; }
.ui-attn--blocker .ui-attn__h, .ui-attn--blocker .ui-attn__row { color: #8A2A21; }
.ui-attn--blocker .ui-attn__list li + li { border-top-color: #F3D5D1; }

/* ---- KPI tiles ----------------------------------------------------------- */
.ui-kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px; }
@media (min-width: 620px) { .ui-kpis { grid-template-columns: repeat(4, 1fr); } }
.ui-kpi {
  position: relative;
  background: var(--a-surface); border: 1px solid var(--a-line);
  border-radius: var(--a-r); box-shadow: var(--a-shadow);
  padding: 13px 46px 13px 14px;
  text-decoration: none; color: inherit;
  display: block; min-height: 74px;
}
.ui-kpi:hover { border-color: #D3DEEA; box-shadow: var(--a-shadow-lg); }
.ui-kpi__v { display: block; font-size: 1.55rem; font-weight: 800; line-height: 1.15; letter-spacing: -.03em; color: var(--a-ink); }
.ui-kpi__l { display: block; margin-top: 1px; font-size: .78rem; font-weight: 600; color: var(--a-muted); overflow-wrap: anywhere; }
.ui-kpi__i {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px; border-radius: 9px;
  display: grid; place-items: center;
}
.ui-kpi__i svg { width: 17px; height: 17px; }
.ui-kpi--blue   .ui-kpi__i { background: var(--a-blue-wash);   color: #2C5FA8; }
.ui-kpi--orange .ui-kpi__i { background: var(--a-orange-wash); color: var(--a-orange-dk); }
.ui-kpi--violet .ui-kpi__i { background: var(--a-violet-wash); color: #5B4BC4; }
.ui-kpi--green  .ui-kpi__i { background: var(--a-ok-wash);     color: var(--a-ok); }

/* ---- Status badges ------------------------------------------------------- */
.ui-badge, .pill {
  display: inline-block; flex: none;
  padding: 3px 9px; border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .01em;
  white-space: nowrap;
  background: var(--a-line-2); color: var(--a-body); border: 1px solid var(--a-line);
}
.ui-badge--new       { background: var(--a-orange-wash); color: #9A4A12; border-color: #F8D8C2; }
.ui-badge--awaiting  { background: var(--a-warn-wash);   color: #8A5A0B; border-color: #F3DFBC; }
.ui-badge--approved,
.ui-badge--ok        { background: var(--a-ok-wash);     color: var(--a-ok); border-color: #C3E8D3; }
.ui-badge--declined  { background: var(--a-bad-wash);    color: var(--a-bad); border-color: #F5CFCB; }
.ui-badge--hold      { background: var(--a-warn-wash);   color: #8A5A0B; border-color: #F3DFBC; }
.ui-badge--blocked   { background: var(--a-violet-wash); color: #4B3DAF; border-color: #DCD5F6; }
.ui-badge--neutral   { background: var(--a-line-2);      color: var(--a-body); border-color: var(--a-line); }
.pill--new { background: var(--a-orange-wash); color: #9A4A12; border-color: #F8D8C2; }
.pill--reviewed { background: var(--a-warn-wash); color: #8A5A0B; border-color: #F3DFBC; }
.pill--approved { background: var(--a-ok-wash); color: var(--a-ok); border-color: #C3E8D3; }
.pill--declined { background: var(--a-bad-wash); color: var(--a-bad); border-color: #F5CFCB; }

/* ---- Route pair ---------------------------------------------------------- */
.ui-route { position: relative; padding: 2px 0; }
.ui-route__leg { display: flex; gap: 10px; align-items: flex-start; padding: 3px 0; }
.ui-route__dot { width: 15px; height: 15px; flex: none; margin-top: 3px; border-radius: 50%; position: relative; }
.ui-route__dot::after { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: #fff; }
.ui-route__dot--a { background: #2C5FA8; }
.ui-route__dot--b { background: var(--a-orange); }
.ui-route__addr { font-size: .89rem; line-height: 1.4; color: var(--a-body); min-width: 0; overflow-wrap: anywhere; }
.ui-route__rail { position: absolute; left: 7px; top: 24px; bottom: 24px; width: 1px; background: var(--a-line); }

/* ---- Quote card ---------------------------------------------------------- */
.ui-quote { padding: 0; overflow: hidden; }
.ui-quote__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding: 14px 15px 8px; }
.ui-quote__who { margin: 0; font-size: 1.02rem; font-weight: 800; letter-spacing: -.015em; min-width: 0; overflow-wrap: anywhere; }
.ui-quote__body { padding: 0 15px 12px; }
.ui-quote__meta {
  display: flex; flex-wrap: wrap; gap: 4px 10px;
  padding: 10px 15px; border-top: 1px solid var(--a-line-2);
  font-size: .78rem; color: var(--a-muted);
}
.ui-quote__meta strong { color: var(--a-body); font-weight: 700; }
.ui-quote__flags {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  padding: 9px 15px; border-top: 1px solid var(--a-line-2); background: #FDFBFA;
  font-size: .79rem; font-weight: 600;
}
.ui-flag { display: inline-flex; align-items: center; gap: 5px; color: var(--a-bad); }
.ui-flag svg { width: 15px; height: 15px; flex: none; }
.ui-flag--muted { color: var(--a-muted); }
.ui-quote__act { padding: 0 15px 14px; }

/* ---- Buttons ------------------------------------------------------------- */
.btn-a, .ui-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--a-tap); padding: 12px 18px;
  border-radius: var(--a-r-sm);
  font-weight: 700; font-size: .93rem; font-family: inherit;
  text-decoration: none; cursor: pointer;
  border: 1px solid var(--a-line); background: #fff; color: var(--a-ink);
  transition: background .14s ease, border-color .14s ease, transform .1s ease;
}
.btn-a:hover, .ui-btn:hover { background: var(--a-line-2); }
.btn-a:active, .ui-btn:active { transform: translateY(1px); }
.btn-a svg, .ui-btn svg { width: 18px; height: 18px; flex: none; }
.btn-a--primary { background: var(--a-orange); border-color: var(--a-orange); color: #fff; }
.btn-a--primary:hover { background: var(--a-orange-dk); border-color: var(--a-orange-dk); }
.btn-a--navy { background: var(--a-navy); border-color: var(--a-navy); color: #fff; }
.btn-a--navy:hover { background: var(--a-navy-deep); border-color: var(--a-navy-deep); }
.btn-a--danger { background: #fff; border-color: #EFC6C1; color: var(--a-bad); }
.btn-a--danger:hover { background: var(--a-bad-wash); }
.btn-a--block { display: flex; width: 100%; }
.btn-a--sm { min-height: 38px; padding: 8px 13px; font-size: .84rem; border-radius: 9px; }
.btn-a[disabled] { opacity: .5; cursor: not-allowed; }
.btn-row { display: grid; gap: 9px; grid-template-columns: 1fr; margin-top: 10px; }
@media (min-width: 560px) { .btn-row { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } }

:where(a, button, input, select, textarea, summary):focus-visible {
  outline: 3px solid var(--a-orange); outline-offset: 2px; border-radius: 4px;
}

/* Round icon actions — phone and email on the quote detail. */
.ui-iact { display: flex; gap: 8px; flex: none; }
.ui-iact a {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--a-blue-wash); color: #2C5FA8; text-decoration: none;
}
.ui-iact a:hover { background: #DDE9F8; }
.ui-iact svg { width: 18px; height: 18px; }

/* Bottom action grid on the quote detail. */
.ui-acts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin-top: 14px; }
@media (min-width: 560px) { .ui-acts { grid-template-columns: repeat(4, 1fr); } }
.ui-acts .btn-a { flex-direction: column; gap: 5px; padding: 12px 8px; font-size: .8rem; min-height: 68px; text-align: center; }
.ui-acts .btn-a svg { width: 20px; height: 20px; }
.ui-acts__ok svg { color: var(--a-ok); }
.ui-acts__no svg { color: var(--a-bad); }
.ui-acts__note svg { color: #2C5FA8; }
.ui-acts__send svg { color: var(--a-navy-soft); }
.ui-acts form { display: contents; }

/* ---- Grouped detail sections -------------------------------------------- */
.ui-grp { background: var(--a-surface); border: 1px solid var(--a-line); border-radius: var(--a-r); box-shadow: var(--a-shadow); margin-bottom: 12px; overflow: hidden; }
.ui-grp__h { display: flex; align-items: center; gap: 9px; padding: 12px 15px; border-bottom: 1px solid var(--a-line-2); }
.ui-grp__h svg { width: 18px; height: 18px; flex: none; color: var(--a-navy-soft); }
.ui-grp__t { margin: 0; font-size: .93rem; font-weight: 800; letter-spacing: -.01em; }
.ui-grp__b { padding: 13px 15px; }
.ui-grp__b > :first-child { margin-top: 0; }
.ui-grp__b > :last-child { margin-bottom: 0; }

/* Label/value rows. Stacks under 380px so a long value never collides. */
.ui-rows { margin: 0; }
.ui-rows > div { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; padding: 8px 0; border-bottom: 1px solid var(--a-line-2); }
.ui-rows > div:first-child { padding-top: 0; }
.ui-rows > div:last-child { border-bottom: 0; padding-bottom: 0; }
.ui-rows dt { color: var(--a-muted); font-size: .85rem; flex: none; }
.ui-rows dd { margin: 0; font-weight: 600; font-size: .89rem; text-align: right; min-width: 0; overflow-wrap: anywhere; }
.ui-rows dd.is-warn { color: var(--a-bad); }
.ui-rows dd.is-ok { color: var(--a-ok); }
.ui-rows dd.is-muted { color: var(--a-muted); font-weight: 500; }
@media (max-width: 379px) {
  .ui-rows > div { flex-direction: column; gap: 2px; }
  .ui-rows dd { text-align: left; }
}
.a-dl { margin: 0; }
.a-dl div { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; border-bottom: 1px solid var(--a-line-2); }
.a-dl div:last-child { border-bottom: 0; }
.a-dl dt { color: var(--a-muted); font-size: .84rem; flex: none; }
.a-dl dd { margin: 0; font-weight: 600; text-align: right; overflow-wrap: anywhere; }

/* ---- Accordion ----------------------------------------------------------
   <details>/<summary> so it works with JavaScript off and the browser handles
   the expanded/collapsed state for assistive technology at no cost. */
.ui-acc { background: var(--a-surface); border: 1px solid var(--a-line); border-radius: var(--a-r); box-shadow: var(--a-shadow); margin-bottom: 11px; overflow: hidden; }
.ui-acc > summary {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 15px; cursor: pointer; list-style: none;
  min-height: 64px;
}
.ui-acc > summary::-webkit-details-marker { display: none; }
.ui-acc__i { width: 34px; height: 34px; flex: none; border-radius: 10px; display: grid; place-items: center; background: var(--a-blue-wash); color: #2C5FA8; }
.ui-acc__i svg { width: 18px; height: 18px; }
.ui-acc__txt { flex: 1; min-width: 0; }
.ui-acc__t { display: block; font-size: .96rem; font-weight: 800; letter-spacing: -.01em; }
.ui-acc__s { display: block; margin-top: 2px; font-size: .8rem; color: var(--a-muted); overflow-wrap: anywhere; }
.ui-acc__chev { width: 18px; height: 18px; flex: none; color: var(--a-muted); transition: transform .18s ease; }
.ui-acc[open] .ui-acc__chev { transform: rotate(90deg); }
.ui-acc__b { padding: 2px 15px 15px; border-top: 1px solid var(--a-line-2); }
.ui-acc__b > :first-child { margin-top: 13px; }
.ui-acc > summary:hover { background: #FBFCFE; }

/* ---- Forms --------------------------------------------------------------- */
.a-field { margin-bottom: 15px; }
.a-field:last-of-type { margin-bottom: 0; }
.a-field label { display: block; font-weight: 700; font-size: .84rem; margin-bottom: 6px; color: var(--a-body); }
.a-field input, .a-field select, .a-field textarea {
  width: 100%; min-height: var(--a-tap); padding: 11px 13px;
  font-size: 1rem; font-family: inherit;
  border: 1px solid #D8E0E9; border-radius: var(--a-r-sm);
  background: #fff; color: var(--a-ink);
}
.a-field textarea { min-height: 96px; resize: vertical; }
.a-field input:focus, .a-field select:focus, .a-field textarea:focus {
  outline: 3px solid rgba(242, 107, 33, .3); outline-offset: 0;
  border-color: var(--a-orange);
}
.a-hint { font-size: .79rem; color: var(--a-muted); margin: 6px 0 0; }

/* Password field with a reveal toggle. */
.ui-pw { position: relative; }
.ui-pw input { padding-right: 50px; }
.ui-pw__eye {
  position: absolute; top: 50%; right: 5px; transform: translateY(-50%);
  width: 40px; height: 40px; border: 0; background: transparent;
  border-radius: 50%; cursor: pointer; display: grid; place-items: center;
  color: var(--a-muted);
}
.ui-pw__eye:hover { background: var(--a-line-2); color: var(--a-body); }
.ui-pw__eye svg { width: 19px; height: 19px; }

/* Weekly hours: two times and a closed toggle, stacked on a phone. */
/* min-width:0 on the cells: a date or time input has a wide intrinsic size in
   Chrome and a grid item will not shrink below it without this, so at 320 the
   picker gets clipped by its own card. */
.a-daygrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: center; }
.a-daygrid > * { min-width: 0; }
.a-field input[type="date"], .a-field input[type="time"] { min-width: 0; }
.a-daygrid .a-check { grid-column: 1 / -1; }
@media (min-width: 560px) { .a-daygrid { grid-template-columns: 1fr 1fr auto; } .a-daygrid .a-check { grid-column: auto; } }
.a-check { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: .88rem; min-height: var(--a-tap); }
.a-check input { width: 22px; height: 22px; min-height: 0; flex: none; accent-color: var(--a-orange); }

.a-suggest { list-style: none; margin: 6px 0 0; padding: 0; border: 1px solid var(--a-line); border-radius: var(--a-r-sm); overflow: hidden; background: #fff; box-shadow: var(--a-shadow); }
.a-suggest__btn { display: block; width: 100%; text-align: left; min-height: var(--a-tap); padding: 11px 13px; border: 0; border-bottom: 1px solid var(--a-line-2); background: #fff; font-size: .92rem; font-family: inherit; cursor: pointer; color: var(--a-ink); }
.a-suggest li:last-child .a-suggest__btn { border-bottom: 0; }
.a-suggest__btn:hover, .a-suggest__btn:focus { background: var(--a-blue-wash); }

/* ---- Alerts -------------------------------------------------------------- */
.a-alert { border-radius: var(--a-r-sm); padding: 12px 14px; margin-bottom: 14px; font-size: .9rem; display: flex; gap: 9px; align-items: flex-start; }
.a-alert svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.a-alert--bad { background: var(--a-bad-wash); border: 1px solid #F5CFCB; color: #7A241D; }
.a-alert--ok { background: var(--a-ok-wash); border: 1px solid #C3E8D3; color: #10552F; }
.a-alert--info { background: var(--a-blue-wash); border: 1px solid #CFDFF4; color: #1E3F5E; }

/* ---- Empty states -------------------------------------------------------- */
.ui-empty { text-align: center; padding: 26px 16px; }
.ui-empty__i { width: 34px; height: 34px; color: #B7C4D3; margin-bottom: 8px; }
.ui-empty__t { margin: 0; font-weight: 700; font-size: .92rem; color: var(--a-body); }
.ui-empty__b { margin: 4px 0 0; font-size: .84rem; color: var(--a-muted); }
.a-empty { color: var(--a-muted); font-size: .9rem; padding: 8px 0; margin: 0; }

/* ---- Agenda / timeline --------------------------------------------------- */
.ui-daynav { display: flex; align-items: center; gap: 9px; margin-bottom: 14px; }
.ui-daynav__d { flex: 1; text-align: center; min-width: 0; }
.ui-daynav__d b { display: block; font-size: .98rem; font-weight: 800; letter-spacing: -.01em; }
.ui-daynav__d span { display: block; font-size: .78rem; color: var(--a-muted); }
.ui-daynav .btn-a { min-height: 42px; padding: 8px 12px; flex: none; }

.ui-tl { margin: 0; }
.ui-tl__row { display: flex; gap: 11px; padding: 10px 0; border-bottom: 1px solid var(--a-line-2); align-items: flex-start; }
.ui-tl__row:last-child { border-bottom: 0; padding-bottom: 0; }
.ui-tl__row:first-child { padding-top: 0; }
.ui-tl__time { flex: none; width: 74px; font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--a-muted); padding-top: 2px; }
.ui-tl__bar { flex: none; width: 4px; border-radius: 999px; background: var(--a-line); align-self: stretch; min-height: 34px; }
.ui-tl__what { min-width: 0; flex: 1; }
.ui-tl__t { margin: 0 0 2px; font-size: .91rem; font-weight: 700; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ui-tl__d { margin: 0; font-size: .82rem; color: var(--a-muted); overflow-wrap: anywhere; }
.ui-tl__row--job .ui-tl__bar    { background: #2C5FA8; }
.ui-tl__row--hold .ui-tl__bar   { background: var(--a-orange); }
.ui-tl__row--block .ui-tl__bar  { background: #6B5BD1; }
.ui-tl__row--cutoff .ui-tl__bar { background: #B7C4D3; }
.ui-tl__row--cutoff .ui-tl__t   { color: var(--a-muted); font-weight: 600; }

.ui-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; padding: 12px 0 0; margin: 0; list-style: none; font-size: .78rem; color: var(--a-muted); }
.ui-legend li { display: flex; align-items: center; gap: 6px; }
.ui-legend i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.ui-legend .l-job { background: #2C5FA8; }
.ui-legend .l-hold { background: var(--a-orange); }
.ui-legend .l-block { background: #6B5BD1; }
.ui-legend .l-cutoff { background: #B7C4D3; }

/* ---- Quick actions ------------------------------------------------------- */
.ui-quick { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ui-quick a {
  background: var(--a-surface); border: 1px solid var(--a-line); border-radius: var(--a-r);
  box-shadow: var(--a-shadow); padding: 14px 8px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  text-decoration: none; color: var(--a-ink);
  font-size: .77rem; font-weight: 700; text-align: center; line-height: 1.25;
  min-height: 86px;
}
.ui-quick a:hover { border-color: #D3DEEA; box-shadow: var(--a-shadow-lg); }
.ui-quick svg { width: 22px; height: 22px; color: var(--a-navy-soft); }

/* ---- Segmented tabs ------------------------------------------------------ */
.ui-tabs {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px;
  background: #E9EEF4; border-radius: 12px; padding: 3px; margin-bottom: 16px;
}
.ui-tabs a {
  min-height: 40px; display: flex; align-items: center; justify-content: center;
  border-radius: 9px; text-decoration: none;
  font-size: .87rem; font-weight: 700; color: var(--a-body);
}
.ui-tabs a[aria-current="page"] { background: var(--a-navy); color: #fff; box-shadow: 0 1px 3px rgba(15, 42, 74, .2); }
.ui-tabs a:not([aria-current]):hover { background: rgba(255, 255, 255, .6); }

/* ---- Misc ---------------------------------------------------------------- */
.ui-map { width: 100%; height: 64px; border-radius: 10px; display: block; border: 1px solid var(--a-line); }
.a-note { border-left: 3px solid var(--a-line); padding: 4px 0 4px 12px; margin-bottom: 12px; }
.a-note__meta { font-size: .76rem; color: var(--a-muted); margin: 3px 0 0; }
/* Structured "what are we moving" rows; old quotes fall back to plain text. */
.a-items { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.a-items li { display: flex; align-items: baseline; gap: 8px; font-size: .88rem; color: var(--a-ink); min-width: 0; }
.a-items__qty { flex: none; font-weight: 800; color: var(--a-navy); font-variant-numeric: tabular-nums; }
.a-items__cat { font-weight: 600; }
.a-items__subs { color: var(--a-muted); font-size: .82rem; }
.a-items__note { display: block; font-size: .84rem; color: var(--a-muted); }
.a-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.a-photo { background: var(--a-page); border: 1px solid var(--a-line); border-radius: 8px; padding: 8px; font-size: .72rem; color: var(--a-muted); overflow-wrap: anywhere; }
.ui-tzline { font-size: .8rem; color: var(--a-muted); margin: 0 0 14px; }
/* Visible to a screen reader, not to the eye. Lets a repeated "Open" button
   carry the quote number it belongs to without cluttering the card. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.a-center { text-align: center; }
.a-spaced { margin-top: 18px; }
.a-mt { margin-top: 14px; }
.a-sub { color: var(--a-muted); font-size: .9rem; margin: 6px 0 16px; }
.a-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82rem; background: var(--a-page); border: 1px solid var(--a-line); border-radius: 8px; padding: 10px 12px; overflow-wrap: anywhere; display: block; }
.ui-sticky-save { position: sticky; bottom: calc(var(--a-tap) + env(safe-area-inset-bottom, 0px) + 10px); z-index: 10; }

/* ---- Login shell --------------------------------------------------------- */
.a-login { max-width: 420px; margin: 8vh auto; padding: 0 18px 40px; }
/* The brand mark, centred above the heading. `height` is fixed and `width` is
   auto so the ratio is always the artwork's own — the intrinsic attributes on
   the <img> reserve the right box before it loads, so nothing shifts. No
   filter, no shadow, no glow: it is the production logo, shown as drawn. */
.a-login__logo { display: block; text-align: center; margin: 0 0 14px; }
.a-login__logo-img {
  display: inline-block;
  height: 56px; width: auto;
  max-width: 100%;
}
@media (max-width: 380px) { .a-login__logo-img { height: 48px; } }
.a-login__brand { text-align: center; font-weight: 800; font-size: 1.2rem; color: var(--a-navy); margin-bottom: 4px; }
.a-login__brand span { color: var(--a-orange); }
.a-login__sub { text-align: center; color: var(--a-muted); font-size: .85rem; margin: 0 0 22px; }

@media (prefers-reduced-motion: reduce) {
  .btn-a, .ui-btn, .ui-acc__chev { transition: none; }
  .btn-a:active, .ui-btn:active { transform: none; }
}

/* ---- Customer photo gallery ----------------------------------------------
   Images come from the authenticated route, so they are ordinary <img> tags
   with no special handling; the security is entirely server-side. */
.a-gallery { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.a-gallery__cell { min-width: 0; }
.a-gallery__btn {
  display: block; width: 100%; padding: 0; cursor: pointer;
  border: 1px solid var(--a-line); border-radius: 10px; overflow: hidden;
  background: var(--a-page); aspect-ratio: 4 / 3;
}
.a-gallery__btn:focus-visible { outline: 3px solid var(--a-navy); outline-offset: 2px; }
/* contain, not cover: a load photo cropped to a square can hide the very
   thing the owner is trying to judge. */
.a-gallery__img { display: block; width: 100%; height: 100%; object-fit: contain; background: #fff; }
.a-gallery__fallback { display: grid; place-items: center; width: 100%; height: 100%; font-size: .8rem; color: var(--a-muted); }
.a-gallery__meta { display: flex; flex-direction: column; gap: 1px; margin: 6px 2px 0; font-size: .74rem; color: var(--a-muted); }
.a-gallery__meta span:first-child { font-weight: 700; color: var(--a-navy); }
@media (max-width: 480px) {
  .a-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
}

/* ---- Preview ---- */
.a-lightbox {
  position: fixed; inset: 0; z-index: 90;
  display: flex; flex-direction: column;
  background: rgba(10, 20, 34, .94);
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}
.a-lightbox[hidden] { display: none; }
.a-lightbox__bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; color: #fff; }
.a-lightbox__caption { font-size: .85rem; font-weight: 600; min-width: 0; }
.a-lightbox__x { width: 44px; height: 44px; flex: none; border: 0; border-radius: 50%; background: rgba(255,255,255,.14); color: #fff; font-size: 26px; line-height: 1; cursor: pointer; }
.a-lightbox__stage { flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 0 8px; min-height: 0; }

/* ---- The portrait frame -------------------------------------------------
   Customer photos are overwhelmingly shot upright, and the viewer presented
   them in whatever shape the stage happened to be. Combined with rasters that
   were being stored on their side, that is how a portrait photo arrived
   looking like letterboxed landscape.

   The frame is 9:16 and the image only ever CONTAINS inside it, so nothing is
   cropped and nothing is stretched. `is-wide` is added by the script once the
   real dimensions are known: a genuine landscape photo releases the frame and
   is shown landscape, full width. Without the script the frame stays portrait
   and a landscape photo is still shown whole, just smaller — degraded, never
   wrong. */
.a-lightbox__frame {
  display: flex; align-items: center; justify-content: center;
  height: 100%; min-height: 0; min-width: 0;
  aspect-ratio: 9 / 16;
  max-height: 100%; max-width: 100%;
  margin-inline: auto;
}
.a-lightbox__frame.is-wide { aspect-ratio: auto; width: 100%; }

/* contain, always: the whole image in its own proportions, letterboxed when
   the photo and the frame disagree. Never cover, which would crop the very
   thing the owner opened the photo to look at. */
.a-lightbox__img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.a-lightbox__nav { flex: none; width: 48px; height: 48px; border: 0; border-radius: 50%; background: rgba(255,255,255,.14); color: #fff; font-size: 30px; line-height: 1; cursor: pointer; }
.a-lightbox__x:focus-visible, .a-lightbox__nav:focus-visible, .a-lightbox__dl:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.a-lightbox__foot { padding: 12px 14px; text-align: center; }
.a-lightbox__dl { color: #fff; font-size: .85rem; font-weight: 700; text-decoration: underline; }
/* 320px is the narrowest phone still in real use; 390px is an iPhone 14/15.
   At both, the close button, caption, arrows and download link must stay on
   screen alongside the image — so the chrome shrinks and the IMAGE yields,
   which is what flex:1 with min-height:0 on the stage arranges. */
@media (max-height: 720px), (max-width: 400px) {
  .a-lightbox__bar { padding: 8px 10px; }
  .a-lightbox__foot { padding: 8px 10px; }
  .a-lightbox__nav { width: 44px; height: 44px; font-size: 26px; }
  .a-lightbox__stage { padding: 0 4px; gap: 4px; }
}

/* The page behind must not move while the modal is open. overflow:hidden is
   ignored by iOS for touch scrolling, so the fixed position is what actually
   holds it still; overscroll-behavior stops the rubber-band handing the
   gesture back to the document. */
body.a-noscroll { overflow: hidden; overscroll-behavior: none; position: fixed; inset: 0; width: 100%; }

/* The action matching the quote's stored review state. Marked by weight, a
   ring and a filled tint as well as colour, because "which one is current"
   must survive a monochrome screen and a colour-blind reader. */
.ui-acts .btn-a.is-current {
  font-weight: 800;
  box-shadow: inset 0 0 0 2px currentColor;
}
.ui-acts .btn-a.is-current::after {
  content: "";
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; flex: none;
}

/* ---- Quote number ---------------------------------------------------------
   The operational reference is short now, so the meta row can sit on one line
   instead of the old identifier forcing a break mid-string. */
.ui-quote__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.ui-quote__no { white-space: nowrap; color: var(--a-navy); }
.ui-quote__meta span { white-space: nowrap; }

/* The qt_ reference stays available for support, quiet and secondary. It is
   long and unbreakable, so it is allowed to wrap anywhere rather than push
   the card sideways. */
.ui-ref__public {
  margin-top: 2px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .74rem; color: var(--a-muted);
  overflow-wrap: anywhere;
}

/* ---- Quote view filter ----------------------------------------------------
   One native select, same on phone and desktop. Five views will not fit as a
   tab strip at 320px without wrapping or scrolling sideways, and a picker the
   platform draws is correct for keyboard and screen readers without any work
   from us. */
.ui-filter { margin: 0 0 16px; }
.ui-filter__label {
  display: block; margin-bottom: 6px;
  font-size: .78rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; color: var(--a-muted);
}
.ui-filter__row { display: flex; gap: 8px; align-items: stretch; }
.ui-filter__select {
  flex: 1; min-width: 0;
  min-height: var(--a-tap);
  padding: 0 12px;
  border: 1px solid var(--a-line); border-radius: var(--a-r-sm);
  background: var(--a-surface); color: var(--a-ink);
  font: inherit; font-size: 1rem; font-weight: 700;
  appearance: auto;   /* keep the platform's own indicator */
  cursor: pointer;
}
.ui-filter__select:focus-visible { outline: 3px solid var(--a-orange); outline-offset: 2px; }
/* The submit is the no-JavaScript path. With the script running the select
   navigates on change, so this is redundant and hidden rather than removed. */
.ui-filter__go {
  flex: none; min-height: var(--a-tap); padding: 0 16px;
  border: 1px solid var(--a-navy); border-radius: var(--a-r-sm);
  background: var(--a-navy); color: #fff;
  font: inherit; font-size: .9rem; font-weight: 700; cursor: pointer;
}
.ui-filter__go:focus-visible { outline: 3px solid var(--a-orange); outline-offset: 2px; }
.js .ui-filter__go { display: none; }

/* ---- Job offer decision -------------------------------------------------
   The three-state panel and the accept/decline controls.

   .ui-acts is a grid of small square tiles, which is right for four review
   buttons and wrong for one decision that commits a truck. --decide drops to
   a single full-width row so Accept reads as the primary action it is. */
.ui-states dd { display: flex; justify-content: flex-end; }
@media (max-width: 419px) { .ui-states dd { justify-content: flex-start; } }

.ui-acts--decide { grid-template-columns: 1fr; margin-top: 16px; }
@media (min-width: 560px) { .ui-acts--decide { grid-template-columns: 1fr; } }
.ui-acts--decide .btn-a {
  flex-direction: row; gap: 9px; padding: 0 18px;
  min-height: 52px; font-size: .95rem; font-weight: 700;
}
.ui-acts--decide .btn-a svg { width: 20px; height: 20px; }
.ui-acts--decide .btn-a[disabled] { opacity: .5; cursor: not-allowed; }
/* Accept is the primary control, so its icon inherits the button's own colour
   rather than the green used on the small review tiles. */
.ui-acts--decide .ui-acts__ok svg { color: currentColor; }

/* Declining is deliberately two steps: the disclosure is the confirmation.
   A <details> rather than a scripted dialog, so it works with the CSP's ban
   on inline script, with JavaScript off, and with a keyboard. */
.a-confirm { margin-top: 10px; }
.a-confirm > summary {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 52px; font-size: .95rem; font-weight: 700;
  cursor: pointer; list-style: none;
}
.a-confirm > summary::-webkit-details-marker { display: none; }
.a-confirm > summary svg { color: var(--a-bad); width: 20px; height: 20px; }
.a-confirm__body {
  margin-top: 10px; padding: 14px;
  border: 1px solid var(--a-line); border-radius: var(--a-r-sm);
  background: var(--a-bad-wash);
}
.a-confirm__body .a-hint { margin-top: 0; }
.a-confirm[open] > summary { border-color: var(--a-bad); color: var(--a-bad); }

/* ==========================================================================
   PHASE 3 — the driver experience.

   ONE RULE RUNS THROUGH ALL OF THIS: below 900px the portal is a phone app,
   at 900px and up it is a desktop operations screen. They share services,
   routes and status vocabulary; they do not share composition. Every block
   below picks a side rather than trying to be both, because "responsive" is
   how a phone control ends up stretched across a desk and a desk layout ends
   up crushed into a thumb.
   ========================================================================== */

/* ---- Availability chip (DESKTOP ONLY) ------------------------------------
   Lives in the header. Mobile gets the card instead — see .ui-avail — and
   the two are never both on screen. */
.a-avail { display: none; }

@media (min-width: 900px) {
  .a-avail { display: block; flex: none; }
  .a-avail__btn {
    display: inline-flex; align-items: center; gap: 8px;
    min-height: 38px; padding: 0 14px;
    border: 1px solid rgba(255, 255, 255, .28); border-radius: 999px;
    background: rgba(255, 255, 255, .08); color: #fff;
    font: inherit; font-size: .84rem; font-weight: 700; cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
  }
  .a-avail__btn:hover { background: rgba(255, 255, 255, .16); }
  .a-avail__btn:focus-visible { outline: 3px solid var(--a-orange); outline-offset: 2px; }
  .a-avail__dot { width: 9px; height: 9px; border-radius: 50%; background: #94A3B8; flex: none; }
  .a-avail__btn.is-online .a-avail__dot { background: #34D399; }
  .a-avail__btn[disabled] { opacity: .6; cursor: progress; }
}

/* ---- Availability card (MOBILE ONLY) -------------------------------------
   The first thing on the phone dashboard. Sized like a switch you are meant
   to throw, not a badge you are meant to read. */
.ui-avail {
  margin: 0 0 18px; padding: 16px;
  border: 1px solid var(--a-line); border-left: 4px solid #94A3B8;
  border-radius: var(--a-r); background: var(--a-surface);
  box-shadow: var(--a-shadow);
}
.ui-avail.is-online { border-left-color: var(--a-ok); background: var(--a-ok-wash); }
.ui-avail__top { display: flex; gap: 12px; align-items: flex-start; }
.ui-avail__dot {
  width: 12px; height: 12px; border-radius: 50%; flex: none; margin-top: 5px;
  background: #94A3B8; box-shadow: 0 0 0 4px rgba(148, 163, 184, .18);
}
.ui-avail.is-online .ui-avail__dot {
  background: var(--a-ok); box-shadow: 0 0 0 4px rgba(21, 128, 61, .16);
}
.ui-avail__h { margin: 0; font-size: 1.05rem; font-weight: 800; color: var(--a-ink); }
.ui-avail__sub { margin: 4px 0 0; font-size: .86rem; line-height: 1.45; color: var(--a-body); }
.ui-avail__btn {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; min-height: 52px; margin-top: 14px; padding: 0 18px;
  border-radius: var(--a-r-sm); border: 1px solid transparent;
  font: inherit; font-size: .98rem; font-weight: 800; cursor: pointer;
}
.ui-avail__btn--on { background: var(--a-navy); color: #fff; }
.ui-avail__btn--off { background: #fff; color: var(--a-body); border-color: var(--a-line); }
.ui-avail__btn:focus-visible { outline: 3px solid var(--a-orange); outline-offset: 2px; }
.ui-avail__btn[disabled] { opacity: .65; cursor: progress; }
/* Loading state. A spinner only — the label changes too, so this is never the
   sole signal that something is happening. */
.ui-avail__spin {
  width: 16px; height: 16px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: a-spin .7s linear infinite;
}
@keyframes a-spin { to { transform: rotate(360deg); } }

@media (min-width: 900px) { .ui-avail { display: none; } }

/* ---- Incoming offer alert ------------------------------------------------
   MOBILE: a near-full-screen sheet. The panel is a column — head, scrollable
   body, pinned actions — so Accept and Decline are reachable without
   scrolling at any height, in landscape, and at large text sizes. That is the
   single most important property of this component: a decision control the
   owner has to hunt for is a decision that does not get made.
   ------------------------------------------------------------------------- */
.oa { position: fixed; inset: 0; z-index: 100; display: flex; }
.oa[hidden] { display: none; }
.oa__scrim { position: absolute; inset: 0; background: rgba(10, 31, 58, .55); }

.oa__panel {
  position: relative;
  display: flex; flex-direction: column;
  width: 100%; margin-top: auto;
  max-height: calc(100dvh - 24px);
  background: var(--a-surface);
  border-radius: var(--a-r-lg) var(--a-r-lg) 0 0;
  box-shadow: var(--a-shadow-lg);
  animation: oa-rise .22s ease-out;
}
@keyframes oa-rise { from { transform: translateY(14px); opacity: .6; } }

.oa__head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px 10px; border-bottom: 1px solid var(--a-line-2);
}
.oa__heading { flex: 1; min-width: 0; }
.oa__eyebrow {
  margin: 0; font-size: .72rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--a-orange);
}
.oa__title { margin: 1px 0 0; font-size: 1.12rem; font-weight: 800; color: var(--a-ink); }
.oa__close {
  flex: none; width: 40px; height: 40px; border: 0; border-radius: 50%;
  background: var(--a-line-2); color: var(--a-body); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.oa__close:focus-visible { outline: 3px solid var(--a-orange); outline-offset: 2px; }

/* Countdown. The ring is decoration; the number is the information. */
.oa__timer { position: relative; flex: none; width: 44px; height: 44px; }
.oa__ring { width: 44px; height: 44px; transform: rotate(-90deg); }
.oa__ring-track, .oa__ring-fill { fill: none; stroke-width: 3.5; }
.oa__ring-track { stroke: var(--a-line); }
.oa__ring-fill {
  stroke: var(--a-orange); stroke-linecap: round;
  stroke-dasharray: 119.4; stroke-dashoffset: 0;
  transition: stroke-dashoffset .95s linear;
}
.oa__count {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: .88rem; font-weight: 800; color: var(--a-ink); font-variant-numeric: tabular-nums;
}

.oa__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 16px 6px; }
.oa__price {
  margin: 0 0 12px; font-size: 2.1rem; line-height: 1;
  font-weight: 800; letter-spacing: -.02em; color: var(--a-navy);
}
.oa__facts { margin: 0; display: grid; gap: 0; }
.oa__facts > div {
  display: flex; justify-content: space-between; gap: 14px;
  padding: 9px 0; border-bottom: 1px solid var(--a-line-2);
}
.oa__facts dt { color: var(--a-muted); font-size: .85rem; flex: none; }
.oa__facts dd {
  margin: 0; font-weight: 700; font-size: .9rem; text-align: right;
  min-width: 0; overflow-wrap: anywhere;
}
.oa__items { margin: 12px 0 0; font-size: .89rem; line-height: 1.45; color: var(--a-body); }
.oa__photos, .oa__slot { margin: 6px 0 0; font-size: .84rem; color: var(--a-muted); }
.oa__status { margin: 12px 0 0; font-size: .89rem; font-weight: 700; color: var(--a-body); min-height: 1.2em; }
.oa__status.is-bad { color: var(--a-bad); }
.oa__status.is-ok { color: var(--a-ok); }

.oa__reasons { margin: 14px 0 0; }
.oa__reasons-h { margin: 0 0 8px; font-weight: 800; font-size: .95rem; color: var(--a-ink); }
.oa__reasons-list { display: grid; gap: 2px; }
.oa__reason {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--a-tap); padding: 4px 8px;
  border-radius: var(--a-r-sm); font-size: .92rem; cursor: pointer;
}
.oa__reason:hover { background: var(--a-line-2); }
.oa__reason input { width: 20px; height: 20px; flex: none; accent-color: var(--a-navy); }
.oa__reason:focus-within { outline: 3px solid var(--a-orange); outline-offset: -2px; }
.oa__reasons-note { margin: 10px 0 0; font-size: .8rem; color: var(--a-muted); line-height: 1.45; }

/* Pinned actions. Padded past the home indicator AND the bottom nav, so the
   primary control is never under a system bar or the app chrome. */
.oa__acts {
  flex: none; display: grid; gap: 9px;
  padding: 12px 16px calc(14px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--a-line); background: var(--a-surface);
}
/* `display: grid` on a class beats the user agent's `[hidden] { display: none }`,
   so without this the decline-confirmation bar sits on screen alongside the
   main actions from the moment the sheet opens — two competing sets of buttons
   for one decision. Any element here that toggles with `hidden` needs it. */
.oa__acts[hidden], .oa__reasons[hidden], .oa__photos[hidden], .oa__slot[hidden] { display: none; }
.oa__btn {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; min-height: 54px; padding: 0 18px;
  border-radius: var(--a-r-sm); border: 1px solid transparent;
  font: inherit; font-size: 1rem; font-weight: 800; cursor: pointer;
}
.oa__btn svg { width: 20px; height: 20px; }
.oa__btn--accept { background: var(--a-orange); color: #fff; }
.oa__btn--accept:hover { background: var(--a-orange-dk); }
.oa__btn--decline { background: #fff; color: var(--a-bad); border-color: var(--a-line); }
.oa__btn--ghost { background: #fff; color: var(--a-body); border-color: var(--a-line); }
.oa__btn:focus-visible { outline: 3px solid var(--a-navy); outline-offset: 2px; }
.oa__btn[disabled] { opacity: .6; cursor: progress; }
.oa__link {
  display: flex; align-items: center; justify-content: center;
  text-align: center; font-size: .88rem; font-weight: 700;
  color: var(--a-navy-soft); text-decoration: none; padding: 8px; min-height: 40px;
}
.oa__link:hover { text-decoration: underline; }

/* Landscape on a phone is short. Trim the vertical spend so the pinned
   actions and at least some facts stay on screen together. */
@media (max-width: 899px) and (orientation: landscape) {
  .oa__panel { max-height: 100dvh; }
  .oa__price { font-size: 1.5rem; margin-bottom: 8px; }
  .oa__btn { min-height: 46px; }
  .oa__acts { grid-template-columns: 1fr 1fr; }
  .oa__link { grid-column: 1 / -1; }
}

/* DESKTOP: a contained dialog over a still-visible portal. The operator is
   mid-task; taking the whole viewport to ask one question would throw away
   the context they are working in. */
@media (min-width: 900px) {
  .oa { align-items: center; justify-content: center; padding: 24px; }
  .oa__scrim { background: rgba(10, 31, 58, .38); }
  .oa__panel {
    width: min(560px, 100%); margin: 0;
    max-height: min(76vh, 720px);
    border-radius: var(--a-r-lg);
    animation: oa-pop .18s ease-out;
  }
  @keyframes oa-pop { from { transform: scale(.985); opacity: .7; } }
  .oa__price { font-size: 1.9rem; }
  .oa__acts {
    grid-template-columns: 1fr 1fr auto;
    align-items: center; padding: 14px 20px;
    border-radius: 0 0 var(--a-r-lg) var(--a-r-lg);
  }
  .oa__btn { min-height: 46px; font-size: .95rem; }
  .oa__link { padding: 0 12px; }
  .oa__acts--confirm { grid-template-columns: 1fr 1fr; }
  .oa__head, .oa__body { padding-left: 20px; padding-right: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .oa__panel { animation: none; }
  .oa__ring-fill { transition: none; }
  .ui-avail__spin { animation-duration: 2s; }
}

/* ---- Notification rows (shared) ------------------------------------------ */
.a-notif__list { list-style: none; margin: 0; padding: 0; }
.a-notif__row {
  display: flex; align-items: stretch; gap: 4px;
  border-bottom: 1px solid var(--a-line-2);
}
.a-notif__row:last-child { border-bottom: 0; }
.a-notif__row.is-unread { background: var(--a-blue-wash); }
.a-notif__main {
  display: flex; align-items: flex-start; gap: 11px;
  flex: 1; min-width: 0; padding: 13px 12px;
  text-decoration: none; color: inherit; min-height: var(--a-tap);
}
a.a-notif__main:hover { background: rgba(15, 42, 74, .04); }
a.a-notif__main:focus-visible { outline: 3px solid var(--a-orange); outline-offset: -3px; }
.a-notif__icon { flex: none; color: var(--a-navy-soft); margin-top: 1px; }
.a-notif__row--warning .a-notif__icon { color: var(--a-warn); }
.a-notif__row--critical .a-notif__icon { color: var(--a-bad); }
.a-notif__text { display: grid; gap: 2px; min-width: 0; }
.a-notif__kind {
  font-size: .72rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--a-muted);
}
.a-notif__title { font-size: .92rem; font-weight: 700; color: var(--a-ink); overflow-wrap: anywhere; }
.a-notif__meta { display: flex; gap: 10px; font-size: .78rem; color: var(--a-muted); }
.a-notif__unread {
  flex: none; align-self: center; width: 9px; height: 9px;
  border-radius: 50%; background: var(--a-orange);
}
.a-notif__read { display: flex; }
.a-notif__read-btn {
  height: 100%; min-width: var(--a-tap); border: 0; background: transparent;
  color: var(--a-muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.a-notif__read-btn:hover { color: var(--a-ok); background: rgba(21, 128, 61, .08); }
.a-notif__read-btn:focus-visible { outline: 3px solid var(--a-orange); outline-offset: -3px; }
.a-notif {
  border: 1px solid var(--a-line); border-radius: var(--a-r);
  background: var(--a-surface); overflow: hidden; box-shadow: var(--a-shadow);
}
.a-notif__empty { padding: 8px; }

/* ---- Notification drawer (DESKTOP ONLY) ---------------------------------- */
.a-drawer { display: none; }
@media (min-width: 900px) {
  .a-drawer { position: fixed; inset: 0; z-index: 90; display: block; }
  .a-drawer[hidden] { display: none; }
  .a-drawer__scrim { position: absolute; inset: 0; background: rgba(10, 31, 58, .3); }
  .a-drawer__panel {
    position: absolute; top: 0; right: 0; bottom: 0; width: min(400px, 92vw);
    background: var(--a-surface); box-shadow: var(--a-shadow-lg);
    display: flex; flex-direction: column;
    animation: a-drawer-in .18s ease-out;
  }
  @keyframes a-drawer-in { from { transform: translateX(16px); opacity: .7; } }
  .a-drawer__head {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 16px; border-bottom: 1px solid var(--a-line);
  }
  .a-drawer__title { margin: 0; flex: 1; font-size: 1rem; font-weight: 800; color: var(--a-ink); }
  .a-drawer__all {
    border: 0; background: transparent; font: inherit; font-size: .82rem;
    font-weight: 700; color: var(--a-navy-soft); cursor: pointer; padding: 6px 8px;
  }
  .a-drawer__all:hover { text-decoration: underline; }
  .a-drawer__x {
    flex: none; width: 34px; height: 34px; border: 0; border-radius: 50%;
    background: var(--a-line-2); color: var(--a-body); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
  }
  .a-drawer__body { flex: 1; overflow-y: auto; }
  .a-drawer__foot {
    display: block; padding: 13px 16px; text-align: center;
    border-top: 1px solid var(--a-line); font-size: .86rem; font-weight: 700;
    color: var(--a-navy-soft); text-decoration: none;
  }
  .a-drawer__foot:hover { text-decoration: underline; }
}

/* ---- Desktop portal shell ------------------------------------------------
   Below 900px nothing here applies and the portal is exactly the phone app it
   has always been. */
.a-topnav { display: none; }

@media (min-width: 900px) {
  /* A fixed bottom bar is a phone control. Gone. */
  .a-nav { display: none; }

  .a-topnav { display: flex; align-items: center; gap: 4px; flex: 1; margin-left: 18px; }
  .a-topnav a {
    padding: 8px 14px; border-radius: 999px;
    font-size: .88rem; font-weight: 700; text-decoration: none;
    color: rgba(255, 255, 255, .74);
  }
  .a-topnav a:hover { color: #fff; background: rgba(255, 255, 255, .1); }
  .a-topnav a[aria-current="page"] { color: #fff; background: rgba(255, 255, 255, .16); }
  .a-topnav a:focus-visible { outline: 3px solid var(--a-orange); outline-offset: 2px; }

  /* The bottom bar is gone, so the page no longer has to end above it. */
  .a-wrap { max-width: 1180px; padding: 26px 28px 48px; }
  .a-bar { padding: 12px 24px; }
  .a-bar__spacer { display: none; }

  /* Multi-column operations layout: the work queue beside the day, rather
     than a single column of cards scrolled forever. */
  .ui-cols {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 28px; align-items: start;
  }
}

/* ---- Job execution ------------------------------------------------------
   The screen a driver holds while standing beside the truck. One action
   dominates; everything else is available but out of the way. */
.jb-now {
  margin: 0 0 16px; padding: 18px 16px;
  border: 1px solid var(--a-line); border-left: 4px solid var(--a-orange);
  border-radius: var(--a-r); background: var(--a-surface); box-shadow: var(--a-shadow);
}
.jb-now.is-done { border-left-color: var(--a-ok); background: var(--a-ok-wash); }
.jb-now__eyebrow {
  margin: 0; font-size: .72rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--a-muted);
}
.jb-now__h { margin: 3px 0 0; font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; color: var(--a-ink); }
.jb-now__facts { margin: 14px 0 0; }
.jb-now__facts > div {
  display: flex; justify-content: space-between; gap: 14px;
  padding: 8px 0; border-bottom: 1px solid var(--a-line-2);
}
.jb-now__facts > div:last-child { border-bottom: 0; }
.jb-now__facts dt { color: var(--a-muted); font-size: .85rem; }
.jb-now__facts dd { margin: 0; font-weight: 700; font-size: .9rem; text-align: right; }
.jb-now .ui-route { margin-top: 14px; }

.jb-acts { display: grid; gap: 9px; margin-top: 12px; }
.jb-acts .btn-a { justify-content: flex-start; }

/* The primary action. Sticky above the bottom bar on a phone so it is never
   scrolled past, and clear of the home indicator. */
.jb-do { position: sticky; bottom: calc(var(--a-tap) + env(safe-area-inset-bottom, 0px) + 10px); z-index: 20; margin-top: 18px; }
.jb-do__btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 58px; font-size: 1.05rem; font-weight: 800;
  box-shadow: var(--a-shadow-lg); cursor: pointer; list-style: none;
}
.jb-do__btn::-webkit-details-marker { display: none; }
.jb-do__btn[disabled] { opacity: .6; cursor: progress; }
.jb-do__spin {
  width: 18px; height: 18px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: a-spin .7s linear infinite;
}
.jb-confirm__body {
  margin-top: 10px; padding: 14px; display: grid; gap: 9px;
  border: 1px solid var(--a-line); border-radius: var(--a-r-sm);
  background: var(--a-surface); box-shadow: var(--a-shadow-lg);
}
.jb-confirm__q { margin: 0 0 4px; font-weight: 700; font-size: .95rem; color: var(--a-ink); }

/* The approve confirmation on the offer screen reuses .a-confirm but is a
   GO action, not a stop one, so it is not tinted red. */
.a-confirm--go > summary svg { color: currentColor; }
.a-confirm__body--go { background: var(--a-surface); }
.a-confirm--go > summary.is-off { opacity: .55; }

/* The horizontal tracker is a desktop shape. */
.jb-track { display: none; }

@media (min-width: 900px) {
  /* On a desktop the action does not need pinning — there is room for it in
     the flow, and a sticky bar on a wide screen is a phone control. */
  .jb-do { position: static; max-width: 420px; }

  .jb-track {
    display: block; margin: 0 0 20px; padding: 24px 26px 20px;
    border: 1px solid var(--a-line); border-radius: var(--a-r);
    background: var(--a-surface); box-shadow: var(--a-shadow);
  }
  .jb-track__list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(8, 1fr); }
  .jb-track__step { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 4px; }
  .jb-track__line { position: absolute; top: 17px; right: 50%; left: -50%; height: 2px; background: var(--a-line); }
  .jb-track__step.is-done .jb-track__line,
  .jb-track__step.is-current .jb-track__line { background: var(--a-ok); }
  .jb-track__marker {
    position: relative; z-index: 1; width: 36px; height: 36px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--a-line-2); border: 2px solid var(--a-line-2);
    color: var(--a-muted); font-weight: 800; font-size: .82rem;
  }
  .jb-track__glyph { width: 18px; height: 18px; }
  .jb-track__step.is-done .jb-track__marker { background: var(--a-ok); border-color: var(--a-ok); color: #fff; }
  .jb-track__step.is-current .jb-track__marker {
    background: var(--a-orange); border-color: var(--a-orange); color: #fff;
    box-shadow: 0 0 0 4px rgba(242, 107, 33, .18);
  }
  .jb-track__t { margin-top: 9px; font-size: .78rem; font-weight: 700; line-height: 1.3; color: var(--a-muted); overflow-wrap: anywhere; }
  .jb-track__step.is-done .jb-track__t { color: var(--a-body); }
  .jb-track__step.is-current .jb-track__t { color: var(--a-ink); font-weight: 800; }
  .jb-track__at { margin-top: 3px; font-size: .71rem; color: var(--a-muted); font-variant-numeric: tabular-nums; }

  .jb-acts { grid-template-columns: repeat(3, 1fr); }
}

/* ---- Location sharing panel ----------------------------------------------
   MOBILE: the driver's own control. Buttons big enough to hit on a bumpy road
   without looking carefully, and the state readable at a glance.
   DESKTOP: read-only. The controls are removed entirely and a line of text
   explains that the phone is the source — a laptop offering to share "the
   truck's" location would be reporting the office. */
.jb-loc {
  background: #fff;
  border: 1px solid var(--a-line);
  border-radius: 14px;
  padding: 16px 18px;
  margin: 0 0 16px;
}

.jb-loc__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.jb-loc__h {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--a-navy);
}

/* The dot is reinforcement, never the message: every state is spelled out in
   words directly beneath it, so this carries no information of its own and a
   colour-blind reader loses nothing. */
.jb-loc__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: none;
  background: var(--a-muted);
}
.jb-loc__dot--active,
.jb-loc__dot--reporting     { background: var(--a-ok); }
.jb-loc__dot--unavailable,
.jb-loc__dot--catching_up,
.jb-loc__dot--interrupted   { background: #B45309; }
.jb-loc__dot--denied        { background: var(--a-bad); }
.jb-loc__dot--stopped,
.jb-loc__dot--closed,
.jb-loc__dot--idle,
.jb-loc__dot--needed,
.jb-loc__dot--not_started   { background: var(--a-muted); }

.jb-loc__label {
  margin: 10px 0 2px;
  font-size: 15px;
  font-weight: 600;
  color: var(--a-ink);
}

.jb-loc__detail {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--a-muted);
}

.jb-loc__meta {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--a-muted);
  font-variant-numeric: tabular-nums;
}

.jb-loc__acts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px 0 0;
}

/* 48px: a target that can be hit standing in someone's hallway holding a
   sofa cushion, which is the actual usage. */
.jb-loc__btn {
  min-height: 48px;
  flex: 1 1 auto;
}

/* `hidden` must win over the flex display above — the same specificity trap
   that has bitten this project before. */
.jb-loc__acts [hidden],
.jb-loc__why[hidden] { display: none; }

.jb-loc__why {
  margin: 12px 0 0;
  padding: 12px 14px;
  background: var(--a-wash);
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--a-muted);
}

/* MOBILE hides the desktop explanation; DESKTOP hides the controls. */
.jb-loc__desk { display: none; }

@media (min-width: 900px) {
  .jb-loc__acts,
  .jb-loc__why { display: none; }

  .jb-loc__desk {
    display: block;
    margin: 12px 0 0;
    padding: 12px 14px;
    background: var(--a-wash);
    border-radius: 10px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--a-muted);
  }
}

/* ---- Push notification preferences ---------------------------------------
   Deliberately plain. A permission request dressed up as an inducement is a
   dark pattern; this states what each notification is and lets the answer be
   no, with no second asking. */
.np {
  background: #fff;
  border: 1px solid var(--a-line);
  border-radius: 14px;
  padding: 16px 18px;
  margin: 16px 0 0;
}

.np__h {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 700;
  color: var(--a-navy);
}

.np__state {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--a-muted);
}

.np__list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: grid;
  gap: 2px;
}

.np__row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--a-line);
}
.np__row:last-child { border-bottom: 0; }

.np__row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--a-navy);
}

.np__row label {
  font-size: 14px;
  color: var(--a-ink);
  cursor: pointer;
  /* The whole row is the target, not just the box. */
  flex: 1;
  min-height: 24px;
  display: flex;
  align-items: center;
}

.np__acts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.np__acts [hidden] { display: none; }

.np__btn { min-height: 44px; }

/* ---- Scroll clearance for the fixed bottom navigation --------------------
   Anything the BROWSER scrolls to — a focused control, an anchor jump, an
   element scrolled into view by script — is positioned without any knowledge
   of a fixed overlay. Without this, tabbing to a control near the bottom of a
   long page parks it underneath the navigation, where it is visible enough to
   aim at and impossible to press: the tap lands on the nav and the driver is
   taken somewhere else entirely.

   Caught by a controlled mobile browser doing exactly that to the location
   retry control. scroll-padding is the one-line answer and it fixes keyboard
   focus at the same time. */
html {
  scroll-padding-bottom: calc(var(--a-tap) + env(safe-area-inset-bottom, 0px) + 16px);
}

/* Belt and braces for the controls it matters most for: a driver reaching for
   these is usually holding something in the other hand. */
.jb-loc__btn,
.jb-do__btn,
.np__btn {
  scroll-margin-bottom: calc(var(--a-tap) + env(safe-area-inset-bottom, 0px) + 16px);
}

@media (min-width: 900px) {
  /* No fixed bottom navigation on desktop, so no clearance needed. */
  html { scroll-padding-bottom: 0; }
}

/* ---- Install instruction sheet (iOS) -------------------------------------
   Only ever opened by a deliberate tap on the install control, and only where
   the platform cannot install programmatically. */
.ui-sheet {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(9, 22, 36, .55);
  padding: 0 0 env(safe-area-inset-bottom, 0px);
}
.ui-sheet[hidden] { display: none; }

.ui-sheet__panel {
  width: 100%; max-width: 480px;
  background: #fff;
  border-radius: 18px 18px 0 0;
  padding: 22px 20px calc(22px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 40px rgba(9, 22, 36, .25);
}
.ui-sheet__h { margin: 0 0 6px; font-size: 18px; font-weight: 800; color: var(--a-navy); }
.ui-sheet__p { margin: 0 0 14px; font-size: 14px; line-height: 1.55; color: var(--a-muted); }
.ui-sheet__steps {
  margin: 0 0 18px; padding: 0 0 0 20px;
  font-size: 15px; line-height: 1.9; color: var(--a-ink);
}
.ui-sheet__steps strong { font-weight: 700; }

@media (min-width: 900px) {
  /* Centred on a desktop rather than pinned to the bottom edge. */
  .ui-sheet { align-items: center; }
  .ui-sheet__panel { border-radius: 18px; }
}

/* The install control matches the bell and avatar it sits beside; a-bar__btn
   already carries the 44px target, focus ring and hover treatment. */
.a-bar__btn[data-install-btn][hidden] { display: none; }

/* ---- Header control touch targets ----------------------------------------
   The circles are 38px because three of them plus the brand have to fit on a
   360px phone, and 44px each would overflow. But 38px is under the minimum
   target size, and these are pressed one-handed in a moving vehicle.

   So the VISUAL stays 38 and the TARGET becomes 44, via a transparent inset
   overlay. Nothing moves, nothing overflows, and the thumb gets the area the
   guidance asks for. Applied to all three so the bell and avatar gain it too
   — they had the same problem before the install button existed. */
.a-bar__btn::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 44px; height: 44px;
  transform: translate(-50%, -50%);
  /* Purely a hit area: invisible, and never on top of the icon it serves. */
  border-radius: 50%;
}

/* The line that spells out a contradiction the badge cannot. */
.ui-quote__state {
  margin: 6px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--a-muted);
}

/* Three separate truths on the quote detail: review, decision, booking. A
   single badge cannot hold all three, and collapsing them is what let an
   approved-but-unbooked record read as "Approved". */
.ui-facts { margin: 0; display: grid; gap: 10px; }
.ui-facts > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding-bottom: 10px; border-bottom: 1px solid var(--a-line-2);
}
.ui-facts > div:last-child { border-bottom: 0; padding-bottom: 0; }
.ui-facts dt { font-size: 13px; color: var(--a-muted); flex: none; }
.ui-facts dd { margin: 0; font-size: 14px; font-weight: 600; color: var(--a-ink); text-align: right; }

/* ---------------------------------------------------------------------------
   It will not all fit.

   Secondary to the stage action on purpose. The driver reaches for "Items
   loaded" nine times out of ten, and this sitting beside it at equal weight is
   how the wrong one gets pressed with a sofa in both hands.
   --------------------------------------------------------------------------- */
.jb-now__trip {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--a-muted);
}
.jb-trip { margin-top: 12px; }
.jb-trip__add { margin-top: 12px; }
.jb-trip__figures {
  margin: 14px 0;
  display: grid;
  gap: 8px;
}
.jb-trip__figures > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.jb-trip__figures dt { color: var(--a-muted); font-size: 14px; }
.jb-trip__figures dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 600; }
.jb-trip__warn {
  margin: 12px 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--a-warn-wash, #fff6e5);
  font-size: 14px;
  line-height: 1.5;
}
.jb-trip__note {
  margin: 12px 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--a-muted);
}
