/* =====================================================================
   styles.css — all styling for the dashboard (linked from index.html)

   How this file is organised:
     1. Design tokens   — every colour, spacing, radius, shadow and font
                          size is defined ONCE here as a CSS variable
                          (--name: value). To change the look of the whole
                          app, edit this first block only.
     2. Base            — resets and page-wide defaults, icons
     3. Layout          — floating sidebar + main area (CSS grid)
     4. Components      — buttons, cards, tables, badges, messages
                          (4b: the Dashboard page)
     5. Dialog          — the add / detail / edit dialog
     5b. Accounts       — the login page, the sidebar's signed-in box, the
                          full-screen password / "not available" screens
     5c. Question dialog — the small "Assign anyway?" box
     6. Responsive      — what changes on phone-sized screens

   Rule of thumb: below section 1, no colours are written directly — rules
   always use var(--token-name).
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. DESIGN TOKENS
   --------------------------------------------------------------------- */
:root {
  /* Colour: page and surfaces */
  --color-bg: #f5f6f8;            /* off-white page background */
  --color-surface: #ffffff;       /* cards, inputs, dialogs */
  --color-surface-muted: #f8f9fb; /* table header, hover states */
  --color-row-hover: #f1f5fe;     /* table row under the mouse */
  --color-border: #e4e7ec;
  --color-border-strong: #cdd2da;
  --color-backdrop: rgb(16 24 40 / 0.45); /* dimmed page behind a dialog */

  /* Colour: text */
  --color-text: #1b2333;
  --color-text-muted: #667085;

  /* Colour: the one accent (primary buttons, active nav item, focus) */
  --color-accent: #2f5fd0;
  --color-accent-hover: #2650b4;
  --color-accent-soft: #e9effc;
  --color-on-accent: #ffffff;     /* text drawn on top of the accent */
  --color-focus-ring: rgb(47 95 208 / 0.3);

  /* Colour: danger (Delete) */
  --color-danger: #c62828;
  --color-danger-soft: #fdecec;
  --color-on-danger: #ffffff;

  /* Colour: dark navy sidebar */
  --color-sidebar-bg: #11203d;
  --color-sidebar-text: #b9c4d8;
  --color-sidebar-text-strong: #ffffff;
  --color-sidebar-hover: #1b2f55;
  --color-sidebar-focus: #9ec1ff;

  /* Colour: status pills. Every status is shown in one of five "tones"
     (a background + text colour pair). script.js decides which tone each
     status gets, e.g. trip "delivered" = green, driver "on_leave" = amber. */
  --tone-grey-bg: #eceef2;
  --tone-grey-text: #475467;
  --tone-blue-bg: #dbe7fd;
  --tone-blue-text: #1c4ab5;
  --tone-amber-bg: #fdf0c9;
  --tone-amber-text: #8a4b00;
  --tone-green-bg: #d9f3e1;
  --tone-green-text: #14612f;
  --tone-red-bg: #fbdcdc;
  --tone-red-text: #9b1c1c;

  /* Colour: what a colour MEANS (used by the trip screens; add it to other screens as they are redesigned).
       green  = done / good          yellow = waiting, needs attention      red = a problem, expired, cancel, error
       blue   = buttons, links, the selected tab, information              grey   = not done yet
     COLOUR IS NEVER THE ONLY SIGNAL: every use also carries an icon, a tick or words. Every text / background pair
     here is checked to be at least 4.5 : 1 by tests/test-contrast.js. (The older --tone-* pill colours above are
     unchanged; where a value is the same it is repeated here on purpose, so the two sets can be merged later.) */
  --color-success: #1a7f3c;       /* the solid green: a done circle, a filled bar segment */
  --color-success-soft: #d9f3e1;
  --color-success-text: #14612f;
  --color-on-success: #ffffff;    /* the tick / text drawn on the solid green */
  --color-attention: #f6c90e;     /* the solid yellow (soft yellow, never orange) */
  --color-attention-soft: #fff4c4;
  --color-attention-text: #5c4300;
  --color-on-attention: #2b2000;
  --color-danger-text: #9b1c1c;   /* (--color-danger, --color-danger-soft and --color-on-danger are defined above) */
  --color-info-soft: #e9effc;     /* (the solid blue is --color-accent) */
  --color-info-text: #1c4ab5;
  --color-neutral-soft: #eceef2;
  --color-neutral-text: #475467;
  --color-neutral-ring: #8993a4;  /* the grey ring of a step that is not done yet */

  /* Spacing scale */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;

  /* Corner radius */
  --radius-sm: 0.375rem;
  --radius-md: 0.625rem;
  --radius-lg: 0.875rem;
  --radius-xl: 1.125rem;
  --radius-pill: 999px;

  /* Shadows */
  --shadow-card: 0 1px 2px rgb(16 24 40 / 0.05), 0 2px 8px rgb(16 24 40 / 0.06);
  --shadow-float: 0 10px 28px rgb(16 24 40 / 0.2), 0 2px 6px rgb(16 24 40 / 0.1); /* the floating sidebar */
  --shadow-dialog: 0 24px 64px rgb(16 24 40 / 0.28), 0 4px 12px rgb(16 24 40 / 0.12);
  --shadow-focus: 0 0 0 3px var(--color-focus-ring);

  /* Typography: system font stack only (no downloads) */
  --font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 0.9375rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.625rem;
  --line-height: 1.5;

  /* Icons (all drawn as outlines; see the sprite at the top of index.html) */
  --icon-size: 1.25rem;           /* about 20px */
  --icon-size-title: 1.5rem;      /* beside a page title */
  --icon-size-empty: 3rem;        /* above an empty-state message */
  --icon-stroke: 1.75;
  --icon-stroke-empty: 1.25;

  /* Layout sizes (relative units, so nothing is a fixed pixel width) */
  --sidebar-width: 15rem;
  --sidebar-width-collapsed: 4.5rem;
  --sidebar-inset: 0.75rem;       /* the gap around the floating sidebar */
  --content-max-width: 90rem;
  --table-min-width: 36rem;       /* below this a table scrolls sideways */
  --table-min-width-wide: 56rem;  /* the Trips table (9 columns + names/routes/last update); narrower screens scroll it inside its card */
  --history-time-width: 11rem;    /* the time column in a trip's History */
  --table-max-height: 70vh;       /* lets the sticky header do its job */
  --dialog-width: 40rem;          /* the "Add" dialog */
  --dialog-max-height: 85vh;
  --form-column-min: 15rem;       /* narrowest a form column may get */
  --avatar-size: 3rem;
  --icon-button-size: 2.25rem;
  --dashboard-list-max-height: 20rem; /* a long panel list scrolls inside its card */
  --dashboard-count-icon-size: 2.75rem;
  --dashboard-bar-height: 0.625rem;
  --icon-size-dashboard-empty: 2rem;
  --doc-icon-size: 2.25rem;       /* the file icon in the document list */
  --avatar-camera-size: 1.5rem;   /* the little camera button on the avatar */
  --toast-action-duration: 6s;    /* a toast with an Undo button stays a little longer */
  --search-width: 22rem;          /* widest the list search box grows */
  --chip-height: 2.25rem;
  --tap-target: 2.75rem;          /* smallest comfortable touch target (44px) */
  --auth-card-width: 26rem;       /* the login / change-password card */
  --confirm-dialog-width: 28rem;  /* the small "Assign anyway?" question box */
  --sort-arrow-size: 0.875rem;    /* the arrow in a sortable column header */
  --settings-card-max-width: 40rem; /* the My account card in Settings */
  --drawer-width: 47.5rem;        /* the trip drawer on wide screens: about 760px */
  --drawer-tab-height: var(--tap-target);
  --field-height: 3.5rem;         /* the rounded trip-form fields: 56px or taller */
  --field-font-size: 1.0625rem;   /* 17px: what is typed in them */
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace; /* container numbers */
  --drawer-duration: 0.25s;       /* the trip drawer sliding in */
  --font-size-title: 1.375rem;    /* the route title at the top of the trip drawer */
  --step-circle-size: 2.25rem;    /* a numbered circle in the New trip steps / a milestone circle */
  --flow-line-width: 0.1875rem;

  /* Motion */
  --transition: 0.15s ease;
  --dialog-duration: 0.15s;       /* fade + scale when a dialog opens/closes */
  --dialog-scale-start: 0.97;
  --sidebar-duration: 0.25s;      /* sidebar collapsing / expanding */
  --menu-duration: 0.2s;          /* phone menu opening / closing */
  --toast-width: 24rem;           /* widest a toast may be */
  --toast-gap: var(--space-4);    /* distance from the screen edge */
  --toast-duration: 0.2s;         /* a toast slides down and fades in */
  --toast-offset: 0.75rem;        /* how far above its place it starts */
  --topbar-height: 4.25rem;       /* the phone top bar (app name + menu button); toasts sit below it */
  --spin-duration: 0.8s;          /* the refresh icon turning */
  --menu-offset: 1rem;            /* how far the phone menu slides down as it opens */

  /* Stacking order */
  --z-menu-backdrop: 70;          /* the phone menu sits below the dialog layers */
  --z-menu: 80;
  --z-toast: 110;                 /* above the dialog, so a message is never hidden */
  --z-backdrop: 90;
  --z-panel: 100;
  --z-auth: 105;                  /* login-style screens: above the dialog, below toasts */
}


/* ---------------------------------------------------------------------
   2. BASE
   --------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-family);
  font-size: var(--font-size-base);
  line-height: var(--line-height);
  color: var(--color-text);
  background: var(--color-bg);
}

h1, h2, h3, p {
  margin: 0;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

/* The HTML "hidden" attribute must always win, even over rules like
   display: flex that are set further down. */
[hidden] {
  display: none !important;
}

/* Text that screen readers read but sighted users don't see. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Visible keyboard focus on everything you can tab to. (Text inputs get a
   glowing ring instead — see the forms section.) */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}

/* --- Icons ---
   Every icon is a simple outline drawn once in the <svg> "sprite" at the
   top of index.html and then shown anywhere with:
     <svg class="icon"><use href="#icon-name"></use></svg>
   They take their colour from the text colour around them (currentColor). */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.icon {
  flex: none;
  width: var(--icon-size);
  height: var(--icon-size);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* ---------------------------------------------------------------------
   3. LAYOUT — floating sidebar on the left, content on the right (CSS grid)

   The first grid column is the sidebar's width PLUS the gap around it. The
   sidebar's width comes from --sidebar-current, so collapsing the sidebar
   only changes that one value, and the grid animates the column (and so
   the content next to it) smoothly.
   --------------------------------------------------------------------- */
.app-shell {
  --sidebar-current: var(--sidebar-width);
  display: grid;
  grid-template-columns: calc(var(--sidebar-current) + var(--sidebar-inset) * 2) minmax(0, 1fr);
  min-height: 100vh;
  transition: grid-template-columns var(--sidebar-duration) ease;
}

.sidebar {
  position: sticky;
  top: var(--sidebar-inset);
  align-self: start;
  height: calc(100vh - var(--sidebar-inset) * 2);
  margin: var(--sidebar-inset);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-3);
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: var(--color-sidebar-bg);
  box-shadow: var(--shadow-float);
  color: var(--color-sidebar-text);
}

.sidebar-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}

.brand {
  min-width: 0;
  padding: var(--space-1) var(--space-2) 0;
}

.brand-name {
  font-size: var(--font-size-lg);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--color-sidebar-text-strong);
}

.brand-tagline {
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-sidebar-text);
}

/* The button that collapses / expands the sidebar */
.sidebar-toggle {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--icon-button-size);
  height: var(--icon-button-size);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-sidebar-text);
  transition: background-color var(--transition), color var(--transition);
}

.sidebar-toggle:hover {
  background: var(--color-sidebar-hover);
  color: var(--color-sidebar-text-strong);
}

.sidebar-toggle:focus-visible {
  outline-color: var(--color-sidebar-focus);
}

.sidebar-toggle .icon {
  transition: transform var(--sidebar-duration) ease;
}

/* The phone menu pieces. On a wide screen the wrapper has no box at all
   (display: contents), so the nav lays out in the sidebar exactly as
   before, and the button, title, close button and backdrop are hidden.
   Section 6 (phone) turns them on. */
.menu-panel {
  display: contents;
}

.menu-toggle,
.menu-panel-header,
.menu-backdrop {
  display: none;
}

/* The nav keeps class="tabs": script.js finds the buttons with
   'nav.tabs button' and toggles the "active" class on them. */
.tabs {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* The Settings nav at the bottom of the sidebar: just its own height, so the
   main nav above it takes the free space and Settings sits down by the signed-in box. */
.tabs.tabs-bottom {
  flex: none;
  overflow: visible;
}

.tabs button {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 0.625rem var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-sidebar-text);
  font-size: var(--font-size-base);
  font-weight: 500;
  text-align: left;
  white-space: nowrap;
  transition: background-color var(--transition), color var(--transition);
}

.tabs button:hover {
  background: var(--color-sidebar-hover);
  color: var(--color-sidebar-text-strong);
}

.tabs button.active {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.tabs button:focus-visible {
  outline-color: var(--color-sidebar-focus);
}

/* Collapsed sidebar (desktop only): just a narrow strip of icons.
   The "sidebar-collapsed" class sits on <html> — a tiny script in the
   <head> of index.html adds it before the page is first drawn, so a saved
   collapsed state never flashes open — and script.js toggles it. The
   nav labels stay in the page for screen readers (they're only hidden
   visually), and script.js gives each button a tooltip (title). */
@media (min-width: 48.01em) {
  html.sidebar-collapsed .app-shell {
    --sidebar-current: var(--sidebar-width-collapsed);
  }

  html.sidebar-collapsed .brand {
    display: none;
  }

  html.sidebar-collapsed .sidebar-top {
    justify-content: center;
  }

  html.sidebar-collapsed .sidebar-toggle .icon {
    transform: rotate(180deg);
  }

  html.sidebar-collapsed .tabs button {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }

  html.sidebar-collapsed .nav-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
}

.main {
  min-width: 0; /* lets wide tables scroll inside their card instead of stretching the page */
  padding: var(--space-5) var(--space-5) var(--space-5) var(--space-2);
}

/* Only the section with class "active" is shown (script.js moves the
   class around when a nav button is clicked). */
.tab-section {
  display: none;
  max-width: var(--content-max-width);
}

.tab-section.active {
  display: block;
}

/* Page header: icon + title + description on the left, "Add ..." on the right */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.page-header h2 {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-xl);
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.page-header .page-title-icon {
  width: var(--icon-size-title);
  height: var(--icon-size-title);
  color: var(--color-accent);
}

.page-header p {
  margin-top: var(--space-1);
  color: var(--color-text-muted);
}

.page-header .btn {
  flex: none;
}


/* ---------------------------------------------------------------------
   4. COMPONENTS
   --------------------------------------------------------------------- */

/* --- Buttons ---
   Three styles: primary (Save, Add), secondary (Cancel, Edit, Undo) and
   danger (Delete). Buttons made by script.js (the form's Save/Cancel and
   the Undo button) are matched by where they sit; buttons in index.html
   use the .btn classes. Both end up looking identical. */
.btn,
form button[type="submit"],
.cancel-edit-button,
.undo-message button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.5rem 1rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: 600;
  line-height: 1.25;
  transition: background-color var(--transition), border-color var(--transition),
    color var(--transition);
}

/* Primary */
.btn-primary,
form button[type="submit"] {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.btn-primary:hover,
form button[type="submit"]:hover {
  background: var(--color-accent-hover);
}

/* Secondary */
.btn-secondary,
.cancel-edit-button,
.undo-message button {
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.btn-secondary:hover,
.cancel-edit-button:hover,
.undo-message button:hover {
  background: var(--color-surface-muted);
  border-color: var(--color-text-muted);
}

/* Danger */
.btn-danger {
  background: var(--color-danger-soft);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.btn-danger:hover {
  background: var(--color-danger);
  color: var(--color-on-danger);
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* --- Cards --- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

.table-card {
  overflow: hidden; /* keeps the table's corners rounded with the card */
}

/* --- Forms: labelled fields in a responsive grid (they live in the dialog) --- */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--form-column-min)), 1fr));
  gap: var(--space-4);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.field label {
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 2.5rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: var(--font-size-base);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.field input::placeholder {
  color: var(--color-text-muted);
  opacity: 0.8;
}

.field textarea {
  min-height: 5rem;
  font: inherit;
  resize: vertical;
}

.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: var(--color-text-muted);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
}

/* A heading inside a form ("Cargo") that spans the whole grid */
.form-subheading {
  grid-column: 1 / -1;
  margin: var(--space-2) 0 calc(var(--space-2) * -1);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Every form in the dialog (trips, clients, drivers, trucks, routes, border posts, users) is used on phones too:
   inputs, dropdowns and the Save / Cancel buttons are 44px tall */
#panel-forms .field input,
#panel-forms .field select {
  min-height: var(--tap-target);
}

#panel-forms .form-actions button {
  min-height: var(--tap-target);
}

.form-actions {
  grid-column: 1 / -1; /* the button row spans the whole grid */
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: var(--space-1);
}

/* --- Toasts: short messages at the top centre of the screen ---
   They slide down and fade in, and stack downwards when there are several.
   On a phone the stack starts just below the top bar (see section 6). */
.toast-region {
  position: fixed;
  top: var(--toast-gap);
  left: 0;
  right: 0;
  margin: 0 auto;
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  width: min(var(--toast-width), calc(100% - var(--toast-gap) * 2));
  pointer-events: none; /* the empty region never blocks clicks */
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(calc(var(--toast-offset) * -1));
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  max-width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 1px solid;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-float);
  font-size: var(--font-size-sm);
  font-weight: 600;
  pointer-events: auto;
  animation: toast-in var(--toast-duration) ease-out;
}

.toast-success {
  background: var(--tone-green-bg);
  border-color: var(--tone-green-text);
  color: var(--tone-green-text);
}

.toast-error {
  background: var(--tone-red-bg);
  border-color: var(--tone-red-text);
  color: var(--tone-red-text);
}

.toast-text {
  overflow-wrap: anywhere;
}

/* An "Undo" button inside a toast */
.toast-action {
  flex: none;
  padding: 0 var(--space-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 700;
  text-decoration: underline;
}

.toast-action:hover {
  background: var(--tone-green-text);
  color: var(--tone-green-bg);
}

.toast-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  margin: calc(var(--space-1) * -1) calc(var(--space-2) * -1) calc(var(--space-1) * -1) 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
}

.toast-close:hover {
  background: var(--tone-red-text);
  color: var(--tone-red-bg);
}

/* --- The red message above a form's buttons when a save fails --- */
.form-error {
  flex: 1 1 100%;
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--tone-red-text);
  border-radius: var(--radius-md);
  background: var(--tone-red-bg);
  color: var(--tone-red-text);
  font-size: var(--font-size-sm);
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* --- Search box and status chips above each list --- */
.list-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.search-field {
  position: relative;
  flex: 1 1 14rem;
  max-width: var(--search-width);
}

.search-field .search-icon {
  position: absolute;
  top: 50%;
  left: var(--space-3);
  transform: translateY(-50%);
  color: var(--color-text-muted);
  pointer-events: none;
}

.search-field input {
  width: 100%;
  min-height: 2.5rem;
  padding: 0.5rem 2.5rem 0.5rem 2.5rem; /* room for the icon and the clear button */
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font-size: var(--font-size-base);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.search-field input::placeholder {
  color: var(--color-text-muted);
  opacity: 0.8;
}

.search-field input:hover {
  border-color: var(--color-text-muted);
}

.search-field input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
}

.search-clear {
  position: absolute;
  top: 50%;
  right: var(--space-1);
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
}

.search-clear:hover {
  background: var(--color-surface-muted);
  color: var(--color-text);
}

.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* The second chip row of Trucks and Drivers: the operation (script.js: OPERATIONS). A small word in front says what the chips filter. */
.operation-chips {
  align-items: center;
}

.operation-chips-label {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* The operation under a truck's plate or a driver's name in the tables */
.operation-label {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
}

/* The operation choice above the Dashboard's Last 30 days numbers */
.dash-stats-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0;
}

.dash-stats-filter label {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* A chip is a toggle button. Off: plain outline. On: it takes the colours
   of its status pill (the .tone-* classes are added by script.js). */
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--chip-height);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-sm);
  font-weight: 600;
  transition: background-color var(--transition), border-color var(--transition);
}

.filter-chip:hover {
  border-color: var(--color-text-muted);
}

.filter-chip[aria-pressed="true"] {
  border-color: currentColor;
}

.filter-chip-count {
  min-width: 1.25rem;
  padding: 0 var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  text-align: center;
}

.filter-chip[aria-pressed="true"] .filter-chip-count {
  background: var(--color-surface);
  color: inherit;
}

/* "No matches. Clear filters" (shown when the filters hide every row) */
.no-match-message {
  position: sticky;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  width: 100cqw;
  padding: var(--space-6) var(--space-4);
  color: var(--color-text-muted);
  text-align: center;
  white-space: normal;
}

.no-match-message .icon {
  width: var(--icon-size-empty);
  height: var(--icon-size-empty);
  stroke-width: var(--icon-stroke-empty);
  opacity: 0.6;
}

/* --- Tables --- */
.table-scroll {
  position: relative; /* so the 1px visually-hidden spans inside the table are clipped by this box (they made the whole page scroll sideways on a phone) */
  overflow: auto; /* sideways scrolling happens here, inside the card */
  max-height: var(--table-max-height);
  container-type: inline-size; /* lets the empty-state message use "100cqw" = the visible card width */
}

.data-table {
  width: 100%;
  min-width: var(--table-min-width);
  border-collapse: separate; /* (not "collapse", which breaks sticky headers) */
  border-spacing: 0;
  font-size: var(--font-size-sm);
}

.data-table--wide {
  min-width: var(--table-min-width-wide);
}

.data-table th,
.data-table td {
  padding: 0.75rem var(--space-4);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  vertical-align: middle;
}

.data-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-surface-muted);
  border-bottom-color: var(--color-border-strong);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.data-table tbody tr:last-child td {
  border-bottom: 0;
}

.data-table tbody tr:not(.empty-row):hover td {
  background: var(--color-row-hover);
}

/* Cell types added by script.js */
.data-table td.cell-date {
  white-space: nowrap; /* "15 Apr 2027" should never break across lines */
}

/* Rows open a detail dialog when clicked (or when Enter is pressed) */
.row-clickable {
  cursor: pointer;
}

.row-clickable:focus-visible {
  outline-offset: -2px; /* keeps the focus ring inside the scrolling card */
}

/* The chevron (>) at the end of every row, drawn with two borders */
.data-table th.chevron-col,
.data-table td.row-chevron {
  width: 1%;
  padding-left: 0;
  text-align: right;
}

.data-table td.row-chevron {
  color: var(--color-text-muted);
}

.data-table td.row-chevron::after {
  content: "";
  display: inline-block;
  width: 0.45rem;
  height: 0.45rem;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.6;
  transition: opacity var(--transition), transform var(--transition);
}

.row-clickable:hover td.row-chevron::after,
.row-clickable:focus-visible td.row-chevron::after {
  opacity: 1;
  transform: translateX(2px) rotate(45deg);
}

/* --- Sortable column headers ---
   script.js turns the text of a header that has data-sort into a real
   <button> (so it works with the keyboard) with an arrow after the text.
   The arrow is invisible until the column is sorted (or the header is
   hovered / focused); it points up for ascending and down for descending. */
.data-table thead th.is-sortable {
  padding: 0;
}

.sort-button {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  width: 100%;
  min-height: var(--tap-target);
  padding: 0.75rem var(--space-4);
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-align: left;
  text-transform: inherit;
  white-space: nowrap;
  cursor: pointer;
}

.sort-button:hover {
  color: var(--color-text);
}

.sort-button:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px; /* keeps the focus ring inside the scrolling card */
}

.sort-button .sort-arrow {
  flex: none;
  width: var(--sort-arrow-size);
  height: var(--sort-arrow-size);
  opacity: 0;
  transition: opacity var(--transition), transform var(--transition);
}

.sort-button:hover .sort-arrow,
.sort-button:focus-visible .sort-arrow {
  opacity: 0.5;
}

.data-table thead th[aria-sort="ascending"] .sort-arrow,
.data-table thead th[aria-sort="descending"] .sort-arrow {
  opacity: 1;
}

.data-table thead th[aria-sort="ascending"],
.data-table thead th[aria-sort="descending"] {
  color: var(--color-text);
}

.data-table thead th[aria-sort="descending"] .sort-arrow {
  transform: rotate(180deg);
}

/* --- Phone numbers: the number as a tel: link plus a small WhatsApp link ---
   Only numbers that follow the rule (+ and country code) get these; anything
   else is shown as plain text. */
.phone-value {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
}

.phone-link {
  color: var(--color-accent);
  text-decoration: none;
}

.phone-link:hover {
  text-decoration: underline;
}

.phone-whatsapp {
  display: inline-grid;
  place-items: center;
  /* a comfortable tap area that does not make the table row taller */
  width: var(--tap-target);
  height: var(--tap-target);
  margin: calc((var(--tap-target) - var(--icon-size)) / -2) calc((var(--tap-target) - var(--icon-size)) / -2) calc((var(--tap-target) - var(--icon-size)) / -2) calc(var(--space-1) * -1);
  border-radius: var(--radius-md);
  color: var(--tone-green-text);
}

.phone-whatsapp:hover {
  background: var(--tone-green-bg);
}

.phone-link:focus-visible,
.phone-whatsapp:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* --- Empty state: the friendly row shown when a table has no records ---
   The message is as wide as the VISIBLE card (100cqw) and pinned to the
   left edge while scrolling, so it stays centred on screen even when the
   table underneath is wider than the card. A large muted icon sits above
   the text. */
.data-table td.empty-state {
  padding: 0;
}

.empty-state-message {
  position: sticky;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  width: 100cqw;
  padding: var(--space-7) var(--space-4);
  color: var(--color-text-muted);
  text-align: center;
  white-space: normal;
}

.empty-state-icon {
  width: var(--icon-size-empty);
  height: var(--icon-size-empty);
  stroke-width: var(--icon-stroke-empty);
  opacity: 0.6;
}

/* --- Status pills (Trips, Drivers, Trucks) ---
   .badge is the pill shape; the tone class picks its colours. */
.badge {
  display: inline-block;
  padding: 0.125rem 0.625rem;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}

.badge-grey {
  background: var(--tone-grey-bg);
  color: var(--tone-grey-text);
}

.badge-blue {
  background: var(--tone-blue-bg);
  color: var(--tone-blue-text);
}

.badge-amber {
  background: var(--tone-amber-bg);
  color: var(--tone-amber-text);
}

.badge-green {
  background: var(--tone-green-bg);
  color: var(--tone-green-text);
}

.badge-red {
  background: var(--tone-red-bg);
  color: var(--tone-red-text);
}

/* Document alerts (a driver's or truck's dialog): one line per expired / expiring document */
.compliance-lines {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.compliance-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* The Compliance page's search box is 44px tall (a new page, used on phones too) */
#compliance-section .search-field input {
  min-height: var(--tap-target);
}

/* Compliance page: the "Who / what" cell and the Expires cell are two lines (a name and a small note) */
.data-table td.cell-compliance {
  min-width: 8rem;
}

/* Availability (Drivers and Trucks): the pill, and a small line under it about the trip */
.availability {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  min-width: 0;
}

.availability-note {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 400;
  white-space: normal;
  overflow-wrap: anywhere;
}

.data-table td.cell-availability {
  min-width: 9rem;
  max-width: 14rem;
}

/* A driver's or truck's current and upcoming trips (in their dialog) */
.panel-trip-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.panel-trip-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.panel-trip-item:last-child {
  border-bottom: 0;
}

/* "Recent trips" under the "Active trips" list of a driver or truck */
.panel-subtitle {
  margin-top: var(--space-5);
}

.panel-trip-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.panel-trip-ref {
  font-weight: 600;
}

.panel-trip-route {
  overflow-wrap: anywhere;
}

.panel-trip-dates {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* A pill that sits right after some text (the licence expiry warning) */
.badge-after-text {
  margin-left: var(--space-2);
}

/* --- Documents section in the detail dialog --- */
.doc-list {
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
}

.doc-list li + li {
  border-top: 1px solid var(--color-border);
}

.doc-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
}

.doc-item-icon {
  display: grid;
  place-items: center;
  width: var(--doc-icon-size);
  height: var(--doc-icon-size);
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
  color: var(--color-accent);
}

.doc-item-name {
  display: block;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.doc-item-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.doc-item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

/* small buttons (also used on links that look like buttons) */
.btn-small {
  padding: 0.25rem 0.625rem;
  font-size: var(--font-size-xs);
  text-decoration: none;
}

/* The dashed "drop a file here" area */
.doc-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-4);
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--transition), background-color var(--transition);
}

.doc-dropzone:hover,
.doc-dropzone.is-dragover {
  border-color: var(--color-accent);
  background: var(--color-accent-soft);
  color: var(--color-text);
}

.doc-dropzone-link {
  color: var(--color-accent);
  font-weight: 600;
  text-decoration: underline;
}

.doc-dropzone-hint {
  font-size: var(--font-size-xs);
}

.doc-upload-form {
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
}

.doc-upload-file {
  margin-bottom: var(--space-3);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.doc-upload-form .form-error,
.doc-pick-error {
  margin-top: var(--space-3);
}

#doc-pick-error {
  margin-top: var(--space-3);
}

.doc-upload-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* The paperclip column in the tables */
.data-table th.doc-col,
.data-table td.cell-docs {
  width: 1%;
  padding-right: var(--space-2);
  padding-left: var(--space-2);
  color: var(--color-text-muted);
  text-align: right;
  white-space: nowrap;
}

.doc-count {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.doc-count .icon {
  width: 1rem;
  height: 1rem;
}

/* --- "X deleted. Undo" message (created by script.js above the table) --- */
.undo-message {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-3) var(--space-4);
  padding: 0.5rem var(--space-3);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
  font-size: var(--font-size-sm);
}


/* ---------------------------------------------------------------------
   4b. DASHBOARD
   The home page: a row of count cards, then a grid of panel cards. Every
   panel is one card; script.js adds them from its DASHBOARD_PANELS list,
   so a new panel needs no new CSS unless it has a new kind of content.
   --------------------------------------------------------------------- */
.dashboard-counts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.dashboard-panels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.dashboard-message {
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-muted);
}

.dashboard-message.is-error {
  border-color: var(--tone-red-text);
  background: var(--tone-red-bg);
  color: var(--tone-red-text);
}

/* the Undo message after deleting from a dashboard dialog */
.dashboard-undo .undo-message {
  margin: 0 0 var(--space-4);
  background: var(--color-surface);
}

/* "Updated 14:32" with a small refresh button, under the date */
.dashboard-updated {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.icon-button {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  transition: background-color var(--transition), color var(--transition);
}

.icon-button:hover {
  background: var(--color-surface-muted);
  color: var(--color-text);
}

/* the refresh icon turns while data is loading */
.icon-button.is-refreshing .icon {
  animation: spin var(--spin-duration) linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* --- Count cards (buttons: they open the Trips page) --- */
.dash-count {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  color: inherit;
  text-align: left;
  transition: border-color var(--transition), background-color var(--transition);
}

.dash-count:hover {
  border-color: var(--color-accent);
  background: var(--color-row-hover);
}

.dash-count-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--dashboard-count-icon-size);
  height: var(--dashboard-count-icon-size);
  border-radius: var(--radius-md);
}

.dash-count-number {
  display: block;
  font-size: var(--font-size-xl);
  font-weight: 700;
  line-height: 1.1;
}

.dash-count-label {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  line-height: 1.3;
}

/* Tone colours for the small icon circles (same tones as the status pills) */
.tone-grey { background: var(--tone-grey-bg); color: var(--tone-grey-text); }
.tone-blue { background: var(--tone-blue-bg); color: var(--tone-blue-text); }
.tone-amber { background: var(--tone-amber-bg); color: var(--tone-amber-text); }
.tone-green { background: var(--tone-green-bg); color: var(--tone-green-text); }
.tone-red { background: var(--tone-red-bg); color: var(--tone-red-text); }

/* --- Panel cards --- */
.dashboard-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

.dashboard-card-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.dashboard-card-header .icon {
  color: var(--color-accent);
}

.dashboard-card-title {
  font-size: var(--font-size-base);
  font-weight: 600;
}

.dashboard-card-body {
  flex: 1;
  min-width: 0;
}

/* A panel's friendly "nothing here" message */
.dash-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  color: var(--color-text-muted);
  text-align: center;
}

.dash-empty .icon {
  width: var(--icon-size-dashboard-empty);
  height: var(--icon-size-dashboard-empty);
  stroke-width: var(--icon-stroke-empty);
  opacity: 0.6;
}

/* A list of clickable rows (trips, attention items) */
.dash-list {
  max-height: var(--dashboard-list-max-height);
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.dash-list li + li {
  border-top: 1px solid var(--color-border);
}

.dash-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  transition: background-color var(--transition);
}

.dash-item:hover {
  background: var(--color-row-hover);
}

.dash-item:focus-visible {
  outline-offset: -2px; /* keeps the focus ring inside the card */
}

.dash-item-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
}

.dash-item-main {
  flex: 1;
  min-width: 0;
}

.dash-item-title {
  display: block;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.dash-item-sub {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

/* A trip's History (in the trip dialog): when | what and who */
.history-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.history-item {
  display: grid;
  grid-template-columns: var(--history-time-width) minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.history-item:last-child {
  border-bottom: 0;
}

.history-when {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.history-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.history-what {
  overflow-wrap: anywhere; /* a driver's note can be long */
}

.history-who {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.progress-subtitle {
  font-size: var(--font-size-base);
  font-weight: 600;
}

.progress-editor {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
}

.progress-editor .form-grid {
  margin-top: var(--space-3);
}

.progress-editor input,
.progress-editor select {
  min-height: var(--tap-target);
}

.progress-editor-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.progress-editor-actions button {
  min-height: var(--tap-target);
}

/* The Border Posts page: time at the border, last 90 days */
.stats-card {
  margin-top: var(--space-4);
  padding: var(--space-4);
}

.stats-title {
  margin-bottom: var(--space-1);
  font-size: var(--font-size-lg);
}

/* The Trips table's "Last update" cell: wraps instead of widening the table */
.data-table td.cell-last-update {
  min-width: 9rem;
  max-width: 14rem;
}

.dash-item-side {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}

/* --- Trips by status: pill | bar | count --- */
.dash-bars {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: var(--space-4);
  list-style: none;
}

.dash-bar-row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) 2rem;
  align-items: center;
  gap: var(--space-3);
}

.dash-bar-count {
  font-weight: 600;
  text-align: right;
}

/* The bars are real <progress> elements, so no inline widths are needed.
   Every browser styles them through its own pseudo-elements, which is why
   each rule is written twice. */
.dash-bar {
  width: 100%;
  height: var(--dashboard-bar-height);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-surface-muted);
  appearance: none;
  -webkit-appearance: none;
  overflow: hidden;
}

.dash-bar::-webkit-progress-bar {
  background: var(--color-surface-muted);
}

.dash-bar-grey::-webkit-progress-value { background: var(--tone-grey-text); }
.dash-bar-blue::-webkit-progress-value { background: var(--tone-blue-text); }
.dash-bar-amber::-webkit-progress-value { background: var(--tone-amber-text); }
.dash-bar-green::-webkit-progress-value { background: var(--tone-green-text); }
.dash-bar-red::-webkit-progress-value { background: var(--tone-red-text); }

.dash-bar-grey::-moz-progress-bar { background: var(--tone-grey-text); }
.dash-bar-blue::-moz-progress-bar { background: var(--tone-blue-text); }
.dash-bar-amber::-moz-progress-bar { background: var(--tone-amber-text); }
.dash-bar-green::-moz-progress-bar { background: var(--tone-green-text); }
.dash-bar-red::-moz-progress-bar { background: var(--tone-red-text); }

/* --- Fleet today: a pill and its count, per availability --- */
.dash-fleet-group {
  padding: var(--space-4);
}

.dash-fleet-group + .dash-fleet-group {
  border-top: 1px solid var(--color-border);
}

.dash-fleet-title {
  margin-bottom: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.dash-fleet-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.dash-fleet-list li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.dash-fleet-count {
  font-weight: 700;
}

.dash-fleet-none {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}


/* ---------------------------------------------------------------------
   5. DIALOG
   One dialog (see index.html) is reused by every tab. It appears in the
   middle of the screen over a dimmed backdrop, fading in and growing very
   slightly. The "is-open" class (added by script.js) is what shows it;
   "visibility: hidden" while closed keeps its buttons and fields out of
   the tab order. It is never taller than --dialog-max-height: the title bar
   and the buttons stay put and only the middle (the body) scrolls.
   (The class names still say "panel" because script.js uses them.)
   --------------------------------------------------------------------- */
.panel-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-backdrop);
  background: var(--color-backdrop);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dialog-duration) ease,
    visibility 0s linear var(--dialog-duration);
}

.panel-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.panel {
  position: fixed;
  inset: 0;
  margin: auto; /* with inset: 0, this centres it both ways */
  z-index: var(--z-panel);
  display: flex;
  flex-direction: column;
  width: min(calc(100% - var(--space-5)), var(--dialog-width));
  height: fit-content;
  max-height: var(--dialog-max-height);
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  box-shadow: var(--shadow-dialog);
  opacity: 0;
  transform: scale(var(--dialog-scale-start));
  visibility: hidden;
  transition: opacity var(--dialog-duration) ease,
    transform var(--dialog-duration) ease,
    visibility 0s linear var(--dialog-duration);
}

.panel.is-open {
  opacity: 1;
  transform: none;
  visibility: visible;
  transition-delay: 0s;
}

.panel:focus {
  outline: none; /* the dialog itself is focused programmatically, not by Tab */
}

.panel-header {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.panel-title {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-lg);
  line-height: 1.3;
  overflow-wrap: anywhere;
}

/* Round avatar: initials for people/companies, a truck icon for trucks.
   (A placeholder for a photo that can be uploaded later.) */
.panel-avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: 50%;
  background: var(--color-accent-soft);
  color: var(--color-accent);
  font-size: var(--font-size-lg);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.panel-avatar .icon {
  width: 1.75rem;
  height: 1.75rem;
}

/* The wrapper lets the camera button sit on the avatar's corner */
.panel-avatar-wrap {
  position: relative;
  flex: none;
}

.panel-avatar {
  overflow: hidden;
}

/* A real photo fills the circle */
.panel-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-camera {
  position: absolute;
  right: calc(var(--space-1) * -1);
  bottom: calc(var(--space-1) * -1);
  display: grid;
  place-items: center;
  width: var(--avatar-camera-size);
  height: var(--avatar-camera-size);
  padding: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-text-muted);
  box-shadow: var(--shadow-card);
}

.avatar-camera .icon {
  width: 0.875rem;
  height: 0.875rem;
}

.avatar-camera:hover {
  background: var(--color-accent-soft);
  color: var(--color-accent);
}

.avatar-camera:disabled {
  opacity: 0.6;
  cursor: progress;
}

.panel-close {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--icon-button-size);
  height: var(--icon-button-size);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-muted);
  transition: background-color var(--transition), color var(--transition);
}

.panel-close:hover {
  background: var(--color-surface-muted);
  color: var(--color-text);
}

.panel-body {
  flex: 1;
  min-height: 0; /* lets this middle part shrink and scroll */
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-5);
}

/* The form's button row stays visible at the bottom while a long form scrolls */
.panel-body .form-actions {
  position: sticky;
  bottom: 0;
  padding: var(--space-3) 0 0;
  margin-top: var(--space-2);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}

.panel-footer {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
}

/* Edit on the left, Delete far right: kept well apart */
.panel-footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

/* Trip status buttons: a row ABOVE Edit and Delete, with a thin line between */
.panel-status-actions {
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.panel-status-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.panel-status-hint {
  margin-top: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* A status button wears the colours of the status pill it leads to */
.btn-status-blue {
  background: var(--tone-blue-bg);
  border-color: var(--tone-blue-text);
  color: var(--tone-blue-text);
}

.btn-status-amber {
  background: var(--tone-amber-bg);
  border-color: var(--tone-amber-text);
  color: var(--tone-amber-text);
}

.btn-status-green {
  background: var(--tone-green-bg);
  border-color: var(--tone-green-text);
  color: var(--tone-green-text);
}

.btn-status-blue:hover:not(:disabled),
.btn-status-amber:hover:not(:disabled),
.btn-status-green:hover:not(:disabled) {
  background: var(--color-surface);
}

/* Sections inside the detail view */
.panel-section + .panel-section {
  margin-top: var(--space-5);
}

.panel-section-title {
  margin-bottom: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* "Documents" heading: a button that expands/collapses its content */
.panel-section-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: left;
}

.panel-section-toggle::after {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  margin-right: var(--space-1);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--transition);
}

.panel-section-toggle[aria-expanded="false"]::after {
  transform: rotate(-45deg);
}

.panel-docs-body {
  margin-top: var(--space-3);
}

.panel-empty {
  padding: var(--space-4);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  text-align: center;
}

/* Read-only "label: value" list */
.detail-list {
  margin: 0;
}

.detail-row {
  display: grid;
  grid-template-columns: minmax(6rem, 10rem) minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.detail-row dt {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.detail-row dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.detail-row dd.is-empty {
  color: var(--color-text-muted);
}

/* The small "ID 4" line at the bottom of the Details list */
.detail-id {
  margin-top: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
}


/* ---------------------------------------------------------------------
   5b. ACCOUNTS — login, signed-in box, password screens, Users form
   --------------------------------------------------------------------- */

/* Until the server has confirmed who is logged in, the app is not shown
   (script.js adds "app-ready" to <body>). */
body:not(.app-ready) .app-shell {
  display: none;
}

/* A full-window screen with one card in the middle. Used by login.html and by
   the change-password / "not available" screens in index.html. */
.auth-screen {
  position: fixed;
  inset: 0;
  z-index: var(--z-auth);
  display: grid;
  place-items: center;
  padding: var(--space-4);
  overflow-y: auto;
  background: var(--color-bg);
}

.auth-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: min(var(--auth-card-width), 100%);
  padding: var(--space-6) var(--space-5);
  box-shadow: var(--shadow-float);
}

.auth-card h1,
.auth-card h2 {
  font-size: var(--font-size-xl);
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.auth-brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.auth-brand p,
.auth-intro {
  color: var(--color-text-muted);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.auth-form .form-actions {
  padding-top: var(--space-2);
}

.auth-form .btn,
.auth-form button[type="submit"],
.auth-card .form-actions .btn {
  min-height: var(--tap-target);
}

.auth-form button[type="submit"] {
  flex: 1 1 auto;
}

.auth-note {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* A notice above the login form ("Your session has ended...") */
.auth-notice {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--tone-amber-text);
  border-radius: var(--radius-md);
  background: var(--tone-amber-bg);
  color: var(--tone-amber-text);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* Small grey help line under a field */
.field-hint {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
}

.panel-hint {
  margin-bottom: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.auth-heading {
  margin-bottom: var(--space-1);
  font-size: var(--font-size-lg);
  line-height: 1.25;
}

#setup-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* A password field with the show / hide "eye" button at its right end
   (password-toggle.js wraps every password input in .password-field). */
.password-field {
  position: relative;
}

.field .password-field input {
  padding-right: var(--tap-target); /* room for the button, so text never runs under it */
}

.password-toggle {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%); /* centred on the field; the 44px tap target may stick out a hair above and below */
  display: grid;
  place-items: center;
  width: var(--tap-target);
  height: var(--tap-target);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-muted);
  transition: color var(--transition);
}

.password-toggle:hover {
  color: var(--color-text);
}

.password-toggle:focus-visible {
  outline-offset: -3px; /* inside the field, so the ring is not clipped */
}

/* The signed-in box at the bottom of the sidebar (and of the phone menu) */
.sidebar-user {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-sidebar-hover);
}

/* A button: it opens Settings > My account */
.sidebar-user-info {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  text-align: left;
  transition: background-color var(--transition);
}

.sidebar-user-info:hover {
  background: var(--color-sidebar-hover);
}

.sidebar-user-info:focus-visible {
  outline-color: var(--color-sidebar-focus);
}

.sidebar-user-name {
  overflow: hidden;
  color: var(--color-sidebar-text-strong);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-user-role {
  color: var(--color-sidebar-text);
  font-size: var(--font-size-xs);
}

.sidebar-action {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 0.5rem var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-sidebar-text);
  font-size: var(--font-size-sm);
  font-weight: 500;
  text-align: left;
  white-space: nowrap;
  transition: background-color var(--transition), color var(--transition);
}

.sidebar-action:hover {
  background: var(--color-sidebar-hover);
  color: var(--color-sidebar-text-strong);
}

.sidebar-action:focus-visible {
  outline-color: var(--color-sidebar-focus);
}

@media (min-width: 48.01em) {
  html.sidebar-collapsed .sidebar-user-info {
    display: none;
  }

  html.sidebar-collapsed .sidebar-action {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }
}

/* Settings page: a small tab bar, then one panel at a time. The tabs are real
   buttons; the selected one is underlined. They wrap onto a second row on a
   narrow screen, so nothing scrolls sideways. */
.settings-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.settings-tabs [role="tab"] {
  min-height: var(--tap-target);
  margin-bottom: -1px; /* the underline sits on the bar's own line */
  padding: 0 var(--space-2);
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-base);
  font-weight: 600;
  transition: color var(--transition), border-color var(--transition);
}

.settings-tabs [role="tab"]:hover {
  color: var(--color-text);
}

.settings-tabs [role="tab"][aria-selected="true"] {
  border-bottom-color: var(--color-accent);
  color: var(--color-accent);
}

.settings-card {
  max-width: var(--settings-card-max-width);
  padding: var(--space-2) var(--space-5);
}

.settings-card .detail-row:last-child {
  border-bottom: 0;
}

.settings-card .detail-row dd .field-hint {
  margin-top: var(--space-2);
}

/* The Users tab: its description on the left, "Add User" on the right */
/* Settings > Company */
.company-form {
  padding: var(--space-4) 0;
}

.field-wide {
  grid-column: 1 / -1;
}

/* Big enough to tap: the fields and the Save button of the company form */
.company-form input,
.company-form textarea,
.company-form button[type="submit"] {
  min-height: var(--tap-target);
}

/* An address keeps its line breaks */
.detail-row dd.is-multiline {
  white-space: pre-line;
}

.settings-card > .panel-hint {
  margin: var(--space-3) 0 0;
}

.settings-card > .form-error {
  margin: var(--space-3) 0 0;
}

.settings-panel-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.settings-panel-header p {
  margin: 0;
  color: var(--color-text-muted);
}

/* The Users form: the driver / client dropdown only shows for its own role,
   and the username + first password only when ADDING (script.js puts
   data-editing-id on the form while editing). */
.user-form .field-driver,
.user-form .field-client {
  display: none;
}

.user-form:has(select[name="role"] option[value="driver"]:checked) .field-driver,
.user-form:has(select[name="role"] option[value="client"]:checked) .field-client {
  display: flex;
}

.user-form[data-editing-id] .field-add-only {
  display: none;
}


/* ---------------------------------------------------------------------
   5c. QUESTION DIALOG — the small "Assign anyway?" box
   A native <dialog> (opened with showModal(), so it sits above everything).
   --------------------------------------------------------------------- */
.confirm-dialog {
  width: min(calc(100% - var(--space-5)), var(--confirm-dialog-width));
  padding: 0;
  border: 0;
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-dialog);
}

.confirm-dialog::backdrop {
  background: var(--color-backdrop);
}

.confirm-dialog-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
}

.confirm-dialog-title {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: 1.25;
}

.confirm-dialog-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  overflow-wrap: anywhere;
}

.confirm-dialog-text p {
  margin: 0;
}

.confirm-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding-top: var(--space-2);
}

.confirm-dialog-actions .btn {
  min-height: var(--tap-target);
}

@media (max-width: 30em) {
  .confirm-dialog-actions .btn {
    flex: 1 1 auto;
  }
}

/* ---------------------------------------------------------------------
   6. RESPONSIVE — phone-sized screens
   The floating sidebar turns into a flat top bar: the app name on the left
   and a menu button on the right. The same nav buttons then live in a menu
   panel that drops down from the top over a dimmed backdrop (script.js opens
   and closes it). There is no collapse button on a phone. Dialogs fill
   almost the whole screen.
   --------------------------------------------------------------------- */
@media (max-width: 48em) {
  /* Two rows now (top bar, then content). The content row gets all the
     spare height, so on a short page the top bar doesn't stretch. */
  .app-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .sidebar {
    position: static;
    align-self: auto;
    height: auto;
    margin: 0;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    overflow: visible;
    border-radius: 0;
    box-shadow: none;
  }

  .sidebar-toggle {
    display: none;
  }

  .sidebar-top {
    align-items: center;
  }

  .brand {
    padding: 0;
  }

  .brand-tagline {
    display: none;
  }

  /* The menu button (and the close button inside the menu) */
  .menu-toggle,
  .menu-close {
    flex: none;
    display: grid;
    place-items: center;
    width: var(--tap-target);
    height: var(--tap-target);
    padding: 0;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-sidebar-text-strong);
    transition: background-color var(--transition);
  }

  .menu-toggle:hover,
  .menu-close:hover {
    background: var(--color-sidebar-hover);
  }

  .menu-toggle:focus-visible,
  .menu-close:focus-visible {
    outline-color: var(--color-sidebar-focus);
  }

  /* The menu panel: fixed to the top of the screen, hidden until script.js
     adds "is-open". "visibility: hidden" while closed keeps its buttons out
     of the tab order and away from screen readers. */
  .menu-panel {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: var(--z-menu);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-height: 100vh;
    max-height: 100dvh;
    padding: var(--space-3) var(--space-4) var(--space-4);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
    background: var(--color-sidebar-bg);
    box-shadow: var(--shadow-float);
    opacity: 0;
    transform: translateY(calc(var(--menu-offset) * -1));
    visibility: hidden;
    transition: opacity var(--menu-duration) ease,
      transform var(--menu-duration) ease,
      visibility 0s linear var(--menu-duration);
  }

  .menu-panel.is-open {
    opacity: 1;
    transform: none;
    visibility: visible;
    transition-delay: 0s;
  }

  .menu-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
  }

  .menu-panel-title {
    color: var(--color-sidebar-text-strong);
    font-size: var(--font-size-lg);
    font-weight: 700;
  }

  /* The same nav buttons, as a vertical list of big tap targets */
  .tabs {
    flex: none;
    overflow: visible;
  }

  .tabs button,
  .sidebar-action,
  .sidebar-user-info {
    min-height: var(--tap-target);
    padding: var(--space-2) var(--space-3);
  }

  .settings-card {
    padding: var(--space-1) var(--space-4);
  }

  .settings-panel-header .btn {
    min-height: var(--tap-target);
  }

  .settings-card .btn {
    min-height: var(--tap-target);
  }

  /* The phone numbers in the read-only company details (call / WhatsApp links) */
  .settings-card .detail-row dd a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target);
  }

  .menu-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: var(--z-menu-backdrop);
    background: var(--color-backdrop);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--menu-duration) ease,
      visibility 0s linear var(--menu-duration);
  }

  .menu-backdrop.is-open {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
  }

  .main {
    padding: var(--space-4);
  }

  .page-header {
    flex-direction: column;
    align-items: stretch;
  }

  .page-header h2 {
    font-size: var(--font-size-lg);
  }

  /* List search + chips: full-width search, bigger chips to tap */
  .search-field {
    flex-basis: 100%;
    max-width: none;
  }

  .filter-chip {
    min-height: var(--tap-target);
  }

  /* Toasts: just below the top bar, so the menu button stays uncovered */
  .toast-region {
    top: calc(var(--topbar-height) + var(--space-2));
  }

  /* Dashboard: everything in one column */
  .dashboard-counts,
  .dashboard-panels {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Dialogs: nearly full screen, with a small margin all round */
  .panel {
    width: calc(100% - var(--space-3));
    height: calc(100vh - var(--space-3));
    height: calc(100dvh - var(--space-3));
    max-height: none;
    border-radius: var(--radius-lg);
  }

  .panel-header,
  .panel-footer {
    padding-left: var(--space-4);
    padding-right: var(--space-4);
  }

  /* documents: the actions drop below the file name */
  .doc-item {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .doc-item-actions {
    grid-column: 1 / -1;
  }

  .doc-item-actions .btn-small {
    min-height: var(--tap-target);
  }

  .avatar-camera {
    width: calc(var(--avatar-camera-size) + var(--space-2));
    height: calc(var(--avatar-camera-size) + var(--space-2));
  }

  /* big status / Edit / Delete buttons that are easy to tap */
  .panel-status-buttons .btn,
  .panel-footer-row .btn {
    min-height: var(--tap-target);
  }

  .panel-status-buttons .btn {
    flex: 1 1 auto;
  }

  .panel-body {
    padding: var(--space-4);
  }

  /* a trip's History: time above the text */
  .history-item {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-1);
  }

  /* label above value instead of side by side */
  .detail-row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-1);
  }
}

/* =====================================================================
   7. THE TRIP SCREENS: drawer, tabs, timeline, New trip steps, rounded fields
   ---------------------------------------------------------------------
   Everything below belongs to the trip's detail drawer and the New trip / Edit trip form (script.js: TRIP DRAWER, NEW TRIP
   STEPS, TRIP PROGRESS). It is added AFTER everything else so the older dialog rules (which every other page still uses)
   are untouched: the drawer only changes a dialog whose data-size is "drawer". Colours are the meaning tokens in :root
   (green = done, yellow = waiting / attention, red = problem, blue = buttons and selection, grey = not done yet).
   Colour is never the only signal: every state below also has a word, a tick or an icon.
   ===================================================================== */

/* --- 7a. The drawer itself --- */
.panel[data-size="drawer"] {
  inset: 0 0 0 auto;              /* stuck to the right edge, full height */
  margin: 0;
  width: min(100%, var(--drawer-width));
  height: 100vh;
  height: 100dvh;
  max-height: none;
  border-radius: var(--radius-xl) 0 0 var(--radius-xl);
  opacity: 1;                     /* it slides in (visibility keeps it out of reach while closed) */
  transform: translateX(100%);
  transition: transform var(--drawer-duration) ease, visibility 0s linear var(--drawer-duration);
}

.panel[data-size="drawer"].is-open {
  transform: none;
  transition-delay: 0s;
}

/* a phone: the drawer is the whole screen */
@media (max-width: 47.99em) {
  .panel[data-size="drawer"] {
    width: 100%;
    border-radius: 0;
  }
}

/* The close button is a full 44px target here (every other dialog keeps its smaller one) */
.panel[data-size="drawer"] .panel-close {
  width: var(--tap-target);
  height: var(--tap-target);
}

/* --- 7b. The header: reference + status, route, client --- */
.panel.is-drawer-detail .panel-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "top close"
    "title title"
    "client client";
  align-items: center;
  column-gap: var(--space-3);
  row-gap: 0;
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 0;
}

.panel.is-drawer-detail .trip-head-top {
  grid-area: top;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.panel.is-drawer-detail .panel-title {
  grid-area: title;
  font-size: var(--font-size-title);
  font-weight: 700;
  line-height: 1.25;
}

.panel.is-drawer-detail .panel-close {
  grid-area: close;
  align-self: start;
}

.trip-head-ref {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.trip-head-client {
  grid-area: client;
  color: var(--color-text-muted);
  font-size: var(--font-size-base);
}

/* --- 7c. The part of the head that stays in view: crew, steps bar, alerts, tabs --- */
.trip-head {
  flex: none;
  padding: 0 var(--space-5);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}

.trip-crew {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  margin: 0 0 var(--space-2);
}

.trip-crew-item dt {
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.trip-crew-item dd {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* nine small bars: one per milestone, green when it is recorded */
.drawer-steps {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.drawer-steps-bar {
  flex: 1;
  display: flex;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.drawer-step-seg {
  flex: 1;
  height: 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--color-border-strong);
}

.drawer-step-seg.is-done {
  background: var(--color-success);
}

.drawer-steps-text {
  flex: none;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* what needs attention (yellow = waiting / running out, red = expired / a problem) */
.trip-alerts {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
}

.trip-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: 600;
  line-height: 1.35;
}

.trip-alert .icon {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.1rem;
}

.trip-alert.is-attention {
  border-color: var(--color-attention);
  background: var(--color-attention-soft);
  color: var(--color-attention-text);
}

.trip-alert.is-danger {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
  color: var(--color-danger-text);
}

.trip-alert-more {
  padding: 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* the tabs: a row that scrolls sideways inside itself (the page never does) */
.trip-tabs {
  display: flex;
  gap: var(--space-1);
  margin: 0 calc(var(--space-5) * -1);
  padding: 0 var(--space-5);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.trip-tabs::-webkit-scrollbar {
  display: none;
}

.trip-tab {
  flex: none;
  min-height: var(--drawer-tab-height);
  padding: 0 var(--space-3);
  border: 0;
  border-bottom: 3px solid transparent;
  background: transparent;
  color: var(--color-text-muted);
  font-weight: 600;
  white-space: nowrap;
}

.trip-tab:hover {
  color: var(--color-text);
}

.trip-tab[aria-selected="true"] {
  border-bottom-color: var(--color-accent);
  color: var(--color-info-text);
}

.trip-tab:focus-visible {
  outline-offset: -3px;
}

.trip-tab-count {
  color: var(--color-text-muted);
  font-weight: 500;
}

/* --- 7d. The panes: one tab shows exactly one --- */
#panel-detail[data-active-tab="details"] > [data-tab-pane]:not([data-tab-pane="details"]),
#panel-detail[data-active-tab="cargo"] > [data-tab-pane]:not([data-tab-pane="cargo"]),
#panel-detail[data-active-tab="progress"] > [data-tab-pane]:not([data-tab-pane="progress"]),
#panel-detail[data-active-tab="documents"] > [data-tab-pane]:not([data-tab-pane="documents"]),
#panel-detail[data-active-tab="history"] > [data-tab-pane]:not([data-tab-pane="history"]) {
  display: none;
}

/* the tab names the pane, so its own small title and the "Documents" fold-up button are not needed */
.panel.is-drawer-detail [data-tab-pane] > .panel-section-title,
.panel.is-drawer-detail .panel-section-toggle {
  display: none;
}

/* ...except the "Recent trips" heading under the Active trips list: it is a second list in the same tab, so it keeps its title
   (the script hides it while the list has no rows) */
.panel.is-drawer-detail [data-tab-pane] > .panel-section-title.panel-subtitle {
  display: block;
}

.panel.is-drawer-detail [data-tab-pane] > .panel-section-title.panel-subtitle[hidden] {
  display: none;
}

.panel.is-drawer-detail #panel-detail > .panel-section {
  margin-top: 0;
}

.panel.is-drawer-detail .panel-docs-body {
  margin-top: 0;
}

.panel.is-drawer-detail [data-tab-pane]:focus-visible {
  outline-offset: 4px;
}

.panel[data-size="drawer"] .panel-body {
  padding: var(--space-5);
}

/* --- 7e. Progress: ONE vertical flow of steps --- */
.progress-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.progress-top .panel-hint {
  margin: 0;
}

.progress-action {
  min-height: var(--tap-target);
}

.flow {
  margin: 0;
  padding: 0;
  list-style: none;
}

.flow-item,
.flow-aside {
  position: relative;
}

.flow-item {
  display: grid;
  grid-template-columns: var(--step-circle-size) minmax(0, 1fr);
  column-gap: var(--space-3);
  padding-bottom: var(--space-4);
}

/* the line that joins one circle to the next: green after a step that is done */
.flow-item::before,
.flow-aside::before {
  content: "";
  position: absolute;
  top: var(--step-circle-size);
  bottom: 0;
  left: calc(var(--step-circle-size) / 2 - var(--flow-line-width) / 2);
  width: var(--flow-line-width);
  background: var(--color-border-strong);
}

.flow-item.is-done::before {
  background: var(--color-success);
}

.flow-item:last-child::before {
  display: none;
}

.flow-aside {
  padding: 0 0 var(--space-4) calc(var(--step-circle-size) + var(--space-3));
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.flow-aside::before {
  top: 0;
}

.flow-mark {
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
  width: var(--step-circle-size);
  height: var(--step-circle-size);
  border: 2px solid var(--color-neutral-ring);
  border-radius: 50%;
  background: var(--color-surface);
}

.flow-mark .icon {
  width: 1.25rem;
  height: 1.25rem;
  stroke-width: 2.5;
}

/* done: a green circle with a white tick */
.flow-mark.is-done {
  border-color: var(--color-success);
  background: var(--color-success);
  color: var(--color-on-success);
}

/* a truck waiting at a border: yellow with an hourglass and a dark outline */
.flow-mark.is-wait {
  border-color: var(--color-attention-text);
  background: var(--color-attention);
  color: var(--color-on-attention);
}

.flow-mark.is-wait .icon {
  width: 1.125rem;
  height: 1.125rem;
}

.flow-main {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
  padding-top: 0.375rem;
  overflow-wrap: anywhere;
}

.flow-label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-weight: 600;
}

.flow-item.is-todo .flow-label {
  color: var(--color-text-muted);
}

.flow-when,
.flow-note {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.flow-actions {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.flow-chip {
  align-self: flex-start;
  padding: 0.125rem var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-neutral-soft);
  color: var(--color-neutral-text);
  font-size: var(--font-size-xs);
  font-weight: 700;
}

.flow-chip.is-attention {
  border: 1px solid var(--color-attention);
  background: var(--color-attention-soft);
  color: var(--color-attention-text);
}

/* an open border crossing: the whole entry is yellow */
.flow-item.is-open .flow-main {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-attention);
  border-radius: var(--radius-md);
  background: var(--color-attention-soft);
}

.flow-item.is-open .flow-when {
  color: var(--color-attention-text);
}

/* buttons used in the timeline */
.btn-quiet-danger {
  border-color: transparent;
  background: transparent;
  color: var(--color-danger-text);
}

.btn-quiet-danger:hover:not(:disabled) {
  background: var(--color-danger-soft);
}

.btn-attention {
  border-color: var(--color-attention-text);
  background: var(--color-attention);
  color: var(--color-on-attention);
}

.btn-attention:hover:not(:disabled) {
  background: var(--color-attention-soft);
}

/* --- 7f. The footer of the drawer --- */
.panel[data-size="drawer"] .panel-footer {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--color-surface);
}

/* the buttons of the status row and of the Edit / Delete row become one row */
.panel[data-size="drawer"] .panel-status-actions,
.panel[data-size="drawer"] .panel-status-buttons,
.panel[data-size="drawer"] .panel-footer-row {
  display: contents;
}

.panel[data-size="drawer"] .panel-footer .btn {
  min-height: var(--tap-target);
  padding: 0 var(--space-4);
  font-weight: 600;
}

/* the main action: solid (green when it finishes the trip, blue otherwise) */
.panel[data-size="drawer"] .panel-status-buttons .btn:not([data-status-action="cancelled"]) {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.panel[data-size="drawer"] .panel-status-buttons .btn[data-status-action="delivered"] {
  border-color: var(--color-success);
  background: var(--color-success);
  color: var(--color-on-success);
}

.panel[data-size="drawer"] .panel-status-buttons .btn:disabled {
  opacity: 0.55;
}

/* Cancel trip: red outline */
.panel[data-size="drawer"] .panel-status-buttons .btn[data-status-action="cancelled"] {
  border: 1.5px solid var(--color-danger);
  background: var(--color-surface);
  color: var(--color-danger-text);
}

/* Edit trip: blue, calm */
.panel[data-size="drawer"] #panel-edit {
  border: 1.5px solid var(--color-accent);
  background: var(--color-info-soft);
  color: var(--color-info-text);
}

/* Delete: far away from the others and quiet */
.panel[data-size="drawer"] #panel-delete {
  margin-left: auto;
  border-color: transparent;
  background: transparent;
  color: var(--color-danger-text);
  font-weight: 500;
}

.panel[data-size="drawer"] #panel-delete:hover:not(:disabled) {
  background: var(--color-danger-soft);
}

.panel[data-size="drawer"] .panel-status-hint {
  order: 10;
  flex: 1 1 100%;
}

/* "More" (a phone only) */
.panel-more {
  position: relative;
  display: none;
}

.panel-more-menu {
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--space-2));
  z-index: 2;
  min-width: 12rem;
  margin: 0;
  padding: var(--space-1);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-float);
  list-style: none;
}

.panel-more-item {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--tap-target);
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  font-weight: 600;
  text-align: left;
}

.panel-more-item:hover {
  background: var(--color-surface-muted);
}

.panel-more-item.is-danger {
  color: var(--color-danger-text);
}

@media (max-width: 47.99em) {
  .panel[data-size="drawer"] .panel-footer {
    flex-wrap: nowrap;
    padding: var(--space-3) var(--space-4);
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
  }

  /* the main action and More; everything else lives in More */
  .panel[data-size="drawer"] .panel-status-buttons .btn[data-status-action="cancelled"],
  .panel[data-size="drawer"] #panel-edit,
  .panel[data-size="drawer"] #panel-delete {
    display: none;
  }

  .panel[data-size="drawer"] .panel-footer:not(.has-primary) #panel-edit {
    display: inline-flex;
  }

  .panel[data-size="drawer"] .panel-status-buttons .btn,
  .panel[data-size="drawer"] #panel-edit {
    flex: 1 1 auto;
  }

  .panel[data-size="drawer"] .panel-more {
    display: block;
    flex: none;
  }

  .panel[data-size="drawer"] .panel-status-hint {
    order: 0;
    flex: 1 1 100%;
  }

  .panel[data-size="drawer"] .panel-footer {
    flex-wrap: wrap;
  }

  .panel.is-drawer-detail .panel-header,
  .trip-head,
  .panel[data-size="drawer"] .panel-body {
    padding-left: var(--space-4);
    padding-right: var(--space-4);
  }

  .trip-tabs {
    margin: 0 calc(var(--space-4) * -1);
    padding: 0 var(--space-4);
  }
}

/* the one-line summary of several alerts (a phone only; see below) */
.trip-alerts-toggle {
  display: none;
}

/* a phone: the head must stay small (about a third of the screen at most). Several alerts fold into one tappable line, and
   on a screen that is not very tall the truck / driver / date row folds away (the same facts are in the Details tab). */
@media (max-width: 47.99em) {
  .panel.is-drawer-detail .panel-title {
    font-size: var(--font-size-lg);
  }

  .trip-alerts-toggle {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: var(--tap-target);
    margin-bottom: var(--space-2);
    padding: 0 var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: 700;
    text-align: left;
  }

  .trip-alerts-toggle .icon {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
  }

  .trip-alerts-toggle::after {
    content: "";
    flex: none;
    width: 0.45rem;
    height: 0.45rem;
    margin-left: auto;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
  }

  .trip-alerts-toggle[aria-expanded="true"]::after {
    transform: rotate(-135deg);
  }

  .trip-alerts-toggle.is-attention {
    border-color: var(--color-attention);
    background: var(--color-attention-soft);
    color: var(--color-attention-text);
  }

  .trip-alerts-toggle.is-danger {
    border-color: var(--color-danger);
    background: var(--color-danger-soft);
    color: var(--color-danger-text);
  }

  /* folded until the line is tapped; opened, the list scrolls inside itself so the head never takes over the screen */
  .trip-alerts[data-collapsible="true"]:not([data-open="true"]) {
    display: none;
  }

  .trip-alerts {
    max-height: 30vh;
    overflow-y: auto;
  }
}

@media (max-width: 47.99em) and (max-height: 50em) {
  .trip-crew {
    display: none;
  }
}

/* --- 7g. New trip: the four numbered steps --- */
.trip-stepper {
  flex: none;
  padding: var(--space-3) var(--space-5) var(--space-2);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}

.stepper-list {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}

.stepper-item {
  position: relative;
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
  text-align: center;
}

/* the line from the circle before to this one, drawn behind the circles */
.stepper-item + .stepper-item::before {
  content: "";
  position: absolute;
  top: calc(var(--step-circle-size) / 2 - var(--flow-line-width) / 2);
  right: 50%;
  width: 100%;
  height: var(--flow-line-width);
  background: var(--color-border-strong);
}

.stepper-item.is-done + .stepper-item::before {
  background: var(--color-success);
}

.stepper-circle {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--step-circle-size);
  height: var(--step-circle-size);
  border: 2px solid var(--color-neutral-ring);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-weight: 700;
}

.stepper-item.is-current .stepper-circle {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-on-accent);
  box-shadow: var(--shadow-focus);
}

/* a finished step: a green circle with a white tick (drawn with borders, so it follows the colour tokens) */
.stepper-item.is-done .stepper-circle {
  border-color: var(--color-success);
  background: var(--color-success);
  font-size: 0;
}

.stepper-item.is-done .stepper-circle::after {
  content: "";
  width: 0.7rem;
  height: 0.4rem;
  margin-top: -0.15rem;
  border-bottom: 2px solid var(--color-on-success);
  border-left: 2px solid var(--color-on-success);
  transform: rotate(-45deg);
}

.stepper-label {
  max-width: 100%;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.stepper-item.is-current .stepper-label {
  color: var(--color-text);
}

.stepper-count {
  margin-top: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
  text-align: center;
}

/* which fields show: ADD shows one step at a time, EDIT shows everything */
.trip-form[data-mode="step"][data-step-current="1"] [data-step]:not([data-step="1"]),
.trip-form[data-mode="step"][data-step-current="2"] [data-step]:not([data-step="2"]),
.trip-form[data-mode="step"][data-step-current="3"] [data-step]:not([data-step="3"]),
.trip-form[data-mode="step"][data-step-current="4"] [data-step]:not([data-step="4"]),
.trip-form[data-mode="edit"] [data-step="4"],
.trip-form[data-mode="edit"] .step-intro {
  display: none;
}

.trip-form .step-heading[data-step="1"] {
  padding-top: 0;
  border-top: 0;
}

.trip-form[data-mode="step"] .step-heading {
  margin: 0;
  padding-top: 0;
  border-top: 0;
  color: var(--color-text);
  font-size: var(--font-size-lg);
  letter-spacing: 0;
  text-transform: none;
}

.trip-form .step-heading:focus {
  outline: none;
}

.step-intro {
  grid-column: 1 / -1;
  margin: calc(var(--space-2) * -1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* the red box at the top of the form */
.step-error-box {
  grid-column: 1 / -1;
  padding: var(--space-3) var(--space-4);
  border: 1.5px solid var(--color-danger);
  border-radius: var(--radius-md);
  background: var(--color-danger-soft);
  color: var(--color-danger-text);
  font-size: var(--font-size-sm);
}

.step-error-box ul {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-5);
}

/* Review */
.trip-review {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.review-group {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.review-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.review-title {
  font-size: var(--font-size-base);
  font-weight: 700;
}

.review-change {
  min-height: var(--tap-target);
}

/* --- 7h. THE ROUNDED FIELDS (reusable: put class "field-lg" on a .field) ---
   56px or taller, the label small inside the top edge, 17px semi-bold value, a lighter placeholder, a clear blue focus
   ring, a unit inside the field, a grey hint under it, a small green tick when it is filled and valid. */
.field.field-lg {
  position: relative;
  gap: 0;
}

.field-lg > label {
  position: absolute;
  z-index: 1;
  top: var(--space-2);
  left: var(--space-4);
  right: var(--space-4);
  overflow: hidden;
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: 600;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none; /* a click goes through to the field underneath */
}

.field-lg > input,
.field-lg > select,
#panel-forms .field-lg > input,
#panel-forms .field-lg > select {
  min-height: var(--field-height);
  padding: 1.6rem var(--space-4) 0.45rem;
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--field-font-size);
  font-weight: 600;
}

.field-lg > input::placeholder {
  color: var(--color-text-muted);
  font-weight: 400;
  opacity: 1;
}

.field-lg > input:hover,
.field-lg > select:hover {
  border-color: var(--color-text-muted);
}

.field-lg > input:focus,
.field-lg > select:focus {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
}

.field-lg:focus-within > label {
  color: var(--color-info-text);
}

.field-lg > input.is-mono {
  font-family: var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.field-lg > input.is-mono::placeholder {
  text-transform: none;
}

.field-lg > input.has-unit {
  padding-right: 2.75rem;
}

.field-unit {
  position: absolute;
  top: 1.6rem;
  right: var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--field-font-size);
  font-weight: 600;
  line-height: 1.35;
  pointer-events: none;
}

.field-lg .field-hint {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* a filled, valid field shows a small green tick (the tick shape is the signal; the colour only helps) */
.field-lg.is-valid::after {
  content: "";
  position: absolute;
  top: 1.45rem;
  right: var(--space-4);
  width: 0.7rem;
  height: 0.4rem;
  border-bottom: 2px solid var(--color-success);
  border-left: 2px solid var(--color-success);
  transform: rotate(-45deg);
  pointer-events: none;
}

.field-lg.is-valid:has(.field-unit)::after {
  right: 2.6rem;
}

.field-lg.has-error > input,
.field-lg.has-error > select {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
}

.field-lg.has-error > label {
  color: var(--color-danger-text);
}

.field-error {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-1);
  color: var(--color-danger-text);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

/* --- 7i. The trip form fills the drawer: its Back / Next / Save bar stays pinned at the bottom --- */
.panel[data-size="drawer"] .panel-body {
  display: flex;
  flex-direction: column;
}

.panel[data-size="drawer"] #panel-forms,
.panel[data-size="drawer"] #panel-forms > [data-panel-form] {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

.panel[data-size="drawer"] .trip-form,
.panel[data-size="drawer"] .drawer-form {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

.panel[data-size="drawer"] .trip-form-fields,
.panel[data-size="drawer"] .drawer-form-fields {
  flex: 1 0 auto;
  align-content: start;
}

.panel[data-size="drawer"] .trip-form .form-actions,
.panel[data-size="drawer"] .drawer-form .form-actions {
  margin-top: auto;
  padding: var(--space-3) 0 0;
}

/* a detail view keeps the normal flow inside the (now flex) body */
.panel[data-size="drawer"] #panel-detail {
  flex: 1 0 auto;
}

/* =====================================================================
   8. THE OTHER RECORDS IN THE DRAWER: clients, drivers, trucks, routes, border posts, users
   ---------------------------------------------------------------------
   They open in the same drawer as a trip (section 7: script.js ENTITY DRAWER): the same header, key facts, alert strip,
   tabs and footer, and the same rounded fields. Only what differs from a trip is here; the class names of the shared
   parts (trip-head, trip-tabs, trip-alert ...) are the trip drawer's own and are used as they are. Colours are the meaning
   tokens in :root. Colour is never the only signal: pills and alert lines also have words and icons.
   ===================================================================== */

/* the Trips tab of a driver or a truck */
#panel-detail[data-active-tab="trips"] > [data-tab-pane]:not([data-tab-pane="trips"]) {
  display: none;
}

/* --- 8a. The header with a round picture (clients, drivers, trucks, users): the picture on the left, the rest beside it --- */
.panel.is-entity-drawer .panel-header {
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "avatar top close"
    "avatar title title"
    "avatar client client";
  column-gap: var(--space-3);
}

.panel.is-entity-drawer .panel-header:has(.panel-avatar-wrap[hidden]) {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "top close"
    "title title"
    "client client";
}

.panel.is-entity-drawer .panel-avatar-wrap {
  grid-area: avatar;
  align-self: center;
}

/* the camera button is a small circle on the picture but a full 44px target */
.panel[data-size="drawer"] .avatar-camera {
  width: var(--avatar-camera-size);
  height: var(--avatar-camera-size);
}

.panel[data-size="drawer"] .avatar-camera::after {
  content: "";
  position: absolute;
  inset: -0.625rem;
}

/* --- 8b. The footer: Edit (blue), Reset password, and the quiet button on the far right --- */
.panel[data-size="drawer"] #panel-delete.btn-secondary {
  color: var(--color-info-text); /* Reactivate is not a warning */
}

.panel[data-size="drawer"] #panel-delete:disabled {
  opacity: 0.55;
}

@media (max-width: 47.99em) {
  /* on a phone Reset password and Unlock account live in the More menu with Deactivate */
  .panel[data-size="drawer"] #panel-reset-password,
  .panel[data-size="drawer"] #panel-unlock-account {
    display: none;
  }
}

/* A login that is locked (too many wrong passwords): a yellow pill with a lock and words, under the status of the user */
.badge-locked {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.badge-locked .icon {
  width: 1em;
  height: 1em;
}

/* --- 8c. The rounded fields for the records' forms (section 7h has the field itself) --- */
/* a unit inside the field: "t" and "km" */
.field-lg > input.has-unit[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

.field-lg > input.has-unit[type="number"]::-webkit-inner-spin-button,
.field-lg > input.has-unit[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.field-lg > input.has-unit-wide {
  padding-right: 3.5rem;
}

.field-lg.is-valid:has(.field-unit-wide)::after {
  right: 3.35rem;
}

/* a password field: the same rounded look, the eye button stays at its end */
.field-lg .password-field > input {
  width: 100%;
  min-height: var(--field-height);
  padding: 1.6rem calc(var(--tap-target) + var(--space-1)) 0.45rem var(--space-4);
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--field-font-size);
  font-weight: 600;
}

.field-lg .password-field > input:hover {
  border-color: var(--color-text-muted);
}

.field-lg .password-field > input:focus {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
  outline: none;
}

.field-lg.has-error .password-field > input {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
}

.field-lg .password-toggle {
  right: var(--space-1);
}

/* a field that is not shown (the driver / client dropdown of the Users form) takes no room */
.drawer-form .field-lg[hidden] {
  display: none;
}

/* a form fills the drawer to its bottom edge: no empty strip under the Save / Cancel row, and the row stays above the
   labels of the fields that scroll under it */
.panel[data-size="drawer"] .panel-body:has(#panel-forms:not([hidden]) > [data-panel-form]:not([hidden]) > :is(.drawer-form, .trip-form)) {
  padding-bottom: 0;
}

.panel[data-size="drawer"] :is(.drawer-form, .trip-form) .form-actions {
  z-index: 2;
  padding-bottom: var(--space-4);
}

/* a field with a problem: the outline and the background turn red (the message under it says what is wrong) */
#panel-forms :is(.drawer-form, .trip-form) .field-lg.has-error > input,
#panel-forms :is(.drawer-form, .trip-form) .field-lg.has-error > select,
#panel-forms :is(.drawer-form, .trip-form) .field-lg.has-error .password-field > input {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
}

/* --- 8d. A phone: the key facts of a record show two across (the third one is in the Details tab), so the head stays small --- */
@media (max-width: 47.99em) {
  .panel.is-entity-drawer .trip-crew {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .panel.is-entity-drawer .trip-crew-item:nth-child(n + 3) {
    display: none;
  }
}

/* --- 8e. The Reset password section of a user: set apart from the details, its field is a rounded field too --- */
.panel.is-entity-drawer #panel-reset-section {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.panel.is-entity-drawer #panel-reset-section .form-actions {
  position: static;
  border-top: 0;
  padding-top: 0;
}

/* --- 8f. The buttons of a document in a record's drawer (View, Download, Delete) are full 44px targets --- */
.panel.is-entity-drawer .doc-item-actions .btn-small {
  min-height: var(--tap-target);
}

/* =====================================================================
   9. THE MAINTENANCE TAB OF A TRUCK (script.js: MAINTENANCE)
   ---------------------------------------------------------------------
   Unique class names (maint-*): this stylesheet is shared with the driver and client pages. Yellow = in the workshop now
   (the attention token), green = the "back" button, red = Delete. Every state also has words and an icon.
   ===================================================================== */
#panel-detail[data-active-tab="maintenance"] > [data-tab-pane]:not([data-tab-pane="maintenance"]) {
  display: none;
}

.maint-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.maint-top .panel-hint {
  flex: 1 1 14rem;
  margin: 0;
}

.maint-add {
  min-height: var(--tap-target);
}

.maint-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.maint-item {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

/* an open record: the truck is in the workshop now */
.maint-item.is-open {
  border-color: var(--color-attention);
  background: var(--color-attention-soft);
}

.maint-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.maint-workshop {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.maint-when {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  font-weight: 600;
}

.maint-item.is-open .maint-when {
  color: var(--color-attention-text);
}

.maint-when .icon {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
}

.maint-text,
.maint-cost {
  margin: var(--space-1) 0 0;
  overflow-wrap: anywhere;
}

.maint-notes,
.maint-meta {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.maint-meta {
  margin: var(--space-1) 0 0;
}

.maint-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.maint-actions .btn {
  min-height: var(--tap-target);
}

.maint-delete {
  margin-left: auto;
  border-color: transparent;
  background: transparent;
  color: var(--color-danger-text);
  font-weight: 500;
}

.maint-delete:hover {
  background: var(--color-danger-soft);
}

/* the add / edit form inside the pane */
.maint-form {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
}

.maint-form .field-wide {
  grid-column: 1 / -1;
}

.maint-form .field-lg > select {
  width: 100%;
}

/* =====================================================================
   10. TRIP EXPENSES (script.js: EXPENSES) AND EXCHANGE RATES (script.js: EXCHANGE RATES)
   ---------------------------------------------------------------------
   Unique class names (exp-*, rate-*): this stylesheet is shared with the driver and client pages. Green = up to date,
   yellow = getting old, red = too old or a problem, blue = the chosen chip; every state also has words.
   ===================================================================== */
#panel-detail[data-active-tab="expenses"] > [data-tab-pane]:not([data-tab-pane="expenses"]) {
  display: none;
}

.exp-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.exp-total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}

.exp-total-label {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.exp-total-value {
  font-size: var(--font-size-title);
  font-weight: 700;
}

.exp-total-note {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.exp-add {
  min-height: var(--tap-target);
}

.exp-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.exp-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}

.exp-day {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: 700;
}

.exp-day-total {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.exp-item {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.exp-main {
  flex: 1 1 14rem;
  min-width: 0;
}

.exp-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.exp-detail {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.exp-amounts {
  margin: var(--space-1) 0 0;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.exp-note {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

.exp-actions {
  display: flex;
  gap: var(--space-2);
}

.exp-actions .btn {
  min-height: var(--tap-target);
}

.exp-delete {
  border-color: transparent;
  background: transparent;
  color: var(--color-danger-text);
  font-weight: 500;
}

.exp-delete:hover {
  background: var(--color-danger-soft);
}

/* the form */
.exp-form {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
}

.exp-form .field-wide {
  grid-column: 1 / -1;
}

.exp-kinds {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.exp-kinds legend {
  padding: 0;
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.exp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.exp-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-target);
  padding: 0 var(--space-4);
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  font-weight: 600;
  cursor: pointer;
}

.exp-chip input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.exp-chip.is-chosen {
  border-color: var(--color-accent);
  background: var(--color-info-soft);
  color: var(--color-info-text);
}

.exp-chip:focus-within {
  box-shadow: var(--shadow-focus);
}

/* =====================================================================
   REPORTS (script.js: REPORTS). Unique class names (rpt-*): this stylesheet is shared with the driver and client pages.
   ===================================================================== */
.rpt-range {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding: var(--space-4);
}

.rpt-presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.rpt-presets .btn,
.rpt-dates .btn,
.rpt-download {
  min-height: var(--tap-target);
}

.rpt-dates {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-3);
}

.rpt-dates .field {
  flex: 1 1 11rem;
  max-width: 16rem;
}

.rpt-period {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  font-weight: 600;
}

.rpt-sections {
  display: grid;
  gap: var(--space-4);
}

.rpt-card {
  padding: var(--space-4);
}

.rpt-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.rpt-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: 700;
}

.rpt-total {
  margin: var(--space-2) 0;
  font-weight: 700;
}

.rpt-note,
.rpt-empty {
  margin: var(--space-1) 0 var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* A report table shows EVERY row in the page (no box with its own vertical scroll, so no scrolling inside scrolling). A table wider than
   its card still scrolls sideways inside it; one that fits lets go of its overflow ("is-fit", script.js: watchReportTableFit), so
   its header sticks to the top of the page while the rows scroll past. */
.table-scroll.rpt-scroll {
  max-height: none;
}

.table-scroll.rpt-scroll.is-fit {
  overflow: visible;
}

.rpt-table .rpt-num,
.rpt-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Price changes (script.js: PRICE CHANGES) and the expenses filter strip (script.js: updateBorderExpenseLinks). Unique class names: plog-*, exp-filter, flow-expenses */
.plog-section {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.plog-admin {
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-neutral-soft, var(--color-surface));
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.plog-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: var(--space-2) 0;
  padding: 0;
  list-style: none;
}

.plog-item {
  display: flex;
  flex-direction: column;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow-wrap: anywhere;
}

.plog-when {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.exp-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-3) 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-info-soft);
  color: var(--color-info-text);
  font-weight: 600;
}

.exp-filter .btn,
.flow-expenses-button {
  min-height: var(--tap-target);
}

.flow-expenses:empty {
  display: none;
}

/* an element with the hidden attribute must stay hidden even where a class sets display:flex */
.crew-suggest[hidden],
.exp-filter[hidden],
.alw-top [hidden],
.plog-section[hidden] {
  display: none;
}

/* Allowance requests (script.js: ALLOWANCE REQUESTS, in the Expenses tab). Unique class names: alw-* */
.alw-section {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.alw-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-2) 0;
}

.alw-top .btn,
.alw-actions .btn {
  min-height: var(--tap-target);
}

.alw-waiting-note {
  color: var(--color-attention-text, var(--color-text-muted));
  font-weight: 600;
}

.alw-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: var(--space-3) 0;
  padding: 0;
  list-style: none;
}

.alw-item {
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.alw-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.alw-amount {
  font-size: var(--font-size-lg);
}

.alw-reason {
  margin: var(--space-2) 0 var(--space-1);
  overflow-wrap: anywhere;
}

.alw-meta,
.alw-note {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

.alw-note {
  color: var(--color-text);
}

.alw-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* Usual truck / reserve driver (script.js: updateCrewSuggestion, the driver form). Unique class names: crew-* */
.crew-check {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  min-height: var(--tap-target);
}

.crew-check input[type="checkbox"] {
  width: 1.5rem;
  height: 1.5rem;
  margin: 0;
}

.crew-check label {
  font-weight: 600;
}

.crew-check .field-hint {
  flex: 1 1 100%;
  margin: 0;
}

.crew-suggest {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-info-soft);
  color: var(--color-info-text);
  font-size: var(--font-size-sm);
}

.crew-suggest-button {
  min-height: var(--tap-target);
}

/* Settings > Exchange rates */
.rate-list {
  display: flex;
  flex-direction: column;
  margin: var(--space-3) 0 var(--space-4);
  padding: 0;
  list-style: none;
}

.rate-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.rate-name {
  display: flex;
  flex-direction: column;
  min-width: 9rem;
}

.rate-name-full {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.rate-value {
  display: flex;
  flex: 1 1 14rem;
  flex-direction: column;
}

.rate-number {
  font-weight: 700;
}

.rate-asof {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.rate-form {
  align-items: start;
}

.rate-form + .rate-form {
  margin-top: var(--space-5);
}

/* a deactivated currency reads quieter, and says so in words (the "Deactivated" badge) */
.rate-item.is-inactive .rate-name,
.rate-item.is-inactive .rate-value {
  opacity: 0.7;
}

.rate-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.rate-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.rate-actions .btn {
  min-height: var(--tap-target);
}

.rate-rename {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  align-items: end;
  gap: var(--space-2);
}

.rate-rename-label {
  flex: 1 1 100%;
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.rate-rename input {
  flex: 1 1 12rem;
  min-height: var(--tap-target);
}

.rate-rename .btn {
  min-height: var(--tap-target);
}

.rate-rename-error {
  flex: 1 1 100%;
  margin: 0;
}

.rate-both {
  color: var(--color-text);
  font-weight: 600;
}

.rate-subtitle {
  grid-column: 1 / -1;
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--font-size-base);
  font-weight: 700;
}

.rate-form .rate-subtitle {
  margin-top: 0;
}

.rate-form .form-actions button {
  min-height: var(--tap-target);
}

/* =====================================================================
   11. DASHBOARD: "LAST 30 DAYS" (script.js: DASHBOARD: LAST 30 DAYS)
   ---------------------------------------------------------------------
   Unique class names (stat-*, dash-stats*): this stylesheet is shared with the driver and client pages. Cards are neutral;
   green ("Good") and yellow ("Check") only where a threshold applies, always with words and an icon.
   ===================================================================== */
.dash-stats {
  margin: var(--space-5) 0;
}

.dash-stats-title {
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: 700;
}

.dash-stats-hint {
  margin: var(--space-1) 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.dash-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--space-4);
}

.stat-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}

.stat-label {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.stat-value {
  margin: 0;
  font-size: var(--font-size-title);
  font-weight: 700;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.stat-sub,
.stat-help,
.stat-empty {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.stat-flag {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  font-weight: 700;
}

.stat-flag .icon {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
}

.stat-tone-good {
  border-color: var(--color-success);
  background: var(--color-success-soft);
}

.stat-tone-good .stat-flag {
  color: var(--color-success-text);
}

.stat-tone-attention {
  border-color: var(--color-attention);
  background: var(--color-attention-soft);
}

.stat-tone-attention .stat-flag {
  color: var(--color-attention-text);
}

.dash-stats-panels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.stat-panel {
  min-width: 0;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}

.stat-panel-title {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-base);
  font-weight: 700;
}

.stat-list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.stat-list-item {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.stat-list-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

.stat-list-number {
  flex: none;
  font-weight: 600;
}

.stat-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}

.stat-table th,
.stat-table td {
  padding: var(--space-2) var(--space-2) var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  text-align: left;
}

.stat-table .stat-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.stat-table thead th {
  color: var(--color-text-muted);
  font-weight: 600;
}

.stat-total th,
.stat-total td {
  font-weight: 700;
}

@media (max-width: 47.99em) {
  .dash-stats-panels {
    grid-template-columns: minmax(0, 1fr);
  }
}
