/* ==========================================================================
   AHP BMS/RMS — design system and app shell
   --------------------------------------------------------------------------
   One stylesheet for the whole application. The three original pages each
   carried their own copy of these tokens, which is why they had already
   started to drift apart. Everything lives here now.

   Layout contract:
     desktop  — fixed left rail, content scrolls independently
     phone    — bottom tab bar, header hides on scroll (Q39)
   ========================================================================== */

/* --------------------------------------------------------------------------
   Palette — AHP_Brand_Guidelines.docx v1.0, §4.

     AHP Orange        #FF731B   logo, headings, links, primary buttons,
                                 table header fill, totals/CTA bands
     AHP Orange Light  #FF924E   secondary accents, hover, tags
     Black             #000000   body copy, dark section backgrounds
     Charcoal          #333333   subheadings, secondary headings
     Grey              #666666   body/description text, captions
     Border Grey       #EAEAEA   borders, dividers, subtle backgrounds
     White             #FFFFFF

   The navy this replaced was never a brand colour. It came from the
   registration prototype and propagated by copy-paste through three pages.
   The client-facing quote document was already correct — quote_render.js has
   been on the brand card since it was written — so this was internal only,
   which is lucky rather than by design.

   "Keep it orange-and-black" (§2), so the rail is black with orange for the
   live item, rather than a full orange panel. Orange carries meaning here —
   it marks what is actionable — and a screen that is mostly orange has no way
   left to say "this one".
   -------------------------------------------------------------------------- */

:root {
  /* Brand */
  --brand:#FF731B;  --brand-lift:#FF924E;  --brand-deep:#E05F0F;
  --rail-bg:#0D0D0D;  --rail-bg-2:#1A1A1A;

  /* Kept as aliases so nothing that still says "navy" breaks mid-refactor. */
  --navy:var(--brand);  --navy-lift:var(--brand-lift);  --navy-deep:#000;

  /* Ink and surfaces */
  --ink:#000;  --muted:#666666;  --faint:#8C8C8C;
  --bg:#F7F7F8;  --surface:#fff;  --surface-2:#F4F4F5;
  --line:#EAEAEA;  --line-soft:#F1F1F1;

  /* State.
     Deliberately not orange. Orange is the brand and marks what you can act
     on; if a warning were also orange, neither would mean anything. The amber
     below is dark enough to read as caution next to #FF731B. */
  --ok:#12703C;    --ok-bg:#E7F3EC;
  --warn:#8A5A00;  --warn-bg:#FFF3E0;
  --bad:#C0261B;   --bad-bg:#FBEAE9;
  --info:#333333;  --info-bg:#F4F4F5;

  /* Geometry */
  --rail:232px;  --rail-collapsed:60px;  --header-h:56px;
  --r:10px;  --r-sm:7px;

  --shadow:0 1px 2px rgba(0,0,0,.05), 0 1px 3px rgba(0,0,0,.08);
  --shadow-pop:0 8px 28px rgba(0,0,0,.18);

  /* §5. Both are resolved locally — Montserrat is on your machines via the
     document templates, Aptos ships with Office. Neither is fetched: the
     system must not depend on a third party, and it has to look the same
     with the network unplugged. */
  --font-head:Montserrat,"Segoe UI",system-ui,-apple-system,Arial,sans-serif;
  --font-body:Aptos,"Aptos Display",system-ui,-apple-system,"Segoe UI",Arial,sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root.auto-theme {
    --ink:#F2F2F2;  --muted:#A8A8A8;  --faint:#7A7A7A;
    --bg:#0D0D0D;  --surface:#1A1A1A;  --surface-2:#222222;
    --line:#2E2E2E;  --line-soft:#242424;
    --ok-bg:#102A1B;  --warn-bg:#2B2110;  --bad-bg:#2E1614;  --info-bg:#222222;
    --shadow:0 1px 2px rgba(0,0,0,.4);
  }
}

* { box-sizing:border-box; -webkit-tap-highlight-color:transparent; }

html, body { height:100%; }

body {
  margin:0;
  font:15px/1.5 var(--font-body);
  background:var(--bg); color:var(--ink);
  overscroll-behavior-y:none;
}

/* --------------------------------------------------------------- typography */

h1,h2,h3,h4 { margin:0; font-family:var(--font-head); font-weight:700; line-height:1.25; }
h1,h2 { letter-spacing:-.01em; }
h3 { color:var(--ink); }
h1 { font-size:20px; }
h2 { font-size:17px; }
h3 { font-size:15px; }
h4 { font-size:12px; text-transform:uppercase; letter-spacing:.09em; color:var(--muted); }
p  { margin:0 0 10px; }
a  { color:var(--navy); }

.num  { font-variant-numeric:tabular-nums; }
.dim  { color:var(--muted); }
.faint{ color:var(--faint); }
.tiny { font-size:12px; }
.strong { font-weight:650; }
.nowrap { white-space:nowrap; }

/* ------------------------------------------------------------------ controls */

input, select, textarea, button {
  font:inherit; padding:10px 12px; border-radius:var(--r-sm);
  border:1px solid var(--line); background:var(--surface); color:var(--ink);
  width:100%;
}
/* 16px on touch stops iOS zooming the page when a field takes focus */
@media (pointer:coarse) { input, select, textarea { font-size:16px; } }

textarea { resize:vertical; }
/* Placeholders had no rule, so they took the browser default — which differs
   between Safari, Chrome and Firefox, and is the wrong weight against this
   palette. One colour, everywhere. */
::placeholder { color: var(--muted); opacity: 1; }

input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, [tabindex]:focus-visible {
  outline:2px solid var(--brand); outline-offset:1px;
}

button {
  background:var(--navy); color:#fff; border:0; font-weight:600;
  cursor:pointer; min-height:42px; width:auto; padding:10px 16px;
}
button:hover:not(:disabled) { background:var(--navy-lift); }
button:disabled { opacity:.45; cursor:default; }
button.ghost  { background:var(--surface); color:var(--navy); border:1px solid var(--navy); }
button.quiet  { background:var(--surface-2); color:var(--ink); border:1px solid var(--line); }
button.danger { background:var(--surface); color:var(--bad); border:1px solid var(--bad); }
button.link   { background:none; border:0; color:var(--navy); padding:0; min-height:0;
                text-decoration:underline; font-weight:500; }
button.small  { min-height:0; padding:6px 10px; font-size:13px; }
button.icon   { min-height:0; padding:6px 8px; background:none; color:var(--muted); }
button.icon:hover { background:var(--surface-2); color:var(--ink); }

label { display:block; font-family:var(--font-head); font-size:10.5px; color:var(--muted);
        margin:10px 0 4px; font-weight:700; text-transform:uppercase; letter-spacing:.09em; }

.field-note { font-size:12px; color:var(--muted); margin-top:4px; }

/* -------------------------------------------------------------------- layout */

.row  { display:flex; gap:10px; flex-wrap:wrap; }
.row > * { flex:1; min-width:150px; }
.row.tight { gap:6px; }
.row.middle { align-items:center; }
.row.nowrap { flex-wrap:nowrap; }
.spacer { flex:1; min-width:0; }
.hide { display:none !important; }

.card {
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r); padding:16px; margin-bottom:14px; box-shadow:var(--shadow);
}
.card.flush { padding:0; overflow:hidden; }
.card-head {
  display:flex; align-items:center; gap:10px;
  padding:12px 16px; border-bottom:1px solid var(--line-soft);
}
.card-head h2, .card-head h3 { flex:1; min-width:0; }

/* ------------------------------------------------------------------- the app */

#app { display:flex; min-height:100dvh; }

/* --- left rail --- */

#rail {
  width:var(--rail); flex:0 0 var(--rail);
  background:var(--rail-bg); color:#fff;
  display:flex; flex-direction:column;
  position:sticky; top:0; height:100dvh;
  padding-top:env(safe-area-inset-top);
  transition:width .14s ease, flex-basis .14s ease;
}
#rail.collapsed { width:var(--rail-collapsed); flex-basis:var(--rail-collapsed); }
#rail.collapsed .rail-label, #rail.collapsed .rail-section,
#rail.collapsed #recents, #rail.collapsed .who-name { display:none; }
#rail.collapsed .rail-item { justify-content:center; padding-left:0; padding-right:0; }

.rail-brand {
  display:flex; align-items:center; gap:10px;
  padding:14px 16px; font-weight:700; letter-spacing:.04em; font-size:15px;
}
.rail-brand img { height:22px; width:auto; }
.rail-brand { font-family:var(--font-head); }
.rail-brand .mark {
  width:28px; height:28px; border-radius:6px; background:var(--brand); color:#fff;
  display:grid; place-items:center; font-size:11px; font-weight:800; flex:0 0 auto;
  letter-spacing:.02em;
}

#railNav { flex:1; overflow-y:auto; padding:4px 8px 12px; }

.rail-item {
  display:flex; align-items:center; gap:11px;
  padding:9px 10px; margin:1px 0; border-radius:var(--r-sm);
  color:#dde4f0; text-decoration:none; cursor:pointer;
  font-size:14px; font-weight:500; border:0; background:none; width:100%;
  text-align:left; min-height:0;
}
.rail-item:hover { background:rgba(255,255,255,.08); color:#fff; }
.rail-item.on { background:var(--brand); color:#fff; font-weight:650; }
.rail-item .ico { width:18px; flex:0 0 18px; text-align:center; opacity:.9; }

/* A sub-item of an open section. Indented and quieter, so the eye reads the
   section headings first and the children as belonging to one of them. */
.rail-child { padding-left:26px; font-size:13px; opacity:.82; }
.rail-child .ico { opacity:.5; }
#rail.collapsed .rail-child { display:none; }
.rail-item.on .ico { opacity:1; }
.rail-label { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rail-item .pip {
  font-size:11px; font-weight:700; padding:1px 6px; border-radius:9px;
  background:rgba(255,255,255,.2);
}
.rail-item.on .pip { background:rgba(0,0,0,.28); color:#fff; }
.rail-item .pip.warn { background:var(--warn); color:#fff; }

.rail-section {
  font-size:10px; text-transform:uppercase; letter-spacing:.09em;
  color:rgba(255,255,255,.42); padding:14px 12px 5px; font-weight:700;
}

#recents .rail-item { font-size:13px; padding:6px 10px; color:#B8B8B8; }

.rail-foot { border-top:1px solid rgba(255,255,255,.12); padding:8px; }
.who { display:flex; align-items:center; gap:10px; padding:6px 8px; cursor:pointer;
       border-radius:var(--r-sm); color:#dde4f0; }
.who:hover { background:rgba(255,255,255,.08); }
.who .av { width:28px; height:28px; border-radius:50%; background:var(--brand);
           display:grid; place-items:center; font-size:12px; font-weight:700;
           flex:0 0 auto; color:#fff; }
.who-name { flex:1; min-width:0; font-size:13px; overflow:hidden;
            text-overflow:ellipsis; white-space:nowrap; }
.who-name small { display:block; color:rgba(255,255,255,.55); font-size:11px; }

/* --- main column --- */

#main { flex:1; min-width:0; display:flex; flex-direction:column; }

#topbar {
  height:var(--header-h); flex:0 0 auto;
  background:var(--surface); border-bottom:1px solid var(--line);
  display:flex; align-items:center; gap:10px; padding:0 14px;
  position:sticky; top:0; z-index:30;
  padding-top:env(safe-area-inset-top);
}
#searchWrap { flex:1; max-width:620px; position:relative; }

/* The bell (Q15). The badge sits on the button rather than beside it so the
   header does not reflow every time the count changes. */
#btnBell { position:relative; font-size:16px; }
#btnBell .pip {
  position:absolute; top:0; right:0;
  min-width:16px; height:16px; padding:0 4px;
  border-radius:8px; font-size:10px; line-height:16px; font-weight:600;
  text-align:center; color:#fff; background:var(--warn);
  box-shadow:0 0 0 2px var(--surface);
}
#btnBell .pip.bad { background:var(--bad); }
#btnBell .pip.hide { display:none; }

/* Text colours. These were being used by class name — `.tiny.bad`,
   `.tiny.warn` — in three screens before they existed anywhere, so they
   rendered as ordinary grey text and the warning did not warn. */
.bad  { color:var(--bad); }
.warn { color:var(--warn); }
.ok   { color:var(--ok); }
a.warn:hover, a.bad:hover { text-decoration:underline; }

/* A card that is itself the warning, rather than containing one. */
.card.warn {
  border-color:var(--warn);
  background:var(--warn-bg);
}
.card.warn h2 { color:var(--warn); }

button.icon.small { padding:2px 6px; font-size:12px; }
#search {
  width:100%; padding:8px 12px 8px 34px; border-radius:20px;
  background:var(--surface-2); border:1px solid transparent;
}
#search:focus { background:var(--surface); border-color:var(--line); }
#searchWrap .mag { position:absolute; left:12px; top:50%; transform:translateY(-50%);
                   color:var(--muted); pointer-events:none; font-size:14px; }
#searchWrap .kbd { position:absolute; right:10px; top:50%; transform:translateY(-50%);
                   color:var(--faint); font-size:11px; pointer-events:none; }
#search:focus + .mag + .kbd { display:none; }

#results {
  position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:60;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow-pop); max-height:min(70vh,520px); overflow-y:auto; padding:4px;
}
#results .grp { font-size:10px; text-transform:uppercase; letter-spacing:.08em;
                color:var(--muted); padding:8px 10px 4px; font-weight:700; }
#results .hit { display:flex; gap:10px; align-items:center; padding:8px 10px;
                border-radius:var(--r-sm); cursor:pointer; }
#results .hit:hover, #results .hit.cursor { background:var(--surface-2); }
#results .hit .t { flex:1; min-width:0; }
#results .hit .t small { display:block; color:var(--muted); font-size:12px; }
#results .empty { padding:16px; color:var(--muted); text-align:center; font-size:14px; }

#screen { flex:1; min-width:0; padding:18px; max-width:1240px; width:100%; }
#screen.wide { max-width:none; }

/* --- offline / status strip --- */

#netbar {
  display:none; align-items:center; gap:8px;
  background:var(--warn-bg); color:var(--warn);
  border-bottom:1px solid #f0dfb8; padding:6px 14px; font-size:13px; font-weight:600;
  position:sticky; top:var(--header-h); z-index:29;
}
body.offline #netbar { display:flex; }

.asof { font-size:11px; color:var(--warn); font-weight:600; white-space:nowrap; }
body:not(.offline) .asof { display:none; }

/* --- phone --- */

#tabbar { display:none; }

@media (max-width:860px) {
  #rail { display:none; }
  #app { flex-direction:column; }
  #screen { padding:14px 12px calc(74px + env(safe-area-inset-bottom)); }

  #topbar { transition:transform .18s ease; }
  body.scrolled-down #topbar { transform:translateY(-100%); }

  #tabbar {
    display:flex; position:fixed; bottom:0; left:0; right:0; z-index:40;
    background:var(--surface); border-top:1px solid var(--line);
    padding-bottom:env(safe-area-inset-bottom);
  }
  #tabbar a {
    flex:1; display:flex; flex-direction:column; align-items:center; gap:2px;
    padding:8px 2px 7px; text-decoration:none; color:var(--muted);
    font-size:10.5px; font-weight:600; position:relative;
  }
  #tabbar a.on { color:var(--brand); }
  #tabbar a .ico { font-size:19px; line-height:1; }
  #tabbar a .pip {
    position:absolute; top:4px; right:calc(50% - 18px);
    background:var(--bad); color:#fff; font-size:9px; font-weight:700;
    min-width:15px; height:15px; border-radius:8px; display:grid; place-items:center;
    padding:0 3px;
  }
}

/* Reorder arrows. Arrows rather than drag: they work on a phone, in a van,
   with gloves, and a mis-drop on a 60-line list costs more than a slower move. */
button.mv { width:24px; min-height:22px; padding:0; font-size:10px; line-height:1;
            background:var(--surface-2); color:var(--ink); border:1px solid var(--line);
            border-radius:5px; margin-right:2px; }
button.mv:hover:not(:disabled) { background:var(--brand); color:#fff; border-color:var(--brand); }
button.mv:disabled { opacity:.25; cursor:default; }
td.mv { white-space:nowrap; padding-right:0; }

/* -------------------------------------------------------------- status chips */

.chip {
  display:inline-flex; align-items:center; gap:5px;
  font-size:11px; font-weight:700; padding:3px 8px; border-radius:11px;
  text-transform:uppercase; letter-spacing:.04em; white-space:nowrap;
  background:var(--surface-2); color:var(--muted);
}
.chip.ok   { background:var(--ok-bg);   color:var(--ok); }
.chip.warn { background:var(--warn-bg); color:var(--warn); }
.chip.bad  { background:var(--bad-bg);  color:var(--bad); }
.chip.info { background:var(--info-bg); color:var(--info); }
.chip.plain{ background:none; padding:0; }

.dot { width:7px; height:7px; border-radius:50%; background:currentColor; flex:0 0 auto; }

/* status colours, one place */
.st-enquiry   { background:var(--surface-2); color:var(--muted); }
.st-quoted    { background:var(--info-bg);  color:var(--info); }
.st-confirmed { background:var(--ok-bg);    color:var(--ok); }
.st-inprep,
.st-onsite    { background:var(--warn-bg);  color:var(--warn); }
.st-returned  { background:var(--info-bg);  color:var(--info); }
.st-invoiced,
.st-paid      { background:var(--ok-bg);    color:var(--ok); }
.st-lost,
.st-cancelled { background:var(--bad-bg);   color:var(--bad); }

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

table { width:100%; border-collapse:collapse; font-size:14px; }
th { text-align:left; font-family:var(--font-head); font-size:10.5px; text-transform:uppercase;
     color:var(--muted); border-bottom:2px solid var(--line); padding:8px 10px;
     letter-spacing:.09em; font-weight:700; white-space:nowrap; }
td { padding:9px 10px; border-bottom:1px solid var(--line-soft); vertical-align:middle; }
td.num, th.num { text-align:right; font-variant-numeric:tabular-nums; }
tbody tr.click { cursor:pointer; }
tbody tr.click:hover { background:var(--surface-2); }
tr.section td { background:var(--surface-2); font-weight:700; font-size:11.5px;
                text-transform:uppercase; letter-spacing:.05em; }
table.flush th:first-child, table.flush td:first-child { padding-left:16px; }
table.flush th:last-child,  table.flush td:last-child  { padding-right:16px; }

/* ------------------------------------------------------------- empty / error */

.empty-state { text-align:center; padding:44px 20px; color:var(--muted); }
.empty-state .big { font-size:34px; margin-bottom:10px; opacity:.5; }
.empty-state h3 { color:var(--ink); margin-bottom:6px; }
.empty-state p { max-width:420px; margin:0 auto 14px; }

/* An honest gap. Used wherever a screen is real but the data behind it isn't
   built yet — deliberately visible rather than a blank panel that looks broken. */
.gap-note {
  background:var(--info-bg); border:1px dashed #9db4dd; border-radius:var(--r);
  padding:14px 16px; color:var(--navy); font-size:13.5px;
}
.gap-note b { display:block; margin-bottom:3px; }

/* ------------------------------------------------------------------- toasts */

#toasts { position:fixed; bottom:18px; left:50%; transform:translateX(-50%);
          z-index:200; display:flex; flex-direction:column; gap:8px; align-items:center;
          pointer-events:none; }
@media (max-width:860px) { #toasts { bottom:calc(78px + env(safe-area-inset-bottom)); } }
.toast {
  background:var(--navy-deep); color:#fff; padding:11px 16px; border-radius:var(--r);
  box-shadow:var(--shadow-pop); font-size:14px; display:flex; align-items:center; gap:12px;
  pointer-events:auto; max-width:min(92vw,520px); animation:rise .16s ease;
}
.toast.bad { background:var(--bad); }
.toast.ok  { background:var(--ok); }
.toast button { background:rgba(255,255,255,.2); color:#fff; padding:4px 10px;
                min-height:0; font-size:13px; }
@keyframes rise { from { opacity:0; transform:translateY(8px); } }

/* ------------------------------------------------------------------- dialogs */

.scrim { position:fixed; inset:0; background:rgba(16,24,40,.44); z-index:100;
         display:grid; place-items:center; padding:16px; }
.sheet {
  background:var(--surface); border-radius:var(--r); box-shadow:var(--shadow-pop);
  width:min(560px,100%); max-height:88vh; overflow-y:auto; padding:20px;
}
.sheet.wide { width:min(880px,100%); }
.sheet h2 { margin-bottom:4px; }
.sheet .actions { display:flex; gap:10px; justify-content:flex-end; margin-top:18px; }
@media (max-width:860px) {
  .scrim { align-items:flex-end; padding:0; }
  .sheet { width:100%; max-height:92vh; border-radius:var(--r) var(--r) 0 0; }
}

/* ------------------------------------------------------------------- loading */

.skeleton { background:linear-gradient(90deg,var(--surface-2) 25%,var(--line-soft) 37%,var(--surface-2) 63%);
            background-size:400% 100%; animation:sk 1.1s ease infinite;
            border-radius:5px; height:13px; }
@keyframes sk { from { background-position:100% 50%; } to { background-position:0 50%; } }

.spin { display:inline-block; width:14px; height:14px; border:2px solid var(--line);
        border-top-color:var(--navy); border-radius:50%; animation:spin .6s linear infinite; }
@keyframes spin { to { transform:rotate(360deg); } }

@media (prefers-reduced-motion:reduce) {
  *, *::before, *::after { animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* ------------------------------------------------------------------ printing */

@media print {
  #rail, #topbar, #tabbar, #netbar, #toasts { display:none !important; }
  #screen { padding:0; max-width:none; }
  .card { box-shadow:none; border-color:#ccc; break-inside:avoid; }
}

/* Q11 — the global create button. Brand orange because it is the one action
   in the rail that makes something rather than going somewhere. */
.rail-new {
  width: 100%; text-align: left; background: none; border: 0;
  font: inherit; cursor: pointer; color: var(--brand);
  margin-bottom: 6px;
}
.rail-new .ico { color: var(--brand); font-weight: 700; }
.rail-new:hover { background: rgba(255,115,27,.10); }

/* The rate card reads as a table of figures, not a grid of buttons. The number
   is the content; the button is only how you change it, so it stays invisible
   until you go near it. */
.rate-cell {
  background: none; border: 0; font: inherit; color: var(--ink);
  padding: 4px 6px; border-radius: 4px; cursor: pointer;
  font-variant-numeric: tabular-nums;   /* columns of money should line up */
}
.rate-cell:hover  { background: rgba(255,115,27,.12); color: var(--brand); }
.rate-cell:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.rate-cell.unset  { color: var(--faint); }
.rate-cell.unset:hover { color: var(--brand); }

th.right, td.right { text-align: right; }

/* Inline rate editing: the input occupies the same box as the figure it
   replaces, so the column does not jump when you click into it. */
.rate-input {
  width: 96px; height: 28px; padding: 2px 6px; text-align: right;
  font: inherit; font-variant-numeric: tabular-nums;
}


/* Waiting-to-send count, in the rail under the destinations. */
.rail-queue { padding: 0 10px; }
.rail-queue .pip {
  display: inline-block; min-width: 20px; padding: 2px 7px; border-radius: 999px;
  background: var(--brand); color: #fff; font-size: 12px; text-align: center;
}

/* Buttons that sit next to each other need room between them.
   Two orange buttons touching read as one wide button, and on a phone the tap
   targets genuinely overlap — a 44px target with no gap is a 44px target you
   hit the edge of. 10px is the smallest gap that still separates them at a
   glance.

   Done with `gap` on the container rather than margins on the button, so a
   button never carries spacing it does not need when it is alone. */
/* .tabs and .btn-row had NO base rule — no display, no layout, nothing.
   `gap` on a container that is not flex or grid does nothing at all, so the
   line below was decorative, and the `margin-left: 0` further down then
   removed the button+button fallback that WAS working.

   Two rules, each correct on its own reading, cancelling each other out. The
   tabs on Finance, Purchasing, Reports, Admin, Compliance and the job screen
   have run together since the day they were written. */
.tabs, .btn-row {
  display: flex; flex-wrap: wrap; align-items: center;
  margin-bottom: 14px;
}
/* A tab row sits under a heading and above content; it needs air on both
   sides, not just between its buttons. */
.tabs { margin-top: 2px; }

.row, .actions, .card-head, .tabs, .btn-row { gap: 10px; }
.row > * + *, .actions > * + * { margin-left: 0; }

/* Tabs size to their label. Without this they inherit `.row > *`-style
   stretching in some containers and a five-tab row becomes five equal slabs
   with the text lost in the middle of each. */
.tabs > button { flex: 0 0 auto; min-width: 0; }

/* Anywhere buttons are siblings outside a flex row, fall back to a margin. */
button + button, button + .btn, .btn + button { margin-left: 10px; }
.row button + button, .actions button + button,
.card-head button + button, .tabs button + button { margin-left: 0; }

/* Two primaries side by side is usually a design mistake, but where it
   happens the gap has to be bigger — they compete for the same glance. */
.actions .primary + .primary, .row .primary + .primary { margin-left: 4px; }

/* ------------------------------------------------------------ the calendar */
/* Seven columns, and bars that span them. A job running Tuesday to Friday is
   one bar, not four copies — which is the only reason to have a calendar
   rather than a list. */
.cal-head { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-dow {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); padding: 4px 6px;
}
.cal-week { position: relative; margin-bottom: 4px; }
.cal-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-day {
  min-height: 84px; background: var(--surface-2); border-radius: 6px;
  padding: 4px 6px;
}
.cal-day.other { opacity: .45; }
.cal-day.today { outline: 2px solid var(--brand); outline-offset: -2px; }
.cal-date { font-size: 12px; color: var(--muted); }

/* Bars float over the day cells, below the date numbers. */
.cal-lanes {
  position: absolute; inset: 22px 0 4px 0;
  display: flex; flex-direction: column; gap: 3px; pointer-events: none;
}
.cal-lane { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-bar {
  pointer-events: auto;
  border: 0; border-radius: 5px; cursor: pointer;
  font: 500 12px/1.3 inherit; text-align: left;
  padding: 3px 7px; min-height: 22px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--brand); color: #fff;
}
.cal-bar:hover { background: var(--brand-hover); }
.cal-bar.st-quoted   { background: #666; }
.cal-bar.st-enquiry  { background: #888; }
.cal-bar.st-lost,
.cal-bar.st-cancelled { background: #B0B0B0; }
