/* ============================================================
   Tuesday2 — app shell chrome (on top of styles.css tokens).
   Token-only: never a raw colour literal; tint via color-mix(in oklab, ...).
   Every class here is rendered by frontend/app/shell.jsx (CONSTITUTION §4).
   ============================================================ */

.app {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 56px 1fr;
  min-height: 100vh;
  background: var(--paper);
}

/* ── TOPBAR ─────────────────────────────────────────────── */
.topbar {
  grid-column: 1 / 3;
  height: 56px;
  display: grid;
  grid-template-columns: 240px 1fr auto;
  align-items: center;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 18px;
  border-right: 1px solid var(--line);
  height: 100%;
}
.brand { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; }
.topbar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 20px;
  border-right: 1px solid var(--line);
  height: 100%;
}
.srch-icon { color: var(--muted); display: inline-flex; }
.srch-input {
  border: none; background: transparent; outline: none;
  font-family: var(--font-mono); font-size: 12px; color: var(--ink);
  flex: 1; max-width: 480px;
}
.srch-input::placeholder { color: var(--muted-2); }
.srch-kbd {
  font-size: 10px; border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 6px; color: var(--muted);
}
.topbar-right { display: flex; align-items: center; gap: 12px; padding: 0 18px; height: 100%; }

/* reporting-currency segmented switch (self-mounted by reporting-currency.js —
   engineering-owned chrome, like #tuesday-db-toggle). Token-only; ported 1:1 from
   the original Tuesday .ccy-switch/.ccy-opt (globals.css). GBP/EUR/USD re-rolls all
   displayed money (display-only; stored amounts stay base GBP). */
.ccy-switch { display: inline-flex; border: 1.5px solid var(--ink); border-radius: var(--r-pill); overflow: hidden; }
.ccy-opt { appearance: none; border: 0; background: var(--paper); color: var(--muted); font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .06em; padding: 6px 12px; cursor: pointer; }
.ccy-opt:hover { background: var(--paper-2); color: var(--ink); }
.ccy-opt.active { background: var(--ink); color: var(--paper); }
.ccy-opt + .ccy-opt { border-left: 1px solid var(--line); }

.theme-toggle, .bell {
  background: none; border: none; cursor: pointer; padding: 6px;
  display: inline-flex; align-items: center; color: var(--muted); border-radius: 6px;
  position: relative; text-decoration: none;
}
.theme-toggle:hover, .bell:hover { color: var(--ink); background: var(--paper-2); }
.bell-count {
  position: absolute; top: -2px; right: -2px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: var(--r-pill); font-size: 10px; line-height: 16px;
  text-align: center; color: var(--paper);
  background: var(--orange);
}

/* persistent LIVE/MOCK data-source pill (self-mounted by api-hooks.jsx) */
#tuesday-db-toggle { font-family: var(--font-mono); }

/* operator menu */
.op-menu-wrap { position: relative; }
.op-menu {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: none; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 4px 8px 4px 4px; color: var(--ink);
}
.op-menu:hover, .op-menu.open { border-color: var(--line-strong); }
.op-avatar, .op-pop-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: var(--paper);
  background: var(--ink);
}
.op-pop {
  position: absolute; right: 0; top: calc(100% + 8px); width: 264px; z-index: 60;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-dialog); padding: 8px; display: flex; flex-direction: column; gap: 2px;
}
.op-pop-id { display: flex; gap: 10px; align-items: center; padding: 8px; }
.op-pop-id-text { display: flex; flex-direction: column; }
.op-pop-name { font-weight: 600; font-size: 13px; }
.op-pop-email { font-size: 11px; color: var(--muted); }
.op-pop-section-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted-2); padding: 6px 8px 2px; }
.op-pop-item {
  display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: var(--r-sm);
  cursor: pointer; background: none; border: none; width: 100%; text-align: left; color: var(--ink); font-size: 13px;
}
.op-pop-item:hover { background: var(--paper-2); }
.op-pop-item-accent { color: var(--orange); }
.op-pop-item-muted { color: var(--muted); }
.op-pop-icon { display: inline-flex; color: var(--muted); }
.op-pop-text { display: flex; flex-direction: column; flex: 1; }
.op-pop-sub { font-size: 10px; color: var(--muted-2); }
.op-pop-kbd { margin-left: auto; font-size: 10px; border: 1px solid var(--line); border-radius: 4px; padding: 1px 6px; color: var(--muted); }
.op-pop-divider { height: 1px; background: var(--line); margin: 4px 0; }

/* ── SIDEBAR ────────────────────────────────────────────── */
.sidebar {
  grid-row: 2; grid-column: 1;
  border-right: 1px solid var(--line);
  background: var(--paper);
  padding: 12px 10px;
  display: flex; flex-direction: column; gap: 4px;
  position: sticky; top: 56px; height: calc(100vh - 56px); overflow-y: auto;
}
.nav-group { display: flex; flex-direction: column; gap: 2px; }
.nav-divider { height: 1px; background: var(--line); margin: 10px 4px; }
.nav-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: var(--r-sm); color: var(--muted); font-size: 13px; font-weight: 500;
  /* M31 parity: nav labels UPPERCASE like the original .rail-link
     (operator-console.css:20). Labels are static chrome props in shell.jsx
     ("Dashboard"/"Orders"/…) — never a data value, so uppercasing is safe. */
  text-transform: uppercase; letter-spacing: 0.06em;
}
.nav-item:hover { background: var(--paper-2); color: var(--ink); }
.nav-item.active { background: color-mix(in oklab, var(--orange) 12%, var(--paper)); color: var(--ink); }
.nav-item.active .nav-icon { color: var(--orange); }
.nav-icon { display: inline-flex; color: inherit; }
.nav-label { flex: 1; }
.nav-badge {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill);
  font-family: var(--font-mono); font-size: 10px; line-height: 18px; text-align: center;
  color: var(--ink); background: var(--paper-3);
}
.nav-badge.critical { color: var(--paper); background: var(--bad); }
.sidebar-foot { margin-top: auto; padding: 10px 10px 4px; font-size: 10px; color: var(--muted-2); }
.sidebar-foot .muted { color: var(--muted-2); }

/* ── main content slot ──────────────────────────────────── */
.main { grid-row: 2; grid-column: 2; padding: 24px 28px; overflow-y: auto; min-width: 0; }

/* ── ConfirmDialog (global) ─────────────────────────────── */
.scrim {
  position: fixed; inset: 0; background: color-mix(in oklab, var(--ink) 38%, transparent);
  display: grid; place-items: center; z-index: 90;
}
.dialog {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-dialog); display: flex; flex-direction: column;
}
.dialog-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px 8px; }
.dialog-title { font-family: var(--font-display); font-weight: 700; font-size: 15px; }
.dialog-sub { font-size: 11px; color: var(--muted); }
.dialog-body { padding: 8px 18px 16px; }
.dialog-foot { display: flex; align-items: center; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--line); }
.dialog-foot .grow { flex: 1; }
.btn {
  font-family: var(--font-sans); font-size: 13px; font-weight: 600; cursor: pointer;
  padding: 8px 14px; border-radius: var(--r-sm); border: 1px solid var(--line-strong);
  background: var(--ink); color: var(--paper);
  /* M31 parity: chrome buttons UPPERCASE like the original .btn
     (operator-console.css:47). .btn labels are chrome action words
     (Save/Cancel/Mark read/Add/…) — audited across *.jsx, none interpolate a
     client/company name or order ref, so uppercasing wraps only chrome. */
  text-transform: uppercase; letter-spacing: 0.06em;
}
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn.primary { background: var(--ink); color: var(--paper); }
.btn.danger { background: var(--bad); border-color: var(--bad); color: var(--paper); }
.btn.sm { padding: 5px 10px; font-size: 12px; }
.btn:focus-visible { outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px var(--orange-soft); }

/* ── ErrorBoundary verbose panel ────────────────────────── */
.eb-wrap { padding: 40px; display: grid; place-items: start center; min-height: 60vh; }
.eb-panel {
  max-width: 820px; width: 100%; background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 24px;
}
.eb-heading { font-family: var(--font-display); font-weight: 700; font-size: 18px; color: var(--bad); }
.eb-msg { margin: 10px 0; font-size: 13px; color: var(--ink); }
.eb-section-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); margin-top: 14px; }
.eb-pre {
  white-space: pre-wrap; word-break: break-word; font-size: 12px; color: var(--ink-soft);
  background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 10px; margin-top: 4px; max-height: 220px; overflow: auto;
}
.eb-context { font-size: 12px; color: var(--muted); margin-top: 4px; }
.eb-actions { display: flex; gap: 8px; margin-top: 16px; }
.eb-btn { font-family: var(--font-sans); font-size: 13px; font-weight: 600; cursor: pointer; padding: 8px 14px; border-radius: var(--r-sm); border: 1px solid var(--line); background: transparent; color: var(--ink); }
.eb-btn-primary { background: var(--ink); color: var(--paper); border-color: var(--line-strong); }

/* ── orders placeholder (M04 shell-proof; the real screen lands M06) ────── */
.screen-stub { display: flex; flex-direction: column; gap: 6px; }
.screen-stub-eyebrow { font-size: 10px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); }
.screen-stub h1 { font-family: var(--font-display); font-weight: 900; letter-spacing: -0.02em; font-size: 24px; }
.stub-list { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.stub-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--paper-2);
}
.stub-row .id { font-family: var(--font-mono); font-size: 12px; color: var(--muted); min-width: 84px; }
.stub-row .who { flex: 1; font-weight: 600; }
.stub-row .amt { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.stub-loading, .stub-error, .stub-empty { padding: 24px; color: var(--muted); }
.stub-error { color: var(--bad); }

/* ============================================================
   M06 READ-SCREEN PRESENTATION (initial canvas; the designer refines via the
   round-trip). Token-only per CONSTITUTION §5: NO raw hex here — status/stage
   colours come FROM DATA as inline style in the JSX (status.color / STAGE_COLORS),
   the one sanctioned data-driven exception. NOTE: this lives in shell.css (a
   handwritten-canvas surface, not a designer drop) — keep rules token-only.
   ============================================================ */
.scr-head { display:flex; align-items:flex-end; justify-content:space-between; gap:16px; padding:var(--s-8) 0 var(--s-7); }
.scr-title { font-family:var(--font-display); font-size:30px; margin:0; }
.scr-sub { color:var(--muted); margin-top:4px; font-size:13px; }
.scr-loading, .scr-error, .scr-empty { padding:var(--s-9); color:var(--muted); font-size:12px; }
.scr-error { color:var(--bad); }
.scr-filterbar { display:flex; align-items:center; gap:10px; padding:var(--s-4) 0 var(--s-6); flex-wrap:wrap; }
.scr-search { display:flex; align-items:center; gap:7px; background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-md); padding:6px 10px; min-width:260px; flex:0 0 300px; }
.scr-search input { border:0; background:transparent; color:var(--ink); font:inherit; outline:none; width:100%; }
.scr-search-ic { color:var(--muted); display:flex; }
.scr-select { background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-md); padding:6px 10px; color:var(--ink); font-size:12px; }
.scr-count { color:var(--muted); font-size:11px; }
.grow { flex:1; }
.scr-chips { display:flex; gap:6px; }
.scr-chip { border:1px solid var(--line); background:transparent; color:var(--muted); border-radius:var(--r-pill); padding:5px 12px; font-size:11px; cursor:pointer; }
/* M31 parity: active segment chip = SOLID DARK fill (original .ccy-opt.active /
   .set-navlink.active: background var(--ink); color var(--paper)). Inactive
   .scr-chip (line above) is unchanged. */
.scr-chip.active { border-color:var(--ink); color:var(--paper); background:var(--ink); }

/* Orders / Clients table (CSS grid; column template set per-table) */
.otbl-wrap { overflow-x:auto; border:1px solid var(--line); border-radius:var(--r-lg); }
.otbl { min-width:760px; }
.otbl-head, .otbl-row, .otbl-foot { display:grid; grid-template-columns:96px minmax(150px,1.4fr) repeat(4, minmax(96px,1fr)) 92px 100px 100px 96px; align-items:center; gap:10px; padding:9px 14px; }
.cl-tbl .otbl-head, .cl-tbl .otbl-row { grid-template-columns:minmax(160px,1.4fr) minmax(110px,1fr) minmax(120px,1.1fr) 70px 100px 100px 110px; }
.otbl-head { border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--paper); }
.oth { font-family:var(--font-mono); font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.oth.num, .otd.num { text-align:right; justify-self:end; }
.otbl-row { border-bottom:1px solid var(--line); cursor:pointer; color:inherit; }
.otbl-row:hover { background:color-mix(in oklab, var(--ink) 4%, var(--paper)); }
.otd { min-width:0; display:flex; flex-direction:column; gap:2px; font-size:12.5px; }
.otd.num { display:block; }
.otd-id { color:var(--orange); font-size:12px; }
.otd-ext { color:var(--muted-2); font-size:10px; display:flex; align-items:center; gap:5px; }
.otd-client { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* the foot row sets its OWN gridTemplateColumns inline (label 1fr + 4 money cols),
   so it is independent of the dimension count — no grid-column span arithmetic. */
.otbl-foot { border-top:1px solid var(--line-strong); background:var(--paper-2); }
.otd-totlab { color:var(--muted); font-size:11px; }
.tot { font-weight:700; }

/* Status read-pill (colour from data via inline style) */
.opill { display:inline-flex; align-items:center; gap:5px; border:1px solid var(--line); border-radius:var(--r-pill); padding:2px 9px; font-size:10.5px; white-space:nowrap; background:transparent; }
.opill-dot { width:6px; height:6px; border-radius:50%; flex:0 0 auto; }
.opill-none { color:var(--muted-2); border-color:var(--line); }

/* M28 Orders-list status badge — FILLED soft-tinted, 2-line wrap INSIDE the pill.
   Port of the original Tuesday .spill (src/app/globals.css). Dedicated to the orders
   table pill (orders.jsx EditablePill); the FILL + wrap is what keeps the pill IN its
   column so a wide label no longer spills into the next column.
   STANDING RULE: the FILLED tint (border-color + background) comes from DATA as an
   INLINE color-mix on the pill (status.color), NOT from this rule — keep tint inline.
   white-space:normal + word-break:break-word are load-bearing (they stop the overflow);
   do NOT switch this pill back to white-space:nowrap. Leave the shared `.opill`
   (order-detail/order-modal) and `.pipe-lab.spill` (dashboard pipeline) untouched. */
.opill-fill { display:inline-flex; align-items:center; gap:5px; padding:3px 8px 3px 6px; border-radius:11px; border:1.25px solid var(--line); font-family:var(--font-mono); font-size:10px; font-weight:600; letter-spacing:.01em; line-height:1.25; max-width:100%; white-space:normal; text-align:left; }
.opill-fill .lab { overflow:visible; word-break:break-word; }
.opill-fill > span:first-child, .opill-fill > svg:first-child { flex-shrink:0; align-self:center; }
.opill-fill.click { cursor:pointer; transition:transform .05s; }
.opill-fill.click:hover { filter:brightness(.97); }
.opill-fill.click:active { transform:translateY(1px); }
.opill-fill.opill-none { color:var(--muted-2); border-color:var(--line); background:var(--paper-2); }

/* Dashboard */
.kpi-grid { display:grid; grid-template-columns:repeat(4, 1fr); gap:14px; }
.kpi-card { position:relative; border:1px solid var(--line); border-radius:var(--r-lg); padding:16px; background:var(--paper-2); }
.kpi-corner { position:absolute; top:12px; right:12px; }
.kpi-lab { font-family:var(--font-mono); font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.kpi-big { font-family:var(--font-display); font-size:26px; margin-top:6px; }
.kpi-sub { font-family:var(--font-mono); font-size:10px; color:var(--muted-2); margin-top:4px; }
.kpi-good .kpi-big { color:var(--good); }
.kpi-bad .kpi-big { color:var(--bad); }
.dash-split { display:grid; grid-template-columns:1.4fr 1fr; gap:18px; margin-top:18px; align-items:start; }
@media (max-width:1100px){ .dash-split { grid-template-columns:1fr; } .kpi-grid { grid-template-columns:repeat(2,1fr); } }
.dash-prog, .brk-card, .msg-card { border:1px solid var(--line); border-radius:var(--r-lg); background:var(--paper-2); overflow:hidden; }
.brk-head, .dash-prog .brk-head { display:flex; align-items:center; justify-content:space-between; padding:13px 16px; border-bottom:1px solid var(--line); }
.brk-body { padding:16px; display:flex; flex-direction:column; gap:18px; }
.brk-dim-lab { margin-bottom:6px; }
.brk-bar { display:flex; height:9px; border-radius:var(--r-pill); overflow:hidden; background:color-mix(in oklab, var(--ink) 8%, var(--paper)); }
.brk-seg { height:100%; }
.brk-legend { display:flex; flex-wrap:wrap; gap:12px; margin-top:8px; }
.brk-leg { font-size:10.5px; color:var(--muted); display:inline-flex; align-items:center; gap:5px; }
.brk-leg b { color:var(--ink); margin-left:3px; }
.brk-dot { width:8px; height:8px; border-radius:50%; }
.dash-prog-body { display:flex; flex-direction:column; }
.pocard { display:flex; align-items:center; gap:12px; padding:12px 16px; border-bottom:1px solid var(--line); color:inherit; }
.pocard:hover { background:color-mix(in oklab, var(--ink) 4%, var(--paper)); }
.pocard-id { color:var(--orange); font-size:12px; width:80px; flex:0 0 auto; }
.pocard-client { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pocard-meta { font-size:11px; }
.dash-side { display:flex; flex-direction:column; gap:18px; position:sticky; top:0; }
.msg-list { max-height:360px; overflow:auto; }
.msg-row { display:flex; gap:10px; padding:11px 16px; border-bottom:1px solid var(--line); color:inherit; }
.msg-row:hover { background:color-mix(in oklab, var(--ink) 4%, var(--paper)); }
.msg-av { width:26px; height:26px; flex:0 0 auto; border-radius:50%; background:var(--paper-3); display:flex; align-items:center; justify-content:center; font-size:9px; }
.msg-body { min-width:0; flex:1; display:flex; flex-direction:column; gap:3px; }
.msg-h { display:flex; align-items:center; gap:7px; }
.msg-no { color:var(--orange); font-size:11px; }
.msg-meta { color:var(--muted); font-size:10.5px; }
.msg-t { font-size:12px; overflow:hidden; text-overflow:ellipsis; }

/* Order / client detail */
.od-main { max-width:1080px; }
.od-back { display:inline-flex; align-items:center; gap:5px; color:var(--muted); font-size:11px; margin-bottom:4px; }
.od-grid { display:grid; grid-template-columns:1fr 1fr; gap:16px; align-items:start; }
@media (max-width:900px){ .od-grid { grid-template-columns:1fr; } }
.od-card { border:1px solid var(--line); border-radius:var(--r-lg); background:var(--paper-2); padding:16px; }
.od-card-h { margin-bottom:12px; }
.od-fields { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.od-field-lab { font-size:10px; letter-spacing:.04em; }
.od-field-val { font-size:13px; margin-top:2px; }
.od-carrier { display:inline-flex; align-items:center; gap:6px; }
/* M29 — order-modal carrier COMBO (SC-02): a styled control that shows the carrier's
   Lucide icon + label like the read view's .od-carrier, but is EDITABLE via a
   transparent native <select> stretched over it (keeps the exact onChange ->
   set({carrierId}) write; no new menu component). The face is pointer-events:none so
   clicks fall through to the invisible select; the select carries the accessible list. */
.md-carrier-combo { position:relative; display:flex; align-items:center; gap:6px; width:100%; border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper); padding:8px 10px; min-height:36px; }
.md-carrier-combo:focus-within { border-color:var(--orange); }
.md-carrier-face { display:inline-flex; align-items:center; gap:6px; font-size:13px; color:var(--ink); pointer-events:none; }
.md-carrier-face .md-carrier-ph { color:var(--muted-2); }
.md-carrier-combo .md-carrier-chev { margin-left:auto; display:inline-flex; align-items:center; color:var(--muted-2); pointer-events:none; }
.md-carrier-combo select { position:absolute; inset:0; width:100%; height:100%; opacity:0; border:0; margin:0; padding:0; cursor:pointer; font-size:13px; }
.od-statuses { display:flex; flex-wrap:wrap; gap:14px; margin-top:14px; }
.od-status { display:flex; flex-direction:column; gap:5px; }
.od-computed { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-bottom:14px; }
.od-cell { border:1px solid var(--line); border-radius:var(--r-md); padding:12px; background:var(--paper); display:flex; flex-direction:column; gap:3px; }
.od-cell-accent { border-color:var(--orange); background:var(--orange-soft); }
.od-cell-val { font-size:20px; }
.od-cell-lab { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; }
.od-cell-note { font-size:10px; color:var(--muted-2); }
.od-cargo { font-size:12px; color:var(--muted); padding-bottom:10px; }
.od-legs { display:flex; flex-direction:column; gap:8px; }
.od-leg { display:flex; align-items:center; gap:10px; padding:8px 0; border-bottom:1px solid var(--line); font-size:12px; }
.od-leg-no { flex:0 0 auto; width:22px; height:22px; border-radius:50%; background:var(--paper-3); display:flex; align-items:center; justify-content:center; font-size:10px; }
.od-leg-desc { flex:1; min-width:0; }
.od-leg-money { color:var(--muted); font-size:11px; }
.od-leg-track { color:var(--muted-2); font-size:10px; }
.od-orderlink { color:inherit; }
.od-orderlink:hover { background:color-mix(in oklab, var(--ink) 4%, var(--paper)); }
.od-notes { margin-top:12px; font-size:12px; color:var(--muted); }
.od-msgs { display:flex; flex-direction:column; gap:10px; }
.od-msg { display:flex; gap:10px; padding:8px 0; border-bottom:1px solid var(--line); }
.od-msg.unread { background:var(--orange-soft); border-radius:var(--r-sm); padding:8px; }
/* ── M42 chat-bubble message design — PORTED VERBATIM from the ORIGINAL Tuesday
   src/app/globals.css:380-391 (.chat/.avatar/.msg/.msg.me/.bubble/.meta/.txt/
   .notify-flag). Parity-restoration under the Q01=Z / HR-20 Phase-4 override:
   the values below are the original's ACTUAL numbers, namespaced .md-* to live in
   shell.css. ADDITIVE — the .od-msg* rules ABOVE are KEPT (they style the M06
   order-detail READ view + dashboard/inbox rows); only the order-EDITOR switches
   to these .md-* bubble classes (P06). ── */
.md-chat { display:flex; flex-direction:column; gap:14px; }
.md-avatar { width:30px; height:30px; border-radius:50%; background:var(--ink); color:var(--paper); font-family:var(--font-mono); font-size:10px; font-weight:700; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.md-msg { display:flex; gap:10px; }
.md-msg.me { flex-direction:row-reverse; }
.md-msg .md-bubble { max-width:76%; background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-md); padding:9px 13px; }
.md-msg.me .md-bubble { background:color-mix(in oklab, var(--orange) 9%, var(--paper)); border-color:color-mix(in oklab, var(--orange) 28%, var(--line)); }
.md-msg .md-meta { display:flex; align-items:center; gap:8px; font-family:var(--font-mono); font-size:9px; text-transform:uppercase; letter-spacing:.08em; color:var(--muted); margin-bottom:4px; }
.md-msg .md-txt { font-size:13px; line-height:1.5; color:var(--ink); white-space:pre-wrap; word-break:break-word; }
.md-notify-inline { display:inline-flex; align-items:center; gap:4px; color:var(--orange); }
/* M42 — a bubble is a drop target for a file dragged from the Files strip. */
.md-msg .md-bubble.md-linkdrop { border-color:var(--orange); background:color-mix(in oklab, var(--orange) 12%, var(--paper)); }
/* M42 — linked-file chips rendered UNDER a bubble (reuse the existing .md-att-chip look). */
.md-linked-files { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
/* ── M43 delete-message affordance — a cross-in-circle (Lucide x-circle) button on
   each bubble. ADDITIVE + engineering-owned (Q01=Z override): reuses existing tokens,
   authors NO new visual design. `position:relative` is added here as a same-specificity
   rule that appears AFTER the M42 `.md-msg .md-bubble` rule (shell.css:383) — later
   source order wins for `position` while every M42 declaration (max-width/background/
   border/border-radius/padding) is left intact, so the bubble layout + the file-link
   chips do not shift. The button anchors to the bubble's top-right corner, sits above
   the content (small pill), and is revealed on hover or keyboard focus so it never
   clutters the resting bubble. ── */
.md-msg .md-bubble { position:relative; }
.md-msg-del { position:absolute; top:-9px; right:-9px; width:20px; height:20px; padding:0; display:inline-flex; align-items:center; justify-content:center; border-radius:50%; border:1px solid var(--line); background:var(--paper); color:var(--muted); cursor:pointer; opacity:0; transition:opacity .12s ease, color .12s ease, border-color .12s ease; }
.md-msg .md-bubble:hover .md-msg-del,
.md-msg-del:focus-visible { opacity:1; }
.md-msg-del:hover, .md-msg-del:focus-visible { color:var(--bad); border-color:color-mix(in oklab, var(--bad) 45%, var(--line)); }
/* ── M22 Notes composer ── */
.od-composer { display:flex; flex-direction:column; gap:8px; margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
.od-composer-input { width:100%; min-height:64px; resize:vertical; font:inherit; font-size:13px; color:var(--ink); background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-sm); padding:8px 10px; box-sizing:border-box; }
.od-composer-input:focus { outline:none; border-color:var(--orange); box-shadow:0 0 0 3px var(--orange-soft); }
.od-composer-row { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.od-notify-check { display:inline-flex; align-items:center; gap:6px; font-size:12px; color:var(--muted); cursor:pointer; user-select:none; }
.od-notify-check input { accent-color:var(--orange); cursor:pointer; }
.od-notify-flag { display:inline-flex; align-items:center; gap:3px; font-size:10px; color:var(--orange); margin-left:6px; }
/* ── M22 Financials quote-ref mirror ── */
.md-ref-col { display:flex; flex-direction:column; gap:6px; }
.md-ref-mirror { color:var(--muted-2); background:var(--paper-2); cursor:default; }
.md-ref-note { font-size:10px; color:var(--muted-2); }

/* Clients grid */
.cl-section { display:flex; align-items:center; gap:6px; margin:var(--s-6) 0 var(--s-5); }
.cl-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:14px; margin-bottom:var(--s-8); }
@media (max-width:1100px){ .cl-grid { grid-template-columns:repeat(2,1fr); } }
@media (max-width:700px){ .cl-grid { grid-template-columns:1fr; } }
.cl-card { border:1px solid var(--line); border-radius:var(--r-lg); background:var(--paper-2); padding:16px; color:inherit; display:flex; flex-direction:column; gap:14px; }
.cl-card:hover { border-color:color-mix(in oklab, var(--orange) 40%, var(--line)); }
.cl-card-h { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; }
.cl-name { font-size:14px; }
.cl-meta { display:flex; align-items:center; gap:6px; font-size:11px; color:var(--muted); margin-top:3px; }
.cl-stats, .cl-card .cl-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:8px; }
.cl-stat { display:flex; flex-direction:column; gap:2px; }
.cl-stat-lab { font-size:9px; }
.cl-stat-val { font-size:13px; font-weight:600; }

/* ── M39: ORIGINAL client-CARD look (restored to Tuesday parity) ──────────────────
   Ported byte-for-byte from Tuesday src/app/globals.css:249-256,417-418 (+ the .card
   base globals.css:86 folded into .client-card because Tuesday2 has no .card base).
   The card JSX uses these ORIGINAL class names (not the cl-* ones) so the shared
   .cl-stat* (client-drawer) + .scr-* (orders/inbox) classes stay byte-untouched. */
.recent-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:14px; }
@media (max-width:1000px){ .recent-grid { grid-template-columns:1fr 1fr; } }
.client-card { background:var(--paper); border:1px solid var(--line); border-radius:var(--r-lg); overflow:hidden; padding:18px; cursor:pointer; transition:background .1s, border-color .1s; }
.client-card:hover { background:var(--paper-2); }
.cc-name { font-family:var(--font-display); font-weight:900; font-size:18px; letter-spacing:-.015em; line-height:1.05; }
.cc-meta { font-family:var(--font-mono); font-size:10px; color:var(--muted); letter-spacing:.03em; margin-top:5px; }
.cc-stats { display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r-md); overflow:hidden; margin-top:4px; }
.cc-stat { background:var(--paper); padding:10px 12px; }
.cc-stat .lab { font-family:var(--font-mono); font-size:8.5px; text-transform:uppercase; letter-spacing:.1em; color:var(--muted); }
.cc-stat .val { font-family:var(--font-mono); font-weight:700; font-size:15px; margin-top:2px; font-feature-settings:"tnum"; }

/* Inbox */
.inbox-item { display:flex; gap:12px; padding:14px; border:1px solid var(--line); border-radius:var(--r-lg); background:var(--paper-2); margin-bottom:10px; }
.inbox-item.unread { border-color:color-mix(in oklab, var(--orange) 45%, var(--line)); }
.inbox-body { flex:1; min-width:0; }
.inbox-h { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.inbox-no { color:var(--orange); font-size:11px; }
.inbox-t { font-size:12.5px; margin-top:4px; color:var(--ink-soft); }
.inbox-flag { display:inline-flex; align-items:center; gap:4px; font-size:9px; letter-spacing:.08em; text-transform:uppercase; color:var(--orange); }
.inbox-acts { display:flex; align-items:center; }

/* ── M09 Order modal + Client drawer ─────────────────────────────────────── */
/* .btn.accent — the orange CTA variant Tuesday's modal Save + the VAT/Import-Tax
   "Applied" toggles use. Tuesday2's base .btn set (shell.css:158) ships ghost/
   primary/danger/sm but NOT accent, so it is defined here (orange filled). */
.btn.accent { background:var(--orange); border-color:var(--orange); color:var(--paper); }
.btn.accent:hover { background:color-mix(in oklab, var(--orange) 88%, var(--ink)); }
/* M29 — order + client DETAIL now open as the original's full-height RIGHT-EDGE
   slide-over drawer (not a centered floating dialog). Ported VERBATIM from the
   original Tuesday src/app/globals.css:184-187. align:stretch + justify:flex-end on
   the flex scrim anchors the panel to the right; the panel is height:100% with a
   left border only (it sits against the viewport right edge) and slides in from
   translateX(28px). STANDING RULE: keep .big-scrim's classname — both drawers'
   scrim-mousedown-to-close test (e.target.classList.contains('big-scrim')) depends on it. */
.big-scrim { position:fixed; inset:0; background:color-mix(in oklab, var(--ink) 30%, transparent); display:flex; align-items:stretch; justify-content:flex-end; z-index:50; animation:bigfade .14s ease; }
@keyframes bigfade { from { opacity:0; } to { opacity:1; } }
.big-dialog { width:760px; max-width:96vw; height:100%; background:var(--paper); border-left:1.5px solid var(--ink); box-shadow:0 24px 60px -20px color-mix(in oklab, var(--ink) 40%, transparent); display:flex; flex-direction:column; animation:bigslide .2s ease; }
@keyframes bigslide { from { transform:translateX(28px); opacity:.6; } to { transform:none; opacity:1; } }
.cd-dialog { width:820px; max-width:96vw; }
.md-state { padding:40px; text-align:center; color:var(--muted); }
.bd-head { display:flex; align-items:flex-start; gap:12px; padding:16px 18px; border-bottom:1px solid var(--line); }
.bd-head .grow, .md-inline .grow, .md-section .grow { flex:1; }
.dialog-eyebrow { font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; }
.page-sub { font-size:11px; color:var(--muted-2); margin-top:3px; }
.bd-title-row { display:flex; align-items:center; gap:12px; margin-top:5px; }
.dialog-title { font-size:22px; }
.icon-btn { border:1px solid var(--line); background:var(--paper); border-radius:var(--r-sm); width:32px; height:32px; display:flex; align-items:center; justify-content:center; cursor:pointer; margin-left:auto; }
.icon-btn:hover { border-color:var(--orange); }
.bd-tabs { display:flex; gap:2px; padding:0 18px; border-bottom:1px solid var(--line); flex-wrap:wrap; }
.bd-tab { border:none; background:none; padding:11px 12px; font:600 12px/1 var(--font-mono,monospace); color:var(--muted); cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; }
.bd-tab:hover { color:var(--ink); }
.bd-tab.active { color:var(--orange); border-bottom-color:var(--orange); }
/* M29 — NOTES-tab message-count badge (SC-02). Ported from the original Tuesday
   operator-console.css:24 (.ct base pill shape) + :425 (.ct.alert orange fill). Only
   the .bd-tab uses it here; kept token-only. */
.bd-tab .ct { display:inline-flex; align-items:center; font-family:var(--font-mono); font-size:10px; line-height:1; background:var(--paper-3); color:var(--muted); border-radius:999px; padding:1px 7px; }
.bd-tab .ct.alert { background:var(--orange); color:var(--paper); }
.bd-body { padding:18px; overflow:auto; flex:1; display:flex; flex-direction:column; gap:14px; }
.bd-err { padding:8px 18px; color:var(--bad); font-size:12px; background:color-mix(in oklab, var(--bad) 10%, var(--paper)); }
.bd-foot { display:flex; align-items:center; gap:10px; padding:14px 18px; border-top:1px solid var(--line); }
.md-fgrid { display:grid; grid-template-columns:repeat(2,1fr); gap:12px; }
.md-frow { display:flex; flex-direction:column; gap:5px; min-width:0; }
.md-frow.span, .md-frow[data-span], .md-divider.span { grid-column:1 / -1; }
.md-divider { height:1px; background:var(--line); margin:2px 0; }
.md-flab { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; }
.md-frow-note { font-size:11px; color:var(--muted); margin-bottom:10px; display:flex; align-items:center; }
.r-input { width:100%; border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper); color:var(--ink); padding:8px 10px; font-size:13px; }
.r-input:focus { outline:none; border-color:var(--orange); }
/* M29 (Q01 option B) — phone fields show a leading dial-code CHIP (e.g. "+44") like the
   original's phone-field, WITHOUT the out-of-scope countries picker (docs/PARITY.md defers
   the flag/+44 typeahead to a follow-up). A read-only mono chip sits left of the number
   input inside a shared bordered wrapper; the input itself stays fully editable and keeps
   its existing onChange -> seam write. If Q01 is answered "A", this chip becomes the
   interactive flag+dial trigger in the follow-up patch instead. */
.md-phone-wrap { display:flex; align-items:stretch; border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper); }
.md-phone-wrap:focus-within { border-color:var(--orange); }
.md-phone-dial { display:flex; align-items:center; gap:5px; padding:0 10px; border-right:1px solid var(--line); background:var(--paper-2); border-radius:var(--r-sm) 0 0 var(--r-sm); font-family:var(--font-mono); font-size:11px; font-weight:600; color:var(--ink); white-space:nowrap; }
.md-phone-wrap .r-input { border:0; border-radius:0 var(--r-sm) var(--r-sm) 0; }
.md-phone-wrap .r-input:focus { border-color:transparent; }
.md-textarea { min-height:80px; resize:vertical; font-family:inherit; }
.md-inline { display:flex; align-items:center; gap:8px; }
.md-inline.grow { flex:1; }
.md-pct { width:88px; text-align:right; }
.md-pct-sym, .md-pct-note { font-size:11px; color:var(--muted-2); }
.md-pct-val { font-size:12px; color:var(--ink); font-weight:600; }
.md-money { display:flex; align-items:center; gap:6px; border:1px solid var(--line); border-radius:var(--r-sm); padding:0 8px; background:var(--paper); }
.md-money-sym { color:var(--muted); font-size:12px; }
.md-money-in { flex:1; min-width:0; border:none; background:none; color:var(--ink); padding:8px 2px; font-size:13px; text-align:right; }
.md-money-in:focus { outline:none; }
.md-money-ccy { border:none; background:none; color:var(--muted); font-size:11px; cursor:pointer; }
.md-card { border:1px solid var(--line); border-radius:var(--r-md); padding:14px; background:var(--paper-2); display:flex; flex-direction:column; gap:12px; }
.md-section { display:flex; align-items:center; gap:8px; font-size:12px; }
.md-computed { margin:0; }
.md-unit { display:flex; align-items:center; gap:8px; }
.md-unit .r-input { flex:1; }
.md-unit-col { border:1px solid var(--line); border-radius:var(--r-sm); padding:10px; display:flex; flex-direction:column; gap:10px; background:var(--paper); }
.md-unit-head { display:flex; align-items:center; gap:8px; }
.md-ut { font-size:12px; color:var(--muted); }
.md-num { flex:0 0 auto; width:22px; height:22px; border-radius:50%; background:var(--paper-3); display:flex; align-items:center; justify-content:center; font-size:10px; }
/* M44 — restyle to the ORIGINAL .leg-grid (globals.css:409): a 3-col ratio for
   Description / Carrier cost / Charged-to-client, fields bottom-aligned. Ported
   VALUES (parity-restoration), not new design. A single-col variant is applied
   inline for the Tracking row (mirrors the original's second .leg-grid at
   gridTemplateColumns:"1fr"). */
.md-leg-grid { display:grid; grid-template-columns:1.6fr 1fr 1fr; gap:10px; align-items:end; }
.md-leg-grid.one { grid-template-columns:1fr; }
/* M44 — per-leg carrier row: a full-width single field above the notes (reuses the
   .md-frow field styling; no new visual design). */
.md-leg-carrier { margin-top:2px; }
/* M44 — RESTORED per-leg Leg-notes, ported from the original .full-notes /
   .full-notes textarea (globals.css:412-414) with IN-RIGA tokens. The rebuild
   dropped this though ShippingLeg.notes always existed. */
.md-full-notes { margin-top:10px; display:flex; flex-direction:column; gap:5px; }
.md-full-notes textarea { width:100%; min-height:42px; border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper); padding:8px 10px; font-size:12px; color:var(--ink); resize:vertical; }
.md-full-notes textarea:focus { outline:none; border-color:var(--orange); box-shadow:0 0 0 3px var(--orange-soft); }
.md-boxf { display:flex; flex-direction:column; gap:4px; flex:1; }
.md-boxf .r-input { text-align:right; }
.md-del { flex:0 0 auto; }
.md-totbar { display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding-top:8px; border-top:1px solid var(--line); font-size:12px; }
.md-tot-lab { color:var(--muted); }
.md-tot-val { color:var(--ink); font-weight:600; margin-right:14px; }
/* M21 attachments panel. STANDING RULE: colours/spacings here use ONLY the IN-RIGA
   :root tokens (var(--line/orange/muted/muted-2/bad/paper-2/r-sm/r-pill)); never a raw
   hex and never Tailwind — this file has no build step. */
.md-dz { display:flex; align-items:center; gap:8px; border:1px dashed var(--line); border-radius:var(--r-sm); padding:14px; color:var(--muted-2); cursor:pointer; transition:border-color .12s, background .12s, color .12s; }
.md-dz:hover { border-color:var(--orange); color:var(--orange); }
.md-dz.over { border-color:var(--orange); background:color-mix(in oklab, var(--orange) 8%, transparent); color:var(--orange); }
.md-dz.busy { cursor:progress; opacity:.85; }
.md-dz.disabled { opacity:.7; cursor:default; }
.md-dz-lab { font-size:11px; }
.md-att-count { font-size:10px; color:var(--muted); }
.md-att-strip { display:flex; flex-wrap:wrap; gap:6px; }
.md-att-chip { display:inline-flex; align-items:center; gap:4px; font-size:11px; border:1px solid var(--line); border-radius:var(--r-pill); padding:2px 4px 2px 8px; background:var(--paper-2); }
.md-att-open { display:inline-flex; align-items:center; gap:5px; border:0; background:none; color:var(--ink); font:inherit; cursor:pointer; max-width:220px; padding:0; }
.md-att-open:hover { color:var(--orange); }
.md-att-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.md-att-del { display:inline-flex; align-items:center; justify-content:center; border:0; background:none; color:var(--muted-2); cursor:pointer; padding:2px; border-radius:var(--r-pill); }
.md-att-del:hover { color:var(--bad); background:color-mix(in oklab, var(--bad) 10%, transparent); }
.md-att-notice { display:flex; align-items:center; gap:8px; font-size:11px; color:var(--bad); border:1px solid var(--bad); border-radius:var(--r-sm); padding:8px 10px; background:color-mix(in oklab, var(--bad) 8%, transparent); }
.md-att-notice-x { display:inline-flex; align-items:center; justify-content:center; border:0; background:none; color:var(--bad); cursor:pointer; padding:2px; flex:0 0 auto; }
/* M29 — client drawer 4-stat strip regains cell DIVIDERS (SC-02). Ported from the
   original Tuesday operator-console.css:253-256 .cc-stats hairline-gap technique: the
   grid container is line-coloured with a 1px gap + 1px border + overflow:hidden, and
   each cell paints its own paper background, so the 1px gaps read as hairline dividers
   between the 4 cells. Replaces the old dividerless gap:10px grid. */
.cd-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r-md); overflow:hidden; }
.cd-stats .cl-stat { background:var(--paper); padding:10px 12px; gap:2px; }
.cd-same { display:flex; align-items:center; gap:8px; font-size:12px; color:var(--muted); }
@media (max-width:640px){ .md-fgrid, .md-leg-grid, .cd-stats { grid-template-columns:1fr; } }
.inbox-readtag { display:inline-flex; align-items:center; gap:5px; font-size:10px; color:var(--muted); }
.inbox-readtag.unread { color:var(--warn); }

/* ── M18 Orders write-parity controls ────────────────────────────────────────
   STANDING RULE (grid): the orders table grid template is now set INLINE per row
   from the live dimension count (orders.jsx gridFor()), because M18 adds a Dash
   column. The .otbl-head/.otbl-row/.otbl-foot default grid above is a FALLBACK
   only — any future column add updates gridFor() in orders.jsx, NOT this CSS.
   Token-only (no raw hex); status/stage colours come FROM DATA as inline style. */

/* SortHead — the .oth column header is now a <button>; reset native chrome so it
   matches the old <span> look but shows a hover + a pointer + the active chevron. */
button.oth { border:0; background:none; padding:0; cursor:pointer; display:inline-flex; align-items:center; gap:4px; font:inherit; color:var(--muted); letter-spacing:.06em; text-transform:uppercase; font-family:var(--font-mono); font-size:10px; }
button.oth.num { justify-content:flex-end; }
button.oth:hover { color:var(--ink); }

/* status pill as a button (quick-edit trigger) — same look as the read .opill */
.opill-btn { cursor:pointer; }
.opill-btn:hover { background:color-mix(in oklab, var(--ink) 5%, var(--paper)); }
/* M29 — order-modal Overview status control: the filled .opill-fill pill is the FACE,
   an invisible native <select> is stretched over it so the pill stays clickable/editable
   with no new menu component (keeps the exact pickStatus write). */
.md-status-combo { position:relative; display:inline-flex; align-items:center; }
.md-status-combo .opill-fill { cursor:pointer; }
.md-status-sel { position:absolute; inset:0; width:100%; height:100%; opacity:0; border:0; margin:0; padding:0; cursor:pointer; }
.qedit-wrap { position:relative; display:inline-block; }

/* quick-edit popover (.qedit) */
.qedit { position:absolute; top:116%; left:0; z-index:40; min-width:186px; background:var(--paper); border:1px solid var(--line); border-radius:var(--r-md); box-shadow:var(--shadow-dialog); padding:5px; display:flex; flex-direction:column; gap:2px; }
.qedit-opt { display:flex; align-items:center; gap:8px; width:100%; text-align:left; border:0; background:none; cursor:pointer; padding:6px 8px; border-radius:var(--r-sm); color:var(--ink); font-size:12px; }
.qedit-opt:hover { background:var(--paper-2); }
.qedit-opt.sel { background:color-mix(in oklab, var(--orange) 12%, var(--paper)); }
.qedit-ic { display:inline-flex; flex:0 0 auto; }
.qedit-lab { flex:1; min-width:0; }
.stage-chip { font-size:9px; letter-spacing:.04em; text-transform:uppercase; color:var(--muted-2); border:1px solid var(--line); border-radius:var(--r-pill); padding:1px 6px; }

/* Filter button in the filterbar */
.filter-btn { display:inline-flex; align-items:center; gap:6px; border:1px solid var(--line); background:var(--paper-2); color:var(--ink); border-radius:var(--r-md); padding:6px 12px; font-size:12px; cursor:pointer; }
.filter-btn:hover { border-color:var(--line-strong); }
.filter-btn.on { border-color:var(--orange); color:var(--orange); }
.filter-cnt { min-width:16px; height:16px; padding:0 4px; border-radius:var(--r-pill); background:var(--orange); color:var(--paper); font-size:10px; line-height:16px; text-align:center; }

/* docked Filter drawer — replaces the LEFT rail for its lifetime (parity with the
   original Tuesday, globals.css:477-480,486). body.filter-docked hides the sidebar and
   reflows .main to the remaining column; the panel is FIXED to the left edge under the
   56px topbar as a 280px full-height drawer, so it docks left instead of flowing below
   the table. M38: this REPLACES the earlier below-the-table layout; it copies the
   original's docking values (parity-restoration, no new design language). */
body.filter-docked .sidebar { display:none; }
body.filter-docked .app { grid-template-columns:280px 1fr; }
body.filter-docked .main { grid-column:2; }
.fpanel.docked { position:fixed; left:0; top:56px; bottom:0; width:280px; max-width:280px; z-index:40; overflow-y:auto; border-right:1px solid var(--line); background:var(--paper); padding:14px 12px; display:flex; flex-direction:column; gap:12px; }
.fpanel-head { display:flex; align-items:center; gap:8px; }
.fpanel-title { font-size:13px; }
.fpanel-count { font-size:10px; color:var(--muted); }
.fpanel-hint { font-size:10px; color:var(--muted); }
.fpanel-cols { display:flex; flex-direction:column; gap:14px; }
.fpanel-col-h { font-size:11px; margin-bottom:6px; }
.fpanel-stage { margin-bottom:8px; }
.fpanel-stage-h { font-size:9px; letter-spacing:.06em; text-transform:uppercase; margin-bottom:4px; }
.fpanel-row { display:flex; align-items:center; gap:8px; padding:2px 0; }
.fpanel-lab { font-size:12px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tri { display:inline-flex; border:1px solid var(--line); border-radius:var(--r-sm); overflow:hidden; flex:0 0 auto; }
.tri-btn { border:0; background:var(--paper); color:var(--muted-2); width:22px; height:20px; display:inline-flex; align-items:center; justify-content:center; cursor:pointer; }
.tri-btn + .tri-btn { border-left:1px solid var(--line); }
.tri-btn.inc.on { background:color-mix(in oklab, var(--good) 18%, var(--paper)); color:var(--good); }
.tri-btn.exc.on { background:color-mix(in oklab, var(--bad) 18%, var(--paper)); color:var(--bad); }

/* Dash show-on-dashboard checkbox (per row) */
.dash-check { display:inline-flex; align-items:center; justify-content:center; cursor:pointer; }
.dash-check input { width:15px; height:15px; accent-color:var(--orange); cursor:pointer; }

/* ── M24 dashboard interactive controls ── */
.dash-tools { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:4px 0 16px; }
.dash-chips { display:flex; gap:6px; flex-wrap:wrap; }
.dash-chip { font:600 11px/1 var(--font-mono,monospace); letter-spacing:.03em; padding:6px 11px; border-radius:var(--r-pill); border:1px solid var(--line); background:transparent; color:var(--muted); cursor:pointer; }
.dash-chip:hover { border-color:var(--orange); color:var(--ink); }
/* M31 parity: active period chip = SOLID DARK fill (original .ccy-opt.active /
   .set-navlink.active: background var(--ink); color var(--paper)). Inactive
   .dash-chip (line above) is unchanged — outline only the ACTIVE one flips. */
.dash-chip.active { border-color:var(--ink); color:var(--paper); background:var(--ink); }
.dash-custom { display:flex; align-items:center; gap:8px; }
.dash-custom-sep { color:var(--muted); font-size:11px; }
.dash-date { font-size:11px; padding:5px 8px; border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper); color:var(--ink); }
.kpi-card.kpi-click { text-decoration:none; color:inherit; cursor:pointer; transition:border-color .12s ease, transform .12s ease; }
.kpi-card.kpi-click:hover { border-color:var(--orange); transform:translateY(-1px); }
.dash-hidden-note { padding:8px 16px; font-size:11px; color:var(--muted); border-bottom:1px solid var(--line); background:color-mix(in oklab, var(--orange) 6%, var(--paper)); }
/* .pocard is the original .po-card 2-column grid: LEFT head column (id+eye-off / client / profit, stacked) | RIGHT the Pipeline four-row block. Ports src/app/globals.css .po-card + .po-head. */
.pocard { display:grid; grid-template-columns:188px 1fr; align-items:center; gap:18px; padding:16px 18px; }
@media (max-width:640px){ .pocard { grid-template-columns:1fr; gap:12px; } }
.pocard-head { display:flex; flex-direction:column; gap:5px; min-width:0; }
.pocard-idrow { display:flex; align-items:center; gap:6px; }
.pocard-id { color:var(--orange); font-size:12px; text-decoration:none; }
.pocard-client { font-weight:600; font-size:13px; letter-spacing:-.005em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:inherit; text-decoration:none; }
.pocard-meta { font-size:9px; text-transform:uppercase; letter-spacing:.08em; color:var(--muted-2); }
.pocard-hide { width:22px; height:22px; margin-left:0; flex:0 0 auto; }
/* M40 completed-order state: when ALL FOUR dimension steps are complete, dashboard.jsx tags the
   card .pocard-complete and the WHOLE card washes GREEN. There is NO such state in the original
   Tuesday to copy (its finished order is a plain .po-card with four full bars), so per "do not
   invent a green" we REUSE the app's OWN completion green — the --good token — with the SAME
   color-mix recipe the original green status pill uses (operator-console.css .state-pill.tone-green:
   ~9% --good wash + ~55% --good edge). STANDING RULE: keep this keyed on var(--good) (the app's
   completion colour) — do not drift to a hardcoded/invented green. See M40 questions.toml Q01. */
.pocard-complete { background:color-mix(in oklab, var(--good) 9%, var(--paper-2)); box-shadow:inset 3px 0 0 color-mix(in oklab, var(--good) 55%, var(--line)); }
/* Pipeline stage-bars (M24; M30 = original .plg-row anatomy: label | slim bar | icon+status).
   Each row ports src/components/pipeline.tsx PipelineRow + src/app/globals.css .plg-*. */
.pipe { display:flex; flex-direction:column; gap:10px; }
.pipe-row { display:flex; align-items:center; gap:12px; }
.pipe-dim { font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); width:92px; flex:0 0 auto; }
.pipe-track { position:relative; flex:1; min-width:60px; max-width:120px; height:11px; border-radius:var(--r-pill); overflow:hidden; background:color-mix(in oklab, var(--ink) 7%, var(--paper)); border:1px solid var(--line); }
.pipe-fill { position:absolute; inset:0 auto 0 0; height:100%; border-radius:var(--r-pill) 0 0 var(--r-pill); }
.pipe-tick { position:absolute; top:0; bottom:0; width:1.5px; background:var(--paper); opacity:.7; transform:translateX(-50%); }
.pipe-cur { display:flex; align-items:center; gap:6px; width:150px; flex:0 0 auto; }
.pipe-cur .lab { font-size:10.5px; letter-spacing:.02em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* ── M19 Clients write-parity: file-blob badge + files popup ─────────────────
   Token-only (no raw hex). The blob count + popup items come from
   AttachmentApi.list (LIVE) — [] in MOCK, so the blob never renders in MOCK. */

/* the client name (card + table) lays its name text and the file-blob inline */
.cl-name { display:inline-flex; align-items:center; gap:7px; min-width:0; }
.otd-client { display:inline-flex; align-items:center; gap:7px; min-width:0; }

/* .files-blob — small paper-clip count badge next to a client name */
.files-blob { display:inline-flex; align-items:center; gap:3px; flex:0 0 auto; border:1px solid var(--line); background:var(--paper-2); color:var(--muted); border-radius:var(--r-pill); padding:1px 7px; font-family:var(--font-mono); font-size:10px; line-height:1; cursor:pointer; }
.files-blob:hover { border-color:var(--orange); color:var(--orange); }

/* .fp-* — the files popup (list + open). Mirrors the big-dialog scrim pattern but
   smaller; scrim closes on outside mousedown, Esc closes (handled in JSX). */
.fp-scrim { position:fixed; inset:0; z-index:60; background:color-mix(in oklab, var(--ink) 42%, transparent); display:flex; align-items:center; justify-content:center; padding:24px; }
.fp-card { width:min(440px, 96vw); max-height:80vh; display:flex; flex-direction:column; background:var(--paper); border:1px solid var(--line); border-radius:var(--r-lg); box-shadow:var(--shadow-dialog); overflow:hidden; }
.fp-head { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:14px 16px; border-bottom:1px solid var(--line); }
.fp-title { font-size:16px; margin-top:2px; }
.fp-body { padding:8px; overflow-y:auto; display:flex; flex-direction:column; gap:4px; }
.fp-row { display:flex; align-items:center; gap:10px; width:100%; text-align:left; border:0; background:none; cursor:pointer; padding:9px 10px; border-radius:var(--r-md); color:var(--ink); }
.fp-row:hover { background:var(--paper-2); }
.fp-row-ic { display:inline-flex; flex:0 0 auto; }
.fp-row-meta { display:flex; flex-direction:column; gap:2px; flex:1; min-width:0; }
.fp-row-name { font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fp-row-sub { font-size:10px; color:var(--muted); }
.fp-foot { padding:10px 16px; border-top:1px solid var(--line); font-size:10px; color:var(--muted); }

/* ── M27 mobile-responsive rail collapse (<=768px) ───────────────────────────
   PIXEL-PARITY (2026-07-02 audit): at desktop the shell is a 2-col grid
   (.app{grid-template-columns:240px 1fr}) with the .topbar spanning both columns
   (row 1) and the .sidebar as a sticky 240px column (row 2 / col 1). Below 768px
   that fixed 240px rail shoved .main off-screen (measured: at 390px .app resolved
   to "240px 150px", .main width=150, documentElement.scrollWidth=882 -> horizontal
   overflow). This block ports the ORIGINAL Tuesday's mobile intent
   (operator-console.css:171 @media(max-width:880px){.app{grid-template-columns:1fr}
   .rail{display:none} ...}) — single-column .app + full-width main — but, because
   Tuesday2's ONLY primary nav lives in this rail (multi-page SPA; the topbar has
   no Dashboard/Orders/Clients links), it COLLAPSES the rail into a compact
   horizontal, internally-scrolling nav STRIP instead of hiding it, so nav stays
   reachable per SC-01 (see questions.toml Q01 — non-blocking, default = this
   keep-reachable behavior). ADDITIVE + breakpoint-scoped: NOTHING here applies at
   >=769px, so the desktop layout is byte-unchanged (verified at 1280px + 1000px).
   Token-only; no raw hex; no Tailwind. */
@media (max-width: 768px) {
  /* single column; topbar (auto) then nav strip (auto) then main (1fr) */
  .app { grid-template-columns: 1fr; grid-template-rows: auto auto 1fr; }

  /* topbar: reflow to a wrapping flex bar. brand+(hidden search) on line 1,
     the action cluster (theme/bell/ccy/operator) wraps to line 2 so the many
     Tuesday2 topbar controls fit 390px without horizontal overflow. */
  .topbar { grid-column: 1; display: flex; flex-wrap: wrap; height: auto; }
  .topbar-search { display: none; }               /* search box is the droppable non-essential (matches original topbar minimalism) */
  .topbar-left { flex: 1 1 auto; border-right: 0; padding: 0 14px; height: 56px; }
  .topbar-right { flex: 1 1 100%; justify-content: flex-end; padding: 0 8px 8px; gap: 8px; height: auto; }
  .ccy-opt { padding: 6px 10px; }                 /* trim the widest control (GBP/EUR/USD) so the cluster clears 390px */

  /* rail -> compact horizontal, internally-scrolling nav strip (row 2). */
  .sidebar {
    grid-row: 2; grid-column: 1;
    position: static; height: auto;
    flex-direction: row; align-items: center; gap: 6px;
    overflow-x: auto; overflow-y: hidden;
    border-right: 0; border-bottom: 1px solid var(--line);
    padding: 8px 10px;
  }
  .sidebar .nav-group { flex-direction: row; gap: 4px; }
  .sidebar .nav-divider, .sidebar .sidebar-foot { display: none; }
  .nav-item { white-space: nowrap; }
  .nav-label { flex: 0 0 auto; }

  /* main fills the full width below the strip. */
  .main { grid-row: 3; grid-column: 1; padding: 18px 16px; }

  /* when the Orders filter drawer is docked, keep the sidebar hidden on mobile
     (its desktop docked layout already replaces the sidebar; the M18 rule
     `body.filter-docked .sidebar{display:none}` still applies — this line is a
     defensive no-op affirming the mobile strip is also hidden while docked). */
  body.filter-docked .sidebar { display: none; }
}