/* ---------------------------------------------------------------------------
   THE BACK OFFICE IS A WAREHOUSE TERMINAL.

   Neil, 13 September: "one header, one exception line, then tables." And on 14
   September, for the rest of it: every ops page inherits this, starting with
   the bar.

   This is the ops visual language, and it is deliberately NOT the public
   site's. The marketing pages are a line drawing on cream paper with hard
   shadows and display type; that is right for somebody deciding whether to
   hand over a card and wrong for somebody reading a 47-line change log at a
   desk or a bag table on a doorstep. Ops gets hairlines, a gray header row,
   tabular numbers, and colour only where it means something.

   ONE FILE OWNS THIS LOOK. Neil's instruction: do not make a second one. So
   the page chrome below and the order console further down live together, and
   anything added for another screen belongs here too.

   IT IS LOADED BY adminPage() FOR EVERY /ops PAGE, after lyndry.css, so
   anything it names wins. That is what lets a page nobody has rewritten yet
   still wear the right bar and the right ground. Fingerprinted under
   /css/<hash>/ like every other file in this directory, so a change here
   reaches every phone on the next deploy.

   IT IS NEVER LOADED ON A PUBLIC PAGE. The selectors below name `body`, which
   would repaint the marketing site if this sheet ever reached it. It is linked
   in one place and that place renders ops only.
   --------------------------------------------------------------------------- */

/* --- the page itself ------------------------------------------------------

   THE GROUND IS GREY AND THE TYPE IS SMALL, which is the whole difference. A
   marketing page is read once at arm's length; this is read all day, and the
   thing that matters is how much of a table fits above the fold.

   System fonts, not the brand faces. Grandstander and Outfit are the public
   voice, they cost a network round trip, and nobody reading a bag list needs a
   display face. The ops bar drops them; a page that has not been rewritten yet
   still asks for them in its own markup, and will stop as it is rewritten. */
body {
  background: var(--c-bg, #f3f4f6);
  color: var(--c-ink, #111827);
  font: 13px/1.45 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Tokens at the page level, so the bar and every later screen read the same
   ones the console already uses. The console re-declares them on itself and
   that is deliberate: it stays self-contained if this block ever moves. */
body {
  --c-bg: #f3f4f6;
  --c-ink: #111827;
  --c-muted: #6b7280;
  --c-line: #d1d5db;
  --c-line-strong: #9ca3af;
  --c-head: #e5e7eb;
  --c-row: #ffffff;
  --c-row-alt: #f9fafb;
  --c-green: #166534;
  --c-green-bg: #dcfce7;
  --c-amber: #92400e;
  --c-amber-bg: #fef3c7;
  --c-red: #991b1b;
  --c-red-bg: #fee2e2;
  --c-blue: #1e40af;
  --c-link: #1d4ed8;
  --c-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* A MARKETING SURFACE HAS NO BUSINESS ON AN OPS PAGE.

   .hero paints a full-width band of Suds green and is the public site's
   opening gesture. The ops sign-in borrowed it, so the first screen anybody
   sees at a desk was a green field with a bubble card floating on it.

   There is exactly one .hero under /ops and it is that sign-in. Neutralising
   it here rather than editing the page keeps this pass to the shell: no body
   markup moves, and if another screen ever borrows the same class it inherits
   the correction for free. */
.hero {
  background: none;
  padding-top: 24px;
  padding-bottom: 0;
}

/* --- the bar --------------------------------------------------------------

   40px of dark, and nothing else. It was the public site's header: cream, a
   3px ink underline, a hard shadow and a 44px logo, which is a lot of a phone
   spent on chrome before the driver sees a stop.

   THE MARKUP IS UNTOUCHED. This is the same header, the same four <details>
   menus and the same Sign out button that were already there - restyled, not
   rebuilt. That is what makes this safe to ship before any page body is
   rewritten: nothing moved, so nothing can have moved wrongly. */
.site-header {
  background: #111827;
  border: 0;
  box-shadow: none;
  position: sticky;
  top: 0;
  z-index: 40;
}

.site-header-bar.ops-bar {
  min-height: 40px;
  height: auto;
  padding: 0 12px;
  gap: 14px;
  max-width: none;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

/* THE MARK IS A WORD HERE, NOT THE ARTWORK.
   CLAUDE.md is explicit that `compact` at 38px is the smallest the wordmark
   stays readable at, and a 40px bar cannot hold 38px of logo. Squeezing it to
   22px turned LYNDRY into a smear, which is the exact failure that rule exists
   to prevent - so the bar wears a text wordmark instead, as the mockups do.
   The artwork is untouched and still the mark everywhere else. */
.ops-bar .ops-mark {
  color: #fff;
  font: 700 13px/1 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0.06em;
  text-decoration: none;
  white-space: nowrap;
  flex: none;
}
.ops-bar .ops-mark:hover { text-decoration: none; color: #fff; }

.ops-bar .site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 1 1 auto;
  flex-wrap: wrap;
  border: 0;
  background: none;
  box-shadow: none;
  padding: 0;
}

/* A menu title, and the one link a single-item group collapses to. */
.ops-bar .ops-menu > summary,
.ops-bar .ops-menu-solo {
  color: #d1d5db;
  background: none;
  border: 0;
  border-radius: 3px;
  box-shadow: none;
  padding: 5px 9px;
  font: 600 13px/1 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  list-style: none;
  text-decoration: none;
  /* INLINE-FLEX, NOT INLINE-BLOCK. The caret is a ::after child of this
     element, so a display that does not lay its children out in a row drops
     the triangle onto its own line above the word. It did. */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

/* Smaller than the public site's, to match 13px type. */
.ops-bar .ops-menu > summary::after {
  border-left-width: 3px;
  border-right-width: 3px;
  border-top-width: 4px;
}

.ops-bar .ops-menu > summary::-webkit-details-marker { display: none; }
.ops-bar .ops-menu > summary::marker { content: ''; }

.ops-bar .ops-menu > summary:hover,
.ops-bar .ops-menu-solo:hover { background: #1f2937; color: #fff; text-decoration: none; }

/* WHERE YOU ARE, said quietly. A highlighted word rather than an opened panel
   covering the page you just asked for - the rule the nav already followed. */
.ops-bar .ops-menu[data-here="1"] > summary,
.ops-bar .ops-menu-solo[aria-current="page"] { color: #fff; background: #1f2937; }

.ops-bar .ops-menu[open] > summary { background: #1f2937; color: #fff; }

/* The panel is a plain white card on a hairline, not a floating marketing
   surface. It opens with no script, exactly as it did. */
.ops-bar .ops-menu-panel {
  position: absolute;
  z-index: 50;
  margin-top: 6px;
  min-width: 190px;
  background: #fff;
  color: var(--c-ink);
  border: 1px solid var(--c-line-strong);
  border-radius: 3px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
  padding: 4px;
  display: flex;
  flex-direction: column;
}

.ops-bar .ops-menu-panel a {
  color: var(--c-ink);
  padding: 6px 10px;
  border-radius: 2px;
  font-size: 13px;
  text-decoration: none;
  white-space: nowrap;
}

.ops-bar .ops-menu-panel a:hover { background: var(--c-row-alt); text-decoration: none; }
.ops-bar .ops-menu-panel a[aria-current="page"] { font-weight: 700; }

/* Who is signed in, and the way out. */
.ops-bar .eyebrow {
  color: #9ca3af !important;
  font: 500 12px/1 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0;
  text-transform: none;
}

.ops-bar .btn,
.ops-bar .btn-outline.btn-sm {
  background: transparent;
  color: #d1d5db;
  border: 1px solid #374151;
  border-radius: 3px;
  box-shadow: none;
  height: auto;
  min-height: 0;
  padding: 4px 9px;
  font: 500 12px/1.2 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0;
  text-transform: none;
  transform: none;
}

.ops-bar .btn:hover { background: #1f2937; color: #fff; transform: none; box-shadow: none; }

/* ON A PHONE THE BAR EARNS ITS 40px AND NOT A PIXEL MORE.

   At 375px the mark, four menus, a name, a role and a Sign out button wrapped
   onto three rows - 88px of chrome before the first stop. Neil runs this as a
   home-screen app, so that is a third of the screen spent saying who he is.

   The name goes first because it is the only thing here nobody needs: you know
   who you are signed in as, and the one case where it matters, being signed in
   as the wrong person, is answered by the Sign out button beside it. */
@media (max-width: 719px) {
  .ops-bar .eyebrow { display: none; }
  .site-header-bar.ops-bar { padding: 0 10px; gap: 10px; }
  /* TWO ROWS, NOT THREE. The mark and the way out share the top line; the
     menus take the one below. Left to wrap on their own the three groups
     landed on three separate rows, which is 80px of a 812px screen. */
  .ops-bar .site-nav { gap: 0; order: 3; flex-basis: 100%; }
  .site-header-bar.ops-bar > form { margin-left: auto !important; }
  .ops-bar .ops-menu > summary,
  .ops-bar .ops-menu-solo { padding: 5px 7px; }
}

/* The content starts right under the bar. 36px of air above a table is a third
   of a phone screen. The wrapper keeps its own padding for a bare page, which
   is the driver's route and is deliberately still roomy. */
body > main.container {
  max-width: none;
  padding-top: 14px !important;
  padding-left: 12px;
  padding-right: 12px;
  padding-bottom: 48px !important;
}

/* AND THE FOOTER HAS TO LINE UP WITH IT, WHICH IT DID NOT.

   Neil, 26 September, on the laundromat portal's sign-in page: the Processing
   Instructions link and the phone number "should be aligned with the sign in and
   button". They were 48px to the right of the card above them.

   The cause is that this override names `main` and the portal is the only ops
   screen with a FOOTER. So `main.container` was flattened to the full width with
   a 12px gutter while `footer.container` kept the marketing site's rules - a
   1240px max-width, `margin: 0 auto` and the 40px desktop gutter. Measured at
   1280px: the card's content began at 12px and the footer's at 60px.

   It is a sibling selector rather than a wider one on purpose. `.container` is
   the public site's wrapper and is used inside ops cards; flattening every one of
   them would reach markup this rule has no business touching. */
body > footer.container {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  padding-left: 12px;
  padding-right: 12px;
}

.console {
  --c-bg: #f3f4f6;
  --c-ink: #111827;
  --c-muted: #6b7280;
  --c-line: #d1d5db;
  --c-line-strong: #9ca3af;
  --c-head: #e5e7eb;
  --c-row: #ffffff;
  --c-row-alt: #f9fafb;
  --c-green: #166534;
  --c-green-bg: #dcfce7;
  --c-amber: #92400e;
  --c-amber-bg: #fef3c7;
  --c-red: #991b1b;
  --c-red-bg: #fee2e2;
  --c-link: #1d4ed8;
  --c-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  font: 13px/1.4 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--c-ink);
  /* NO GROUND OF ITS OWN. Neil, 13 September: "this background should match
     the background surrounding it." Painting --c-bg here drew the console as a
     gray box with a cream seam down both sides. It inherits the page instead;
     when every ops screen is a console, the ground is set once in the chrome
     and this still inherits. --c-bg stays a token for the day that happens. */
  background: transparent;
  padding: 8px 16px 40px;
  max-width: 1280px;
  font-variant-numeric: tabular-nums;
}
.console a { color: var(--c-link); text-decoration: none; }
.console a:hover { text-decoration: underline; }
.console .mono { font-family: var(--c-mono); font-size: 12px; }
.console .muted { color: var(--c-muted); }

/* --- identity row ---------------------------------------------------------- */
.console .crumb { color: var(--c-muted); font-size: 12px; margin: 0 0 6px; }
.console .title-row {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 0 0 6px;
}
/* WRITTEN OUT, NOT AS A font SHORTHAND, for the third time in this file.
   `font: 700 20px/1.2 inherit` is INVALID - a CSS-wide keyword is not a
   <family-name> - so the browser throws the WHOLE declaration away. This
   heading has been rendering at the UA default ever since, which is 2em of the
   console's 13px: 26px, in whatever the inherited family happens to be. The
   warning block further down this file describes this exact trap and these two
   rules were sitting above it doing it. */
.console h1 {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0;
}
.console .id { font-family: var(--c-mono); color: var(--c-muted); font-size: 13px; }
.console .meta { color: var(--c-muted); margin: 0 0 10px; }
.console .meta span { margin-right: 14px; white-space: nowrap; }
.console .meta b { color: var(--c-ink); font-weight: 600; }

/* --- chips: small, flat, and only the true ones ---------------------------- */
.console .chip {
  display: inline-block; font-size: 11px; font-weight: 600; padding: 1px 7px;
  border-radius: 3px; background: var(--c-head); color: #374151;
  text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap;
}
.console .chip.ok { background: var(--c-green-bg); color: var(--c-green); }
.console .chip.warn { background: var(--c-amber-bg); color: var(--c-amber); }
.console .chip.bad { background: var(--c-red-bg); color: var(--c-red); }

/* --- toolbar: small buttons, real forms ------------------------------------
   Every button is a <form method="post"> to a route that already exists. On a
   phone they go full width, because a driver taps these with one hand at a
   door and 44px is the floor for a touch target - the warehouse look does not
   get to make the doorstep worse. */
.console .toolbar { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; align-items: flex-start; }
.console .toolbar form { margin: 0; display: contents; }
.console .cbtn {
  background: #fff; border: 1px solid var(--c-line-strong); padding: 5px 10px;
  border-radius: 3px; cursor: pointer; color: var(--c-ink); font: inherit;
  min-height: 30px; text-decoration: none; display: inline-block;
}
.console .cbtn:hover { background: #f3f4f6; text-decoration: none; }
.console .cbtn.primary { background: #111827; color: #fff; border-color: #111827; }
.console .cbtn.primary:hover { background: #000; }
.console .cbtn.danger { color: var(--c-red); border-color: #fca5a5; }
.console .toolbar .field { display: inline-flex; gap: 6px; align-items: center; }
.console .toolbar input, .console .toolbar select {
  font: inherit; padding: 4px 6px; border: 1px solid var(--c-line-strong); border-radius: 3px;
  min-height: 30px; background: #fff;
}
@media (max-width: 720px) {
  .console .toolbar form { display: flex; width: 100%; }
  .console .cbtn { min-height: 44px; flex: 1; text-align: center; }
  .console .toolbar .field { width: 100%; }
  .console .toolbar input, .console .toolbar select { min-height: 44px; flex: 1; }
}

/* --- the one exception strip ----------------------------------------------- */
.console .strip {
  border: 1px solid #f59e0b; background: var(--c-amber-bg); padding: 8px 10px; margin: 0 0 12px;
}
.console .strip.open { border-color: #ef4444; background: var(--c-red-bg); }
.console .strip b { font-weight: 700; }
.console .strip .row { margin-top: 4px; }
.console .strip .bad { color: var(--c-red); font-weight: 600; }

/* --- stage rail ------------------------------------------------------------- */
.console .rail {
  display: flex; background: #fff; border: 1px solid var(--c-line); margin: 0 0 4px; overflow-x: auto;
}
.console .rail .s { flex: 1; min-width: 110px; padding: 6px 10px; border-right: 1px solid var(--c-line); }
.console .rail .s:last-child { border-right: 0; }
.console .rail .s .n { font-weight: 700; font-size: 12px; }
.console .rail .s .t { color: var(--c-muted); font-size: 11px; }
.console .rail .s.on { background: var(--c-green-bg); }
.console .rail .s.now { background: var(--c-amber-bg); }

/* --- two columns, one below 960 ------------------------------------------- */
.console .layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
@media (max-width: 960px) { .console .layout { grid-template-columns: 1fr; } }
.console .side { position: sticky; top: 8px; }
@media (max-width: 960px) { .console .side { position: static; } }

/* Same invalid shorthand as h1 above, same silent failure: these section
   labels have never been 11px, never been bold and never been uppercase. */
.console h2 {
  font-size: 11px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #4b5563;
  margin: 16px 0 6px;
}
.console h2:first-child { margin-top: 0; }

/* --- tables ----------------------------------------------------------------- */
.console table.data { width: 100%; border-collapse: collapse; background: var(--c-row); font-size: 13px; }
.console table.data th {
  text-align: left; font-size: 11px; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase;
  color: #4b5563; background: var(--c-head); border: 1px solid var(--c-line); padding: 5px 8px; white-space: nowrap;
}
.console table.data td { border: 1px solid var(--c-line); padding: 5px 8px; vertical-align: top; background: var(--c-row); }
.console table.data tbody tr:nth-child(even) td { background: var(--c-row-alt); }
.console table.data td.num, .console table.data th.num { text-align: right; }
.console table.data td.mono { font-family: var(--c-mono); font-size: 12px; }
.console table.data tfoot td { font-weight: 700; background: var(--c-head); }
.console table.data td.who { white-space: nowrap; color: var(--c-muted); }
.console .tablewrap { overflow-x: auto; }

/* --- key/value --------------------------------------------------------------- */
.console table.kv { width: 100%; border-collapse: collapse; background: #fff; }
.console table.kv th, .console table.kv td {
  border: 1px solid var(--c-line); padding: 5px 8px; text-align: left; font-weight: 400; vertical-align: top;
}
.console table.kv th { width: 38%; background: var(--c-head); color: #4b5563; font-size: 12px; }

/* --- log filters: links, not scripts --------------------------------------- */
.console .filters { color: var(--c-muted); font-size: 12px; margin: -2px 0 6px; }
.console .filters a, .console .filters span { margin-right: 12px; }
.console .filters span.on { color: var(--c-ink); font-weight: 700; }

/* --- thread ------------------------------------------------------------------ */
.console .thread { background: #fff; border: 1px solid var(--c-line); }
.console .thread .m { padding: 7px 8px; border-bottom: 1px solid var(--c-line); white-space: pre-wrap; word-break: break-word; }
.console .thread .m:last-child { border-bottom: 0; }
.console .thread .m.in { background: var(--c-row-alt); }
.console .thread .when { color: var(--c-muted); font-size: 11px; margin-bottom: 2px; white-space: normal; }
.console .hint { color: var(--c-muted); font-size: 12px; margin-top: 6px; }

/* --- the page-level banners the route already passes ----------------------- */
/* THE CONSOLE FLASH IS THE SAME OBJECT AS .ops-note, so it says the same
   thing the same way. It predates the component and drew a filled red or
   green panel; the tone is the left rule now, and the panel stays white -
   otherwise the one screen with the most notices on it is the one screen
   where they look different. */
.console .flash {
  padding: 10px 12px;
  margin: 0 0 12px;
  background: var(--c-row);
  border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-line-strong);
}
.console .flash.problem { border-left-color: #b91c1c; }
.console .flash.done { border-left-color: #15803d; }
/* --- the shared table, off inline styles ---------------------------------

   admin.js's table() used to write padding, borders and type onto every cell.
   An inline style beats every stylesheet rule, so no skin could reach the one
   piece of markup the restyle is actually about. The rules below reproduce
   what those inline styles said, exactly, so the four Admin screens that also
   call table() look the way they did before this moved.

   The terminal override is further down and applies only under
   .ops-terminal. */
.ops-table-wrap { overflow-x: auto; }

.ops-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}

.ops-table th {
  text-align: left;
  padding: 10px 14px 10px 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-500);
  border-bottom: 2px solid var(--ink-900);
  white-space: nowrap;
}

.ops-table td {
  padding: 14px 14px 14px 0;
  border-bottom: 1px solid var(--ink-100);
  vertical-align: top;
}

.ops-empty { font-size: 16px; color: var(--ink-500); margin: 0; }

/* ===========================================================================
   THE TERMINAL SKIN.

   Neil, 14 September, slice two: the live day only - the orders board, the
   route, routing and the load-out. Everything under .ops-terminal, so a page
   that has not been converted keeps the look its body was written for. Adding
   a later slice is adding the flag to those routes.

   WHAT THIS IS DOING is restyling the primitives those pages already use -
   cards, tables, badges, buttons, labels - rather than rewriting four large
   page bodies. The markup on these screens is load-bearing: the run page is a
   driver's only screen and the routing board decides where a van goes. A skin
   that leaves the structure alone cannot reorder a stop or hide a control,
   which a rewrite of 200KB of markup very much could.
   =========================================================================== */

/* --- the page ------------------------------------------------------------- */

/* WRITTEN OUT, NOT AS A font SHORTHAND. `font: 700 20px/1.2 inherit` looks
   right and is invalid - the shorthand will not take `inherit` as the family,
   so the browser throws the WHOLE declaration away and the heading stayed at
   the design system's 40px. It failed silently and looked like a specificity
   problem.

   AND THEY SHOUT, because fifty headings across the ops pages are written as
   <h1 style="font-family:var(--font-display);font-size:38px;...">, and an
   inline style beats every ordinary rule. Without !important this block did
   nothing at all on most of the screens slices two to four converted - they
   kept 38px of display type over a 13px table.

   I did not catch that when those slices shipped because I checked the skin
   against markup I had injected myself, which carried no inline styles. The
   right test was a real page, and it is what found this one. */
.ops-terminal h1 {
  font-family: inherit !important;
  font-size: 20px !important;
  font-weight: 700 !important;
  line-height: 1.2 !important;
  letter-spacing: -0.02em !important;
  margin: 0 0 10px;
}

.ops-terminal h2 {
  font-family: inherit !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  line-height: 1.25 !important;
  letter-spacing: 0 !important;
  margin: 0 0 8px;
}

/* --- the console keeps its own heading scale ------------------------------

   THE ORDER PAGE OPTED INTO .ops-terminal ON 16 SEPTEMBER, and the generic
   h1/h2 rules above immediately stomped the console's own. They carry
   !important for a good reason - fifty inline `font-family:var(--font-display)`
   headings across ops needed beating - but the console never had those. It has
   a deliberate two-step scale: a 20px page title and an 11px uppercase section
   label (BAGS, ORDER, MONEY), and the terminal's 15px h2 with letter-spacing
   forced to 0 turned those labels into small headings instead.

   So the console's own scale is restored, at a specificity that wins: two
   classes and an element against one class and an element, plus !important to
   answer !important. Nothing else about the terminal skin is touched, and a
   page that is .ops-terminal WITHOUT a .console inside it is unaffected. */
.ops-terminal .console h1 {
  font-size: 20px !important;
  font-weight: 700 !important;
  line-height: 1.2 !important;
  letter-spacing: -0.02em !important;
}

.ops-terminal .console h2 {
  font-size: 11px !important;
  font-weight: 700 !important;
  line-height: 1.3 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase;
}

.ops-terminal h3 {
  font-family: inherit !important;
  font-size: 13px !important;
  font-weight: 700 !important;
  line-height: 1.3 !important;
  margin: 0 0 6px;
}

/* The display classes are the public voice and are used for headings on these
   pages too. Same treatment. */
.ops-terminal .display-1,
.ops-terminal .display-2,
.ops-terminal .display-3 {
  font-family: inherit;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

/* An eyebrow becomes a plain small label. The mono uppercase is the public
   site's voice and costs a line of height for four words. */
.ops-terminal .eyebrow {
  font: 600 11px/1.2 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 4px;
}

/* --- cards become panels --------------------------------------------------

   The design system's card is cream, ink-outlined and casts a hard 6px
   shadow. Six of those stacked down a routing board is a lot of furniture
   around three numbers. Here a card is a white panel on a hairline. */
.ops-terminal .card,
.ops-terminal .card-xl {
  background: var(--c-row);
  border: 1px solid var(--c-line);
  border-radius: 3px;
  padding: 12px 14px !important;
  margin-bottom: 12px;
  /* !important because these pages write their shadows INLINE, and an inline
     style beats every ordinary rule. It is the one declaration here that has
     to shout, and it is shouting at markup this slice deliberately does not
     touch - rewriting four page bodies to remove a shadow is not worth the
     risk to a driver's only screen. */
  box-shadow: none !important;
}

.ops-terminal .card-sunken { background: var(--c-row-alt); }

/* Colour still means something. A card the page painted red or amber keeps
   its meaning and loses only the shadow - these are the exception lines and
   they are the one thing that must not get quieter. */
.ops-terminal .card[style*="--stain"],
.ops-terminal .card[style*="stain-500"] {
  border-color: #ef4444;
}

/* --- tables --------------------------------------------------------------- */

.ops-terminal .ops-table { font-size: 13px; }

.ops-terminal .ops-table th {
  background: var(--c-head);
  border-bottom: 1px solid var(--c-line-strong);
  border-top: 1px solid var(--c-line);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--c-ink);
  padding: 6px 10px;
}

.ops-terminal .ops-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--c-line);
  vertical-align: top;
}

.ops-terminal .ops-table tbody tr:nth-child(even) { background: var(--c-row-alt); }
.ops-terminal .ops-table tbody tr:nth-child(odd) { background: var(--c-row); }

/* Any other table on these pages, not only the shared helper. The run and
   routing pages build their own. */
.ops-terminal table { border-collapse: collapse; }
.ops-terminal .ops-empty { font-size: 13px; color: var(--c-muted); }

/* Figures line up. A column of weights you cannot compare at a glance is a
   column you have to read twice. */
.ops-terminal td, .ops-terminal .num { font-variant-numeric: tabular-nums; }

/* --- badges become chips -------------------------------------------------- */

.ops-terminal .badge {
  display: inline-block;
  border: 0;
  border-radius: 2px;
  box-shadow: none;
  padding: 1px 6px;
  font: 700 11px/1.6 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0.02em;
  text-transform: none;
  background: var(--c-head);
  color: var(--c-ink);
  vertical-align: baseline;
}

/* --- buttons -------------------------------------------------------------- */

.ops-terminal .btn {
  height: auto;
  min-height: 0;
  border-radius: 3px;
  border: 1px solid var(--c-line-strong);
  background: #fff;
  color: var(--c-ink);
  box-shadow: none;
  padding: 5px 10px;
  font: 600 13px/1.2 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0;
  text-transform: none;
  transform: none;
}

.ops-terminal .btn:hover { background: var(--c-row-alt); transform: none; box-shadow: none; }
.ops-terminal .btn:active { transform: none; box-shadow: none; }

.ops-terminal .btn-primary {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: #fff;
}
.ops-terminal .btn-primary:hover { background: #000; }

/* THE DRIVER'S BUTTONS STAY BIG, AND THIS IS THE ONE PLACE THE SKIN GIVES WAY.
   CLAUDE.md: a control on the run is 56px and full width because it is tapped
   on a doorstep with one hand full, and no touch target goes below 44px. A
   13px toolbar button is right at a desk and wrong in a stairwell.

   ONLY WHERE SOMEBODY IS STANDING UP. This was every terminal page until slice
   four, which was wrong the moment the desk screens arrived: it made the text
   blast's Send it a 52px slab, when the spec asks for exactly the opposite -
   a dangerous action should be a small button, not a hero. .ops-touch is set
   on the route by adminPage, so it is a decision rather than a guess about a
   URL. */
.ops-terminal.ops-touch .btn-lg,
.ops-terminal.ops-touch .btn-full {
  min-height: 52px;
  padding: 14px 18px;
  font-size: 16px;
  font-weight: 700;
}

/* At a desk a big button is just a button. Full width is kept where the markup
   asked for it - that is layout, not a target size. */
.ops-terminal:not(.ops-touch) .btn-lg {
  min-height: 0;
  padding: 5px 10px;
  font-size: 13px;
  font-weight: 600;
}

.ops-terminal .btn-full { width: 100%; display: block; }

.ops-terminal .btn-sm {
  min-height: 0;
  padding: 3px 8px;
  font-size: 12px;
}

/* --- fields --------------------------------------------------------------- */

.ops-terminal .input,
.ops-terminal .select,
.ops-terminal input[type="text"],
.ops-terminal input[type="date"],
.ops-terminal input[type="time"],
.ops-terminal input[type="number"],
.ops-terminal select {
  height: auto;
  border: 1px solid var(--c-line-strong);
  border-radius: 3px;
  box-shadow: none;
  background: #fff;
  padding: 5px 8px;
  font: 13px/1.3 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* The scan box and the weight box are typed at a door, so they keep a real
   target. Same reasoning as the buttons above, and scoped the same way. */
.ops-terminal.ops-touch .input-lg {
  padding: 12px 12px;
  font-size: 16px;
  min-height: 48px;
}

.ops-terminal .field-label {
  font: 600 11px/1.2 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin-bottom: 3px;
}

/* --- links ---------------------------------------------------------------- */

.ops-terminal a { color: var(--c-link); }
.ops-terminal a:hover { text-decoration: underline; }

/* --- THE MAP IS NOT OURS TO SKIN ----------------------------------------

   The route planner is the one ops page with a runtime dependency: Leaflet,
   OpenStreetMap tiles and OSRM. Leaflet builds its own controls out of plain
   anchors and divs, and styles them from its own stylesheet - so a blanket
   link colour or a table rule reaching inside the map restyles somebody
   else's component, which is how a zoom button ends up blue and 13px.

   Everything under the map keeps its own look. The planner already paints the
   tiles and its tooltips deliberately; that is its business, not this file's. */
.ops-terminal #rp-map a,
.ops-terminal .leaflet-container a {
  color: inherit;
}

.ops-terminal #rp-map,
.ops-terminal .leaflet-container {
  font-size: initial;
}

.ops-terminal .leaflet-container table,
.ops-terminal .leaflet-container .btn {
  all: revert;
}

/* A card that is a link keeps no lift and no shadow. */
.ops-terminal a .card:hover { transform: none; box-shadow: none; }

/* ===========================================================================
   THE OLD LOOK, DRAWN INLINE, ON TOP OF THE NEW ONE.

   Neil, 14 September, reading it on his phone: cream paper, giant display
   type, thick black outlines and hard shadows still showing through the grey
   terminal.

   He is right, and the reason is the thing that already bit once on headings.
   The ops markup writes its look INLINE - 69 display-font declarations, 47
   shadows, 27 cream backgrounds - and an inline style beats every ordinary
   rule. Slices two to six restyled the primitives by class, so everything a
   page painted on itself came straight back through.

   THESE RULES MATCH THE INLINE STRING, NOT THE ELEMENT. [style*="..."] is the
   only way to reach a declaration a page wrote on itself, and it is the point
   of using it here: it lets this file neutralise CREAM without touching the
   red of an exception banner or the amber of a held order. A blanket
   background rule would have flattened both, and the one thing that must stay
   loud is the line that says somebody has not paid.

   THE REAL FIX IS TO STOP WRITING STYLE ATTRIBUTES IN THE MARKUP. That is a
   rewrite of every ops page body and it is not this change; this is what makes
   the screens right today without touching a single page's structure.
   =========================================================================== */

/* --- cream becomes a white panel -----------------------------------------

   THE PROPERTY NAME IS IN THE MATCH, and it has to be. Matching the bare token
   caught the red issues banner, whose inline style reads
   `background:var(--stain-500);color:var(--paper-050);` - cream as the TEXT
   colour on a red ground. The rule painted its background white, leaving white
   text on white: the one line on the board that must never go quiet, gone.

   Caught by rendering the real banner markup rather than a tidy copy of it.
   Matching `background:` and `background-color:` explicitly cannot make that
   mistake, because a colour declaration no longer looks like a background one. */
.ops-terminal [style*="background:var(--paper-000)"],
.ops-terminal [style*="background:var(--paper-050)"],
.ops-terminal [style*="background:var(--paper-100)"],
.ops-terminal [style*="background:var(--paper-200)"],
.ops-terminal [style*="background-color:var(--paper-000)"],
.ops-terminal [style*="background-color:var(--paper-050)"],
.ops-terminal [style*="background-color:var(--paper-100)"],
.ops-terminal [style*="background-color:var(--paper-200)"] {
  background-color: var(--c-row) !important;
}

/* --- thick ink outlines become hairlines --------------------------------- */
.ops-terminal [style*="solid var(--ink-900)"] {
  border-color: var(--c-line) !important;
  border-width: 1px !important;
}

/* A 14px pill radius on a panel is the public site's shape. The progress bar
   keeps its own, further down. */
.ops-terminal [style*="border-radius:14px"],
.ops-terminal [style*="border-radius:16px"],
.ops-terminal [style*="border-radius:18px"] {
  border-radius: 3px !important;
}

/* --- hard shadows go ------------------------------------------------------

   Every shadow in this markup is the design system's hard ink offset. There is
   no blurred one to preserve. */
.ops-terminal [style*="box-shadow"] {
  box-shadow: none !important;
}

/* --- display type becomes the interface face ------------------------------

   The family always. The SIZE only where the markup asked for something large,
   matched on the inline string - so a 30px heading and a 32px count come down
   and anything already small is left alone rather than being pushed UP to meet
   a blanket size. */
.ops-terminal [style*="var(--font-display)"] {
  font-family: inherit !important;
  letter-spacing: 0 !important;
}

.ops-terminal [style*="var(--font-display)"][style*="font-size:2"],
.ops-terminal [style*="var(--font-display)"][style*="font-size:3"],
.ops-terminal [style*="var(--font-display)"][style*="font-size:4"] {
  font-size: 18px !important;
  font-weight: 700 !important;
  line-height: 1.2 !important;
}

/* A count tile's number is the one piece of display type worth keeping big -
   it is the whole content of the tile. Big for a terminal, not for a poster. */
.ops-terminal .card > [style*="font-family:var(--font-display)"][style*="font-size:3"] {
  font-size: 22px !important;
}

/* --- the driver route strip -----------------------------------------------

   Its progress bar is a 12px pill with a 2px ink border, which the rules above
   flatten to a hairline. Keeping the pill radius here is deliberate: a
   progress bar reads as a bar, and it is the one rounded thing left. */
.ops-terminal [style*="border-radius:999px"] {
  border-radius: 999px !important;
  height: 8px !important;
}

/* --- scan and weight boxes ------------------------------------------------

   The load-out and the run write thick outlines on their inputs inline. They
   stay large on the standing-up screens - that is the ops-touch rule - but a
   3px ink frame is the public look. */
.ops-terminal input[style*="var(--ink-900)"],
.ops-terminal textarea[style*="var(--ink-900)"] {
  border-color: var(--c-line-strong) !important;
  border-width: 1px !important;
}

/* --- nothing hides under the bar -----------------------------------------

   THE BAR IS STICKY AND THE APP RUNS UNDER THE STATUS BAR. adminPage sets
   apple-mobile-web-app-status-bar-style to black-translucent so the top of the
   screen is ours, which also means the page begins BEHIND the clock on a
   home-screen launch. On Neil's phone the first row of tiles was arriving
   under it.

   env(safe-area-inset-top) is what that inset is called; the fallback is zero,
   so a desktop browser is unaffected. */
.ops-terminal .site-header {
  padding-top: env(safe-area-inset-top, 0px);
}

/* And a little air under the bar, so a tile that scrolls up to it is not
   touching it at the moment it stops. */
.ops-terminal > main.container,
.ops-terminal body > main.container {
  scroll-padding-top: 56px;
}

.ops-terminal .card {
  scroll-margin-top: 56px;
}

/* --- notices, and the one look they all share -----------------------------

   THE BANNER WAS THE LAST PIECE OF THE PUBLIC SITE LEFT IN OPS. Neil, 16
   September: an issue is raised and the strip across the top is cream card
   stock with a hard ink shadow and a 24px display face, sitting on a grey
   terminal. Every other thing on the page had been flattened around it.

   ONE CLASS, AND IT IS NOT UNDER .ops-terminal. That scope is opt-in - 43 of
   the 89 adminPage calls ask for it - so a notice styled there would look
   right on half the screens and like the marketing site on the rest. The
   issues banner in particular renders in the shared shell on EVERY ops page,
   which is exactly the set .ops-terminal does not cover. This sheet is loaded
   on every ops page and nowhere else, so plain selectors are both safe and
   the only thing that reaches all of them.

   WHITE PANEL ON THE GREY GROUND, HAIRLINE, 13px. Same furniture as a table,
   because a notice is something you read at a desk next to one.

   COLOUR CARRIES MEANING AND NOTHING ELSE. The old banners flooded the whole
   panel - a full-bleed Stain red strip for an open issue, Sunbeam yellow for
   a held weight - which is a lot of shouting for something that is on screen
   all day, and it left no louder register for the genuinely urgent. The tone
   lives in a 3px left rule and the label above the text; the panel stays
   white. Red means somebody must act, amber means something is waiting, green
   means it worked. */
.ops-note {
  display: block;
  margin: 0 0 12px;
  padding: 10px 12px;
  background: var(--c-row, #fff);
  border: 1px solid var(--c-line, #d1d5db);
  border-left: 3px solid var(--c-line-strong, #9ca3af);
  border-radius: 0;
  box-shadow: none;
  color: var(--c-ink, #111827);
  font: 13px/1.45 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* A notice is often a link to the screen that fixes it. It must not pick up
   the blue underline a link in a table gets - the whole panel is the target. */
a.ops-note,
a.ops-note:hover { text-decoration: none; color: var(--c-ink, #111827); }

.ops-note--bad { border-left-color: #b91c1c; }
.ops-note--warn { border-left-color: #b45309; }
.ops-note--good { border-left-color: #15803d; }

/* The eyebrow, minus the display face and the letter-spacing of a poster.
   11px is the label size the rest of ops uses. */
.ops-note__label {
  display: block;
  margin: 0 0 3px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--c-muted, #6b7280);
}

.ops-note--bad .ops-note__label { color: var(--c-red, #991b1b); }
.ops-note--warn .ops-note__label { color: var(--c-amber, #92400e); }
.ops-note--good .ops-note__label { color: var(--c-green, #166534); }

/* WHAT WAS A 24px DISPLAY HEADLINE IS 13px BOLD. It is a sentence, not a
   masthead, and it sits one line above the explanation it belongs to. */
.ops-note__title {
  display: block;
  margin: 0 0 4px;
  /* NOT the font shorthand. `font: 700 13px/1.35 inherit` looks tidier and is
     invalid - a CSS-wide keyword is not a <family-name>, so the browser drops
     the whole declaration and the title renders at body weight. Found by
     looking at the rendered page, not by reading the rule. */
  font-size: 13px;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: 0;
}

.ops-note__body { margin: 0; }
.ops-note__body + .ops-note__body { margin-top: 6px; }

/* The "open them" / "change it" affordance on a banner that is a link. */
.ops-note__go {
  color: var(--c-link, #1d4ed8);
  font-weight: 600;
  white-space: nowrap;
}

/* Some notices carry a figure or two - two scales that disagree, a count.
   Tabular so the columns line up, and nowhere near the old 26px. */
.ops-note__figures {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin: 8px 0;
  font-variant-numeric: tabular-nums;
}

.ops-note__figures b { display: block; font-size: 15px; font-weight: 700; }

/* A banner that is a link puts its target on the right on a wide screen and
   underneath on a phone. */
.ops-note__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}

/* --- beating what is still written inline ---------------------------------

   Neil: beat those exact inline rules, or stop writing them. Everything this
   pass touched stopped writing them, which is why the block above is plain
   classes with no !important in it.

   These two are the exception, and they earn it: .card and .card-xl come from
   lyndry.css and are still on some of the converted markup for their padding,
   so the cream fill and the hard offset shadow would come back through the
   class rather than through a style attribute. Naming them on .ops-note is
   how the panel stays white. */
.ops-note.card,
.ops-note.card-xl {
  background: var(--c-row, #fff);
  border: 1px solid var(--c-line, #d1d5db);
  border-left: 3px solid var(--c-line-strong, #9ca3af);
  border-radius: 0;
  box-shadow: none;
}

.ops-note.card.ops-note--bad,
.ops-note.card-xl.ops-note--bad { border-left-color: #b91c1c; }
.ops-note.card.ops-note--warn,
.ops-note.card-xl.ops-note--warn { border-left-color: #b45309; }
.ops-note.card.ops-note--good,
.ops-note.card-xl.ops-note--good { border-left-color: #15803d; }

/* ===========================================================================
   THE INTAKE TABLE.

   Neil's brief, 16 September: the "what is still missing" cards are replaced
   by a table of every field, its value, whether that value is EXPLICIT,
   DEFAULT, MISSING or N/A, and a way to ask for it.

   TWO THINGS THE OLD CARDS GOT WRONG AND THIS MUST NOT.

   A DEFAULT IS NOT A WARNING. Anything unanswered used to be a gap with a
   button on it, so "cold water" and "no address" looked the same. Only a
   MISSING row that is genuinely holding something up is loud here; a default
   is plain grey text.

   AND IT IS ALWAYS THERE. The cards appeared only when something was missing,
   so a fully set up customer's screen said nothing at all about what we knew.
   Completed rows stay, and each offers an update.

   IT OPENS WITH :target AND NOTHING ELSE. The action is a link to the row's
   own id; this shows that row. No script, like every other ops screen - and
   one composer at a time for free, so there is never a second half-typed
   message on screen that somebody thinks they sent.

   TOKENS RATHER THAN THE DESIGN SYSTEM'S, because this renders on both skins:
   the conversation and the order page are terminal, the customer page is not.
   The --c-* tokens are declared on body above, so they resolve on either.
   =========================================================================== */

.intake { margin: 0 0 18px; }

.intake-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  margin: 0 0 6px;
}

.intake-summary { color: var(--c-muted); font-size: 12px; }

.intake-tbl th[scope="row"] {
  font-weight: 600;
  white-space: nowrap;
  text-align: left;
  border-bottom: 1px solid var(--c-line);
  padding: 6px 10px 6px 0;
}

.intake-tbl td { vertical-align: top; }

.intake-none { color: var(--c-muted); }

/* --- the state word ------------------------------------------------------- */

/* COMPACT TEXTUAL INDICATORS, his rule 36. A pill per row in four colours
   would make the table a traffic light, which is the thing it replaces. */
.intake-state {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 3px;
  white-space: nowrap;
  background: var(--c-head);
  color: var(--c-muted);
}

.intake-state--ok { background: var(--c-green-bg); color: var(--c-green); }
.intake-state--warn { background: var(--c-amber-bg); color: var(--c-amber); }
.intake-state--bad { background: var(--c-red-bg); color: var(--c-red); }

.intake-asked {
  margin-top: 3px;
  font-size: 11px;
  color: var(--c-muted);
  line-height: 1.35;
}

/* --- the action ----------------------------------------------------------- */

.intake-act { white-space: nowrap; }

/* Its own button rather than .cbtn, which is scoped to .console and therefore
   invisible on the customer page. */
.intake .cbtn {
  display: inline-block;
  padding: 3px 9px;
  border: 1px solid var(--c-line-strong);
  border-radius: 4px;
  background: var(--c-row);
  color: var(--c-ink);
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
  text-decoration: none;
  box-shadow: none;
}

.intake .cbtn:hover { background: var(--c-head); text-decoration: none; }
.intake .cbtn.primary { background: #111827; border-color: #111827; color: #fff; }
.intake .cbtn.primary:hover { background: #000; }

/* --- the composer --------------------------------------------------------- */

/* Hidden until its own link is followed. display:none on a <tr> and back to
   table-row is the whole mechanism. */
.intake-ask { display: none; }
.intake-ask:target { display: table-row; }

.intake-ask > td { background: var(--c-row-alt) !important; padding: 10px !important; }

.intake-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 5px;
}

.intake-text {
  width: 100%;
  resize: vertical;
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  padding: 7px 9px;
  border: 1px solid var(--c-line-strong);
  border-radius: 4px;
  background: var(--c-row);
  color: var(--c-ink);
  box-shadow: none;
}

.intake-send {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 8px;
}

.intake-cost {
  color: var(--c-muted);
  font-size: 11px;
  line-height: 1.4;
  flex: 1 1 200px;
  min-width: 0;
}

/* A phone. The table scrolls sideways in .ops-table-wrap, which is right for
   four short columns and wrong for a textarea - so the composer row stops
   being part of that width and the value column is allowed to wrap. */
@media (max-width: 560px) {
  .intake-tbl th[scope="row"] { white-space: normal; }
  .intake-act { white-space: normal; }
}

.console .layout.order-detail-layout { grid-template-columns: 340px minmax(0, 1fr); }
.console .order-summary { margin: 14px 0; }
@media (max-width: 960px) { .console .layout.order-detail-layout { grid-template-columns: 1fr; } }

.customer-texting { padding: 16px; margin-bottom: 24px; }
.customer-texting form { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.texting-switch { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; border: 0; background: transparent; color: inherit; cursor: pointer; }
.texting-switch-track { display: inline-flex; width: 44px; height: 24px; padding: 2px; border: 1px solid #101210; border-radius: 20px; background: #cbd5e1; }
.texting-switch-track span { width: 18px; height: 18px; border-radius: 50%; background: white; border: 1px solid #101210; }
.texting-switch[aria-checked="true"] .texting-switch-track { background: #0ea47a; justify-content: flex-end; }
.texting-switch:disabled { cursor: default; }
.customer-details-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.customer-details-table th, .customer-details-table td { border: 1px solid #cbd5e1; padding: 9px 12px; text-align: left; vertical-align: top; overflow-wrap: anywhere; }
.customer-details-table th { width: 34%; background: #e2e8f0; font-weight: 600; }
.customer-details-table td { background: #fff; }

/* Order controls precede the full-width details. */
.console .order-controls { margin: 14px 0; }
.console .order-controls #carrier { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:20px; }
.console .order-intake { width:100%; margin:14px 0; }
.console .order-intake table { width:100%; }
@media(max-width:640px) { .console .order-controls #carrier { grid-template-columns:1fr; } }

.logistics-board { max-width: none; }
.logistics-header h1 { font-size:24px; margin:2px 0 16px; }
.logistics-stats { display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px;margin-bottom:24px; }
.ops-terminal .logistics-stats > * { min-width:0!important; background:#fff!important;color:#172b4d!important;border-top:3px solid #536d86!important;padding:14px!important; }
.logistics-board > section { background:#fff;border:1px solid #d8dee7;border-radius:4px;padding:16px;margin-bottom:20px!important; }
.logistics-board .ops-table-wrap { width:100%; }
.logistics-board progress { display:block;width:100px;height:6px;margin-top:5px;accent-color:#267b72; }
.logistics-board .ops-table th { background:#edf1f5;letter-spacing:.04em; }
.logistics-board .ops-table td { padding-top:10px;padding-bottom:10px; }

.ops-terminal .logistics-stats > * * { color:#172b4d!important; }
@media(min-width:1100px) { .logistics-stats { grid-template-columns:repeat(9,minmax(0,1fr)); } }


/* Shared typography for every dispatch table, including driver progress. */
.ops-terminal .logistics-board .ops-table {
  font-family: inherit;
  font-size: 13px;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.ops-terminal .logistics-board .ops-table td {
  font-weight: 400;
  padding: 10px;
  vertical-align: middle;
}
.ops-terminal .logistics-board .ops-table td a {
  font-family: inherit;
  font-size: inherit;
  font-weight: 400;
  color: #2456a6;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.ops-terminal .logistics-board .ops-table td a:hover { color: #163869; }
.ops-terminal .logistics-board .ops-table th {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  padding: 8px 10px;
}
.ops-terminal .logistics-board .ops-table .badge {
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
}
.ops-terminal .logistics-board > section h2 { margin-bottom: 14px; }

/* Shared operations presentation. Inline legacy typography yields to this
   scale; status colors, numeric alignment and action permissions are retained. */
.ops-terminal main.container {
  font-size: 13px;
  line-height: 1.5;
}
.ops-terminal main.container table {
  font-family: inherit;
  font-size: 13px !important;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.ops-terminal main.container table td {
  font-size: 13px !important;
  font-weight: 400;
  padding: 10px !important;
  vertical-align: middle;
}
.ops-terminal main.container table th {
  font-family: inherit;
  font-size: 11px !important;
  font-weight: 600 !important;
  line-height: 1.5;
  letter-spacing: .04em;
  padding: 8px 10px !important;
}
.ops-terminal main.container table :is(td, th) a:not(.btn):not(.cbtn) {
  font-family: inherit !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  color: #2456a6;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.ops-terminal main.container table :is(td, th) a:not(.btn):not(.cbtn) :is(span, strong, b) {
  font-size: inherit !important;
  font-weight: inherit !important;
}
.ops-terminal main.container table :is(td, th) a:not(.btn):not(.cbtn):hover { color: #163869; }
.ops-terminal main.container :is(.badge, .chip) {
  font-family: inherit;
  font-size: 11px !important;
  font-weight: 600 !important;
  line-height: 1.4;
}
.ops-terminal main.container h1 {
  font-size: 20px !important;
  font-weight: 700 !important;
  line-height: 1.25 !important;
}
.ops-terminal main.container h2 {
  font-size: 15px !important;
  font-weight: 700 !important;
  line-height: 1.3 !important;
  letter-spacing: 0 !important;
  text-transform: none;
  margin-bottom: 14px;
}
.ops-terminal main.container :is(.eyebrow, .field-label) {
  font-family: inherit;
  font-size: 11px !important;
  font-weight: 600;
  letter-spacing: .04em;
  line-height: 1.5;
}
.ops-terminal main.container :is(.btn, .cbtn) {
  font-family: inherit !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  line-height: 1.4;
}
.ops-terminal main.container table.kv th,
.ops-terminal main.container .customer-details-table th,
.ops-terminal main.container th[scope="row"] {
  font-size: 13px !important;
  letter-spacing: 0;
  text-transform: none;
}

/* Shared focused work area and selectable schedule cards. */
.ops-terminal .ops-workspace { width:100%; max-width:960px; margin:0 auto; }
.ops-terminal .ops-text-link { font:inherit; font-weight:400; color:#2456a6; text-decoration:underline; text-underline-offset:2px; }
.ops-terminal .ops-window { min-width:0; border-width:1px; border-radius:4px; box-shadow:none!important; padding:12px; font:inherit; }
.ops-terminal .ops-window .rr-when { font-family:inherit; font-size:11px; font-weight:600; line-height:1.5; }
.ops-terminal .ops-window .rr-what { font-family:inherit; font-size:13px; font-weight:400!important; line-height:1.5; }
.ops-terminal a.ops-window { text-decoration:underline; text-underline-offset:2px; }
.ops-terminal.ops-touch main.container .btn-full { min-height:56px; }
@media(max-width:600px) {
  .ops-terminal .run-routes { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .ops-terminal .ops-window { min-height:64px; }
}

.ops-summary-grid { display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin-bottom:24px; }
.ops-terminal .ops-summary-grid > .card { min-width:0!important;background:var(--c-row)!important;color:var(--c-ink)!important;border-top:3px solid #536d86!important;padding:14px!important; }
.ops-navigation-grid { display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));grid-auto-rows:1fr;gap:16px; }
.ops-navigation-card { display:block;color:inherit;text-decoration:none; }
.ops-navigation-card:hover .card { border-color:#2456a6; }
.ops-navigation-card:focus-visible { outline:2px solid #2456a6;outline-offset:3px; }
.ops-filter-panel { display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end;margin:16px 0 24px;padding:16px;border:1px solid var(--c-line);border-radius:4px;background:var(--c-row); }

/* POS workspace — one shared skin for every operations screen.
   Existing workflow layouts and semantic status colors remain authoritative. */
body.pos-app {
  --c-bg: #f7f9fc;
  --c-ink: #253247;
  --c-muted: #58677d;
  --c-line: #dfe5ee;
  --c-line-strong: #a7b5c8;
  --c-head: #f6f8fb;
  --c-row-alt: #fafbfd;
  --c-link: #245bb0;
  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: var(--font-body);
  --font-mono: var(--font-body);
  --ink-400: #65738a;
  --ink-500: #58677d;
  --paper-050: #fff;
  background: var(--c-bg);
  font-family: var(--font-body);
  color: var(--c-ink);
}
.pos-app *, .pos-app *::before, .pos-app *::after { box-sizing: border-box; }
.pos-app > [role="status"] { position:relative; z-index:60; font-size:10px!important; border:0!important; padding:5px 12px!important; }
.pos-topbar { height:72px; display:flex; align-items:center; gap:24px; padding:0 28px; background:white; border-bottom:1px solid var(--c-line); position:sticky; top:0; z-index:45; }
.pos-brand { display:flex; align-items:center; gap:9px; font-size:18px; font-weight:800; letter-spacing:.03em; text-decoration:none; color:#17263e; flex-shrink:0; }
.pos-brand span { font-size:10px; font-weight:700; letter-spacing:.08em; background:#eaf1ff; color:#245bb0; padding:4px 6px; border-radius:5px; }
.pos-context { display:flex; align-items:center; gap:14px; font-size:12px; color:var(--c-muted); min-width:0; flex:1; }
.pos-context strong { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--c-ink); }
.pos-context-divider { color:#a7b5c8; }
.pos-account { display:flex; align-items:center; gap:16px; }
.pos-account form { margin:0; }
.pos-user { font-size:11px; color:var(--c-muted); }
.pos-sidebar { width:208px; position:fixed; top:98px; bottom:0; left:0; z-index:42; padding:22px 12px 16px; background:#fff; border-right:1px solid var(--c-line); display:flex; flex-direction:column; overflow-y:auto; }
.pos-app:not(:has(> [role="status"])) .pos-sidebar { top:72px; }
.pos-navigation { flex:1; }
.pos-navigation > summary { display:none; }
.pos-navigation:not([open]) > nav { display:block; }
.pos-nav-group { margin-bottom:22px; }
.pos-nav-label { padding:0 12px; margin:0 0 8px; color:#68758b; font-size:10px; font-weight:600; letter-spacing:.09em; text-transform:uppercase; }
.pos-app .pos-sidebar .pos-nav-link { display:flex; align-items:center; gap:12px; min-height:44px; padding:10px 12px; margin:3px 0; border-radius:8px; color:#4d5d74; font-size:12px; font-weight:500; text-decoration:none; }
.pos-nav-link svg { flex-shrink:0; }
.pos-app .pos-sidebar .pos-nav-link:hover { background:#f3f6fb; color:#245bb0; text-decoration:none; }
.pos-app .pos-sidebar .pos-nav-link[aria-current="page"] { color:#245bb0; background:#eaf1ff; font-weight:600; }
.pos-sidebar-foot { padding:16px 12px 0; border-top:1px solid var(--c-line); font-size:11px; font-weight:600; color:#4d5d74; }
.pos-sidebar-foot span { font-weight:400; font-size:10px; }
.pos-app > main.container { width:auto; max-width:none; margin-left:208px; padding:28px 30px 64px!important; min-height:calc(100vh - 98px); }
.pos-app.pos-focused > main.container { margin-left:auto; }
.pos-skip { position:fixed; top:-80px; left:220px; z-index:100; background:#fff; padding:12px; }
.pos-skip:focus { top:8px; }
.pos-app :focus-visible { outline:3px solid #3a75d5; outline-offset:3px; }
.pos-app main.container :is(h1,h2,h3,h4,p,input,select,textarea,button,table) { font-family:var(--font-body); }
.pos-app main.container h1 { margin:4px 0 20px; color:#17263e; }
.pos-app main.container .eyebrow { color:var(--c-muted); }
.pos-app main.container :is(.card,.panel,.ops-filter-panel,.ops-window),
.pos-app .logistics-board > section { border:1px solid var(--c-line); border-radius:12px!important; background:white; box-shadow:none!important; }
.pos-app main.container :is(.card,.card-xl) { padding:20px!important; }
.pos-app main.container .ops-note { border:1px solid var(--c-line); border-left:3px solid #8293ac; border-radius:8px; padding:12px 16px; margin-bottom:24px; background:#fff; }
.pos-app main.container .ops-note--bad { border-left-color:#c93232; }
.pos-app main.container .ops-note--warn { border-left-color:#b8650d; }
.pos-app main.container .ops-note--good { border-left-color:#08785c; }
.pos-app main.container .ops-note__label { font-size:10px; }
.pos-app main.container .ops-note__go { font-size:12px; font-weight:600; }
.pos-app main.container :is(.input,select,textarea,input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="range"]):not([type="submit"])) { border:1px solid #bac6d7; border-radius:7px; background:#fff; color:#253247; min-height:40px; font:13px/1.5 var(--font-body); padding:9px 12px; max-width:100%; box-shadow:none; }
.pos-app main.container textarea { min-height:110px; width:100%; resize:vertical; }
.pos-app main.container input::placeholder, .pos-app main.container textarea::placeholder { color:#68758b; opacity:1; }
.pos-app main.container .field-label { display:block; margin-bottom:7px; }
.pos-app main.container .field-hint { color:#58677d; line-height:1.6; }
.pos-app :is(.btn,.cbtn), .pos-app main.container :is(.btn,.cbtn) { min-height:38px; padding:9px 14px; border:1px solid #c5cfdd; border-radius:7px; background:#fff; color:#33435c; box-shadow:none; font:600 12px/1.4 var(--font-body); text-transform:none; letter-spacing:0; white-space:normal; }
.pos-app :is(.btn,.cbtn):hover { background:#f0f5ff; border-color:#7197d4; transform:none; }
.pos-app :is(.btn-ink,.btn-primary,.cbtn-primary) { background:#306bd0!important; color:white!important; border-color:#306bd0!important; }
.pos-app .cbtn-danger { color:#ac2525; border-color:#e9baba; background:#fff7f7; }
.pos-app.ops-touch main.container :is(.btn,.cbtn) { min-height:48px; }
.pos-app main.container :is(.badge,.chip) { border-radius:5px!important; padding:4px 7px; white-space:normal; display:inline-block; }
.pos-app main.container table { border-collapse:separate; border-spacing:0; background:white; width:100%; }
.pos-app main.container table th { background:#f6f8fb; color:#53637a; border-bottom:1px solid var(--c-line); text-align:left; }
.pos-app main.container table td { border-bottom:1px solid #e8edf4; color:#253247; }
.pos-app main.container table tr:nth-child(even) td { background:#fafbfd; }
.pos-app main.container table tr:hover td { background:#f2f6fd; }
.pos-app main.container .ops-table-wrap { border:1px solid var(--c-line); border-radius:10px; overflow-x:auto; max-width:100%; }
.pos-app .logistics-board > section { padding:20px; margin-bottom:24px!important; }
.pos-app .logistics-stats { gap:12px; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); }
.pos-app.ops-terminal .logistics-stats > *, .pos-app.ops-terminal .ops-summary-grid > .card { border:1px solid var(--c-line)!important; border-top:1px solid var(--c-line)!important; border-radius:10px!important; padding:18px!important; }
.pos-app .ops-summary-grid { gap:16px; }
.pos-app .ops-navigation-grid { gap:18px; }
.pos-app .ops-navigation-card .card { height:100%; min-height:108px; display:flex; flex-direction:column; justify-content:center; }
.pos-app .ops-navigation-card:hover .card { border-color:#306bd0; background:#f8fbff; }
.pos-app .ops-navigation-card .card::after { content:'→'; color:#306bd0; align-self:flex-end; margin-top:8px; }
.pos-app .console { --c-bg:#f7f9fc; --c-line:#dfe5ee; --c-head:#f6f8fb; --c-ink:#253247; background:transparent; }
.pos-app.pos-login .hero { min-height:calc(100vh - 26px)!important; }
.pos-app.pos-login .hero > .container { background:#fff; border:1px solid var(--c-line); border-radius:16px; padding:36px!important; margin:32px auto; }
.pos-app.pos-login .pos-brand { margin-bottom:32px; }
.pos-app.pos-login .card { border:0; padding:0!important; }
@media(min-width:1600px) { .pos-app .logistics-stats { grid-template-columns:repeat(9,minmax(0,1fr)); } }
@media(max-width:1100px) and (min-width:761px) {
 .pos-sidebar { width:100px; padding:16px 7px; }
 .pos-app .pos-sidebar .pos-nav-link { flex-direction:column; gap:5px; padding:10px 3px; font-size:10px; text-align:center; }
 .pos-nav-label { padding:0; text-align:center; font-size:9px; }
 .pos-sidebar-foot { display:none; }
 .pos-app > main.container { margin-left:100px; padding:24px!important; }
 .pos-user { display:none; }
}
@media(max-width:760px) {
 .pos-topbar { height:64px; padding:0 16px; gap:12px; }
 .pos-brand { font-size:16px; }
 .pos-context, .pos-user { display:none; }
 .pos-account { margin-left:auto; }
 .pos-sidebar, .pos-app:not(:has(> [role="status"])) .pos-sidebar { position:relative; width:100%; top:auto; padding:0 16px; border-right:0; border-bottom:1px solid var(--c-line); max-height:none; }
 .pos-navigation > summary { display:flex; justify-content:space-between; align-items:center; min-height:44px; padding:10px 0; font-size:12px; font-weight:600; cursor:pointer; }
 .pos-navigation:not([open]) > nav { display:none; }
 .pos-navigation nav { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; }
 .pos-nav-group { margin:0 0 12px; }
 .pos-nav-label { margin:8px 0; }
 .pos-app .pos-sidebar .pos-nav-link { min-height:44px; font-size:12px; }
 .pos-sidebar-foot { display:none; }
 .pos-app > main.container { margin-left:0; padding:20px 14px 48px!important; }
 .pos-app .logistics-stats { grid-template-columns:repeat(2,minmax(0,1fr)); }
 .pos-app main.container :is(.card,.card-xl), .pos-app .logistics-board > section { padding:16px!important; }
 .pos-app main.container :is(input,select,textarea) { font-size:16px!important; }
 .pos-app main.container :is(.btn,.cbtn) { min-height:44px; }
 .pos-app.pos-login .hero > .container { width:calc(100% - 28px); padding:24px!important; }
 .pos-skip { left:14px; }
}
.pos-app .console { padding:0; max-width:none; --c-mono:var(--font-body); }
.pos-app .console :is(.order-controls,.order-summary,.order-intake:not(:empty),.order-detail-layout > div) { padding:20px; background:#fff; border:1px solid var(--c-line); border-radius:12px; margin-bottom:20px; min-width:0; }
.pos-app .console .order-intake:empty { display:none; }
.pos-app .console .order-summary { overflow-x:auto; }
.pos-app .console .order-detail-layout { gap:20px; }
.pos-app .console .tablewrap { border:1px solid var(--c-line); border-radius:8px; }
.pos-app .console .title-row { margin:0 0 20px; align-items:center; }
.pos-app .console .title-row h1 { margin:0; }
.pos-app .console .filters { display:flex; flex-wrap:wrap; gap:8px; padding:0 0 12px; }
.pos-app .console .filters > * { padding:7px 10px; border-radius:6px; }
.pos-app .console .filters .on { background:#eaf1ff; color:#245bb0; }
@media(min-width:761px) {
 .pos-app > [role="status"] { position:sticky; top:0; height:26px; }
 .pos-app:has(> [role="status"]) .pos-topbar { top:26px; }
}
@media(max-width:760px) {
 .pos-app .console :is(.order-controls,.order-summary,.order-intake:not(:empty),.order-detail-layout > div) { padding:16px; }
}
@media(min-width:1100px) and (max-width:1599px) {
 .pos-app .logistics-stats { grid-template-columns:repeat(5,minmax(0,1fr)); }
}
@media(min-width:761px) and (max-width:1099px) {
 .pos-app .logistics-stats { grid-template-columns:repeat(3,minmax(0,1fr)); }
}
@media(max-width:760px) {
 .pos-app main.container .ops-table-wrap > table { min-width:640px; }
}

/* Reusable stacked forms for operations controls. */
.ops-form-stack { display:grid; gap:16px; max-width:720px; }
.ops-form-stack > label { display:grid; gap:7px; font-size:13px; }
.ops-form-stack :is(input,textarea,select) { width:100%; min-width:0; box-sizing:border-box; }
.ops-form-stack > .btn { justify-self:start; }
.ops-form-stack > p { margin:0; }

.pos-app .console .order-management > summary { cursor:pointer; font-size:14px; font-weight:600; padding:4px 0; }
.pos-app .console .order-management:not([open]) > .order-management-body { display:none; }
.pos-app .console .order-management-body { padding-top:18px; }
.pos-app .console .order-management-body > h2 { margin-top:24px; border-top:1px solid var(--c-line); padding-top:18px; }
.pos-app .console .title-row { margin:12px 0 18px; }

.pos-app .console .layout.order-detail-layout { grid-template-columns:minmax(0,1fr); }




/* Laundromat receipt and intake: one action per order, no customer details. */
.shop-intake { max-width:1440px; margin:0 auto; }
.shop-workspace-heading { display:flex; align-items:center; justify-content:space-between; gap:20px; margin:4px 0 28px; }
.pos-app main.container .shop-workspace-heading h1 { margin:6px 0 8px; font-size:28px; line-height:1.2; font-weight:750; letter-spacing:-.025em; }
.shop-workspace-heading p { margin:0; color:var(--c-muted); font-size:13px; }
.shop-workspace-heading .eyebrow { font-size:10px; font-weight:650; letter-spacing:.09em; text-transform:uppercase; }
.shop-eyebrow-dot { margin:0 7px; }
.shop-stats { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; margin-bottom:26px; }
.pos-app main.container .shop-stat { display:grid; grid-template-columns:42px 1fr auto; grid-template-rows:auto auto; column-gap:13px; row-gap:3px; text-decoration:none; color:var(--c-ink); margin:0; transition:border-color .15s,background .15s; }
.pos-app main.container .shop-stat:hover,.pos-app main.container .shop-stat[aria-current] { border-color:#8eb2ee; background:#fbfdff; }
.shop-stat-icon { display:grid; place-items:center; width:42px; height:42px; border-radius:10px; grid-row:1/3; align-self:center; }
.shop-stat-label { font-size:11px; color:#607089; line-height:1.5; }
.shop-stat strong { grid-column:2; font-size:26px; line-height:1.1; font-weight:750; font-variant-numeric:tabular-nums; }
.shop-stat-arrow { color:#8390a3; grid-column:3; grid-row:1/3; align-self:center; }
.shop-status { display:inline-flex; width:fit-content; align-items:center; gap:6px; padding:5px 9px; border-radius:6px; font-size:11px; font-weight:650; white-space:normal; line-height:1.4; }
.shop-status::before { content:''; width:5px; height:5px; background:currentColor; border-radius:50%; flex-shrink:0; }
.shop-status--incoming { color:#245bb0; background:#edf3ff; }
.shop-status--intake { color:#93610b; background:#fff6df; }
.shop-status--wash { color:#6650ab; background:#f1edfc; }
.shop-status--ready { color:#167463; background:#e5f5ef; }
.pos-app main.container .shop-orders-panel { padding:0!important; overflow:hidden; }
.shop-panel-heading { display:flex; align-items:center; justify-content:space-between; gap:20px; padding:22px 24px; }
.shop-panel-heading h2,.shop-order-sidebar h2 { font-size:15px; margin:0 0 5px; font-weight:700; }
.shop-panel-heading p { margin:0; color:var(--c-muted); font-size:12px; }
.shop-search { display:flex; align-items:center; gap:8px; margin:0; flex-shrink:0; }
.pos-app main.container .shop-search input { width:225px; min-height:42px; }
.pos-app.ops-touch main.container .shop-search .btn { min-height:42px; }
.shop-filters { display:flex; gap:22px; padding:0 24px; border-bottom:1px solid var(--c-line); overflow-x:auto; }
.shop-filter { display:flex; align-items:center; gap:7px; border-bottom:2px solid transparent; padding:11px 0 14px; font-size:12px; color:#65738a; text-decoration:none; white-space:nowrap; }
.shop-filter:hover { color:#245bb0; text-decoration:none; }
.shop-filter.is-active { color:#245bb0; font-weight:650; border-bottom-color:#306bd0; }
.shop-filter span { background:#f0f3f8; border-radius:5px; padding:1px 6px; font-size:10px; }
.shop-filter.is-active span { background:#eaf1ff; }
.shop-order-head,.shop-order-row { display:grid; grid-template-columns:minmax(185px,1.4fr) minmax(135px,1fr) minmax(115px,1fr) 65px minmax(130px,.9fr); gap:16px; align-items:center; padding:16px 24px; }
.shop-order-head { background:#f8fafd; color:#68778e; font-size:10px; letter-spacing:.05em; text-transform:uppercase; font-weight:650; border-bottom:1px solid #e8edf4; }
.shop-order-row { border-bottom:1px solid #edf0f5; color:#253247; text-decoration:none; min-height:88px; }
.shop-order-row:hover { background:#f8fbff; text-decoration:none; color:#253247; }
.shop-order-identity { display:flex; align-items:center; gap:12px; min-width:0; }
.shop-order-icon { color:#6d819e; display:grid; place-items:center; background:#f2f5fa; width:36px; height:40px; border:1px solid #e6ebf3; border-radius:8px; flex-shrink:0; }
.shop-order-identity strong { font-size:13px; font-weight:650; }
.shop-order-row small { display:block; color:#6a798e; font-size:11px; line-height:1.5; margin-top:4px; overflow-wrap:anywhere; }
.shop-order-driver span { font-size:12px; }
.shop-order-weight { font-weight:650; font-size:13px; font-variant-numeric:tabular-nums; }
.shop-order-weight small { display:inline; font-weight:400; }
.shop-order-action { display:flex; justify-content:flex-end; align-items:center; gap:12px; color:#245bb0; font-size:12px; font-weight:650; }
.shop-order-row .shop-review-flag { color:#ae402d; }
.shop-list-footer { display:flex; justify-content:space-between; gap:12px; padding:14px 24px; font-size:11px; color:#758197; }
.shop-empty { display:flex; flex-direction:column; align-items:center; padding:52px 20px; text-align:center; color:#77869b; }
.shop-empty > svg { width:34px; height:34px; margin-bottom:12px; }
.shop-empty h3 { font-size:15px; color:#33435c; margin:0 0 6px; }
.shop-empty p { font-size:12px; margin:0 0 16px; }
.shop-intake-detail { max-width:1160px; margin:0 auto; }
.shop-back { display:inline-flex; margin-bottom:24px; font-size:12px; text-decoration:none; color:#65738a; }
.shop-detail-grid { display:grid; grid-template-columns:minmax(0,1.8fr) minmax(265px,1fr); align-items:start; gap:24px; }
.pos-app main.container .shop-intake-panel { padding:28px!important; margin:0; }
.shop-intake-panel h2 { font-size:20px; line-height:1.3; margin:0 0 12px; font-weight:700; letter-spacing:-.015em; }
.shop-intake-panel p { max-width:none; font-size:13px; line-height:1.65; }
.shop-intake-panel > p { color:#58677d; }
.shop-intake-panel form { margin:24px 0 0; }
.shop-intake-inputs { display:grid; grid-template-columns:1fr; gap:18px; }
.shop-intake-panel .field { margin:0; }
.pos-app main.container .shop-intake-panel .field-label { font-size:12px; font-weight:600; text-transform:none; letter-spacing:0; }
.pos-app main.container .shop-intake-panel .input { width:100%; min-height:52px; font-size:17px; }
.shop-field-help { margin:10px 0 22px; font-size:11px!important; color:#718098; }
.shop-intake-panel .btn-primary { width:100%; font-size:13px!important; min-height:50px!important; }
.shop-intake-panel form + .muted { margin-top:14px; font-size:11px; text-align:center; }
.shop-order-sidebar { display:grid; gap:20px; }
.shop-order-sidebar .card { margin:0; }
.shop-progress { list-style:none; padding:0; margin:24px 0 0; }
.shop-progress li { display:flex; position:relative; gap:13px; min-height:67px; color:#8090a5; }
.shop-progress li:last-child { min-height:36px; }
.shop-progress li:not(:last-child)::after { content:''; position:absolute; top:30px; bottom:7px; left:14px; border-left:1px solid #e1e7ef; }
.shop-progress li > span { display:grid; place-items:center; width:29px; height:29px; border-radius:50%; border:1px solid #dfe5ee; background:#f8fafd; font-size:11px; flex-shrink:0; }
.shop-progress strong { display:block; font-size:12px; font-weight:600; }
.shop-progress small { display:block; margin-top:3px; font-size:10px; }
.shop-progress .is-complete { color:#58766d; }
.shop-progress .is-complete > span { color:#167463; background:#e5f5ef; border-color:#d3ebe2; }
.shop-progress .is-current { color:#245bb0; }
.shop-progress .is-current > span { background:#306bd0; color:white; border-color:#306bd0; }
.shop-handover p { color:#65738a; font-size:12px; line-height:1.65; }
.shop-handover > a { font-size:12px; font-weight:600; text-decoration:none; }
.shop-icon { display:grid; place-items:center; width:38px; height:38px; color:#5275a8; background:#eef3fb; border-radius:9px; flex-shrink:0; }
.shop-handover .shop-icon { margin-bottom:15px; }
.shop-reference { font-family:var(--font-body); font-size:12px; overflow-wrap:anywhere; background:#f5f7fb; border:1px solid #e7ecf4; border-radius:7px; padding:10px 12px; }
.shop-courier { display:flex; align-items:center; gap:12px; margin:20px 0; }
.shop-courier strong { font-size:13px; }
.shop-courier p { margin:2px 0 0; color:#65738a; font-size:12px; }
.shop-intake-facts { display:grid; grid-template-columns:1fr 1fr; gap:20px; padding:0 0 24px; margin:0 0 24px; border-bottom:1px solid #e7ecf4; }
.shop-intake-facts dt { font-size:11px; color:#6b7a90; }
.shop-intake-facts dd { margin:6px 0 0; font-size:23px; color:#253247; font-weight:700; overflow-wrap:anywhere; }
.pos-app main.container .shop-intake-panel .ops-table { min-width:0; }
.shop-intake-panel .ops-table th,.shop-intake-panel .ops-table td { padding:13px 15px; font-size:12px; }
.shop-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; }
@media(max-width:1250px) {
 .shop-stats { gap:12px; }
 .pos-app main.container .shop-stat { grid-template-columns:1fr auto; gap:8px; }
 .shop-stat-icon { width:32px; height:32px; grid-column:2; grid-row:1/3; }
 .shop-stat-label,.shop-stat strong { grid-column:1; }
 .shop-stat-arrow { display:none; }
 .shop-panel-heading { align-items:flex-start; flex-direction:column; }
 .shop-order-head,.shop-order-row { grid-template-columns:minmax(155px,1.2fr) minmax(125px,1fr) minmax(110px,1fr) minmax(120px,1fr); gap:12px; }
 .shop-order-head > :nth-child(4),.shop-order-weight { display:none; }
}
@media(max-width:900px) {
 .shop-detail-grid { grid-template-columns:minmax(0,1fr); }
 .shop-order-sidebar { grid-template-columns:1fr 1fr; }
 .shop-order-driver,.shop-order-head > :nth-child(3) { display:none; }
 .shop-order-head,.shop-order-row { grid-template-columns:minmax(155px,1.2fr) minmax(125px,1fr) minmax(120px,1fr); }
}
@media(max-width:600px) {
 .shop-workspace-heading { align-items:flex-start; flex-wrap:wrap; gap:14px; }
 .pos-app main.container .shop-workspace-heading h1 { font-size:26px; }
 .shop-workspace-heading .eyebrow { font-size:9px; }
 .shop-workspace-heading > .btn { min-height:40px!important; }
 .shop-stats { grid-template-columns:1fr 1fr; gap:10px; margin-bottom:20px; }
 .pos-app main.container .shop-stat { padding:16px!important; }
 .shop-stat strong { font-size:24px; }
 .shop-stat-label { font-size:10px; }
 .shop-panel-heading { padding:18px 16px; }
 .shop-search { width:100%; }
 .pos-app main.container .shop-search input { width:100%; min-width:0; }
 .shop-filters { padding:0 16px; gap:18px; }
 .shop-order-head { display:none; }
 .shop-order-row { grid-template-columns:minmax(0,1fr) auto; padding:18px 16px; gap:12px; }
 .shop-order-identity { grid-column:1/3; }
 .shop-order-status { grid-column:1; }
 .shop-order-action { grid-column:2; font-size:11px; gap:5px; }
 .shop-order-row .shop-status { font-size:10px; }
 .shop-list-footer { padding:14px 16px; flex-wrap:wrap; font-size:10px; }
 .shop-detail-grid { gap:18px; }
 .pos-app main.container .shop-intake-panel { padding:20px!important; }
 .shop-intake-inputs { grid-template-columns:1fr; }
 .shop-order-sidebar { grid-template-columns:1fr; }
 .shop-back { margin-bottom:20px; }
 .shop-intake-facts dd { font-size:20px; }
}

/* Order overview: pickup, destination and saved/proposed pricing */
.order-overview{background:#fff;border:1px solid #dbe4f0;border-radius:14px;padding:24px;margin:20px 0}.order-overview h2{font-size:20px;margin:0 0 20px}.order-overview h3{font-size:16px;margin:0 0 14px}.order-overview-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:28px}.order-overview dl{margin:0 0 18px}.order-overview dl>div{display:flex;justify-content:space-between;gap:24px;padding:12px 0;border-bottom:1px solid #e4eaf1}.order-overview dt{color:#52647a}.order-overview dd{margin:0;text-align:right;font-weight:600;overflow-wrap:anywhere}.order-price-panel{background:#f7f9fc;border:1px solid #e4eaf1;border-radius:10px;padding:20px}.order-overview .hint{color:#64748b;font-size:13px;line-height:1.5}.order-overview #laundromat{margin-top:14px}.order-overview #laundromat~h2{display:none}@media(max-width:900px){.order-overview-grid{grid-template-columns:1fr}.order-overview{padding:18px}}

/* Three operational queues; incoming delivery information leads the board. */
.shop-stats.shop-stats-three { grid-template-columns:repeat(3,minmax(0,1fr)); }
.shop-board-toolbar { display:flex; justify-content:space-between; align-items:center; gap:20px; margin:0 0 22px; }
.shop-board-toolbar p { font-size:12px; color:#60718a; margin:0; }
.shop-delivery-section { margin-bottom:26px!important; scroll-margin-top:100px; }
.shop-section-count { color:#5a6c88; background:#eef3fb; padding:2px 8px; border-radius:6px; font-size:13px; margin-left:7px; }
.shop-delivery-scroll { overflow-x:auto; }
.shop-delivery-table { width:100%; border-collapse:collapse; min-width:680px; text-align:left; }
.shop-delivery-table thead { background:#f7f9fc; }
.shop-delivery-table thead th { padding:13px 24px; font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:.055em; color:#5d6e86; border-block:1px solid #e6ecf5; }
.shop-delivery-table tbody td,.shop-delivery-table tbody th { padding:20px 24px; border-bottom:1px solid #edf0f5; font-size:13px; font-weight:400; vertical-align:middle; }
.shop-delivery-table tbody th { font-size:15px; font-weight:700; }
.shop-delivery-table tbody tr:last-child>* { border-bottom:0; }
.shop-delivery-table small { display:block; margin-top:5px; color:#7c899e; font-size:11px; }
.shop-delivery-table .shop-section-empty { text-align:center; padding:35px 20px; color:#7c899e; }
.shop-driver-call { display:block; margin-top:6px; font-size:12px; }
.shop-delivery-table a[aria-disabled="true"] { pointer-events:none; opacity:.5; }
.shop-delivery-table button[disabled] { opacity:.55; cursor:not-allowed; }
.shop-confirm-handover { display:flex; gap:12px; align-items:flex-start; font-size:13px; line-height:1.6; }
.shop-confirm-handover input { width:18px; height:18px; flex-shrink:0; margin-top:2px; }
.shop-board-toolbar #shop-sync-note { max-width:48%; }
#shop-board-live.is-stale .shop-delivery-status { opacity:.6; }
@media(max-width:700px) {
 .shop-stats.shop-stats-three { grid-template-columns:1fr; }
 .shop-board-toolbar { flex-direction:column; align-items:stretch; }
 .shop-board-toolbar #shop-sync-note { max-width:none; }
 .shop-board-toolbar .shop-search { width:100%; }
 .shop-board-toolbar .shop-search input { min-width:0; width:100%; }
 .shop-delivery-table thead th,.shop-delivery-table tbody td,.shop-delivery-table tbody th { padding:14px 16px; }
}

/* Return dispatch belongs beside the READY order, where the missing driver is visible. */
.order-return-dispatch { margin-top: 20px; }
.order-return-dispatch h2 { margin: 4px 0 8px; }
.order-return-dispatch-actions { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 16px; margin-top: 18px; align-items: end; }
.order-return-dispatch-actions form { margin: 0; }
.order-return-dispatch-actions .btn { width: 100%; min-height: 44px; }
.order-return-inhouse { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 10px; align-items: end; }
.order-return-inhouse label { display: grid; gap: 6px; font-weight: 700; }
.order-return-inhouse select { min-height: 44px; padding: 8px 10px; border: 1px solid var(--c-line); border-radius: 6px; background: white; font: inherit; }
@media (max-width: 760px) { .order-return-dispatch-actions { grid-template-columns: 1fr; } .order-return-inhouse { grid-template-columns: 1fr; } }

/* Delivery proof remains beside the intake form so the bags can be matched. */
.shop-delivery-proof figure { margin:16px 0 0; }
.shop-delivery-proof img { display:block; width:100%; max-height:320px; object-fit:contain; border:1px solid #dfe6f0; border-radius:10px; background:#f6f8fb; }
.shop-delivery-proof img[hidden],.shop-delivery-proof p[hidden] { display:none; }
.shop-delivery-proof a { display:block; }
.shop-delivery-proof a span { display:block; margin-top:9px; font-size:12px; }
.shop-delivery-proof p { font-size:13px; color:#58677d; }
