/* CREAM AND NAVY, BY DAY. WARM CHARCOAL AND A LIFTED BLUE, BY NIGHT.

     #f4efe4   the cream the page is made of
     #fffdf8   a warm white for the cards on it — not #ffffff, which reads as a hole in the paper
     #241f17   warm ink; a neutral near-black on cream looks like a printing error
     #34495e   the navy of the company site's Quote button — the accent, and the only thing pressed
     #8caee8   that same navy lifted, for the dark theme, where the navy itself is a smudge

   Two rules hold the whole palette together.

   THE ACCENT IS ONE HUE AT TWO LIGHTNESSES, not two colours. Light and dark are the same product in
   two rooms, so the accent moves in lightness only. What flips with it is --on-accent: the ink that
   sits on a filled button is white on the navy and near-black on the lifted blue, because white on
   #8caee8 measures 2.2:1.

   GREEN MEANS "IN ORDER" AND NOTHING ELSE. It was the accent here for a long time, which meant every
   button and every healthy status wore the same colour and neither one said anything. It now appears
   on a status pill and nowhere else.

   The measurements that drove it: white on #34495e is 9.29:1, where white on the old #008361 accent
   was 3.18:1 — the one pair the previous palette never passed. */
:root {
  /* Native controls — the date picker above all — paint themselves from this, not from our
     tokens. Without it a date field renders as a white pill on a dark page. */
  color-scheme: light;

  /* Deep greens where the navy used to be. Nothing paints a dark chrome any more — the sidebar that
     used them is gone — but they stay defined and in-palette so a stray reference cannot bring the
     old blue back on its own. */
  /* The slate the site's hero gradient falls to, and the navy of its Quote button. These replace the
     deep greens: the website uses green as the GROUND and navy as the thing you press, which is the
     opposite way round from where this portal started. */
  /* The dark panels — the sign-in hero, the tenant plate. Navy rather than the old deep green: on a
     cream page a green block reads as a status, and navy is what the company's own site puts on the
     thing it wants pressed. */
  --navy-950: #1c2a38;
  --navy-900: #263849;
  --navy-800: #34495e;
  --slate: #6a85b6;

  /* Warm ink. A neutral near-black on cream looks like a printing error — the page is warm, so the
     text on it has to be, or the two never settle. */
  --ink-900: #241f17;
  --ink-700: #4b4338;
  --ink-500: #6f6759;
  /* A hairline with the cream in it rather than a grey, so a card edge belongs to the page. */
  --line: #e2d9c7;

  /* Cream, and a warm white for the cards over it. Not #ffffff: pure white on cream reads as a hole
     punched in the page, where a warm white reads as paper on paper. */
  --surface: #fffdf8;
  --surface-soft: #f4efe4;
  --surface-alt: #faf6ec;
  --surface-blue: #eaeef5;

  /* Navy on cream. White on #34495e is 9.29:1 — the old green managed 3.18:1, which is the one pair
     the previous palette never passed. */
  --primary: #34495e;
  --primary-dark: #263849;

  /* The three states. Each is dark enough to be read as TEXT on its own pale fill, which is what a
     status pill actually is — not a colour with words near it. */
  --good: #1a6b43;
  --good-soft: #e6efe2;
  --warn: #8a5200;
  --warn-soft: #f7ecd9;
  --bad: #a8291f;
  --bad-soft: #f9e9e6;
  --info-soft: #eaeef5;
  /* The fourth state: nothing recorded yet. Warm, like the rest of the page — the cold grey it
     replaced was the only colour on this palette that came from nowhere. */
  --muted: #544e44;
  --muted-soft: #ece6da;
  /* The mark, washed over the page. This is a CONTRAST BUDGET, not a taste setting: the overlay
     lands on the ink and on what is under it alike. Swept against the rendered tree — light
     breaks at 0.10 and holds at 0.08; this sits at 0.06 so the pages I could not sign in to
     have room too. Raising it means re-running that sweep. */
  --watermark: rgba(36, 31, 23, 0.06);
  /* The edge of a state panel. The fills were tokens and the borders were literals, which is why
     six rules carried a hex value: there was nothing to name them with. */
  --warn-line: #e6cfa6;
  --bad-line: #ecb8b1;
  --info-line: #c8d2e2;
  /* The ink that sits ON a filled accent — a primary button, a danger button, a filled icon. It is
     not a text colour and not a surface; it belongs to the fill. */
  --on-accent: #ffffff;
  /* The accent seen faintly: focus rings, the glow under a raised button. Eleven rules had the old
     green spelled out as rgba(0,131,97,…), which is how a palette change leaves a trail of the
     previous one behind it. */
  --accent-glow: rgba(52, 73, 94, 0.20);
  --accent-glow-strong: rgba(52, 73, 94, 0.32);
  --shadow: 0 18px 50px rgba(74, 58, 33, 0.10);
  --radius: 18px;
  --radius-sm: 10px;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--ink-900);
  background: var(--surface-soft);
  font-synthesis: none;
}

* { box-sizing: border-box; }
html { min-height: 100%; background: var(--surface-soft); }
body {
  min-height: 100vh;
  margin: 0;
  /* A warm haze at the top right — the cream concentrated rather than a second colour laid over it.
     Kept faint: this is a working screen, and a full-strength gradient behind a table is unreadable. */
  background: radial-gradient(circle at top right, rgba(198, 173, 126, 0.26), transparent 34rem), var(--surface-soft);
}
button, input, select { font: inherit; }
a { color: inherit; text-decoration: none; }
code { padding: .12rem .35rem; border-radius: 6px; background: var(--surface-alt); font-size: .9em; }
button:disabled { cursor: not-allowed; opacity: .58; }

.boot-screen, .loading-state {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  min-height: 100vh;
  color: var(--ink-700);
}
.boot-screen p { margin: .25rem 0 0; color: var(--ink-500); }

.brand-mark {
  display: inline-grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 16px;
  background: linear-gradient(135deg, var(--slate), var(--navy-800));
  color: white;
  font-weight: 800;
  letter-spacing: .03em;
  box-shadow: 0 10px 28px var(--accent-glow-strong);
}
.brand-mark.small { width: 2.3rem; height: 2.3rem; border-radius: 11px; font-size: .82rem; }

/* THE MARK, where the plate above is carrying the PRODUCT rather than a tenant.
   The green tile exists because the old brand was two letters, and letters need something to sit on.
   This one is a shape and wants the ground it is on — so the plate, its gradient and its shadow all
   come off, and only the initials-in-a-tile case keeps them.

   Inlined into the markup rather than loaded through <img>: an SVG behind <img> is its own document,
   inherits no colour, and the currentColor version rendered black on black the first time. */
.brand-mark-logo {
  background: none;
  box-shadow: none;
  color: var(--ink-900);
  border-radius: 0;
}
.brand-mark-logo .mark { display: block; width: 100%; height: 100%; }
/* On the dark half of the sign-in split, where the ink token would disappear into the panel. */
.auth-visual .brand-mark-logo { color: #ffffff; }

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.65rem;
  padding: .7rem 1rem;
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  font-weight: 700;
  transition: transform 140ms ease, box-shadow 140ms ease, background 140ms ease;
}
/* `display: inline-flex` above beats the browser's own `[hidden] { display: none }`, so a button
   hidden in JavaScript stayed on screen. Found on the driver hero, where the Edit control sat there
   with the form it had opened - and it was already live on the sales invoice screen, where "Retry
   save" showed permanently beside "All changes saved". The same bug had been patched one-off three
   times elsewhere (.drawer, .drawer-scrim, .walkaround-books). This is the general case. */
.button[hidden] { display: none; }
.button:hover:not(:disabled) { transform: translateY(-1px); }
.button-primary { color: var(--on-accent); background: var(--primary); box-shadow: 0 8px 20px var(--accent-glow); }
.button-primary:hover:not(:disabled) { background: var(--primary-dark); }
.button-secondary { color: var(--ink-900); background: var(--surface); border-color: var(--line); }
.button-ghost { color: rgba(255,255,255,.76); background: transparent; border-color: rgba(255,255,255,.18); }
.button-ghost.light { color: var(--ink-700); border-color: var(--line); }
/* .button-ghost is WHITE INK, drawn for a dark panel, and `.light` has to be remembered every time it
   is used anywhere else. It was forgotten on the Remove button of Work history and of Fleet, so both
   were white on cream: the owner's words were "sunt butoane care nu se vad ceva delete". The same
   thing had already been patched one-off for the drawer's Sign out (see .drawer-footer below), which
   is the tell that remembering a modifier is not a mechanism. A cream panel or an auth card now
   supplies the ink itself, so the next one cannot go missing. */
.panel .button-ghost:not(.light), .auth-form .button-ghost:not(.light) { color: var(--ink-700); border-color: var(--line); }
.panel .button-ghost:not(.light):hover, .auth-form .button-ghost:not(.light):hover { color: var(--ink-900); border-color: var(--ink-500); }
.full-width { width: 100%; }
.text-button { display: inline; padding: 0; border: 0; color: var(--primary); background: transparent; cursor: pointer; font-weight: 700; }

.eyebrow { display: block; margin-bottom: .45rem; color: var(--primary); font-size: .73rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.muted { color: var(--ink-500); }
.security-note { margin: 0; padding: .85rem 1rem; border: 1px solid var(--info-line); border-radius: 10px; color: var(--ink-500); background: var(--info-soft); font-size: .83rem; line-height: 1.5; }

.auth-page { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(24rem, .85fr); min-height: 100vh; }
.auth-panel { padding: clamp(2rem, 5vw, 5rem); }
.auth-visual {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  color: white;
  background: linear-gradient(145deg, rgba(28,42,56,.98), rgba(19,29,39,.96)), radial-gradient(circle at 80% 20%, var(--slate) 0, transparent 26rem);
}
.auth-visual::after {
  position: absolute;
  right: -12rem;
  bottom: -12rem;
  width: 32rem;
  height: 32rem;
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 50%;
  content: "";
  box-shadow: 0 0 0 5rem rgba(255,255,255,.025), 0 0 0 10rem rgba(255,255,255,.018);
}
.auth-brand, .driver-brand { display: flex; align-items: center; gap: .8rem; }
.auth-brand { position: relative; z-index: 1; gap: 1rem; }
.auth-brand strong, .driver-brand strong { display: block; }
.auth-brand small, .driver-brand small { display: block; margin-top: .18rem; color: rgba(255,255,255,.62); }
.auth-copy { position: relative; z-index: 1; max-width: 48rem; }
.auth-copy .eyebrow { color: #8eb7ff; }
.auth-copy h1 { max-width: 45rem; margin: 0 0 1.25rem; font-size: clamp(2.5rem, 5vw, 5rem); line-height: 1; letter-spacing: -.055em; }
.auth-copy > p { max-width: 43rem; color: rgba(255,255,255,.74); font-size: 1.08rem; line-height: 1.7; }
.auth-feature-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .85rem; margin-top: 2rem; }
.auth-feature-grid > div { padding: 1rem; border: 1px solid rgba(255,255,255,.09); border-radius: 12px; background: rgba(255,255,255,.05); backdrop-filter: blur(10px); }
.auth-feature-grid strong, .auth-feature-grid span { display: block; }
.auth-feature-grid span { margin-top: .3rem; color: rgba(255,255,255,.62); font-size: .82rem; }
.auth-form-panel { display: grid; place-items: center; background: var(--surface); }
.auth-form { display: grid; gap: 1.15rem; width: min(100%,28rem); }
.auth-form h2 { margin: 0; font-size: 2rem; letter-spacing: -.035em; }
.auth-form p { margin: .4rem 0 0; color: var(--ink-500); line-height: 1.55; }
.auth-form label { display: grid; gap: .45rem; color: var(--ink-700); font-size: .87rem; font-weight: 700; }
.auth-form input, .filter-bar input, .filter-bar select, .compact-select { width: 100%; min-height: 2.8rem; padding: .75rem .85rem; border: 1px solid var(--line); border-radius: 10px; outline: none; color: var(--ink-900); background: var(--surface); }
.auth-form input:focus, .filter-bar input:focus, .filter-bar select:focus, .compact-select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--accent-glow); }
.form-message { padding: .8rem 1rem; border-radius: 10px; font-size: .87rem; }
.form-message.success { color: var(--good); background: var(--good-soft); }
.form-message.error { color: var(--bad); background: var(--bad-soft); }
/* Not an error and not a success: a refusal the applicant can do nothing about and does not need
   to worry about — "you have already registered". Red would tell them something went wrong. */
.form-message.info { color: var(--ink-700); background: var(--bg-sunken, #f6f7f9); }

.configuration-page { display: grid; place-items: center; min-height: 100vh; padding: 2rem; }
.configuration-card { width: min(100%,42rem); padding: clamp(1.5rem,5vw,3rem); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.configuration-card h1 { margin: 1.3rem 0 .7rem; letter-spacing: -.035em; }
.configuration-card p, .configuration-card li { color: var(--ink-700); line-height: 1.65; }

/* ---- the shell: a bar, and a menu that comes in from the left ---------------------------------------
   This was a 17rem rail welded to the page, holding eighteen destinations in one flat column. It spent
   a third of a laptop screen on a list nobody reads twice, and the ☰ that was meant to put it away
   existed only below 900px — so at a desk, where the portal is actually used, it could not be closed
   at all.
   It became the driver app's pattern at every width: the bar says where you are and who you are, and
   the menu is somewhere you go, grouped, and then leave.

   2026-09-11 — IT CAME BACK BESIDE THE PAGE, FOLDED. The owner asked for the sidebar with its groups as
   dropdowns, and to leave the colours alone. Folded it is ten rows until opened, not thirty-nine, and ☰
   puts it away at every width and remembers — both reasons the rail went are answered. Docked from
   1180px; narrower, or in the phone layout, it is the drawer still. nav-menu.js decides. */
/* 280px, not 17.5rem: the planner's docked breakpoint is 1150px plus this, and a rem grows with the
   browser's font size while a media query's pixels do not. */
.portal-shell { --nav-w: 280px; display: flex; flex-direction: column; min-height: 100vh; }

/* THE MARK, GHOSTED ACROSS EVERY SIGNED-IN PAGE.

   IT SITS OVER THE CONTENT, NOT BEHIND IT. Behind was the obvious way and it does not work: this
   portal's pages are wall-to-wall cards, each with an opaque background, so a mark underneath them
   is covered everywhere except a few 20px gutters — measured, and it was invisible on a normal
   screen. A watermark on paper is over the print, and so is this one.

   That means the alpha is not a taste decision, it is a contrast budget: everything on the page gets
   this colour laid over it, foreground and background alike. The value below is the largest one at
   which nothing in the rendered tree drops under 4.5:1 — checked by walking the page, not by eye.

   Drawn with a MASK rather than a background image, for the reason recorded when the favicon went
   black on black: an SVG referenced by url() is its own document and inherits nothing, so
   `currentColor` inside it resolves to black and the mark would stay dark on the dark theme. A mask
   has no colour of its own — it cuts the shape out of `background`, which is a token here.

   Fixed, so it sits still while the page scrolls under it — a watermark that scrolls is just a very
   large picture of a letter, and you notice it. pointer-events: none, or it would swallow every
   click on the page. z-index 5 keeps it under the topbar (20), the drawer (40) and modals (1000):
   a ghost over a dialog is a smudge on the thing you are trying to read. */
.portal-shell::before {
  content: none;
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background: var(--watermark);
  --mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 6 L95 94 L83.55 94 L50 28.39 L16.45 94 L5 94 Z'/%3E%3C/svg%3E");
  -webkit-mask: var(--mark) no-repeat center 58% / min(78vmin, 40rem) auto;
  mask: var(--mark) no-repeat center 58% / min(78vmin, 40rem) auto;
}

/* No ghost on paper, none in high-contrast mode, and none over a page the user is trying to read at
   a phone size, where 78vmin of letter across a narrow column stops being a watermark. */
@media print { .portal-shell::before { display: none; } }
@media (forced-colors: active) { .portal-shell::before { display: none; } }
@media (max-width: 700px) { .portal-shell::before { display: none; } }
.workspace { min-width: 0; }

.topbar-menu {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 2.75rem; height: 2.75rem; margin-left: -.4rem; padding: 0;
  border: none; border-radius: var(--radius-sm); background: none;
  color: var(--ink-900); cursor: pointer;
}
.topbar-menu:hover { background: var(--surface-soft); }
.topbar-menu:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.topbar-menu-bars { display: flex; flex-direction: column; gap: 4px; width: 1.15rem; }
.topbar-menu-bars span { display: block; height: 2px; border-radius: 2px; background: currentColor; }

.icon { width: 1.25rem; height: 1.25rem; flex: none; }

.drawer-scrim { position: fixed; inset: 0; z-index: 40; background: rgba(38, 30, 18, .42); }
.drawer-scrim[hidden] { display: none; }

.drawer {
  position: fixed; z-index: 41; top: 0; bottom: 0; left: 0;
  display: flex; flex-direction: column;
  /* Over the page the whole drawer scrolls, as it always has, at the width it always had — a narrower
     one wrapped the product's name onto two lines. Docked, it is the menu's width and only the list
     scrolls (below). The safe-area inset used to be a second .drawer rule 2,400 lines down that quietly
     zeroed the top padding on every desk. */
  width: min(20rem, 86vw); padding: calc(.75rem + env(safe-area-inset-top)) .75rem 1rem;
  overflow-y: auto;
  background: var(--surface);
  border-right: 1px solid var(--line);
  box-shadow: 12px 0 44px rgba(38, 30, 18, .16);
}
.drawer[hidden] { display: none; }

.drawer-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; padding: .25rem .3rem 1.1rem; }
.drawer-brand { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.drawer-brand strong { display: block; font-size: .95rem; letter-spacing: -.02em; }
.drawer-brand small { display: block; margin-top: .1rem; color: var(--ink-500); font-size: .75rem; }
.drawer-close {
  flex: none; width: 2.2rem; height: 2.2rem; padding: 0;
  border: none; border-radius: var(--radius-sm); background: none;
  color: var(--ink-500); font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.drawer-close:hover { background: var(--surface-soft); color: var(--ink-900); }

.drawer-groups {
  display: flex; flex-direction: column; gap: 2px;
  /* Room for a focus ring without clipping it. */
  margin: 0 -.35rem; padding: 0 .35rem .5rem;
}
.drawer-group { display: flex; flex-direction: column; gap: 1px; padding-bottom: .85rem; }
/* The label is the whole point of the grouping, so it has to be readable as a heading and not as a
   dimmer menu item — hence the size, the weight and the tracking rather than just a lighter grey. */
.drawer-group-label {
  padding: .55rem .55rem .3rem;
  color: var(--ink-500); font-size: .68rem; font-weight: 800;
  letter-spacing: .09em; text-transform: uppercase;
}
.drawer-link {
  display: flex; align-items: center; gap: .75rem;
  /* 44px. Measured at 41.6 first, which is under the smallest thing a finger reliably hits — and the
     portal is opened on a phone often enough that the user chip is hidden below 900px for it. */
  min-height: 2.75rem; padding: 0 .55rem; border-radius: var(--radius-sm);
  color: var(--ink-900); font-size: .9rem; font-weight: 600;
}
.drawer-link .icon { flex: none; width: 1.2rem; height: 1.2rem; color: var(--ink-500); }
.drawer-link:hover { background: var(--surface-soft); }
/* Where you are is said three ways — a tinted panel, the accent ink, and the icon lighting up —
   because on a list this long a single change of shade is not something you find at a glance. */
.drawer-link.active { color: var(--primary-dark); background: var(--surface-blue); font-weight: 750; }
.drawer-link.active .icon { color: var(--primary); }
.drawer-link:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }

.drawer-footer { display: grid; gap: .3rem; flex: none; margin-top: auto; padding-top: .75rem; border-top: 1px solid var(--line); }
/* Rows rather than three bordered buttons: beside the page, the foot of the menu is on screen all day
   and must not out-shout it. In the colours they always had — navy, and the blue tint on hover. The
   owner said to leave the colours alone, and the first draft of this rule had put them in ink. Their
   text stands in the column every row's text stands in. */
.portal-switch { display: flex; align-items: center; min-height: 2.3rem; padding: 0 .55rem 0 calc(.55rem + 1.2rem + .75rem); border-radius: var(--radius-sm); color: var(--primary-dark); font-size: .86rem; font-weight: 700; }
.portal-switch:hover { background: var(--surface-blue); }
.portal-switch:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
/* .button-ghost is white ink, drawn for the dark panels. On the drawer's warm white it was a Sign out
   button nobody could see — true before the menu folded, and it only mattered less while the drawer
   was shut. The drawer takes the ink .button-ghost.light already uses. */
.drawer-footer .button-ghost { color: var(--ink-700); border-color: var(--line); }
.drawer-footer .button-ghost:hover { color: var(--ink-900); border-color: var(--ink-500); }

/* The page behind must not scroll under an open drawer. */
body.drawer-open { overflow: hidden; }

/* ---- the menu, folded, and docked beside the page --------------------------------------------------
   nav-menu.js decides; this only draws. Every colour below is a token that was already on the page —
   the owner asked for the sidebar's shape and said to leave the colours as they are. */

/* Docked: the same element, beside the page instead of over it. */
.portal-shell.nav-docked { padding-left: var(--nav-w); }
.nav-docked .drawer { z-index: 30; width: var(--nav-w); overflow: hidden; box-shadow: none; }
/* Docked, the head and the foot stay put and only the list between them scrolls, in a thin track whose
   thumb is the page's muted ink (in the hairline colour it measured 1.4:1). The gutter is kept even when
   nothing scrolls, or every chevron jumped sideways the moment a fold made the list overflow. */
.nav-docked .drawer-groups {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--ink-500) transparent; scrollbar-gutter: stable;
  padding-right: .1rem;
}
/* The company is named at the foot of the menu, so the bar lets its label go and gives the page title
   the room: docked at 1180px the bar is only 900px wide. The switcher, where there is one, stays; and in
   a window too short to keep the foot on screen, the bar keeps the name as well. The exact opposite of the
   short-window query, so no height — a scaled screen's included — falls between the two. */
@media not all and (max-height: 36rem) {
  .nav-docked .topbar-controls .organisation-label { display: none; }
}
/* Docked, the product's name keeps to one line, even beside a scrollbar. */
.nav-docked .drawer-brand > span { min-width: 0; }
.nav-docked .drawer-brand strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-docked .drawer-close { display: none; }
/* The ghosted mark centres on the page, not half under the menu. */
.portal-shell.nav-docked::before { left: var(--nav-w); }

/* A fold: one row with its icon and a chevron, the same height and weight as a plain row, so the two
   read as one list. */
.nav-fold { display: flex; flex-direction: column; }
.nav-fold-head {
  display: flex; align-items: center; gap: .75rem; width: 100%;
  min-height: 2.75rem; padding: 0 .55rem;
  border: 0; border-radius: var(--radius-sm); background: none;
  color: var(--ink-900); font: inherit; font-size: .9rem; font-weight: 600; text-align: left;
  cursor: pointer;
}
.nav-fold-name { flex: 1; min-width: 0; }
.nav-fold-head .icon { flex: none; width: 1.2rem; height: 1.2rem; color: var(--ink-500); }
.nav-fold-head:hover { background: var(--surface-soft); }
.nav-fold-head:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.nav-chevron { flex: none; width: 1rem; height: 1rem; color: var(--ink-500); transition: transform .18s ease; }
.nav-fold.is-open > .nav-fold-head .nav-chevron { transform: rotate(90deg); }
/* Folded away, the group you are in still says so — in the tint the row you are on wears. The accent
   ink alone did not carry it on the light theme, where navy and warm ink are both nearly black. */
.nav-fold.has-active > .nav-fold-head { color: var(--primary-dark); font-weight: 700; }
.nav-fold.has-active > .nav-fold-head .icon { color: var(--primary); }
.nav-fold.has-active:not(.is-open) > .nav-fold-head { background: var(--surface-blue); }

/* Closed is out of the tab order and out of a screen reader's list, not merely out of sight — hence
   visibility and not height alone. It turns after the fold has shut, so the closing is seen. */
.nav-fold-panel {
  display: grid; grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows .2s ease, visibility 0s linear .2s;
}
.nav-fold.is-open > .nav-fold-panel { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows .2s ease, visibility 0s; }
/* The rows hang from a guide that runs down from the fold's icon. No vertical padding here: at 0fr the
   box must be able to be nothing at all, and padding would leave a sliver of it showing. */
.nav-fold-inner {
  display: flex; flex-direction: column; gap: 1px; min-height: 0; overflow: hidden;
  margin-left: calc(1.15rem - 4px); padding-left: calc(.7rem + 4px);
  background: linear-gradient(var(--line), var(--line)) no-repeat 3.5px 0 / 1px 100%;
}
.nav-fold-inner > :first-child { margin-top: 2px; }
.nav-fold-inner > :last-child { margin-bottom: .45rem; }
/* In the ink and weight every row has always had — the owner said to leave the colours alone, and a
   first draft had greyed these. A little smaller than a fold head, which says they belong to it. */
.drawer-link.nav-sub {
  position: relative; min-height: 2.35rem; padding: .35rem .6rem;
  font-size: .86rem; line-height: 1.25;
}
.drawer-link.nav-sub.active { color: var(--primary-dark); font-weight: 700; }
/* Where you are, on the guide: a dot, beside the tint the row already takes from .drawer-link.active. */
.drawer-link.nav-sub.active::before {
  content: ""; position: absolute; top: 50%; left: calc(-.7rem - 4px);
  width: 7px; height: 7px; margin-top: -3.5px; border-radius: 50%;
  background: var(--primary); box-shadow: 0 0 0 2px var(--surface);
}
/* 44px on a phone, where a finger is the pointer. (Any other touched screen: further down, after the
   docked rows it has to beat.) */
.phone-layout .drawer-link.nav-sub, .phone-layout .portal-switch { min-height: 2.75rem; }

/* Whose workspace, under the company's initials — the tenant's tile, not the product's A. */
.nav-workspace {
  display: flex; align-items: center; gap: .7rem; min-width: 0;
  padding: .45rem .5rem; border-radius: var(--radius-sm); color: var(--ink-900);
}
a.nav-workspace:hover { background: var(--surface-soft); }
a.nav-workspace:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.nav-workspace .brand-mark { flex: none; box-shadow: none; }
.nav-workspace-text { min-width: 0; }
.nav-workspace-text strong { display: block; overflow: hidden; font-size: .86rem; text-overflow: ellipsis; white-space: nowrap; }
.nav-workspace-text small { display: block; margin-top: .05rem; color: var(--ink-500); font-size: .74rem; }

@media (prefers-reduced-motion: reduce) {
  .nav-fold-panel, .nav-fold.is-open > .nav-fold-panel, .nav-chevron { transition: none; }
}

/* A window too short for the head, the foot and a list between them — a laptop at 400% zoom, a window
   with the developer tools under it. Docked, a fixed head and foot squeezed the list to nothing, so the
   whole drawer scrolls instead, as it does over the page. */
@media (max-height: 36rem) {
  .nav-docked .drawer { overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--ink-500) transparent; }
  .nav-docked .drawer-groups { flex: none; min-height: auto; overflow: visible; }
}

/* Docked beside a page and driven by a mouse, a row is 40px, and the drawer's Sign out is left to the
   one in the bar beside it. On a 1366x768 laptop the ten rows of a folded menu then fit without a
   scrollbar; with that Sign out and 44px rows they did not, even with every fold shut. */
@media (pointer: fine) {
  .nav-docked .drawer-link:not(.nav-sub), .nav-docked .nav-fold-head { min-height: 2.5rem; }
}
.nav-docked .drawer-footer [data-action="logout"] { display: none; }
.nav-docked .drawer-group { padding-bottom: .45rem; }
/* And the head and the foot tightened the same way: at 1366x650, with every fold shut, the tenth row
   was still cut in half. */
.nav-docked .drawer-head { padding-bottom: .55rem; }
@media (pointer: fine) {
  .nav-docked .portal-switch { min-height: 2rem; }
}

/* 44px wherever a finger can be the pointer — a phone, and any screen that is touched, a touchscreen
   laptop included: its primary pointer is the trackpad, so (pointer: coarse) missed it. After the
   docked 40px rows above and as specific, so a touched screen never gets them. */
@media (any-pointer: coarse) {
  .drawer-link, .drawer-link.nav-sub, .nav-fold-head, .portal-switch,
  .nav-docked .drawer-link:not(.nav-sub), .nav-docked .nav-fold-head, .nav-docked .portal-switch { min-height: 2.75rem; }
}

/* Forced colours paint over every tint, so an outline says where you are instead. */
@media (forced-colors: active) {
  .drawer-link.active, .nav-fold.has-active:not(.is-open) > .nav-fold-head { outline: 2px solid CanvasText; outline-offset: -2px; }
  .drawer-link.nav-sub.active::before { forced-color-adjust: none; background: Highlight; box-shadow: none; }
  /* Focus has to look different from "you are here", or tabbing onto the row changes nothing — and in a
     different place, not only a different colour: some contrast themes put Highlight and CanvasText under
     2:1 apart. Inside the row, clear of its text, where the fold's overflow cannot clip it. */
  .drawer-link.active:focus-visible, .nav-fold.has-active:not(.is-open) > .nav-fold-head:focus-visible { outline: 3px solid Highlight; outline-offset: -6px; }
}

/* The first thing on every page, out of sight until the keyboard reaches it: docked, the menu is
   twenty-odd tab stops long. */
.skip-link {
  position: fixed; z-index: 70; top: .6rem; left: .6rem;
  padding: .55rem .9rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--primary-dark);
  font: inherit; font-size: .88rem; font-weight: 700; cursor: pointer;
  transform: translateY(-300%);
}
.skip-link:focus-visible { transform: none; outline: 2px solid var(--primary); outline-offset: 2px; }
/* Focused by the skip button, the page itself wears no ring: it is a place, not a control. */
.content-area:focus { outline: none; }
/* The glass is on a ::before, never on the bar. A backdrop-filter ON a fixed or sticky element gets
   its own compositing layer, and WebKit stops re-compositing that layer against the viewport after a
   system file picker rebuilds the page - the bar then paints where the DOCUMENT is rather than where
   the SCREEN is, and scrolls away with the content. It happened to all three of the driver app's
   bars at once. Same shape here, same fix. `validate-glass-bars.mjs` keeps it. */
.topbar { position: sticky; z-index: 20; top: 0; display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 5rem; padding: .9rem clamp(1rem,3vw,2.25rem); border-bottom: 1px solid var(--line); background: transparent; }
.topbar::before { content: ""; position: absolute; inset: 0; z-index: 0; background: color-mix(in srgb, var(--surface) 92%, transparent); backdrop-filter: blur(14px); }
.topbar > * { position: relative; z-index: 1; }
.topbar-title h1 { margin: 0; font-size: 1.45rem; letter-spacing: -.035em; }
.topbar-title p { margin: .22rem 0 0; color: var(--ink-500); font-size: .84rem; }
.topbar-controls { display: flex; align-items: center; gap: .65rem; }
/* How many incidents are still waiting, on every office screen. Rendered only when there is something
   in it: a counter that is usually zero teaches people to stop seeing it, and then it is invisible on
   the morning it says three. Red only when one of them is high or critical — otherwise the colour
   stops meaning urgency and starts meaning "incidents exist". */
.alert-chip {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 2.2rem; padding: 0 .7rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-700);
  font-size: .82rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.alert-chip .icon { width: 1.05rem; height: 1.05rem; }
.alert-chip:hover { background: var(--surface-soft); }
.alert-chip-urgent { border-color: #f0c2bf; background: var(--bad-soft); color: var(--bad); }
.alert-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* A line under a panel heading, for saying what the panel is showing when the numbers above it are
   counting something else. */
.panel-note { display: block; margin-top: .3rem; color: var(--ink-500); font-size: .78rem; font-weight: 500; }

/* Money, in a table. Right-aligned against one edge and in tabular figures, because a column of
   amounts that does not line up is the first thing anybody stops trusting. */
th.numeric, td.numeric { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* A withdrawn invoice. Faded rather than removed — this company received it, and the row is what makes
   the number it spent explicable instead of a hole in somebody's sequence. Not struck through: the
   figures on it were real, and a line through a number reads as "this was wrong" when what happened is
   "this was withdrawn". */
tr.invoice-cancelled { color: var(--ink-500); background: var(--surface-soft); }
/* A credit note, indented under the invoice it reverses. Its own row rather than a footnote on the
   invoice's: it is a separate document with its own number, and somebody reconciling needs to find it
   as one. */
tr.invoice-credit-row { color: var(--ink-700); background: var(--surface-blue); font-size: .88rem; }
tr.invoice-credit-row > td:first-child { padding-left: 1.6rem; }
tr.invoice-cancelled strong { font-weight: 600; }

/* Everything this office can send a driver, in one row, in the same place on every driver's page.
   Its own class: .driver-actions was already taken by the driver-preview shell's header, and two
   different things sharing one name is how a change to one of them silently moves the other. */
.driver-send-actions { flex-wrap: wrap; }

/* What has come the OTHER way, above the fold. Rows rather than metric cards: a count on its own says
   how many, and what somebody opening this page needs is what and whether it is theirs to do. */
.arrived-list { display: flex; flex-direction: column; gap: .5rem; }
.arrived-row {
  display: flex; align-items: center; gap: .9rem; width: 100%;
  padding: .8rem .9rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: inherit; text-align: left; font: inherit; cursor: pointer;
}
.arrived-row:hover { background: var(--surface-soft); }
.arrived-row:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.arrived-count {
  flex: none; min-width: 2.1rem; height: 2.1rem; padding: 0 .5rem;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--surface-blue); color: var(--primary-dark);
  font-size: .95rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.arrived-row-urgent .arrived-count { background: var(--bad-soft); color: var(--bad); }
.arrived-body { flex: 1 1 auto; min-width: 0; }
.arrived-body strong { display: block; font-size: .95rem; }
.arrived-body small { display: block; margin-top: .15rem; color: var(--ink-500); font-size: .8rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.arrived-row .row-chevron { flex: none; color: var(--ink-500); font-size: 1.15rem; }
/* Nothing waiting is a real answer and worth one quiet line, not an empty box with a heading. */
.arrived-clear { display: flex; align-items: baseline; gap: .75rem; }

/* Where a button further up the page has just taken you. Two seconds, then gone — long enough to
   find, short enough not to become part of the furniture. */
.panel-flash { animation: panel-flash 1.4s ease-out; }
@keyframes panel-flash {
  0%, 40% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 35%, transparent); }
  100% { box-shadow: 0 0 0 3px transparent; }
}
@media (prefers-reduced-motion: reduce) { .panel-flash { animation: none; } }

/* Settled incidents, folded away. They are a record rather than a queue, and while they sat in the
   same list the thing you scan every morning was mostly work somebody had already finished. */
.history-fold { margin-top: 1.1rem; border-top: 1px solid var(--line); padding-top: .9rem; }
.history-fold > summary {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .35rem 0; cursor: pointer; font-size: .9rem; list-style: revert;
}
.history-fold > summary .muted { color: var(--ink-500); font-size: .82rem; font-weight: 500; }
.history-fold > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.history-fold > .action-card-list { margin-top: .8rem; }

.compact-select { max-width: 18rem; min-height: 2.4rem; padding: .45rem .7rem; font-size: .82rem; }
.organisation-label, .user-chip { padding: .55rem .75rem; border: 1px solid var(--line); border-radius: 999px; color: var(--ink-700); background: var(--surface); font-size: .78rem; font-weight: 700; }
.user-chip { max-width: 15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Quiet, next to the name it signs out. It is not an action anybody should hit by accident on the
   way to something else, so it is a text button rather than a filled one. */
/* The theme switch. One button, not a pair: there are two states and a pair spends twice the width
   saying so. Sized to match the sign-out beside it so the topbar keeps one rhythm. */
.theme-toggle {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-500);
  font-size: .95rem;
  line-height: 1;
  cursor: pointer;
}
.theme-toggle:hover { color: var(--ink-900); border-color: var(--ink-500); }
.theme-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.topbar-signout {
  flex: 0 0 auto;
  padding: .4rem .7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-500);
  font: inherit;
  font-size: .82rem;
  cursor: pointer;
  white-space: nowrap;
}
.topbar-signout:hover { color: var(--ink-700); border-color: var(--ink-500); }
.topbar-title { min-width: 0; }
.topbar-title h1 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-banner { padding: .8rem clamp(1rem,3vw,2.25rem); border-bottom: 1px solid #f2d79e; color: #7a5000; background: var(--warn-soft); font-size: .86rem; }
/* A table stretched across a 27" monitor is not more readable, it is a longer distance for the eye to
   travel back along. Centred, with a ceiling. */
.content-area { display: grid; gap: 1.25rem; width: 100%; max-width: 96rem; margin: 0 auto; padding: clamp(1rem,3vw,2.25rem); }

.page-actions { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.page-actions h2 { margin: 0; font-size: 1.65rem; letter-spacing: -.04em; }
.action-row { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.metric-grid { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: .9rem; }
.metric-grid.compact { grid-template-columns: repeat(auto-fit,minmax(min(100%,9rem),1fr)); }
.metric-card { min-width: 0; padding: 1.15rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); box-shadow: 0 8px 28px rgba(74, 58, 33, .045); }
.metric-card.metric-danger { border-color: var(--bad-line); background: linear-gradient(180deg, var(--surface), var(--bad-soft)); }
/* Fleet bulk import (Wave A) — file chooser only; everything else reuses the design system. */
.fleet-import-drop { margin: .4rem 0 .2rem; padding: 1rem; border: 1px dashed var(--line); border-radius: var(--radius-sm); background: var(--surface-alt); }
.fleet-import-drop input[type="file"] { width: 100%; max-width: 100%; }
/* Fleet bulk import (Wave B1) — batch-create progress bar. */
.fleet-import-bar { height: 10px; margin: .5rem 0 .25rem; border-radius: 999px; background: var(--line); overflow: hidden; }
.fleet-import-bar-fill { height: 100%; background: var(--accent, #2f6df6); transition: width .2s ease; }
.metric-label { overflow-wrap: anywhere; color: var(--ink-500); font-size: .76rem; font-weight: 750; text-transform: uppercase; white-space: normal; }
.metric-value { margin-top: .45rem; font-size: clamp(1.45rem,3vw,2.25rem); font-weight: 820; letter-spacing: -.05em; }
.metric-hint { margin-top: .35rem; color: var(--ink-500); font-size: .76rem; }
.dashboard-columns { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 1.1rem; }
.panel { min-width: 0; padding: 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: 0 10px 35px rgba(74, 58, 33, .045); }
.panel-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.panel-header h3 { margin: 0; font-size: 1.15rem; letter-spacing: -.025em; }
.panel-header > span { color: var(--ink-500); font-size: .82rem; }
.inline-link { display: inline-block; margin-top: 1rem; color: var(--primary); font-weight: 750; }

.status-pill { display: inline-flex; align-items: center; width: fit-content; padding: .28rem .55rem; border-radius: 999px; font-size: .7rem; font-weight: 800; letter-spacing: .01em; text-transform: capitalize; }
/* The tokens, not literals. These two were the only pills still carrying a hex value — `.status-bad`
   beside them already used `var(--bad)` — and a dark green ink on the dark theme's dark green fill
   measured 2.50:1. Invisible, and missed by every pass that went hunting for white. */
.status-good { color: var(--good); background: var(--good-soft); }
.status-warn { color: var(--warn); background: var(--warn-soft); }
.status-bad { color: var(--bad); background: var(--bad-soft); }
.status-muted { color: var(--muted); background: var(--muted-soft); }
.status-info { color: #33473f; background: var(--info-soft); }

/* The document library's table (#/office/fleet/document-library). What a row IS lives in one column
   as chips instead of being spelt out in grey under the date, and the two dates - performed, and
   received - sit together rather than three columns apart. */
.lib-when { font-weight: 700; }
/* Where the performed date came from. On every row, because the header of document-library.js says
   that distinction must never be blurred - but not as two identical greys. A date a machine read is
   the one an examiner would ask about, so it is the one that is coloured. */
.lib-source { font-size: .74rem; color: #56685f; }
.lib-source-machine { color: var(--warn); font-weight: 700; }
.lib-chips { display: flex; flex-wrap: wrap; gap: .3rem; }
.lib-chips .status-pill { text-transform: none; }
/* A filename is the least human thing on the row and the longest. It takes what is left and stops
   there; the whole name is on the title, and the Open button beside it is what anybody actually
   wants from it. */
.lib-file { max-width: 22rem; }
.lib-file span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 900px) { .lib-file { max-width: 12rem; } }

/* A WIDE TABLE ON A NARROW SCREEN.
   `.data-table` is on a dozen screens and had no phone treatment at all: every one of them scrolls
   sideways, with "read off the document" broken over three lines. `.ptable` has had a card layout for
   phones for months; this is the same treatment, offered to a `.data-table` that OPTS IN with
   `.stacks` and carries a data-label on every cell. Applying it to `.data-table` wholesale would turn
   the other eleven into cards with no labels on them, which is worse than scrolling - so they are
   left alone until each is given its labels.  */
.phone-layout .data-table.stacks,
.phone-layout .data-table.stacks thead, .phone-layout .data-table.stacks tbody,
.phone-layout .data-table.stacks tr, .phone-layout .data-table.stacks th,
.phone-layout .data-table.stacks td {
  display: block; width: auto; min-width: 0;
}
/* Not display:none - that takes the headings from a screen reader too. */
.phone-layout .data-table.stacks thead {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.phone-layout .data-table.stacks tbody tr {
  border: 1px solid var(--line); border-radius: 12px; padding: .7rem .8rem;
  margin-bottom: .6rem; background: var(--surface);
}
.phone-layout .data-table.stacks td { border: 0; padding: .28rem 0; text-align: left; }
.phone-layout .data-table.stacks td::before {
  content: attr(data-label);
  display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin-bottom: .12rem;
}
/* The registration is the card's name, not another field - and the cell with the button needs no
   heading above it at all. */
.phone-layout .data-table.stacks .lib-vehicle { font-size: 1.05rem; }
.phone-layout .data-table.stacks .lib-act::before { content: none; }
.phone-layout .data-table.stacks .lib-act { padding-top: .5rem; }
.phone-layout .data-table.stacks .lib-act .button { width: 100%; }
.phone-layout .data-table.stacks .lib-file { max-width: none; }
.phone-layout .data-table.stacks .lib-file span { white-space: normal; overflow-wrap: anywhere; }
.issue-list { display: grid; gap: .65rem; margin: 0; padding: 0; list-style: none; }
.issue-list li { display: flex; align-items: flex-start; gap: .75rem; padding: .7rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); }
.issue-list strong, .issue-list span { display: block; }
.issue-list span { margin-top: .2rem; color: var(--ink-500); font-size: .78rem; line-height: 1.45; }
.definition-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .8rem; margin: 0; }
.definition-grid > div { min-width: 0; padding: .75rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); }
.definition-grid dt { margin-bottom: .25rem; color: var(--ink-500); font-size: .72rem; font-weight: 750; text-transform: uppercase; }
.definition-grid dd { margin: 0; overflow-wrap: anywhere; font-weight: 700; }

/* The value stored behind the words.

   A reviewer deciding somebody's employment status reads "A genuine, usable right" — and still has to
   be able to say that what is stored is `genuine`, in a note, in an appeal, to an auditor. So the words
   stand in FRONT of the identifier rather than replacing it: monospaced so it reads as a value rather
   than as more prose, and quiet enough that the sentence is what the eye lands on. */
.stored-as {
  display: inline-block;
  margin-left: .4rem;
  padding: .05rem .35rem;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--surface);
  color: var(--ink-500);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .72rem;
  font-weight: 600;
  vertical-align: 1px;
}

/* Where one limb of the status test ends and the next begins. Thirty-four answers in one grid is a
   payload dump with better spacing; substitution, control and mutuality are weighed separately. */
.answer-section {
  margin: 1.35rem 0 .6rem;
  padding-top: .8rem;
  border-top: 1px solid var(--line);
  color: var(--ink-500);
  font-size: .74rem;
  font-weight: 750;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.answer-section:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.capability-grid, .settings-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: .7rem; }
.capability-item, .setting-item, .check-row { display: flex; align-items: center; justify-content: space-between; gap: .65rem; padding: .75rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); font-size: .82rem; font-weight: 650; }

.filter-bar { display: grid; grid-template-columns: minmax(13rem,1fr) 12rem auto; gap: .6rem; width: min(100%,44rem); }
.result-count { color: var(--ink-500); font-size: .85rem; }
.table-panel { padding: 0; overflow: hidden; }
.table-panel .panel-header { padding: 1.25rem 1.25rem 0; }
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .83rem; }
th, td { padding: .85rem 1rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
th { color: var(--ink-500); background: var(--surface-alt); font-size: .7rem; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
tbody tr:hover { background: #fafcff; }
.driver-name-link strong, .driver-name-link span, .table-subtext { display: block; }
.driver-name-link span, .table-subtext { margin-top: .18rem; color: var(--ink-500); font-size: .74rem; }

.driver-hero, .release-hero { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: clamp(1.25rem,3vw,2rem); border-radius: var(--radius); color: white; background: radial-gradient(circle at 85% 10%,rgba(106,133,182,.55),transparent 18rem), linear-gradient(135deg, var(--navy-900), var(--slate)); box-shadow: var(--shadow); }
.driver-hero h2, .release-hero h2 { margin: 0; font-size: clamp(1.8rem,4vw,3rem); letter-spacing: -.05em; }
.driver-hero .eyebrow, .release-hero .eyebrow { color: #a8c8ff; }
.hero-meta { display: flex; align-items: center; gap: .65rem; margin-top: .8rem; color: rgba(255,255,255,.72); flex-wrap: wrap; }
.office-driver-hero .button-secondary { color: white; border-color: rgba(255,255,255,.2); background: rgba(255,255,255,.08); }

/* Correcting a driver's name, in the hero. The hero is `color: white`, and .action-form is built for
   a cream panel: dark-ink labels, a one-column grid, full-width boxes. Rendered there it came out as
   black text on navy with two enormous white slabs. So this is its own small kit rather than a
   borrowed one. The form is a flex child of .hero-meta and takes a whole row of its own. */
.hero-edit { padding: .18rem .6rem; font-size: .75rem; }
.driver-name-form { flex-basis: 100%; margin-top: .7rem; }
.driver-name-form[hidden] { display: none; }
.driver-name-fields { display: flex; align-items: flex-end; gap: .6rem; flex-wrap: wrap; }
.driver-name-fields label { display: block; min-width: 0; }
.driver-name-fields label > span { display: block; margin-bottom: .3rem; color: rgba(255,255,255,.72); font-size: .74rem; font-weight: 750; letter-spacing: .02em; text-transform: uppercase; }
.driver-name-fields input { width: 13rem; max-width: 100%; padding: .38rem .6rem; border: 1px solid rgba(255,255,255,.28); border-radius: 9px; background: rgba(255,255,255,.1); color: white; font: inherit; font-size: .9rem; }
.driver-name-fields input::placeholder { color: rgba(255,255,255,.45); }
.driver-name-fields input:focus { outline: 2px solid rgba(168,200,255,.85); outline-offset: 1px; background: rgba(255,255,255,.16); }
.driver-name-form p { margin: .55rem 0 0; color: rgba(255,255,255,.6); font-size: .76rem; }
@media (max-width: 640px) {
  .driver-name-fields input { width: 100%; }
  .driver-name-fields label { flex-basis: 100%; }
}
.stack-list { display: grid; gap: .7rem; }
.stack-card { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: .9rem; padding: 1rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); }
.stack-card > div:first-child span, .compact-card > div span { display: block; margin-top: .25rem; color: var(--ink-500); font-size: .78rem; }
.stack-card dl { grid-column: 1/-1; display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: .6rem; margin: 0; }
.stack-card dl div { padding: .55rem; border-radius: 8px; background: var(--surface); }
.stack-card dt { color: var(--ink-500); font-size: .68rem; text-transform: uppercase; }
.stack-card dd { margin: .2rem 0 0; font-size: .8rem; font-weight: 700; }
.compact-card { display: flex; align-items: center; justify-content: space-between; gap: .8rem; padding: .75rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); }

.timeline { position: relative; display: grid; gap: .3rem; }
.timeline-item { position: relative; display: grid; grid-template-columns: 1rem minmax(0,1fr); gap: .75rem; padding: .7rem 0; }
.timeline-item::before { position: absolute; top: 1.65rem; bottom: -.65rem; left: .35rem; width: 1px; background: var(--line); content: ""; }
.timeline-item:last-child::before { display: none; }
.timeline-dot { z-index: 1; width: .72rem; height: .72rem; margin-top: .22rem; border: 2px solid white; border-radius: 50%; background: var(--primary); box-shadow: 0 0 0 2px #bdd0f5; }
.timeline-heading { display: flex; justify-content: space-between; gap: .8rem; }
.timeline-heading time, .timeline-item p, .timeline-item span { color: var(--ink-500); font-size: .75rem; }
.timeline-item p { margin: .28rem 0 .12rem; }

.finding-list { display: grid; gap: .85rem; }
.finding-card { padding: 1.1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: 0 8px 28px rgba(74, 58, 33, .04); }
.finding-head { display: flex; justify-content: space-between; gap: 1rem; }
.finding-head h3 { margin: .55rem 0 .15rem; }
.finding-head p, .finding-count { margin: 0; color: var(--ink-500); font-size: .76rem; }
.finding-pills { display: flex; gap: .4rem; }
.compact-definitions { grid-template-columns: repeat(4,minmax(0,1fr)); margin-top: .85rem; }
.finding-card details { margin-top: .8rem; }
.finding-card summary { cursor: pointer; color: var(--primary); font-size: .8rem; font-weight: 750; }
.json-view { max-height: 22rem; overflow: auto; padding: .8rem; border-radius: 10px; color: #dce7fb; background: #0c1628; font-size: .72rem; line-height: 1.5; }
.finding-actions { display: flex; gap: .5rem; margin-top: .85rem; flex-wrap: wrap; }
.filter-toolbar { display: flex; align-items: center; justify-content: space-between; padding: .85rem 1rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.filter-toolbar span { display: block; margin-top: .2rem; color: var(--ink-500); font-size: .78rem; }

.release-hero p { max-width: 43rem; color: rgba(255,255,255,.72); }
.release-score, .driver-compliance-score { display: grid; place-items: center; min-width: 8rem; min-height: 8rem; padding: 1rem; border: 1px solid rgba(255,255,255,.18); border-radius: 50%; background: rgba(255,255,255,.08); text-align: center; }
.release-score strong, .driver-compliance-score strong { display: block; font-size: 2.35rem; line-height: 1; }
.release-score span, .driver-compliance-score span { display: block; margin-top: .25rem; color: rgba(255,255,255,.66); font-size: .75rem; }
.release-blocker-list, .check-list { display: grid; gap: .65rem; }
.release-blocker { display: flex; align-items: flex-start; gap: .75rem; padding: .8rem; border: 1px solid var(--line); border-radius: 10px; }
.release-blocker p { margin: .25rem 0; color: var(--ink-700); line-height: 1.45; }
.release-blocker span:last-child { color: var(--ink-500); font-size: .75rem; }
.callout { margin-top: 1rem; padding: .9rem 1rem; border-left: 4px solid var(--primary); border-radius: 0 10px 10px 0; background: var(--surface-blue); }
.callout p { margin: .3rem 0 0; color: var(--ink-700); }

.driver-shell { min-height: 100vh; }
.driver-topbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 4.8rem; padding: .8rem clamp(1rem,4vw,3rem); color: white; background: var(--navy-900); }
.driver-actions { display: flex; align-items: center; gap: .6rem; }
.driver-content { display: grid; gap: 1.1rem; width: min(100%,82rem); margin: 0 auto; padding: clamp(1rem,4vw,3rem); }
.driver-page-title h1 { margin: 0; letter-spacing: -.04em; }
.driver-dashboard-grid { display: grid; grid-template-columns: minmax(0,1.45fr) minmax(20rem,.55fr); gap: 1rem; }
.driver-primary-card, .driver-side-card { padding: 1.35rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: 0 10px 35px rgba(74, 58, 33, .05); }
.driver-primary-card h3, .driver-side-card h3 { margin: 0; font-size: 1.35rem; }
.driver-primary-card > p, .driver-side-card > p { color: var(--ink-500); line-height: 1.55; }
.driver-primary-card .button { margin-top: 1rem; }

.empty-state { display: grid; place-items: center; padding: 1.5rem; color: var(--ink-500); text-align: center; }
.empty-state h3 { margin: .5rem 0 .25rem; color: var(--ink-900); }
.empty-state p { max-width: 30rem; margin: 0; line-height: 1.55; }
.empty-icon { display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%; color: var(--primary); background: var(--surface-blue); font-size: 1.2rem; }
.loading-state { min-height: 18rem; }
.spinner { width: 1.25rem; height: 1.25rem; border: 2px solid #d9e3f0; border-top-color: var(--primary); border-radius: 50%; animation: spin 700ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.error-panel { border-color: #f2c8c8; background: #fffafa; }
.toast-root { position: fixed; z-index: 100; right: 1rem; bottom: 1rem; display: grid; gap: .55rem; width: min(24rem,calc(100vw - 2rem)); }
.toast { padding: .85rem 1rem; border-radius: 10px; color: white; background: var(--navy-800); box-shadow: var(--shadow); transition: all 250ms ease; }
.toast-success { background: var(--good); }
.toast-error { background: var(--bad); }
/* A warning that looks exactly like a notification is not read as a warning. Amber, and it holds
   longer than the others — see toast() — because the things this app warns about are sentences, not
   words: "nobody signs in as that address, their account is X". */
.toast-warning { background: var(--warn, #b45309); }
.toast-out { opacity: 0; transform: translateY(.5rem); }

@media (max-width: 1180px) {
  .metric-grid, .metric-grid.compact { grid-template-columns: repeat(3,minmax(0,1fr)); }
  .capability-grid, .settings-grid { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .compact-definitions { grid-template-columns: repeat(2,minmax(0,1fr)); }
}

@media (max-width: 900px) {
  .auth-page { grid-template-columns: 1fr; }
  .auth-visual { min-height: 34rem; }
  .topbar-controls .user-chip { display: none; }
  .dashboard-columns, .driver-dashboard-grid { grid-template-columns: 1fr; }
  .stack-card dl { grid-template-columns: repeat(2,minmax(0,1fr)); }
}

@media (max-width: 680px) {
  .auth-panel { padding: 1.4rem; }
  .auth-feature-grid { grid-template-columns: 1fr; }
  .auth-copy h1 { font-size: 2.45rem; }
  .topbar { align-items: flex-start; }
  .topbar-controls { max-width: 45%; }
  .compact-select { max-width: 100%; }
  .content-area, .driver-content { padding: .85rem; }
  .page-actions, .driver-hero, .release-hero { align-items: flex-start; flex-direction: column; }
  .metric-grid, .metric-grid.compact { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .capability-grid, .settings-grid, .definition-grid, .compact-definitions { grid-template-columns: 1fr; }
  .filter-bar { grid-template-columns: 1fr; }
  .organisation-label { display: none; }
  .driver-actions .button-ghost { display: none; }
  .release-score, .driver-compliance-score { min-width: 6.5rem; min-height: 6.5rem; }
}

/* Package 24 — controlled write actions and launch controls */
.action-form { display: grid; gap: 1rem; }
.action-form label, .action-form fieldset { min-width: 0; }
.action-form label > span:first-child { display: block; margin-bottom: .42rem; color: var(--ink-700); font-size: .82rem; font-weight: 750; }
.action-form input:not([type="checkbox"]):not([type="radio"]),
.action-form select,
.action-form textarea {
  width: 100%;
  min-height: 2.75rem;
  padding: .72rem .82rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  outline: none;
  color: var(--ink-900);
  background: var(--surface);
  font: inherit;
}
.action-form textarea { min-height: 6.5rem; resize: vertical; line-height: 1.5; }
.action-form input:focus, .action-form select:focus, .action-form textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
.form-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .85rem; }

/* The driver's own share code, written on the company document it stands for. Deliberately quieter
   than the approved facts above it, and labelled: a code on a card headed "Approved evidence" must not
   be read as approved evidence. */
.wallet-sharecode {
  margin: .45rem 0 0; display: flex; flex-direction: column; gap: .15rem;
}
.wallet-sharecode code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1rem; font-weight: 700; letter-spacing: .08em;
  user-select: all;
}

/* The two share codes, at the top of Driver 360. They were already on the page and the operator could
   not find them twice — the fifteenth panel down is not where anybody looks for the one string they
   are about to type into gov.uk. */
.share-code-strip .share-code-row {
  display: flex; flex-wrap: wrap; gap: 1rem;
}
.share-code-one {
  display: flex; flex-direction: column; align-items: flex-start; gap: .3rem;
  padding: .7rem .9rem; border-radius: .6rem;
  border: 1px solid var(--line, currentColor);
}
.share-code-one code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.15rem; font-weight: 700; letter-spacing: .1em;
  user-select: all;
}

/* A DVLA code drawn out of the vault. Shown large because somebody is about to type it into gov.uk,
   and set apart because it is the one thing on this screen that is not ours to keep: the RPC that
   produced it says do not persist, log or cache it, and this element is the only place it exists. */
.revealed-code {
  margin: .4rem 0 0; padding: .8rem 1rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.4rem; font-weight: 700; letter-spacing: .12em;
  border-radius: .6rem; border: 1px dashed var(--ink-300, currentColor);
  user-select: all;
}

.full-span { grid-column: 1 / -1; }
.dynamic-form { align-items: start; }
.dynamic-fieldset, .training-quiz fieldset {
  grid-column: 1 / -1;
  margin: 0;
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-alt);
}
.dynamic-fieldset legend, .training-quiz legend { padding: 0 .4rem; color: var(--ink-900); font-weight: 800; }
.checkbox-stack { display: grid; gap: .65rem; }
.checkbox-stack.two-columns { grid-template-columns: repeat(2,minmax(0,1fr)); }
.checkbox-card, .radio-card {
  display: flex !important;
  align-items: flex-start;
  gap: .7rem;
  padding: .8rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-alt);
  cursor: pointer;
}
.checkbox-card input, .radio-card input { flex: 0 0 auto; width: 1rem; height: 1rem; margin-top: .14rem; accent-color: var(--primary); }
.checkbox-card span, .radio-card span { min-width: 0; margin: 0 !important; }
.checkbox-card strong { display: block; color: var(--ink-900); }

/* Privacy questions (#/office/privacy-questions). The panels use .action-form like every other form,
   which supplies the inputs; this supplies what a fieldset and a legend lack, because a fieldset
   nothing styles draws the browser's own box and the first version of that screen shipped that way. */
.privacy-form fieldset.q { margin: 0; padding: 0; border: 0; min-width: 0; display: block; }
.privacy-form fieldset.q > legend { display: block; padding: 0; margin: 0 0 .5rem; color: var(--ink-700); font-size: .82rem; font-weight: 750; }
.privacy-form fieldset.q > small, .privacy-form label > small { display: block; margin-top: .45rem; }
.privacy-form .checkbox-stack { gap: .5rem; }
.privacy-form .radio-card span.muted { color: var(--ink-500); }
.privacy-form input[type="number"] { max-width: 10rem; }
.checkbox-card small { display: block; margin-top: .25rem; color: var(--ink-500); line-height: 1.45; }
.action-panel { width: min(100%,68rem); margin-inline: auto; }
.action-card-list { display: grid; gap: .9rem; }
.action-record { padding: 1rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); }
/* Visibly finished: a quieter ground than a live one. Must sit AFTER .action-record — it did not, and
   at equal specificity the later rule wins, so the measured background came back unchanged. Still
   fully readable: this is evidence somebody may have to produce years later, not decoration. */
.action-record-settled { background: var(--surface-soft); }
.action-record-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .8rem; margin-bottom: .85rem; }
.action-record-head h3, .action-record-head h4 { margin: 0; }
/* The reference and who it is about, one under the other. Written as <strong> then <span>, they ran together into
   "INC-DEM-0087Sam Demo" on the incident cards, which reads as one word nobody can search for. */
.action-record-head > div:first-child { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.action-record-head > div:first-child > span { color: var(--ink-500); font-size: .88rem; }
/* A count beside a button's words ("Invite a driver · 1 waiting"): the button is an inline flex box and throws
   away a leading space, so the gap is set here. */
.button-count:not(:empty) { margin-left: .35rem; }
/* And the button keeps its words on one line: on a laptop it folded into "Invite a driver" over "· 1 waiting". */
.record-invite { white-space: nowrap; }
.action-record-head p { margin: .25rem 0 0; color: var(--ink-500); }
.document-content { max-height: 28rem; overflow: auto; margin-bottom: 1rem; padding: 1rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); white-space: pre-wrap; line-height: 1.65; }
.training-quiz { gap: 1.1rem; }
.training-quiz fieldset { display: grid; gap: .6rem; }
.declaration-list { display: grid; gap: .55rem; margin: 0 0 1rem; padding-left: 1.4rem; color: var(--ink-700); line-height: 1.55; }
.launch-columns { align-items: start; }
.action-form details, .panel details { margin-top: .75rem; }
.action-form summary, .panel summary { cursor: pointer; color: var(--primary); font-weight: 750; }

@media (max-width: 900px) {
  .form-grid, .checkbox-stack.two-columns { grid-template-columns: 1fr; }
  .full-span { grid-column: auto; }
}

/* Package 24 — office TOTP MFA gate */
.mfa-page { background: linear-gradient(145deg, var(--surface-soft) 0%, var(--surface-blue) 100%); }
.mfa-card { width: min(100%,48rem); }
.mfa-card-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.5rem; }
.mfa-card-head h1 { margin: .2rem 0 0; }
.mfa-card .auth-form { width: 100%; }
.mfa-enrollment { display: grid; grid-template-columns: minmax(11rem,15rem) 1fr; align-items: center; gap: 1.5rem; margin-bottom: 1.4rem; }
.mfa-qr-wrap { display: grid; place-items: center; padding: .75rem; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); }
.mfa-qr { display: block; width: 100%; max-width: 14rem; aspect-ratio: 1; }
.mfa-secret-label { margin-bottom: .35rem !important; font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.mfa-secret { display: block; max-width: 100%; padding: .7rem; border-radius: 9px; overflow-wrap: anywhere; background: var(--surface-blue); color: var(--navy-800); }
.mfa-error { margin-bottom: 1rem; padding: .8rem 1rem; border: 1px solid var(--bad-line); border-radius: 10px; color: var(--bad); background: var(--bad-soft); }
.mfa-footer { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--line); color: var(--ink-500); }
@media (max-width: 680px) {
  .mfa-enrollment { grid-template-columns: 1fr; }
  .mfa-qr-wrap { width: min(100%,16rem); margin-inline: auto; }
  .mfa-footer { align-items: stretch; flex-direction: column; }
}

/* Package 25I — mobile Driver PWA and document workspace */
.driver-shell-mobile { padding-bottom: calc(5rem + env(safe-area-inset-bottom)); background: var(--surface-soft); }
.driver-shell-mobile .driver-topbar { position: sticky; z-index: 35; top: 0; padding-top: calc(.8rem + env(safe-area-inset-top)); box-shadow: 0 8px 28px rgba(38, 30, 18, .12); }
.driver-shell-mobile .driver-content { width: min(100%,76rem); }
.driver-bottom-nav { position: fixed; z-index: 40; right: 0; bottom: 0; left: 0; display: grid; grid-template-columns: repeat(4,1fr); min-height: 4.65rem; padding: .4rem max(.45rem,env(safe-area-inset-right)) calc(.4rem + env(safe-area-inset-bottom)) max(.45rem,env(safe-area-inset-left)); border-top: 1px solid rgba(74, 58, 33, .14); background: transparent; box-shadow: 0 -12px 35px rgba(74, 58, 33, .12); }
.driver-bottom-nav::before { content: ""; position: absolute; inset: 0; z-index: 0; background: rgba(255,255,255,.96); backdrop-filter: blur(16px); }
.driver-bottom-nav > a { position: relative; z-index: 1; }
.driver-bottom-nav a { display: grid; place-items: center; align-content: center; gap: .18rem; min-width: 0; border-radius: 12px; color: var(--ink-500); font-weight: 750; text-decoration: none; }
.driver-bottom-nav a > span { font-size: 1.15rem; line-height: 1; }
.driver-bottom-nav a small { font-size: .68rem; }
.driver-bottom-nav a.active { color: var(--primary); background: var(--surface-blue); }
.mobile-home-hero { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: clamp(1.2rem,4vw,2rem); border-radius: 22px; color: white; background: radial-gradient(circle at top right,rgba(106,133,182,.36),transparent 42%),linear-gradient(145deg, var(--navy-800), var(--navy-950)); box-shadow: 0 18px 44px rgba(38, 30, 18, .18); }
.mobile-home-hero h2 { margin: .25rem 0 .45rem; font-size: clamp(1.7rem,5vw,2.6rem); letter-spacing: -.04em; }
.mobile-home-hero p { max-width: 38rem; margin: 0; color: rgba(255,255,255,.72); line-height: 1.55; }
.mobile-status-ring { display: grid; flex: 0 0 auto; place-items: center; align-content: center; width: 6.4rem; height: 6.4rem; border: 1px solid rgba(255,255,255,.2); border-radius: 50%; background: rgba(255,255,255,.08); }
.mobile-status-ring strong { font-size: 2rem; line-height: 1; }
.mobile-status-ring span { margin-top: .25rem; color: rgba(255,255,255,.68); font-size: .72rem; }
.assistant-card { display: grid; grid-template-columns: auto 1fr; gap: 1rem; padding: 1.25rem; border: 1px solid var(--info-line); border-radius: 18px; background: linear-gradient(145deg, var(--surface), var(--surface-blue)); box-shadow: 0 10px 35px rgba(52,73,94,.07); }
.assistant-card h3 { margin: .2rem 0 .35rem; }
.assistant-card p { margin: 0; color: var(--ink-700); line-height: 1.55; }
.assistant-icon { display: grid; place-items: center; width: 3.1rem; height: 3.1rem; border-radius: 15px; color: var(--on-accent); background: var(--primary); font-size: 1.4rem; box-shadow: 0 10px 25px var(--accent-glow-strong); }
.assistant-composer-placeholder { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: .75rem; min-height: 3rem; padding: .55rem .65rem .55rem 1rem; border: 1px solid var(--line); border-radius: 14px; color: var(--ink-500); background: var(--surface); }
.assistant-composer-placeholder button { display: grid; place-items: center; width: 2.2rem; height: 2.2rem; border: 0; border-radius: 10px; color: white; background: #aab8cd; }
.quick-action-grid { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: .75rem; }
.quick-action { display: grid; gap: .25rem; min-width: 0; padding: 1rem; border: 1px solid var(--line); border-radius: 16px; color: var(--ink-900); background: var(--surface); box-shadow: 0 8px 25px rgba(74, 58, 33, .04); text-decoration: none; }
.quick-action > span { display: grid; place-items: center; width: 2.4rem; height: 2.4rem; margin-bottom: .25rem; border-radius: 12px; color: var(--primary); background: var(--surface-blue); }
.quick-action small { color: var(--ink-500); }
.mobile-home-columns { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 1rem; align-items: start; }
.mobile-section { min-width: 0; padding: 1.15rem; border: 1px solid var(--line); border-radius: 18px; background: var(--surface); box-shadow: 0 10px 35px rgba(74, 58, 33, .045); }
.mobile-section-head, .mobile-page-intro, .document-type-head, .activity-card-head, .notification-head, .secure-preview-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .8rem; }
.mobile-section-head { margin-bottom: 1rem; }
.mobile-section-head h3, .mobile-page-intro h2, .document-type-head h3 { margin: .15rem 0 0; }
.mobile-section-head > a { color: var(--primary); font-weight: 750; text-decoration: none; }
.mobile-page-intro { align-items: center; padding: 1.15rem; border: 1px solid var(--line); border-radius: 18px; background: var(--surface); }
.mobile-page-intro p { max-width: 48rem; margin: .4rem 0 0; color: var(--ink-500); line-height: 1.55; }
.mobile-next-action { display: grid; gap: .85rem; }
.mobile-next-action h3 { margin: .2rem 0 .35rem; }
.mobile-next-action p { margin: 0; color: var(--ink-500); line-height: 1.5; }
.mobile-next-meta, .task-card-meta { display: flex; align-items: center; flex-wrap: wrap; gap: .55rem; color: var(--ink-500); font-size: .78rem; }
.notification-list, .task-list, .activity-list, .document-file-list { display: grid; gap: .75rem; }
.notification-card { display: grid; grid-template-columns: auto 1fr; gap: .7rem; padding: .8rem; border: 1px solid var(--line); border-radius: 13px; background: var(--surface-alt); }
.notification-dot { width: .55rem; height: .55rem; margin-top: .35rem; border-radius: 50%; background: var(--primary); box-shadow: 0 0 0 4px var(--accent-glow); }
.notification-head span { color: var(--ink-500); font-size: .7rem; }
.notification-card p { margin: .3rem 0 0; color: var(--ink-700); line-height: 1.45; }
.task-card { display: grid; gap: .8rem; padding: 1rem; border: 1px solid var(--line); border-radius: 15px; background: var(--surface-alt); }
.task-card-warning { border-color: var(--warn-line); background: var(--warn-soft); }
.task-card h3 { margin: .2rem 0 .3rem; }
.task-card p { margin: 0; color: var(--ink-700); line-height: 1.5; }
.task-card .button { justify-self: start; }
.mobile-profile-card { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1rem; padding: 1.25rem; border-radius: 18px; color: white; background: linear-gradient(145deg, var(--navy-800), var(--navy-950)); }
.mobile-profile-card h2 { margin: .2rem 0; }
.mobile-profile-card p { margin: 0; color: rgba(255,255,255,.68); }
.profile-avatar { display: grid; place-items: center; width: 4rem; height: 4rem; border: 1px solid rgba(255,255,255,.2); border-radius: 18px; background: rgba(255,255,255,.1); font-size: 1.6rem; font-weight: 850; }
/* ============================ My Profile / Account Settings ============================ */
/* content-area is a grid; pin its single track shrinkable so cards can't blow out the viewport */
.account-content { grid-template-columns: minmax(0, 1fr); }
.account-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: start; min-width: 0; }
.account-grid .span-2 { grid-column: 1 / -1; }
@media (max-width: 960px) { .account-grid { grid-template-columns: minmax(0, 1fr); } }

/* Fields — full-width, label above input (portal input language) */
.account-field { display: grid; gap: .4rem; margin-bottom: .95rem; min-width: 0; }
.account-field:last-child { margin-bottom: 0; }
.account-field > span { color: var(--ink-700); font-size: .82rem; font-weight: 700; }
.account-field input, .account-field select { width: 100%; min-width: 0; min-height: 2.8rem; padding: .72rem .85rem; font: inherit; color: var(--ink-900); background: var(--surface); border: 1px solid var(--line); border-radius: 10px; outline: none; }
.account-field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-500) 50%), linear-gradient(135deg, var(--ink-500) 50%, transparent 50%); background-position: calc(100% - 1.05rem) 1.2rem, calc(100% - .7rem) 1.2rem; background-size: .38rem .38rem, .38rem .38rem; background-repeat: no-repeat; padding-right: 2.2rem; }
.account-field input:focus, .account-field select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--accent-glow); }
.account-field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem; }
@media (max-width: 560px) { .account-field-row { grid-template-columns: minmax(0, 1fr); } }
.account-savebar { display: flex; justify-content: flex-end; gap: .7rem; }

/* Avatar */
.avatar-head { display: flex; align-items: center; gap: 1.1rem; margin-bottom: 1rem; flex-wrap: wrap; }
.avatar-preview-lg { display: grid; place-items: center; width: 5rem; height: 5rem; border-radius: 20px; font-size: 2.5rem; color: white; background: linear-gradient(145deg, var(--navy-800), var(--navy-950)); box-shadow: 0 10px 30px rgba(74, 58, 33, .18); }
.avatar-picker { display: flex; gap: .55rem; flex-wrap: wrap; }
.avatar-option { cursor: pointer; }
.avatar-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.avatar-option > span { display: grid; place-items: center; width: 3.1rem; height: 3.1rem; font-size: 1.6rem; border: 1.5px solid var(--line); border-radius: 15px; background: var(--surface-alt); transition: border-color .12s, box-shadow .12s, transform .12s; }
.avatar-option > span:hover { transform: translateY(-1px); }
.avatar-option input:checked + span { border-color: var(--primary); background: var(--surface-blue); box-shadow: 0 0 0 3px var(--accent-glow); }
.avatar-option input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Preference toggle rows (notifications + marketing) */
.pref-list { display: grid; gap: .55rem; }
.pref-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .8rem .95rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); }
.pref-row .pref-label { display: block; font-weight: 700; color: var(--ink-900); }
.pref-row .pref-hint { display: block; font-weight: 500; font-size: .8rem; color: var(--ink-500); margin-top: .12rem; }
.switch { position: relative; display: inline-block; width: 2.6rem; height: 1.5rem; flex: 0 0 auto; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track { position: absolute; inset: 0; border-radius: 999px; background: #cbd5e6; transition: background .15s; }
.switch .track::before { content: ""; position: absolute; top: 2px; left: 2px; width: 1.1rem; height: 1.1rem; border-radius: 50%; background: var(--surface); box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .15s; }
.switch input:checked + .track { background: var(--primary); }
.switch input:checked + .track::before { transform: translateX(1.1rem); }
.switch input:focus-visible + .track { box-shadow: 0 0 0 3px var(--accent-glow-strong); }
.essential-note { display: flex; gap: .55rem; align-items: flex-start; margin-bottom: .9rem; padding: .8rem .95rem; border-radius: 12px; background: var(--surface-blue); color: var(--ink-700); font-size: .85rem; line-height: 1.5; }
.essential-note strong { color: var(--ink-900); }
.subtle-action { margin-top: .8rem; }
.field-static { display: grid; gap: .25rem; margin-bottom: .9rem; }
.field-static .field-label { color: var(--ink-500); font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.field-static strong { font-size: 1.05rem; color: var(--ink-900); }
.security-panel p { color: var(--ink-700); line-height: 1.55; }
.document-card-grid, .document-library-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .85rem; }
.document-type-card, .document-library-card, .activity-card { display: grid; gap: .8rem; min-width: 0; padding: 1rem; border: 1px solid var(--line); border-radius: 15px; background: var(--surface-alt); }
.document-type-card > p, .document-library-card p, .activity-card p { margin: 0; color: var(--ink-500); line-height: 1.5; }
.document-file-button, .document-file-static { display: flex; align-items: center; justify-content: space-between; gap: .65rem; width: 100%; padding: .75rem; border: 1px solid var(--line); border-radius: 11px; color: var(--ink-900); background: var(--surface); text-align: left; }
.document-file-button { cursor: pointer; }
.document-file-button:hover { border-color: var(--primary); }
.document-file-button small, .document-file-static small { min-width: 0; overflow: hidden; color: var(--ink-500); text-overflow: ellipsis; white-space: nowrap; }
.activity-card-head span { color: var(--ink-500); font-size: .72rem; }
.upload-slot-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .8rem; }
.upload-slot-card { position: relative; display: flex; align-items: center; gap: .85rem; min-height: 6rem; padding: 1rem; border: 1px dashed var(--line); border-radius: 15px; color: var(--ink-900); background: var(--surface-alt); cursor: pointer; }
.upload-slot-card:hover { border-color: var(--primary); background: var(--surface-blue); }
.upload-slot-card input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.upload-slot-card small { display: block; margin-top: .25rem; color: var(--ink-500); }
.upload-slot-icon { display: grid; flex: 0 0 auto; place-items: center; width: 2.8rem; height: 2.8rem; border-radius: 13px; color: var(--on-accent); background: var(--primary); font-size: 1.25rem; }
.mobile-action-panel { width: min(100%,60rem); margin-inline: auto; }
.upload-progress { padding: .85rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); }
.upload-progress[data-status="success"] { border-color: var(--good); background: var(--good-soft); }
.upload-progress[data-status="error"] { border-color: var(--bad-line); background: var(--bad-soft); }
.upload-progress-copy { display: flex; justify-content: space-between; gap: .8rem; margin-bottom: .55rem; }
.upload-progress-track { height: .55rem; overflow: hidden; border-radius: 999px; background: #dce6f3; }
.upload-progress-track span { display: block; height: 100%; border-radius: inherit; background: var(--primary); transition: width 180ms ease; }
.action-row, .confirmation-actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: .65rem; }
.warning-list { margin: 1rem 0; padding: .9rem 1rem; border: 1px solid var(--warn-line); border-radius: 12px; background: var(--warn-soft); }
.warning-list ul { margin-bottom: 0; color: var(--ink-700); }

/* How sure the reader was of ONE field, under the box a reviewer is about to type into.
   Quiet by default — most fields are read cleanly and a note on every one is a note on none — and
   marked where the score came from, because that is the field the metric card above is about. */
.field-confidence { display: block; margin-top: .25rem; color: var(--ink-500); font-size: .78rem; }
.field-confidence-weakest { color: var(--warn-ink, var(--ink-700)); font-weight: 600; }
.secure-preview-modal { position: fixed; z-index: 1000; inset: 0; display: grid; place-items: center; padding: 1rem; background: transparent; }
.secure-preview-modal::before { content: ""; position: absolute; inset: 0; z-index: 0; background: rgba(38, 30, 18, .78); backdrop-filter: blur(8px); }
.secure-preview-modal > * { position: relative; z-index: 1; }
.secure-preview-card { display: grid; gap: .8rem; width: min(100%,68rem); max-height: calc(100vh - 2rem); padding: 1rem; overflow: auto; border-radius: 18px; background: var(--surface); box-shadow: 0 25px 80px rgba(0,0,0,.35); }
.secure-preview-head h3 { margin: .2rem 0 0; }
.secure-preview-frame { display: grid; place-items: center; min-height: 22rem; overflow: auto; border: 1px solid var(--line); border-radius: 13px; background: #eef3f9; }
.secure-preview-frame img { display: block; max-width: 100%; max-height: 72vh; object-fit: contain; }
.secure-preview-frame iframe { width: 100%; height: 72vh; border: 0; background: var(--surface); }
.install-button { white-space: nowrap; }

@media (min-width: 901px) {
  .driver-bottom-nav { right: 50%; left: 50%; width: min(34rem,100%); transform: translateX(-50%); border: 1px solid rgba(74, 58, 33, .14); border-bottom: 0; border-radius: 18px 18px 0 0; }
}

@media (max-width: 760px) {
  .driver-shell-mobile .driver-content { padding: .8rem; }
  .driver-shell-mobile .driver-page-title { display: none; }
  .driver-shell-mobile .driver-topbar { min-height: 4.2rem; padding-right: .75rem; padding-left: .75rem; }
  .driver-brand strong { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .driver-brand small { display: none; }
  .driver-actions .install-button { display: inline-flex; padding: .55rem .7rem; font-size: .75rem; }
  .mobile-home-columns, .document-card-grid, .document-library-grid, .upload-slot-grid { grid-template-columns: 1fr; }
  .quick-action-grid { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .mobile-metrics { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .mobile-page-intro { align-items: stretch; flex-direction: column; }
  .mobile-home-hero { align-items: flex-start; }
  .mobile-status-ring { width: 5.4rem; height: 5.4rem; }
  .assistant-card { grid-template-columns: auto 1fr; }
  .mobile-profile-card { grid-template-columns: auto 1fr; }
  .mobile-profile-card > .pill { grid-column: 1 / -1; justify-self: start; }
  .confirmation-actions .button, .action-row .button { flex: 1 1 100%; }
  .secure-preview-modal { padding: 0; }
  .secure-preview-card { width: 100%; max-height: 100vh; min-height: 100vh; border-radius: 0; }
}

@media (max-width: 420px) {
  .driver-actions .install-button { display: none; }
  .mobile-home-hero { flex-direction: column; }
  .mobile-status-ring { width: 100%; height: auto; min-height: 4.5rem; border-radius: 14px; }
  .mobile-status-ring strong, .mobile-status-ring span { display: inline; }
  .document-file-button, .document-file-static, .notification-head { align-items: flex-start; flex-direction: column; }
}

/* Package 25J — Office document review and Driver 360 document workspace */
.button-danger { color: var(--on-accent); background: var(--bad); box-shadow: 0 8px 20px rgba(196,60,60,.18); }
.button-danger:hover:not(:disabled) { background: #a92f2f; }
.office-review-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 1rem; }
.office-review-card { display: grid; gap: .9rem; min-width: 0; padding: 1rem; border: 1px solid var(--line); border-radius: 14px; background: var(--surface-alt); }
.office-review-card-warning { border-color: var(--warn-line); background: var(--warn-soft); }
.office-review-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .8rem; }
.office-review-card-head h3 { margin: .15rem 0 .3rem; }
.office-review-card-head p { margin: 0; color: var(--ink-500); }
.office-review-card-head a { color: var(--primary); font-weight: 750; }
.office-review-card .button { justify-self: start; }
.office-review-layout { display: grid; grid-template-columns: minmax(0,1.1fr) minmax(0,.9fr); gap: 1rem; align-items: start; }
.review-evidence-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .8rem; margin-top: 1rem; }
.review-evidence-grid .json-view { max-height: 19rem; margin: 0; }
.office-decision-actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: .65rem; }
.office-document-card { background: var(--surface); }
.office-activity-card { background: var(--surface); }
.office-activity-decision { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; padding-top: .65rem; border-top: 1px solid var(--line); color: var(--ink-500); font-size: .78rem; }
.office-activity-decision small { margin-left: auto; }
@media (max-width: 1000px) {
  .office-review-layout, .office-review-grid, .review-evidence-grid { grid-template-columns: 1fr; }
}
@media (max-width: 680px) {
  .office-decision-actions .button { flex: 1 1 100%; }
  .office-review-card-head { flex-direction: column; }
}

/* CSF-1C Phase 2 — main-portal single entry point: sign-up choice + driver signup */
.signup-choice {
  display: flex;
  align-items: center;
  gap: .95rem;
  text-align: left;
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(74, 58, 33, .04);
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease, background .16s ease;
}
.signup-choice:hover,
.signup-choice:focus-visible {
  border-color: var(--primary);
  background: var(--surface-blue);
  box-shadow: 0 12px 28px var(--accent-glow);
  transform: translateY(-2px);
  outline: none;
}
.signup-choice-icon {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--primary);
  background: var(--surface-blue);
  border: 1px solid var(--line);
  border-radius: 14px;
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.signup-choice:hover .signup-choice-icon,
.signup-choice:focus-visible .signup-choice-icon {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.signup-choice-body { flex: 1; min-width: 0; }
.signup-choice-body strong { display: block; font-size: 1.08rem; letter-spacing: -.01em; margin-bottom: .25rem; color: var(--ink-900); }
.signup-choice-body span { display: block; font-size: .85rem; line-height: 1.5; color: var(--ink-500); }
.signup-choice-arrow {
  flex: none;
  align-self: center;
  color: var(--primary);
  font-size: 1.25rem;
  font-weight: 700;
  opacity: .55;
  transition: transform .16s ease, opacity .16s ease;
}
.signup-choice:hover .signup-choice-arrow,
.signup-choice:focus-visible .signup-choice-arrow { transform: translateX(4px); opacity: 1; }
.auth-alt { font-size: .9rem; color: var(--ink-500); }

/* CSF-1C Phase 3 — Platform Admin registration queue */
.filter-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1rem; }
.filter-tab {
  display: inline-block;
  padding: .35rem .8rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--ink-500);
  background: var(--surface);
}
.filter-tab.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.table-wrap { overflow-x: auto; }

/* Nineteen places in this portal wrote class="muted small" and nothing made it small: the class read
   as styling and was decoration. Same shape as the buttons wearing a colour with no form. */
.small { font-size: .82rem; line-height: 1.45; }

/* A bar for a month's spend against the biggest month. Deliberately the navy, not the green: green
   in this portal means "in order", and money is not a verdict. */
.bar-track {
  height: .55rem;
  background: var(--surface-alt);
  border-radius: 999px;
  overflow: hidden;
}
.bar-fill {
  height: 100%;
  min-width: 2px;
  background: var(--primary);
  border-radius: 999px;
}
.data-table { border-collapse: collapse; width: 100%; min-width: 640px; }
.data-table th, .data-table td { text-align: left; padding: .7rem .8rem; border-bottom: 1px solid var(--line); font-size: .88rem; vertical-align: top; }
.data-table th { font-size: .72rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-500); }
.data-table tr:last-child td { border-bottom: 0; }
.row-link { cursor: pointer; }
.row-link:hover td { background: var(--surface-soft); }
.callout-danger { border-color: var(--danger, #c0392b); }
.audit-timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }
.audit-timeline li { border-left: 2px solid var(--line); padding: 0 0 0 1rem; }
.audit-head { font-weight: 700; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.button-small { padding: .3rem .7rem; font-size: .8rem; }
.button-small + .button-small { margin-left: .35rem; }

/* ============================================================================
   Platform Admin Compliance Catalogue — draft-authoring polish (m14d9).
   Visual/layout only, scoped to .catalogue-authoring. No behaviour/ID change.
   ============================================================================ */
.catalogue-authoring { max-width: 960px; margin: 0 auto; }
.catalogue-authoring > p:first-child { margin: 0 0 .4rem; }                 /* back link */
.catalogue-authoring .panel { padding: 1.5rem 1.6rem; }
.catalogue-authoring .panel + .panel, .catalogue-authoring .panel + section.panel { margin-top: 1.1rem; }
@media (max-width: 640px) { .catalogue-authoring .panel { padding: 1.15rem 1.1rem; } }

/* section cards (fieldsets rendered as clean cards; native fieldset chrome removed) */
.catalogue-authoring .form-section,
.catalogue-authoring .form-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.4rem;
  margin: 0 0 1.1rem; padding: 1.15rem 1.25rem 1.3rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-soft);
}
.catalogue-authoring .form-section:last-of-type, .catalogue-authoring .form-grid:last-of-type { margin-bottom: 0; }
.catalogue-authoring .form-section > legend {
  grid-column: 1 / -1; float: none; width: auto; padding: 0; margin: 0 0 .1rem;
  color: var(--primary); font-size: .72rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
}
/* toggle wrappers flow their inner fields into the parent grid (hidden still hides) */
.catalogue-authoring #recurring-fields:not([hidden]),
.catalogue-authoring #trailer-subtype-field:not([hidden]) { display: contents; }
/* full-row (non-field) children */
.catalogue-authoring .form-section > p,
.catalogue-authoring .form-section > .muted,
.catalogue-authoring .form-section > .field-error,
.catalogue-authoring .form-section .form-check,
.catalogue-authoring .form-section > #mode-help,
.catalogue-authoring .form-section > #allowed-preview { grid-column: 1 / -1; }
@media (max-width: 720px) {
  .catalogue-authoring .form-section, .catalogue-authoring .form-grid { grid-template-columns: 1fr; }
}

/* fields — label above, full-width control (portal input language) */
.catalogue-authoring .form-field { display: flex; flex-direction: column; gap: .38rem; min-width: 0; }
.catalogue-authoring .form-field > label { color: var(--ink-700); font-size: .82rem; font-weight: 750; }
.catalogue-authoring .form-field input:not([type="checkbox"]),
.catalogue-authoring .form-field select {
  width: 100%; min-height: 2.8rem; padding: .7rem .85rem; color: var(--ink-900); background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; outline: none; transition: border-color .15s, box-shadow .15s;
}
.catalogue-authoring .form-field select {
  appearance: none; padding-right: 2.2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-500) 50%), linear-gradient(135deg, var(--ink-500) 50%, transparent 50%);
  background-position: calc(100% - 1.05rem) 1.25rem, calc(100% - .7rem) 1.25rem; background-size: .38rem .38rem, .38rem .38rem; background-repeat: no-repeat;
}
.catalogue-authoring .form-field input:focus,
.catalogue-authoring .form-field select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--accent-glow); }
.catalogue-authoring .form-field.has-error input,
.catalogue-authoring .form-field.has-error select { border-color: var(--bad); box-shadow: 0 0 0 3px rgba(196,60,60,.13); }
.catalogue-authoring .form-field > .muted { color: var(--ink-500); font-size: .78rem; line-height: 1.45; }
.catalogue-authoring .field-error { margin: 0; color: var(--bad); font-size: .8rem; font-weight: 650; }
.catalogue-authoring .field-error:empty { display: none; }

/* checkboxes */
.catalogue-authoring .form-check { gap: .3rem; padding: .1rem 0; }
.catalogue-authoring .form-check > label { display: flex; align-items: center; gap: .55rem; color: var(--ink-900); font-weight: 650; }
.catalogue-authoring .form-check input[type="checkbox"] { width: 1.05rem; height: 1.05rem; accent-color: var(--primary); }

/* action bar — grouped at the end (secondary → primary), full-width on mobile */
.catalogue-authoring .action-row { justify-content: flex-end !important; gap: .65rem; margin-top: 1.35rem; padding-top: 1.15rem; border-top: 1px solid var(--line); }
@media (max-width: 560px) { .catalogue-authoring .action-row .button { flex: 1 1 100%; } }

/* review summary as calm definition chips */
.catalogue-authoring .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: .7rem 1.1rem; margin: .25rem 0 1rem; }
.catalogue-authoring .summary-grid > div { display: flex; flex-direction: column; gap: .2rem; padding: .65rem .8rem; background: var(--surface-soft); border: 1px solid var(--line); border-radius: 10px; font-size: .9rem; }
.catalogue-authoring .summary-grid > div > .muted:first-child { color: var(--ink-500); font-size: .7rem; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.catalogue-authoring .notice { margin: 0 0 1rem; }

/* =============================================================================
   Minimal Publish Now — m14d10. Scoped to the publish region + confirmation modal.
   The m14d9 catalogue chip look is scoped to the DIALOG (.publish-confirm), NOT the
   full-screen overlay — so the backdrop covers the whole viewport (see .modal-overlay)
   and the dialog stays 540px/centred. Visual only — no behaviour is expressed in CSS.
   ============================================================================= */
.catalogue-publish-region .action-row { border-top: 1px solid var(--line); }
.catalogue-publish-region #publish-disabled-reason:empty { display: none; }
.catalogue-publish-region #publish-disabled-reason { font-size: .82rem; max-width: 46ch; text-align: right; line-height: 1.4; }
#publish-region-error:empty, #publish-modal-error:empty { display: none; }

/* modal overlay + dialog */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 1.25rem; background: transparent;
  overflow-y: auto;
}
/* absolute, not fixed. Fixed would keep the tint over the viewport while the overlay scrolls - but
   it would also be a fixed element carrying a backdrop-filter, which is the whole fault being fixed
   here. The dialog inside caps at `100vh - 2.5rem` and scrolls itself, so the overlay almost never
   scrolls at all. */
.modal-overlay::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: rgba(74, 58, 33, .55);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.modal-overlay > * { position: relative; z-index: 1; }
.modal-dialog {
  width: 100%; max-width: 540px; max-height: calc(100vh - 2.5rem);
  overflow-y: auto; background: var(--surface, #fff);
  border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 24px 60px rgba(74, 58, 33, .32);
  padding: 1.5rem 1.6rem;
}
@media (max-width: 560px) { .modal-dialog { padding: 1.2rem 1.15rem; border-radius: 13px; } }
.modal-dialog .modal-header h3 { margin: 0 0 .35rem; font-size: 1.15rem; }
.modal-dialog .modal-body { margin: 0; }
.modal-dialog .modal-body > p { margin: .5rem 0; line-height: 1.5; }
.modal-dialog .notice { margin: .75rem 0; }
/* summary chips scoped to the dialog (m14d9 catalogue look) — no longer inherited from a
   .catalogue-authoring overlay, so the overlay can be a true full-viewport backdrop. */
.publish-confirm .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .6rem .9rem; margin: .4rem 0 1rem; }
.publish-confirm .summary-grid > div { display: flex; flex-direction: column; gap: .2rem; padding: .6rem .75rem; background: var(--surface-soft); border: 1px solid var(--line); border-radius: 10px; font-size: .9rem; }
.publish-confirm .summary-grid > div > .muted:first-child { color: var(--ink-500); font-size: .7rem; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.modal-actions {
  display: flex; justify-content: space-between; align-items: center;
  gap: .65rem; margin-top: 1.35rem; padding-top: 1.15rem; border-top: 1px solid var(--line);
}
@media (max-width: 480px) {
  .modal-actions { flex-direction: column-reverse; align-items: stretch; }
  .modal-actions .button { width: 100%; }
}

/* =============================================================================
   Office Compliance Policy — m14d11. Reuses the m14d10 catalogue visual language
   (chips, cards, inputs, modal). Framework and organisation policy are visually
   separated; the confirmation modal reuses the shared full-viewport overlay.
   ============================================================================= */
.office-policy { max-width: 960px; margin: 0 auto; }
.office-policy > p:first-child { margin: 0 0 .4rem; }
.office-policy .panel { padding: 1.5rem 1.6rem; }
.office-policy .panel + .panel, .office-policy .panel + section.panel { margin-top: 1.1rem; }
@media (max-width: 640px) { .office-policy .panel { padding: 1.15rem 1.1rem; } }
.office-policy .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .6rem 1rem; margin: .5rem 0 .75rem; }
.office-policy .summary-grid > div { display: flex; flex-direction: column; gap: .2rem; padding: .6rem .8rem; background: var(--surface-soft); border: 1px solid var(--line); border-radius: 10px; font-size: .9rem; }
.office-policy .form-section { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem 1.1rem; border: 1px solid var(--line); border-radius: 12px; padding: 1.1rem 1.2rem; margin: .5rem 0; }
.office-policy .form-section > legend { grid-column: 1 / -1; font-weight: 800; font-size: .82rem; color: var(--ink-700); text-transform: uppercase; letter-spacing: .05em; padding: 0; }
.office-policy .form-section > .field-error, .office-policy .form-section .form-check { grid-column: 1 / -1; }
@media (max-width: 640px) { .office-policy .form-section { grid-template-columns: 1fr; } }
.office-policy .form-field { display: flex; flex-direction: column; gap: .38rem; min-width: 0; }
.office-policy .form-field > label { color: var(--ink-700); font-size: .82rem; font-weight: 750; }
.office-policy .form-field input:not([type="checkbox"]), .office-policy .form-field select { padding: .6rem .7rem; border: 1px solid var(--line); border-radius: 9px; font: inherit; background: var(--surface); }
.office-policy .form-field input:focus, .office-policy .form-field select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--accent-glow); outline: none; }
.office-policy .form-field.has-error input, .office-policy .form-field.has-error select { border-color: var(--bad); box-shadow: 0 0 0 3px rgba(196,60,60,.13); }
.office-policy .form-field > .muted { color: var(--ink-500); font-size: .78rem; }
.office-policy .field-error { margin: 0; color: var(--bad); font-size: .8rem; font-weight: 650; }
.office-policy .field-error:empty { display: none; }
.office-policy .form-check { flex-direction: row; align-items: center; }
.office-policy .form-check > label { display: flex; align-items: center; gap: .55rem; font-weight: 650; color: var(--ink-900); }
.office-policy .form-check input[type="checkbox"] { width: 1.05rem; height: 1.05rem; accent-color: var(--primary); }
.office-policy .action-row { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
#policy-error:empty, #ocp-modal-error:empty { display: none; }
/* modal confirm chips (dialog-scoped; overlay stays a full-viewport backdrop) */
.policy-confirm .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .6rem .9rem; margin: .4rem 0 1rem; }
.policy-confirm .summary-grid > div { display: flex; flex-direction: column; gap: .2rem; padding: .6rem .75rem; background: var(--surface-soft); border: 1px solid var(--line); border-radius: 10px; font-size: .9rem; }
.policy-confirm .summary-grid > div > .muted:first-child { color: var(--ink-500); font-size: .7rem; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.policy-confirm .form-field { display: flex; flex-direction: column; gap: .35rem; margin: .6rem 0; }
.policy-confirm .form-field > label { font-size: .82rem; font-weight: 750; color: var(--ink-700); }
.policy-confirm .form-field input { padding: .55rem .7rem; border: 1px solid var(--line); border-radius: 9px; font: inherit; }

/* --- M14D14 Asset Compliance Setup (single vehicle · Vehicle PMI) --------------------------- */
/* Base notice styling (shared; previously only scoped to catalogue/modal contexts). */
.notice { margin: .75rem 0; padding: .7rem .85rem; border-radius: 10px; border: 1px solid var(--line); background: var(--surface-soft); font-size: .9rem; }
.notice-error { color: var(--bad); background: var(--bad-soft); border-color: var(--bad-line); }
.notice-info { color: #33473f; background: var(--info-soft); border-color: #cfe0f5; }

/* Choosing the dates on the audit pack (#/office/fleet/audit-pack). The two boxes and their button
   sit on one line on a desktop and stack on a phone; the button aligns with the inputs rather than
   with their labels, which is what `align-self: end` is doing. */
.pack-dates { margin-top: .75rem; align-items: end; }
.pack-dates-go { align-self: end; }
.pack-dates-go .button { width: 100%; }
@media (max-width: 640px) { .pack-dates-go { margin-top: .2rem; } }
.asset-compliance .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: .6rem .9rem; margin: .5rem 0; }
.asset-compliance .summary-grid > div { display: flex; flex-direction: column; gap: .2rem; padding: .55rem .7rem; background: var(--surface-soft); border: 1px solid var(--line); border-radius: 10px; }
.asset-compliance .form-check { display: block; margin: .25rem 0; font-weight: 600; }
.asset-compliance .form-check input { margin-right: .45rem; }
.asset-compliance code { font-size: .82em; background: var(--surface-soft); padding: .05rem .3rem; border-radius: 5px; }

/* ---- driver document wallet (Office) --------------------------------------------------------
   The same shape the driver sees on their phone. A document is a physical thing with a face, and a
   reviewer recognises a licence by its picture before reading a single field — the Office looks at
   far more of them than any one driver does. */

.wallet-grid {
  display: grid;
  /* min(300px, 100%) rather than a bare 300px: on a narrow window a fixed minimum pushes the grid
     wider than its container and the whole page scrolls sideways. */
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: 18px;
}

.wallet-theme-rose  { --wa: #f7d9df; --wb: #fceff1; --wink: #8b5566; }
.wallet-theme-lilac { --wa: #ded9ef; --wb: #f1edfa; --wink: #5f5588; }
.wallet-theme-sky   { --wa: #cfe0ee; --wb: #e9f2f8; --wink: #45677f; }
.wallet-theme-sand  { --wa: #e8dcc4; --wb: #f6efde; --wink: #78683f; }
.wallet-theme-mint  { --wa: #cfe8dc; --wb: #e9f6ef; --wink: #3f6f5a; }
.wallet-theme-peach { --wa: #f6ded0; --wb: #fcf0e8; --wink: #8a6046; }

.wallet-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px 20px 16px;
  border-radius: 22px;
  color: var(--wink);
  background: linear-gradient(150deg, var(--wa) 0%, var(--wb) 100%);
}
/* A superseded version still belongs in the wallet — an auditor asks what was on file in March, not
   only what is on file today — but it must never be mistaken for the current one. */
.wallet-card-superseded { opacity: 0.66; }

.wallet-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.wallet-card-head h3 { font-size: 1.15rem; font-weight: 700; margin: 0; color: inherit; }
.wallet-card-head p { margin: 4px 0 0; font-size: 0.72rem; opacity: 0.7; word-break: break-all; }
.wallet-badge {
  flex: 0 0 auto;
  padding: 5px 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.62);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.wallet-face {
  min-height: 132px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.38) center / cover no-repeat;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);
  cursor: pointer;
  transition: transform 120ms ease;
}
.wallet-face:hover { transform: scale(1.01); }
.wallet-face-loaded { cursor: zoom-in; }
.wallet-face-empty,
.wallet-face-doc {
  display: grid;
  place-content: center;
  cursor: default;
  font-size: 0.78rem;
  opacity: 0.7;
}
.wallet-face-doc::after { content: "PDF"; font-weight: 700; letter-spacing: 0.06em; }

/* A face that is still arriving, and one that never did. The second used to look exactly like an
   empty card, which is how a broken preview went unnoticed. */
.wallet-face-loading { animation: wallet-face-pulse 1.1s ease-in-out infinite; }
@keyframes wallet-face-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
.wallet-face-failed {
  display: grid;
  place-content: center;
  padding: 10px;
  text-align: center;
  font-size: 0.72rem;
  background: rgba(255, 107, 107, 0.16);
}
.wallet-face-failed::after {
  content: "Preview unavailable: " attr(data-face-error);
  opacity: 0.85;
}

.wallet-facts { display: flex; flex-direction: column; gap: 2px; }
.wallet-facts strong { font-size: 0.98rem; }
.wallet-facts span { font-size: 0.8rem; opacity: 0.78; }

.wallet-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.wallet-chip {
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.62);
}
.wallet-chip-soon { background: rgba(245, 196, 81, 0.5); }
.wallet-chip-expired { background: rgba(255, 107, 107, 0.42); }

.wallet-sides { display: flex; gap: 8px; flex-wrap: wrap; }
.wallet-side {
  border: 0;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.5);
  color: inherit;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
}
.wallet-side:hover { background: rgba(255, 255, 255, 0.8); }

/* ---- assign training ------------------------------------------------------------------------
   The office is answering "what does this driver need, and why", not browsing a module list — so
   the driver's own history sits on every card rather than in a separate table somewhere else. */

/* auto-FIT, not auto-fill: with six packs and a wide screen, auto-fill reserves empty tracks and the
   last row hangs off to one side. And the cards stretch, so a two-line name does not make its
   neighbour a different height. */
.training-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); gap: .85rem; align-items: stretch; }
@media (max-width: 640px) {
  .training-grid { grid-template-columns: 1fr; gap: .7rem; }
  .training-card { padding: .85rem .9rem; }
  .training-card-head { flex-wrap: wrap; gap: .35rem; }
  .training-facts { gap: .25rem .7rem; }
}

.training-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: start;
  padding: 1rem 1.05rem;
  border: 1px solid var(--line-100, #dde6e2);
  border-radius: 14px;
  background: var(--surface);
  cursor: pointer;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.training-card:hover { border-color: var(--ink-500); box-shadow: 0 2px 10px rgba(16,20,28,.06); }
/* A card with no checkbox has nothing in the first column, and the empty track left every name
   indented as though something were missing from beside it. */
.training-card:not(:has(> input)) { grid-template-columns: 1fr; }
.training-card:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--accent-glow, rgba(45,90,160,.16)); }
.training-card input { margin-top: 3px; width: 18px; height: 18px; }
/* A pack the driver is already part-way through. Dimmed and unselectable rather than absent — the
   office needs to see that it is already in hand, not wonder why it is missing. */
.training-card-blocked { opacity: 0.6; cursor: not-allowed; }
.training-card-blocked input { cursor: not-allowed; }

.training-card-body { display: flex; flex-direction: column; gap: .45rem; height: 100%; }
.training-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.training-card-head { margin-bottom: .3rem; }
.training-card-head strong { font-size: 1.02rem; line-height: 1.3; letter-spacing: -.01em; }
/* The label wraps the name, the facts and the note, so the body's own gap never reaches between
   them. Without this the numbers sit flush against the title. */
.training-card-body > label, .training-card-body > span:first-child { display: flex; flex-direction: column; }
/* Not --ink-500. The portal's muted token is #56685f, which measures 3.99:1 on white — under the
   threshold for text this size, everywhere it is used. Fixing it portal-wide would change every
   screen, so it is raised separately; this line is darkened so the new screen is at least readable. */
.training-card-meta { font-size: 0.76rem; color: #56685f; }
.training-card-note { font-size: 0.78rem; }

/* WHAT A PACK IS, AT A GLANCE.
   It used to be one run-on line - the module CODE, then lessons, questions, pass mark, validity and
   languages, all separated by middots - which wrapped into three cramped rows and led with
   ACCIDENT_PROCEDURE, a database identifier read by nobody. The numbers are what the office is
   comparing, so they are the thing that carries weight; the words around them do not. */
.training-facts { display: flex; flex-wrap: wrap; gap: .3rem .85rem; font-size: .78rem; color: #56685f; }
.training-facts b { color: var(--ink-900); font-weight: 750; font-variant-numeric: tabular-nums; }

/* Reading a pack is the SECOND thing this screen is for, so it sits at the foot of the card and
   weighs nothing. `margin-top: auto` is what squares the cards off: the row of buttons drops to the
   bottom whatever length the name ran to, so a grid of them lines up instead of stepping. */
.training-read { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; margin-top: auto; padding-top: .55rem; border-top: 1px solid var(--line); }
.training-read-label { font-size: .74rem; font-weight: 750; text-transform: uppercase; letter-spacing: .04em; color: #56685f; margin-right: .1rem; }
.training-read .button { min-height: 1.85rem; padding: .2rem .62rem; font-size: .76rem; border: 1px solid var(--line); border-radius: 999px; }
.training-read .button:hover { border-color: var(--ink-500); color: var(--ink-900); }

/* ---- folded sections ---- */

.fold { padding: 0; }
.fold-summary {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; cursor: pointer; list-style: none;
  border-radius: inherit;
}
.fold-summary::-webkit-details-marker { display: none; }
.fold-summary:hover { background: var(--surface-soft); }
.fold-summary:focus-visible { outline: 2px solid var(--ink-900); outline-offset: -2px; }
/* A finished group on Arriving documents, folded shut. It is a real <button> and not a <summary>,
   because the open state has to survive the repaint that follows confirming a document - a <details>
   would snap closed under him every time he acted on the list above it. */
.fold-head {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  width: 100%; padding: .1rem 0; border: 0; background: none; cursor: pointer;
  color: var(--ink-900); font: inherit; text-align: left;
}
.fold-head strong { font-size: 1.05rem; }
.fold-head:hover .fold-hint { color: var(--ink-900); border-color: var(--ink-500); }
.fold-head:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 8px; }
.fold-hint {
  flex: none; padding: .18rem .62rem; border: 1px solid var(--line); border-radius: 999px;
  color: #56685f; font-size: .74rem; font-weight: 750; text-transform: uppercase; letter-spacing: .04em;
}
/* (0377) A fold on the audit pack, which is different from a fold on Arriving documents. That one
   leaves its table out of the page entirely. This page IS the paper - "Print it" prints the screen -
   so a section not in the document could not be printed at all, and a pack that printed only what
   somebody remembered to expand would be complete-looking and short. Every row is always rendered;
   this hides it on screen, and the print rule below puts it back. */
/* An import row that is finished: filed, already had, or left out. Sorted below the work rather
   than hidden, and toned down so the eye stops at the boundary between the two without a heading
   having to announce it. Deliberately subtle - these rows are still the record of what was
   imported, and somebody asked to prove a duplicate was handled has to be able to read it. */
.history-item-done td { color: var(--ink-700); }
.history-item-done .table-subtext { opacity: .8; }

.fold-wrap { padding: 1.25rem 1.25rem 1rem; display: flex; flex-direction: column; gap: .4rem; }
.fold-wrap p { margin: 0; }
/* NAMED FOR THE AUDIT PACK, not `.fold-body`. That class was already carried by the <details> folds
   on Agreements, Work offers and ui.js, and giving it `display: none` here shut all three: their
   summaries still toggled `open` while the body stayed hidden, so "Send an agreement" and "Send a
   work offer" simply did nothing for two days. Shipped in 0377, found by the owner pressing them. */
.pack-fold-body { display: none; }
.pack-fold-body.is-open { display: block; }
@media print {
  .pack-fold-body { display: block !important; }
  .fold-hint { display: none; }
}

.fold-heading { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.fold-heading h3 { margin: 0; }
.fold-status { display: inline-flex; align-items: center; gap: 8px; flex: none; }
/* The item count is one of only three things a shut fold shows, so it does not sit at the portal's
   .muted grey. That grey failed AA outright when this was written (4.29:1); the driver-app palette
   lifted it to 5.93:1, which passes — but this line is what somebody reads to decide whether to open
   a fold at all, and --ink-700's 9.93:1 is worth the deliberate exception. It is still smaller and
   lighter than the heading, so it still reads as secondary. */
.fold-status .muted { color: var(--ink-700); font-size: 0.82rem; font-weight: 500; }
/* The triangle is drawn here rather than left to the browser, so it can turn. */
.fold-summary::after {
  content: "›"; font-size: 1.35rem; line-height: 1; color: var(--ink-500);
  transition: transform 120ms ease;
}
.fold[open] .fold-summary::after { transform: rotate(90deg); }
.fold[open] .fold-summary { border-bottom: 1px solid var(--line); border-radius: 0; }
.fold-body { padding: 14px 16px 16px; }
.fold-body > .table-scroll, .fold-body > .timeline, .fold-body > .activity-list { margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .fold-summary::after { transition: none; } }

/* ---- records the office produces ---- */

/* The facts an examiner asks for, laid out to be read down rather than hunted through prose. */
.fact-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 12px; margin: 0; }
.fact-list dt { color: var(--ink-500); font-size: .7rem; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.fact-list dd { margin: 3px 0 0; font-size: .95rem; font-weight: 600; }

/* The existing .summary-grid is scoped to one authoring screen, so a bare one renders as nothing.
   Same shape, unscoped, for any screen that wants three numbers across the top. */
.summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); gap: 10px; }
.summary-grid > div { display: flex; flex-direction: column; gap: 3px; padding: 10px 12px;
  background: var(--surface-soft); border: 1px solid var(--line); border-radius: 10px; }
.summary-grid > div > strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }


.filter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); gap: 10px; }
.filter-grid label { display: flex; flex-direction: column; gap: 4px; }
.filter-grid span { font-size: .72rem; font-weight: 650; color: var(--ink-500); text-transform: uppercase; letter-spacing: .03em; }

.record-items { display: flex; flex-direction: column; }
.record-item { display: flex; align-items: center; gap: 10px; padding: 9px 4px; }
.record-item + .record-item { border-top: 1px solid color-mix(in srgb, #000 8%, transparent); }
.record-item-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.record-item-body strong { font-weight: 500; font-size: .92rem; }
.record-item-body small { color: var(--ink-500); font-size: .78rem; }
/* A defect is the line somebody scrolling fifteen months of records is looking for. */
.record-item-defect { background: color-mix(in srgb, #b3261e 8%, transparent); border-radius: 8px; padding-left: 8px; padding-right: 8px; }
.record-item-defect .record-item-body strong { font-weight: 700; }
.record-item-note { color: #7a1d16; }

/* A small table of worked-out figures. Digits line up, because a column of consumption numbers is
   read by comparing them, not by reading each one. */
.record-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: .9rem; }
.record-table th { text-align: left; padding: 6px 8px; color: var(--ink-500); font-size: .72rem;
  text-transform: uppercase; letter-spacing: .04em; border-bottom: 1px solid var(--line); }
.record-table td { padding: 8px; border-bottom: 1px solid color-mix(in srgb, #000 6%, transparent);
  font-variant-numeric: tabular-nums; }
.record-table tr:last-child td { border-bottom: 0; }

/* The number somebody came to this screen for. */
.fuel-figure { display: flex; flex-direction: column; align-items: flex-end; flex: none; }
.fuel-figure strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.fuel-figure small { color: var(--ink-500); font-size: .7rem; }
.row-static { cursor: default; }
.row-when { color: var(--ink-500); font-size: .74rem; }

/* ---- editing the walkaround checklist ---- */

.wa-list { display: flex; flex-direction: column; gap: 12px; }
.wa-item {
  padding: 12px 14px;
  border-radius: var(--radius-md, 12px);
  background: var(--bg-sunken, #f6f7f9);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #000 8%, transparent);
}
/* An item that cannot be published yet is marked here, not only in the summary at the top: a list of
   forty questions is too long to go hunting through for the one with an empty field. */
.wa-item-incomplete { box-shadow: inset 0 0 0 2px color-mix(in srgb, #b3261e 55%, transparent); }
.wa-item-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.wa-item-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .78rem; color: var(--ink-500); }
.wa-item-move { margin-left: auto; display: inline-flex; gap: 4px; }
.wa-item-move button {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid color-mix(in srgb, #000 14%, transparent);
  background: var(--surface); cursor: pointer; font-size: .9rem; line-height: 1;
}
.wa-item-move button:disabled { opacity: .4; cursor: not-allowed; }
.wa-remove { color: #b3261e; font-weight: 700; }
.wa-item-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
.wa-item-grid label { display: flex; flex-direction: column; gap: 3px; }
.wa-item-grid span { font-size: .72rem; font-weight: 650; color: var(--ink-500); text-transform: uppercase; letter-spacing: .03em; }
.wa-critical { display: flex; align-items: flex-start; gap: 9px; margin-top: 10px; }
.wa-critical input { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.wa-critical span { display: flex; flex-direction: column; gap: 2px; }
.wa-critical small { color: var(--ink-500); font-size: .76rem; line-height: 1.45; }

@media (max-width: 720px) {
  .wa-item-grid { grid-template-columns: 1fr; }
}

.pill-row { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.reason-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: 10px; }
.reason-option {
  display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: start;
  padding: 12px 14px; border: 1px solid var(--line-100, #dde6e2); border-radius: 10px; cursor: pointer;
}
.reason-option:hover { border-color: var(--ink-500); }
.reason-option span { display: flex; flex-direction: column; gap: 2px; }
.reason-option small { color: #56685f; font-size: 0.76rem; }
.reason-option input { margin-top: 3px; }

.plain-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 5px; font-size: 0.9rem; }
.skipped-note {
  margin-top: 12px; padding: 11px 13px; border-radius: 9px; font-size: 0.85rem;
  background: rgba(245, 196, 81, 0.16); border: 1px solid rgba(180, 130, 20, 0.32);
}

/* ---- work offers, company details and contractor companies (0063 / 0064) ----------------------- */

/* A column of cards rather than a table. Each of these is a document about one company or one week's
   work, and a document does not read well as a row. */
.card-column { display: flex; flex-direction: column; gap: 16px; }

/* Label above value, wrapping into as many columns as fit. Used wherever a record is being read
   rather than edited. */
.detail-grid {
  display: grid; gap: 12px 24px; margin: 12px 0 0;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.detail-grid > div { min-width: 0; }
.detail-grid dt {
  margin: 0 0 2px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-700);
}
.detail-grid dd { margin: 0; overflow-wrap: anywhere; }

/* The price is the thing the eye goes to on an offer, so it sits opposite the name at the size it
   deserves rather than being one field among fifteen. */
.offer-price { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.offer-price strong { font-size: 1.35rem; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.offer-price .muted { font-size: 0.78rem; }

/* Deciding on a substitute is a separate act from reading the offer, so it is boxed off. */
.substitute-decision, .verify-row {
  margin-top: 14px; padding: 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-soft);
}
.substitute-decision p:first-child { margin-top: 0; }

.checkbox-row {
  display: flex; align-items: center; gap: 10px; margin: 12px 0;
  flex-direction: row;
}
.checkbox-row input { width: auto; margin: 0; }
.checkbox-row span { font-weight: 500; }

/* Not an error — nothing has gone wrong. Something has not been done yet, and doing it is the point
   of the panel, so it reads as amber rather than red. */
.warning-panel {
  border-left: 4px solid var(--warn);
  background: var(--warn-soft);
}
.warning-panel h3 { margin-top: 0; }

/* A hint under a field, not a placeholder inside it: a placeholder disappears exactly when somebody
   starts typing, which is when they need it. */
.field-hint { display: block; margin-top: 4px; color: var(--ink-700); font-size: 0.78rem; line-height: 1.4; }

/* A fold inside a form. Flatter than a panel-level one so it reads as part of the form rather than
   as a second card sitting inside the first. */
.sub-fold {
  margin: 14px 0; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-soft);
}
.sub-fold .fold-summary { padding: 10px 12px; }
.sub-fold .fold-heading h4 { margin: 0; font-size: 0.95rem; }
.sub-fold .fold-body { padding: 0 12px 12px; }
.sub-fold[open] .fold-summary { border-bottom: 1px solid var(--line); }

/* ---- agreements (0066) ---------------------------------------------------------------------------- */

/* Countersigning is the operator entering into a contract, not an approval step, so it is boxed off
   from the record above it and asks for the same three confirmations the contractor gave. */
.countersign {
  margin-top: 14px; padding: 16px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-soft);
}
.countersign > p:first-child { margin-top: 0; }
.agreement-card .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.78rem; }

/* A quiet action: available, but not competing with the one somebody came here to do. */
.button-quiet { background: none; border: 1px solid var(--line); color: var(--ink-700); }
.button-quiet:hover { background: var(--surface-soft); }


/* ---- the office in the dark ------------------------------------------------------------------------
   The driver app has had this since the wallet work and the office is the same product, so it gets
   the same choice. Light stays the default here — an office screen is usually a desk under a ceiling
   light, which is the opposite of a cab with the sun on the windscreen.

   Only tokens are redefined. Nothing below this block knows which theme it is in, which is the whole
   reason the surfaces and the state colours were turned into tokens first: there were fifty-four
   bare `white` backgrounds and seventeen copies of #f9fcfb, and each one would have been a white
   card on a black page.

   THE ACCENT IS LIFTED, NOT RECOLOURED. #34495e is a fine accent on paper and reads as almost black
   against a dark ground — a smudge rather than a colour. #8caee8 is the same navy at the lightness
   this ground needs. An earlier version of this theme used a neon mint here instead, which is a
   different colour rather than the same one, and it shouted from every button on the page.

   THE STATE COLOURS INVERT RATHER THAN DIM. A warning on a light page is a pale wash with a darker
   edge; the same wash on a dark page is a bright slab. So the fills go dark and the ink goes bright,
   which is the same relationship the other way up. */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* WARM CHARCOAL, NOT GREEN-BLACK. Every surface here used to be tinted green (#121a17, #0b100e),
     which is what made the whole dark theme feel like one loud colour rather than a dark room with
     things in it. These are the cream's own night form: the same warmth, taken down. */
  --navy-950: #141821;
  --navy-900: #1a2028;
  --navy-800: #232c38;
  /* Lifted, because the site's slate is a mid-tone that disappears against a dark ground. */
  --slate: #8fa5cf;

  --ink-900: #f2ede3;
  --ink-700: #c6bfb2;
  --ink-500: #958e80;
  --line: #3a352d;

  --surface: #1a1815;
  --surface-soft: #111010;
  --surface-alt: #201d19;
  --surface-blue: #1a2231;

  /* The accent, and the whole point of this change. It was #12b98a — a neon mint that shouted from
     every button on the page. This is the light theme's navy lifted until it works on a dark ground:
     the same hue, so the two themes are one product, at the lightness the ground actually needs. */
  --primary: #8caee8;
  --primary-dark: #6f93d2;

  /* Green stays where green MEANS something — "this is in order" — but it is a natural green now
     rather than the neon one, and it is no longer the accent, so it appears on a status and nowhere
     else. */
  --good: #6bbf8c;
  --good-soft: #16241c;
  --warn: #e8b563;
  --warn-soft: #2a2115;
  --warn-line: #463519;
  --bad: #ff8b82;
  --bad-soft: #2b1715;
  --bad-line: #4f221e;
  --info-soft: #161f2b;
  --muted: #bab2a4;
  --muted-soft: #262320;
  --watermark: rgba(242, 237, 227, 0.06);
  --info-line: #293850;

  /* Dark, because the accent is now a LIGHT colour: white on #8caee8 measures 2.2:1. This token is
     why the accent can be flipped at all without every filled button losing its label. */
  --on-accent: #101823;
  --accent-glow: rgba(140, 174, 232, 0.22);
  --accent-glow-strong: rgba(140, 174, 232, 0.38);
  /* A shadow is a darkening, and there is nothing darker than this ground to darken it with. Kept
     for depth but taken down, because a 50px black bloom on near-black is just a muddy halo. */
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
}

/* The page's own ground, which is painted on html and body rather than through a token. The green
   wash over it is halved: at full strength on a dark ground it reads as a stain rather than a tint. */
:root[data-theme="dark"] body {
  background:
    radial-gradient(circle at top right, rgba(140, 174, 232, 0.10), transparent 30rem),
    var(--surface-soft);
}

/* The sign-in split. Its left half is already a dark panel in the light theme, so in the dark theme
   it needs to separate from the page rather than blend into it. */
:root[data-theme="dark"] .auth-visual {
  border-right: 1px solid var(--line);
}

/* A white input on a dark card is the single most obvious way to get this wrong, and there are three
   different selectors that set one. They all take the surface below the card. */
:root[data-theme="dark"] .topbar {
  border-bottom-color: var(--line);
  background: rgba(17, 16, 16, 0.92);
}
:root[data-theme="dark"] .driver-bottom-nav {
  border-top-color: var(--line);
  background: rgba(17, 16, 16, 0.96);
}

:root[data-theme="dark"] .auth-form input,
:root[data-theme="dark"] .filter-bar input,
:root[data-theme="dark"] .filter-bar select,
:root[data-theme="dark"] .compact-select,
:root[data-theme="dark"] .account-field input,
:root[data-theme="dark"] .account-field select {
  background: var(--surface-alt);
}

/* ---- the data processing agreement, on the registration page --------------------------------------
   Shown in full and scrolled in place rather than hidden behind a link. The company is about to
   upload its drivers' passports; "you agreed to terms somewhere" is not a defence for either side.
   Bounded height so the form is still a form, and focusable so it can be read with a keyboard. */
.reg-dpa { margin: 1.5rem 0 0; }
.reg-dpa h3 { margin: 0 0 .35rem; font-size: 1rem; font-weight: 650; }
.reg-dpa-note { margin: 0 0 .75rem; font-size: .86rem; color: var(--muted); line-height: 1.55; }
.reg-dpa-body {
  max-height: 320px;
  overflow-y: auto;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-soft);
  font-size: .84rem;
  line-height: 1.65;
}
.reg-dpa-body:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.reg-dpa-body h4 { margin: 1.1rem 0 .4rem; font-size: .88rem; font-weight: 650; color: var(--ink-900); }
.reg-dpa-body h4:first-child { margin-top: 0; }
.reg-dpa-body p { margin: 0 0 .6rem; color: var(--muted); }
.reg-dpa-body strong { color: var(--ink-900); font-weight: 600; }
.reg-dpa-body ul { margin: 0 0 .7rem; padding-left: 18px; color: var(--muted); }
.reg-dpa-body li { margin-bottom: .3rem; }
.reg-dpa-body hr { border: 0; border-top: 1px solid var(--line); margin: 1rem 0 .8rem; }
.reg-dpa-accept {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  margin: .85rem 0 1.1rem;
  font-size: .86rem;
  line-height: 1.5;
}
.reg-dpa-accept input { margin-top: .2rem; flex: 0 0 auto; }

/* ---- retiring a lorry, from the fleet list --------------------------------------------------------
   The controls sit in their own column rather than behind a menu: an operator selling a truck should
   not have to hunt for the way to say so, and the status is already the column beside it.

   The select itself is `.compact-select`, the same one the filter bars use — a second, nearly
   identical style would make this one control look subtly foreign in its own portal. */
.fleet-row-actions { display: flex; gap: .5rem; align-items: center; justify-content: flex-end; }
.fleet-row-actions .compact-select { max-width: 11rem; }
.fleet-row-actions .compact-select:disabled { opacity: .55; }
.button-ghost.fleet-delete { color: var(--muted); }
.button-ghost.fleet-delete:hover { color: var(--bad); }

/* ---- the inbox, and the bell on the bar ------------------------------------------------------------
   Written into the middle of the fleet planner's section by mistake, where a guard that reads
   "nothing on the planner is smaller than 0.72rem" quite reasonably objected to a badge. */
/* The bell, and the number on it. A badge that reads "0" is a badge saying nothing loudly, so there
   is no badge at all when there is nothing unread. */
.inbox-bell { position: relative; display: inline-grid; place-items: center; text-decoration: none; }
.inbox-badge {
  position: absolute; top: -.25rem; right: -.3rem;
  min-width: 1.15rem; padding: 0 .25rem;
  border-radius: 999px; background: var(--bad); color: var(--on-accent);
  font-size: .68rem; font-weight: 800; line-height: 1.2; text-align: center;
  font-variant-numeric: tabular-nums;
}

.inbox-list { display: grid; gap: 0; padding: 0; }
.inbox-item {
  display: flex; align-items: center; justify-content: space-between; gap: .8rem;
  padding: .85rem 1rem; border-bottom: 1px solid var(--line);
}
.inbox-item:last-child { border-bottom: 0; }
.inbox-what { margin: 0 0 .15rem; font-weight: 600; }
/* Unread is a mark down the side, not a colour wash: the words are the thing being read. */
.inbox-unread { border-left: 3px solid var(--p-info); padding-left: calc(1rem - 3px); }
.phone-layout .inbox-item { flex-direction: column; align-items: flex-start; }
.phone-layout .inbox-item .button { width: 100%; text-align: center; }

/* ---- fleet planner ---------------------------------------------------------------------------------
   A wall of dates, so colour and mark do the reading before the words do. Five bands, and one of them
   — "not tracked" — is deliberately not a soft grey: a check nobody is watching is not a quiet state,
   it is the state where a lorry goes over its date and nothing anywhere says a word.

   ITS OWN COLOURS, ON PURPOSE, AND ONLY HERE.

   The office palette is warm and low-contrast by design — brick red, brown-amber, muted green. That
   is right for a page you read a paragraph of and wrong for a grid of two hundred dates you SCAN.
   The owner asked for the brighter set from the layout he sent, so this screen gets a set of its own,
   defined below and used nowhere else. The rest of the office keeps its identity untouched.

   Everything is also a size up from where it started: he could not read it. */

.planner-scope {
  /* One step down from the #d92d20 in his picture: on its own pale ground that red measured 4.44,
     and the OVERDUE label is small bold text where 4.5 is the floor. Same red, still bright. */
  --p-bad: #b42318;      --p-bad-bg: #fef3f2;   --p-bad-line: #fda29b;
  --p-warn: #b54708;     --p-warn-bg: #fffaeb;  --p-warn-line: #fec84b;
  --p-info: #175cd3;     --p-info-bg: #eff8ff;
  --p-good: #027a48;     --p-good-bg: #ecfdf3;
  --p-unknown: #475467;  --p-unknown-bg: #f2f4f7;
}
:root[data-theme="dark"] .planner-scope {
  /* Lifted and desaturated a step: the same five hues have to sit on charcoal without glowing. */
  --p-bad: #ff8b82;      --p-bad-bg: #2e1a18;   --p-bad-line: #7a3b34;
  --p-warn: #f5b544;     --p-warn-bg: #2c2415;
  --p-info: #7cb1ff;     --p-info-bg: #16233a;
  --p-good: #55d69a;     --p-good-bg: #14291f;
  --p-unknown: #b6b0a4;  --p-unknown-bg: #232019;
}

/* --- the numbers along the top --- */
/* A driver's walkaround book: names first, then the month and the filed checks. */
.walkaround-books { container: check-books / inline-size; }
/* Read aloud, never drawn. It was scoped to the walkaround books, so the Ask screen drew its "Your question" label and the catalogue its "Identity" legend. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.walkaround-books [hidden] { display: none !important; }
.wcb-driver-panel { max-width: 64rem; margin: 0 auto; padding: 0; overflow: hidden; }
.wcb-driver-heading { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; padding: 1.2rem 1.4rem; border-bottom: 1px solid var(--line); }
.wcb-driver-heading h2 { margin: 0; font-size: 1.15rem; }
.wcb-driver-search { width: min(100%, 20rem); }
.wcb-driver-search input { width: 100%; }
.wcb-driver-search input, .wcb-month-picker input { min-height: 2.65rem; padding: .6rem .75rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink-900); font: inherit; }
.wcb-driver-search input:focus-visible, .wcb-month-picker input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.wcb-driver { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .9rem 1.4rem; border-bottom: 1px solid var(--line); }
.wcb-driver:last-child { border-bottom: 0; }
.wcb-driver:hover { background: var(--surface-alt); }
.wcb-driver strong { display: block; font-size: .98rem; }
.wcb-driver small { color: var(--ink-500); }
.wcb-driver .button { min-width: 5.8rem; gap: .8rem; }
.wcb-driver-panel > .muted { padding: 1rem 1.4rem; }
.wcb-book { padding: 1.25rem; }
.wcb-book-heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1.5rem; }
.wcb-book-heading h2 { margin: .2rem 0 0; font-size: 1.5rem; }
.wcb-month-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .85rem; margin-bottom: 1rem; }
.wcb-month-step, .wcb-month-picker { display: flex; align-items: center; gap: .6rem; }
.wcb-month-step h3 { min-width: 11rem; margin: 0; text-align: center; font-size: 1.1rem; }
.wcb-month-arrow { padding: .35rem .75rem; font-size: 1.4rem; min-width: 2.5rem; }
.wcb-month-picker label { font-size: .78rem; color: var(--ink-500); }
.wcb-month-picker input { width: 10rem; min-height: 2.65rem; }
.wcb-book-key { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .65rem; margin-bottom: 1rem; font-size: .77rem; color: var(--ink-500); }
.wcb-legend, .wcb-legend > span { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.wcb-legend { gap: 1rem; }
.wcb-status-dot { display: inline-block; flex: none; width: .45rem; height: .45rem; border-radius: 50%; background: currentColor; }
.wcb-key-clear { color: var(--good); }
.wcb-key-defects { color: var(--warn); }
.wcb-key-stopped { color: var(--bad); }
.wcb-weekdays { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border: 1px solid var(--line); border-radius: 12px 12px 0 0; background: var(--surface-alt); }
.wcb-weekdays span { padding: .65rem; font-size: .75rem; font-weight: 700; color: var(--ink-500); text-align: center; }
.wcb-calendar { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px; border: 1px solid var(--line); border-top: 0; border-radius: 0 0 12px 12px; overflow: hidden; background: var(--line); }
.wcb-day { min-width: 0; min-height: 8rem; padding: .55rem; background: var(--surface); }
.wcb-outside { background: var(--surface-alt); }
.wcb-day-number { display: grid; place-items: center; width: 1.7rem; height: 1.7rem; margin-bottom: .35rem; font-size: .8rem; font-weight: 700; color: var(--ink-700); }
.wcb-today .wcb-day-number { border-radius: 50%; background: var(--primary); color: var(--on-accent); }
.wcb-day-checks { display: grid; gap: .4rem; }
.wcb-entry { display: grid; gap: .15rem; min-width: 0; padding: .45rem .5rem; border: 1px solid var(--line); border-left: 3px solid currentColor; border-radius: 7px; text-decoration: none; overflow-wrap: anywhere; }
.wcb-entry:hover { filter: brightness(.96); box-shadow: 0 2px 6px rgba(0,0,0,.06); }
.wcb-entry:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.wcb-entry-clear { color: var(--good); background: var(--good-soft); }
.wcb-entry-defects { color: var(--warn); background: var(--warn-soft); }
.wcb-entry-stopped { color: var(--bad); background: var(--bad-soft); }
.wcb-entry-unknown { color: var(--ink-500); background: var(--surface-alt); }
.wcb-entry-time { display: flex; align-items: center; gap: .35rem; font-size: .78rem; font-weight: 750; font-variant-numeric: tabular-nums; }
.wcb-entry-vehicle { font-size: .75rem; font-weight: 650; }
.wcb-entry-outcome { font-size: .72rem; }
.wcb-calendar-note { margin: .85rem 0 0; font-size: .77rem; color: var(--ink-500); }
@container check-books (max-width: 45rem) {
  .wcb-book { padding: .75rem; }
  .wcb-month-step h3 { min-width: 9rem; font-size: 1rem; }
  .wcb-day { padding: .3rem; min-height: 6rem; }
  .wcb-entry { padding: .35rem .25rem; }
  .wcb-entry-outcome { display: none; }
}
@container check-books (max-width: 32rem) {
  .wcb-book-heading { align-items: flex-start; flex-direction: column; margin-bottom: 1rem; }
  .wcb-book-heading h2 { font-size: 1.25rem; }
  .wcb-month-toolbar, .wcb-month-picker { gap: .4rem; }
  .wcb-month-picker label { display: none; }
  .wcb-weekdays span { padding: .5rem .1rem; font-size: .72rem; }
  .wcb-day { padding: .15rem; }
  .wcb-day-number { font-size: .72rem; }
  .wcb-entry { border-left-width: 2px; padding: .4rem .15rem; }
  .wcb-entry-time { font-size: .72rem; justify-content: center; }
  .wcb-entry-time .wcb-status-dot, .wcb-entry-vehicle { display: none; }
  .wcb-driver-heading, .wcb-driver { padding: .8rem; }
}

.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13.5rem, 1fr));
  gap: 1rem;
  margin-bottom: 1.4rem;
}
.kpi {
  display: flex; align-items: center; gap: 1rem;
  padding: 1.25rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
}
.kpi-icon {
  flex: 0 0 auto;
  width: 3.4rem; height: 3.4rem;
  display: grid; place-items: center;
  border-radius: 14px;
}
.kpi-icon svg { width: 1.8rem; height: 1.8rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.kpi-icon svg .dot { fill: currentColor; stroke: none; }
.kpi-body { display: flex; flex-direction: column; min-width: 0; gap: .1rem; }
.kpi-value { font-size: 2.5rem; line-height: 1; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink-900); }
.kpi-label { font-size: 1rem; font-weight: 700; color: var(--ink-900); }
.kpi-hint { font-size: .82rem; color: var(--ink-500); }

.kpi-bad     .kpi-icon { background: var(--p-bad-bg);     color: var(--p-bad); }
.kpi-unknown .kpi-icon { background: var(--p-unknown-bg); color: var(--p-unknown); }
.kpi-warn    .kpi-icon { background: var(--p-warn-bg);    color: var(--p-warn); }
.kpi-soft    .kpi-icon { background: var(--p-info-bg);    color: var(--p-info); }
.kpi-good    .kpi-icon { background: var(--p-good-bg);    color: var(--p-good); }
.kpi-plain   .kpi-icon { background: var(--surface-alt);  color: var(--ink-700); }
.kpi-bad { border-color: var(--p-bad-line); }

/* The garage's own list. A row is a name, what it reads as on paper, and a figure — the figure right
   where the eye goes for one. */
.prices-list { padding: 0; }
.price-item {
  display: flex; align-items: center; gap: .9rem;
  padding: .85rem 1rem; border-bottom: 1px solid var(--line);
}
.price-item:last-child { border-bottom: 0; }
.price-item > div:first-child { flex: 1 1 auto; min-width: 0; }
.price-name { margin: 0 0 .15rem; font-weight: 600; }
.price-figure { text-align: right; font-variant-numeric: tabular-nums; }
.price-figure strong { display: block; font-size: 1.05rem; }
/* Archived is faded, not hidden: it is still a thing this garage once charged for. */
.price-archived { opacity: .6; }
.phone-layout .price-item { flex-wrap: wrap; }
.phone-layout .price-item > div:first-child { flex: 1 0 100%; }
.phone-layout .price-figure { text-align: left; }
.phone-layout .price-item .button { margin-left: auto; }


/* A tile that filters is a button, and has to look like one that can be pressed and can be ON. The
   markup is a <button>, so the browser's own styling has to be cleared first. */
button.kpi {
  width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer;
  transition: border-color .12s ease, box-shadow .12s ease;
}
button.kpi:hover { border-color: var(--ink-500); }
button.kpi:focus-visible { outline: 2px solid var(--p-info); outline-offset: 2px; }
.kpi-on { box-shadow: inset 0 0 0 2px var(--p-info); }
.filter-said { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin: -.4rem 0 1rem; }

/* --- table beside a panel --- */
.planner-split { display: grid; grid-template-columns: minmax(0, 1fr) 21rem; gap: 1.2rem; align-items: start; }
@media (max-width: 1150px) { .planner-split { grid-template-columns: minmax(0, 1fr); } }
.planner-aside { position: sticky; top: 1rem; }

/* --- the ring --- */
.donut-body { display: grid; gap: 1.1rem; justify-items: center; }
.donut { width: 11rem; height: 11rem; transform: rotate(-90deg); }
.donut .ring { fill: none; stroke-width: 15; }
.donut .ring-track { stroke: var(--surface-alt); }
.donut .ring-bad { stroke: var(--p-bad); }
.donut .ring-unknown { stroke: var(--p-unknown); }
.donut .ring-warn { stroke: var(--p-warn); }
.donut .ring-soft { stroke: var(--p-info); }
.donut .ring-good { stroke: var(--p-good); }

.donut-legend { list-style: none; margin: 0; padding: 0; width: 100%; display: grid; gap: .55rem; }
.donut-legend li { display: flex; align-items: center; gap: .6rem; font-size: .95rem; }
.donut-legend .legend-label { flex: 1 1 auto; color: var(--ink-700); }
.donut-legend .legend-value { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 1.05rem; color: var(--ink-900); }
.donut-legend .dot { width: .75rem; height: .75rem; border-radius: 50%; flex: 0 0 auto; }
.dot-bad { background: var(--p-bad); }
.dot-unknown { background: var(--p-unknown); }
.dot-warn { background: var(--p-warn); }
.dot-soft { background: var(--p-info); }
.dot-good { background: var(--p-good); }

/* --- the grid --- */
.planner-panel { overflow: hidden; }
.ptable { width: 100%; border-collapse: collapse; font-size: 1rem; }
.ptable th {
  text-align: left; white-space: nowrap; vertical-align: bottom;
  padding: .85rem .9rem; border-bottom: 2px solid var(--line);
}
.pth-name { display: block; font-size: .95rem; font-weight: 700; color: var(--ink-900); }
.pth-sub { display: block; font-size: .76rem; font-weight: 500; color: var(--ink-500); }
.pth-vehicle { min-width: 12rem; }

.prow { cursor: pointer; border-bottom: 1px solid var(--line); }
.prow:hover { background: var(--surface-alt); }
.prow.prow-selected { background: var(--surface-blue); }
.prow td { padding: .8rem .9rem; vertical-align: middle; }
.prow td:first-child strong { font-size: 1.05rem; }
.prow-sub { display: block; font-size: .82rem; color: var(--ink-500); }
.prow td:first-child { border-left: 5px solid transparent; }
.prow-bad td:first-child { border-left-color: var(--p-bad); }
.prow-unknown td:first-child { border-left-color: var(--p-unknown); }
.prow-warn td:first-child { border-left-color: var(--p-warn); }
.prow-soft td:first-child { border-left-color: var(--p-info); }
.prow-good td:first-child { border-left-color: var(--p-good); }

.pcell { white-space: nowrap; }
.pcell-line { display: flex; align-items: center; gap: .4rem; }
.pcell-date { font-variant-numeric: tabular-nums; font-weight: 600; font-size: .98rem; color: var(--ink-900); }
.pcell-when { display: block; font-size: .8rem; color: var(--ink-500); }
.pcell-flag {
  display: block; font-size: .72rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--p-bad);
}
.mark { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.mark .bar { stroke: var(--surface); }

.pcell-good .pcell-date, .pcell-good .mark { color: var(--p-good); }
.pcell-soft { background: var(--p-info-bg); }
.pcell-soft .pcell-date, .pcell-soft .mark { color: var(--p-info); }
.pcell-warn { background: var(--p-warn-bg); }
.pcell-warn .mark { color: var(--p-warn); fill: var(--p-warn); }
.pcell-warn .pcell-date { color: var(--p-warn); }
.pcell-bad { background: var(--p-bad-bg); }
.pcell-bad .pcell-date { color: var(--p-bad); }
.pcell-bad .mark { color: var(--p-bad); fill: var(--p-bad); }

.pchip {
  display: inline-block; padding: .3rem .7rem; border-radius: 999px;
  font-size: .85rem; font-weight: 700;
  background: var(--p-unknown-bg); color: var(--p-unknown);
}
.pchip-plain { background: var(--surface-alt); color: var(--ink-700); font-weight: 600; }
.pchip-good { background: var(--p-good-bg); color: var(--p-good); }
/* The chip had two looks — green for "active", grey for everything else — so on the panel that carries
   the Book button, a lorry that is OFF THE ROAD was the same colour as one that had been sold. The
   consequence of missing that one is a vehicle sent out that should not be, so it gets a colour of its
   own and a line to stop the eye. */
.pchip-bad {
  background: var(--p-bad-bg);
  color: var(--p-bad);
  box-shadow: inset 0 0 0 1px var(--p-bad-line);
}

/* --- the vehicle beside the table --- */
.side-card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 1.2rem; }
.side-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.side-head h3 { margin: 0; font-size: 1.35rem; }
.side-sub { font-size: .88rem; color: var(--ink-500); }
.side-close { background: none; border: 0; font-size: 1.6rem; line-height: 1; cursor: pointer; color: var(--ink-500); }
.side-title { margin: 1.2rem 0 .5rem; font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-500); }

/* Opening a job from Work history (0366). The side-card already existed for the fleet planner; these
   are the parts a maintenance record needs that a planner row did not. */
.side-card::backdrop { background: rgba(16, 20, 28, .45); }
.side-card { width: min(100%, 38rem); max-height: 86vh; overflow-y: auto; }
.side-body { margin-top: 1rem; }
.side-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .8rem 1.2rem; margin: 0; }
.side-facts dt { font-size: .74rem; font-weight: 750; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-500); }
.side-facts dd { margin: .15rem 0 0; }
.side-block { margin-top: 1.3rem; }
.side-block h4 { margin: 0 0 .5rem; font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-500); }
.side-block p { margin: 0; }
.job-defects { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.job-defects li { display: flex; align-items: flex-start; gap: .55rem; }
/* .action-row justifies to the end, which is right under a form and wrong under a heading: the
   document button floated off to the far edge of the panel, away from the words naming it. */
.side-block .action-row { justify-content: flex-start; flex-wrap: wrap; }
/* The whole row opens the job, so it has to look like it does. */
.m-row { cursor: pointer; }
.m-row:hover { background: var(--surface-soft, rgba(0,0,0,.03)); }
.m-row:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.m-search { min-width: 18rem; flex: 1 1 18rem; }
/* What a time box was understood to mean, under the box. The fitter writes hours; this says it back
   in minutes, which is what makes 0.15 visibly not a quarter of an hour. */
/* A size that came from the last sheet rather than from the fitter's hand. Marked so it is checked,
   and it stops being marked the moment they touch it. */
.insp-carried { border-style: dashed !important; }

.insp-said { display: block; font-size: .72rem; color: var(--muted); margin-top: .15rem; }
.insp-said-bad { color: var(--danger, #b3261e); font-weight: 600; }
.insp-bad { border-color: var(--danger, #b3261e) !important; }

.side-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.side-list li { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .55rem 0; border-bottom: 1px solid var(--line); font-size: .98rem; }
.side-list li:last-child { border-bottom: 0; }
.side-name { color: var(--ink-700); }
.side-value { display: inline-flex; align-items: center; gap: .35rem; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink-900); }
.side-value.side-good { color: var(--p-good); }
.side-value.side-soft { color: var(--p-info); }
.side-value.side-soft .mark { color: var(--p-info); }
.side-value.side-warn { color: var(--p-warn); }
.side-value.side-warn .mark { color: var(--p-warn); fill: var(--p-warn); }
.side-value.side-bad { color: var(--p-bad); }
.side-value.side-bad .mark { color: var(--p-bad); fill: var(--p-bad); }
.side-value.side-unknown { color: var(--p-unknown); font-weight: 500; font-style: italic; }
.side-note { font-size: .86rem; color: var(--ink-500); margin: .9rem 0 0; }
.side-actions { display: grid; gap: .55rem; margin-top: 1.1rem; }

/* --- room to work ---------------------------------------------------------------------------------
   The shell caps its content at 96rem and centres it, which is right for a page of prose and wrong
   for a grid two hundred dates wide: on a large monitor the table sat in the middle with empty cream
   on both sides. This screen asks for the whole width instead. */
.content-area.content-wide { max-width: none; }

.content-wide .planner-split { grid-template-columns: minmax(0, 1fr) 23rem; gap: 1.5rem; }
/* Repeated below the widening rule, not above it: the shared breakpoint further up the file loses to
   anything written after it, and without this the side panel stayed wedged beside the table at 900px
   with both columns too narrow to read. */
@media (max-width: 1150px) {
  .content-wide .planner-split { grid-template-columns: minmax(0, 1fr); }
}

/* Docked, the page is the menu's width narrower than the window, and a media query measures the
   window. This split was written after the old rail went, for a page as wide as the window, so it gets
   a docked copy at 1150px plus the menu. (The 1180, 1000 and 960 rules date from when a 17rem rail
   stood beside every page: docked, they get back the width they were drawn for.) */
@media (max-width: 1430px) {
  .nav-docked .planner-split, .nav-docked .content-wide .planner-split { grid-template-columns: minmax(0, 1fr); }
}

/* The spare room goes to the DATE columns. Shrinking the registration column to its content is what
   does it — the browser then shares what is left between the six that carry the dates.

   Deliberately NOT `table-layout: fixed`. Fixed divides the width evenly whatever the content needs,
   which on a 1280 laptop squeezed the date columns to 87px and clipped fifty-one cells. Auto keeps
   every date legible and lets the table scroll inside its own box when the screen is genuinely too
   small — a scroll bar is a smaller failure than a hidden expiry date. */
.content-wide .pth-vehicle { width: 1%; min-width: 12rem; }
.content-wide .prow td { padding: .95rem 1.1rem; }
.content-wide .ptable th { padding: 1rem 1.1rem; }

/* The action lives on the check itself in the side panel. Small, quiet, and never in the grid: a
   table cell is too small a target for something that writes to a compliance record. */
.side-list li { gap: .5rem; }
.side-done {
  flex: 0 0 auto;
  padding: .28rem .6rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--ink-700);
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  cursor: pointer;
}
.side-done:hover:not(:disabled) { background: var(--p-good-bg); color: var(--p-good); border-color: var(--p-good); }
.side-done:disabled { opacity: .35; cursor: default; }

/* ---- setting up ------------------------------------------------------------------------------------
   The first screen a new company sees. It has one job: make the order obvious, and make the six
   confirmations feel like decisions rather than a form to get past. */
.start-scope { display: grid; gap: 1.2rem; }

.start-intro h2 { margin: 0 0 .4rem; font-size: 1.5rem; }
.start-intro p { max-width: 60ch; }

.start-steps { list-style: none; margin: 1.1rem 0 0; padding: 0; display: grid; gap: .7rem; }
.start-step { display: flex; align-items: flex-start; gap: .8rem; }
.start-step-no {
  flex: 0 0 auto; width: 1.9rem; height: 1.9rem;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--surface-alt); color: var(--ink-700);
  font-weight: 700; font-size: .9rem;
}
.start-step-done .start-step-no { background: var(--good-soft); color: var(--good); }
.start-step-done strong { color: var(--ink-500); font-weight: 600; }
.start-step-detail { display: block; font-size: .85rem; color: var(--ink-500); }
.start-clear { margin-top: 1rem; color: var(--good); }

.start-checks { display: grid; gap: .8rem; }
.start-check {
  display: flex; align-items: center; justify-content: space-between; gap: 1.2rem; flex-wrap: wrap;
  padding: 1rem 1.1rem;
  border: 1px solid var(--line); border-radius: 14px; background: var(--surface);
}
.start-check-head { display: flex; align-items: flex-start; gap: .8rem; flex: 1 1 22rem; min-width: 0; }
.start-check-head h4 { margin: 0 0 .15rem; font-size: 1.05rem; }
.start-check-sub { display: block; font-size: .85rem; color: var(--ink-500); max-width: 52ch; }

.start-dot {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem; margin-top: .1rem;
  border-radius: 50%; border: 2px dashed var(--line);
}
.start-tick {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem; margin-top: .1rem;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--good-soft); color: var(--good);
}
.start-tick svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

.start-check-done { background: var(--surface-alt); }
.start-check-done h4 { color: var(--ink-700); }

.start-check-action { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.start-suggested { font-size: .85rem; color: var(--ink-500); }
.start-suggested strong { color: var(--ink-900); }
.start-bounds { font-size: .76rem; color: var(--ink-500); }

.start-interval { display: inline-flex; align-items: center; gap: .4rem; }
.start-interval input[type="number"] {
  width: 4.5rem; padding: .45rem .55rem; font: inherit; font-size: .95rem;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink-900);
  font-variant-numeric: tabular-nums;
}
.start-interval select {
  padding: .45rem .55rem; font: inherit; font-size: .95rem;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink-900);
}
.start-unit-fixed { font-size: .95rem; color: var(--ink-700); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- one spreadsheet, several operators -------------------------------------------------------------
   A transport manager holding four licences keeps one file. On this platform those four are four
   tenants, so the import has to be told which rows are which — and told, not guessed at. */
.company-picker { margin: .9rem 0 0; padding: .9rem 1rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); }
.company-picker > p:first-child { margin-top: 0; }
.company-values { display: flex; flex-wrap: wrap; gap: .5rem .9rem; margin: .6rem 0 .2rem; }
.company-value { display: flex; align-items: center; gap: .45rem; font-size: .9rem; cursor: pointer; }
.company-value input { flex: 0 0 auto; }
.company-value strong { font-weight: 700; }
.company-value .muted { font-size: .78rem; margin-left: .3rem; }

/* ---- maintenance ------------------------------------------------------------------------------------
   Spend and repairs. The bars are a ranking, not a chart: an operator wants to know which lorry is
   eating the money, and the exact width of the third bar is not the point. */
.m-reports { display: grid; grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr)); gap: 1.2rem; margin-bottom: 1.2rem; }
.m-subhead { margin: 1.2rem 0 .5rem; font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-500); }

.mbars { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.mbars li { display: grid; grid-template-columns: 7rem 1fr auto 2.2rem; align-items: center; gap: .6rem; font-size: .92rem; }
.mbar-label { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mbar-track { height: .55rem; border-radius: 999px; background: var(--surface-alt); overflow: hidden; }
.mbar-fill { display: block; height: 100%; border-radius: 999px; background: var(--p-info); }
.mbar-value { font-variant-numeric: tabular-nums; font-weight: 700; }
.mbar-count { font-variant-numeric: tabular-nums; font-size: .82rem; color: var(--ink-500); text-align: right; }
/* The rows past the cut. One cell, so it must break out of the four-column grid the bars sit in,
   or it renders as a label in a 7rem box with three empty columns beside it. */
.mbars li.mbar-rest { display: block; font-size: .85rem; padding-top: .15rem; }
/* (0387) The two controls at the end of a cost row: the paper, and removing the row. A label styled
   as a button is the file picker itself, the same trick the historical import uses, so the press that
   opens the picker is the press on the words. */
.fc-row-actions { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.fc-attach { cursor: pointer; }
/* A bar's label is now a button, and must not look like one: it sits in the same grid cell the span
   did, keeps the same weight and truncation, and only says it is pressable on hover and focus. */
.mbar-press { appearance: none; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; font-weight: 600; color: inherit; text-align: left; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mbar-press:hover, .mbar-press:focus-visible { text-decoration: underline; }
.fc-narrowed { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; }

.m-who { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.m-who li { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; flex-wrap: wrap; font-size: .95rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line); }
.m-who li:last-child { border-bottom: 0; }
.m-who strong { font-variant-numeric: tabular-nums; font-size: 1.05rem; }

.m-form .form-grid { gap: .8rem; }
.m-work { max-width: 22rem; white-space: normal; }
/* A PMI or a tacho reader writes work_done as a JSON ARRAY, and the cell used to print the array.
   Several lines are now several lines. */
.work-lines { margin: 0; padding-left: 1.1rem; }
.work-lines li { margin: 0 0 .18rem; }
.work-lines li:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------------------------------------
   The service portal — a garage and an operator looking at the same booking from two sides.

   Every colour here is a token. The one thing this block adds to the palette is a LEFT EDGE on a
   booking card: a booking has a state that decides what you do next, and a pill alone at the top of a
   card is read after the card rather than before it. The edge is the first thing the eye lands on
   going down a column of them.

   Green still means only "in order" — a booking that is agreed and needs nothing. Anything waiting on
   a person is warm, because a person has to act.
   --------------------------------------------------------------------------------------------------- */

.service-scope { display: grid; gap: 1rem; }

.section-title { margin: .75rem 0 0; font-size: .95rem; font-weight: 800; color: var(--ink-700); }

/* The card, and its edge. */
.booking-card { border-left: 4px solid var(--line); }
/* The status pills elsewhere hold one word, so `capitalize` reads as a proper noun. These hold a
   short phrase, and title case turns "not recorded yet" into a headline. */
.booking-card .status-pill, .service-scope .status-pill { text-transform: none; }
.booking-good { border-left-color: var(--good); }
.booking-warn { border-left-color: var(--warn); }
.booking-bad { border-left-color: var(--bad); }
.booking-plain { border-left-color: var(--muted); }

/* Whose turn it is. The one addressed to the reader is filled; the other is a quiet line, because a
   column where every row shouts is a column nobody reads. */
.booking-turn { margin: .4rem 0 0; color: var(--ink-500); font-size: .85rem; }
.booking-turn-yours {
  padding: .45rem .6rem; border-radius: var(--radius-sm);
  background: var(--warn-soft); color: var(--warn); font-weight: 750;
}

/* What to do next, in one line. */
.booking-step { margin: .45rem 0 0; color: var(--ink-700); font-size: .85rem; font-weight: 650; }

.booking-actions { margin-top: .7rem; }

/* How the date was agreed. Folded away because it matters on the day of an argument and not before. */
.booking-history { margin-top: .7rem; border-top: 1px solid var(--line); padding-top: .5rem; }
.booking-history summary { cursor: pointer; color: var(--ink-500); font-size: .78rem; font-weight: 700; }
.booking-history-list { margin: .5rem 0 0; padding-left: 1.1rem; display: grid; gap: .3rem; }
.booking-history-list li { color: var(--ink-700); font-size: .82rem; line-height: 1.5; }

/* The forms inside a card: completing a job, offering another day. */
.booking-form { display: grid; gap: .6rem; margin-top: .7rem; padding: .8rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-alt); }
.booking-form label { display: grid; gap: .25rem; color: var(--ink-500);
  font-size: .74rem; font-weight: 750; text-transform: uppercase; letter-spacing: .02em; }
.booking-form input, .booking-form select, .booking-form textarea {
  width: 100%; padding: .5rem .6rem; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink-900); font: inherit; text-transform: none;
  letter-spacing: normal;
}
.booking-form textarea { resize: vertical; }

/* Four small boxes in a row on a desk, stacked on a phone. minmax(0,…) so a long select cannot
   push the row wider than the card it sits in. */
.field-row { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); }
.field-row > label { min-width: 0; }

/* Booking from the planner: the form opens inside the side card, under the check it belongs to. */
.side-booking { display: grid; gap: .55rem; margin-top: .8rem; padding: .75rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-alt); }
.side-booking label { display: grid; gap: .25rem; color: var(--ink-500);
  font-size: .72rem; font-weight: 750; text-transform: uppercase; letter-spacing: .02em; }
.side-booking input, .side-booking select {
  width: 100%; padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink-900); font: inherit; text-transform: none;
  letter-spacing: normal;
}

/* The Book button beside Done. Quieter than Done: recording what happened is the commoner act. */
.side-book {
  padding: .3rem .55rem; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-700);
  font: inherit; font-size: .72rem; font-weight: 750; cursor: pointer;
}
.side-book:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.side-book:disabled { opacity: .4; cursor: not-allowed; }

.planner-booking-actions { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
.planner-booking-actions .button { padding: .2rem .5rem; min-height: 1.8rem; font-size: .75rem; box-shadow: none; }
.side-list li:has(.side-booked) { flex-wrap: wrap; }
.phone-layout .planner-booking-actions .button { min-height: 2.6rem; }
.booking-details .planner-booking-actions { gap: .5rem; }
.booking-details .planner-booking-actions .button { min-height: 2.4rem; padding: .45rem .8rem; font-size: .85rem; }
.booking-detail-list { display: grid; gap: .8rem; margin: 0; }
.booking-detail-list dt { color: var(--ink-500); font-size: .75rem; font-weight: 750; }
.booking-detail-list dd { margin: .15rem 0 0; color: var(--ink-900); font-size: .95rem; overflow-wrap: anywhere; }
.booking-detail-note { white-space: pre-wrap; }

/* Ticking the lorries a garage is to hold. */
.chip-grid { display: flex; flex-wrap: wrap; gap: .45rem; margin: .5rem 0 .8rem; }
.chip-check {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .35rem .6rem; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-alt); color: var(--ink-700);
  font-size: .8rem; font-weight: 700; cursor: pointer;
}
.chip-check:has(input:checked) { border-color: var(--primary); background: var(--surface-blue); color: var(--primary); }
.chip-check input { accent-color: var(--primary); }

/* Taking one lorry back, from the chip it sits on. */
.chip-x {
  margin-left: .35rem; padding: 0 .15rem; border: 0; border-radius: 999px;
  background: transparent; color: var(--ink-500); font: inherit; font-weight: 800; cursor: pointer;
  line-height: 1;
}
.chip-x:hover { color: var(--bad); }

/* The code a garage hands out. Read aloud down a telephone, so: monospaced, wide, unmissable. */
.connect-code {
  margin: .3rem 0 .7rem; padding: .7rem .9rem;
  border: 1px dashed var(--line); border-radius: var(--radius-sm);
  background: var(--surface-alt); color: var(--ink-900);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.4rem; font-weight: 700; letter-spacing: .12em; text-align: center;
}

@media (max-width: 720px) {
  .connect-code { font-size: 1.1rem; letter-spacing: .08em; }
  .booking-actions { flex-direction: column; align-items: stretch; }
}

/* The invitation screen shows one or more real cards inside the sign-in card, so it needs more than
   the 42rem a "you have no access" message wanted. */
.configuration-card.configuration-wide { width: min(100%, 56rem); text-align: left; }
.configuration-card.configuration-wide .panel { text-align: left; }

/* ---------------------------------------------------------------------------------------------------
   A cell that is booked.

   The band colour is the DATE's, and it does not move: a lorry whose brake test ran out last week is
   out of date today whatever is in the diary. So this is a second mark laid over the top — a small
   badge along the bottom of the cell, and a hairline down its left edge so a booked column is
   scannable without reading a word.

   Blue, deliberately, and not green: green on this palette means only "in order", and an overdue
   cell that is booked is not in order. The offered one is warm, because it is still waiting on a
   person.
   --------------------------------------------------------------------------------------------------- */

.pcell-booked {
  display: flex; align-items: center; gap: .25rem;
  margin-top: .3rem; padding: .15rem .35rem; border-radius: 999px;
  font-size: .72rem; font-weight: 800; letter-spacing: .01em; line-height: 1.2;
  white-space: nowrap;
}
.pcell-booked svg { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.pcell-booked svg .tick { stroke-width: 2; }

.pcell-booked-booked { background: var(--surface-blue); color: var(--primary); }
.pcell-booked-offered { background: var(--warn-soft); color: var(--warn); }

/* The edge. Inset so it does not fight the row's own left border. */
.pcell-has-booked { box-shadow: inset 3px 0 0 var(--primary); }
.pcell-has-offered { box-shadow: inset 3px 0 0 var(--warn); }

/* The same fact in the side panel, where there is room for the words. */
.side-booked {
  display: inline-flex; align-items: center;
  padding: .15rem .4rem; border-radius: 999px;
  font-size: .72rem; font-weight: 800; white-space: nowrap;
}
.side-booked-booked { background: var(--surface-blue); color: var(--primary); }
.side-booked-offered { background: var(--warn-soft); color: var(--warn); }

/* Open the existing booking badge without adding another action row to the planner. */
.button.booking-open { min-height: 0; border: 0; box-shadow: none; text-align: left; }
.button.booking-open:hover:not(:disabled) { text-decoration: underline; transform: none; }
.button.booking-open:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }

/* The office planner keeps its overview above a compact, full-width sheet. */
.office-fleet-planner { container: office-fleet / inline-size; }
.office-fleet-planner .kpi-row {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: .6rem; margin-bottom: .75rem;
}
.office-fleet-planner .kpi { min-width: 0; gap: .6rem; padding: .7rem .8rem; border-radius: 12px; }
.office-fleet-planner .kpi-icon { width: 2rem; height: 2rem; border-radius: 9px; }
.office-fleet-planner .kpi-icon svg { width: 1.3rem; height: 1.3rem; }
.office-fleet-planner .kpi-value { font-size: 1.65rem; }
.office-fleet-planner .kpi-label { font-size: .8rem; line-height: 1.2; }
.office-fleet-planner .kpi-hint { display: none; }
.office-fleet-planner .planner-overview {
  display: flex; align-items: center; gap: 1.5rem;
  padding: .65rem 1rem; margin-bottom: .75rem;
}
.office-fleet-planner .planner-overview .panel-header { flex: 0 0 auto; margin: 0; }
.office-fleet-planner .planner-overview h3 { font-size: .95rem; }
.office-fleet-planner .planner-overview .panel-note { font-size: .72rem; }
.office-fleet-planner .donut-body { display: flex; align-items: center; gap: 1.2rem; min-width: 0; flex: 1; }
.office-fleet-planner .donut { flex: 0 0 auto; width: 4.5rem; height: 4.5rem; }
.office-fleet-planner .donut-legend { display: flex; flex-wrap: wrap; gap: .45rem 1.1rem; }
.office-fleet-planner .donut-legend li { gap: .35rem; font-size: .78rem; }
.office-fleet-planner .donut-legend .legend-value { font-size: .85rem; }
.office-fleet-planner .donut-legend .dot { width: .55rem; height: .55rem; }
.office-fleet-planner .planner-split { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
.office-fleet-planner .planner-main { min-width: 0; }
.office-fleet-planner .planner-aside { width: 100%; max-width: 22rem; justify-self: end; }
.office-fleet-planner .planner-main > .small { margin: .35rem 0 .65rem; }
.office-fleet-planner .ptable { font-size: .86rem; }
.office-fleet-planner .ptable th { padding: .65rem .6rem; }
.office-fleet-planner .pth-vehicle { width: 1%; min-width: 6.25rem; max-width: 10rem; }
.office-fleet-planner .pth-name { font-size: .8rem; }
.office-fleet-planner .pth-sub { font-size: .72rem; }
.office-fleet-planner .prow td { padding: .6rem; }
.office-fleet-planner .prow td:first-child strong { font-size: .9rem; }
.office-fleet-planner .prow-sub { font-size: .72rem; overflow-wrap: anywhere; }
.office-fleet-planner .pcell-line { gap: .25rem; }
.office-fleet-planner .pcell-date { font-size: .86rem; }
.office-fleet-planner .pcell-when { font-size: .72rem; }
.office-fleet-planner .pcell-flag { font-size: .72rem; }
.office-fleet-planner .pcell .mark { width: .85rem; height: .85rem; }
.office-fleet-planner .pcell .pchip { padding: .2rem .4rem; font-size: .72rem; }
.office-fleet-planner .pcell-booked {
  width: fit-content; max-width: 100%; flex-wrap: wrap; gap: .1rem .2rem;
  font-size: .72rem; white-space: normal;
}
.office-fleet-planner .booking-day { white-space: nowrap; }
.office-fleet-planner .side-booked { gap: .2rem; }
@container office-fleet (min-width: 80rem) {
  .office-fleet-planner .planner-split.planner-with-details { grid-template-columns: minmax(0, 1fr) 22rem; }
}
@container office-fleet (max-width: 55rem) {
  .office-fleet-planner .kpi-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .office-fleet-planner .planner-overview { gap: .75rem; }
  .office-fleet-planner .donut-body { gap: .65rem; }
}
@container office-fleet (max-width: 36rem) {
  .office-fleet-planner .planner-overview { align-items: flex-start; flex-direction: column; }
  .office-fleet-planner .kpi { padding: .55rem; }
  .office-fleet-planner .kpi-icon { display: none; }
}

/* ---------------------------------------------------------------------------------------------------
   The inspection sheet.

   Fifty-one rows a fitter goes down with dirty hands. The codes are BUTTONS, not a dropdown: a
   dropdown is two taps and a scroll for each item, and by the fourth it costs more attention than the
   item does. One tap, and the whole column readable without opening anything.

   The letter is what a fitter looks for; the word is in the tooltip for whoever reads it afterwards.
   --------------------------------------------------------------------------------------------------- */

.insp-list { display: grid; gap: .5rem; margin: 0; padding: 0; list-style: none; }

.insp-item {
  display: grid; gap: .45rem; padding: .6rem .7rem;
  border: 1px solid var(--line); border-left: 4px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface);
}
/* Answered fades back so the eye lands on what is left. */
.insp-item-done { background: var(--surface-alt); border-left-color: var(--good); }
/* An X with no words is the one thing that stops a sheet being signed, so it says so before the press. */
.insp-item-needs { border-left-color: var(--bad); background: var(--bad-soft); }

.insp-item-head { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.insp-num {
  min-width: 1.7rem; padding: .1rem .35rem; border-radius: 6px;
  background: var(--muted-soft); color: var(--ink-700);
  font-size: .72rem; font-weight: 800; text-align: center;
  font-variant-numeric: tabular-nums;
}
.insp-label { flex: 1 1 12rem; font-size: .88rem; font-weight: 650; color: var(--ink-900); }
.insp-im { font-size: .72rem; font-weight: 700; color: var(--ink-500); white-space: nowrap; }

.insp-codes { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
.insp-code {
  min-width: 2.4rem; padding: .38rem .5rem;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink-700);
  font: inherit; font-size: .82rem; font-weight: 800; cursor: pointer;
}
.insp-code:hover { border-color: var(--ink-500); }
.insp-code-good.is-chosen { background: var(--good-soft); border-color: var(--good); color: var(--good); }
.insp-code-bad.is-chosen { background: var(--bad-soft); border-color: var(--bad); color: var(--bad); }
.insp-code-warn.is-chosen { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }
.insp-code-soft.is-chosen { background: var(--info-soft); border-color: var(--info-line); color: var(--primary); }
.insp-code-plain.is-chosen { background: var(--muted-soft); border-color: var(--muted); color: var(--muted); }

.insp-monitor {
  margin-left: auto; padding: .3rem .55rem;
  border: 1px dashed var(--line); border-radius: 999px;
  background: transparent; color: var(--ink-500);
  font: inherit; font-size: .72rem; font-weight: 700; cursor: pointer;
}
.insp-monitor.is-chosen { border-style: solid; border-color: var(--warn); background: var(--warn-soft); color: var(--warn); }

.insp-words, .insp-loose, .insp-loose-mins {
  width: 100%; padding: .45rem .55rem;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink-900); font: inherit; font-size: .85rem;
}

@media (max-width: 640px) {
  .insp-monitor { margin-left: 0; }
  .insp-code { flex: 1 1 auto; }
}

.phone-layout .insp-codes {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: .3rem;
}
.phone-layout .insp-code { min-width: 0; padding: .55rem .2rem; font-size: .95rem; }
/* Its own row, full width, under the five. It is a different kind of answer from S/X/R/A/NA and it
   used to be squeezed in beside them, which is how it ended up half off the screen. */
.phone-layout .insp-monitor { grid-column: 1 / -1; margin-left: 0; text-align: center; }
/* A long item name must wrap rather than push the card wide. */
.phone-layout .insp-item-head { flex-wrap: wrap; }
.phone-layout .insp-item-head > * { min-width: 0; overflow-wrap: anywhere; }

/* The kind of work, chosen once before the sheet opens. It used to be a browser prompt asking a
   fitter to type "brake_test" with the underscore in the right place. */
.insp-kind-picker { gap: .5rem; }
.insp-kind-grid { display: flex; flex-wrap: wrap; gap: .45rem; }
.insp-kind { flex: 1 1 9.5rem; justify-content: center; text-align: center; }

/* What a booking's sheet says about itself, on the booking. */
.booking-sheet {
  margin-top: .7rem; padding: .7rem .8rem;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt);
}
.booking-sheet p { margin: 0 0 .3rem; }
.booking-sheet .pill-row { margin-top: .5rem; }

/* Signed, at the TOP. The press is at the bottom of fifty-one items, and somebody left staring at
   the row they were already on reads it as nothing having happened. */
.insp-signed-banner { margin-bottom: 1rem; }
.insp-signed-banner .pill-row { margin-top: .6rem; }

.callout-good { border-color: var(--good); background: var(--good-soft); }
/* A question that has been answered: worth showing, not worth shouting about. */
.callout-plain { border-color: var(--line); background: var(--surface-alt); }
/* (0399) The AdBlue notes above the consumption table. One line per lorry worth a question, and
   nothing at all when every lorry is in band: a panel that is always there is a panel nobody reads. */
/* (0400) The Defects list. A critical fault carries its colour on the whole card, because this is a
   page somebody scans in the morning looking for the one that matters, not a page they read. */
.defect-card + .defect-card { margin-top: .7rem; }
.defect-critical { box-shadow: inset 3px 0 0 var(--bad, #c0392b); }
.defect-answer { margin-top: .8rem; }
.defect-roadworthy { display: flex; gap: .5rem; align-items: center; font-weight: 600; }
.defect-roadworthy input { width: 1.1rem; height: 1.1rem; flex: none; }

.adblue-notes p { margin: 0; }
.adblue-notes p + p { margin-top: .4rem; }
.callout-warn { border-color: var(--warn); background: var(--warn-soft); }


/* --- ON PAPER ---------------------------------------------------------------------------------
   A signed sheet has to leave the screen: an operator files it, a garage hands it to a customer,
   and an examiner asks for it in three years. This is the browser's own print dialogue, which is
   also Save as PDF on every platform his fitters use — no library, no server, and it works offline.

   What goes is everything that is a control rather than a fact: the menu, the buttons, the
   toolbar. What stays is the sheet. */
@media print {
  :root { --surface: #fff; --surface-alt: #fff; --surface-blue: #fff; --ink-900: #000; }
  .topbar, .drawer, .drawer-scrim, .no-print, .toast-stack, .preview-banner { display: none !important; }
  /* Both, because .portal-shell.nav-docked outranks .portal-shell and a media query adds no weight:
     printed at a desk, the sheet kept a 280px gap where the menu had stood. */
  .portal-shell, .portal-shell.nav-docked { display: block; background: #fff; padding-left: 0; }
  .content-area { padding: 0; max-width: none; }
  body { background: #fff; color: #000; }

  .panel {
    border: 1px solid #999; border-radius: 0; box-shadow: none; background: #fff;
    margin: 0 0 .35rem; padding: .5rem .6rem;
    /* A section split down the middle of a page is a section somebody reads twice or not at all. */
    break-inside: avoid; page-break-inside: avoid;
  }
  .insp-item { break-inside: avoid; page-break-inside: avoid; padding: .2rem .35rem; }
  .insp-list { gap: .15rem; }
  .insp-code { border: 1px solid #000; background: #fff !important; color: #000 !important; }
  .callout { border: 1px solid #000; background: #fff !important; }
  .side-list li { border-bottom: 1px solid #ddd; }
  h3 { font-size: 1rem; }
  a[href^="#"]::after { content: ""; }
}

/* Which due date this sheet answers. Radios rather than a dropdown: the choice moves a legal date,
   and every option has to be readable at once — including "none of these", which is a real answer. */
.insp-cycle {
  display: flex; gap: .6rem; align-items: baseline;
  padding: .5rem .6rem; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); cursor: pointer;
}
.insp-cycle:has(input:checked) { border-color: var(--primary); background: var(--surface-blue); }
.insp-cycle span { display: grid; gap: .1rem; }

/* --- THE TYRE AND BRAKE GRID -------------------------------------------------------------------
   His sheet prints it as a table and a fitter reads it as one: four wheel positions across, axles
   down. It scrolls sideways inside its own box rather than making the page scroll, because on a
   tablet in a bay the page scrolling sideways loses the column headings. */
.insp-grid-scroll { overflow-x: auto; margin-top: .7rem; }
.insp-grid { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: .8rem; }
.insp-grid caption { text-align: left; padding: .2rem 0 .4rem; }
.insp-grid th, .insp-grid td {
  border: 1px solid var(--line); padding: .3rem .35rem; text-align: left; vertical-align: top;
}
.insp-grid thead th { background: var(--surface-alt); font-size: .72rem; font-weight: 700; }
.insp-grid tbody th { background: var(--surface-alt); text-align: center; width: 3rem; }
.insp-cell { display: table-cell; }
.insp-m, .insp-f {
  width: 100%; padding: .25rem .3rem; margin-bottom: .15rem;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); color: var(--ink-900); font: inherit; font-size: .78rem;
}
.insp-m:last-child, .insp-f:last-child { margin-bottom: 0; }
.insp-narrow { max-width: 4.5rem; }
.insp-tick { text-align: center; }
.insp-tick input { width: 1.1rem; height: 1.1rem; }
.insp-faults { min-width: 44rem; }
.insp-faults td, .insp-faults th { font-size: .8rem; }

@media print {
  /* His page 1 prints the item list in TWO COLUMNS, which is why fifty-one items fit on one sheet
     with the tyre grid under them. One column down the page turns the same sheet into four. */
  .insp-list { columns: 2; column-gap: 1rem; }
  .insp-item { break-inside: avoid; page-break-inside: avoid; }

  .insp-grid-scroll { overflow: visible; }
  .insp-grid { min-width: 0; font-size: .68rem; }
  .insp-grid th, .insp-grid td { border: 1px solid #000; padding: .12rem .2rem; }
  .insp-grid thead th { background: #eee !important; }
  .insp-grid tbody th { background: #eee !important; }
  /* His fault page starts on a sheet of its own, and so does this one. */
  .insp-faults { page-break-before: auto; }
}

/* --- THE SHEET AS A PRINTED DOCUMENT -----------------------------------------------------------
   A second rendering of the same data, laid out the way his own paper is, under an AMARINE
   letterhead. It never appears on screen: the screen is built for a fitter with dirty hands and the
   paper for whoever reads it in three years, and one stylesheet serving both suits neither. */
.print-sheet { display: none; }

@media print {
  /* The interactive screen goes; this takes its place. A preview is a draft, and a draft does not
     print: pressing print on one gives a blank sheet rather than an invoice with no number. */
  .service-scope, .paper-preview { display: none !important; }
  .print-sheet { display: block; color: #000; font-size: 8.5pt; line-height: 1.25; }

  @page { size: A4 portrait; margin: 9mm; }
}

/* THE PAPER'S FURNITURE, on paper and on the screen. It was print-only; a preview before issuing shows
   the same page on the screen, so it applies wherever a .pf- element is — and one only ever is inside a
   .print-sheet (hidden on screen) or a .paper-preview (hidden in print). */
  .pf-page { page-break-after: always; }
  .pf-page:last-child { page-break-after: auto; }

  .pf-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    border-bottom: 2px solid #000; padding-bottom: 2mm; margin-bottom: 2mm;
  }
  .pf-brand { display: flex; align-items: center; gap: 2mm; }
  .pf-mark { width: 7mm; height: 7mm; color: #000; }
  .pf-brand strong { display: block; font-size: 13pt; letter-spacing: .18em; }
  .pf-brand small { display: block; font-size: 6.5pt; letter-spacing: .06em; }
  .pf-title { font-size: 13pt; font-weight: 700; }
  .pf-ref { text-align: right; font-size: 8pt; }

  .pf-withdrawn { border: 1.5pt solid #000; padding: 1.5mm; margin: 0 0 2mm; }

  /* The header block: three fields across, as his sheet prints them. */
  .pf-header { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; margin-bottom: 1mm; }
  .pf-header-wide { grid-template-columns: repeat(3, 1fr); }
  /* The invoice's reference row. Four short values - a plate and three numbers - which fit across
     an A4 at about 47mm each; the labels are 5.5pt and the values are never long. */
  .pf-header-four { grid-template-columns: repeat(4, 1fr); }
  .pf-f { border: .5pt solid #000; padding: .5mm 1.2mm; min-height: 5mm; }
  .pf-f span { display: block; font-size: 5.5pt; text-transform: uppercase; letter-spacing: .04em;
    line-height: 1.1; }
  .pf-f strong { font-size: 8pt; font-weight: 700; line-height: 1.15; }

  .pf-codes, .pf-note { margin: 1mm 0; font-size: 6.8pt; }
  .pf-note { border: .5pt solid #000; padding: .6mm; line-height: 1.1; font-size: 6.4pt; }

  /* Two columns, flowing down the first before the second — which is how fifty-one items fit on one
     side of paper, and how his sheet reads. */
  .pf-items { columns: 2; column-gap: 3mm; margin-top: 1.5mm; }
  /* A trailer's sixty-five. At two columns it ran 312mm against A4's 279. */
  .pf-items-3 { columns: 3; column-gap: 2mm; }
  /* 278.2mm of 279 is not a margin, it is a coincidence waiting to break on the first sheet
     with a longer label. */
  .pf-items-3 .pf-item, .pf-items-3 .pf-sec { font-size: 6.2pt; line-height: 1.1; }
  .pf-items-3 .pf-item { padding: .05mm 0; }
  .pf-items-3 .pf-sec { margin-top: .7mm; }
  .pf-items-3 .pf-im, .pf-items-3 .pf-no { width: 4mm; }
  .pf-items-3 .pf-res { width: 5mm; }
  .pf-sec, .pf-item {
    display: flex; align-items: baseline; gap: 1mm;
    break-inside: avoid; page-break-inside: avoid;
  }
  .pf-sec {
    font-weight: 700; font-size: 6.5pt; text-transform: uppercase; line-height: 1.15;
    border-bottom: 1pt solid #000; margin-top: 1mm; padding-bottom: .2mm;
  }
  .pf-sec span:first-child { flex: 1; }
  .pf-sec-im, .pf-sec-no { width: 5mm; text-align: center; }
  .pf-item { border-bottom: .3pt solid #999; padding: .15mm 0; font-size: 6.8pt; line-height: 1.15; }
  .pf-label { flex: 1; }
  .pf-im { width: 5mm; text-align: center; }
  .pf-no { width: 5mm; text-align: center; }
  .pf-res { width: 6mm; text-align: center; font-weight: 700; }

  .pf-grids { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5mm; margin-top: 2mm; }
  /* Fixed, so a long figure widens a cell instead of the whole table walking off the page. */
  .pf-grid { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 6.5pt;
    break-inside: avoid; }
  .pf-grid caption {
    text-align: left; font-weight: 700; font-size: 7pt; padding-bottom: .5mm;
  }
  .pf-grid th, .pf-grid td { border: .5pt solid #000; padding: .3mm; text-align: center; height: 3.2mm; }
  .pf-grid thead th { background: #eee !important; font-size: 5.5pt; overflow: hidden; }
  .pf-ambient { grid-column: 1 / -1; margin: 0; font-size: 7.5pt; }

  .pf-faults { width: 100%; border-collapse: collapse; font-size: 7.5pt; margin-top: 2mm; }
  .pf-faults th, .pf-faults td { border: .5pt solid #000; padding: 1mm; text-align: left; }
  .pf-faults thead th { background: #eee !important; font-size: 6.5pt; }
  .pf-faults tr { break-inside: avoid; }
  .pf-none { text-align: center; }

  .pf-notes { border: .5pt solid #000; padding: 1.5mm; margin: 2mm 0 0; min-height: 8mm; font-size: 7.5pt; }

  .pf-sign {
    display: grid; grid-template-columns: 1fr 1fr 1.2fr; gap: 2mm;
    margin-top: 3mm; break-inside: avoid;
  }
  .pf-sign-box { border: .5pt solid #000; padding: 1.5mm; min-height: 14mm; }
  .pf-sign-box span { display: block; font-size: 6pt; text-transform: uppercase; }
  .pf-sign-box strong { display: block; margin-top: 4mm; font-size: 9pt; }
  .pf-sign-box small { display: block; font-size: 6.5pt; }
  .pf-cert { margin: 0; font-size: 6.8pt; border: .5pt solid #000; padding: 1.5mm; }
  .pf-sign-operator { grid-template-columns: 1fr 2fr; }

  .pf-foot { margin-top: 2mm; font-size: 6.5pt; text-align: center; }

  /* Where to send the money. Kept TIGHT on purpose: as a stacked list with a screen-sized heading it
     measured 57mm and pushed a four-line invoice onto a second sheet of A4. Never split across a page
     break either - an account number and the reference it belongs to are one fact. */
  .pf-payto { margin-top: 2.5mm; break-inside: avoid; }
  .pf-payto-say {
    font-size: 6pt; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
    margin-bottom: .8mm;
  }
  .pf-payref { margin: 1mm 0 0; font-size: 7.5pt; }
  .pf-payref strong { font-size: 8.5pt; letter-spacing: .02em; }

/* The logo, on the screen that sets it. Boxed at a fixed height so a wide mark and a tall one both
   sit where a letterhead sits, and neither pushes the panel about. */
.logo-preview {
  display: inline-flex; align-items: center; justify-content: center;
  max-width: 100%; padding: .6rem .8rem; margin: .6rem 0 .3rem;
  border: 1px solid var(--line); border-radius: 10px; background: #fff;
}
.logo-preview img { max-height: 4.5rem; max-width: 16rem; object-fit: contain; }

/* Paper furniture, on paper and in a preview (see above). */
  .pf-logo { width: 12mm; height: 9mm; object-fit: contain; }
  /* Held open even when there is no logo, so a garage that has not uploaded one gets the same
     document and not a differently shaped one. */
  .pf-logo-none { display: inline-block; }
  .pf-by {
    margin: .8mm 0 0; padding: .8mm 1.2mm; border: .5pt solid #000; font-size: 7pt;
  }
  /* A band, not a whisper. It sits under the garage's document and says who made the paper. */
  .pf-platform {
    display: flex; align-items: center; gap: 2mm; justify-content: center;
    margin: 2.5mm 0 0; padding-top: 1.5mm; border-top: 1pt solid #000;
    color: #000; break-inside: avoid;
  }
  .pf-platform .pf-mark { width: 5mm; height: 5mm; }
  .pf-platform-name { font-size: 10pt; font-weight: 700; letter-spacing: .22em; }
  .pf-platform-say { font-size: 6.8pt; color: #333; }
  /* On a screen that is itself the document and prints itself (the audit pack, the payroll pack), the band
     is on the paper and not on the screen, whose theme may be dark. After .pf-platform, so this wins. */
  .pf-platform-paper-only { display: none; }
  @media print { .pf-platform-paper-only { display: flex; } }

/* The invoice totals, on the screen that types them. */
.inv-totals { margin-top: .8rem; }
.inv-totals li:last-child { border-top: 1px solid var(--line); padding-top: .4rem; }

/* Paper furniture, on paper and in a preview (see above). Two parties side by side, as an invoice
   prints them. */
  .pf-parties { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; margin: 2mm 0; }
  .pf-party { border: .5pt solid #000; padding: 1.5mm; font-size: 8pt; }
  .pf-party span {
    display: block; font-size: 6pt; text-transform: uppercase; letter-spacing: .04em;
  }
  .pf-party strong { display: block; font-size: 9.5pt; margin-bottom: .5mm; }
  .pf-party-extra { font-size: 7pt; color: #333; }

  .pf-invoice-lines tfoot th { text-align: right; background: #f4f4f4 !important; }
  .pf-invoice-lines tfoot td { text-align: right; font-variant-numeric: tabular-nums; }
  .pf-invoice-lines td:nth-child(n+3) { text-align: right; font-variant-numeric: tabular-nums; }
  .pf-total th, .pf-total td { font-size: 10pt; font-weight: 700; }

/* A PREVIEW OF THE PAPER, on the screen, before it is issued. White and black whatever the theme,
   because it is the page the customer will hold; an A4 sheet's width, scrolled sideways inside its own
   box on a narrow screen rather than squeezed until the columns fold. */
.paper-scroll { overflow-x: auto; margin: .75rem 0 1.5rem; }
.paper-preview {
  display: block; box-sizing: border-box; width: 210mm; min-height: 150mm; margin: 0 auto; padding: 9mm;
  background: #fff; color: #000; font-size: 8.5pt; line-height: 1.25;
  border: 1px solid var(--line); box-shadow: 0 10px 34px rgba(38, 30, 18, .12);
}
.pf-preview-band {
  margin: 0 0 3mm; padding: 1.5mm 2mm; border: 1.5pt dashed #000; text-align: center;
  font-size: 8pt; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}

/* ---------------------------------------------------------------------------------------------------
   THE PORTAL ON A TELEPHONE

   Set by index.html before the stylesheet paints, from a stored choice OR the window width. One
   class, one copy of these rules, and a toggle in the top bar that can overrule the screen — a
   tablet and a phone held sideways are both cases where the width says one thing and the person
   wants the other.

   Measured on his own phone and in a browser at 390px before any of this was written:
     * the header printed itself over the clock and the Dynamic Island — no safe-area inset existed
       anywhere except the driver app;
     * the work screen opened with SIX summary tiles, one per row, 123px each: 819px of numbers to
       scroll past before any work appeared, on a screen 844px tall;
     * "What is due" put five things on one flex row inside 342px, so dates broke in half —
       "2026-08-" on one line and "31" on the next;
     * the vehicles table was a table.
   --------------------------------------------------------------------------------------------------- */

/* Applies always, not only on a phone: the insets are zero on a desktop, and an installed app on
   any device draws under the system bars. This is what "pe lungime e prea sus" was. */
.topbar {
  padding-top: calc(.9rem + env(safe-area-inset-top));
  padding-right: max(clamp(1rem, 3vw, 2.25rem), env(safe-area-inset-right));
  padding-left: max(clamp(1rem, 3vw, 2.25rem), env(safe-area-inset-left));
}
.portal-shell { padding-bottom: env(safe-area-inset-bottom); }

.phone-layout {
  /* Nothing on a phone should need pinching. */
  -webkit-text-size-adjust: 100%;
}

/* ---- the scoreboard stops being the screen -------------------------------------------------------- */
.phone-layout .kpi-row {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .55rem;
  margin-bottom: .9rem;
}
.phone-layout .kpi {
  flex-direction: column; align-items: flex-start; gap: .15rem;
  padding: .7rem .75rem; border-radius: 12px;
}
/* The icon is decoration; on a phone it is decoration occupying a third of the tile. */
.phone-layout .kpi-icon { display: none; }
.phone-layout .kpi-value { font-size: 1.7rem; }
.phone-layout .kpi-label { font-size: .82rem; line-height: 1.15; }
/* The hint explains the label. The label is the thing being counted, and on a tile this size the
   hint is the difference between six tiles and nine. */
.phone-layout .kpi-hint { display: none; }

/* ---- a row of five things becomes two lines ------------------------------------------------------- */
.phone-layout .side-list li {
  flex-wrap: wrap; align-items: baseline; gap: .25rem .5rem; padding: .6rem 0;
}
.phone-layout .side-list .side-name { flex: 1 0 100%; font-weight: 600; }
/* A date must never break in half. */
.phone-layout .side-list .side-value { white-space: nowrap; }
.phone-layout .side-list .side-book { margin-left: auto; }

/* ---- and the tables ------------------------------------------------------------------------------- */
.phone-layout .insp-faults,
.phone-layout .insp-faults thead, .phone-layout .insp-faults tbody,
.phone-layout .insp-faults tr, .phone-layout .insp-faults th, .phone-layout .insp-faults td,
.phone-layout .ptable,
.phone-layout .ptable thead, .phone-layout .ptable tbody,
.phone-layout .ptable tr, .phone-layout .ptable th, .phone-layout .ptable td {
  display: block; width: auto; min-width: 0;
}

/* The headings live on each value now. Not display:none — that takes them from a screen reader too. */
.phone-layout .insp-faults thead, .phone-layout .ptable thead {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.phone-layout .insp-faults tr, .phone-layout .ptable tbody tr {
  border: 1px solid var(--line); border-radius: 10px; padding: .55rem .7rem;
  margin-bottom: .6rem; background: var(--surface);
}
.phone-layout .insp-faults td, .phone-layout .insp-faults th,
.phone-layout .ptable td, .phone-layout .ptable th {
  border: 0; padding: .3rem 0; text-align: left;
}

.phone-layout .insp-faults td::before, .phone-layout .insp-faults th[data-label]::before,
.phone-layout .ptable td::before {
  content: attr(data-label);
  display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin-bottom: .15rem;
}
.phone-layout .insp-faults th[scope="row"] {
  font-weight: 700; padding-bottom: .35rem;
  border-bottom: 1px solid var(--line); margin-bottom: .35rem;
}
/* The registration is the card's name, not another field. */
.phone-layout .ptable .pth-vehicle {
  font-size: 1.05rem; padding-bottom: .35rem;
  border-bottom: 1px solid var(--line); margin-bottom: .35rem;
}
.phone-layout .ptable .pth-vehicle::before { content: none; }
.phone-layout .ptable .prow-sub { display: block; font-size: .78rem; color: var(--muted); }

/* Every box the full width of the block: a fitter is typing with one thumb. */
.phone-layout .insp-faults input[type="text"], .phone-layout .insp-faults input:not([type]),
.phone-layout .insp-faults input[inputmode], .phone-layout .insp-faults select { width: 100%; box-sizing: border-box; }
.phone-layout .insp-faults .insp-narrow { width: 100%; }
.phone-layout .insp-faults .insp-tick { display: flex; align-items: center; gap: .5rem; }
.phone-layout .insp-faults .insp-tick::before { margin-bottom: 0; }
.phone-layout .insp-faults .insp-tick input { width: auto; }
.phone-layout .insp-faults td:empty::before { opacity: .55; }

/* THE TYRE GRID IS DELIBERATELY LEFT AS A GRID. Its rows are axles and its columns are near-side and
   off-side, inner and outer — the shape IS the information, the way it is on his paper. Stacking it
   makes sixteen blocks out of one picture of a lorry. It scrolls, and says so. */
.phone-layout .insp-grid-scroll, .phone-layout .table-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.phone-layout .insp-grid-scroll:not(:has(.insp-faults))::after {
  content: "Drag sideways for the rest of the grid";
  display: block; font-size: .68rem; color: var(--muted); padding: .3rem 0 0;
}

/* ---- and the things a thumb has to hit ------------------------------------------------------------ */
.phone-layout .button, .phone-layout .side-book { min-height: 2.6rem; }
.phone-layout .pill-row { flex-wrap: wrap; gap: .5rem; }
.phone-layout .pill-row .button { flex: 1 1 auto; }
.phone-layout .panel { padding: .95rem .9rem; }
.phone-layout .field-row, .phone-layout .filter-grid { grid-template-columns: minmax(0, 1fr); }
.phone-layout .inv-totals .side-value { font-variant-numeric: tabular-nums; }

/* The layout control says which of the three it is on, so a person can tell without pressing it. */
.layout-toggle[data-layout="phone"] { color: var(--p-info); }
.layout-toggle[data-layout="wide"] { color: var(--p-info); }

/* ---- Ask: the chat in the office portal --------------------------------------------------------
   A thread, not a transcript. The office reads this between two phone calls, so the question is
   quiet and the answer is the thing with weight — the opposite of a messaging app, where both sides
   are equal because both sides are people. Here one side is a filing cabinet. */
.ask-panel { display: grid; gap: 1rem; padding: 1.15rem; }
.ask-thread { display: flex; flex-direction: column; gap: 1.4rem; max-height: 60vh; overflow-y: auto;
  padding-right: .25rem; }
.ask-turn { display: flex; flex-direction: column; gap: .5rem; }
/* The question, set back and lighter: it is there so the answer has something to be an answer TO. */
.ask-question { margin: 0; color: var(--ink-500); font-size: .92rem; }
.ask-question::before { content: "You asked: "; font-weight: 600; letter-spacing: .01em; }
.ask-answer { padding: .9rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-alt); }
.ask-answer p { margin: 0; }
/* Answer formatting stays inside the reply, clear in both live messages and saved history. */
.ask-answer-text { display: grid; gap: .6rem; overflow-wrap: anywhere; }
.ask-answer-text ul, .ask-answer-text ol { margin: 0; padding-left: 1.4rem; }
.ask-answer-text li { margin: .2rem 0; white-space: pre-line; }
.ask-answer-text pre { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: .9em; }
.ask-answer-waiting { background: var(--surface); border-style: dashed; }
/* Where the numbers came from. Small, always present, and never omitted when the answer had none —
   "no figures were looked up" is the more important of the two things this line can say. */
.ask-source { margin-top: .55rem !important; }
.ask-form { display: flex; gap: .6rem; }
.ask-form input { flex: 1; min-width: 0; padding: .7rem .85rem; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface); color: var(--ink-900); }
.ask-form input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.ask-foot { margin: 0; }
@media (max-width: 640px) {
  .ask-form { flex-direction: column; }
  .ask-thread { max-height: none; }
}

/* The card the office presses. Deliberately quieter than a panel and louder than a paragraph: it is
   an offer sitting inside an answer, and it has to read as a thing with an edge without shouting.
   Every colour is one of this stylesheet own tokens — the first draft reached for --accent,
   --surface-2 and --border-strong, none of which exist here, and the card would have shipped with
   no left edge at all in either theme. */
.ask-card {
  margin-top: .75rem;
  padding: .75rem .9rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
}
.ask-card-head {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin: 0 0 .5rem;
}
.ask-card .detail-grid { margin: 0 0 .5rem; }
.ask-card .action-row { margin-top: .75rem; display: flex; gap: .6rem; flex-wrap: wrap; }
/* Once it has been pressed there is nothing to press. Green, because on this platform green means
   only "in order" — and a booking that went through is exactly that. */
.ask-card-done {
  border-left-color: var(--good);
  background: var(--good-soft);
}

/* A question the platform never received. Dashed like the waiting state, because it is the same kind
   of thing — an answer that is not there — and bordered in the warning colour rather than the error
   one: nothing is wrong with what they typed, the request simply did not arrive. */
.ask-answer-failed {
  border-style: dashed;
  border-color: var(--warn-line);
  background: var(--warn-soft);
}
.ask-answer-failed .action-row { margin-top: .6rem; }

/* Whose question this was, on a colleague's turn only. Quiet: it is context, not the message. */
.ask-asked-by { margin: -.35rem 0 .5rem; color: var(--ink-500); font-size: .78rem; }

/* Full company and platform material reader. */
.office-material-reader { max-width: 74rem; margin: 0 auto; }
.omr-heading h2 { margin-top: .4rem; overflow-wrap: anywhere; }
.omr-metadata { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); gap: 1rem; margin: 1.2rem 0; }
.omr-metadata > div { min-width: 0; }
.omr-metadata dt { color: var(--ink-500); font-size: .76rem; }
.omr-metadata dd { margin: .3rem 0 0; overflow-wrap: anywhere; }
/* A signed agreement that names the wrong engaging company (0335): said in the page, not in a tooltip. */
.omr-warning { margin: 1rem 0; padding: .9rem 1rem; border: 1px solid var(--danger, #b3261e); border-left-width: 4px; border-radius: 12px; line-height: 1.55; }
.omr-prose { line-height: 1.75; overflow-wrap: anywhere; }
.omr-document { padding: clamp(1.1rem, 3vw, 2.5rem); }
.omr-prose > :first-child { margin-top: 0; }
.omr-prose > :last-child { margin-bottom: 0; }
.omr-prose h2, .omr-prose h3, .omr-prose h4, .omr-prose h5, .omr-prose h6 { margin: 1.5em 0 .55em; line-height: 1.35; }
.omr-prose p, .omr-prose ul, .omr-prose ol { margin: .8rem 0; }
.omr-prose li + li { margin-top: .4rem; }
.omr-summary { max-width: 65ch; }
.omr-lesson, .omr-question { border: 1px solid var(--line); border-radius: 12px; margin-top: .8rem; overflow: hidden; }
.omr-lesson > summary, .omr-question > summary { padding: 1rem; cursor: pointer; overflow-wrap: anywhere; }
.omr-lesson > summary:hover, .omr-question > summary:hover { background: var(--surface-alt); }
.omr-lesson > summary:focus-visible, .omr-question > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: -3px; }
.omr-position { display: inline-block; margin-right: .65rem; color: var(--ink-500); font-size: .78rem; }
.omr-code { color: var(--ink-500); font-size: .76rem; margin-left: .4rem; overflow-wrap: anywhere; }
.omr-lesson-body, .omr-question-body { border-top: 1px solid var(--line); padding: 1rem; }
.omr-questions { margin-top: 1.5rem; }
.omr-question { border-radius: 8px; }
.omr-options { padding-left: 1.5rem; line-height: 1.6; }
.omr-options li { padding: .3rem 0; overflow-wrap: anywhere; }
.omr-correct { display: inline-block; margin-left: .65rem; color: var(--good); font-size: .75rem; font-weight: 700; }
.omr-explanation { padding-top: .7rem; border-top: 1px solid var(--line); }
.omr-languages { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.omr-languages [aria-current="page"] { font-weight: 750; border-color: var(--primary); }
.omr-signature + .omr-signature { margin-top: 1.5rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
.omr-form-fields, .omr-declaration-list { padding-left: 1.5rem; }
.omr-form-field, .omr-declaration-list > li { margin-top: 1.2rem; overflow-wrap: anywhere; }
.omr-form-field h4 { margin: .4rem 0; }
.omr-required { margin-left: .65rem; font-size: .72rem; color: var(--ink-500); font-weight: 500; }
.omr-field-options { line-height: 1.7; padding-left: 1.25rem; }
.omr-other-wording { color: var(--ink-500); }
@media (max-width: 600px) {
  .omr-lesson > summary, .omr-question > summary, .omr-lesson-body, .omr-question-body { padding: .8rem; }
  .omr-position { display: block; margin-bottom: .25rem; }
}

/* Export selection appears only when requested, leaving the normal calendar uncluttered. */
.wcb-export-toolbar { margin: 1rem 0; }
.wcb-export-toolbar > p { margin: .6rem 0; font-size: .8rem; }
.wcb-export-toolbar > p:empty { display: none; }
.wcb-selectable { cursor: pointer; }
.wcb-selectable input { width: 1.1rem; height: 1.1rem; margin: 0 0 .3rem; accent-color: var(--primary); }
.wcb-selectable:has(input:checked) { outline: 2px solid var(--primary); outline-offset: -1px; }
.wcb-selectable:has(input:focus-visible) { outline: 2px solid var(--primary); outline-offset: 2px; }
.wcb-selectable:has(input:disabled) { cursor: wait; }

/* Work lists: actions first, full labels and a compact count strip. */
.work-summary-grid { display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem; }
.work-summary-item { display:flex;flex-direction:column;gap:.5rem;padding:.9rem;border:1px solid var(--line);border-radius:var(--radius-sm);color:var(--ink-900);text-decoration:none; }
.work-summary-item:hover,.metric-link:hover .metric-card { border-color:var(--primary);background:var(--surface-soft); }
.work-summary-item strong { font-size:1.7rem;line-height:1.2; }
.work-summary-item > span:first-child { min-height:2.8em; }
.work-summary-item small { color:var(--ink-500);line-height:1.5; }
.work-summary-link { margin-top:auto;font-size:.85rem;font-weight:700;color:var(--primary); }
.command-metrics { grid-template-columns:repeat(3,minmax(0,1fr)); }
.command-metrics .metric-card { padding:.75rem;box-shadow:none; }
.metric-link { text-decoration:none;color:inherit; }
/* My companies (a transport manager of several): one card per company, each figure a way into that company. */
.my-companies { display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,30rem),1fr));gap:1rem; }
.my-company .panel-header { align-items:flex-start; }
.my-company-figures { display:grid;grid-template-columns:repeat(auto-fill,minmax(9.5rem,1fr));gap:.6rem; }
.my-company-figure { display:flex;flex-direction:column;gap:.25rem;padding:.7rem .8rem;border:1px solid var(--line);border-radius:var(--radius-sm);color:var(--ink-700);text-decoration:none;font-variant-numeric:tabular-nums; }
.my-company-figure strong { font-size:1.45rem;line-height:1.15;color:var(--ink-500); }
.my-company-figure span { font-size:.82rem;line-height:1.35; }
.my-company-figure small { font-size:.75rem;color:var(--ink-500); }
.my-company-figure.is-waiting strong { color:var(--ink-900); }
.my-company-figure.is-waiting { border-color:var(--warn-line);background:var(--warn-soft); }
.my-company-figure.is-bad { border-color:var(--bad-line);background:var(--bad-soft); }
.my-company-figure.is-bad small { color:var(--bad);font-weight:700; }
.my-company-figure:hover, .my-company-figure:focus-visible { border-color:var(--primary); }
.my-company.is-clear .panel-header .eyebrow::after { content:" · nothing waiting"; }
.my-company-totals { display:grid;grid-template-columns:repeat(auto-fill,minmax(10rem,1fr));gap:.75rem;font-variant-numeric:tabular-nums; }
.my-company-totals div { display:flex;flex-direction:column;gap:.2rem; }
.my-company-totals strong { font-size:1.7rem;line-height:1.15; }
.my-company-totals span { font-size:.85rem;color:var(--ink-500); }
.record-pagination { display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap; }
.record-filters { align-items:end;flex-wrap:wrap; }
.record-filters label,.filter-bar label { min-width:0; }
.record-filters input,.record-filters select { min-width:0;max-width:100%; }
@media(max-width:1000px){.work-summary-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media(max-width:600px){.work-summary-grid,.command-metrics{grid-template-columns:1fr;}.record-filters{display:grid;grid-template-columns:1fr 1fr;}.record-filters label:first-child{grid-column:1/-1;}}

/* 0314 — a driver's onboarding, the office's half, at the top of Driver 360. Existing tokens only. */
.onboarding-panel .panel-header p { margin: .25rem 0 0; }
.onboarding-progress { height: .45rem; margin: .2rem 0 1rem; border-radius: 999px; background: var(--surface-soft); overflow: hidden; }
.onboarding-progress span { display: block; height: 100%; border-radius: inherit; background: var(--good); }
.onboarding-actions { margin-bottom: 1rem; }
.onboarding-action h4 { margin: 0; }
.onboarding-action .action-record-head { flex-wrap: wrap; }
.onboarding-action .action-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.onboarding-action .action-form .full-span { grid-column: 1 / -1; }
.onboarding-first { margin: 0 0 .8rem; color: var(--ink-700); }
.onboarding-nothing { margin: 0 0 1rem; color: var(--ink-700); }
.onboarding-steps summary { cursor: pointer; font-weight: 700; color: var(--ink-700); }
.onboarding-step-list { list-style: none; margin: .7rem 0 0; padding: 0; display: grid; gap: .35rem; }
.onboarding-step { display: flex; align-items: center; justify-content: space-between; gap: .8rem; padding: .45rem .6rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); }
.onboarding-step-name { min-width: 0; }
@media (max-width: 640px) {
  .onboarding-action .action-form { grid-template-columns: 1fr; }
}

/* 0317 — what inside the documents step is the office's. */
.onboarding-waiting-items { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.onboarding-waiting-items li { display: flex; align-items: center; justify-content: space-between; gap: .8rem; flex-wrap: wrap; padding: .55rem .7rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-soft); }

/* 0320 — the photographs a driver took at the end of a walkaround. Existing tokens only. */
.walkaround-photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: .6rem; }
.walkaround-photo { position: relative; padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-soft); cursor: pointer; overflow: hidden; aspect-ratio: 1 / 1; max-width: 100%; }
.walkaround-photo-img { position: absolute; inset: 0; background-size: cover; background-position: center; }
.walkaround-photo small { position: absolute; left: .35rem; bottom: .3rem; padding: 0 .35rem; border-radius: 999px; background: var(--surface); color: var(--ink-700); font-size: .72rem; }
.walkaround-photo:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 2px; }

/* 0321 — a PDF a driver sent (a delivery note) has no picture to show; its tile says what it is. */
.evidence-file-pdf .walkaround-photo-img { display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--ink-700); }

/* 0321 — driver photos: drivers first, then one driver's sets as compact rows with small thumbnails. Existing tokens only. */
.evidence-panel { display: grid; gap: 1rem; }
.evidence-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem; padding: .7rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); }
.evidence-filters label { display: grid; gap: .25rem; min-width: 150px; flex: 1 1 150px; font-size: .78rem; color: var(--ink-500); font-weight: 700; }
.evidence-filters select, .evidence-filters input { padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink-900); font: inherit; }
.evidence-filter-actions { display: flex; gap: .4rem; }
.evidence-drivers { display: grid; gap: .5rem; }
.evidence-driver { display: flex; align-items: center; gap: .8rem; padding: .7rem .85rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-alt); color: inherit; text-decoration: none; }
.evidence-driver:hover { background: var(--surface-soft); }
.evidence-driver:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 2px; }
.evidence-avatar { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2.4rem; height: 2.4rem; border-radius: 999px; background: var(--surface-soft); border: 1px solid var(--line); color: var(--ink-700); font-weight: 800; font-size: .85rem; }
.evidence-avatar-large { width: 3rem; height: 3rem; font-size: 1rem; }
.evidence-driver-body { display: grid; gap: .15rem; min-width: 0; flex: 1; }
.evidence-driver-kinds { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .15rem; }
.evidence-kind-chip { padding: .05rem .45rem; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-700); font-size: .7rem; font-weight: 700; }
.evidence-driver-state { display: inline-flex; align-items: center; gap: .6rem; flex: none; color: var(--ink-500); font-size: 1.2rem; }
.evidence-back { display: inline-block; margin-bottom: .6rem; color: var(--primary); font-weight: 750; text-decoration: none; }
.evidence-driver-head { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.evidence-driver-head h3 { margin: 0; }
.evidence-driver-head > div { flex: 1; min-width: 0; }
.evidence-rows { display: grid; gap: .5rem; }
.evidence-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .8rem; align-items: center; padding: .6rem .75rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); }
.evidence-row-submitted { border-left: 3px solid var(--warn); }
.evidence-row-body { display: grid; gap: .2rem; min-width: 0; }
.evidence-row-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.evidence-row-meta a { color: var(--primary); font-weight: 700; }
.evidence-row-note { font-size: .86rem; color: var(--ink-700); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.evidence-row-foot { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.evidence-thumbs { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .35rem; max-width: 22rem; }
.evidence-thumb { position: relative; width: 56px; height: 56px; padding: 0; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-soft); cursor: pointer; overflow: hidden; }
.evidence-thumb .walkaround-photo-img { position: absolute; inset: 0; background-size: cover; background-position: center; font-size: .7rem; }
.evidence-thumb:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 2px; }
/* Driver reports (0336): one report, one row, the same frame as a set of driver photos. */
.report-row { display: grid; gap: .3rem; padding: .65rem .8rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-alt); }
.report-row-open { border-left: 3px solid var(--warn); }
.report-row-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.report-row-text { margin: 0; font-size: .9rem; color: var(--ink-900); white-space: pre-line; overflow-wrap: anywhere; }
.report-row-note { margin: 0; font-size: .86rem; color: var(--ink-700); }
.report-flags { display: flex; flex-wrap: wrap; gap: .3rem; }
.report-flag { padding: .05rem .5rem; border-radius: 999px; border: 1px solid var(--warn); color: var(--ink-900); background: var(--surface); font-size: .72rem; font-weight: 700; }
.report-photos > summary { cursor: pointer; color: var(--primary); font-weight: 700; font-size: .86rem; }
.report-photos[open] > summary { margin-bottom: .45rem; }
.report-row-actions { display: inline-flex; gap: .3rem; margin-left: auto; }

/* The repair sheet (office-repair-sheet.js): big targets, because it is filled beside a lorry. */
.rs-form .form-grid { gap: .9rem; }
.rs-block { display: grid; gap: .45rem; }
.rs-label { font-size: .78rem; font-weight: 700; color: var(--ink-500); }
.rs-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.rs-chip {
  padding: .55rem .8rem; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-900); font: 600 .88rem var(--font-body, inherit); cursor: pointer;
}
.rs-chip:hover { background: var(--surface-soft); }
.rs-chip:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 2px; }
.rs-chip-on { background: var(--primary); border-color: var(--primary); color: #fff; }
.rs-odo { display: grid; grid-template-columns: minmax(0, 1fr) 5.5rem; gap: .4rem; }
.rs-odo input, .rs-odo select { min-width: 0; }
.rs-form .full-width { margin-top: .9rem; padding-block: .8rem; font-size: 1rem; }
.rs-saved { border-left: 3px solid var(--good); }
.rs-wheels { margin-top: .9rem; display: grid; gap: .6rem; justify-items: start; }

/* (0398) Wheel and tyre check. The form is a page of numbers typed with oily hands on a phone, so the
   three tread boxes are the big ones and everything else gets out of their way. One card per axle:
   fourteen tyres in one list is a list somebody loses their place in. */
.wtc-axle { padding-block: .9rem; }
.wtc-axle + .wtc-axle { margin-top: .7rem; }
.wtc-axle-count { align-items: center; gap: .4rem; flex-wrap: wrap; }
.wtc-tyre {
  border: 1px solid var(--line); border-radius: .6rem; padding: .6rem .7rem; margin-top: .6rem;
  background: var(--surface);
}
.wtc-tyre-head { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; margin-bottom: .45rem; }
/* The colour is on the whole tyre, not only its pill: a page of fourteen cards is scanned, not read. */
.wtc-warn { border-color: var(--warn, #b7791f); box-shadow: inset 3px 0 0 var(--warn, #b7791f); }
.wtc-bad { border-color: var(--bad, #c0392b); box-shadow: inset 3px 0 0 var(--bad, #c0392b); }
.wtc-depths { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem; }
.wtc-depths label, .wtc-extra label { display: grid; gap: .15rem; min-width: 0; }
.wtc-depths span, .wtc-extra span { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-600, #666); }
/* 16px, because anything smaller makes a phone zoom the page in on the first tap and the fitter then
   types the next three numbers at the wrong magnification. */
.wtc-depths input { font-size: 16px; text-align: center; padding-block: .55rem; }
.wtc-extra { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .4rem; margin-top: .45rem; }
.wtc-extra input { font-size: 16px; padding-block: .45rem; }
.wtc-declare { display: flex; gap: .6rem; align-items: flex-start; font-weight: 600; }
.wtc-declare input { width: 1.2rem; height: 1.2rem; margin-top: .15rem; flex: none; }
.wtc-saved { border-left: 3px solid var(--good); }

/* The wheel torque register (office-wheel-torque.js). The wheels are drawn as the vehicle stands, nearside left. */
.wt-wheels { display: grid; gap: .45rem; padding: .75rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-soft); }
.wt-legend { display: grid; grid-template-columns: 1fr auto 1fr; gap: .5rem; font-size: .72rem; color: var(--ink-500); }
.wt-legend span:nth-child(2) { text-align: center; }
.wt-legend span:last-child { text-align: right; }
.wt-axle { display: grid; grid-template-columns: 4.2rem 1fr 2.5rem 1fr 4rem; align-items: center; gap: .4rem; }
.wt-axle-name { font-size: .78rem; font-weight: 700; color: var(--ink-700); }
.wt-side { display: flex; gap: .3rem; }
.wt-side:first-of-type { justify-content: flex-end; }
.wt-beam { height: 4px; border-radius: 2px; background: var(--line); }
.wt-wheel { min-width: 3rem; min-height: 2.6rem; padding: .3rem .5rem; border: 2px solid var(--ink-500); border-radius: 8px;
  background: var(--surface); color: var(--ink-900); font: 700 .8rem var(--font-body, inherit); cursor: pointer; }
.wt-wheel:hover { background: var(--surface); border-color: var(--primary); }
.wt-wheel:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 2px; }
.wt-wheel-on { background: var(--primary); border-color: var(--primary); color: #fff; }
.wt-twin { display: flex; align-items: center; gap: .25rem; font-size: .75rem; color: var(--ink-500); }
.wt-checks { display: grid; gap: .35rem; border: 0; padding: 0; margin: 0; }
.wt-checks legend { font-size: .82rem; font-weight: 750; color: var(--ink-700); margin-bottom: .3rem; }
.wt-check { display: flex; gap: .5rem; align-items: flex-start; font-size: .88rem; }
.wt-waiting { display: grid; gap: .35rem; padding: .8rem 0; border-top: 1px solid var(--line); }
.wt-waiting-head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.wt-waiting .wt-sentence { margin: 0; }
.wt-overdue .wt-sentence, .wt-investigate .wt-sentence { color: var(--bad); font-weight: 700; }
.wt-retorque-form { margin-top: .4rem; padding: .8rem; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.wt-void td { text-decoration: line-through; color: var(--ink-500); }
.wt-waiting > .button { justify-self: start; }
.wt-filters { display: flex; flex-wrap: wrap; gap: .75rem; padding: 0 1.25rem .9rem; }
.wt-filters label { display: grid; gap: .3rem; min-width: 12rem; font-size: .8rem; font-weight: 700; color: var(--ink-700); }
.wt-filters select { min-height: 2.5rem; padding: .45rem .7rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--ink-900); font: 500 .9rem var(--font-body, inherit); }
.table-panel td.num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.wt-void td:last-child, .wt-void td:nth-last-child(2) { text-decoration: none; }
@media (max-width: 640px) {
  .wt-axle { grid-template-columns: 3.4rem 1fr 1rem 1fr; }
  .wt-twin { grid-column: 1 / -1; justify-self: end; }
  .wt-wheel { min-width: 2.6rem; }
}

/* The register on paper. Only ever inside a .print-sheet. */
  .pf-register { width: 100%; border-collapse: collapse; font-size: 7.5pt; margin-top: 2mm; }
  .pf-register th, .pf-register td { border: .5pt solid #000; padding: .8mm 1mm; text-align: left; vertical-align: top; }
  .pf-register thead th { background: #eee !important; font-size: 6.5pt; text-transform: uppercase; letter-spacing: .03em; }
  .pf-register tr { break-inside: avoid; }
  .pf-register .pf-void td { text-decoration: line-through; color: #555; }

/* A driver report on paper (see office-driver-reports.js). Only ever inside a .print-sheet. */
  .pf-driver { font-size: 11pt; margin: 3mm 0 1.5mm; padding-bottom: .5mm; border-bottom: 1pt solid #000; break-after: avoid; }
  .pf-report { border: .5pt solid #000; padding: 1.5mm 2mm; margin: 0 0 2mm; font-size: 8pt; }
  .pf-report-head { display: flex; justify-content: space-between; gap: 2mm; border-bottom: .5pt solid #000;
    padding-bottom: .8mm; margin-bottom: 1mm; break-after: avoid; }
  .pf-report-head strong { font-size: 10pt; }
  .pf-report-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8mm 3mm; margin: 0 0 1mm; break-inside: avoid; }
  .pf-report-facts dt { font-size: 5.5pt; text-transform: uppercase; letter-spacing: .04em; color: #333; }
  .pf-report-facts dd { margin: 0; font-weight: 700; overflow-wrap: anywhere; }
  .pf-report-text { margin: .8mm 0; white-space: pre-line; overflow-wrap: anywhere; }
  .pf-report-note { margin: .8mm 0; font-size: 7pt; color: #333; }
  .pf-photos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5mm; margin-top: 1.5mm; }
  .pf-photo { display: block; width: 100%; height: 48mm; object-fit: cover; border: .5pt solid #000; break-inside: avoid; }
@media (max-width: 640px) {
  .evidence-row { grid-template-columns: 1fr; }
  .evidence-thumbs { justify-content: flex-start; max-width: none; }
  .evidence-row-note { white-space: normal; }
}
