/**
 * RBP Group — mono theme.
 * Loaded AFTER app.css (AdminKit) to override the look for auth/onboarding.
 * Monochrome surfaces + a single blue accent for primary actions.
 */
:root {
  --rbpg-bg: #f4f4f5;
  --rbpg-surface: #ffffff;
  --rbpg-border: #e4e4e7;
  --rbpg-border-strong: #d4d4d8;
  --rbpg-text: #18181b;
  --rbpg-muted: #71717a;
  --rbpg-grey: #f4f4f5;
  --rbpg-grey-hover: #e4e4e7;
  --rbpg-primary: #2563eb;
  --rbpg-primary-hover: #1d4ed8;

  /* ── Status tones ──────────────────────────────────────────────────────────
   * One ramp per meaning, for every blip on every page. There were four
   * near-duplicate palettes before this — three greens, three reds, and a
   * "mono-pastel" set whose amber (#85693a) was olive and failed AA at 4.49:1 —
   * so the same estimate could read a different colour in the cockpit, the list
   * and the builder. Verify any change with
   * `node scripts/dev/check-tone-contrast.mjs`.
   *
   * Three steps, because a blip has three jobs and one colour cannot do all of
   * them on a mono canvas:
   *
   *   tint  the field. Held at the same luminance across all five tones (spread
   *         0.057), so no pill shouts louder than another for want of meaning.
   *   ink   the text. Dark enough to clear 4.5:1 on its own tint — these are
   *         11-12px caps, which WCAG counts as normal text, not large.
   *   dot   the signal. Full chroma, and the reason the ink is allowed to be
   *         dark: dark amber IS brown, physically, so hue has to live somewhere
   *         that does not have to be read. The dot is that place.
   *
   * `lit` is the same tone for dark chrome, where a pale tint washes out against
   * near-black. It matches the -300 inks the cockpit header already uses for save
   * state, so the header keeps one language.
   */
  --tone-info-tint: #eff6ff;
  --tone-info-ink: #1d4ed8;
  --tone-info-dot: #2563eb;
  --tone-info-lit: #93c5fd;

  --tone-ok-tint: #f0fdf4;
  --tone-ok-ink: #15803d;
  --tone-ok-dot: #16a34a;
  --tone-ok-lit: #86efac;

  --tone-warn-tint: #fffbeb;
  --tone-warn-ink: #b45309;
  --tone-warn-dot: #f59e0b;
  --tone-warn-lit: #fcd34d;

  --tone-bad-tint: #fef2f2;
  --tone-bad-ink: #b91c1c;
  --tone-bad-dot: #ef4444;
  --tone-bad-lit: #fca5a5;

  --tone-neutral-tint: #f4f4f5;
  --tone-neutral-ink: #52525b;
  --tone-neutral-dot: #a1a1aa;
  --tone-neutral-lit: #d4d4d8;

  /* Bars and meters. Every bar draws from these, so a healthy bar is one green app-wide. Muted
     against the zinc greys: a bar fills a wide strip, and full-chroma colour at that size
     outshouts the text beside it. Progress with no judgement in it is graphite. */
  --meter-track: #e4e4e7;
  --meter-fill: #3f3f46;
  --meter-ok: #5f9373;
  --meter-warn: #d39b3a;
  --meter-bad: #c4554d;
  --meter-none: #a1a1aa;
  --rbpg-radius: 12px;
  /* Controls (buttons, inputs, selects) are squarer than cards: one radius, set here. */
  --rbpg-radius-ctl: 8px;
  --rbpg-radius-ctl-sm: 6px;
  --rbpg-radius-lg: 16px;
  --rbpg-appbar-h: 64px;
  --rbpg-footer-h: 76px;
  --rbpg-max: 1080px;

  /* Card type scale. Inside a card, size says what a thing is, and weight says how much
     it matters. A number is bold; a word in a number's place (Learning, Pending) is not.
     A zero, or "no data", drops to the muted ink at normal weight. */
  --type-display: 1.35rem;   /* the card's one headline number */
  --type-figure: 1.1rem;     /* every other number: split cells, pile counts */
  --type-row: 0.82rem;       /* a named row or line: a health part, a lever, a name */
  --type-body: 0.82rem;      /* sentences inside a card */
  --type-label: 0.76rem;     /* the label over a number */
  --type-meta: 0.72rem;      /* the muted line under a number, a measure, a footnote */
  --type-eyebrow: 0.68rem;   /* uppercase group heads and role labels */
  --weight-number: 700;
  --weight-strong: 600;
}

/* Reserve the scrollbar gutter so opening a modal (which hides overflow) never
   changes layout width — no sideways shift of content, fixed footer or dialogs. */
html { scrollbar-gutter: stable; }

body {
  background: var(--rbpg-bg);
  color: var(--rbpg-text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* ---- Typography ------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 { color: var(--rbpg-text); font-weight: 700; }
.text-muted { color: var(--rbpg-muted) !important; }
a { color: var(--rbpg-primary); }

/* ---- Buttons: mono by default, blue for primary ---------------------- */
.btn {
  border-radius: var(--rbpg-radius-ctl);
  font-weight: 600;
  padding: 0.7rem 1.4rem;
  font-size: 1rem;
  line-height: 1.2;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.btn-lg { padding: 0.85rem 1.6rem; font-size: 1.05rem; }
/* Bootstrap's `-sm` sizes are declared before this stylesheet loads, so the base
   rule above was silently winning and `.btn-sm` rendered at full size on every
   page in the app. Restated here, after the base, so asking for a small control
   gets one — which is what a dozen call sites already thought they were doing. */
.btn-sm { padding: 0.42rem 0.85rem; font-size: 0.875rem; border-radius: var(--rbpg-radius-ctl-sm); }

/* Primary = the one attention-grabbing action */
.btn-primary,
.btn-success {
  background: var(--rbpg-primary);
  border: 1px solid var(--rbpg-primary);
  color: #fff;
}
.btn-primary:hover, .btn-primary:focus,
.btn-success:hover, .btn-success:focus {
  background: var(--rbpg-primary-hover);
  border-color: var(--rbpg-primary-hover);
  color: #fff;
  box-shadow: none;
}

/* Default / secondary = light grey fill, no border, bold black text */
.btn-secondary,
.btn-light,
.btn-default {
  background: var(--rbpg-grey);
  border: 1px solid transparent;
  color: var(--rbpg-text);
  font-weight: 700;
}
.btn-secondary:hover, .btn-light:hover, .btn-default:hover {
  background: var(--rbpg-grey-hover);
  color: var(--rbpg-text);
}

/* Outline = white fill, soft grey border, softens on hover (no hard border) */
.btn-outline-secondary,
.btn-outline-primary {
  background: var(--rbpg-surface);
  border: 1px solid var(--rbpg-border-strong);
  color: var(--rbpg-text);
  font-weight: 600;
}
.btn-outline-secondary:hover, .btn-outline-secondary:focus,
.btn-outline-primary:hover, .btn-outline-primary:focus {
  background: var(--rbpg-grey);
  border-color: var(--rbpg-grey);
  color: var(--rbpg-text);
  box-shadow: none;
}

.btn:focus, .btn:focus-visible { box-shadow: 0 0 0 0.2rem rgba(37, 99, 235, 0.15); }
.btn:disabled { opacity: 0.55; }

/* ---- Inputs: bigger, rounder ---------------------------------------- */
.form-control,
.form-select {
  border-radius: var(--rbpg-radius-ctl);
  border: 1px solid var(--rbpg-border-strong);
  padding: 0.7rem 0.9rem;
}
/* Reserve room on the right for the dropdown chevron so it never overlaps the
   text (esp. on width:auto selects like the per-page picker). */
.form-select {
  padding-right: 2.25rem;
  background-position: right 0.75rem center;
  font-size: 1rem;
  color: var(--rbpg-text);
  background-color: var(--rbpg-surface);
}
.form-control-lg, .form-select-lg { padding: 0.85rem 1rem; font-size: 1.05rem; }
/* Same story as `.btn-sm` above. */
.form-control-sm, .form-select-sm { padding: 0.42rem 0.7rem; font-size: 0.875rem; border-radius: var(--rbpg-radius-ctl-sm); }
.form-select-sm { padding-right: 2rem; background-position: right 0.55rem center; }
.form-control:focus,
.form-select:focus {
  border-color: var(--rbpg-primary);
  box-shadow: 0 0 0 0.2rem rgba(37, 99, 235, 0.12);
}
.form-control::placeholder { color: #a1a1aa; }
.form-label { font-weight: 600; color: var(--rbpg-text); margin-bottom: 0.35rem; }
.input-group > .form-control { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.input-group > .btn { border-top-left-radius: 0; border-bottom-left-radius: 0; }

.form-check-input:checked { background-color: var(--rbpg-primary); border-color: var(--rbpg-primary); }
.form-check-input:focus { box-shadow: 0 0 0 0.2rem rgba(37, 99, 235, 0.15); }

/* ---- Cards ----------------------------------------------------------- */
.card {
  background: var(--rbpg-surface);
  border: 1px solid var(--rbpg-border);
  border-radius: var(--rbpg-radius-lg);
  box-shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
}

/* ---- Alerts (muted, mono) -------------------------------------------
   Bootstrap's alert component is not in the CSS these pages load: `app.css`
   carries no `.alert` rules and `alerts_bs5.css` is linked by nothing. For as
   long as this file set only a border, every `alert-danger` on the app — 70-odd
   of them, including the one the onboarding wizard reports a failed Finish in —
   drew as a white box with a grey hairline, no padding and black text. So the
   padding and the tones are here, not inherited.

   The tones are the five in `:root`, the same ones the status pills use, so an
   alert and a blip do not say the same thing in two different reds. */
.alert {
  padding: .7rem .85rem;
  margin-bottom: 1rem;
  border-radius: var(--rbpg-radius);
  border: 1px solid var(--rbpg-border);
  background: var(--rbpg-surface);
  color: var(--rbpg-text);
  font-size: .8rem;
  line-height: 1.55;
}
.alert > :last-child { margin-bottom: 0; }
/* The tone carries the meaning; a link inside must not add a second colour. */
.alert a { color: inherit; text-decoration: underline; }
.alert-heading { font-size: .82rem; font-weight: 700; color: inherit; margin: 0 0 .15rem; }

.alert-danger { background: var(--tone-bad-tint); border-color: var(--tone-bad-lit); color: var(--tone-bad-ink); }
.alert-warning { background: var(--tone-warn-tint); border-color: var(--tone-warn-lit); color: var(--tone-warn-ink); }
.alert-success { background: var(--tone-ok-tint); border-color: var(--tone-ok-lit); color: var(--tone-ok-ink); }
.alert-primary { background: var(--tone-info-tint); border-color: var(--tone-info-lit); color: var(--tone-info-ink); }
/* Left as the grey it has always been. `alert-info` is the app's "for your
   information" box and reads as chrome, not as a state worth a colour. */
.alert-info { background: #f4f4f5; color: var(--rbpg-text); }
.alert-secondary, .alert-light, .alert-dark {
  background: var(--tone-neutral-tint); border-color: var(--tone-neutral-lit); color: var(--tone-neutral-ink);
}

/* ---- Badges --------------------------------------------------------- */
.badge.bg-primary-subtle { background: #eff3fe !important; color: var(--rbpg-primary) !important; font-weight: 600; }

/* =====================================================================
   Fixed app shell (header + footer) used by onboarding
   ===================================================================== */
.rbpg-appbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--rbpg-appbar-h);
  background: var(--rbpg-surface);
  border-bottom: 1px solid var(--rbpg-border);
  display: flex;
  align-items: center;
  padding: 0 1.25rem;
  z-index: 1030;
}
.rbpg-appbar .rbpg-exit {
  background: transparent;
  border: 1px solid var(--rbpg-border-strong);
  color: var(--rbpg-text);
  font-weight: 600;
  padding: 0.45rem 1.05rem;
  border-radius: var(--rbpg-radius);
}
.rbpg-appbar .rbpg-exit:hover { background: var(--rbpg-grey); }
.login-brand { margin-bottom: 0.35rem; }
.login-mark {
  display: block;
  margin: 0 auto;
  max-height: 32px;
  max-width: 220px;
  width: auto;
  height: auto;
  object-fit: contain;
}
/* The platform logo in the fixed app bar. 28px against a 64px bar leaves the
   mark room to breathe; the logo is a wide lockup, so height is what is pinned
   and the width follows. */
.rbpg-brand-mark { display: block; height: 28px; width: auto; }
.rbpg-brand {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-weight: 800;
  letter-spacing: 0.06em;
  font-size: 0.95rem;
  color: var(--rbpg-text);
  text-transform: uppercase;
  white-space: nowrap;
}

.rbpg-footer {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  min-height: var(--rbpg-footer-h);
  background: var(--rbpg-surface);
  border-top: 1px solid var(--rbpg-border);
  display: flex;
  align-items: center;
  padding: 0.9rem 1.25rem;
  z-index: 1030;
}
.rbpg-footer-inner {
  width: 100%;
  max-width: var(--rbpg-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.rbpg-shell {
  min-height: 100vh;
  padding-top: var(--rbpg-appbar-h);
  padding-bottom: calc(var(--rbpg-footer-h) + 1.5rem);
}
.rbpg-body {
  max-width: var(--rbpg-max);
  margin: 0 auto;
  padding: 2.25rem 1.25rem 1rem;
}

@media (max-width: 575.98px) {
  .rbpg-brand { font-size: 0.78rem; }
  .rbpg-body { padding-top: 1.25rem; }
}

/* =====================================================================
   Supplier app shell (sidebar + topbar + content) — monochrome
   Used by supplier.html and the supplier-* pages via supplier-shell.js
   ===================================================================== */
:root { --rbpg-sidebar-w: 248px; }

.app { min-height: 100vh; }

.app-sidebar {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--rbpg-sidebar-w);
  background: var(--rbpg-surface);
  border-right: 1px solid var(--rbpg-border);
  display: flex;
  flex-direction: column;
  z-index: 1040;
}
.app-sidebar .app-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1.25rem 1.4rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.9rem;
  color: var(--rbpg-text);
  text-decoration: none;
  border-bottom: 1px solid var(--rbpg-border);
}
.app-brand .app-brand-mark {
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--rbpg-text); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.85rem; font-weight: 800; letter-spacing: 0;
}
/* White, because a Brand logo is somebody else's artwork and almost all of it is
   dark ink drawn for white paper. The band used to be near-black — right for the
   one white REPIID mark it was built for, wrong for every Brand since.
   Height matches the main-content header (--rbpg-appbar-h) so the divider lines align */
.app-sidebar .app-brand {
  height: var(--rbpg-appbar-h);
  padding: 0 1rem;
  justify-content: center;
  background: #fff;
  border-bottom: 1px solid var(--rbpg-border);
  box-sizing: border-box;
}
/* Scaled by whichever dimension runs out first, so a tall square mark and a wide
   wordmark both land inside the band without being stretched or cropped. */
.app-brand .app-brand-logo {
  display: none; height: auto; width: auto;
  max-height: 60px; max-width: 100%;
  object-fit: contain; flex: 0 1 auto; min-width: 0;
}
.app-brand .app-brand-logo.is-loaded { display: block; }
/* The platform wordmark is a wide mark in a 64px band. Vendor logos keep the
   60px cap above; this one stays short so the bar still has space around it. */
.app-brand .app-brand-logo--platform { max-height: 24px; }
/* Shared logo/name chrome: the name is also the stable fallback while an image
   loads or fails, and neither can widen the fixed sidebar. */
.app-sidebar .app-brand--text,
.app-sidebar .app-brand--chrome { color: var(--rbpg-text); overflow: hidden; }
.app-brand-name {
  min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* A logo that has loaded already says the name — printing it again beside the
   artwork is the same word twice. The span stays in the markup because it is
   what shows when the image is missing, slow or broken. */
.app-brand .app-brand-logo.is-loaded + .app-brand-name { display: none; }
.app-nav { padding: 0.9rem 0.75rem; overflow-y: auto; flex: 1; }
.app-nav .nav-label {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--rbpg-muted); font-weight: 700; padding: 0.4rem 0.75rem 0.5rem;
}
/* A group with no heading, which in the admin tree is Settings sitting on its own
   at the bottom. A rule over it would read as a divider between two halves of a
   list; the gap says "and separately, this" without claiming there is a category. */
.app-nav .nav-gap { height: 1.1rem; }
.app-nav a {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.7rem 0.8rem; margin-bottom: 0.15rem;
  border-radius: 10px;
  color: var(--rbpg-text); text-decoration: none;
  font-weight: 600; font-size: 0.95rem;
}
.app-nav a svg, .app-nav a i { width: 18px; height: 18px; color: var(--rbpg-muted); }
.app-nav a:hover { background: var(--rbpg-grey); }
.app-nav a.active { background: var(--rbpg-text); color: #fff; }
.app-nav a.active svg, .app-nav a.active i { color: #fff; }
.app-nav .nav-badge {
  margin-left: auto;
  min-width: 20px; height: 18px; padding: 0 6px;
  border-radius: 999px;
  background: #dc2626; color: #fff;
  font-size: 0.7rem; font-weight: 800; line-height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
}
.app-nav a.active .nav-badge { background: #fff; color: var(--rbpg-text); }

/* ---- Message center -------------------------------------------------- */
/* Folder rail reuses .rail-* (My repairs). Icons need sizing here. */
.rail-stage svg, .rail-stage i { width: 16px; height: 16px; color: var(--rbpg-muted); flex: 0 0 auto; }
.rail-stage.active svg, .rail-stage.active i { color: #fff; }

.msg-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }

/* Conversation list — Gmail single-row density: avatar · name · subject+snippet
   (one truncated line) · date right. Bold only on unread name+subject; no tint. */
.msg-list { display: flex; flex-direction: column; }
.msg-conv {
  display: flex; gap: 0.85rem; align-items: center; width: 100%; text-align: left; cursor: pointer;
  border: 0; background: none; border-bottom: 1px solid var(--rbpg-border);
  padding: 0.55rem 1.25rem;
}
.msg-conv:hover { background: #fafafa; }
.msg-conv:last-child { border-bottom: 0; }
.msg-avatar {
  width: 32px; height: 32px; border-radius: 50%; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  background: #f1f1f4; color: #52525b;
}
.msg-avatar svg { width: 16px; height: 16px; }
/* Channel tint — calm pastel, carries the transport signal (no separate blip). */
.msg-avatar--email { background: #eef2ff; color: #4f46e5; }
.msg-avatar--sms { background: #ecfdf5; color: #059669; }
.msg-avatar--note { background: #fffbeb; color: #d97706; }
.msg-avatar.sk { background: #ececec; }
/* Name shrinks to its content (no reserved dead space after short names). */
.msg-conv-who {
  flex: 0 1 auto; min-width: 0; max-width: 32%;
  color: var(--rbpg-text); font-weight: 500; font-size: 0.88rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Subject + snippet share one truncating line (subject first, snippet greys out). */
.msg-conv-main { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.msg-conv-subject { color: var(--rbpg-text); font-size: 0.87rem; font-weight: 400; }
.msg-conv-preview { color: var(--rbpg-muted); font-size: 0.87rem; }
.msg-conv-preview::before { content: " — "; }
.msg-conv-meta { flex: 0 0 auto; padding-left: 0.5rem; display: flex; align-items: center; gap: 0.5rem; }
.msg-conv-time { flex: 0 0 auto; color: var(--rbpg-muted); font-size: 0.75rem; white-space: nowrap; }
.msg-chip { flex: 0 0 auto; font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; padding: 0.05rem 0.36rem; border-radius: 4px; }
.msg-chip--overdue { color: #b91c1c; background: #fef2f2; border: 1px solid #fecaca; }
.msg-chip--ai { color: #fff; background: #0d0d0d; border: 1px solid #0d0d0d; }

/* Row 3-dot actions — subtle, appears on row hover/focus (Gmail-style). */
.msg-conv-menu { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: 0; border-radius: 6px; background: transparent; color: var(--rbpg-muted); cursor: pointer; opacity: 0.5; transition: opacity 0.12s, background 0.12s; }
.msg-conv:hover .msg-conv-menu, .msg-conv:focus-within .msg-conv-menu { opacity: 1; }
.msg-conv-menu:hover { background: #ececef; color: var(--rbpg-text); }
.msg-conv-menu:focus-visible { opacity: 1; outline: 2px solid var(--rbpg-text); outline-offset: 1px; }

/* Row action dropdown (appended to body, fixed-positioned). */
.msg-menu { z-index: 1200; min-width: 200px; background: #fff; border: 1px solid var(--rbpg-border); border-radius: 10px; box-shadow: 0 16px 40px rgba(0,0,0,0.16); padding: 0.3rem; }
.msg-menu-item { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 7px; padding: 0.5rem 0.6rem; font-size: 0.86rem; color: var(--rbpg-text); cursor: pointer; }
.msg-menu-item:hover, .msg-menu-item:focus-visible { background: #f4f4f5; outline: none; }

/* Route supplier picker (modal). */
.msg-picker-back { position: fixed; inset: 0; z-index: 1300; background: rgba(17,17,17,0.28); display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.msg-picker { width: 100%; max-width: 460px; background: #fff; border-radius: 14px; box-shadow: 0 24px 60px rgba(0,0,0,0.3); overflow: hidden; display: flex; flex-direction: column; }
.msg-picker-title { padding: 0.7rem 1rem 0; font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rbpg-muted); }
.msg-picker-input { border: 0; border-bottom: 1px solid var(--rbpg-border); padding: 0.8rem 1rem; font-size: 0.95rem; outline: none; }
.msg-picker-list { max-height: 320px; overflow-y: auto; padding: 0.4rem; }
.msg-picker-item { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 8px; padding: 0.6rem 0.7rem; font-size: 0.9rem; cursor: pointer; }
.msg-picker-item:hover, .msg-picker-item:focus-visible { background: var(--rbpg-text); color: #fff; outline: none; }
.msg-picker-empty { color: var(--rbpg-muted); font-size: 0.88rem; padding: 1rem; text-align: center; }
.msg-pill {
  flex: 0 0 auto; min-width: 1.2rem; text-align: center;
  background: var(--rbpg-text); color: #fff; font-size: 0.7rem; font-weight: 700;
  padding: 0.03rem 0.38rem; border-radius: 999px;
}
.msg-conv.unread .msg-conv-who { font-weight: 700; }
.msg-conv.unread .msg-conv-subject { font-weight: 700; color: var(--rbpg-text); }
.msg-conv.unread .msg-conv-preview { color: var(--rbpg-text); }

/* Mentions folder (MENTION-6): the conversation row with a person's face, the
   case number as a chip, and a red unread dot in place of the count pill. */
.msg-avatar--face { overflow: hidden; border: 1px solid var(--rbpg-border); background: var(--rbpg-grey); color: var(--rbpg-text); font-size: 0.8rem; font-weight: 700; }
.msg-avatar--face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.msg-conv-ref { display: inline-block; margin-left: 0.4rem; padding: 0 0.35rem; border-radius: 5px; background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); color: var(--rbpg-muted); font-size: 0.72rem; font-weight: 500; font-variant-numeric: tabular-nums; vertical-align: 1px; }
.msg-conv--mention .msg-conv-preview b { font-weight: 600; }
.msg-conv--mention .msg-conv-who { flex: 0 0 9.5rem; max-width: 9.5rem; }
.msg-head .btn { white-space: nowrap; }
.msg-head p { font-size: 0.8rem; margin-top: 2px; }
.msg-mention-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: transparent; }
.msg-conv.unread .msg-mention-dot { background: var(--tone-bad-dot); }
.msg-chip--team { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--rbpg-muted); background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); text-transform: none; letter-spacing: 0; font-weight: 600; font-size: 0.68rem; }
.msg-more { display: block; width: 100%; padding: 0.7rem 1.25rem; border: 0; background: none; color: var(--rbpg-text); font-size: 0.84rem; font-weight: 600; cursor: pointer; }
.msg-more:hover { background: #fafafa; }
.msg-more:disabled { opacity: .6; cursor: default; }
.msg-empty { padding: 3.5rem 1.25rem; text-align: center; color: var(--rbpg-muted); }
.msg-conv--skel { pointer-events: none; }
.msg-conv--skel .sk-line { height: 11px; border-radius: 6px; background: #ececec; }
.msg-conv--skel .msg-conv-who { width: 130px; }

.app-main {
  margin-left: var(--rbpg-sidebar-w);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.app-topbar {
  height: var(--rbpg-appbar-h);
  background: var(--rbpg-surface);
  border-bottom: 1px solid var(--rbpg-border);
  display: flex; align-items: center;
  padding: 0 1.75rem; gap: 1rem;
  position: sticky; top: 0; z-index: 1030;
}
.app-topbar .topbar-title { font-size: 1.15rem; font-weight: 700; margin: 0; }
.app-topbar .topbar-right { margin-left: auto; display: flex; align-items: center; gap: 0.6rem; }
/* The menu list lives in this same wrapper. A ul's margin (and the line box
   under an inline button) makes the wrapper taller than the circle, and the
   bar then centers that taller box. The wrapper is the circle; the menu is
   taken out of the flow. */
.app-topbar .topbar-right > .dropdown {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; min-width: 0; min-height: 0;
  flex: 0 0 32px; overflow: visible;
}
.app-topbar .topbar-right > .dropdown > .dropdown-menu {
  position: absolute; top: calc(100% + 8px); right: 0; left: auto;
  margin: 0;
}
.app-hamburger { display: none; background: none; border: 0; padding: 0.4rem; }

/* NAV-6 — the account button is the avatar alone. The warn ring means one thing:
   a REPIID agent inside a vendor's dashboard. */
.app-account {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; min-width: 0; min-height: 0;
  padding: 0; margin: 0; border: 0; border-radius: 50%;
  background: transparent; cursor: pointer; flex: 0 0 auto; line-height: 0;
  transition: box-shadow .12s ease;
}
.app-account::after { display: none; }
.app-account:hover, .app-account:focus-visible, .app-account[aria-expanded="true"] {
  outline: 0; box-shadow: 0 0 0 3px var(--rbpg-grey-hover);
}
.app-account--viewing { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--tone-warn-dot); }
.app-account--viewing:hover, .app-account--viewing:focus-visible, .app-account--viewing[aria-expanded="true"] {
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--tone-warn-dot), 0 0 0 7px var(--rbpg-grey-hover);
}
.app-account-avatar {
  width: 32px; height: 32px; border-radius: 50%; overflow: hidden; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
}
.app-account > .app-account-avatar { position: absolute; inset: 0; }
.app-account-avatar[hidden] { display: none; }
.app-account-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.app-account-avatar--init {
  font-size: 0.75rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1;
  color: #fff; background: hsl(var(--h, 210), 42%, 46%);
}
.app-account-avatar--lg { width: 40px; height: 40px; }
.app-account-avatar--lg.app-account-avatar--init { font-size: 0.9rem; }

/* NAV-5 — the account menu. Scoped, so no other dropdown changes. */
.app-account-menu {
  min-width: 240px; max-width: 300px; padding: 6px;
  line-height: 1.45; font-size: 0.875rem;
  border: 1px solid var(--rbpg-border); border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .08);
}
.app-account-id {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 10px 10px; min-width: 0;
}
.app-account-id-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.app-account-sep { border-top: 1px dotted #d4d4d8; margin: 0 10px 6px; }
.app-account-id-name,
.app-account-id-meta { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-account-id-name { font-size: 0.875rem; font-weight: 600; color: var(--rbpg-text); }
.app-account-id-meta { font-size: 0.78rem; font-weight: 400; color: var(--rbpg-muted); }
.app-account-id-viewing { color: var(--tone-warn-ink); font-weight: 500; }
.app-account-menu .dropdown-item {
  display: block; width: auto; line-height: 1.4; text-decoration: none;
  font-size: 0.85rem; font-weight: 500; color: var(--rbpg-text);
  padding: 7px 10px; border-radius: 8px; white-space: nowrap;
}
.app-account-menu .dropdown-item:hover,
.app-account-menu .dropdown-item:focus,
.app-account-menu .dropdown-item:active { background: var(--rbpg-grey); color: var(--rbpg-text); }

/* NAV-7 — "Add your photo": the approval pill's component, in the no-state tone,
   because nobody is waiting on it. A phone's bar has no room for it, so there
   the menu's Profile link carries the same dot instead. */
.app-photo-nudge { text-decoration: none; cursor: pointer; white-space: nowrap; }
.app-photo-nudge:hover,
.app-photo-nudge:focus-visible { background: var(--rbpg-grey-hover); color: var(--tone-neutral-ink); text-decoration: none; }
.app-profile--nophoto::after {
  content: ''; display: none; width: 7px; height: 7px; margin-left: 0.45rem;
  border-radius: 50%; background: var(--tone-neutral-dot); vertical-align: middle;
}
@media (max-width: 575.98px) {
  .app-photo-nudge { display: none; }
  .app-profile--nophoto::after { display: inline-block; }
}

.app-content { padding: 1.9rem 1.75rem 3rem; max-width: 1280px; width: 100%; }
.page-head { margin-bottom: 1.5rem; }
.page-head h1 { font-size: 1.5rem; margin: 0 0 0.25rem; }
.page-head p { color: var(--rbpg-muted); margin: 0; }

/* Cards get more breathing room in the app */
.app-content .card { margin-bottom: 1.5rem; }
.app-content .card-header {
  background: transparent; border-bottom: 1px solid var(--rbpg-border);
  padding: 1.15rem 1.4rem;
}
.app-content .card-header .card-title { font-size: 1.02rem; font-weight: 700; }
.app-content .card-body { padding: 1.4rem; }

/* Stat cards */
.stat-card .stat-label { color: var(--rbpg-muted); font-weight: 600; font-size: 0.85rem; margin-bottom: 0.35rem; }
.stat-card .stat-value { font-size: 2rem; font-weight: 800; line-height: 1; }
.stat-card .stat-sub { color: var(--rbpg-muted); font-size: 0.8rem; margin-top: 0.4rem; }
/* A word where the number goes ("Learning", "Pending") reads as a figure, not a headline. */
.app-content .stat-card .stat-value.stat-value--word { font-size: var(--type-figure); font-weight: var(--weight-strong); letter-spacing: 0; line-height: 1.2; }
/* The card type scale as classes, for markup a page script writes. */
.rbpg-t-row { font-size: var(--type-row); font-weight: var(--weight-strong); line-height: 1.35; color: var(--rbpg-text); }
.rbpg-t-body { font-size: var(--type-body); line-height: 1.45; }
.rbpg-t-label { font-size: var(--type-label); font-weight: var(--weight-strong); color: var(--rbpg-muted); }
.rbpg-t-meta { font-size: var(--type-meta); line-height: 1.35; color: var(--rbpg-muted); }
a.dash-stat-link {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
}
a.dash-stat-link:hover { border-color: var(--rbpg-border-strong); color: inherit; }
.stat-card .stat-value .rbpg-rating {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
}

/* ---- The top row (HEALTH-9) -------------------------------------------
   One bar for every card that has a target. Colour means the same on each, whatever
   the direction of the number: ok on track, warn watch it, bad act now, none no data
   yet. The colours are the shared `--meter-*` set. */
.stat-card--meter .card-body { padding-bottom: 2.1rem; }
.stat-meter {
  position: absolute; left: 1.4rem; right: 1.4rem; bottom: 0.95rem;
  height: 5px; border-radius: 999px; overflow: hidden; pointer-events: none;
  background: var(--meter-track);
}
.stat-meter > span {
  display: block; height: 100%; width: 0; border-radius: inherit;
  background: var(--meter-none); transition: width 0.3s ease;
}
.stat-meter--ok > span   { background: var(--meter-ok); }
.stat-meter--warn > span { background: var(--meter-warn); }
.stat-meter--bad > span  { background: var(--meter-bad); }
.stat-meter--none > span { width: 100% !important; opacity: 0.35; }
.stat-meter[hidden] { display: none; }
/* A part scoring nothing still shows its colour, so an empty bar never reads as broken. */
.stat-meter--bad > span { min-width: 3%; }
/* The same bar in the flow of a card body (health parts, estimates, the goal), not pinned to the foot. */
.stat-meter.stat-meter--inline { position: relative; left: auto; right: auto; bottom: auto; display: block; margin-top: 0.4rem; }

/* HEALTH-10: a card's verdict lives top right of its label row, never inline with the number. */
.stat-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.35rem; min-height: 1.35rem; }
.stat-card .stat-head .stat-label { margin-bottom: 0; }
.stat-card .stat-value .stat-of { font-size: var(--type-figure); font-weight: var(--weight-strong); color: var(--rbpg-muted); }
/* A pill on a card is a tag beside the number, not a second headline: the compact size. */
.stat-card .pill { font-size: 0.62rem; padding: 0.14rem 0.45rem; gap: 0.3rem; letter-spacing: 0.04em; }
.stat-card .pill::before { width: 5px; height: 5px; }

/* What an action is worth (+25), or what not doing it costs (New work paused). A number, not a status: no dot, no caps. */
.rbpg-gain {
  display: inline-flex; align-items: center; flex: none; white-space: nowrap;
  padding: 0.14rem 0.55rem; border-radius: 999px;
  font-size: var(--type-meta); font-weight: var(--weight-number); font-variant-numeric: tabular-nums;
  background: var(--tone-ok-tint); color: var(--tone-ok-ink);
}
.rbpg-gain--bad { background: var(--tone-bad-tint); color: var(--tone-bad-ink); }

/* Do these next: one row per action, worth on the right, how and a link under it. */
.rbpg-next { list-style: none; margin: 0; padding: 0; }
.rbpg-next > li { padding: 0.65rem 0; border-top: 1px solid var(--rbpg-border); }
.rbpg-next > li:first-child { border-top: 0; padding-top: 0.25rem; }
.rbpg-next > li:last-child { padding-bottom: 0; }
.rbpg-next__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.rbpg-next a { color: var(--rbpg-text); font-weight: var(--weight-strong); text-decoration: none; white-space: nowrap; }
.rbpg-next a:hover { text-decoration: underline; }

/* Two states a top card can be in besides showing its number. `.stat-note` is the
   one short line over a failed card; it is hidden otherwise. */
.stat-card .stat-note { display: none; }
.stat-card--loading .card-body,
.stat-card--failed .card-body { position: relative; }
.stat-card--failed .stat-note {
  display: flex; align-items: center; position: absolute; left: 1.4rem; right: 1.4rem;
  top: 3rem; bottom: 1rem; font-size: 0.85rem; font-weight: 600; line-height: 1.3;
  color: var(--rbpg-text);
}
.stat-card .stat-retry { text-decoration: underline; cursor: pointer; font-weight: 700; }

/* Loading: a shimmer where the value and the line under it go, never a "—". The
   card-sized version of `.skeleton-row`; the content stays so the card keeps its height. */
.stat-card--loading .stat-value,
.stat-card--loading .stat-sub { position: relative; color: transparent; }
.stat-card--loading .stat-value > *,
.stat-card--loading .stat-sub > * { visibility: hidden; }
.stat-card--loading .stat-value::after,
.stat-card--loading .stat-sub::after {
  content: ''; position: absolute; left: 0; top: 0; width: 55%; height: 1.5rem; border-radius: 5px;
  background: linear-gradient(90deg, #f0f0f0 25%, #e4e4e7 50%, #f0f0f0 75%);
  background-size: 200% 100%; animation: rbpg-shimmer 1.4s infinite;
}
.stat-card--loading .stat-sub { min-height: 1rem; }
.stat-card--loading .stat-sub::after { width: 85%; height: 0.9rem; }
.stat-card--loading .stat-meter { visibility: hidden; }

/* Failed: no stale figure, just the way to ask again. */
.stat-card--failed .stat-value,
.stat-card--failed .stat-sub,
.stat-card--failed .stat-meter { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .stat-card--loading .stat-value::after,
  .stat-card--loading .stat-sub::after { animation: none; }
  .stat-meter > span { transition: none; }
}

/* Equal-height cards on the same row (no need for per-card h-100) */
.app-content .row > [class*="col"] { display: flex; flex-direction: column; }
.app-content .row > [class*="col"] > .card { flex: 1 1 auto; }

/* Toolbar row above tables/lists */
.rbpg-toolbar { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.rbpg-toolbar .spacer { margin-left: auto; }

/* ---- Padded, readable tables ---------------------------------------- */
.table.rbpg-table { margin: 0; }
.table.rbpg-table thead th {
  background: var(--rbpg-grey);
  color: var(--rbpg-muted);
  font-weight: 700; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em;
  border-bottom: 1px solid var(--rbpg-border);
  padding: 0.85rem 1.1rem; white-space: nowrap;
}
.table.rbpg-table tbody td {
  padding: 0.95rem 1.1rem;
  border-bottom: 1px solid var(--rbpg-border);
  vertical-align: middle; font-size: 0.92rem;
}
.table.rbpg-table tbody tr:last-child td { border-bottom: 0; }
.table.rbpg-table tbody tr:hover td { background: #fafafa; }

/* Fixed table layout so column widths stay locked when sorting re-renders rows
   (content no longer dictates width → no horizontal shift). Every column gets an
   explicit width except the Item column, which flexes to fill the remainder. */
.table.rbpg-table--fixed { table-layout: fixed; width: 100%; min-width: 54rem; }
.table.rbpg-table--fixed td, .table.rbpg-table--fixed th { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.table.rbpg-table--fixed td.rbpg-thumb-cell { overflow: visible; }
/* Status and priority are chips. Ellipsis after a pill reads as a broken label. */
.table.rbpg-table--fixed th.ws-col-status,
.table.rbpg-table--fixed td.ws-col-status,
.table.rbpg-table--fixed th.ws-col-priority,
.table.rbpg-table--fixed td.ws-col-priority {
  overflow: visible;
  text-overflow: clip;
}

/* Thumbnail cell: tight vertical padding so the image fills the row height
   (roughly the normal text-cell height) — a bigger avatar without taller rows.
   Specificity must beat `.table.rbpg-table tbody td`, hence the doubled classes. */
.table.rbpg-table td.rbpg-thumb-cell { padding-top: 0.4rem; padding-bottom: 0.4rem; padding-left: 2rem; padding-right: 1rem; width: 6rem; }
.rbpg-table .rbpg-thumb { width: 48px; height: 48px; object-fit: cover; display: block; border-radius: 8px; border: 1px solid var(--rbpg-border); background: var(--rbpg-grey); }

/* VIEW-3 — one case row. Every column is a fixed rem except Case, which
   absorbs leftover width. The Case td must stay `table-cell` (flex lives
   on an inner wrap) or the title shrinks to its text and Leads leaves a hole. */
.table.rbpg-table--cases {
  width: 100% !important;
  min-width: 42rem;
  table-layout: fixed;
}
.table.rbpg-table--cases thead th {
  padding: 0.5rem 0.85rem;
  font-size: 0.68rem;
}
.table.rbpg-table--cases tbody td,
.table.rbpg-table--cases .rbpg-case-link,
.table.rbpg-table--cases .rbpg-case-title,
.table.rbpg-table--cases .rbpg-ref-cell,
.table.rbpg-table--cases .rbpg-who-name,
.table.rbpg-table--cases .rbpg-who-sub,
.table.rbpg-table--cases .rbpg-age {
  font-size: 0.78rem;
  line-height: 1.3;
}
.table.rbpg-table--cases tbody td {
  padding: 0.42rem 0.85rem;
  vertical-align: middle;
}
.table.rbpg-table--fixed td.rbpg-case-cell,
.table.rbpg-table--fixed td.rbpg-who-cell {
  white-space: normal;
  overflow: hidden;
  text-overflow: clip;
}
.table.rbpg-table td.rbpg-case-cell {
  display: table-cell;
  padding-top: 0.38rem;
  padding-bottom: 0.38rem;
}
.rbpg-case-inner {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
  max-width: 100%;
}
.rbpg-table--cases .rbpg-thumb {
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  border-radius: 6px;
}
.rbpg-case-stack { min-width: 0; flex: 1; }
.rbpg-case-line {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}
.rbpg-case-line .rbpg-case-link,
.rbpg-case-line .rbpg-case-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.rbpg-case-flags {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  flex: none;
}
.rbpg-table--cases .rbpg-cell-labels { margin-top: 0.12rem; }
/* Second line under the title: tag chips and label bars, so the title keeps the full width. */
.rbpg-case-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.4rem;
  margin-top: 0.18rem;
  min-width: 0;
}
.rbpg-case-meta:not(:has(> :not(:empty))) { display: none; }
.rbpg-case-meta .rbpg-case-flags { flex-wrap: wrap; flex: 0 1 auto; }
.rbpg-case-meta .rbpg-case-flags:empty { display: none; }
.rbpg-table--cases .rbpg-case-meta .rbpg-cell-labels { margin-top: 0; }
.rbpg-ref-cell { font-weight: 500; }
.rbpg-who-name,
.rbpg-who-sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rbpg-who-sub { color: var(--rbpg-muted); }
.table.rbpg-table--cases .rbpg-ref-cell,
.table.rbpg-table--cases .rbpg-age {
  font-family: inherit;
  font-variant-numeric: normal;
}
/* One chip box on every case list — Status, Missing, Warranty, Hold, Priority. */
.table.rbpg-table--cases .pill,
.table.rbpg-table--cases .pq-kind,
.table.rbpg-table--cases .pq-prio,
.table.rbpg-table--cases .pq-kind-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.2;
  padding: 0.1rem 0.42rem;
  text-transform: none !important;
  letter-spacing: 0 !important;
  vertical-align: middle;
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
  box-sizing: border-box;
}
.table.rbpg-table--cases .rbpg-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1 1 auto;
}
.table.rbpg-table--cases td.rbpg-col-status,
.table.rbpg-table--cases td.ws-col-status,
.table.rbpg-table--cases th.ws-col-status {
  overflow: hidden;
  white-space: nowrap;
  vertical-align: middle;
  text-overflow: clip;
}
.table.rbpg-table--cases .rbpg-status-inner {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
  max-width: 100%;
  width: max-content;
}
.table.rbpg-table--cases .rbpg-status-inner > .pill,
.table.rbpg-table--cases .rbpg-status-inner > .pq-kind,
.table.rbpg-table--cases td.rbpg-col-status > .pill {
  flex: 0 1 auto;
  width: max-content;
  max-width: 100%;
}
/* Single-stage piles drop Status. The Case column takes the leftover — a
   zero-width Status cell would swallow that leftover and leave a hole. */
.rbpg-table--hide-status .rbpg-col-status { display: none; }
.rbpg-table--no-vendor .rbpg-who-sub { display: none; }

/* Soft neutral grey→white ramp for the content page (matches the process-page
   message thread), instead of the flat grey app background. */
.rbpg-ramp-bg {
  background: linear-gradient(180deg, #f4f4f5 0%, #f8f8f9 40%, #fcfcfc 70%, #ffffff 100%);
  background-attachment: fixed;
}

/* Clickable case title in list tables (opens the case, like the dashboard).
   Also matches a <button>: something that opens an overlay instead of
   navigating is still a title you click, and should read the same. */
.rbpg-table .rbpg-case-link { color: var(--rbpg-text); text-decoration: none; cursor: pointer; vertical-align: middle; }
.rbpg-table .rbpg-case-link:hover { color: var(--rbpg-primary); text-decoration: underline; }
.rbpg-table button.rbpg-case-link {
  background: none; border: 0; padding: 0; max-width: 100%;
  display: inline-block; text-align: left;
}
/* An identifier that is also the way in — the Estimate column's reference. Blue
   at rest, unlike `.rbpg-case-link` beside it, which is a title first and a link
   second. The underline waits for hover so fifty rows are not fifty underlines. */
.rbpg-table a.rbpg-ref-link { color: var(--rbpg-text); text-decoration: none; }
.rbpg-table a.rbpg-ref-link:hover { text-decoration: underline; }

/* Sortable headers */
th[data-sort] { cursor: pointer; user-select: none; }
th[data-sort]::after { content: '⇅'; opacity: 0.35; margin-left: 0.4rem; font-size: 0.8em; }
th.sort-active::after { opacity: 1; }
th.sort-asc::after { content: '↑'; }
th.sort-desc::after { content: '↓'; }

/* Skeleton loading rows */
.skeleton-row td > span {
  display: block; height: 0.9rem; border-radius: 5px;
  background: linear-gradient(90deg, #f0f0f0 25%, #e4e4e7 50%, #f0f0f0 75%);
  background-size: 200% 100%; animation: rbpg-shimmer 1.4s infinite;
}
@keyframes rbpg-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* Pagination */
.rbpg-pager { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.4rem; gap: 0.75rem; flex-wrap: wrap; }
.rbpg-pager .page-info { color: var(--rbpg-muted); font-size: 0.88rem; }

/* ---- Verification center -------------------------------------------- */
.verify-progress { display: flex; align-items: center; gap: 1rem; }
.verify-progress .progress { flex: 1; height: 10px; border-radius: 999px; background: var(--meter-track); }
.verify-progress .progress-bar { background: var(--meter-fill); border-radius: 999px; }
/* While the count is still unknown the bar runs the full width as a moving
   tint — a bar at 0% would be the same wrong claim as "0 of 3" in words. */
.verify-progress--loading .progress-bar {
  background: linear-gradient(90deg, #e4e4e7 25%, #d4d4d8 50%, #e4e4e7 75%);
  background-size: 200% 100%; animation: rbpg-shimmer 1.4s infinite;
}

/* The placeholder cards, shaped like the real ones. `sk-bar` rather than the
   `sk-line` the message list uses: that one is sized for conversation rows. */
.doc-card--skel { pointer-events: none; }
.doc-card--skel .doc-icon { background: #ececef; }
.doc-card--skel .sk-bar {
  display: block; height: 11px; border-radius: 6px; margin-bottom: .55rem;
  background: linear-gradient(90deg, #f0f0f0 25%, #e4e4e7 50%, #f0f0f0 75%);
  background-size: 200% 100%; animation: rbpg-shimmer 1.4s infinite;
}
.doc-card--skel .sk-bar--title { width: 45%; height: 13px; }
.doc-card--skel .sk-bar--desc { width: 80%; }
.doc-card--skel .sk-bar--pill { width: 92px; height: 22px; border-radius: 999px; margin-bottom: 0; }

/* A Bootstrap row gutters horizontally and not at all vertically, so a second
   row of cards sat flush against the first. One `gap` drives both axes, at the
   1.5rem `.app-content .card` already puts between every other card. Two
   columns from md up, as `col-md-6` did. */
.doc-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
@media (min-width: 768px) { .doc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.doc-card { display: flex; align-items: flex-start; gap: 1rem; padding: 1.25rem; border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius); background: var(--rbpg-surface); height: 100%; }
.doc-card .doc-icon { width: 42px; height: 42px; border-radius: 11px; background: var(--rbpg-grey); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.doc-card .doc-icon svg, .doc-card .doc-icon i { width: 20px; height: 20px; color: var(--rbpg-text); }
.doc-card .doc-body { flex: 1; min-width: 0; }
.doc-card .doc-title { font-weight: 700; margin: 0 0 0.15rem; }
/* The key contact's name opens their record. Underlined rather than coloured:
   it sits inside a bold title, and a blue word there reads as an error. */
.doc-card .doc-title a { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--rbpg-muted); }
.doc-card .doc-title a:hover, .doc-card .doc-title a:focus-visible { text-decoration-color: currentColor; }
.doc-card .doc-desc { color: var(--rbpg-muted); font-size: 0.85rem; margin: 0 0 0.75rem; }
/* A document we are not asking THIS business for — a sole trader has no
   certificate of incorporation. Dimmed and left in place rather than removed:
   a vendor who knows the list is three long needs to see that the third was
   considered and does not apply, not find a gap where it used to be. Opacity
   alone, so it reads as "not yours" rather than "disabled, try again". */
.doc-card-na { opacity: .55; }
.doc-card-na .doc-icon { background: transparent; border: 1px dashed var(--rbpg-border-strong); }

/* THE chip — status, priority, warranty. One box: font, padding, gap, dot.
   Colour, case and weight say what it is; size does not.
   An inline-flex box hands its baseline to its FIRST flex item, which here is
   a textless dot — so a pill set beside a label used to sit off the line it
   belonged on. Centring it is both correct and what the eye expects. */
.pill,
.pq-prio,
.pq-kind,
.pq-kind-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.75rem;
  padding: 0.28rem 0.6rem;
  border-radius: 999px;
  line-height: 1.3;
  box-sizing: border-box;
  vertical-align: middle;
  --blip: currentColor;
}
/* `flex: none` because a dot is not a negotiable part of a pill: in a narrow
   table cell a long label was squeezing the circle into an ellipse. */
.pill::before,
.pq-prio::before,
.pq-kind::before,
.pq-kind-inline::before {
  content: '';
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--blip);
}
.pill { font-weight: 700; }
.pill-verified { background: var(--tone-ok-tint);      color: var(--tone-ok-ink);      --blip: var(--tone-ok-dot); }
.pill-pending  { background: var(--tone-warn-tint);    color: var(--tone-warn-ink);    --blip: var(--tone-warn-dot); }
.pill-rejected { background: var(--tone-bad-tint);     color: var(--tone-bad-ink);     --blip: var(--tone-bad-dot); }
.pill-missing  { background: var(--tone-neutral-tint); color: var(--tone-neutral-ink); --blip: var(--tone-neutral-dot); }
/* In flight — an estimate that is with the customer. Estimates already speak
   blue for this in .pq-est-status and .eb-pill, so without a blue in the shared
   set the same estimate would read amber on the Estimates page and blue in the
   cockpit and the builder. Colour only for meaning; the "one blue per screen"
   rule governs competing CTAs, not status. */
.pill-info     { background: var(--tone-info-tint);    color: var(--tone-info-ink);    --blip: var(--tone-info-dot); }

/* Priority — sentence case, not bold. Fixed width so High and Urgent
   occupy the same box in the column. Geometry lives on the shared chip. */
.pq-prio {
  justify-content: center;
  width: 5.5rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
.pq-prio--low    { background: var(--tone-neutral-tint); color: var(--tone-neutral-ink); --blip: var(--tone-neutral-dot); }
.pq-prio--normal { background: var(--tone-info-tint);    color: var(--tone-info-ink);    --blip: var(--tone-info-dot); }
.pq-prio--high   { background: var(--tone-warn-tint);    color: var(--tone-warn-ink);    --blip: var(--tone-warn-dot); }
.pq-prio--urgent { background: var(--tone-bad-tint);     color: var(--tone-bad-ink);     --blip: var(--tone-bad-dot); }

/* Status blips read as caps across every page (P3 UI). Priority does not —
   `.pq-prio` is sentence case on purpose. */
.pill,
[class*="rbpg-pill--"],
.rbpg-table .badge { text-transform: uppercase; letter-spacing: 0.03em; }

/* ---- Tabs (mono) ---------------------------------------------------- */
.rbpg-tabs.nav-tabs { border-bottom: 1px solid var(--rbpg-border); gap: 0.25rem; }
.rbpg-tabs .nav-link {
  border: 0; border-bottom: 2px solid transparent;
  color: var(--rbpg-muted); font-weight: 600;
  padding: 0.65rem 1rem; border-radius: 0; background: none;
}
.rbpg-tabs .nav-link:hover { color: var(--rbpg-text); border-bottom-color: var(--rbpg-border-strong); }
.rbpg-tabs .nav-link.active { color: var(--rbpg-text); background: none; border-bottom-color: var(--rbpg-text); }
/* Compact segmented switch for a card header (period pickers). Same markup and
   `.active` toggle as the tabs above. */
.rbpg-tabs--seg.nav-tabs {
  flex-wrap: nowrap; gap: 2px; padding: 3px; border: 0;
  background: var(--rbpg-grey); border-radius: 8px;
}
.rbpg-tabs--seg .nav-link {
  border: 0; border-radius: 6px; padding: 0.28rem 0.7rem;
  font-size: 0.76rem; line-height: 1.2; color: var(--rbpg-muted);
}
.rbpg-tabs--seg .nav-link:hover { color: var(--rbpg-text); }
.rbpg-tabs--seg .nav-link.active {
  background: #fff; color: var(--rbpg-text);
  box-shadow: 0 1px 2px rgba(15, 15, 20, 0.08), 0 0 0 1px rgba(15, 15, 20, 0.04);
}

/* Earnings card (supplier dashboard). */
.rbpg-earn .stat-value { letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.rbpg-earn__head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.25rem 0.5rem; }
.rbpg-earn__of { color: var(--rbpg-muted); font-size: var(--type-body); }
.rbpg-earn__bar { margin-top: 0.9rem; gap: 0.75rem; }
.rbpg-earn__bar .progress { height: 6px; }
.rbpg-earn__pct { font-size: var(--type-label); font-weight: var(--weight-number); white-space: nowrap; font-variant-numeric: tabular-nums; }
.rbpg-earn__split {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 1.25rem 0 1.1rem; padding-top: 1.1rem; border-top: 1px solid var(--rbpg-border);
}
.rbpg-earn__cell { padding: 0 1rem; min-width: 0; }
.rbpg-earn__cell:first-child { padding-left: 0; }
.rbpg-earn__cell:last-child { padding-right: 0; }
.rbpg-earn__cell + .rbpg-earn__cell { border-left: 1px solid var(--rbpg-border); }
.rbpg-earn__label, .rbpg-figure__label { color: var(--rbpg-muted); font-size: var(--type-label); font-weight: var(--weight-strong); margin-bottom: 0.3rem; }
.rbpg-earn__value, .rbpg-figure__value { font-size: var(--type-figure); font-weight: var(--weight-number); line-height: 1.2; font-variant-numeric: tabular-nums; }
.rbpg-earn__sub, .rbpg-figure__sub { color: var(--rbpg-muted); font-size: var(--type-meta); line-height: 1.35; margin-top: 0.25rem; }
.rbpg-earn__foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem;
  padding: 0.75rem 0.9rem; border-radius: 10px; background: var(--rbpg-grey);
}
.rbpg-earn__takes { font-size: var(--type-body); line-height: 1.4; flex: 1 1 14rem; }
.rbpg-earn__foot .btn-light { background: #fff; border-color: var(--rbpg-border); }
.rbpg-earn__foot .btn-light:hover { background: #fff; border-color: var(--rbpg-border-strong); }
.rbpg-earn__note { color: var(--rbpg-muted); font-size: var(--type-meta); margin-top: 0.6rem; }
/* Pipeline card (supplier dashboard). The piles are `.ws-card`s, tones and all, made
   compact here: label left, count right, oldest time under the label. */
.rbpg-floor__stats {
  display: flex; flex-wrap: wrap;
  margin-bottom: 1.25rem; padding-bottom: 1.1rem; border-bottom: 1px solid var(--rbpg-border);
}
.rbpg-floor__cell { flex: 1 1 0; min-width: 7.5rem; padding: 0 1rem; }
.rbpg-floor__cell:first-child { padding-left: 0; }
.rbpg-floor__cell + .rbpg-floor__cell { border-left: 1px solid var(--rbpg-border); }
.rbpg-floor__groups { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem 1.25rem; }
.rbpg-floor__group { display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; }
.rbpg-floor__group-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: var(--type-eyebrow); font-weight: var(--weight-strong); letter-spacing: 0.06em; text-transform: uppercase;
  /* The right inset puts the blip's digit over the counts in the piles below: a pile's
     padding (.8rem) and border, less the blip's own side padding. */
  color: var(--rbpg-muted); padding: 0 calc(0.45rem + 1px) 0.15rem 0.15rem;
}
.rbpg-floor__group-n {
  min-width: 1.25rem; height: 1.1rem; padding: 0 0.35rem; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--rbpg-grey); color: var(--rbpg-text); letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.rbpg-floor .ws-card {
  flex-direction: row; align-items: center; justify-content: space-between; gap: 0.75rem;
  min-height: 2.9rem; padding: 0.55rem 0.8rem; border-radius: 10px;
}
.rbpg-floor a.ws-card { transition: background-color .15s ease; }
.rbpg-floor a.ws-card:hover,
.rbpg-floor a.ws-card:focus-visible { background: #fefce8; }
.rbpg-floor a.ws-card--muted:hover, .rbpg-floor a.ws-card--muted:focus-visible { border-color: var(--rbpg-border); }
.rbpg-floor a.ws-card--ok:hover, .rbpg-floor a.ws-card--ok:focus-visible { border-color: #bbf7d0; }
.rbpg-floor a.ws-card--warn:hover, .rbpg-floor a.ws-card--warn:focus-visible { border-color: #fde68a; }
.rbpg-floor a.ws-card--bad:hover, .rbpg-floor a.ws-card--bad:focus-visible { border-color: #fecaca; }
.rbpg-floor__pile { min-width: 0; display: flex; flex-direction: column; }
.rbpg-floor .ws-card-label {
  margin: 0; font-size: var(--type-row); font-weight: var(--weight-strong); line-height: 1.3; letter-spacing: 0;
  text-transform: none; color: var(--rbpg-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rbpg-floor .ws-card-count { flex: none; font-size: var(--type-figure); font-weight: var(--weight-number); font-variant-numeric: tabular-nums; }
.rbpg-floor .ws-card-age { margin-top: 0.2rem; font-size: var(--type-meta); }
.rbpg-floor .ws-card-clock { width: 12px; height: 12px; }
.rbpg-floor .ws-card.is-zero .ws-card-label,
.rbpg-floor .ws-card.is-zero .ws-card-count { color: var(--rbpg-muted); font-weight: 500; }
/* An empty pile's zero is a quiet mark, the size of its label, not a light figure. */
.rbpg-floor .ws-card.is-zero .ws-card-count { font-size: var(--type-row); }
.rbpg-floor a.ws-card.is-zero:hover .ws-card-label,
.rbpg-floor a.ws-card.is-zero:focus-visible .ws-card-label { color: var(--rbpg-text); }
.rbpg-floor .ws-card-label { transition: color .15s ease; }
/* The workshop's Pipeline card (FLOOR-8): the piles, then Capacity in a 250px column on the right.
   The bar is the room left, green until the last fifth, amber after, red when full. */
.rbpg-floor__body { display: flex; align-items: stretch; gap: 1.5rem; }
.rbpg-floor__body > .rbpg-floor__groups { flex: 1 1 auto; min-width: 0; }
.rbpg-floor__aside {
  flex: 0 0 250px; display: flex; flex-direction: column; gap: 0.6rem;
  padding-left: 1.5rem; border-left: 1px solid var(--rbpg-border);
}
.rbpg-floor__aside .rbpg-figure__label { margin-bottom: 0; }
.rbpg-floor__cap-main { display: flex; flex-direction: column; gap: 0.6rem; }
.rbpg-floor__cap-bar { height: 8px; border-radius: 999px; background: var(--meter-track); overflow: hidden; }
.rbpg-floor__cap-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--meter-ok); }
.rbpg-floor__cap-bar--warn > span { background: var(--meter-warn); }
.rbpg-floor__cap-bar--bad > span { background: var(--meter-bad); }
.rbpg-floor__cap-rows { margin-top: auto; padding-top: 0.6rem; border-top: 1px solid var(--rbpg-border); display: flex; flex-direction: column; gap: 0.3rem; }
.rbpg-floor__cap-row { display: flex; justify-content: space-between; gap: 0.5rem; font-size: var(--type-meta); color: var(--rbpg-muted); }
.rbpg-floor__cap-row strong { color: var(--rbpg-text); font-weight: var(--weight-strong); font-variant-numeric: tabular-nums; }
@media (max-width: 1199.98px) {
  .rbpg-floor__body { flex-direction: column; }
  .rbpg-floor__aside { flex-basis: auto; padding: 1.1rem 0 0; border-left: 0; border-top: 1px solid var(--rbpg-border); }
}
/* Stacked under the piles there is room for two halves: the figure and bar, then the counts. */
@media (min-width: 576px) and (max-width: 1199.98px) {
  .rbpg-floor__aside { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0; }
  .rbpg-floor__cap-main { padding-right: 1.5rem; }
  .rbpg-floor__aside .rbpg-floor__cap-rows {
    margin-top: 0; padding: 0 0 0 1.5rem; border-top: 0; border-left: 1px dotted #a1a1aa; justify-content: center;
  }
}
@media (max-width: 991.98px) {
  .rbpg-floor__groups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 575.98px) {
  .rbpg-floor__groups { grid-template-columns: 1fr; }
  .rbpg-floor__stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 0.9rem; }
  .rbpg-floor__cell, .rbpg-floor__cell:first-child { padding: 0; }
  .rbpg-floor__cell + .rbpg-floor__cell { border-left: 0; }
}
@media (max-width: 575.98px) {
  .rbpg-earn__split { grid-template-columns: 1fr; row-gap: 0.9rem; }
  .rbpg-earn__cell, .rbpg-earn__cell:first-child, .rbpg-earn__cell:last-child { padding: 0; }
  .rbpg-earn__cell + .rbpg-earn__cell { border-left: 0; }
}
/* Count blip: a small light-grey pill with dark text (tab counts, "1 open" by a
   page title). Empty means none, so no blip. */
.rbpg-count-blip,
.rbpg-tabs .pq-tab-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.25rem; height: 1.1rem; padding: 0 0.35rem; margin-left: 0.3rem;
  border-radius: 999px; background: var(--rbpg-grey);
  color: var(--rbpg-text); font-size: 0.68rem; font-weight: 600; line-height: 1;
  vertical-align: 0.1em;
}
.rbpg-count-blip:empty,
.rbpg-tabs .pq-tab-count:empty { display: none; }
h1 .rbpg-count-blip { height: 1.3rem; padding: 0 0.5rem; margin-left: 0; font-size: 0.75rem; vertical-align: middle; }

/* Hide lower-priority table columns on smaller screens */
@media (max-width: 991.98px) { .hide-sm { display: none !important; } }
@media (max-width: 1199.98px) { .hide-md { display: none !important; } }

/* Row-menu dropdown trigger */
.rbpg-table .dropdown-toggle::after { display: none; }
/* Row-menu items read as light links, not bold buttons. */
.rbpg-table td .dropdown-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; font-weight: 400; }
.rbpg-table td .dropdown-item svg { width: 14px; height: 14px; flex-shrink: 0; }

/* List cards: full-height card so short lists don't collapse, the table scrolls
   INSIDE the card (overflow-x stays on .table-responsive), and the pager is
   pinned to the bottom. Row menus escape the scroll box via Popper "fixed". */
/* overflow:hidden clips the square grey <thead> background to the card's rounded
   corners so the border curve shows (row menus escape via position:fixed). */
.rbpg-list-card { min-height: 460px; display: flex; flex-direction: column; overflow: hidden; }
.rbpg-list-card > .card-header { flex: 0 0 auto; }
.rbpg-list-card > .table-responsive { flex: 1 1 auto; }
.rbpg-list-card > .rbpg-pager { flex: 0 0 auto; border-top: 1px solid var(--rbpg-border); }
/* A list card that is one section of a page (customer record) sizes to its rows. */
.rbpg-list-card--fit { min-height: 0; }
/* Customer facts card: blocks sit side by side in wide columns, so the pencil
   follows its heading instead of drifting to the far edge of the column. */
.rbpg-cust-facts .pq-info-head { justify-content: flex-start; gap: 0.3rem; margin-bottom: 0.5rem; }
/* ── The standard table (.cursor/rules/rbpg-table-spec.mdc) ───────────────────
   One class carries the spec, so every table that wears it reads the same:
   0.68rem headers and 0.78rem cells, rows read from the top, secondary columns
   go below 1280px, middle-column dates and numbers centred, and the row menu
   pinned to the right edge. Pages add the class; they never copy these sizes. */
.table.rbpg-table--std.rbpg-table--fixed { min-width: 42rem; }
/* `--fit`: a short preview (the case and one narrow column) that sits in half a row. It fits its
   card rather than scrolling inside it; the case cell already truncates. */
.table.rbpg-table--std.rbpg-table--fixed.rbpg-table--fit { min-width: 0; }
.table.rbpg-table--std thead th { padding: 0.5rem 0.85rem; font-size: 0.68rem; }
.table.rbpg-table--std tbody td { padding: 0.42rem 0.85rem; vertical-align: top; }
.table.rbpg-table--std tbody td,
.table.rbpg-table--std td .small,
.table.rbpg-table--std .rbpg-case-link,
.table.rbpg-table--std .rbpg-who-name,
.table.rbpg-table--std .rbpg-who-sub,
.table.rbpg-table--std .rbpg-age,
.table.rbpg-table--std .qcq-verdict {
  font-size: 0.78rem;
  line-height: 1.3;
}
.table.rbpg-table--std .pill {
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.2;
  padding: 0.1rem 0.42rem;
  text-transform: none;
  letter-spacing: 0;
}
/* One bold link per row; a secondary link opts out with fw-normal. */
.table.rbpg-table--std .rbpg-case-link { font-weight: 600; }
.table.rbpg-table--std .rbpg-case-link.fw-normal { font-weight: 400; }
/* Links are mono: the hover underlines, it does not turn blue. */
.table.rbpg-table--std .rbpg-case-link:hover { color: var(--rbpg-text); }
/* The title column gives way last: chips shrink before the title does. */
.table.rbpg-table--std .rbpg-case-line .rbpg-case-link { min-width: 4rem; }
.table.rbpg-table--std .rbpg-case-flags { flex: 0 1 auto; min-width: 0; overflow: hidden; }
/* A thumbnail sits inside the title cell, never in a column of its own. */
.table.rbpg-table--std .rbpg-case-inner .rbpg-thumb { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 6px; }
/* Dates, time-ago and numbers: centred in a middle column, flush right in the last. */
.table.rbpg-table--std thead th.rbpg-col-mid,
.table.rbpg-table--std tbody td.rbpg-col-mid {
  text-align: center; padding-left: 0.4rem; padding-right: 0.4rem;
}
.table.rbpg-table--std thead th.rbpg-col-end,
.table.rbpg-table--std tbody td.rbpg-col-end { text-align: right; }
/* Below 1280px the optional columns go, and a row keeps only what identifies
   it: the title, with the reference moved onto the line under it
   (.rbpg-sub-narrow) in place of wide-screen detail (.rbpg-sub-wide). Tag
   blips and label bars are large-screen extras. Media queries, not a size
   container: a container traps the row menus' fixed positioning. */
@media (max-width: 1279.98px) {
  /* Optional columns collapse to zero width rather than display:none: a
     full-width empty-state row still spans a removed column's slot, and the
     table then shares the title column's space with that invisible column. */
  .table.rbpg-table--std th.rbpg-col-opt,
  .table.rbpg-table--std td.rbpg-col-opt {
    width: 0 !important; max-width: 0; padding: 0 !important; border-width: 0 !important;
    overflow: hidden; visibility: hidden; white-space: nowrap;
  }
  .table.rbpg-table--std .rbpg-case-stack .rbpg-case-flags,
  .table.rbpg-table--std .rbpg-case-stack .rbpg-cell-labels,
  .table.rbpg-table--std .rbpg-sub-wide { display: none; }
}
@media (min-width: 1280px) {
  .table.rbpg-table--std .rbpg-sub-narrow { display: none; }
}
/* The row menu stays in view: pinned to the right edge when a narrow screen
   scrolls the table sideways. */
.table.rbpg-table--std[data-row-menu] thead th:last-child,
.table.rbpg-table--std[data-row-menu] tbody td:last-child { position: sticky; right: 0; }
.table.rbpg-table--std[data-row-menu] tbody tr:not(:hover) td:last-child { background: var(--rbpg-surface); }
/* A sticky cell is its own stacking context: lift the one whose menu is open
   above the rows below it. */
.table.rbpg-table--std[data-row-menu] tbody td:last-child:has(.dropdown-menu.show) { z-index: 1056; }
/* Table footer: the paging belongs to the table it pages. Page n of m and the
   View all link on the left; rows-per-page, Previous and Next on the right.
   The pager wrapper is display:contents so its re-rendered children sit in the
   same row as the static link and select. */
.rbpg-table-foot {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.75rem;
  padding: 0.55rem 1rem;
  border-top: 1px solid var(--rbpg-border);
}
.rbpg-table-foot-pager { display: contents; }
.rbpg-table-foot .page-info { order: 0; font-size: 0.75rem; color: var(--rbpg-muted); white-space: nowrap; }
.rbpg-table-foot .page-info strong { color: var(--rbpg-text); }
.rbpg-table-foot-all {
  order: 1; font-size: 0.75rem; font-weight: 600; white-space: nowrap;
  color: var(--rbpg-text); text-decoration: none;
}
.rbpg-table-foot-all:hover { text-decoration: underline; }
/* The select and the paging buttons share one height, so the footer is one row of controls. */
.rbpg-table-foot-size {
  order: 2; margin-left: auto; width: auto;
  height: 1.75rem; padding-top: 0; padding-bottom: 0; line-height: 1;
  font-size: 0.75rem; border-radius: 0.45rem;
}
.rbpg-table-foot-nav { order: 3; display: flex; gap: 0.4rem; }
.rbpg-table-foot-nav .btn {
  display: inline-flex; align-items: center; height: 1.75rem;
  padding: 0 0.65rem; border-radius: 0.45rem; font-size: 0.75rem; line-height: 1;
}

/* Shared workspace footer (P4-ACTIONS-1) — FIXED to the bottom of the content
   area (right of the sidebar). Pinned independent of table height: a short table
   won't pull it up, a tall table won't push it down; content scrolls underneath.
   One row: page-info left, Actions dead-center (absolute), Prev/Next right. */
.rbpg-ws-footer {
  position: fixed; left: var(--rbpg-sidebar-w); right: 0; bottom: 0; z-index: 900;
  display: flex; align-items: center;
  min-height: var(--rbpg-footer-h);
  padding: 0.6rem 0;
  background: var(--rbpg-surface);
  border-top: 1px solid var(--rbpg-border);
  box-shadow: 0 -6px 18px rgba(0,0,0,0.05);
}
/* Inner wrapper matches .app-content (max-width 1280, left-aligned, 1.75rem pad)
   so the pager + centered Actions align with the content instead of centering on
   the full-width footer (which sits right of the capped content on wide screens). */
.rbpg-ws-footer-inner {
  position: relative;
  flex: 1 1 auto; width: 100%; max-width: 1280px;
  padding: 0 1.75rem;
  display: flex; align-items: center;
}
.rbpg-ws-footer .rbpg-pager--flat {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: nowrap; gap: 0.75rem; padding: 0;
}
.rbpg-ws-footer-inner #rbpg-ws-actions {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
}
/* A single-table page pages in the page footer: the same .rbpg-table-foot as a
   table card, around the centred Actions button (page info left, size and
   Previous / Next right). */
.rbpg-ws-footer .rbpg-table-foot { flex: 1 1 auto; flex-wrap: nowrap; padding: 0; border-top: 0; }
/* Reserve space so the pager / last rows aren't hidden behind the fixed footer. */
.app-content--footer { padding-bottom: calc(var(--rbpg-footer-h) + 1.5rem); }
@media (max-width: 991.98px) {
  .rbpg-ws-footer { left: 0; }               /* sidebar goes off-canvas */
}
@media (max-width: 720px) {
  .rbpg-ws-footer-inner { padding-left: 1rem; padding-right: 1rem; }
}
/* Row menu must layer above sticky table headers / neighbouring rows */
.dropdown-menu { z-index: 1056; }

/* Modals go above the workspace shells.
 *
 * Bootstrap puts a modal at 1055, which is fine on a normal page and wrong on
 * every `.pq` one: those shells are fixed at 2000, the action palette at 3000
 * and the file menu at 3500, so a modal opened from a cockpit or the estimate
 * builder rendered BEHIND the page that opened it — visible to the DOM,
 * invisible to the person who asked for it.
 *
 * Raised as a pair so Bootstrap's own ordering is untouched: a modal still sits
 * one step above its backdrop, and no other page changes. Above the file menu
 * too, because a modal is a question and nothing should be able to cover one. */
.modal { z-index: 3600; }
.modal-backdrop { z-index: 3590; }

/* Mobile off-canvas backdrop for the sidebar */
.app-scrim { position: fixed; inset: 0; background: rgba(24, 24, 27, 0.45); z-index: 1039; opacity: 0; pointer-events: none; transition: opacity .2s ease; }
.app-scrim.show { opacity: 1; pointer-events: auto; }
@media (min-width: 992px) { .app-scrim { display: none !important; } }

/* Impersonation banner (44px, fixed) sits above the app.
   Offset the fixed sidebar + sticky topbar below it, and push the main content
   flow down by the same amount so the pinned topbar doesn't overlap the body. */
.app-impersonation {
  position: fixed; top: 0; left: 0; right: 0; height: 44px;
  padding: 0 .75rem; background: #f4f4f5; color: #18181b;
  border-bottom: 1px solid #e4e4e7; z-index: 1060;
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  font-size: .85rem; font-weight: 600;
}
.app-impersonation span {
  min-width: 0; max-width: 28vw; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
}
.app-impersonation .btn { flex: 0 0 auto; padding: .2rem .7rem; }
.app-impersonation-tier { color: var(--rbpg-muted); font-weight: 500; }
.app.impersonating .app-sidebar,
.app.impersonating .app-topbar { top: 44px; }
.app.impersonating .app-main { padding-top: 44px; }
@media (max-width: 720px) {
  .app-impersonation {
    height: 72px; display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: repeat(3, 1fr); gap: 0 .5rem;
    justify-content: stretch; font-size: .72rem;
  }
  .app-impersonation strong { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .app-impersonation span { max-width: none; }
  .app-impersonation .btn { grid-column: 2; grid-row: 1 / span 3; }
  .app.impersonating .app-sidebar,
  .app.impersonating .app-topbar { top: 72px; }
  .app.impersonating .app-main { padding-top: 72px; }
}

/* ---- Vendor detail: logo + per-card settings ------------------------ */
.rbpg-logo-thumb {
  width: 96px; height: 96px; border-radius: 16px; object-fit: cover;
  background: #f3f4f6; border: 1px solid #e5e7eb; flex: 0 0 auto;
}
/* The preview inside the upload dialog. Same shape as the well on the page, so
   what the vendor approves in the modal is what they then see. */
.rbpg-logo-lg {
  width: 200px; height: 80px; border-radius: 12px;
  object-fit: contain; padding: 8px; box-sizing: border-box;
}
img.rbpg-logo-lg { background: #fff; }
.rbpg-logo-empty {
  display: flex; align-items: center; justify-content: center;
  font-size: .72rem; color: #9ca3af; text-align: center;
}
.rbpg-setting-card .card-footer {
  background: transparent; border-top: 1px solid #eef0f2;
}
.rbpg-save-msg.is-ok { color: #4f6f5e; }
.rbpg-save-msg.is-err { color: #9b3b32; }

/* Status pills on the vendor detail page. These were a second, deliberately
   desaturated palette — sage #3f6b54, olive #85693a, a blue with no blue in it
   (#566079) — which is what "muddy" looks like in hex, and the olive failed AA.
   Same tones as `.pill` now; only the geometry differs, because this page sets
   them in denser rows. */
.rbpg-pill {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .2rem .6rem; border-radius: 999px;
  font-size: .75rem; font-weight: 600; line-height: 1.4;
  background: var(--tone-neutral-tint); color: var(--tone-neutral-ink);
  white-space: nowrap; vertical-align: middle;
}
/* No blip here, unlike `.pill`. These sit alone — one in a card header, a short
   row under a page title — where the tint already carries the tone and the dot
   was just a second mark on a chip wide enough to read. `.pill` keeps its dot
   because it works in dense table cells, where tint alone is easy to skim past. */
.rbpg-pill--ok    { background: var(--tone-ok-tint);      color: var(--tone-ok-ink); }
.rbpg-pill--warn  { background: var(--tone-warn-tint);    color: var(--tone-warn-ink); }
.rbpg-pill--info  { background: var(--tone-info-tint);    color: var(--tone-info-ink); }
.rbpg-pill--bad   { background: var(--tone-bad-tint);     color: var(--tone-bad-ink); }
.rbpg-pill--muted { background: var(--tone-neutral-tint); color: var(--tone-neutral-ink); }
.rbpg-pill-row { display: flex; flex-wrap: wrap; gap: .4rem; }

/* Onboarding progress */
.rbpg-progress { height: 8px; background: var(--meter-track); border-radius: 999px; overflow: hidden; }
.rbpg-progress > span { display: block; height: 100%; background: var(--meter-fill); border-radius: 999px; transition: width .3s ease; }
.rbpg-steps { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: .5rem; }
.rbpg-steps li { display: flex; align-items: center; gap: .6rem; font-size: .85rem; color: #6b7280; }
.rbpg-steps li .dot {
  width: 18px; height: 18px; border-radius: 999px; flex: 0 0 auto;
  border: 1.5px solid #d1d5db; display: inline-flex; align-items: center; justify-content: center;
  font-size: .6rem; color: #fff;
}
.rbpg-steps li.done { color: #1f2937; }
.rbpg-steps li.done .dot { background: #111827; border-color: #111827; }
.rbpg-steps li.current { color: #1f2937; font-weight: 600; }
.rbpg-steps li.current .dot { border-color: #111827; }
/* SUP-12: whose move it is, at the end of the rung. Muted and never a badge —
   six pills down one column is the noise the card exists to avoid. */
.rbpg-steps li .label { flex: 1 1 auto; min-width: 0; }
.rbpg-steps li .who { flex: 0 0 auto; color: var(--rbpg-muted); font-weight: 400; font-size: .8rem; }
/* The current rung does the thing it names, where there is a thing to do. */
.rbpg-steps li > .btn { flex: 0 0 auto; margin: -.25rem 0; }

/* ---- Modals (mono, commercial) -------------------------------------- */
/* Add class `rbpg-modal` to the outer `.modal` element. Optional size
   modifiers on the same element: `rbpg-modal--wide` / `rbpg-modal--narrow`.
   Primary action = dark grey (.btn-mono); secondary = light grey (.btn-light). */

/* Structure, for pages that do NOT load Bootstrap's CSS.
   `onboarding.html`, `index.html` and `supplier-process.html` are built on
   AdminKit's `app.css`, which carries no modal rules at all — while
   `adminkit.js` DOES bundle Bootstrap's Modal JS. So a modal opened there was
   shown (`display:block`, a backdrop appended) and then laid out as an
   ordinary block at the bottom of the document: no overlay, no centring, and
   a body with no height to scroll inside. That is what broke the Supplier
   Agreement on the onboarding wizard.

   These restate Bootstrap's own structural values, scoped to `.rbpg-modal`,
   so the pages that DO load Bootstrap land on the same result. Deliberately
   no `max-width` and no `padding`: those belong to the rules below, which
   would otherwise be fighting their own fallback. No `z-index` either: the
   `.modal` / `.modal-backdrop` pair above owns it, and restating Bootstrap's
   1055 here sinks every modal behind the 2000 cockpit shells. */
.rbpg-modal {
  /* Bootstrap's JS sets `display:block` inline when it opens, which beats
     this. Without the rule the overlay would sit over the page permanently. */
  display: none;
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  overflow-x: hidden; overflow-y: auto;
  outline: 0;
}
.modal-backdrop { position: fixed; inset: 0; width: 100vw; height: 100vh; background-color: #000; }
.modal-backdrop.fade { opacity: 0; }
.modal-backdrop.show { opacity: .5; }
.rbpg-modal .modal-dialog { position: relative; width: auto; margin: .5rem; pointer-events: none; }
.rbpg-modal .modal-content { position: relative; display: flex; flex-direction: column; width: 100%; pointer-events: auto; background: var(--rbpg-surface); }
.rbpg-modal .modal-header { display: flex; flex-shrink: 0; }
.rbpg-modal .modal-body { position: relative; flex: 1 1 auto; }
.rbpg-modal .modal-footer { display: flex; flex-shrink: 0; flex-wrap: wrap; align-items: center; }
.rbpg-modal .modal-dialog-centered { display: flex; align-items: center; min-height: calc(100% - 1rem); }
/* The one that was missing: without a bounded height the document cannot
   scroll, so the reader could never reach the end and never agree. */
.rbpg-modal .modal-dialog-scrollable { height: calc(100% - 1rem); }
.rbpg-modal .modal-dialog-scrollable .modal-content { max-height: 100%; overflow: hidden; }
.rbpg-modal .modal-dialog-scrollable .modal-body { overflow-y: auto; }
/* A generated document has no page to link to, so the viewer hides its
   "open in a new tab" link with `d-none` — a Bootstrap class the wizard's
   stylesheet does not define. Without this the link would still show, and
   lead nowhere. */
.rbpg-modal .d-none { display: none !important; }
@media (min-width: 576px) {
  .rbpg-modal .modal-dialog { margin: 1.75rem auto; }
  .rbpg-modal .modal-dialog-centered { min-height: calc(100% - 3.5rem); }
  .rbpg-modal .modal-dialog-scrollable { height: calc(100% - 3.5rem); }
}

.rbpg-modal .modal-dialog { max-width: 620px; }
.rbpg-modal.rbpg-modal--wide .modal-dialog { max-width: 860px; }
.rbpg-modal.rbpg-modal--narrow .modal-dialog { max-width: 480px; }
/* MULTI-4: the whole window with a small margin. Header and footer are fixed and the body is the only thing
   that scrolls, because the Split button must stay reachable however many watches are on the left. */
.rbpg-modal.rbpg-modal--full .modal-dialog {
  max-width: none;
  width: auto;
  margin: 1rem;
  height: calc(100vh - 2rem);
}
.rbpg-modal.rbpg-modal--full .modal-content { height: 100%; }
.rbpg-modal.rbpg-modal--full .modal-body { overflow: hidden; position: relative; min-height: 0; }

.rbpg-modal .modal-content {
  border: 1px solid var(--rbpg-border);
  border-radius: var(--rbpg-radius-lg);
  box-shadow: 0 24px 64px rgba(24, 24, 27, .20);
  overflow: hidden;
}
.rbpg-modal .modal-header {
  align-items: flex-start;
  gap: 1rem;
  padding: 1.35rem 1.6rem;
  border-bottom: 1px solid var(--rbpg-border);
  background: var(--rbpg-surface);
}
.rbpg-modal .modal-title { font-size: 1.2rem; font-weight: 700; line-height: 1.3; }
.rbpg-modal .modal-subtitle { margin: .3rem 0 0; font-size: .875rem; color: var(--rbpg-muted); line-height: 1.45; }
.rbpg-modal .modal-header { justify-content: space-between; }
.rbpg-modal .btn-close { margin: -.25rem -.25rem 0 auto; padding: .65rem; opacity: .55; }

/* Shared: tag chips (used by CustomerEdit + customer view) */
.tag-chip { display: inline-flex; align-items: center; gap: .4rem; background: #e4e4e7; color: #3f3f46; border-radius: 999px; padding: .2rem .6rem; font-size: .78rem; font-weight: 600; }
.tag-chip button { border: 0; background: transparent; color: #71717a; line-height: 1; font-size: .9rem; cursor: pointer; padding: 0; }

/* Create signature (MSG-7): small pick-one role chips and the email-ending preview */
.es-chips { display: flex; flex-wrap: wrap; gap: .3rem; }
.es-chip { border: 1px solid var(--rbpg-border, #e4e4e7); background: #fff; color: #3f3f46; border-radius: 999px; padding: .15rem .55rem; font-size: .74rem; font-weight: 500; line-height: 1.4; cursor: pointer; }
.es-chip:hover { border-color: #a1a1aa; }
.es-chip[aria-pressed="true"] { background: var(--rbpg-text, #18181b); border-color: var(--rbpg-text, #18181b); color: #fff; }
.es-fixed { display: flex; align-items: baseline; gap: .4rem; font-size: .85rem; }
.es-fixed strong { font-weight: 600; }
.es-preview { border: 1px solid var(--rbpg-border, #e4e4e7); border-radius: .5rem; background: #fafafa; padding: .75rem .9rem; font-size: .85rem; line-height: 1.5; }
.es-preview .es-closer { color: var(--rbpg-muted); margin-bottom: .35rem; }
.es-preview .es-name { font-weight: 600; }
.es-preview .es-link { color: #2563eb; text-decoration: underline; }

/* ── Masked customer contact + Reveal (PRIV-1) ─────────────────────────────────
   `ma****@gmail.com` is the resting state of every contact row in the app, so it must
   not read as a warning or an error: the mask is muted and the button quieter still.
   `None on file` is styled as absence rather than as a hidden value — the two facts are
   different, and a screen that renders them alike is how an agent comes to tell a
   customer we have no address for them when we do. */
.rbpg-cr { display: inline-flex; align-items: baseline; gap: .35rem; flex-wrap: wrap; }
.rbpg-cr-mask { color: var(--rbpg-muted); user-select: none; }
.rbpg-cr-none { color: var(--rbpg-muted); font-style: italic; }
/* Selectable on purpose: the reason to reveal an address is almost always to use it. */
.rbpg-cr-open { user-select: all; }
.rbpg-cr-btn {
  display: inline-flex; align-items: center; gap: .25rem;
  border: 1px solid var(--rbpg-border); background: #fff; color: var(--rbpg-muted);
  border-radius: 999px; padding: .05rem .45rem; font-size: .72rem; font-weight: 600;
  line-height: 1.4; cursor: pointer;
}
.rbpg-cr-btn:hover, .rbpg-cr-btn:focus-visible { color: var(--rbpg-ink); border-color: var(--rbpg-ink); }
.rbpg-cr-btn.is-busy { opacity: .5; cursor: default; }
.rbpg-cr-btn.is-done { color: #15803d; border-color: #15803d; }
.rbpg-cr-copy { padding: .05rem .3rem; }
.rbpg-cr-note { color: var(--rbpg-muted); font-size: .7rem; }
.rbpg-cr-note.is-error { color: #b91c1c; }

/* Shared: audit history list (CustomerEdit history modal) */
.hist-item { padding: .85rem 0; border-bottom: 1px solid var(--rbpg-border); }
.hist-item:last-child { border-bottom: 0; }
.hist-actor { width: 30px; height: 30px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: .7rem; font-weight: 800; flex: 0 0 auto; }
.hist-actor.human { background: #e4e4e7; color: #3f3f46; }
.hist-actor.ai { background: #dbeafe; color: #1e40af; }
.hist-actor.system { background: #e5e5e5; color: #525252; }
.hist-diff { font-size: .8rem; background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 8px; padding: .5rem .7rem; margin-top: .4rem; }
.hist-old { color: #b91c1c; text-decoration: line-through; }
.hist-new { color: #15803d; }
.actor-badge { font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: .05rem .4rem; border-radius: 999px; }
.actor-badge.ai { background: #dbeafe; color: #1e40af; }
.rbpg-modal .btn-close:hover { opacity: .9; }

/* Bootstrap's scrollable modal caps the height of `.modal-content` and expects
   the header, body and footer to be its direct children — the body scrolls and
   the other two stay put. Most of our forms wrap all three in a `<form>` so the
   Enter key submits, which leaves one unconstrained child holding the lot: the
   content runs past the capped height and `overflow: hidden` takes the footer,
   and the submit button in it, off the bottom of the dialog. Passing the flex
   column through the form puts it back. */
.modal-dialog-scrollable .modal-content > form {
  display: flex;
  flex-direction: column;
  max-height: 100%;
  overflow: hidden;
}
.modal-dialog-scrollable .modal-content > form > .modal-body { overflow-y: auto; }

.rbpg-modal .modal-body { padding: 1.6rem; }
.rbpg-modal .modal-footer {
  padding: 1.1rem 1.6rem;
  border-top: 1px solid var(--rbpg-border);
  background: var(--rbpg-grey);
  gap: .6rem;
}
.rbpg-modal .modal-footer .btn { padding-inline: 1.25rem; }

/* Comfortable inputs + labels inside modals */
.rbpg-modal .modal-body .form-label { font-weight: 600; font-size: .82rem; margin-bottom: .35rem; }
/* `:not()` so a form that asks for compact controls still gets them: this rule
   is three classes deep and would otherwise outrank `.form-control-sm`. */
.rbpg-modal .modal-body .form-control:not(.form-control-sm),
.rbpg-modal .modal-body .form-select:not(.form-select-sm) { padding: .6rem .85rem; font-size: .95rem; }
.rbpg-modal .modal-body .row + .row { margin-top: .25rem; }

/* A confirmation whose consequences are worth listing rather than describing.
   Tighter than a default list: this is a short set of facts inside a dialog
   somebody is reading in a hurry, not prose. */
.rbpg-modal .rc-list { margin: .65rem 0 0; padding-left: 1.15rem; }
.rbpg-modal .rc-list li { font-size: .9rem; line-height: 1.5; }
.rbpg-modal .rc-list li + li { margin-top: .35rem; }

/* The optional note a confirmation can collect. Set off from the explanation
   above it, because it is the one thing on the dialog that is asking rather
   than telling. */
.rbpg-modal .rc-field { margin-top: 1rem; }
.rbpg-modal .rc-field .form-label { font-size: .85rem; font-weight: 600; margin-bottom: .35rem; }
.rbpg-modal .rc-field textarea { resize: vertical; }

/* Grouped sections with a hint of separation and breathing room */
.rbpg-modal .form-block { margin-bottom: 1.5rem; }
.rbpg-modal .form-block:last-child { margin-bottom: 0; }
.rbpg-modal .form-hint { font-size: .8rem; color: var(--rbpg-muted); margin: .3rem 0 0; }

/* ---- Vendor editors (vendor-edit.js) -------------------------------------
   Compact controls — these forms hold short values (a number, a name, a
   link), and the default modal input was reading as a text box — and titled
   sections behind a rule where one editor asks more than one kind of question. */
.rbpg-modal.ve-modal .modal-body .form-control:not(.form-control-sm),
.rbpg-modal.ve-modal .modal-body .form-select:not(.form-select-sm) { padding: .45rem .7rem; font-size: .9rem; }
.rbpg-modal.ve-modal .modal-body .form-select:not(.form-select-sm) { padding-right: 2rem; background-position: right .6rem center; }
.rbpg-modal.ve-modal .modal-body .input-group-text { padding: .45rem .7rem; font-size: .9rem; color: var(--rbpg-muted); background: var(--rbpg-grey); }
.rbpg-modal.ve-modal .modal-body .input-group .btn { font-size: .875rem; }
.rbpg-modal.ve-modal .modal-body textarea.form-control { line-height: 1.45; }
.rbpg-modal.ve-modal .modal-body .form-check-label { font-size: .88rem; font-weight: 600; }
.rbpg-modal.ve-modal .modal-body .form-check + .form-hint { margin-top: .15rem; padding-left: 2.5em; }
.rbpg-modal.ve-modal .modal-body .form-check:not(.form-switch) + .form-hint { padding-left: 1.5em; }
.ve-sec + .ve-sec { margin-top: 1.25rem; padding-top: 1.15rem; border-top: 1px solid var(--rbpg-border); }
.ve-sec-head { margin-bottom: .7rem; }
.ve-sec-title { margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--rbpg-text); }
.ve-sec-head .form-hint { margin-top: .15rem; }
/* A switch that sits beside an input: start it level with the input, not the label. */
.ve-align-control { padding-top: 1.85rem; }
@media (max-width: 575.98px) { .ve-align-control { padding-top: 0; } }

/* ---- Case editor (case-edit.js) ------------------------------------------
   The vendor editors' compact sections, plus two things a long form needs:
   which boxes you have touched, and the parcel's trip read left to right. */
.cse-modal .modal-body .form-label { font-size: .78rem; margin-bottom: .25rem; }
.cse-modal .modal-body textarea.form-control { resize: vertical; min-height: 3.6rem; }
.cse-modal .form-control:disabled, .cse-modal .form-select:disabled { background-color: var(--rbpg-grey); }
.cse-modal .is-changed { border-color: var(--tone-warn-dot); box-shadow: inset 3px 0 0 var(--tone-warn-dot); }
.cse-leg { position: relative; }
.cse-leg-name { margin-bottom: .45rem; font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--rbpg-muted); }
@media (min-width: 768px) { .cse-leg + .cse-leg { border-left: 1px dashed var(--rbpg-border); } }
.cse-dirty { margin-right: auto; font-size: .8rem; color: var(--rbpg-muted); }

/* ---- Service levels editor (vendor page, SUP-5 / SUP-7) ----------------
   A settings sheet, not a form: each group is a titled section behind a rule,
   and each level is one row with the words on the left and a small control on
   the right, so ten levels read as one column of answers. */
.ve-sl-group + .ve-sl-group { margin-top: 1.4rem; padding-top: 1.25rem; border-top: 1px solid var(--rbpg-border); }
.ve-sl-head { margin-bottom: .5rem; }
.ve-sl-title { margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--rbpg-text); }
.ve-sl-head .form-hint { margin-top: .15rem; }
.ve-sl-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .55rem 0;
}
.ve-sl-row + .ve-sl-row { border-top: 1px dashed var(--rbpg-border); }
.ve-sl-text { min-width: 0; }
.ve-sl-label { display: block; font-size: .86rem; font-weight: 600; line-height: 1.3; }
.ve-sl-text .form-hint { margin-top: .1rem; line-height: 1.35; }
.ve-sl-control { flex: 0 0 auto; width: 9.5rem; }
.rbpg-modal .ve-sl-control .form-select-sm { font-size: .84rem; padding: .3rem 1.8rem .3rem .6rem; }
/* The offered terms: label above, chips below, full width. */
.ve-sl-row--stack { flex-direction: column; align-items: stretch; gap: .5rem; }
.ve-sl-chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.ve-sl-chip-input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.ve-sl-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .26rem .6rem; border: 1px solid var(--rbpg-border); border-radius: 999px;
  background: var(--rbpg-surface, #fff); color: var(--rbpg-muted);
  font-size: .76rem; font-weight: 600; line-height: 1.2; cursor: pointer; user-select: none; white-space: nowrap;
  transition: background .12s, border-color .12s, color .12s;
}
.ve-sl-chip::before { content: ''; width: .5rem; height: .5rem; border-radius: 50%; border: 1px solid currentColor; }
.ve-sl-chip:hover { border-color: var(--rbpg-border-strong, #a1a1aa); color: var(--rbpg-text); }
.ve-sl-chip-input:checked + .ve-sl-chip { background: #3f3f46; border-color: #3f3f46; color: #fff; }
.ve-sl-chip-input:checked + .ve-sl-chip::before { background: #fff; border-color: #fff; }
.ve-sl-chip-input:focus-visible + .ve-sl-chip { box-shadow: 0 0 0 3px rgba(63, 63, 70, .18); }
@media (max-width: 575.98px) {
  .ve-sl-row { flex-direction: column; align-items: stretch; gap: .4rem; }
  .ve-sl-control { width: 100%; }
}

/* ---- What they repair: sub-type tiles (SUP-9) ---------------------------
   One tile per sub-type, in catalogue order. The whole tile is the control;
   the tick is drawn, the checkbox itself is hidden. Mono: charcoal when on,
   hairline when off. */
.vn-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
.vn-tile {
  position: relative; display: flex; align-items: flex-start; gap: .6rem;
  padding: .6rem .7rem; border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius, 8px);
  background: var(--rbpg-surface, #fff); cursor: pointer; user-select: none; margin: 0;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.vn-tile:hover { border-color: var(--rbpg-border-strong, #a1a1aa); }
.vn-tile.is-on { border-color: #3f3f46; background: #fafafa; }
.vn-tile-input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.vn-tile-input:focus-visible ~ .vn-tile-tick { box-shadow: 0 0 0 3px rgba(63, 63, 70, .18); }
.vn-tile-tick {
  flex: 0 0 auto; width: 1.05rem; height: 1.05rem; margin-top: .1rem; border-radius: 4px;
  border: 1.5px solid var(--rbpg-border-strong, #a1a1aa); background: #fff; position: relative;
  transition: background .12s, border-color .12s;
}
.vn-tile.is-on .vn-tile-tick { background: #3f3f46; border-color: #3f3f46; }
.vn-tile.is-on .vn-tile-tick::after {
  content: ''; position: absolute; left: .3rem; top: .1rem; width: .3rem; height: .55rem;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.vn-tile-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.vn-tile-name { font-size: .88rem; font-weight: 600; color: var(--rbpg-text); line-height: 1.25; }
.vn-tile-blurb { font-size: .76rem; color: var(--rbpg-muted); line-height: 1.3; }
.vn-tile-eg { font-size: .76rem; color: var(--rbpg-text); line-height: 1.3; }
/* A tile and its brand list travel together. The list is outside the <label>, so opening it does not tick the tile.
   An open list takes the whole row so a long list is not squeezed into half a column. */
.vn-tile-cell {
  display: flex; flex-direction: column; min-width: 0;
  border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius, 8px); background: var(--rbpg-surface, #fff);
  transition: border-color .12s, background .12s;
}
.vn-tile-cell:hover { border-color: var(--rbpg-border-strong, #a1a1aa); }
.vn-tile-cell.is-on { border-color: #3f3f46; background: #fafafa; }
/* Inside a cell the CARD is the cell; the label is just its clickable top. */
.vn-tile-cell > .vn-tile, .vn-tile-cell > .vn-tile:hover, .vn-tile-cell > .vn-tile.is-on {
  flex: 1 1 auto; border-color: transparent; background: transparent; border-radius: inherit;
}
.vn-tile-cell:has(> .vn-brands[open]) { grid-column: 1 / -1; }
/* Under the tile's text: past the tick (.7rem padding + 1.05rem tick + .6rem gap). */
.vn-brands { margin: .25rem 0 0; font-size: .76rem; }
.vn-tile-cell > .vn-brands { margin: 0 .7rem .6rem 2.35rem; }
.vn-brands > summary { cursor: pointer; color: var(--rbpg-muted); width: fit-content; }
.vn-brands > summary:hover { color: var(--rbpg-text); }
.vn-brands-list { margin-top: .3rem; color: var(--rbpg-muted); line-height: 1.5; }
@media (max-width: 575.98px) { .vn-tiles { grid-template-columns: 1fr; } }

/* ---- Payment method picker -------------------------------------------
   Four tiles rather than a select: the method is the first decision and the
   one that changes what the operator is looking for on their screen — a bank
   reference, a terminal receipt — so it is worth seeing all four at once
   instead of opening a list to find out what the options are. */
.rp-methods {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .5rem;
  margin-bottom: .25rem;
}
.rp-methods button {
  display: block;
  text-align: left;
  padding: .5rem .7rem;
  border: 1px solid var(--rbpg-border);
  border-radius: var(--rbpg-radius);
  background: #fff;
  cursor: pointer;
}
.rp-methods button:hover { background: var(--rbpg-grey); }
.rp-methods button.is-on {
  border-color: #3f3f46;
  box-shadow: inset 0 0 0 1px #3f3f46;
  background: #fff;
}
.rp-m-label { display: block; font-size: .875rem; font-weight: 600; color: var(--rbpg-text); }
.rp-m-hint { display: block; font-size: .75rem; color: var(--rbpg-muted); }

/* ---- Recording a decision on the customer's behalf ---------------------
   The approve/decline toggle borrows the method picker's tiles: it is the same
   kind of choice — the first one, and the one that changes what the rest of the
   form asks for — so it should not look like a different mechanism. */
.rd-toggle { margin-bottom: 1rem; }

/* The work, read back. Not a table: the agent is reading these down a phone,
   and a name against a price in a quiet list is easier to keep your place in
   than a grid. */
.rd-line, .rd-opt {
  display: flex; align-items: center; gap: .6rem;
  padding: .45rem 0; border-bottom: 1px solid var(--rbpg-border);
  font-size: .875rem;
}
.rd-line:last-child, .rd-opt:last-child { border-bottom: 0; }
.rd-line > span, .rd-opt-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.rd-line > b, .rd-opt > b { flex: 0 0 auto; font-variant-numeric: tabular-nums; }

/* The whole row is the hit target, because ticking a £120 upgrade on somebody
   else's behalf should not depend on hitting a 14px box. */
.rd-opt { cursor: pointer; margin: 0; }
.rd-opt:hover { background: var(--rbpg-grey); }
.rd-opt .form-check-input { flex: 0 0 auto; margin: 0; cursor: pointer; }

/* The same three rows the Total card on the page shows, so the button's figure
   can be reconciled against the line prices above it rather than taken on
   trust. Right-aligned values on tabular numerals, as everywhere else money is
   totalled. */
.rd-sum {
  margin-top: .9rem;
  padding-top: .7rem;
  border-top: 1px solid var(--rbpg-border);
}
.rd-sum-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: .18rem 0;
  font-size: .85rem;
}
.rd-sum-row > b { font-variant-numeric: tabular-nums; font-weight: 600; }
.rd-sum-row--grand {
  margin-top: .3rem;
  padding-top: .4rem;
  border-top: 1px solid var(--rbpg-border);
}
.rd-sum-row--grand > span, .rd-sum-row--grand > b { font-weight: 700; }

/* "optional", beside a label. Quiet enough not to compete with the label and
   present enough that nobody hunts for the asterisk that is not there. */
.rd-opt-tag {
  font-size: .7rem;
  font-weight: 500;
  color: var(--rbpg-muted);
  text-transform: none;
  letter-spacing: 0;
}

/* The consequence sits ABOVE the buttons rather than beside them: it is the
   sentence that should be read before the click, and a footnote to the right of
   a primary button is read afterwards, if at all. */
.rbpg-modal .modal-footer.rd-foot {
  display: block;
  text-align: left;
}
.rd-consequence {
  margin: 0 0 .7rem;
  font-size: .78rem;
  line-height: 1.45;
  color: var(--rbpg-muted);
}
.rd-foot-actions { display: flex; justify-content: flex-end; gap: .5rem; }
.rbpg-modal .modal-lead {
  margin: 0 0 1.4rem;
  padding: .85rem 1rem;
  font-size: .875rem;
  color: var(--rbpg-text);
  background: var(--rbpg-grey);
  border: 1px solid var(--rbpg-border);
  border-radius: var(--rbpg-radius);
  line-height: 1.5;
}

/* Two-column page layout — single column until 1280px, then split.
   Use `.rbpg-split` on a wrapper with two direct child <div> columns.
   Add `.rbpg-split--even` for a 50/50 split instead of the default 1.35 / 1. */
.rbpg-split { display: grid; grid-template-columns: 1fr; gap: 1rem; align-items: start; }
@media (min-width: 1280px) {
  .rbpg-split { grid-template-columns: 1.35fr 1fr; }
  .rbpg-split.rbpg-split--even { grid-template-columns: 1fr 1fr; }
  /* Fixed identity sidebar (left) + wide activity panel (right) */
  .rbpg-split.rbpg-split--sidebar { grid-template-columns: 340px 1fr; }
}

/* `--match`: two LISTS side by side rather than a panel beside a detail.
   The default `align-items: start` is right for the common case — a short
   sidebar next to a long feed should not stretch to match it — and wrong when
   both columns are card-wrapped tables with a pager at the bottom, because the
   shorter card's pager then floats halfway up the row next to the taller one's.
   Stretching both and letting the card fill its column puts the two pagers on
   one line, which is the whole point of them matching. */
.rbpg-split--match { align-items: stretch; }
.rbpg-split--match > * { display: flex; min-width: 0; }
.rbpg-split--match > * > .card { flex: 1 1 auto; width: 100%; }

/* Success view inside a modal (post-submit confirmation) */
.rbpg-modal-success { text-align: center; padding: .25rem 0 .25rem; }
.rbpg-success-badge {
  width: 56px; height: 56px; border-radius: 999px;
  margin: .25rem auto 1rem;
  display: inline-flex; align-items: center; justify-content: center;
  color: #3f6b54; background: #eaf1ec; border: 1px solid #d8e6dd;
}

/* Mono primary button (dark grey, not black, not blue) */
.btn-mono {
  background: #3f3f46;
  border: 1px solid #3f3f46;
  color: #fff;
  font-weight: 600;
}
.btn-mono:hover, .btn-mono:focus, .btn-mono:active {
  background: #27272a !important;
  border-color: #27272a !important;
  color: #fff !important;
}
.btn-mono:disabled { background: #a1a1aa; border-color: #a1a1aa; color: #fff; opacity: 1; }

/* Stripe's own indigo, on the one button that connects a Stripe account.
   The admin palette is deliberately mono, and this is the exception worth
   making: a payment processor's colour is recognised before it is read, so
   somebody landing on the Payments tab looking for "where do the keys go"
   finds it without scanning the card. It stays the only coloured button on
   that card, which is what keeps it meaning "this one". */
.btn-stripe {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: #635bff;
  border: 1px solid #635bff;
  color: #fff;
  font-weight: 600;
}
.btn-stripe:hover, .btn-stripe:focus, .btn-stripe:active {
  background: #4f46e5 !important;
  border-color: #4f46e5 !important;
  color: #fff !important;
}
.btn-stripe:disabled { background: #b4afff; border-color: #b4afff; color: #fff; opacity: 1; }
.btn-stripe svg { flex: none; }

/* ---- Responsive ----------------------------------------------------- */
@media (max-width: 991.98px) {
  .app-sidebar { transform: translateX(-100%); transition: transform .2s ease; }
  .app-sidebar.open { transform: translateX(0); }
  .app-main { margin-left: 0; }
  .app-hamburger { display: inline-flex; }
  .app-content { padding: 1.25rem 1rem 3rem; }
}

@media (max-width: 575.98px) {
  .rbpg-modal .modal-header,
  .rbpg-modal .modal-body,
  .rbpg-modal .modal-footer { padding-left: 1.15rem; padding-right: 1.15rem; }
  .rbpg-modal .modal-footer { flex-direction: column-reverse; }
  .rbpg-modal .modal-footer .btn { width: 100%; margin: 0; }
}

/* ---- Cases console: contextual pipeline rail ------------------------- */
.rail-nav .rail-back {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.8rem; margin-bottom: 0.5rem;
  border-radius: 10px; color: var(--rbpg-muted); text-decoration: none;
  font-weight: 600; font-size: 0.85rem;
}
.rail-nav .rail-back:hover { background: var(--rbpg-grey); color: var(--rbpg-text); }
.rail-nav .rail-back svg, .rail-nav .rail-back i { width: 16px; height: 16px; }
.rail-stage {
  display: flex; align-items: center; gap: 0.6rem; width: 100%;
  padding: 0.55rem 0.7rem; margin-bottom: 0.15rem;
  border: 0; background: transparent; border-radius: 10px;
  color: var(--rbpg-text); font-weight: 600; font-size: 0.9rem;
  text-align: left; cursor: pointer;
}
.rail-stage:hover { background: var(--rbpg-grey); }
.rail-stage.active { background: var(--rbpg-text); color: #fff; }
/* A rail row that NAVIGATES is an <a>, and `.app-nav a` (0,1,1) outweighs
   `.rail-stage` (0,1,0) on padding and font size — 45px against 39px, measured.
   Every rail built so far is buttons, so this had never shown; the Settings rail
   (NAV-2) is entirely links and would have been visibly taller row by row. */
.app-nav a.rail-stage {
  padding: 0.55rem 0.7rem;
  font-size: 0.9rem;
  gap: 0.6rem;
}
.app-nav a.rail-stage.active { color: #fff; }
.rail-stage-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.rail-dot--muted { background: var(--rbpg-border) !important; }
.rail-count {
  min-width: 1.6rem; text-align: center; font-size: 0.75rem; font-weight: 700;
  padding: 0.05rem 0.4rem; border-radius: 999px;
  background: var(--rbpg-grey); color: var(--rbpg-muted);
}
.rail-stage.active .rail-count { background: rgba(255,255,255,0.2); color: #fff; }
.rail-count--alert { background: #fee2e2; color: #b91c1c; }
.rail-stage.active .rail-count--alert { background: #dc2626; color: #fff; }

/* ---- `hidden` has to actually hide ----------------------------------- */
/* Bootstrap's display utilities are `!important`, so on any element carrying both a `d-*`
   class and the `hidden` attribute the class wins and `hidden` silently does nothing. The
   workshop's "Process queue" button is `d-inline-flex`, so it sat on the dashboard where
   WF-15 had correctly hidden it, and `#raise-vat-row` in billing has the same shape.

   The UA stylesheet's `[hidden] { display: none }` cannot compete with `!important`, so this
   raises it to match. It has to come before the utilities in specificity terms, hence
   `!important` here too — an attribute that means "not on the page" should not be losing an
   argument to a layout class. */
[hidden] { display: none !important; }

/* ---- Cases console: KPI / health strip ------------------------------- */
.kpi-strip {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.9rem;
  margin-bottom: 1.1rem;
}
.kpi-card {
  background: var(--rbpg-surface); border: 1px solid var(--rbpg-border);
  border-radius: 14px; padding: 0.9rem 1.1rem;
}
.kpi-card--alert { border-color: var(--tone-bad-lit); background: var(--tone-bad-tint); }

/* ---- Workshop floor cards -------------------------------------------
   Count is the card. Pastel wash + a stronger count, not a brick and not a
   6px blip. Oldest time is a clock and a figure; no "oldest / newest / average". */
.ws-card {
  display: flex; flex-direction: column;
  padding: 0.9rem 1.05rem 1rem;
  border: 1px solid var(--rbpg-border);
  border-radius: 14px;
  background: var(--rbpg-surface);
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ws-card:hover { border-color: var(--rbpg-border-strong); }
.ws-card-label {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--rbpg-muted);
  margin-bottom: 0.35rem;
}
.ws-card-count {
  font-size: 2rem; font-weight: 800; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--rbpg-text);
}
.ws-card-age {
  display: inline-flex; align-items: center; gap: 0.3rem;
  margin-top: 0.45rem;
  font-size: 0.84rem; font-weight: 600; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--rbpg-muted);
}
.ws-card-clock { flex: none; width: 14px; height: 14px; }

.ws-card--ok { background: var(--tone-ok-tint); border-color: #bbf7d0; }
.ws-card--ok .ws-card-count { color: var(--tone-ok-ink); }
.ws-card--ok .ws-card-age { color: var(--tone-ok-ink); }

.ws-card--warn { background: var(--tone-warn-tint); border-color: #fde68a; }
.ws-card--warn .ws-card-count { color: var(--tone-warn-ink); }
.ws-card--warn .ws-card-age { color: var(--tone-warn-ink); }

.ws-card--bad { background: var(--tone-bad-tint); border-color: #fecaca; }
.ws-card--bad .ws-card-count { color: var(--tone-bad-ink); }
.ws-card--bad .ws-card-age { color: var(--tone-bad-ink); }

.ws-card--muted { background: var(--rbpg-surface); border-color: var(--rbpg-border); }

.ws-card-link {
  margin-top: 0.55rem; padding: 0; border: 0; background: none;
  align-self: flex-start; font-size: 0.72rem; font-weight: 600;
  color: var(--rbpg-text); text-decoration: underline; text-underline-offset: 2px;
}
.ws-card-link:hover { color: var(--tone-bad-ink); }
.kpi-label {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--rbpg-muted); font-weight: 700; margin-bottom: 0.35rem;
}
.kpi-value { font-size: 1.6rem; font-weight: 800; line-height: 1.1; color: var(--rbpg-text); }
/* Billing (EST-26): whose money a figure is. Two ledgers run in opposite
   directions on that page and the amounts alone cannot say which is which. */
.kpi-sub { margin-top: 0.3rem; font-size: 0.72rem; color: var(--rbpg-muted); }
.kpi-healthbar {
  margin-top: 0.55rem; height: 7px; border-radius: 999px;
  background: var(--meter-track); overflow: hidden;
}
.kpi-healthbar span { display: block; height: 100%; width: 0; border-radius: 999px; transition: width .3s ease, background .3s ease; }

@media (max-width: 991.98px) { .kpi-strip { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 479.98px) { .kpi-strip { grid-template-columns: 1fr 1fr; } }

.hdr-count { font-size: 1.1rem; font-weight: 600; color: var(--rbpg-muted); }
.hdr-blip { width: 10px; height: 10px; border-radius: 50%; display: inline-block; background: var(--rbpg-border); }

/* ===================================================================== */
/* Process cockpit — full-screen queue-clearing workspace (P4-CASE-CONSOLE) */
/* ===================================================================== */
/* Lock the page: the cockpit owns the whole viewport, nothing scrolls behind it. */
body:has(.pq) { overflow: hidden; margin: 0; }
.pq {
  position: fixed; inset: 0; z-index: 2000;
  height: 100vh; height: 100dvh;
  display: grid; grid-template-rows: 56px auto minmax(0, 1fr) 66px;
  background: var(--rbpg-bg, #f5f5f5); color: var(--rbpg-text);
}
/* Pin each direct child to its row: a display:none warnings row is removed from
   the grid, so without this the body/footer auto-shift up a track. */
.pq-top { grid-row: 1; }
.pq-warnings { grid-row: 2; }
.pq-body { grid-row: 3; }
.pq-foot { grid-row: 4; }
.pq-callout {
  position: fixed; z-index: 40; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: 1rem;
  min-height: 66px; padding: 0.85rem 1.1rem;
  background: #b42318; color: #fff;
  box-shadow: 0 -10px 28px rgba(0,0,0,.18);
  transform: translateY(100%); opacity: 0;
}
.pq-callout.is-on { transform: none; opacity: 1; transition: transform .28s ease, opacity .28s ease; }
.pq-callout[hidden] { display: none !important; }
.pq-callout-keep {
  background: #fff; border: 1px solid #fff; color: #3f3f46; font-weight: 600;
}
.pq-callout-keep:hover, .pq-callout-keep:focus { background: #f4f4f5; color: #18181b; }
.pq-callout-overwrite {
  background: transparent; border: 1px solid #fff; color: #fff; font-weight: 600;
}
.pq-callout-overwrite:hover, .pq-callout-overwrite:focus { background: rgba(255,255,255,.14); color: #fff; }
.pq-callout-spin {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
  animation: pq-callout-spin .7s linear infinite;
}
@keyframes pq-callout-spin { to { transform: rotate(360deg); } }
/* Thin, rounded, monochrome scrollbars for every scroll area in the cockpit. */
.pq-queue, .pq-info, .pq-thread, .pq-stage-list, .pq-palette-list, .pq-composer > textarea {
  scrollbar-width: thin; scrollbar-color: #c7c7c7 transparent;
}
.pq-queue::-webkit-scrollbar, .pq-info::-webkit-scrollbar, .pq-thread::-webkit-scrollbar,
.pq-stage-list::-webkit-scrollbar, .pq-palette-list::-webkit-scrollbar,
.pq-composer > textarea::-webkit-scrollbar { width: 8px; height: 8px; }
.pq-queue::-webkit-scrollbar-thumb, .pq-info::-webkit-scrollbar-thumb, .pq-thread::-webkit-scrollbar-thumb,
.pq-stage-list::-webkit-scrollbar-thumb, .pq-palette-list::-webkit-scrollbar-thumb,
.pq-composer > textarea::-webkit-scrollbar-thumb {
  background: #cccccc; border-radius: 999px; border: 2px solid transparent; background-clip: content-box;
}
.pq-queue::-webkit-scrollbar-thumb:hover, .pq-info::-webkit-scrollbar-thumb:hover, .pq-thread::-webkit-scrollbar-thumb:hover { background: #a8a8a8; background-clip: content-box; }
.pq-queue::-webkit-scrollbar-track, .pq-info::-webkit-scrollbar-track, .pq-thread::-webkit-scrollbar-track { background: transparent; }
.pq-top {
  display: flex; align-items: center; gap: 1rem;
  height: 56px; padding: 0 1.1rem;
  background: var(--rbpg-text); color: #fff;
}
.pq-crumb { font-weight: 700; letter-spacing: 0.01em; display: flex; align-items: center; gap: 0.5rem; font-size: 0.95rem; }
.pq-crumb .sep { opacity: 0.5; }
.pq-crumb .muted { color: #d4d4d8; font-weight: 600; }
/* Header stage selector: black bg, white border, red label, chevron */
.pq-stage-btn {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: transparent; color: #f87171; font-weight: 800; font-size: 0.9rem;
  border: 1px solid rgba(255,255,255,0.55); border-radius: 8px;
  padding: 0.2rem 0.6rem; cursor: pointer; line-height: 1.4;
}
.pq-stage-btn:hover { border-color: #fff; background: rgba(255,255,255,0.08); }
.pq-stage-btn:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
.pq-stage-caret { color: #fff; opacity: 0.85; font-size: 0.7rem; }
/* The same fact in the side panel's Case block (WF-19). Quieter than the crumb pill — the crumb has
   to survive a glance, this sits in a list of fields being read deliberately. */
/* Warranty — same chip box as status and priority. Pale yellow field so
   it sits with the other chips; charcoal ink so it does not read as High. */
.pq-kind,
.pq-kind-inline {
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  background: var(--tone-warn-tint);
  color: var(--tone-neutral-ink);
  --blip: var(--tone-warn-dot);
}
/* Hold is a choice, not a warranty or a missing watch. Cool slate, so it
   does not sit in the same yellow family as overdue or Missing. */
.pq-kind--hold,
.pq-kind-inline--hold,
.pq-kind--lead,
.pq-kind-inline--lead,
.pq-kind--next,
.pq-kind-inline--next,
.pq-kind--started,
.pq-kind-inline--started {
  background: #f4f4f5;
  color: #3f3f46;
  --blip: #71717a;
}
/* Missing on the panel's Stage row: the alarm, so red and shouted, with its own icon in place
   of the blip. */
.pq-kind-inline--missing {
  display: inline-flex; align-items: center; gap: 0.3rem;
  max-width: 100%; min-width: 0; box-sizing: border-box;
  padding: 0.1rem 0.45rem; border-radius: 6px;
  font-size: 0.72rem; line-height: 1.35; font-weight: 500; white-space: nowrap;
  background: var(--tone-bad-tint); color: var(--tone-bad-ink);
  vertical-align: middle;
}
.pq-kind-inline--missing::before { display: none; }
.pq-kind-inline--missing svg { flex: none; display: block; }
.pq-kind-inline--missing b {
  flex: none; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
}
.pq-kind-inline--missing b::after { content: '\00b7'; margin-left: 0.3rem; font-weight: 400; }
.pq-kv .v.pq-v-clip { min-width: 0; overflow: hidden; }
.pq-kind-inline--missing #pq-case-stage {
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
/* Links between a repair and its warranty returns, beside the Warranty chip. */
.pq-related { display: inline-flex; flex-wrap: wrap; gap: 0.35rem; margin-left: 0.35rem; }
a.pq-kind.pq-related-link { text-decoration: none; cursor: pointer; }
a.pq-kind.pq-related-link:hover { text-decoration: underline; }
.pq-av-origin { margin-bottom: 0.75rem; }
.pq-av-origin .pq-av-links { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
/* The Return panel on a warranty return (RET-2). */
.pq-ret-head { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.25rem 0 0.6rem; }
.pq-ret-route, .pq-ret-attempt {
  display: inline-flex; align-items: center; padding: 0.2rem 0.55rem;
  border-radius: 8px; font-size: 0.8rem; font-weight: 600;
  background: #f1f1f3; color: #1f1f23;
}
.pq-ret-route.is-failed { background: #fff1e6; color: #8a3b00; }
.pq-ret-route.is-warranty { background: #eaf2ff; color: #1d4ea8; }
.pq-ret-route.is-refund { background: #fde8e8; color: #9b1c1c; }
.pq-ret-attempt { font-weight: 500; }
.pq-ret-attempt.is-hold { background: #fde8e8; color: #9b1c1c; }
.pq-ret-dim { color: #6b6b73; }
.pq-ret-terms { margin-top: 0.6rem; font-size: 0.85rem; }
.pq-ret-terms summary { cursor: pointer; color: #3a3a40; }
.pq-ret-terms ul { margin: 0.5rem 0; padding-left: 1.1rem; }
.pq-ret-terms li { margin-bottom: 0.3rem; }
.pq-ret-choice {
  display: flex; gap: 0.6rem; align-items: flex-start;
  padding: 0.7rem 0.8rem; margin-bottom: 0.5rem;
  border: 1px solid #e3e3e6; border-radius: 10px; cursor: pointer;
}
.pq-ret-choice input { margin-top: 0.2rem; }
.pq-ret-choice span { display: flex; flex-direction: column; gap: 0.15rem; }
.pq-ret-choice small { color: #6b6b73; }
/* The bench, beside the stage (WF-24). Quieter than the stage button because it is a fact rather
   than a control, but not muted grey — for a workshop this is the line that matters. */
.pq-lane {
  display: inline-flex; align-items: center;
  margin-left: 0.5rem; padding: 0.2rem 0.55rem;
  border-radius: 8px; background: rgba(255,255,255,0.14); color: #fff;
  font-weight: 700; font-size: 0.82rem; line-height: 1.4; white-space: nowrap;
}
/* Status pill mid-change: pulse until the server confirms the new stage. */
.pq-stage--moving { animation: pq-stage-pulse 0.9s ease-in-out infinite; }
@keyframes pq-stage-pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }

/* Warning banners (between header and body). Each strip is its own tone;
   the dotted rule is how you see where one alert ends and the next starts. */
.pq-warnings { display: flex; flex-direction: column; gap: 0; padding: 0; }
.pq-warn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1.1rem;
  font-size: 0.84rem;
  font-weight: 600;
  border-bottom: 1px dotted currentColor;
}
.pq-warn-ico { font-size: 0.9rem; opacity: 0.9; }
.pq-warn--urgent { background: var(--tone-bad-tint); color: var(--tone-bad-ink); }
.pq-warn--warn { background: var(--tone-warn-tint); color: var(--tone-warn-ink); }
.pq-warn--reply { background: var(--tone-info-tint); color: var(--tone-info-ink); }
/* Hold sits under overdue on purpose: late is the SLA fact, hold is why nobody
   is moving it. Same chrome as the AIVERIE offer — white, no icon —
   because parking a job is a decision, not another alarm. */
.pq-warn--hold {
  background: var(--rbpg-surface);
  color: var(--rbpg-text);
  font-weight: 500;
  padding: 0.42rem 1.1rem;
}
.pq-warn--hold .pq-warn-txt { font-weight: 500; white-space: normal; color: var(--rbpg-text); }
.pq-warn--hold .pq-kind { flex: none; }
.pq-warn--hold .pq-kind::before { display: none; }
.pq-hold-since {
  display: inline-flex; align-items: center; gap: 0.22rem;
  margin-left: 0.4rem; font-size: 0.72rem; font-weight: 500;
  color: var(--rbpg-muted); white-space: nowrap;
}
.pq-hold-since svg { flex: none; display: block; }
/* Landed / Fixed / Shipped: the date, and underneath it what recorded it. */
.pq-ms-how { display: block; font-size: .72rem; color: var(--rbpg-muted); line-height: 1.3; }
.pq-ms-pending { color: var(--rbpg-muted); }
/* P3-AIV-2: the same strip, carrying an offer rather than a problem — AIVERIE has
   read the photos and is asking whether the record should say so. Deliberately the
   quietest of the three: a case is not in trouble because a machine found something,
   so it reads as neutral chrome with the two verbs on the right. */
.pq-warn--action { background: var(--rbpg-surface); color: var(--rbpg-text); font-weight: 500; padding: 0.42rem 1.1rem; }
/* Drawn icon, optically sized to the text and dropped a hair so its centre sits on
   the text's centre rather than on the line box's. */
.pq-warn--action .pq-warn-ico { display: inline-flex; color: var(--rbpg-muted); }
.pq-warn--action .pq-warn-ico svg { width: 15px; height: 15px; display: block; }
.pq-warn-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-warn-short { display: none; }
.pq-warn-acts { margin-left: auto; display: flex; align-items: center; gap: 0.35rem; flex: none; }
/* Small, and centred by the flexbox rather than by line-height: a button's text
   sitting a pixel high is the thing that makes a strip like this look homemade. */
.pq-warn-acts .pq-btn {
  display: inline-flex; align-items: center; justify-content: center;
  align-self: center; padding: 0.24rem 0.62rem; font-size: 0.75rem; line-height: 1.35;
}
/* On a phone the sentence goes, the count stays. */
@media (max-width: 900px) {
  .pq-warn--action .pq-warn-long { display: none; }
  .pq-warn--action .pq-warn-short { display: inline; }
}
/* Thread-trailing blip (e.g. "customer not messaged for N days"). */
.pq-blip { align-self: center; margin: 0.5rem 0 0.1rem; font-size: 0.74rem; font-weight: 600; color: var(--rbpg-muted); background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 999px; padding: 0.25rem 0.75rem; }
.pq-blip--warn { background: #f7f4ec; color: #6f5a1f; border-color: #e3d9c1; }
.pq-progress { margin-left: auto; display: flex; align-items: center; gap: 0.8rem; font-size: 0.85rem; color: #e4e4e7; }
.pq-progress-bar { width: 160px; height: 6px; border-radius: 999px; background: rgba(255,255,255,0.2); overflow: hidden; }
.pq-progress-bar span { display: block; height: 100%; background: #fff; width: 0; transition: width .25s ease; }
.pq-close {
  border: 0; background: rgba(255,255,255,0.12); color: #fff;
  width: 34px; height: 34px; border-radius: 9px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.pq-close:hover { background: rgba(255,255,255,0.25); }

.pq-body { display: grid; grid-template-columns: 280px minmax(0, 1fr) clamp(280px, 22vw, 400px); min-height: 0; overflow: hidden; }
.pq-queue, .pq-info { background: var(--rbpg-surface); overflow-x: hidden; overflow-y: auto; min-height: 0; min-width: 0; }
.pq-queue { border-right: 1px solid var(--rbpg-border); padding: 0.6rem; }
.pq-info { border-left: 1px solid var(--rbpg-border); padding: 1.1rem; }
.pq-queue-head { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--rbpg-muted); font-weight: 700; padding: 0.4rem 0.5rem 0.6rem; }
.pq-queue-toggle {
  display: none; align-items: center; justify-content: center;
  border: 0; background: rgba(255,255,255,0.12); color: #fff;
  width: 34px; height: 34px; border-radius: 9px; cursor: pointer; flex: 0 0 auto;
}
.pq-queue-toggle:hover { background: rgba(255,255,255,0.25); }
.pq-scrim { display: none; }

.pq-card {
  display: block; width: 100%; text-align: left;
  border: 1px solid #eee; background: #fff;
  border-radius: 11px; padding: 0.6rem 0.7rem; margin-bottom: 0.3rem; cursor: pointer;
}
.pq-card:hover { background: var(--rbpg-grey); border-color: #e2e2e2; }
.pq-card.active { background: #fff; border-color: var(--rbpg-text); box-shadow: 0 1px 0 rgba(0,0,0,0.04); }
.pq-card.done { opacity: 0.5; }
.pq-card.done .pq-card-ref::before { content: '✓ '; color: #16a34a; font-weight: 800; }
.pq-card-top { display: flex; align-items: center; gap: 0.5rem; }
.pq-card-ref { font-family: ui-monospace, monospace; font-size: 0.72rem; color: var(--rbpg-muted); }
.pq-card-age { margin-left: auto; font-size: 0.72rem; color: var(--rbpg-muted); }
.pq-card-age.over { color: #dc2626; font-weight: 700; }
.pq-card-cust { font-weight: 700; font-size: 0.9rem; margin-top: 0.15rem; }
.pq-card-item { font-size: 0.8rem; color: var(--rbpg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Realtime: unread new-message dot + "moved on" fade (docs/design/30). */
.pq-card { position: relative; }
.pq-card-dot { display: none; position: absolute; top: 0.6rem; right: 0.6rem; width: 8px; height: 8px; border-radius: 50%; background: #2563eb; box-shadow: 0 0 0 2px #fff; }
.pq-card--unread .pq-card-dot { display: block; }
.pq-card--unread .pq-card-cust { font-weight: 800; }
.pq-card--moved { opacity: 0.45; }
/* Case labels (AUTO-7) — Trello-style colour bars, rendered app-wide by
   RBPGLabels (lib/rbpg-labels.js). No words: the name shows on hover (.rbpg-tip).
   `--dots` is the compact variant used on queue cards. */
.rbpg-labels { display: inline-flex; gap: 7px; flex-wrap: wrap; align-items: center; }
.rbpg-labels--dots { gap: 5px; margin-top: 0.35rem; }
/* Flat bars — no border, no shadow. Pure colour floating on a transparent strip. */
.rbpg-lbar { width: 42px; height: 11px; border-radius: 999px; display: inline-block; box-shadow: none; border: 0; cursor: default; }
.rbpg-ldot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; box-shadow: none; border: 0; cursor: default; }
/* In-list variant: label bars sit under the item title in the cases/board tables.
   Slightly smaller than the message-window strip so dense rows stay tight; the
   wrapper collapses when a case has no labels so it never adds blank space. */
.rbpg-cell-labels { display: block; margin-top: 0.28rem; }
.rbpg-cell-labels:empty { display: none; }
.rbpg-cell-labels .rbpg-lbar { width: 26px; height: 8px; }
/* Reusable styled hover tooltip ("blip") — any element with .rbpg-tip[data-tip]. */
.rbpg-tip { position: relative; }
.rbpg-tip::after, .rbpg-tip::before { opacity: 0; visibility: hidden; transition: opacity .12s ease; pointer-events: none; position: absolute; z-index: 60; }
.rbpg-tip::after { content: attr(data-tip); left: 50%; bottom: calc(100% + 7px); transform: translateX(-50%); background: #1f2430; color: #fff; font-size: 0.72rem; font-weight: 600; line-height: 1; white-space: nowrap; padding: 5px 8px; border-radius: 6px; box-shadow: 0 4px 14px rgba(0,0,0,0.22); }
.rbpg-tip::before { content: ''; left: 50%; bottom: calc(100% + 2px); transform: translateX(-50%); border: 5px solid transparent; border-top-color: #1f2430; }
.rbpg-tip:hover::after, .rbpg-tip:hover::before { opacity: 1; visibility: visible; }
/* The pinned strip at the bottom-left of the message window (above the composer).
   Transparent so the bars float directly on the message area, with clear spacing
   above the composer so it never crowds the message box. */
.pq-msg-labels { display: flex; align-items: center; gap: 7px; padding: 0 0.9rem; background: transparent; }
.pq-msg-labels:not(:empty) { padding-top: 0.55rem; padding-bottom: 0.7rem; }
.pq-muted { color: var(--rbpg-muted); font-weight: 400; }
.pq-card--moved .pq-card-cust { text-decoration: line-through; }

/* Center: message feed + composer */
.pq-center { display: grid; grid-template-rows: 1fr auto; grid-template-columns: minmax(0, 1fr); min-height: 0; min-width: 0; background: #fff; }
.pq-thread-pane {
  position: relative;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.pq-thread {
  overflow-y: auto; padding: 1.2rem 1.4rem; display: flex; flex-direction: column; gap: 0.7rem;
  flex: 1 1 auto; min-height: 0;
  /* Soft neutral ramp — barely tinted at top, nearly white below. No cool/blue cast. */
  background:
    linear-gradient(
      180deg,
      #f4f4f5 0%,
      #f8f8f9 40%,
      #fcfcfc 70%,
      #ffffff 100%
    );
  background-attachment: fixed;
}
.pq-thread-empty { margin: auto; color: var(--rbpg-muted); font-size: 0.9rem; }
/* The open paints underneath this. Opacity 0 still lays out, so the scroll to
   the latest message happens before the first frame the operator sees. */
.pq-thread.is-arriving { opacity: 0; }
.pq-thread.is-arriving.is-in { opacity: 1; transition: opacity .22s ease; }
.pq-thread-spin {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.pq-thread-spin[hidden] { display: none !important; }
.pq-thread-spin-dot {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--rbpg-border); border-top-color: var(--rbpg-text);
  animation: pq-spin 0.7s linear infinite;
}
/* Shown only when the operator has scrolled up and something new landed below. */
.pq-thread-jump {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 3;
  border: 1px solid #1f2430;
  background: #1f2430;
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1;
  padding: 0.42rem 0.9rem;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  cursor: pointer;
}
.pq-thread-jump:hover { background: #11141c; }
.pq-thread-jump[hidden] { display: none !important; }
/* Inline system log line (routed / snoozed / stage moved) — quiet, centered. */
.pq-sys { align-self: center; display: inline-flex; align-items: center; gap: 0.5rem; margin: 0.55rem 0 0.15rem; font-size: 0.72rem; color: var(--rbpg-muted); background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 999px; padding: 0.22rem 0.7rem; max-width: 90%; }
.pq-sys-text { font-weight: 600; }
.pq-sys-time { opacity: 0.7; }
.pq-sys-ico { opacity: 0.8; font-size: 0.78rem; line-height: 1; }
.pq-sys-actor { opacity: 0.85; font-weight: 600; }
.pq-sys-actor::before { content: '\00b7'; margin: 0 0.4rem 0 0; opacity: 0.6; }
.pq-sys-ai { margin-left: 0.3rem; font-size: 0.6rem; font-weight: 800; letter-spacing: 0.03em; color: #6d28d9; background: #efe7fd; border-radius: 4px; padding: 0.02rem 0.28rem; vertical-align: middle; }
/* A log line whose whole row is the link (a payment: it names no reference to
   underline, but it knows the estimate it settled). Reads as the pill it
   already was until pointed at. */
a.pq-sys--link { text-decoration: none; color: var(--rbpg-muted); cursor: pointer; }
a.pq-sys--link:hover { background: #fff; border-color: #c9d4e5; color: var(--rbpg-text); }

/* References inside notes and log lines: an estimate number, a case, a payment.
   Same ink as the sentence — no blue, no chip. */
.pq-ref {
  color: inherit; text-decoration: underline; text-underline-offset: 2px;
  text-decoration-thickness: 1px; text-decoration-color: currentColor;
  border: 0; background: none; border-radius: 0; padding: 0;
}
.pq-ref:hover { color: inherit; text-decoration-color: currentColor; background: none; }
button.pq-ref {
  appearance: none; font: inherit; line-height: inherit; cursor: pointer;
}

/* Message rows: customer left, our messages + notes right (WhatsApp/Intercom).
   Bubble width shrinks to content up to max-width; date sits below the bubble. */
.pq-msg { max-width: 78%; display: flex; flex-direction: column; gap: 0.22rem; }
.pq-msg--out { align-self: flex-end; align-items: flex-end; }
.pq-msg--in { align-self: flex-start; align-items: flex-start; }

.pq-bubble { display: inline-block; max-width: 100%; border-radius: 15px; overflow: hidden; font-size: 0.9rem; line-height: 1.45; box-shadow: 0 1px 1px rgba(0,0,0,0.04); }
.pq-msg--in .pq-bubble { background: #fff; border: 1px solid var(--rbpg-border); color: var(--rbpg-text); border-bottom-left-radius: 5px; }
.pq-msg--out .pq-bubble { background: #eaf1fb; border: 1px solid #d7e3f6; color: #1c2a44; border-bottom-right-radius: 5px; }
.pq-msg--note .pq-bubble, .pq-bubble--note { background: #fdf6d8; border: 1px solid #f0dfa0; color: #5a4708; border-bottom-right-radius: 5px; }
/* text/doc area — padded. Media (photos) sit flush above with no inner margin. */
.pq-bubble-pad { padding: 0.55rem 0.75rem; }
.pq-bubble--media { width: 300px; max-width: 100%; }
.pq-bubble-subj { font-weight: 700; font-size: 0.82rem; margin-bottom: 0.2rem; }
.pq-bubble-body { white-space: pre-wrap; word-break: break-word; }
.pq-bubble-pad > .pq-atts:first-child { margin-top: 0; }

/* Intercom-style quoted-history unfold: collapse the reply's quoted tail +
   signature behind a small ••• affordance so the thread shows only the new text. */
.pq-quote-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: 0.3rem; padding: 0 0.3rem; height: 12px; min-width: 22px;
  border: 1px solid rgba(0,0,0,0.14); border-radius: 999px;
  background: rgba(0,0,0,0.045); color: inherit; cursor: pointer;
  font-size: 0.6rem; line-height: 1; letter-spacing: 0.04em; opacity: 0.7;
}
.pq-quote-toggle .pq-quote-dots { position: relative; top: -1px; }
.pq-quote-toggle:hover { opacity: 1; background: rgba(0,0,0,0.08); }
.pq-quote-toggle.is-open { background: rgba(0,0,0,0.1); opacity: 1; }
.pq-quoted {
  white-space: pre-wrap; word-break: break-word;
  margin-top: 0.4rem; padding: 0.5rem 0.65rem;
  border-left: 2px solid rgba(0,0,0,0.14);
  background: rgba(0,0,0,0.03); border-radius: 4px;
  font-size: 0.82rem; opacity: 0.72;
}

/* full-bleed photos inside a bubble (WhatsApp-style) */
.pq-media { display: block; background: rgba(0,0,0,0.04); }
.pq-media-item { display: block; width: 100%; border: 0; padding: 0; margin: 0; background: none; cursor: pointer; }
.pq-media--one .pq-media-item img { display: block; width: 100%; max-height: 300px; object-fit: cover; }
.pq-media--multi { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.pq-media--multi .pq-media-item { aspect-ratio: 1; }
.pq-media--multi .pq-media-item img { display: block; width: 100%; height: 100%; object-fit: cover; }

.pq-msg-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.15rem 0.4rem; font-size: 0.66rem; color: var(--rbpg-muted); padding: 0 0.15rem; }
.pq-msg-foot time { color: var(--rbpg-muted); white-space: nowrap; }
.pq-msg-foot .pq-who { font-weight: 600; color: #6b6b70; white-space: nowrap; }
.pq-chan { text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; font-size: 0.58rem; padding: 0.07rem 0.38rem; border-radius: 5px; background: var(--rbpg-grey); color: var(--rbpg-muted); }
.pq-chan--email { background: #e7effb; color: #2563eb; }
.pq-chan--sms { background: #e6f6ec; color: #16a34a; }
.pq-chan--note { background: #fbf0cf; color: #a16207; }

/* Cursor-style composer: bordered card, controls tucked lower-right */
.pq-composer {
  border-top: 1px solid var(--rbpg-border); background: var(--rbpg-surface); padding: 0.7rem 0.9rem;
}
.pq-composer > textarea {
  width: 100%; border: 1px solid var(--rbpg-border); border-top-left-radius: 12px; border-top-right-radius: 12px;
  border-bottom: 0; padding: 0.6rem 0.75rem; resize: none; font-size: 0.9rem;
  min-height: 42px; max-height: 168px; overflow-y: hidden; display: block;
}
.pq-composer > textarea:focus { outline: none; border-color: var(--rbpg-text); }
.pq-sig-preview {
  white-space: pre-line;
  font-size: 0.78rem;
  color: var(--rbpg-muted);
  padding: 0 .75rem .45rem;
  border-left: 1px solid var(--rbpg-border);
  border-right: 1px solid var(--rbpg-border);
}
.pq-composer:focus-within .pq-sig-preview { border-color: var(--rbpg-text); }
.pq-composer--note .pq-sig-preview { display: none; }
.pq-composer--note > textarea { background: #fffdf3; }
.pq-composer-bar {
  display: flex; align-items: center; gap: 0.5rem;
  border: 1px solid var(--rbpg-border); border-top: 0;
  border-bottom-left-radius: 12px; border-bottom-right-radius: 12px;
  padding: 0.35rem 0.4rem 0.35rem 0.5rem; background: #fff;
}
.pq-composer:focus-within .pq-composer-bar,
.pq-composer:focus-within > textarea { border-color: var(--rbpg-text); }
.pq-composer--note .pq-composer-bar { background: #fffdf3; }
.pq-composer-hint { margin-left: auto; font-size: 0.72rem; color: var(--rbpg-muted); white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pq-composer-bar .pq-craft-tones:not([hidden]) { margin-left: auto; }
.pq-composer-bar .pq-craft-tones:not([hidden]) + .pq-composer-hint { margin-left: 0; }

/* channel drop-up */
.pq-chan-wrap { position: relative; }
.pq-chan-btn {
  display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer;
  background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 8px;
  padding: 0.3rem 0.55rem; font-size: 0.82rem; font-weight: 600; color: var(--rbpg-text);
}
.pq-chan-btn:hover { border-color: var(--rbpg-text); }
.pq-chan-caret { font-size: 0.6rem; color: var(--rbpg-muted); }
.pq-chan-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--rbpg-text); display: inline-block; }
.pq-chan-dot--email { background: #2563eb; }
.pq-chan-dot--sms { background: #16a34a; }
.pq-chan-dot--note { background: #d97706; }
.pq-chan-menu {
  position: absolute; bottom: calc(100% + 6px); left: 0; z-index: 30;
  background: #fff; border: 1px solid var(--rbpg-border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.14); padding: 0.3rem; min-width: 190px;
}
.pq-chan-opt {
  display: flex; align-items: center; gap: 0.55rem; width: 100%; text-align: left;
  background: transparent; border: 0; border-radius: 7px; padding: 0.55rem 0.6rem; cursor: pointer; font-size: 0.88rem;
}
.pq-chan-opt:hover { background: var(--rbpg-grey); }

/* circular send with up-arrow */
.pq-send {
  width: 34px; height: 34px; flex: 0 0 auto; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--rbpg-text); color: #fff; display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.05rem; line-height: 1; transition: background .15s, opacity .15s;
}
.pq-send:hover:not(:disabled) { background: #000; }
.pq-send:disabled { opacity: 0.4; cursor: default; }
.pq-send--busy { position: relative; color: transparent; }
.pq-send--busy::after {
  content: ''; position: absolute; width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff; animation: pq-spin 0.7s linear infinite;
}
@keyframes pq-spin { to { transform: rotate(360deg); } }

/* Right: case + customer info */
.pq-info-block { margin-bottom: 1.15rem; }
.pq-info-block h4 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--rbpg-muted); font-weight: 600; margin-bottom: 0.6rem; }
/* Hairline dividers between stacked sections (Case ▸ Customer ▸ Supplier). */
#pq-panel-case .pq-info-block + .pq-info-block { border-top: 1px solid var(--rbpg-border); padding-top: 1.15rem; }
.pq-kv { display: grid; grid-template-columns: 96px 1fr; gap: 0.15rem 0.7rem; font-size: 0.85rem; margin-bottom: 0.4rem; align-items: baseline; }
.pq-kv .k { color: var(--rbpg-muted); font-weight: 400; }
.pq-kv .v { font-weight: 500; color: var(--rbpg-text); word-break: break-word; }
.pq-info-title { font-size: 1rem; font-weight: 700; margin-bottom: 0.35rem; letter-spacing: -0.01em; }
.pq-brand-fact-row { display: flex; align-items: center; gap: 0.55rem; font-size: 0.88rem; font-weight: 600; }
.pq-brand-logo { width: 28px; height: 28px; border-radius: 7px; object-fit: contain; border: 1px solid var(--rbpg-border); background: #fff; }
.pq-brand-logo--empty { display: inline-flex; align-items: center; justify-content: center; color: var(--rbpg-muted); background: var(--rbpg-grey); }
/* Machine case id — dulled, monospace; only shown on the case detail view. */
.pq-caseid { margin-top: 0.6rem; font-family: ui-monospace, monospace; font-size: 0.68rem; color: var(--rbpg-muted); opacity: 0.55; user-select: all; }
.cse-machine-id { font-family: ui-monospace, monospace; font-size: 0.8em; color: var(--rbpg-muted); opacity: 0.55; user-select: all; }
.cse-case-no { font-weight: 700; }
.pq-info-head { display: flex; align-items: center; justify-content: space-between; }
/* Always there, just quiet.
 *
 * These were `opacity: 0` until the block was hovered, which made the only way
 * to edit a case or a customer invisible until you happened to move the mouse
 * over the right area — and on a panel that is mostly read-only text, there is
 * no reason to. An affordance you have to discover by accident is not an
 * affordance. Muted at rest and full contrast on hover says "you can change
 * this" without competing with the values it sits beside. */
/* Centred by flex with the padding zeroed, not by a button's default text
   alignment. A button keeps 6px of side padding, which left these 26px squares
   with a 12px content box — narrower than the 13.3px glyphs in them. An
   overflowing inline box aligns to the start rather than centring, so the icon
   sat a subpixel right of centre, and display scaling rounds that up to a
   visible pixel. */
.pq-edit {
  background: transparent; border: 1px solid transparent; border-radius: 7px; cursor: pointer;
  color: var(--rbpg-muted); width: 26px; height: 26px; line-height: 1; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0.45; transition: opacity .12s, background .12s, color .12s, border-color .12s;
}
/* A plain ASCII plus, sized up to match the pencil's weight. The fullwidth U+FF0B
   it replaces is absent from Inter, so it fell through to whichever CJK-capable
   font the machine happened to offer — a glyph nobody chose, at a width that
   varied by device. */
.pq-edit--add { font-size: 1.05rem; }
.pq-info-block:hover .pq-edit, .pq-edit:focus-visible { opacity: 1; }
.pq-edit:hover { opacity: 1; background: var(--rbpg-grey); color: var(--rbpg-text); border-color: var(--rbpg-border); }

/* The item name and its pencil. Baseline-aligned rather than centred: the name
   wraps to two lines on a long one and a centred button would drift into the
   middle of it. */
/* Only on the Estimate card, whose title is a reference with a revision blip
   beside it. The base `.pq-info-title` is also the case item's name, which wraps
   to two lines and must not be turned into a single row. */
.pq-info-block--est .pq-info-title { display: flex; align-items: center; gap: 0.45rem; }
/* Where the estimate stands, ruled off from the provenance above it. */
.pq-info-money { margin-top: 0.6rem; padding-top: 0.6rem; border-top: 1px solid var(--rbpg-border); }
.pq-info-money .pq-kv:last-child { margin-bottom: 0; }
.pq-info-title--act { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.pq-info-title--act .pq-title-text { min-width: 0; overflow-wrap: anywhere; }
.pq-info-title--act .pq-edit { flex: 0 0 auto; margin-top: -2px; }

/* estimates block in the case rail — one row per estimate, then the money */
/* Edged at rest, not only on hover. The grey wash arrives when the pointer does,
   which left the rows reading as loose lines of text until you touched one — the
   dotted rule says "card" while it is being scanned. A shade darker than
   `--rbpg-border`: dots cover about half the edge, so the token that reads as a
   hairline when solid all but disappears when broken up. */
.pq-est {
  display: grid; grid-template-columns: 1fr auto; gap: 0.15rem 0.45rem; align-items: start;
  padding: 0.5rem 0.55rem; margin: 0 -0.5rem 0.4rem; border-radius: 8px;
  border: 1px dotted #ddd;
  text-decoration: none; color: inherit;
  transition: background .12s, border-color .12s;
}
.pq-est[draggable="true"] { cursor: grab; }
.pq-est.is-dragging, .qc-card.is-dragging { opacity: 0.55; cursor: grabbing; }
.qc-card[draggable="true"] { cursor: grab; }
.pq-est:hover { background: var(--rbpg-grey); border-color: var(--rbpg-border); }
.pq-est:hover .pq-est-rev { background: var(--rbpg-surface); }
.pq-est-main {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.22rem;
  min-width: 0; text-decoration: none; color: inherit;
}
.pq-est-main:hover, .pq-est-main:focus, .pq-est-main:visited {
  text-decoration: none; color: inherit;
}
.pq-est-top { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; }
.pq-est-ref { font-size: 0.85rem; font-weight: 600; color: var(--rbpg-text); }
.pq-est-total { font-size: 0.82rem; font-weight: 600; color: var(--rbpg-text); }
.pq-est-rev {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--rbpg-grey); color: var(--rbpg-muted);
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.02em;
  display: inline-flex; align-items: center; justify-content: center;
}
.pq-est-status {
  display: inline-flex; align-items: center;
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--rbpg-muted);
  background: var(--rbpg-grey); border-radius: 999px; padding: 0.12rem 0.42rem;
}
.pq-est-status[data-status="approved"] { background: var(--tone-ok-tint); color: var(--tone-ok-ink); }
.pq-est-status[data-status="sent"], .pq-est-status[data-status="viewed"] {
  background: var(--tone-info-tint); color: var(--tone-info-ink);
}
.pq-est-status[data-status="rejected"], .pq-est-status[data-status="expired"] {
  background: var(--tone-bad-tint); color: var(--tone-bad-ink);
  --blip: var(--tone-bad-dot);
  font-size: 0.7rem;
  padding: 0.2rem 0.55rem 0.2rem 0.7rem;
}
.pq-est-status[data-status="rejected"]::before,
.pq-est-status[data-status="expired"]::before {
  content: '';
  width: 0.42rem; height: 0.42rem; border-radius: 50%;
  background: var(--blip);
  margin-right: 0.28rem;
  flex: none;
}
.pq-est-note { font-size: 0.72rem; color: var(--tone-warn-ink, var(--rbpg-muted)); }
.pq-est-empty { font-size: 0.85rem; color: var(--rbpg-muted); margin-bottom: 0.5rem; }
#pq-estimates .pq-kv:first-of-type { margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid var(--rbpg-border); }
.pq-kv-act { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.pq-take-pay { flex: 0 0 auto; background: transparent; border: 1px solid var(--rbpg-border); border-radius: 6px; color: var(--rbpg-text); font-size: 0.72rem; font-weight: 600; padding: 0.1rem 0.45rem; cursor: pointer; line-height: 1.4; }
.pq-take-pay:hover { background: var(--rbpg-grey); border-color: var(--rbpg-text); }

/* case cover image + camera */
.pq-cover { position: relative; border-radius: 12px; overflow: hidden; background: var(--rbpg-grey); margin-bottom: 0.7rem; aspect-ratio: 4 / 3; }
.pq-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pq-cover--empty { display: flex; align-items: center; justify-content: center; border: 1px dashed var(--rbpg-border); }
.pq-cover-ph { color: var(--rbpg-muted); font-size: 0.82rem; }
.pq-cover-cam {
  position: absolute; right: 8px; bottom: 8px; width: 34px; height: 34px; border-radius: 50%;
  border: 0; background: rgba(0,0,0,0.62); color: #fff; cursor: pointer; font-size: 0.95rem;
  display: inline-flex; align-items: center; justify-content: center;
}
.pq-cover-cam:hover { background: rgba(0,0,0,0.82); }

.pq-more { background: transparent; border: 0; color: var(--rbpg-muted); font-weight: 600; font-size: 0.8rem; cursor: pointer; padding: 0.35rem 0; }
.pq-more:hover { color: var(--rbpg-text); }
.pq-more-body { margin-top: 0.3rem; }
.pq-kv--block { grid-template-columns: 1fr; gap: 0.15rem; }
.pq-kv--block .k { min-width: 0; }
.pq-kv--addr .v { display: block; }
.pq-addr { line-height: 1.35; }
.pq-add-addr { display: block; margin-left: auto; background: transparent; border: 1px dashed var(--rbpg-border); border-radius: 8px; color: var(--rbpg-text); font-size: 0.8rem; font-weight: 600; padding: 0.3rem 0.55rem; cursor: pointer; }
.pq-sup-empty { margin-bottom: 0.4rem; }
.pq-add-addr:hover { border-color: var(--rbpg-text); background: var(--rbpg-grey); }

/* Customer name → full customer page */
.pq-cust-link { color: var(--rbpg-text); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.pq-cust-link:hover { text-decoration-thickness: 2px; }

/* In-button busy spinner (approve/send/apply) */
.pq-btn.is-busy { pointer-events: none; opacity: 0.85; }
.pq-btn-spin { display: inline-block; width: 13px; height: 13px; border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%; animation: pq-spin 0.7s linear infinite; vertical-align: -2px; }

/* Feed avatars + AI tag (Slice D) */
.pq-avatar { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; overflow: hidden; flex: 0 0 auto; vertical-align: middle; }
.pq-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Slightly smaller + tighter so two initials never touch the circle edge. */
.pq-avatar--init { font-size: 0.5rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1; color: #fff; background: hsl(var(--h, 210), 42%, 46%); }
.pq-avatar[data-ai="1"] { box-shadow: 0 0 0 1.5px #0d0d0d; }
.pq-msg-foot .pq-avatar { margin-left: 0.15rem; }
.pq-chip-routed, .pq-chip-workshop { display: inline-flex; align-items: center; font-size: 0.65rem; font-weight: 600; color: #3f3f46; background: #f4f4f5; border: 1px solid #e4e4e7; border-radius: 4px; padding: 0 5px; height: 16px; margin-left: 0.25rem; white-space: nowrap; }
.pq-route-msg { font-size: 0.68rem; font-weight: 600; color: #3f3f46; background: transparent; border: 1px solid #e4e4e7; border-radius: 4px; padding: 0 6px; height: 18px; margin-left: 0.25rem; cursor: pointer; }
.pq-route-msg:hover { background: #f4f4f5; }
.pq-route-msg:disabled { opacity: .5; cursor: default; }
.pq-chip-ai { display: inline-flex; align-items: center; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.04em; color: #fff; background: #0d0d0d; border-radius: 4px; padding: 0 4px; height: 14px; margin-left: 0.15rem; }

/* AI typing indicator (drafting a reply) */
.pq-msg--typing { opacity: 0.9; }
.pq-bubble--typing { display: inline-flex; align-items: center; gap: 0.5rem; }
.pq-bubble--typing .pq-bubble-pad { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.7rem; }
.pq-typing { display: inline-flex; align-items: center; gap: 3px; }
.pq-typing span { width: 6px; height: 6px; border-radius: 50%; background: var(--rbpg-muted, #888); display: inline-block; animation: pq-typing-bounce 1.2s infinite ease-in-out; }
.pq-typing span:nth-child(2) { animation-delay: 0.18s; }
.pq-typing span:nth-child(3) { animation-delay: 0.36s; }
.pq-typing-txt { font-size: 0.76rem; color: var(--rbpg-muted, #777); }
@keyframes pq-typing-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.5; } 30% { transform: translateY(-3px); opacity: 1; } }

/* Quiet inbound — no letter. Sits on the thread / composer join. */
.pq-quiet {
  display: flex; align-items: center;
  padding: 0.42rem 0.9rem;
  border-top: 1px solid var(--rbpg-border);
  background: #f3f3f4;
  color: var(--rbpg-muted, #666);
  font-size: 0.8rem;
  line-height: 1.35;
}
.pq-quiet[hidden] { display: none !important; }

/* Composer lock — assistant owns the reply (prevents double-handling). */
.pq-ai-lock {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0.9rem; border-top: 1px solid var(--rbpg-border);
  background: #f6f6f7; color: var(--rbpg-muted, #666); font-size: 0.8rem;
}
.pq-ai-lock-dots { flex: 0 0 auto; }
.pq-ai-lock-txt { flex: 1 1 auto; }
.pq-ai-lock-take {
  flex: 0 0 auto; font-size: 0.76rem; font-weight: 600; cursor: pointer;
  color: #0d0d0d; background: #fff; border: 1px solid var(--rbpg-border);
  border-radius: 999px; padding: 0.18rem 0.7rem;
}
.pq-ai-lock-take:hover { border-color: var(--rbpg-text); }
.pq-ai-lock-take:disabled { opacity: 0.6; cursor: default; }
.pq-composer--ailock > textarea { background: #fafafa; color: var(--rbpg-muted, #999); }
.pq-craft-row { display: flex; align-items: center; padding: 0.28rem 0.7rem 0; }
.pq-craft-row[hidden] { display: none !important; }
.pq-craft-chip {
  display: inline-flex; align-items: center; gap: 0.22rem;
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.04em;
  background: var(--rbpg-text); color: #fff; border-radius: 5px; padding: 0.1rem 0.38rem 0.1rem 0.3rem;
  transform: translateY(-1px);
}
.pq-craft-ico { display: block; flex: none; width: 10px; height: 10px; }
.pq-composer--craft > textarea { background: #f7f8ff; }
.pq-composer--craft .pq-composer-bar { background: #f7f8ff; }
.pq-composer--tweak > textarea { background: #f4faf6; }
.pq-composer--tweak .pq-composer-bar { background: #f4faf6; }
.pq-composer--tweak .pq-craft-chip { background: #15803d; }
.pq-craft-tones {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 0.22rem;
  padding: 0;
}
.pq-craft-tones[hidden] { display: none !important; }
.pq-craft-tone {
  font-size: 0.66rem; line-height: 1.2; color: var(--rbpg-muted);
  background: transparent; border: 1px solid var(--rbpg-border);
  border-radius: 999px; padding: 0.1rem 0.4rem; cursor: pointer;
}
.pq-craft-tone:hover { color: var(--rbpg-text); border-color: var(--rbpg-text); }
.pq-craft-tone.is-on {
  color: #fff; background: var(--rbpg-text); border-color: var(--rbpg-text);
}
.pq-composer--tweak .pq-craft-tone.is-on { background: #15803d; border-color: #15803d; }

/* Message-center "AI working…" chip (assistant is drafting). */
.msg-chip--ai-working { color: #0d0d0d; background: #ececed; border: 1px solid #d9d9db; }

/* AIVERIE panel (P3-AIV-1) */
.pq-info-head { display: flex; align-items: center; gap: 0.5rem; }
.pq-info-head h4 { display: inline-flex; align-items: center; gap: 0.4rem; margin-bottom: 0.6rem; }
.pq-av .pq-info-head { justify-content: space-between; }
.pq-av-chip, .pq-av-tag { display: inline-flex; align-items: center; font-size: 0.68rem; color: var(--rbpg-muted); background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 999px; padding: 0.12rem 0.5rem; text-transform: uppercase; letter-spacing: 0.04em; }
.pq-av-chip { margin-bottom: 0.6rem; }
.pq-conf { display: inline-flex; align-items: center; font-size: 0.68rem; font-weight: 700; border-radius: 999px; padding: 0.1rem 0.44rem; letter-spacing: 0.02em; }
.pq-conf--hi { background: #123a20; color: #7ee2a0; }
.pq-conf--mid { background: #3a3312; color: #e6d27a; }
.pq-conf--lo { background: #3a1a12; color: #e89a7a; }
.pq-av-thumb { width: 64px; height: 64px; border-radius: 10px; overflow: hidden; background: var(--rbpg-grey); margin: 0 0 0.6rem; }
.pq-av-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pq-av-sub { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--rbpg-muted); font-weight: 600; margin: 0.7rem 0 0.4rem; }
/* Hairline-divided subsections inside the AIVERIE panel (mirror case sections). */
.pq-av-group + .pq-av-group { border-top: 1px solid var(--rbpg-border); margin-top: 0.9rem; padding-top: 0.9rem; }
.pq-av-group .pq-av-sub:first-child { margin-top: 0; }
.pq-av-sub--tight { margin-top: 0.6rem; }
.pq-av-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.pq-av-tag { text-transform: none; letter-spacing: 0; color: var(--rbpg-text); }
.pq-av-miss { font-size: 0.8rem; color: var(--rbpg-muted); margin-top: 0.6rem; line-height: 1.4; }
.pq-av-links { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 0.7rem; font-size: 0.82rem; }
.pq-av-links a { font-weight: 600; }
.pq-av-timeline { display: flex; flex-direction: column; gap: 0.3rem; }
.pq-av-tl { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; }
.pq-av-tl .t { color: var(--rbpg-text); flex: 1 1 auto; }
.pq-av-note { font-size: 0.85rem; color: var(--rbpg-text); line-height: 1.45; margin: 0 0 0.7rem; }
.pq-av-muted { font-size: 0.82rem; color: var(--rbpg-muted); }
/* SERIAL-1: "· 2 other cases" after the serial link. Not part of the link. */
.pq-serial-others { color: var(--rbpg-muted); white-space: nowrap; }
.pq-serial-check { display: block; margin-top: 0.15rem; font-size: 0.78rem; line-height: 1.35; color: var(--rbpg-muted); }
.pq-serial-check .pq-link-btn { font-size: 0.78rem; margin-left: 0.15rem; }
.pq-av-spin { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; color: var(--rbpg-muted); line-height: 1.4; }
.pq-av--empty { display: flex; flex-direction: column; min-height: 140px; }
.pq-spinner { width: 14px; height: 14px; border: 2px solid var(--rbpg-border); border-top-color: var(--rbpg-text); border-radius: 50%; animation: pq-spin 0.8s linear infinite; flex: 0 0 auto; }
@keyframes pq-spin { to { transform: rotate(360deg); } }
.pq-btn { background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 8px; color: var(--rbpg-text); font-size: 0.82rem; font-weight: 600; padding: 0.4rem 0.7rem; cursor: pointer; align-self: flex-start; }
.pq-btn:hover { border-color: var(--rbpg-text); }
.pq-btn--primary { background: var(--rbpg-text); color: var(--rbpg-bg, #0d0d0d); border-color: var(--rbpg-text); }
.pq-btn--primary:hover { opacity: 0.9; }
.pq-link-btn { background: transparent; border: 0; color: var(--rbpg-text); font-weight: 700; font-size: 0.8rem; cursor: pointer; padding: 0; text-decoration: underline; }
.pq-sub-dull { font-size: 0.76rem; color: var(--rbpg-muted); margin-bottom: 0.4rem; }

/* footer actions grouping */
.pq-actions-context { display: inline-flex; gap: 0.5rem; }
.pq-actions-btn .pq-nav-key, .pq-foot .pq-nav-key { opacity: 0.8; }

/* ---- overlays (stage modal + action palette) ---- */
.pq-overlay { position: fixed; inset: 0; z-index: 3000; background: rgba(15,15,15,0.4); display: flex; align-items: center; justify-content: center; padding: 1rem; }
.pq-overlay--bottom { align-items: flex-end; justify-content: center; padding-bottom: 82px; }
/* The workspace Actions palette aligns its centering region to the content area
   (right of the sidebar) so the card sits directly above the footer Actions
   button, not offset toward the whole-viewport center. */
#rbpg-actions.pq-overlay { left: 0; }
.pq-overlay-card { background: #fff; border-radius: 14px; box-shadow: 0 24px 60px rgba(0,0,0,0.28); width: 100%; max-width: 420px; display: flex; flex-direction: column; max-height: 78vh; }
.pq-overlay-card--mid { max-width: 500px; }
.pq-overlay-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 1rem 1.1rem 0.5rem; }
.pq-overlay-head h3 { font-size: 1.05rem; font-weight: 800; margin: 0; }
.pq-overlay-sub { font-size: 0.82rem; color: var(--rbpg-muted); margin: 0.15rem 0 0; }
.pq-overlay-x { background: transparent; border: 0; font-size: 1rem; color: var(--rbpg-muted); cursor: pointer; }

/* ---- AIVERIE run photo picker ---- */
.pq-av-pick-card { max-width: 680px; }
.pq-av-pick-body { overflow-y: auto; padding: 0.6rem 1.1rem 0.9rem; }
.pq-av-pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); gap: 0.55rem; }
.pq-av-pick { position: relative; padding: 0; margin: 0; border: 2px solid var(--rbpg-border); border-radius: 10px; overflow: hidden; background: var(--rbpg-grey); cursor: pointer; aspect-ratio: 1 / 1; }
.pq-av-pick img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0.5; transition: opacity 0.12s ease; }
.pq-av-pick.is-on { border-color: var(--rbpg-text); }
.pq-av-pick.is-on img { opacity: 1; }
.pq-av-pick-check { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; border-radius: 50%; background: var(--rbpg-text); color: #fff; display: none; align-items: center; justify-content: center; font-size: 0.78rem; }
.pq-av-pick.is-on .pq-av-pick-check { display: flex; }
.pq-av-pick-empty { color: var(--rbpg-muted); font-size: 0.88rem; line-height: 1.5; text-align: center; padding: 2rem 1rem; }
.pq-av-pick-foot { display: flex; align-items: center; gap: 0.8rem; padding: 0.8rem 1.1rem; border-top: 1px solid var(--rbpg-border); }
.pq-av-pick-foot .pq-btn { align-self: auto; }
.pq-av-pick-count { margin-left: auto; font-size: 0.8rem; color: var(--rbpg-muted); }
.pq-btn:disabled { opacity: 0.5; cursor: default; }

/* ---- Routing: the "Route to a vendor" modal (ROUTE-8) and the card in the feed (ROUTE-7). ----
   No design of its own: both are built from the AI draft card's classes (.pq-ai-card, -head, -badge, -agent, -cat,
   -conf, -summary, -label, -sec, -row, -row-t, -foot) and the shared buttons (.pq-btn, --sm, --primary). This block
   only adds what that card has no word for: the chips, the white best-match panel, and the modal's list. Monotone. */
.pq-rt-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.3rem; }
.pq-rt-chip { font-size: 0.72rem; border: 1px solid var(--rbpg-border); border-radius: 999px; padding: 0.05rem 0.45rem; color: var(--rbpg-muted); background: #fff; }
.pq-rt-chip.is-on { border-color: var(--rbpg-text); color: var(--rbpg-text); font-weight: 600; }
.pq-rt-chip.is-on::before { content: '\2713'; margin-right: 0.25em; font-weight: 800; }
.pq-rt-chip--case { background: #fff; color: var(--rbpg-text); }
.pq-rt-title, .pq-rc-name { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; min-width: 0; }
.pq-rt-meta, .pq-rc-meta { font-size: 0.8rem; color: var(--rbpg-muted); }
.pq-rt-gaps, .pq-rc-why { font-size: 0.76rem; color: var(--rbpg-muted); margin-top: 0.2rem; }
.pq-rt-warn { border-color: var(--rbpg-text); color: var(--rbpg-text); }
.pq-rt-badge { flex: 0 0 auto; font-size: 0.72rem; color: var(--rbpg-muted); white-space: nowrap; }
.pq-rt-badge.is-match { color: var(--rbpg-text); font-weight: 600; }
.pq-rt-badge.is-match::before { content: '\2713'; margin-right: 0.25em; font-weight: 800; }

/* The modal: the list is the draft card's dashed rows. */
.pq-rt-card { max-width: 600px; }
.pq-rt-item { font-size: 0.82rem; font-weight: 700; margin-top: 0.2rem; }
.pq-rt-item:empty { display: none; }
.pq-rt-search { padding: 0 1.1rem 0.5rem; }
.pq-rt-search input { width: 100%; box-sizing: border-box; border: 1px solid var(--rbpg-border); border-radius: 8px; padding: 0.45rem 0.65rem; font: inherit; font-size: 0.85rem; background: #fff; }
.pq-rt-search input:focus { outline: none; border-color: var(--rbpg-text); }
.pq-rt-body { overflow-y: auto; padding: 0.2rem 1.1rem 0.9rem; }
.pq-rt-row { padding: 0.55rem 0; }
.pq-rt-row[hidden] { display: none; }
.pq-rt-row.is-off .pq-ai-row-main { opacity: 0.55; }
.pq-rt-empty { color: var(--rbpg-muted); font-size: 0.85rem; text-align: center; padding: 1.4rem 0.5rem; }

/* The card in the feed: a .pq-ai-card. The best match sits in a white panel, like the draft's reply box. */
.pq-rc-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; }
.pq-rc-x { background: transparent; border: 0; padding: 0 0.1rem; margin-left: 0.1rem; font-size: 0.85rem; line-height: 1; color: var(--rbpg-muted); cursor: pointer; }
.pq-rc-x:hover { color: var(--rbpg-text); }
.pq-rc-add { font: inherit; font-size: 0.72rem; border: 1px dashed var(--rbpg-border); border-radius: 999px; padding: 0.05rem 0.4rem; background: #fff; color: var(--rbpg-muted); cursor: pointer; }
.pq-rc-add:hover { border-color: var(--rbpg-text); color: var(--rbpg-text); }
.pq-rc-best { border: 1px solid var(--rbpg-border); border-radius: 8px; background: #fff; padding: 0.6rem 0.7rem; display: flex; flex-direction: column; gap: 0.15rem; }
.pq-rc-name .pq-rc-best-badge { margin-left: auto; display: inline-flex; align-items: center; gap: 0.22rem; }
.pq-rc-alt[hidden] { display: none; }
.pq-rc-alt .pq-btn, .pq-rt-row .pq-btn { align-self: center; flex: 0 0 auto; }
.pq-rc-more { margin-top: 0.35rem; font-size: 0.78rem; }
.pq-rc-foot .pq-intake-done:disabled { opacity: 1; cursor: not-allowed; background: var(--rbpg-text); border-color: var(--rbpg-text); color: #fff; }

/* "Route & send in" | ▾ "Route only": the shared buttons joined, the menu a plain white list under them. */
.pq-split { position: relative; display: inline-flex; flex: 0 0 auto; align-self: center; }
.pq-split > .pq-btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.pq-split > .pq-split-caret { border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-color: #555555; padding-left: 0.4rem; padding-right: 0.4rem; }
.pq-split > .pq-btn:not(.pq-btn--primary).pq-split-caret { border-left-color: var(--rbpg-border); }
.pq-split-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 100%; display: flex; flex-direction: column; padding: 0.25rem; background: #fff; border: 1px solid var(--rbpg-border); border-radius: 8px; box-shadow: 0 6px 18px #00000024; }
.pq-split-menu[hidden] { display: none; }
.pq-split-item { background: transparent; border: 0; border-radius: 6px; padding: 0.35rem 0.6rem; font: inherit; font-size: 0.8rem; font-weight: 600; color: var(--rbpg-text); text-align: left; white-space: nowrap; cursor: pointer; }
.pq-split-item:hover, .pq-split-item:focus-visible { background: var(--rbpg-grey); outline: none; }
/* The routed-to line: the feed's pill with a small black badge (AUTOROUTE / APPROVED / MANUAL) and the why, muted. */
.pq-sys--route { flex-wrap: wrap; row-gap: 0.15rem; }
.pq-sys--route .pq-sys-text { color: var(--rbpg-text); }
.pq-sys-tag { font-size: 0.58rem; font-weight: 800; letter-spacing: 0.06em; background: var(--rbpg-text); color: #fff; border-radius: 4px; padding: 0.08rem 0.32rem; line-height: 1.3; }
.pq-sys-why { font-weight: 500; }
.pq-sys-why::before { content: '\00b7'; margin-right: 0.4rem; opacity: 0.6; }
/* ---- AIVERIE brand tag in the picker title ---- */
.pq-av-brand {
  font-size: 0.6rem; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--rbpg-muted); border: 1px solid var(--rbpg-border); border-radius: 4px;
  padding: 0.05rem 0.32rem; margin-left: 0.45rem; vertical-align: middle; position: relative; top: -1px;
}

/* ---- AIVERIE run mode card (AUTO-8): Basic (default) vs Full ---- */
/* Sits below the photo grid with even breathing room above and below. Monotone. */
.pq-av-mode {
  display: flex; align-items: center; gap: 0.9rem; margin: 0.85rem 1.1rem 0.95rem;
  padding: 0.55rem 0.7rem; border: 1px solid var(--rbpg-border); border-radius: 8px;
  background: #fafafa; cursor: pointer; user-select: none;
}
.pq-av-mode input { position: absolute; opacity: 0; width: 0; height: 0; }
.pq-av-mode-sw {
  flex: 0 0 auto; margin-left: auto; width: 28px; height: 16px; border-radius: 999px;
  background: var(--rbpg-border); position: relative; transition: background 0.15s ease;
}
.pq-av-mode-sw::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 1px rgba(0,0,0,0.2);
  transition: transform 0.15s ease;
}
.pq-av-mode input:checked + .pq-av-mode-sw { background: var(--rbpg-text); }
.pq-av-mode input:checked + .pq-av-mode-sw::after { transform: translateX(12px); }
.pq-av-mode input:focus-visible + .pq-av-mode-sw { outline: 2px solid var(--rbpg-text); outline-offset: 2px; }
.pq-av-mode-txt { display: flex; flex-direction: column; gap: 0.1rem; line-height: 1.3; }
.pq-av-mode-txt strong { font-size: 0.82rem; }
.pq-av-mode-txt span { font-size: 0.73rem; color: var(--rbpg-muted); }
/* Fixed width so the label flip (Run basic ⇄ Run full) never shifts the layout. */
#pq-av-pick-run { min-width: 104px; text-align: center; }

/* ---- Upgrade banner (basic -> full) shown above the facts ---- */
.pq-av-upgrade {
  display: flex; align-items: center; gap: 0.8rem; margin-bottom: 0.7rem;
  padding: 0.6rem 0.75rem; border: 1px solid var(--rbpg-border); border-radius: 10px;
  background: linear-gradient(0deg, #faf7ff, #fbfbfb);
}
.pq-av-upgrade-txt { display: flex; flex-direction: column; gap: 0.1rem; line-height: 1.3; }
.pq-av-upgrade-txt strong { font-size: 0.82rem; }
.pq-av-upgrade-txt span { font-size: 0.74rem; color: var(--rbpg-muted); }
.pq-av-upgrade .pq-btn { margin-left: auto; }
.pq-av-chip--depth { color: var(--rbpg-text); background: #eef6ef; border-color: #cfe6d2; }
.pq-av-cust { font-size: 0.74rem; color: var(--rbpg-muted); margin: -0.15rem 0 0.5rem; font-style: italic; }
.pq-av-actions { margin-top: 0.7rem; display: flex; justify-content: flex-start; }

/* ---- AIVERIE per-photo view badges in the file gallery ---- */
.pq-file-views { position: absolute; top: 6px; left: 6px; display: flex; flex-wrap: wrap; gap: 3px; pointer-events: none; z-index: 2; }
.pq-file-view {
  font-size: 0.6rem; font-weight: 600; letter-spacing: 0.02em; line-height: 1;
  padding: 0.18rem 0.34rem; border-radius: 4px; color: #fff;
  background: rgba(20,20,20,0.72); backdrop-filter: blur(2px);
}
.pq-file-view--warn { background: rgba(203,32,39,0.85); }

/* ---- AI suggestion card (in-thread) ---- */
.pq-ai-card {
  margin: 0.6rem 0 0.2rem; padding: 0.85rem 0.95rem; border: 1px solid var(--rbpg-border);
  border-left: 3px solid var(--rbpg-text); border-radius: 12px; background: #fbfbfb;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.pq-ai-head { display: flex; align-items: center; gap: 0.5rem; }
.pq-ai-badge { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.06em; background: var(--rbpg-text); color: #fff; border-radius: 5px; padding: 0.1rem 0.34rem; }
.pq-ai-agent { font-size: 0.82rem; font-weight: 700; }
.pq-ai-voice {
  display: inline-flex; align-items: center; gap: 0.22rem;
  font-size: 0.68rem; font-weight: 500; color: var(--rbpg-muted);
  letter-spacing: 0.01em;
}
.pq-ai-voice-ico { width: 11px; height: 11px; flex: 0 0 auto; opacity: 0.75; }
.pq-ai-cat { font-size: 0.72rem; color: var(--rbpg-muted); text-transform: capitalize; }
.pq-ai-head-right { margin-left: auto; display: flex; align-items: center; gap: 0.4rem; }
.pq-ai-conf { font-size: 0.72rem; color: var(--rbpg-muted); border: 1px solid var(--rbpg-border); border-radius: 999px; padding: 0.05rem 0.45rem; }
/* Customer sentiment chip in the AI card header — emoji + label, colour by tier.
   Tight vertical padding so the emoji can be larger without inflating the chip. */
/* Flat, borderless pastel pills. Colour maps to valence (green=positive,
   amber=caution, red=negative); the neutral baseline stays a calm slate so the
   eye is only drawn to tones that actually need attention. */
.pq-ai-tone { display: inline-flex; align-items: center; gap: 4px; font-size: 0.68rem; font-weight: 600; border-radius: 999px; padding: 0.06rem 0.46rem 0.06rem 0.36rem; border: none; }
.pq-ai-tone-emo { font-size: 1.25em; line-height: 1; }
.pq-ai-tone > :not(.pq-ai-tone-emo) { margin-right: 1px; }
.pq-ai-tone--pos  { background: #d1fadf; color: #05603a; }
.pq-ai-tone--warn { background: #fdf1c7; color: #8a5a00; }
.pq-ai-tone--bad  { background: #fdd8d8; color: #a81f1f; }
.pq-ai-tone--neutral { background: #eef1f6; color: #5b6675; }

/* Admin re-run: a quiet, muted test-tool button (left of Dismiss).
   Rewrite as me is a real choice — it stays the default sm button. */
.pq-ai-rerun { color: var(--rbpg-muted); }
.pq-ai-rerun:hover { color: var(--rbpg-text); }

/* Sentiment as a status pill on the right of the name row (a health signal, not
   a data field). Name may wrap/truncate; the pill holds the top-right. */
.pq-info-title--mood { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.pq-info-title--mood .pq-title-text { min-width: 0; overflow-wrap: anywhere; }
.pq-info-title--mood .pq-ai-tone { flex: 0 0 auto; margin-top: 1px; }
.pq-ai-summary { font-size: 0.82rem; color: var(--rbpg-text); margin: 0.5rem 0 0.2rem; line-height: 1.4; }
.pq-ai-stale {
  margin: 0.55rem 0 0.15rem; padding: 0.55rem 0.7rem;
  border-radius: 8px; background: #fff8e6; border: 1px solid #f0d48a;
  color: #6f5a1f; font-size: 0.8rem; line-height: 1.4;
}
.pq-ai-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); margin: 0.6rem 0 0.25rem; }
.pq-ai-reply {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 90px;
  border: 1px solid var(--rbpg-border); border-radius: 8px; padding: 0.55rem 0.65rem;
  font: inherit; font-size: 0.85rem; line-height: 1.45; color: var(--rbpg-text); background: #fff;
}
.pq-ai-reply:focus { outline: none; border-color: var(--rbpg-text); }
.pq-ai-letter {
  max-height: 22rem; overflow: auto; border: 1px solid var(--rbpg-border);
  border-radius: 8px; padding: 0.7rem 0.8rem; background: #fff; font-size: 0.85rem;
}
.pq-ai-actions { margin-top: 0.6rem; border-top: 1px solid var(--rbpg-border); padding-top: 0.55rem; }
.pq-ai-actions-h { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); margin-bottom: 0.35rem; }
.pq-ai-act { display: flex; align-items: center; gap: 0.45rem; font-size: 0.82rem; padding: 0.15rem 0; cursor: pointer; }
.pq-ai-act-conf { color: var(--rbpg-muted); font-size: 0.72rem; }
.pq-ai-foot { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.7rem; }
.pq-ai-spacer { flex: 1; }

/* ---- AI card: detected-updates + actions rows ---- */
.pq-ai-sec { margin-top: 0.7rem; border-top: 1px solid var(--rbpg-border); padding-top: 0.55rem; }
.pq-ai-sec-h { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); margin-bottom: 0.4rem; }

/* Internal-only "why this reply" brief panel (doc 35) — admin, collapsed */
.pq-ai-brief { margin-top: 0.6rem; border-top: 1px dashed var(--rbpg-border); padding-top: 0.5rem; }
.pq-ai-brief > summary { cursor: pointer; font-size: 0.7rem; color: var(--rbpg-muted); letter-spacing: 0.03em; list-style: none; }
.pq-ai-brief > summary::-webkit-details-marker { display: none; }
.pq-ai-brief > summary::before { content: '\25B8'; display: inline-block; margin-right: 0.3rem; transition: transform 0.15s; }
.pq-ai-brief[open] > summary::before { transform: rotate(90deg); }
.pq-brief-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.45rem 0 0.35rem; }
.pq-brief-chip { font-size: 0.62rem; padding: 0.05rem 0.35rem; border-radius: 999px; background: rgba(0,0,0,0.06); color: var(--rbpg-muted); }
.pq-brief-chip--warn { background: rgba(180,83,9,0.12); color: #b45309; }
.pq-brief-chip--esc { background: #0d0d0d; color: #fff; }
.pq-brief-list { list-style: none; margin: 0.2rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.pq-brief-list li { display: flex; align-items: flex-start; gap: 0.4rem; font-size: 0.76rem; color: var(--rbpg-text); line-height: 1.35; }
.pq-brief-tag { flex: 0 0 auto; font-size: 0.56rem; font-weight: 700; letter-spacing: 0.04em; padding: 0.05rem 0.28rem; border-radius: 4px; margin-top: 0.08rem; color: #fff; }
.pq-brief-tag--say { background: #2563eb; }
.pq-brief-tag--ask { background: #7c3aed; }

.pq-ai-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.35rem 0; }
.pq-ai-row + .pq-ai-row { border-top: 1px dashed var(--rbpg-border); }

/* Footer the model is told not to write — shown so Send is not a surprise. */
.pq-ai-sig {
  margin-top: 0.15rem; padding: 0.4rem 0.7rem 0.5rem;
  border: 1px solid var(--rbpg-border); border-top: 0;
  border-radius: 0 0 10px 10px; background: #f7f8fa;
}
.pq-ai-sig-h { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--rbpg-muted); margin-bottom: 0.2rem; }
.pq-ai-sig-body { white-space: pre-line; font-size: 0.78rem; line-height: 1.4; color: #5b6675; }
.pq-ai-attach { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.4rem; padding: 0.1rem 0 0.2rem; }

/* Operational actions: one card pattern for every similar action.
   The shared `.pq-btn` pins itself to the top (`align-self: flex-start`);
   these override that so the confirm sits vertically in the middle. */
.pq-ai-actcard {
  display: flex; align-items: center; gap: 0.65rem;
  margin-top: 0.4rem; padding: 0.55rem 0.7rem;
  border-radius: 10px; border: 1px solid #e5e7eb; background: #f3f4f6;
}
.pq-ai-actcard .pq-btn,
.pq-ai-actcard .pq-ai-done {
  align-self: center;
  flex: 0 0 auto;
  margin-left: auto;
}
.pq-ai-actcard .pq-btn {
  display: inline-flex; align-items: center; gap: 0.3rem;
}
.pq-ai-act-ico { font-size: 0.85em; font-weight: 800; line-height: 1; }
.pq-ai-act-thumb { width: 44px; height: 44px; border-radius: 6px; object-fit: cover; background: #e5e7eb; flex: 0 0 auto; }
.pq-ai-actcard--ok { background: #e8f8ee; border-color: #b7e4c7; }
.pq-ai-actcard--warn { background: #fff8e6; border-color: #f0d48a; }
.pq-btn--ok { background: #16a34a; border-color: #16a34a; color: #fff; }
.pq-btn--ok:hover { background: #15803d; border-color: #15803d; color: #fff; }
.pq-ai-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.pq-ai-row-t { font-size: 0.83rem; font-weight: 600; color: var(--rbpg-text); }
.pq-ai-row-v { font-size: 0.8rem; color: var(--rbpg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-ai-done { font-size: 0.8rem; color: #16a34a; font-weight: 600; white-space: nowrap; }
.pq-btn--sm { padding: 0.28rem 0.6rem; font-size: 0.78rem; white-space: nowrap; }

/* ---- Simulate inbound modal ---- */
.pq-sim-body { padding: 0.8rem 1.1rem; }
.pq-sim-body textarea {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 96px;
  border: 1px solid var(--rbpg-border); border-radius: 8px; padding: 0.6rem 0.7rem;
  font: inherit; font-size: 0.9rem; line-height: 1.45; color: var(--rbpg-text);
}
.pq-sim-body textarea:focus { outline: none; border-color: var(--rbpg-text); }

/* ---- AI entity blips (in-thread, doc 34) ---- */
.pq-ent {
  cursor: pointer; border-radius: 3px; padding: 0 1px;
  text-decoration: underline dotted; text-underline-offset: 2px;
  text-decoration-thickness: 1.5px; text-decoration-color: #6366f1;
  background: rgba(99, 102, 241, 0.08); transition: background 0.12s ease;
}
.pq-ent:hover { background: rgba(99, 102, 241, 0.18); }
.pq-ent--phone { text-decoration-color: #0891b2; background: rgba(8, 145, 178, 0.08); }
.pq-ent--phone:hover { background: rgba(8, 145, 178, 0.18); }
/* What the customer said about the watch itself: make, model, reference, serial (FLOW-9). */
.pq-ent--identity { text-decoration-color: #db2777; background: rgba(219, 39, 119, 0.08); }
.pq-ent--identity:hover { background: rgba(219, 39, 119, 0.18); }
.pq-ent.is-confirm { text-decoration-color: #d97706; background: rgba(217, 119, 6, 0.1); }
.pq-ent.is-confirm:hover { background: rgba(217, 119, 6, 0.2); }
.pq-ent.is-applied {
  text-decoration-color: #16a34a; background: rgba(22, 163, 74, 0.08); cursor: default;
}
.pq-msg--out .pq-ent { text-decoration-color: rgba(255,255,255,0.7); background: rgba(255,255,255,0.14); }

/* ---- AI entity compare modal ---- */
.pq-ent-body { padding: 0.8rem 1.1rem; }
.pq-ent-cmp { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
.pq-ent-col {
  border: 1px solid var(--rbpg-border); border-radius: 10px; padding: 0.6rem 0.7rem; background: #fbfbfb;
}
.pq-ent-col--new { border-color: #6366f1; background: rgba(99, 102, 241, 0.05); }
.pq-ent-h { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); margin-bottom: 0.3rem; }
.pq-ent-val { font-size: 0.86rem; line-height: 1.45; color: var(--rbpg-text); }
.pq-ent-none { color: var(--rbpg-muted); font-style: italic; }

/* ---- AIVERIE suggested details (P3-AIV-2) ----
   One row per detail, and the two values ARE the control: two cards, pick one. A
   tickbox beside two panels asked the question twice — the panels showed the choice,
   then a checkbox elsewhere decided it. Radio inputs underneath, so arrow keys work
   and the thing is one question with two answers. Shared by the cockpit and the
   estimate builder through lib/rbpg-fact-suggest.js. */
.pq-sug-body { padding: 0.4rem 1.1rem 0.8rem; overflow-y: auto; }
.pq-sug-row { padding: 0.75rem 0; border-bottom: 1px solid var(--rbpg-border); }
.pq-sug-row:last-child { border-bottom: 0; }
.pq-sug-label { font-size: 0.86rem; font-weight: 700; margin-bottom: 0.4rem; }
.pq-sug-cmp { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
.pq-sug-card {
  display: block; border: 1px solid var(--rbpg-border); border-radius: 10px;
  padding: 0.45rem 0.6rem 0.55rem; background: #fff; min-width: 0; cursor: pointer;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.pq-sug-card:hover { border-color: #b8b8b8; }
/* Chosen: a second inner line rather than a fill, so the value stays the most
   legible thing in the card and no tinted background is needed to say "selected". */
.pq-sug-card.is-on { border-color: var(--rbpg-text); box-shadow: inset 0 0 0 1px var(--rbpg-text); }
.pq-sug-h {
  display: flex; align-items: center; gap: 0.35rem; font-size: 0.66rem;
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); margin-bottom: 0.2rem;
}
.pq-sug-card.is-on .pq-sug-h { color: var(--rbpg-text); }
.pq-sug-h input[type="radio"] { width: 13px; height: 13px; margin: 0; accent-color: var(--rbpg-text); cursor: pointer; }
.pq-sug-val { display: block; font-size: 0.86rem; line-height: 1.4; word-break: break-word; }
.pq-sug-held { font-size: 0.74rem; font-weight: 500; color: var(--rbpg-muted); }
.pq-sug-input {
  display: block; width: 100%; border: 0; padding: 0; background: transparent; font: inherit;
  font-size: 0.86rem; line-height: 1.4; color: var(--rbpg-text); outline: none;
  resize: none; overflow: hidden;
}
.pq-sug-input:focus { box-shadow: 0 1px 0 0 var(--rbpg-text); }
/* Already dealt with, still shown — dimmer, because it is here to be recoverable
   rather than to be asked again. */
.pq-sug-row.is-set-aside { opacity: 0.72; }
.pq-sug-row.is-set-aside:hover, .pq-sug-row.is-set-aside:focus-within { opacity: 1; }
/* Notes under a label. Grey, not amber: a caveat about the evidence is information,
   and washing the row in colour made it look like a fault. */
.pq-sug-note { margin: 0 0 0.4rem; font-size: 0.76rem; line-height: 1.45; color: var(--rbpg-muted); }
.pq-sug-note--care { color: #4a4a4a; font-weight: 600; }
.pq-sug-none { margin-top: 0.45rem; font-size: 0.78rem; }
/* A write that failed says so next to the button that failed, since there is no
   toast to carry it. It takes the slack in the row rather than squeezing the
   buttons, which otherwise wrap their labels to make room for the bad news. */
.pq-sug-err { flex: 1 1 auto; min-width: 0; font-size: 0.76rem; line-height: 1.35; color: #9d1c1c; align-self: center; }
.pq-sug-body ~ .pq-av-pick-foot .pq-btn { white-space: nowrap; }
/* The permanent way back in, in the AIVERIE panel, after a banner is dismissed. */
.pq-av-upgrade--sug { border-style: solid; }
@media (max-width: 560px) {
  .pq-sug-cmp { grid-template-columns: 1fr; }
}
.pq-ent-e164 { color: var(--rbpg-muted); font-size: 0.78rem; }

/* Phone: mobile/landline segmented toggle + SMS hint */
.pq-phone-kind { display: flex; align-items: center; flex-wrap: wrap; gap: 0.55rem; margin-top: 0.85rem; }
.pq-phone-kind-lbl { font-size: 0.8rem; color: var(--rbpg-muted); }
.pq-seg { display: inline-flex; border: 1px solid var(--rbpg-border); border-radius: 8px; overflow: hidden; }
.pq-seg-btn {
  border: 0; background: #fff; color: var(--rbpg-text); cursor: pointer;
  font-size: 0.8rem; padding: 0.32rem 0.7rem; line-height: 1;
}
.pq-seg-btn + .pq-seg-btn { border-left: 1px solid var(--rbpg-border); }
.pq-seg-btn.is-on { background: #0d0d0d; color: #fff; }
.pq-phone-sms { flex-basis: 100%; font-size: 0.76rem; margin-top: 0.15rem; }
.pq-phone-sms.is-ok { color: #15803d; }
.pq-phone-sms.is-warn { color: #b45309; }
.pq-phone-sms.is-muted { color: var(--rbpg-muted); }

.pq-stage-list { overflow-y: auto; padding: 0.5rem 0.7rem 0.9rem; }
.pq-stage-item {
  display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left; cursor: pointer;
  background: transparent; border: 1px solid transparent; border-radius: 10px; padding: 0.6rem 0.7rem; margin-bottom: 0.2rem;
}
.pq-stage-item:hover, .pq-stage-item:focus-visible { background: var(--rbpg-grey); outline: none; }
.pq-stage-item.current { border-color: var(--rbpg-text); background: #fff; }
.pq-stage-item-main { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.pq-stage-item-label { font-weight: 700; font-size: 0.92rem; }
.pq-stage-item-meta { font-size: 0.72rem; color: var(--rbpg-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pq-stage-count { background: var(--rbpg-grey); border-radius: 999px; font-size: 0.75rem; font-weight: 700; padding: 0.1rem 0.5rem; color: var(--rbpg-muted); }
.pq-stage-here { font-size: 0.68rem; font-weight: 800; text-transform: uppercase; color: #dc2626; }

.pq-palette-card { background: #fff; border-radius: 14px; box-shadow: 0 24px 60px rgba(0,0,0,0.3); width: 100%; max-width: 520px; display: flex; flex-direction: column; overflow: hidden; position: relative; }
/* Busy overlay: shown while an async action (e.g. status change) is in flight, so
   the palette acknowledges the click instead of vanishing instantly. */
.pq-palette-busy { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 0.6rem; background: rgba(255,255,255,0.82); backdrop-filter: blur(1px); font-size: 0.9rem; font-weight: 700; color: var(--rbpg-text); }
.pq-palette-spin { width: 18px; height: 18px; border: 2px solid var(--rbpg-border); border-top-color: var(--rbpg-text); border-radius: 50%; animation: pq-palette-spin 0.7s linear infinite; }
@keyframes pq-palette-spin { to { transform: rotate(360deg); } }
.pq-palette-input { border: 0; border-bottom: 1px solid var(--rbpg-border); padding: 0.85rem 1rem; font-size: 0.95rem; outline: none; }
.pq-palette-list { max-height: 320px; overflow-y: auto; overscroll-behavior: contain; padding: 0.4rem; }
.pq-palette-item { display: flex; align-items: center; gap: 0.7rem; width: 100%; text-align: left; cursor: pointer; background: transparent; border: 0; border-radius: 8px; padding: 0.6rem 0.7rem; font-size: 0.9rem; }
.pq-palette-item.sel { background: var(--rbpg-text); color: #fff; }
.pq-palette-ico { width: 20px; flex: 0 0 auto; text-align: center; }
/* An inline-SVG icon (`iconHtml`) inherits the row's colour, so it flips to white
   with the selected row instead of staying dark on dark like an emoji does. */
.pq-palette-ico svg { display: block; margin: 0 auto; color: inherit; }
.pq-palette-empty { color: var(--rbpg-muted); font-size: 0.88rem; padding: 1rem; text-align: center; }
/* A view fetching its rows. The spinner sits with the word rather than replacing
   the card, because the palette is still usable while it loads. */
.pq-palette-loading { display: flex; align-items: center; justify-content: center; gap: 0.5rem; }
.pq-palette-foot { border-top: 1px solid var(--rbpg-border); padding: 0.45rem 1rem; font-size: 0.72rem; color: var(--rbpg-muted); }
.pq-palette-group { padding: 0.55rem 0.7rem 0.25rem; font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); }
.pq-palette-text { display: flex; flex-direction: column; min-width: 0; }
.pq-palette-label { line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-palette-sub { font-size: 0.76rem; color: var(--rbpg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-palette-item.sel .pq-palette-sub { color: rgba(255,255,255,0.72); }
/* Paged palette: header breadcrumb + back, and the "opens a sub-view" chevron. */
.pq-palette-head { display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.85rem 0; }
.pq-palette-back { border: 0; background: transparent; cursor: pointer; font-size: 1.2rem; line-height: 1; color: var(--rbpg-muted); padding: 0.1rem 0.45rem; border-radius: 7px; }
.pq-palette-back:hover { background: var(--rbpg-surface-2, #f4f4f5); color: var(--rbpg-text); }
.pq-palette-crumb { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--rbpg-muted); }
.pq-palette-more { margin-left: auto; color: var(--rbpg-muted); font-size: 1rem; line-height: 1; }
.pq-palette-item.sel .pq-palette-more { color: rgba(255,255,255,0.72); }
.pq-picker-title { padding: 0.7rem 1rem 0; font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rbpg-muted); }

/* Footer */
.pq-foot {
  display: flex; align-items: center; gap: 1rem;
  height: 66px; padding: 0 1.1rem;
  background: var(--rbpg-surface); border-top: 1px solid var(--rbpg-border);
}
.pq-foot .pq-actions { margin: 0 auto; display: flex; gap: 0.6rem; align-items: center; }
.pq-nav-key { font-size: 0.68rem; color: var(--rbpg-muted); margin-left: 0.35rem; }

/* ---- right sidebar tabs (Case | Files) ---- */
.pq-info { padding: 0; display: flex; flex-direction: column; min-width: 0; overflow-x: hidden; }
.pq-tabs { position: sticky; top: 0; z-index: 5; display: flex; align-items: stretch; flex: 0 0 auto; min-width: 0; background: var(--rbpg-surface); border-bottom: 1px solid var(--rbpg-border); padding: 0 0.5rem; }
.pq-tab { flex: 0 1 auto; min-width: 0; background: transparent; border: 0; border-bottom: 2px solid transparent; padding: 0.8rem 0.5rem; font-size: 0.8rem; font-weight: 700; color: var(--rbpg-muted); cursor: pointer; text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; }
.pq-tab:hover { color: var(--rbpg-text); }
.pq-tab.active { color: var(--rbpg-text); border-bottom-color: var(--rbpg-text); }
.pq-tab-count { color: var(--rbpg-muted); font-weight: 600; letter-spacing: 0; }
.pq-tab-add { margin-left: auto; align-self: center; width: 28px; height: 28px; border-radius: 7px; border: 1px solid var(--rbpg-border); background: var(--rbpg-grey); color: var(--rbpg-muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.pq-tab-add:hover { border-color: var(--rbpg-text); color: var(--rbpg-text); }
.pq-tab-add svg { display: block; }
.pq-tab-panel { padding: 1.1rem; flex: 1 1 auto; min-height: 0; min-width: 0; }
#pq-panel-files { display: flex; flex-direction: column; }
/* A panel that shrinks to the column lets its content overflow past its own bottom padding. */
#pq-panel-case, #pq-panel-aiverie, #pq-panel-reports { flex-shrink: 0; padding-bottom: 2rem; }

/* ---- QC: the reports tab, and the timeline card (QC epic) ----
   Here rather than in qc.css because these two render on the case cockpit and
   the estimate builder, which do not load the bench view's stylesheet. Built
   from the existing .pq- vocabulary — no new buttons, no new colours. */
.qc-list { display: flex; flex-direction: column; gap: 0.5rem; }
.qc-list-row {
  display: flex; align-items: flex-start; gap: 0.6rem; width: 100%;
  padding: 0.6rem 0; border: 0; border-bottom: 1px solid var(--rbpg-border);
  background: transparent; text-align: left; cursor: pointer;
  color: inherit; text-decoration: none;
}
.qc-list-row:last-child { border-bottom: 0; }
.qc-list-row:hover .qc-list-title { text-decoration: underline; }
.qc-card {
  display: flex; align-items: flex-start; gap: 0.35rem;
  padding: 0.65rem 0.7rem; border: 1px solid var(--rbpg-border);
  border-radius: 10px; background: var(--rbpg-surface);
}
.qc-card-main {
  display: flex; align-items: flex-start; gap: 0.6rem; flex: 1; min-width: 0;
  padding: 0; border: 0; background: transparent; text-align: left;
  cursor: pointer; color: inherit;
}
.qc-card-main:hover .qc-list-title { text-decoration: underline; }
.qc-card-menu { flex: 0 0 auto; margin-left: auto; align-self: flex-start; }
.qc-card-menu .dropdown-item {
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.28rem 0.75rem;
}
.qc-card--open .qc-list-title { color: #b45309; }
.qc-list-text { display: flex; flex-direction: column; min-width: 0; }
.qc-list-title { font-size: 0.85rem; font-weight: 700; }
.qc-list-sub { font-size: 0.75rem; color: var(--rbpg-muted); }
/* The dot is the whole status language in the rail: four states, no text needed
   until you read the line under it. */
.qc-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 999px; margin-top: 0.32rem; background: #16a34a; }
.qc-dot--warning { background: #f59e0b; }
.qc-dot--alert { background: #dc2626; }
.qc-dot--skipped { background: var(--rbpg-muted); }
/* Unfinished, and the two ways of being unfinished: hollow for a draft somebody
   is part-way through, amber for one deliberately left open. */
.qc-dot--open { background: transparent; box-shadow: inset 0 0 0 2px var(--rbpg-muted); }
.qc-dot--parked { background: #f59e0b; }
.qc-list-row--open .qc-list-title { color: #b45309; }
.qc-list-go {
  margin-left: auto; align-self: center; flex: 0 0 auto;
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: #b45309;
}
.qcq-verdict { display: inline-flex; align-items: center; gap: .45rem; font-weight: 600; font-size: .85rem; }
.qcq-verdict .qc-dot { margin-top: 0; }

/* Hold on the thread: a small card, not a QC report. Who / when / why, and
   the matching take-off. No pill, no resume. */
.pq-hold-card {
  align-self: flex-start;
  flex: 0 0 auto;
  max-width: 460px;
  margin: 0.5rem 0;
  padding: 0.7rem 0.9rem;
  background: var(--rbpg-surface);
  border: 1px solid var(--rbpg-border);
  border-left: 3px solid #3f3f46;
  border-radius: 10px;
}
.pq-hold-card--off { border-left-color: var(--rbpg-muted); }
.pq-hold-card-title { font-size: 0.85rem; font-weight: 800; }

/* Website enquiry at the top of the thread (INTAKE-1). Sibling of hold / QC —
   same card family, no Pass pill, no View report. */
.pq-intake {
  align-self: flex-start;
  flex: 0 0 auto;
  max-width: 460px;
  margin: 0.5rem 0;
  padding: 0.7rem 0.9rem;
  background: var(--rbpg-surface);
  border: 1px solid var(--rbpg-border);
  border-left: 3px solid #2563eb;
  border-radius: 10px;
}
.pq-intake-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.pq-intake-title { font-size: 0.85rem; font-weight: 800; }
.pq-intake-pill {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--rbpg-muted);
}
.pq-intake-block { margin-top: 0.55rem; }
.pq-intake-sub {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--rbpg-muted); margin-bottom: 0.25rem;
}
.pq-intake .pq-kv { font-size: 0.78rem; }
.pq-intake-meta {
  font-size: 0.72rem; color: var(--rbpg-muted); margin-top: 0.45rem;
}
.pq-intake-acts { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.pq-intake-acts .pq-btn:disabled { cursor: not-allowed; }
.pq-intake-acts .pq-btn:disabled:not(.pq-intake-done) { opacity: 0.5; }
.pq-intake-acts .pq-btn:disabled:not(.pq-intake-done):hover { border-color: var(--rbpg-border); }
.pq-intake-acts .pq-intake-done:disabled { opacity: 1; background: var(--rbpg-text); border-color: var(--rbpg-text); color: #fff; }
/* ---------------------------------------------------------------------------
   MULTI-4 — the split screen (`rbpg-split-screen.js`, inside `rbpg-modal--full`).

   Watches on the left, every photo on the right, nothing pre-assigned. Only the two columns scroll, so the
   footer's "n photos not placed stay on Watch 1" never slides out of view while somebody is placing them.

   The drag type is `text/pq-msplit`, not `text/pq-att`: the Files tab and the composer accept that one, and a
   photo dropped on the composer mid-split would be sent to the customer.
--------------------------------------------------------------------------- */
.pq-msplit { display: grid; grid-template-columns: minmax(0, 1fr) 300px; height: 100%; min-height: 0; }
.pq-msplit-left, .pq-msplit-right { overflow-y: auto; min-height: 0; padding: 1rem 1.1rem; }
.pq-msplit-right { border-left: 1px solid var(--rbpg-border); background: var(--rbpg-grey); }
@media (max-width: 900px) {
  .pq-msplit { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }
  .pq-msplit-right { border-left: 0; border-top: 1px solid var(--rbpg-border); }
}

.pq-msplit-said { margin-bottom: 0.9rem; }
.pq-msplit-sub { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rbpg-muted); }
.pq-msplit-saidbody {
  font-size: 0.82rem; white-space: pre-wrap; color: var(--rbpg-text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pq-msplit-saidbody.is-open { display: block; overflow: visible; }
.pq-msplit-link {
  background: none; border: 0; padding: 0; font-size: 0.76rem; font-weight: 600;
  color: var(--rbpg-muted); text-decoration: underline; cursor: pointer;
}
.pq-msplit-link:hover { color: var(--rbpg-text); }

.pq-msplit-rows { display: flex; flex-direction: column; gap: 0.75rem; }
.pq-msplit-note { font-size: 0.78rem; color: var(--rbpg-text); background: #fef9c3; border-radius: 8px; padding: 0.45rem 0.6rem; margin: 0; }
.pq-msplit-row { border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius-lg); padding: 0.75rem; }
.pq-msplit-rowhead { display: flex; align-items: center; justify-content: space-between; font-size: 0.82rem; margin-bottom: 0.55rem; }
.pq-msplit-x { background: none; border: 0; font-size: 1.1rem; line-height: 1; color: var(--rbpg-muted); cursor: pointer; }
.pq-msplit-x:hover { color: var(--rbpg-text); }
.pq-msplit-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.pq-msplit-f { display: block; margin-bottom: 0.5rem; }
.pq-msplit-fl { display: flex; align-items: center; gap: 0.35rem; font-size: 0.72rem; font-weight: 600; color: var(--rbpg-muted); margin-bottom: 0.2rem; }
.pq-msplit-f.is-unsure input, .pq-msplit-f.is-unsure textarea { border-color: #d97706; }
.pq-msplit-check { font-style: normal; font-size: 0.68rem; font-weight: 700; color: #b45309; }
.pq-msplit-ai {
  font-size: 0.6rem; font-weight: 700; letter-spacing: 0.04em; padding: 0.05rem 0.25rem;
  border: 1px solid var(--rbpg-border); border-radius: 4px; color: var(--rbpg-muted);
}
.pq-msplit-add {
  align-self: flex-start; background: none; border: 1px dashed var(--rbpg-border); border-radius: 8px;
  padding: 0.4rem 0.7rem; font-size: 0.8rem; font-weight: 600; color: var(--rbpg-muted); cursor: pointer;
}
.pq-msplit-add:hover { border-color: var(--rbpg-text); color: var(--rbpg-text); }
.pq-msplit-wait { display: flex; align-items: center; gap: 0.5rem; font-size: 0.82rem; color: var(--rbpg-muted); }
.pq-msplit-ghost { height: 150px; border-radius: var(--rbpg-radius-lg); background: var(--rbpg-grey); }

.pq-msplit-trayhead { display: flex; flex-direction: column; gap: 0.1rem; font-size: 0.8rem; margin-bottom: 0.6rem; }
.pq-msplit-trayhead .pq-av-muted { font-size: 0.72rem; }
.pq-msplit-tray, .pq-msplit-photos {
  display: flex; flex-wrap: wrap; gap: 0.5rem; min-height: 76px;
  border: 1px dashed var(--rbpg-border); border-radius: var(--rbpg-radius-lg); padding: 0.45rem;
}
.pq-msplit-tray.is-over, .pq-msplit-photos.is-over { border-color: var(--rbpg-text); background: #fff; }
.pq-msplit-photos { background: #fff; margin-top: 0.15rem; }
.pq-msplit-empty { font-size: 0.74rem; color: var(--rbpg-muted); align-self: center; padding: 0 0.3rem; }
.pq-msplit-tile { position: relative; width: 72px; cursor: grab; }
.pq-msplit-tile.is-all { outline: 2px solid var(--rbpg-text); outline-offset: 1px; border-radius: 8px; }
.pq-msplit-shot { display: block; width: 72px; height: 72px; padding: 0; border: 1px solid var(--rbpg-border); border-radius: 8px; overflow: hidden; background: #fff; cursor: zoom-in; }
.pq-msplit-shot img { width: 100%; height: 100%; object-fit: cover; }
.pq-msplit-badge {
  position: absolute; top: 2px; right: 2px; font-size: 0.6rem; font-weight: 700;
  background: var(--rbpg-text); color: #fff; border-radius: 4px; padding: 0 0.2rem;
}
/* The "Move to…" select is the touch and keyboard path to the same choices the drag offers. */
.pq-msplit-move .form-select { font-size: 0.65rem; padding: 0.1rem 1.1rem 0.1rem 0.25rem; margin-top: 0.2rem; }

.pq-msplit-preview { position: absolute; inset: 0; z-index: 2; background: rgba(24, 24, 27, 0.92); }
.pq-msplit-pv { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.pq-msplit-pv img { max-width: 82%; max-height: 76%; object-fit: contain; }
.pq-msplit-pvclose, .pq-msplit-pvnav {
  position: absolute; background: rgba(255, 255, 255, 0.14); border: 0; color: #fff;
  border-radius: 50%; width: 36px; height: 36px; font-size: 1.3rem; line-height: 1; cursor: pointer;
}
.pq-msplit-pvclose:hover, .pq-msplit-pvnav:hover { background: rgba(255, 255, 255, 0.3); }
.pq-msplit-pvclose { top: 0.8rem; right: 0.8rem; }
.pq-msplit-pvnav.is-prev { left: 0.8rem; }
.pq-msplit-pvnav.is-next { right: 0.8rem; }
.pq-msplit-pvacts { position: absolute; bottom: 1rem; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; padding: 0 1rem; }
.pq-msplit-pvcount { position: absolute; top: 1rem; left: 1rem; color: #fff; font-size: 0.74rem; }

.pq-msplit-foot-note { margin-right: auto; font-size: 0.74rem; color: var(--rbpg-muted); max-width: 60ch; }
.pq-msplit-err { color: #b91c1c; font-weight: 600; }

/* AIVERIE photo assessment (FLOW-1): the intake card's family, violet edge so the two read apart. */
.pq-assess { border-left-color: #7c3aed; }
.pq-assess > .pq-av-muted { margin: 0.55rem 0 0; font-size: 0.78rem; }
.pq-assess-acts { display: flex; gap: 0.5rem; margin-top: 0.6rem; }
.pq-hold-card-why { margin: 0.4rem 0 0; font-size: 0.78rem; color: var(--rbpg-text); }
.pq-hold-card-meta {
  display: flex; align-items: center; gap: 0.35rem;
  font-size: 0.72rem; color: var(--rbpg-muted); margin-top: 0.35rem;
}

.pq-qc {
  align-self: flex-start;
  /* .pq-thread is a column flex container, so a tall card is a shrinkable item:
     it gets squeezed below its content height when the thread overflows. The
     other card types survive that because the overspill simply draws outside
     them — this one clips, to keep the cover photo inside the rounded corners,
     so what got squeezed off was the View report button. */
  flex: 0 0 auto;
  max-width: 460px;
  margin: 0.5rem 0;
  padding: 0.75rem 0.9rem;
  background: var(--rbpg-surface);
  border: 1px solid var(--rbpg-border);
  border-left: 3px solid #16a34a;
  border-radius: 10px;
}
.pq-qc--warning { border-left-color: #f59e0b; }
.pq-qc--alert { border-left-color: #dc2626; }
/* Paused is not a verdict. Amber like a warning, but dashed, so a card that has
   not finished saying anything cannot be mistaken at a glance for one that has. */
.pq-qc--paused { border-left-color: #f59e0b; border-left-style: dashed; }
/* With a photograph the card leads with it, edge to edge. The padding moves off
   the card and onto the blocks below the image, which is why this is a modifier
   rather than a margin on the image. */
.pq-qc--shot { padding: 0 0 .75rem; overflow: hidden; }
.pq-qc--shot > *:not(.pq-qc-cover) { padding-left: .9rem; padding-right: .9rem; }
.pq-qc-cover {
  display: block; width: 100%; padding: 0; border: 0; margin: 0 0 .7rem;
  background: var(--rbpg-grey); cursor: pointer;
}
.pq-qc-cover img { display: block; width: 100%; height: 150px; object-fit: cover; }
.pq-qc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.pq-qc-title { font-size: 0.85rem; font-weight: 800; }
.pq-qc-pill { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rbpg-muted); }
.pq-qc--warning .pq-qc-pill { color: #b45309; }
.pq-qc--alert .pq-qc-pill { color: #b91c1c; }
.pq-qc--paused .pq-qc-pill { color: #b45309; }
.pq-qc-why { margin: 0.45rem 0 0; font-size: 0.78rem; color: var(--rbpg-text); }
.pq-qc-est { margin: 0.2rem 0 0; font-size: 0.78rem; color: var(--rbpg-text); }
.pq-qc-meta { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; font-size: 0.72rem; color: var(--rbpg-muted); margin-top: 0.25rem; }
.pq-qc-meta .pq-ref--quiet { font-size: inherit; color: inherit; font-weight: 500; }
.pq-qc-meta .pq-avatar { width: 20px; height: 20px; }
.pq-qc-meta .pq-avatar--init { font-size: 0.55rem; }
.pq-qc-steps { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.pq-qc-steps li { display: flex; align-items: flex-start; gap: 0.4rem; font-size: 0.78rem; color: var(--rbpg-text); }
.pq-qc-step-body { display: flex; flex-direction: column; gap: 0.12rem; min-width: 0; }
.pq-qc-step-note { font-size: 0.74rem; color: var(--rbpg-muted); }
.pq-qc-steps li.is-bad { color: #b91c1c; font-weight: 600; }
/* The sections nobody answered, rolled into one line. Muted and unticked: a tick
   claims somebody looked. */
.pq-qc-steps li.is-quiet { color: var(--rbpg-muted); font-size: 0.74rem; padding-left: 1.05rem; }
.pq-qc-steps svg { flex: 0 0 auto; width: 13px; height: 13px; color: #16a34a; margin-top: 0.15rem; }
.pq-qc-steps li.is-bad svg { color: #dc2626; }
.pq-qc-actions { margin-top: 0.6rem; }
.pq-qc-sign {
  margin-top: 0.7rem;
  padding-top: 0.65rem;
  border-top: 1px dotted #ddd;
}
.pq-qc-sign-mark {
  display: block;
  height: 44px;
  max-width: 220px;
  object-fit: contain;
  background: transparent;
}
.pq-qc-sign-name {
  margin: 0.28rem 0 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--rbpg-text);
}
/* rbpg-theme defines .btn and .btn-lg but not .btn-sm, and it loads after
   Bootstrap — so `btn-sm` in the markup is overridden back to full size, here
   and everywhere else in the app. Sized locally rather than by adding the
   missing .btn-sm, which would resize every small button on every page. */
.pq-qc-actions .btn { padding: 0.4rem 0.85rem; font-size: 0.8rem; }

/* ---- QC report viewer (RBPGQCView) ----
   A document, over whatever you were doing. Deliberately plain: this is the
   thing that gets printed and the thing that gets quoted back months later. */
.qcv { align-items: center; justify-content: center; }
.qcv[hidden] { display: none; }
.qcv-card {
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.28);
  width: 100%;
  max-width: 720px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}
/* Two tabs of very different lengths: one height, so switching never moves the tabs. */
.qcv-card--tabbed { height: min(88vh, 900px); }

/* The header never scrolls: title, paper tools, verdict, decisions, tabs. */
.qcv-top { flex: 0 0 auto; padding: 1.2rem 1.4rem 0 1.8rem; border-bottom: 1px solid var(--rbpg-border); }
.qcv-card:not(.qcv-card--tabbed) .qcv-top { padding-bottom: .9rem; }
.qcv-top-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.qcv-head-main { min-width: 0; }
.qcv-head-main h2 { font-size: 1.2rem; font-weight: 800; margin: 0; }
.qcv-sub { margin: .15rem 0 0; font-size: .82rem; color: var(--rbpg-muted); }
.qcv-tools { flex: 0 0 auto; display: flex; align-items: center; gap: .35rem; }
.qcv-top .btn { display: inline-flex; align-items: center; gap: .35rem; padding: .35rem .75rem; font-size: .78rem; }
.qcv-x {
  background: transparent; border: 0; line-height: 1; padding: 0 .2rem; margin-left: .2rem;
  font-size: 1.6rem; color: var(--rbpg-muted); cursor: pointer;
}
.qcv-x:hover { color: var(--rbpg-text); }
.qcv-status-row { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; min-height: 1.9rem; }
.qcv-status-row:has([data-role="verdict"]:empty) { display: none; }
.qcv-fu-bar { flex: 1 1 auto; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .5rem; min-width: 0; }
.qcv-fu-bar[hidden] { display: none; }
.qcv-fu-status { display: inline-flex; align-items: center; gap: .5rem; min-width: 0; }
.qcv-fu-state { font-size: .8rem; color: var(--rbpg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qcv-fu-buttons { display: inline-flex; gap: .35rem; margin-left: auto; }

.qcv-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 1.1rem 1.8rem 1.6rem; }
.qcv-load { display: flex; justify-content: center; padding: 3rem 0; }
.qcv-fail { color: #b91c1c; padding: 2rem 0; text-align: center; }
.qcv-verdict {
  flex: 0 0 auto; font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  padding: .25rem .55rem; border-radius: 999px; background: #dcfce7; color: #166534;
}
.qcv-verdict--warning { background: #fef3c7; color: #92400e; }
.qcv-verdict--alert { background: #fee2e2; color: #991b1b; }
.qcv-verdict--skipped { background: var(--rbpg-grey); color: var(--rbpg-muted); }
/* Follow-up beside the verdict, never instead of it. */
.qcv-fu-chip {
  font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  padding: .25rem .55rem; border-radius: 999px;
}
.qcv-fu-chip--in_hand { background: var(--tone-warn-tint); color: var(--tone-warn-ink); }
.qcv-fu-chip--resolved { background: var(--tone-ok-tint); color: var(--tone-ok-ink); }
.qcv-tabs { margin: .6rem 0 -1px; border-bottom: 0 !important; }
.qcv-tabs .nav-link { padding: .55rem .9rem; font-size: .85rem; }
.qcv-tabs .nav-item:first-child .nav-link { padding-left: 0; }
.qcv-fu-compose textarea { font-size: .82rem; resize: vertical; }
.qcv-fu-err { color: var(--tone-bad-ink); font-size: .78rem; margin: 0 auto 0 0; }
.qcv-fu-actions { display: flex; align-items: center; justify-content: flex-end; gap: .4rem; margin-top: .5rem; }
.qcv-fu-actions .btn { padding: .35rem .75rem; font-size: .78rem; }
.qcv-fu-empty { font-size: .8rem; color: var(--rbpg-muted); margin: 1.2rem 0 0; }
.qcv-fu-notes { list-style: none; padding: 0; margin: 1.2rem 0 1rem; }
.qcv-fu-note { display: flex; gap: .55rem; padding: .7rem 0; border-top: 1px solid var(--rbpg-border); }
.qcv-fu-note-main { min-width: 0; flex: 1 1 auto; }
.qcv-fu-note-head { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; font-size: .78rem; }
.qcv-fu-note-who { font-weight: 600; color: var(--rbpg-text); }
.qcv-fu-note-when { margin-left: auto; font-size: .72rem; color: var(--rbpg-muted); }
.qcv-fu-note-text { margin: .25rem 0 0; font-size: .82rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.qcv-fu-tag {
  font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: .1rem .4rem; border-radius: 999px; background: var(--tone-neutral-tint); color: var(--tone-neutral-ink);
}
.qcv-fu-tag--take { background: var(--tone-warn-tint); color: var(--tone-warn-ink); }
.qcv-fu-tag--resolve { background: var(--tone-ok-tint); color: var(--tone-ok-ink); }
.qcv-fu-tag--reopen { background: var(--tone-bad-tint); color: var(--tone-bad-ink); }
.qcv-signed { display: flex; align-items: center; gap: .5rem; margin: .9rem 0 0; font-size: .78rem; }
.qcv-face { flex: 0 0 auto; width: 28px; height: 28px; font-size: .68rem; }
.qcv-signed-who { display: block; color: var(--rbpg-text); font-weight: 600; }
.qcv-signed-when { display: block; font-size: .72rem; color: var(--rbpg-muted); }
.qcv-signoff {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rbpg-border);
}
.qcv-signoff h3 {
  font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--rbpg-muted); margin: 0 0 .7rem;
}
.qcv-signoff-mark { display: block; height: 65px; max-width: 360px; object-fit: contain; background: transparent; }
.qcv-signoff-name { margin: .4rem 0 0; font-size: .85rem; font-weight: 600; color: var(--rbpg-text); }
.qcv-signoff-when { margin: .15rem 0 0; font-size: .78rem; color: var(--rbpg-muted); }

.rbpg-modal.rbpg-modal--sign .modal-dialog { max-width: 720px; }
.rbpg-sign-canvas-wrap {
  height: 260px;
  border: 1px solid var(--rbpg-border);
  border-radius: 0;
  background: #fff;
  touch-action: none;
}
.rbpg-sign-canvas-wrap canvas { display: block; width: 100%; height: 100%; touch-action: none; cursor: crosshair; }
.rbpg-sign-name { margin-top: .85rem; }
.rbpg-sign-name .form-label { margin-bottom: .25rem; font-size: .78rem; font-weight: 600; }
.rbpg-sign-name-hint { margin: .35rem 0 0; font-size: .78rem; color: var(--rbpg-muted); }
.rbpg-sign-err { margin: .6rem 0 0; font-size: .8rem; color: #b91c1c; }
/* My profile, staff and vendor (NAV-7): one look for both pages. */
.pf-hint { color: var(--rbpg-muted); font-size: .85rem; margin: 0 0 1rem; max-width: 60ch; }
.pf-avatar {
  width: 72px; height: 72px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.25rem; font-weight: 800; color: #3f3f46; background: #e4e4e7;
  background-position: center; background-size: cover; text-transform: uppercase; flex: none;
}
.pf-photo { display: flex; align-items: center; gap: .75rem; margin-bottom: 1rem; }
.pf-hand-preview { max-height: 84px; max-width: 330px; object-fit: contain; display: block; margin: 0 0 .75rem; background: transparent; }
/* Report signature card: a fixed signature box, so drawing, saving or clearing never moves the card. */
.pf-hand-box {
  position: relative; width: 100%; height: 120px; margin: 0 0 1rem;
  border: 1px solid var(--rbpg-border); background: #fff;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.pf-hand-box::after {
  content: ''; position: absolute; left: 14px; right: 14px; bottom: 24px;
  border-bottom: 1px solid var(--rbpg-border); pointer-events: none;
}
.pf-hand-box .pf-hand-preview { max-width: calc(100% - 28px); max-height: 84px; margin: 0 0 14px; position: relative; z-index: 1; }
.pf-hand-box .pf-hand-empty { color: var(--rbpg-muted); font-size: .85rem; margin: 0 0 14px; }
/*
 * Profile cards: the body is a column and `.pf-bottom` starts the group pinned to
 * its foot, so side-by-side cards line up their boxes and buttons whatever the
 * hint above runs to. The email signature is the same height as the signature box.
 */
.pf-card .card-body { display: flex; flex-direction: column; }
.pf-card form { display: flex; flex-direction: column; flex: 1 1 auto; }
.pf-card .pf-bottom { margin-top: auto; }
.pf-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: nowrap; }
.pf-sig-text { height: 120px; resize: none; margin: 0 0 1rem; }
.qcv-skip { margin: .3rem 0 0; font-size: .82rem; color: #92400e; }
.qcv-started { margin: .4rem 0 0; font-size: .82rem; color: var(--rbpg-muted); }

.qcv-step { margin-top: 1.5rem; }
.qcv-step h3 {
  font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--rbpg-muted); margin: 0 0 .6rem; padding-bottom: .35rem;
  border-bottom: 1px solid var(--rbpg-border);
}
.qcv-qa { padding: .6rem 0; border-bottom: 1px solid var(--rbpg-border); }
.qcv-qa:last-child { border-bottom: 0; }
.qcv-q { font-size: .85rem; color: var(--rbpg-text); }
.qcv-ans { margin-top: .25rem; }
.qcv-a { font-size: .88rem; font-weight: 700; color: #166534; }
.qcv-a--yes { color: #166534; }
.qcv-a--warning { color: #b45309; }
.qcv-a--alert { color: #b91c1c; }
.qcv-a--blank { color: var(--rbpg-muted); font-weight: 600; }
.qcv-blank { font-size: .85rem; color: var(--rbpg-muted); font-style: italic; }
.qcv-free { font-size: .88rem; }
/* What a corrected fact replaced, said quietly beside the answer: it modifies
   the answer rather than being it. */
.qcv-was { margin-left: .4rem; font-size: .78rem; color: var(--rbpg-muted); text-decoration: line-through; }
.qcv-said {
  margin: .3rem 0 0; padding-left: .7rem;
  border-left: 2px solid var(--rbpg-border-strong);
  font-size: .84rem; white-space: pre-wrap;
}
/* What they wrote, quoted — so it is legible as the operator's words rather
   than as more of the form. */
.qcv-note {
  margin: .4rem 0 0; padding-left: .7rem;
  border-left: 2px solid var(--rbpg-border);
  font-size: .84rem; color: var(--rbpg-text);
}
.qcv-lines { list-style: none; margin: .2rem 0 0; padding: 0; }
.qcv-lines li { display: flex; justify-content: space-between; gap: 1rem; padding: .2rem 0; font-size: .85rem; }
/* The conclusion of an assessment, printed as two lists rather than fourteen
   sections holding one line each. Same required/optional language as the chips
   that recorded it and the estimate it feeds. */
.qcv-work-group { margin: 0 0 .9rem; }
.qcv-work-group h4 {
  font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  margin: 0 0 .35rem; color: var(--rbpg-text);
}
.qcv-work-group--required {
  background: var(--tone-ok-tint);
  border: 1px solid #bbf7d0;
  border-radius: 8px;
  padding: 0.7rem 0.85rem 0.55rem;
}
.qcv-work-group--required h4 { color: var(--tone-ok-ink); }
.qcv-work-group--optional h4 { color: #92400e; }
.qcv-work-list { list-style: none; margin: 0; padding: 0; }
.qcv-work-list li {
  padding: .28rem 0 .28rem .85rem; font-size: .88rem; position: relative;
  border-bottom: 1px dashed var(--rbpg-border);
}
.qcv-work-list li:last-child { border-bottom: 0; }
.qcv-work-list li::before {
  content: ''; position: absolute; left: 0; top: .72rem;
  width: 5px; height: 5px; border-radius: 50%; background: var(--rbpg-text);
}
.qcv-work-group--required .qcv-work-list li { border-bottom-color: #bbf7d0; }
.qcv-work-group--required .qcv-work-list li::before { background: var(--tone-ok-dot); }
.qcv-work-group--optional .qcv-work-list li::before { background: #d97706; }
.qcv-work-note { margin-top: .7rem; }
.qcv-work-note-q { font-size: .72rem; font-weight: 700; color: var(--rbpg-muted); }

.qcv-shots { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.qcv-shots img { width: 92px; height: 92px; object-fit: cover; border-radius: 8px; border: 1px solid var(--rbpg-border); display: block; }

/* Printing the overlay prints the REPORT, not the page behind it. This is what
   the Download PDF button relies on. */
@media print {
  body.qcv-open > *:not(.qcv) { display: none !important; }
  body.qcv-open .qcv { position: static; background: none; padding: 0; }
  body.qcv-open .qcv-card { box-shadow: none; max-height: none; max-width: none; height: auto; overflow: visible; }
  body.qcv-open .qcv-body { overflow: visible; }
  body.qcv-open .qcv-tools, body.qcv-open .qcv-fu-buttons, body.qcv-open .qcv-tabs,
  body.qcv-open [data-qcv-panel="resolution"] { display: none !important; }
  body.qcv-open [data-qcv-panel="report"] { display: block !important; }
}

/* ---- files grid + drop zone ---- */
.pq-files-zone { position: relative; flex: 1 1 auto; min-height: 0; }
.pq-files-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; align-content: start; }
.pq-files-zone--empty { display: flex; align-items: center; justify-content: center; text-align: center; border: 1px dashed var(--rbpg-border); border-radius: 12px; }
.pq-files-empty-inner { color: var(--rbpg-muted); padding: 1.2rem; display: flex; flex-direction: column; align-items: center; gap: 0.35rem; }
.pq-files-empty-inner svg { color: var(--rbpg-border); margin-bottom: 0.3rem; }
.pq-files-empty-title { font-size: 0.9rem; font-weight: 700; color: var(--rbpg-text); margin: 0; }
.pq-files-empty-sub { font-size: 0.8rem; margin: 0; line-height: 1.5; }
/* Drop-to-upload overlay — only visible while dragging OS files over the zone. */
.pq-files-overlay { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; background: rgba(255,255,255,0.82); border: 2px dashed var(--rbpg-text); border-radius: 12px; z-index: 6; }
.pq-files-zone.pq-drop-over .pq-files-overlay { display: flex; }
.pq-files-overlay-card { display: flex; flex-direction: column; align-items: center; gap: 0.4rem; font-size: 0.9rem; font-weight: 700; color: var(--rbpg-text); }
.pq-file { position: relative; border: 1px solid var(--rbpg-border); border-radius: 11px; overflow: hidden; background: #fff; display: flex; flex-direction: column; transition: border-color .12s, box-shadow .12s; }
.pq-file:hover { border-color: #d0d0d3; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.pq-file--cover { border-color: var(--rbpg-text); }
.pq-file-cover-badge { position: absolute; top: 5px; left: 5px; z-index: 2; background: var(--rbpg-text); color: #fff; font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.12rem 0.4rem; border-radius: 6px; pointer-events: none; }
.pq-file-thumb { border: 0; background: var(--rbpg-grey); padding: 0; cursor: pointer; aspect-ratio: 4 / 3; display: block; width: 100%; overflow: hidden; position: relative; }
.pq-file-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pq-file-thumb--doc { display: flex; align-items: center; justify-content: center; }
.pq-file-fallback { position: absolute; inset: 0; align-items: center; justify-content: center; color: var(--rbpg-muted); background: var(--rbpg-grey); }
.pq-file-thumb--doc .pq-file-fallback { position: static; width: 100%; height: 100%; }
.pq-file-fallback .pq-glyph { filter: drop-shadow(0 1px 2px rgba(0,0,0,0.06)); }
/* play badge overlaid on video tiles */
.pq-file-play { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 30px; height: 30px; border-radius: 50%; background: rgba(0,0,0,0.55); pointer-events: none; }
.pq-file-play::after { content: ""; position: absolute; left: 52%; top: 50%; transform: translate(-50%,-50%); border-style: solid; border-width: 6px 0 6px 10px; border-color: transparent transparent transparent #fff; }
.pq-file-meta { padding: 0.45rem 0.55rem 0.55rem; min-width: 0; }
.pq-file-name { display: block; font-size: 0.76rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-file-sub { display: flex; align-items: center; gap: 0.25rem; font-size: 0.64rem; color: var(--rbpg-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.pq-file-dot { opacity: 0.6; }
/* three-dot menu button (top-right of the card) */
.pq-file-menu-btn { position: absolute; top: 5px; right: 5px; width: 26px; height: 26px; border-radius: 7px; border: 0; background: rgba(255,255,255,0.86); color: var(--rbpg-text); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; opacity: 0; transition: opacity .12s, background .12s; box-shadow: 0 1px 3px rgba(0,0,0,0.18); }
.pq-file:hover .pq-file-menu-btn, .pq-file-menu-btn:focus-visible { opacity: 1; }
.pq-file-menu-btn:hover { background: #fff; }
.pq-file-menu-btn svg { display: block; }
@media (hover: none) { .pq-file-menu-btn { opacity: 1; } }

/* body-mounted file action menu */
.pq-file-menu { position: fixed; z-index: 3500; background: #fff; border: 1px solid var(--rbpg-border); border-radius: 10px; box-shadow: 0 12px 34px rgba(0,0,0,0.18); padding: 0.3rem; min-width: 180px; }
.pq-fm-item { display: block; width: 100%; text-align: left; background: transparent; border: 0; border-radius: 7px; padding: 0.55rem 0.65rem; font-size: 0.85rem; color: var(--rbpg-text); cursor: pointer; text-decoration: none; }
.pq-fm-item:hover { background: var(--rbpg-grey); }
.pq-fm-item--danger { color: #b91c1c; }
.pq-fm-item--danger:hover { background: #fbeded; }

/* ---- attachment strips under thread bubbles ---- */
.pq-atts { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.35rem; }
.pq-msg--out .pq-atts { justify-content: flex-end; }
.pq-att { border: 1px solid var(--rbpg-border-strong); border-radius: 999px; background: #fff; cursor: pointer; padding: 0; overflow: hidden; color: var(--rbpg-text); }
.pq-att:hover { background: var(--rbpg-grey); }
.pq-att--img { width: 118px; height: 118px; border-radius: 10px; }
.pq-att--img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pq-att--doc, .pq-att--paper { display: inline-flex; align-items: center; gap: 0.28rem; padding: 0.16rem 0.5rem 0.16rem 0.36rem; max-width: 220px; }
.pq-att--paper { max-width: 280px; }
.pq-att-ico { display: inline-flex; color: var(--rbpg-muted); flex: 0 0 auto; line-height: 0; }
.pq-att-ico svg { display: block; }
.pq-att-name { font-size: 0.68rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-att-size { font-size: 0.58rem; color: var(--rbpg-muted); flex: 0 0 auto; }
.pq-att--paper[aria-busy="true"] { opacity: 0.55; cursor: progress; }
/* Sent without its paperclip — the words went, the file did not. */
.pq-att--dropped { border-color: #d99; border-style: dashed; }
.pq-att--dropped .pq-att-size { color: #b91c1c; }

/* ---- composer: paperclip + pending chips ---- */
.pq-attach { width: 32px; height: 32px; flex: 0 0 auto; border-radius: 8px; border: 1px solid var(--rbpg-border); background: var(--rbpg-grey); cursor: pointer; color: var(--rbpg-muted); display: inline-flex; align-items: center; justify-content: center; }
.pq-attach:hover { border-color: var(--rbpg-text); color: var(--rbpg-text); }
.pq-attach svg { display: block; }
.pq-attach--off, .pq-attach:disabled { opacity: 0.4; cursor: not-allowed; }
.pq-attach--off:hover, .pq-attach:disabled:hover { border-color: var(--rbpg-border); color: var(--rbpg-muted); }

/* ---- composer + bubble: @mentions in a note (MENTION-2) ---- */
.pq-mention-btn[hidden] { display: none; }
.pq-mention-to { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 0 2px 6px; font-size: 0.78rem; }
.pq-mention-to[hidden] { display: none; }
.pq-mention-to-label { color: var(--rbpg-muted); margin-right: 2px; }
.pq-mention-to-off { color: var(--rbpg-muted); }
.pq-mention-chip { display: inline-flex; align-items: center; gap: 2px; padding: 1px 4px 1px 8px; border-radius: 999px; background: var(--tone-info-tint); color: var(--tone-info-ink); font-weight: 500; }
.pq-mention-chip-x { border: 0; background: none; padding: 0 4px; line-height: 1; color: inherit; opacity: 0.6; cursor: pointer; font-size: 0.9rem; }
.pq-mention-chip-x:hover { opacity: 1; }
.pq-note-to { font-size: 0.74rem; font-weight: 600; opacity: 0.75; margin-bottom: 2px; }
.pq-mention { font-weight: 600; }
.pq-mention--me { background: var(--tone-warn-lit); color: inherit; border-radius: 3px; padding: 0 2px; }
.pq-msg--for-me .pq-bubble { box-shadow: 0 0 0 2px var(--tone-warn-dot); }
.pq-note-seen { display: flex; align-items: center; gap: 4px; max-width: 100%; margin-bottom: -0.12rem; padding: 0 0.15rem; font-size: 0.62rem; line-height: 1.2; color: var(--rbpg-muted); }
.pq-note-seen svg { flex: 0 0 auto; opacity: 0.8; }
.pq-note-seen span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- Reply to a note (MENTION-7) ---- */
.pq-note-body { position: relative; display: flex; justify-content: flex-end; max-width: 100%; }
.pq-note-reply {
  position: absolute; right: calc(100% + 6px); top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px;
  font-size: 0.68rem; font-weight: 600; line-height: 1; white-space: nowrap;
  color: var(--rbpg-text); background: var(--rbpg-surface); border: 1px solid var(--rbpg-border);
  border-radius: var(--rbpg-radius-ctl-sm); box-shadow: 0 1px 2px rgb(0 0 0 / 0.06);
  cursor: pointer; opacity: 0; pointer-events: none; transition: opacity 120ms ease, background-color 120ms ease;
}
.pq-note-reply svg { flex: 0 0 auto; }
.pq-note-reply:hover { background: var(--rbpg-grey-hover); }
.pq-note-reply:focus-visible { outline: 2px solid var(--rbpg-text); outline-offset: 1px; }
.pq-msg--note:hover .pq-note-reply,
.pq-msg--note:focus-within .pq-note-reply,
.pq-msg--for-me .pq-note-reply { opacity: 1; pointer-events: auto; }
@media (hover: none) { .pq-note-reply { opacity: 1; pointer-events: auto; } }

.pq-reply-to { display: flex; align-items: center; gap: 4px; margin: 0 2px 6px; padding: 3px 4px 3px 8px; background: var(--rbpg-grey); border-left: 2px solid var(--rbpg-text); border-radius: var(--rbpg-radius-ctl-sm); font-size: 0.72rem; }
.pq-reply-to[hidden] { display: none; }
.pq-reply-to-jump { flex: 1 1 auto; min-width: 0; display: block; padding: 0; border: 0; background: none; font: inherit; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; color: var(--rbpg-muted); }
.pq-reply-to-name { font-weight: 600; color: var(--rbpg-text); }
.pq-reply-to-quote { color: var(--rbpg-muted); }
.pq-reply-to-x { flex: 0 0 auto; width: 20px; height: 20px; padding: 0; border: 0; border-radius: var(--rbpg-radius-ctl-sm); background: none; color: var(--rbpg-muted); font-size: 0.95rem; line-height: 1; cursor: pointer; }
.pq-reply-to-x:hover { color: var(--rbpg-text); background: var(--rbpg-grey-hover); }
@media (prefers-reduced-motion: reduce) { .pq-note-reply { transition: none; } }
.pq-msg--flash .pq-bubble { animation: pq-msg-flash 1.2s ease-out 1; }
@keyframes pq-msg-flash { 0% { box-shadow: 0 0 0 6px var(--tone-info-tint); } 100% { box-shadow: 0 0 0 0 transparent; } }

/* ---- For you: the top-bar @ button, its list, the dashboard card (MENTION-3) ---- */
.app-topbar .topbar-right > .dropdown.rbpg-mentions { width: auto; flex: 0 0 auto; }
.rbpg-mentions-btn { display: inline-flex; align-items: center; gap: 4px; height: 32px; padding: 0 9px; border-radius: 999px; line-height: 1; }
.rbpg-mentions-btn::after { display: none; }
.rbpg-mentions-at { font-weight: 700; font-size: 0.95rem; }
.rbpg-mentions-count { min-width: 18px; padding: 2px 5px; border-radius: 999px; background: var(--tone-bad-dot); color: #fff; font-size: 0.68rem; font-weight: 700; text-align: center; }
.rbpg-mentions-count[hidden] { display: none; }
.rbpg-mentions-menu { width: 400px; max-width: calc(100vw - 24px); padding: 0; border: 1px solid var(--rbpg-border); border-radius: 12px; box-shadow: 0 12px 32px rgba(0, 0, 0, .1); overflow: hidden; }
.rbpg-mentions-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--rbpg-border); font-size: 0.9rem; }
.rbpg-mentions-head [hidden] { display: none; }
.rbpg-mentions-list { max-height: min(480px, calc(100vh - 140px)); overflow-y: auto; }
.rbpg-mentions-empty { padding: 22px 16px; color: var(--rbpg-muted); font-size: 0.84rem; text-align: center; }
.rbpg-mentions-more { display: block; width: 100%; padding: 10px 14px; border: 0; border-top: 1px solid var(--rbpg-border); background: none; color: var(--rbpg-text); font-size: 0.82rem; font-weight: 600; text-align: center; cursor: pointer; }
a.rbpg-mentions-more { text-decoration: none; }
.rbpg-mentions-more span { color: var(--rbpg-muted); font-weight: 400; }
.rbpg-mentions-more:hover { background: var(--rbpg-grey); }
.rbpg-mentions-more:disabled { opacity: .6; cursor: default; }
.rbpg-mentions-more[hidden] { display: none; }
/* One row: avatar | case title + #number + time + dot / "X mentioned you" / the note as a bubble. */
.rbpg-mention-row { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; color: var(--rbpg-text); text-decoration: none; font-size: 0.82rem; line-height: 1.4; }
.rbpg-mention-row + .rbpg-mention-row { border-top: 1px solid var(--rbpg-border); }
.rbpg-mention-row:hover, .rbpg-mention-row:focus-visible { background: var(--rbpg-grey); color: var(--rbpg-text); outline: none; }
.rbpg-mention-face { flex: 0 0 32px; width: 32px; height: 32px; border-radius: 50%; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); color: var(--rbpg-text); font-size: 0.78rem; font-weight: 700; }
.rbpg-mention-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rbpg-mention-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.rbpg-mention-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
.rbpg-mention-title { min-width: 0; flex: 0 1 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 500; color: var(--rbpg-muted); }
.rbpg-mention-row--unread .rbpg-mention-title { font-weight: 650; color: var(--rbpg-text); }
.rbpg-mention-ref { flex: 0 0 auto; padding: 1px 6px; border-radius: 5px; background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); color: var(--rbpg-muted); font-size: 0.7rem; font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.rbpg-mention-head time { flex: 0 0 auto; margin-left: auto; color: var(--rbpg-muted); font-size: 0.72rem; white-space: nowrap; }
.rbpg-mention-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: transparent; }
.rbpg-mention-row--unread .rbpg-mention-dot { background: var(--tone-bad-dot); }
.rbpg-mention-by { color: var(--rbpg-muted); font-size: 0.78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rbpg-mention-by strong { color: var(--rbpg-text); font-weight: 600; }
.rbpg-mention-bubble { align-self: flex-start; max-width: 100%; margin-top: 2px; padding: 7px 11px; border-radius: 4px 12px 12px 12px; background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); color: var(--rbpg-text); overflow-wrap: anywhere; }
.rbpg-mention-text { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.rbpg-mention-bubble b { font-weight: 600; }
.rbpg-mention-row:hover .rbpg-mention-bubble, .rbpg-mention-row:focus-visible .rbpg-mention-bubble { background: #fff; }
.rbpg-for-you-slot { margin-bottom: 1rem; }
.rbpg-for-you-slot[hidden] { display: none; }
.rbpg-for-you { padding: 0; overflow: hidden; }
.rbpg-for-you-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--rbpg-border); }
.rbpg-for-you-head .btn { margin-left: auto; }
.rbpg-for-you-n { min-width: 20px; padding: 1px 7px; border-radius: 999px; background: var(--tone-bad-dot); color: #fff; font-size: 0.7rem; font-weight: 700; text-align: center; }
.pq-pending { display: flex; flex-wrap: wrap; gap: 0.4rem; padding: 0 0 0.55rem; }
.pq-chip { display: inline-flex; align-items: center; gap: 0.4rem; background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 999px; padding: 0.2rem 0.35rem 0.2rem 0.5rem; font-size: 0.76rem; max-width: 210px; }
.pq-chip--img { padding-left: 0.2rem; }
.pq-chip img { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; }
.pq-chip-ico { font-size: 0.85rem; }
.pq-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-chip-x { border: 0; background: transparent; cursor: pointer; color: var(--rbpg-muted); font-size: 0.7rem; padding: 0 2px; line-height: 1; }
.pq-chip-x:hover { color: var(--rbpg-text); }
/* Our own paper, staged for the send: squared off and inked so a generated
   invoice never reads as something the customer uploaded. Wider, because the
   name it carries is a reference the operator wants to see in full. */
.pq-chip--doc { border-radius: 6px; border-color: var(--rbpg-text); background: #fff; max-width: 320px; }
.pq-drop-over { outline: 2px dashed var(--rbpg-text); outline-offset: -4px; }

/* ---- file viewer (lightbox over the message column) ---- */
.pq-center { position: relative; }
.pq-viewer { position: absolute; inset: 0; z-index: 40; background: rgba(20,20,20,0.93); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.pq-viewer-top { position: absolute; top: 0; left: 0; right: 0; z-index: 2; display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 0.8rem; }
.pq-viewer-cap { font-size: 0.8rem; color: #e4e4e7; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-viewer-actions { margin-left: auto; display: flex; gap: 0.4rem; align-items: center; }
.pq-viewer-btn { background: rgba(255,255,255,0.14); color: #fff; border: 0; border-radius: 8px; padding: 0.35rem 0.6rem; font-size: 0.78rem; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; }
.pq-viewer-btn:hover { background: rgba(255,255,255,0.28); color: #fff; }
.pq-viewer-stage { position: relative; z-index: 1; max-width: 88%; max-height: 78%; display: flex; align-items: center; justify-content: center; }
.pq-viewer-stage img { max-width: 100%; max-height: 74vh; object-fit: contain; border-radius: 6px; cursor: zoom-in; user-select: none; transform-origin: center; transition: transform 0.08s ease-out; }
.pq-viewer-stage img.is-zoomed { cursor: grab; }
.pq-viewer-stage img.is-dragging { cursor: grabbing; transition: none; }
.pq-viewer-stage iframe { width: 78vw; max-width: 720px; height: 74vh; border: 0; background: #fff; border-radius: 6px; }
.pq-viewer-stage video { max-width: 100%; max-height: 74vh; border-radius: 6px; background: #000; }
/* Loading spinner, centred on the viewer. Fades in after a beat so a cached image does not flash it. */
.pq-viewer-spin { position: absolute; top: 50%; left: 50%; z-index: 3; width: 40px; height: 40px; margin: -20px 0 0 -20px; border: 3px solid rgba(255,255,255,0.18); border-top-color: #fff; border-radius: 50%; pointer-events: none; opacity: 0; animation: pq-spin 0.8s linear infinite, pq-viewer-spin-in 0.2s ease-out 0.15s forwards; }
.pq-viewer-spin[hidden] { display: none; }
@keyframes pq-viewer-spin-in { to { opacity: 1; } }
.pq-viewer-stage img.is-loading { visibility: hidden; }
.pq-viewer-doc { text-align: center; color: #fff; display: flex; flex-direction: column; gap: 0.7rem; align-items: center; }
.pq-viewer-doc audio { margin-top: 0.4rem; }
.pq-viewer-doc-name { font-size: 0.9rem; color: #e4e4e7; max-width: 60vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-viewer-nav { position: absolute; top: 50%; z-index: 2; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; border: 0; background: rgba(255,255,255,0.16); color: #fff; font-size: 1.4rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.15s, background 0.15s; }
.pq-viewer:hover .pq-viewer-nav, .pq-viewer-nav:focus-visible { opacity: 1; }
.pq-viewer-nav:hover { background: rgba(255,255,255,0.3); }
@media (hover: none) { .pq-viewer-nav { opacity: 1; } }
.pq-viewer-prev { left: 12px; }
.pq-viewer-next { right: 12px; }
/* zoom level: thin vertical bar right of centre, filled from the bottom (100% empty, max full) */
.pq-viewer-zoom { position: absolute; right: 64px; top: 50%; z-index: 2; transform: translateY(-50%); display: flex; flex-direction: column; align-items: center; gap: 0.4rem; opacity: 0; transition: opacity 0.2s; pointer-events: none; }
.pq-viewer-zoom.is-on { opacity: 1; }
.pq-viewer-zoom-track { position: relative; width: 4px; height: 160px; border-radius: 2px; background: rgba(255,255,255,0.22); overflow: hidden; }
.pq-viewer-zoom-fill { position: absolute; left: 0; right: 0; bottom: 0; height: 0; background: #fff; border-radius: 2px; transition: height 0.08s ease-out; }
.pq-viewer-zoom-val { font-size: 0.7rem; color: #e4e4e7; font-variant-numeric: tabular-nums; }
/* bottom info strip: file name + mime + size + uploaded date */
.pq-viewer-bar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; display: flex; align-items: baseline; gap: 0.8rem; padding: 0.6rem 0.9rem; background: linear-gradient(to top, rgba(0,0,0,0.55), rgba(0,0,0,0)); color: #f2f2f4; }
.pq-vbar-name { font-size: 0.82rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pq-vbar-meta { margin-left: auto; font-size: 0.72rem; color: #c9c9cf; white-space: nowrap; text-transform: uppercase; letter-spacing: 0.03em; }

/* Skeletons */
.pq-skel { background: linear-gradient(90deg,#ececec 25%,#f5f5f5 37%,#ececec 63%); background-size: 400% 100%; animation: pq-shimmer 1.2s ease infinite; border-radius: 8px; }
@keyframes pq-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

@media (max-width: 1199.98px) {
  /* Intercom-style: keep case context; queue becomes a left drawer. */
  .pq-body { display: flex; flex-direction: row; min-height: 0; overflow: hidden; }
  .pq-center { flex: 1 1 auto; min-width: 0; }
  .pq-info { flex: 0 0 clamp(260px, 34vw, 360px); width: clamp(260px, 34vw, 360px); }
  .pq-queue-toggle { display: inline-flex; }
  .pq-queue {
    position: fixed; top: 0; left: 0; bottom: 0; width: min(300px, 86vw); z-index: 1040;
    transform: translateX(-105%); transition: transform .2s ease;
    box-shadow: 4px 0 24px rgba(0,0,0,.12); border-right: 1px solid var(--rbpg-border);
  }
  .pq.queue-open .pq-queue { transform: translateX(0); }
  .pq-scrim {
    display: block; position: fixed; inset: 0; z-index: 1039;
    background: rgba(24, 24, 27, 0.45); opacity: 0; pointer-events: none; transition: opacity .2s ease;
  }
  .pq.queue-open .pq-scrim { opacity: 1; pointer-events: auto; }
}
@media (max-width: 639.98px) {
  .pq-info { flex-basis: min(200px, 42vw); width: min(200px, 42vw); }
  .pq-progress-bar { width: 72px; }
  .pq-crumb .muted:first-child, .pq-crumb .sep:first-of-type { display: none; }
}

/* The customer's rating, on the case where the repair happened (REV-7).
   Structured like .pq-qc deliberately — same left-accent card, same place in the
   feed — because it is the same kind of thing: an outcome somebody needs to see
   without going looking for it. The accent carries the verdict, so a 2-star is
   visible while scrolling past. */
.pq-rv {
  align-self: flex-start;
  flex: 0 0 auto;
  max-width: 460px;
  margin: 0.5rem 0;
  padding: 0.7rem 0.9rem;
  background: var(--rbpg-surface);
  border: 1px solid var(--rbpg-border);
  border-left: 3px solid #16a34a;
  border-radius: 10px;
}
.pq-rv--mixed { border-left-color: #f59e0b; }
.pq-rv--poor { border-left-color: #dc2626; }
.pq-rv-top { display: flex; align-items: center; gap: 0.5rem; }
.pq-rv-stars { display: inline-flex; gap: 0.05rem; font-size: 0.95rem; line-height: 1; }
.pq-rv-star { color: var(--rbpg-star-off); }
.pq-rv-star.is-on { color: var(--rbpg-star); }
.pq-rv-score { font-size: 0.85rem; font-weight: 800; }
.pq-rv-pill {
  margin-left: auto; font-size: 0.68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--rbpg-muted);
}
.pq-rv-comment {
  margin-top: 0.5rem; font-size: 0.875rem; line-height: 1.5;
  color: var(--rbpg-text); overflow-wrap: anywhere;
}
.pq-rv-meta { margin-top: 0.4rem; font-size: 0.72rem; color: var(--rbpg-muted); }
.pq-rv-who { font-weight: 600; }

/* Rich reply rendering (thread bubbles) */
.pq-rich a { color: #2563eb; text-decoration: underline; word-break: break-word; }
.pq-rich p { margin: 0 0 0.5rem; }
.pq-rich p:last-child { margin-bottom: 0; }
.pq-rich ul, .pq-rich ol { margin: 0 0 0.5rem 1.1rem; padding: 0; }

/* Designed emails, framed at the width they were designed for.
   Phone-width on purpose: these templates are built mobile-first and that is how
   nearly every customer opens them, so the bubble shows what they actually saw
   rather than a stretched desktop variant nobody receives. */
/* A framed email brings its own card: its own canvas colour, its own white sheet,
   its own border and radius. Wrapping that in the outbound bubble's blue card and
   then bordering the frame on top produced three nested rectangles around one
   email. So a document message drops the bubble entirely — no background, no
   border, no padding — and the email is simply the thing in the thread. */
.pq-bubble--doc { background: none !important; border: 0 !important; box-shadow: none !important; }
.pq-bubble--doc .pq-bubble-pad { padding: 0; }
.pq-msg--doc .pq-bubble { overflow: visible; }
.pq-bubble--doc .pq-bubble-subj {
  font-size: 0.78rem; font-weight: 600; color: var(--rbpg-muted);
  margin: 0 0 0.3rem; padding: 0;
}

.pq-doc { position: relative; width: 390px; max-width: 100%; }
.pq-doc-frame {
  display: block; width: 100%; height: 220px; /* replaced on load by measured height */
  border: 0; background: transparent;
  color-scheme: light; /* emails are designed on a light canvas; don't invert them */
  /* A picture of what was sent, not a copy you can use. Suppressing pointer
     events kills the link cursor as well as the click, so nothing inside invites
     a press — including the review email's five stars, each of which files a
     rating on the customer's behalf when followed. The "show full email" button
     sits outside the frame and still works. */
  pointer-events: none;
}
.pq-doc-more { display: none; }
.pq-doc--clipped::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 1.9rem; height: 4rem;
  background: linear-gradient(to bottom, rgba(255,255,255,0), #fff); pointer-events: none;
}
.pq-doc--clipped .pq-doc-more {
  display: block; width: 100%; padding: 0.4rem 0.6rem;
  border: 1px solid var(--rbpg-border); border-radius: 8px; background: #fff;
  font: inherit; font-size: 0.8rem; font-weight: 600; color: #2563eb;
  cursor: pointer; text-align: center;
}
.pq-doc--clipped .pq-doc-more:hover { background: #f7f9fc; }

/* ==========================================================================
   RBPGEditor — reusable Gmail/Intercom-style rich editor (Trix)
   One connected box: content on top, a compact toolbar docked at the bottom.
   ========================================================================== */
.rbpg-editor {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--rbpg-border, #d7dbe0);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.rbpg-editor:focus-within {
  border-color: var(--rbpg-accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
/* Editing area on top */
.rbpg-editor .rbpg-editor__area {
  order: 1;
  border: 0;
  border-radius: 0;
  min-height: 150px;
  max-height: 420px;
  overflow-y: auto;
  padding: 0.75rem 0.85rem;
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
  color: #1f2430;
}
.rbpg-editor .rbpg-editor__area:focus { outline: none; }
.rbpg-editor .rbpg-editor__area a { color: #2563eb; text-decoration: underline; }
.rbpg-editor .rbpg-editor__area:empty::before,
.rbpg-editor .rbpg-editor__area[data-trix-empty]::before {
  color: #98a2b3;
}

/* Toolbar docked at the BOTTOM, compact */
.rbpg-editor trix-toolbar {
  order: 2;
  padding: 0.2rem 0.35rem;
  background: #f7f8fa;
  border-top: 1px solid var(--rbpg-border, #e6e9ee);
}
.rbpg-editor trix-toolbar .trix-button-row { align-items: center; flex-wrap: nowrap; }
.rbpg-editor trix-toolbar .trix-button-group {
  border: 0;
  margin: 0 0.15rem 0 0;
  box-shadow: none;
}
.rbpg-editor trix-toolbar .trix-button-group:not(:first-child) { margin-left: 0.15rem; }
.rbpg-editor trix-toolbar .trix-button {
  height: 1.7rem;
  width: 1.85rem;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: #475467;
}
.rbpg-editor trix-toolbar .trix-button:not(:disabled):hover { background: #e9edf3; }
.rbpg-editor trix-toolbar .trix-button.trix-active { background: #e2e8f5; color: #1d4ed8; }
.rbpg-editor trix-toolbar .trix-button::before { margin: 22% !important; opacity: 0.85; }

/* Keep only the basics: bold, italic, link, bullet + numbered list.
   Hide heading/quote/code/strike, indentation, attachments and history. */
.rbpg-editor trix-toolbar .trix-button--icon-strike,
.rbpg-editor trix-toolbar .trix-button--icon-heading-1,
.rbpg-editor trix-toolbar .trix-button--icon-quote,
.rbpg-editor trix-toolbar .trix-button--icon-code,
.rbpg-editor trix-toolbar .trix-button--icon-decrease-nesting-level,
.rbpg-editor trix-toolbar .trix-button--icon-increase-nesting-level,
.rbpg-editor trix-toolbar .trix-button-group--file-tools,
.rbpg-editor trix-toolbar .trix-button-group--history-tools { display: none !important; }

/* Link dialog: keep it tidy above the bottom toolbar */
.rbpg-editor trix-toolbar .trix-dialog {
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(16, 24, 40, 0.16);
  font-size: 0.85rem;
}
.rbpg-editor trix-toolbar .trix-dialog .trix-input--dialog {
  border-radius: 6px;
  border: 1px solid var(--rbpg-border, #d7dbe0);
}

/* ── Ratings ────────────────────────────────────────────────────────────────
 * REV-7. The markup comes from `lib/rbpg-stars.js`, which is the one renderer
 * for every screen showing a score. These are the styles for it.
 *
 * Amber is the ONE exception to the status-tone rule in the design system, and
 * it is deliberate: a star is not a status. The five tones mean "in flight",
 * "settled", "waiting", "ended badly" and "no state yet", and a rating is none
 * of those — it is a quantity. Rendering it in `--tone-ok` would say a 2-star
 * review is good news, and in `--tone-warn` that a 5-star one needs attention.
 * A grey star is not a star, so it gets its own value, declared once here.
 */
/*
 * Google's review yellow, deliberately. Our reviews sit next to our Google
 * Business rating in a customer's mind — the thank-you email sends promoters
 * straight there — and a star that is a different yellow in the two places reads
 * as a different, lesser kind of rating. Matching it costs nothing and buys the
 * association.
 *
 * This is the ONLY place either value is written. Three copies of the amber
 * existed before (here, the public survey page, and the case timeline card), and
 * two of them would still be the old colour now.
 */
:root {
  --rbpg-star: #fbbc04;
  --rbpg-star-off: #d4d4d8;
}

.rbpg-rating {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  white-space: nowrap;
  line-height: 1;
}

.rbpg-stars { display: inline-flex; align-items: center; gap: 1px; }

.rbpg-star { display: inline-flex; line-height: 0; }

.rbpg-star svg {
  width: 15px;
  height: 15px;
  display: block;
  fill: var(--rbpg-star-off);
}

.rbpg-star.is-on svg { fill: var(--rbpg-star); }

/* A half star by clipping the same path, so there is one star shape in the
   codebase rather than a second half-width asset that drifts from it. */
.rbpg-star.is-half svg { fill: var(--rbpg-star); clip-path: inset(0 50% 0 0); }

.rbpg-stars--sm .rbpg-star svg { width: 12px; height: 12px; }
.rbpg-stars--lg .rbpg-star svg { width: 22px; height: 22px; }

.rbpg-rating-score {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--rbpg-text);
  font-variant-numeric: tabular-nums;
}

.rbpg-stars--lg + .rbpg-rating-score { font-size: 1.5rem; }

.rbpg-rating-count {
  font-size: 0.75rem;
  color: var(--rbpg-muted);
  font-variant-numeric: tabular-nums;
}

/* A score on its own line under a name in the case rail — the supplier's
   (REV-7) and the customer's (REV-11) — in the shape every rating a customer has
   ever seen uses: glyphs, then the number, then how many. Trailing the name
   instead meant it competed with a long workshop name for the rail's width and
   wrapped mid-component.

   Both selectors carry the same rules because both lines are the same component
   in the same column; only the number underneath differs, and that is a backend
   distinction rather than a visual one.

   `align-items: baseline` rather than center: the stars are 12px and the score
   is 13px, and centring them leaves the numeral sitting visibly low. */
.pq-supplier-rating,
.pq-cust-rating {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  margin: -0.15rem 0 0.4rem;
}
.pq-supplier-rating .rbpg-rating,
.pq-cust-rating .rbpg-rating { gap: 0.3rem; }
.pq-supplier-rating .rbpg-stars,
.pq-cust-rating .rbpg-stars { align-self: center; }
.pq-supplier-rating .rbpg-rating-score,
.pq-cust-rating .rbpg-rating-score { font-size: 0.82rem; font-weight: 700; }
.pq-supplier-rating .rbpg-rating-count,
.pq-cust-rating .rbpg-rating-count { font-size: 0.72rem; }
/* The count is a link to the reviews behind it, but it is still a quiet caption:
   underlining only on hover keeps the line reading as a rating rather than as a
   row of navigation. */
.pq-supplier-rating .rbpg-rating-count a,
.pq-cust-rating .rbpg-rating-count a { color: inherit; text-decoration: none; }
.pq-supplier-rating .rbpg-rating-count a:hover,
.pq-cust-rating .rbpg-rating-count a:hover { color: #2563eb; text-decoration: underline; }

/* Nobody rated yet. Neutral, and deliberately NOT a pill — a pill is a status,
   and "we have not asked anybody yet" is the absence of one.

   On a customer this line is the point rather than a fallback: the question the
   rail is answering is "has this person ever reviewed us", and an empty space
   answers that with silence, which reads identically to a panel that has not
   finished loading. */
.rbpg-rating--none {
  font-size: 0.75rem;
  color: var(--rbpg-muted);
  font-style: italic;
}

/* ── The reviews inbox (REV-8) ──────────────────────────────────────────────*/

/* Fixed layout, and it has to be. Under the default `auto` algorithm a column
   can never be narrower than its own content, so a nowrap cell — five stars, a
   date that must not wrap — sets a floor that no `width` can talk it below, and
   the table answers a container it does not fit by scrolling sideways. Once the
   row menu took a column of its own that is exactly what happened here, and
   trimming the other five moved the number without ever reaching zero.

   Fixed layout inverts it: the declared widths are the truth and the content
   fits them, so this table is the width of its card by construction. The cost is
   that overflow becomes the cell's problem, which is what the truncation below
   is for.

   `.rbpg-table--fixed` above is the same idea and is NOT reused here, for one
   reason: it carries `min-width: 54rem` for wide full-page tables, and this card
   is half a split row at about 43rem — so adopting it would reintroduce the
   sideways scroll it otherwise cures.

   Small text across every column, and tighter gutters than the app default. Both
   buy width, and the first also settles an inconsistency: Case and When were
   `small` while Customer and Supplier were not, so one table was being read at
   two sizes.

   The doubled `.table.rv-table` is not decoration: the defaults it is overriding
   are `.table.rbpg-table tbody td`, and a single class loses to them. */
.table.rv-table { table-layout: fixed; }
.table.rv-table thead th { padding-left: 0.75rem; padding-right: 0.75rem; }
.table.rv-table tbody td {
  font-size: 0.82rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}

/* Reviews is a dense operational inbox. Keep the paired card headers the same
   height and make their controls genuinely small: the theme's base `.btn` rule
   loads after Bootstrap and otherwise overrides `btn-sm` back to full size. */
.rv-page .rbpg-list-card > .card-header {
  min-height: 3.25rem;
  padding: 0.7rem 1rem;
}
.rv-page .rbpg-list-card > .card-header .card-title { font-size: 0.95rem; }
.rv-page #rv-recompute,
.rv-page .rbpg-pager .btn {
  padding: 0.3rem 0.65rem;
  border-radius: 0.45rem;
  font-size: 0.75rem;
  line-height: 1.2;
}
.rv-page .rbpg-pager {
  padding: 0.6rem 1rem;
  gap: 0.5rem;
}
.rv-page .rbpg-pager .page-info { font-size: 0.75rem; }
.rv-page .rbpg-pager .d-flex { gap: 0.4rem !important; }

/* A scanning table, so every row is one line high and the columns line up all
   the way down. Names truncate rather than wrap: a long supplier name that wraps
   sets its whole row two lines tall and breaks the rhythm the table exists for.
   The full name stays readable via the link itself.

   No max-width: under fixed layout the column is already the limit, and a second
   one here would only stop a name using the room it has been given. */
.rv-cell-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Stars and the comment marker on one line. No number beside them: a customer
   rating is a whole number, so the glyphs already say it exactly. */
.rv-cell-rating { white-space: nowrap; }

/* A case reference is one token and must stay on one line. Under fixed layout a
   column no longer widens to fit its content, so "5041086" in a 5rem column
   broke across two lines and set that one row 23px taller than the rest — the
   exact fault the truncation rules above exist to prevent, arriving through the
   one cell that had no rule of its own. */
.rv-cell-ref {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "14 Jul 2026" is three words, and this table sits next to the by-supplier
   panel with barely 500px to divide five ways. Let the date wrap and it stacks
   into three lines, which sets the row three times taller than its neighbours —
   the single worst offender against a table whose whole job is to be scanned. */
.rv-cell-when { white-space: nowrap; }

/* The five-bar spread. Five numbers do not need a charting library, and this
   reads at a glance in a card that is 4rem tall. */
.rv-dist { display: grid; gap: 0.25rem; }

.rv-dist-row { display: flex; align-items: center; gap: 0.5rem; }

.rv-dist-label {
  font-size: 0.7rem;
  color: var(--rbpg-muted);
  width: 1.7rem;
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}

.rv-dist-track {
  flex: 1 1 auto;
  height: 6px;
  border-radius: 3px;
  background: var(--rbpg-grey);
  overflow: hidden;
}

/* Amber, matching the stars, so the bars and the glyphs above them are
   obviously about the same quantity. */
.rv-dist-fill { display: block; height: 100%; background: var(--rbpg-star); border-radius: 3px; }

.rv-dist-n {
  font-size: 0.7rem;
  color: var(--rbpg-muted);
  width: 2.5rem;
  flex: 0 0 auto;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* One review, read in full (RBPGReviewModal). Ordered the way a public review
   card is — who, how many stars, when, then the words — because that is the
   order somebody already expects to read them in. */
.rvm-who { font-size: 1.05rem; font-weight: 700; line-height: 1.2; }
.rvm-stars { margin-top: 0.45rem; }
.rvm-when { margin-top: 0.35rem; font-size: 0.8rem; color: var(--rbpg-muted); }

/* The gap above is the point: it separates the customer from their sentence, so
   the prose reads as a quotation rather than another field in a form. */
.rvm-comment {
  margin-top: 1.35rem;
  font-size: 1rem;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.rvm-comment--empty { color: var(--rbpg-muted); font-style: italic; }

.rvm-meta {
  margin-top: 1.35rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rbpg-border);
  font-size: 0.8rem;
  color: var(--rbpg-muted);
}

/* Visually hidden, still read aloud. The stars are aria-hidden, so this is the
   whole accessible name for a rating: "4.9 out of 5, from 156 reviews". */
.rbpg-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* SET-2/3 — Settings hub and compact Brand administration. */
.set-identity {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-right: 3rem;
}
.set-platform-mark {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 7.5rem;
  height: 64px;
  padding: 0 0.75rem;
  background: #fff;
  border: 1px solid var(--rbpg-border);
  border-radius: 10px;
}
.set-platform-mark img {
  display: block;
  max-height: 24px;
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
.set-platform-mark-word {
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.75rem;
}
.set-identity-side {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
}
.set-identity-dots {
  line-height: 1;
  padding: 0.3rem 0.55rem;
}
.set-identity-side .dropdown-item {
  font-size: 0.8125rem;
  padding: 0.3rem 0.85rem;
}
.set-identity-side .dropdown-menu {
  min-width: 8rem;
}

/* Settings hub cards (NAV-2). The whole card is the link, so the hit target is the
   card and not a word at the bottom of it. */
.set-card {
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.set-card:hover, .set-card:focus-visible {
  border-color: var(--rbpg-accent, #0d6efd);
  transform: translateY(-2px);
  color: inherit;
}
.set-card-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.set-card-head svg { color: var(--rbpg-muted); flex: 0 0 auto; }
/* Empty on every card but Brands, which fills it with its counts. Reserving the
   space keeps the explanations on one baseline across the row. */
.set-card-foot { padding-top: 0.75rem; min-height: 1.25rem; }

.br-search { width: min(22rem, 100%); }
.br-status { width: 10rem; }
.br-table { table-layout: fixed; }
.br-table th:nth-child(1) { width: 28%; }
.br-table th:nth-child(2) { width: 25%; }
.br-table th:nth-child(3) { width: 18%; }
.br-table th:nth-child(4) { width: 15%; }
.br-table th:nth-child(5) { width: 14%; }

.br-logo {
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--rbpg-border);
  border-radius: 0.4rem;
  object-fit: contain;
  background: #fff;
  flex: 0 0 auto;
}

.br-logo--empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--rbpg-muted);
  background: var(--rbpg-grey);
  font-weight: 700;
}

.br-url {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.br-url a {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 767.98px) {
  .br-table th:nth-child(2), .br-table td:nth-child(2),
  .br-table th:nth-child(4), .br-table td:nth-child(4) { display: none; }
  .br-table th:nth-child(1) { width: 45%; }
  .br-table th:nth-child(3) { width: 32%; }
  .br-table th:nth-child(5) { width: 23%; }
}

/* Automations — what the system may say to a customer unattended, and what
   waits for a person. The step rows are a list rather than a table because the
   only column that matters is the switch on the right. */
.au-hint {
  color: var(--rbpg-muted);
  font-size: 0.82rem;
  margin-bottom: 1rem;
}

.au-strong { font-weight: 600; }

/* The pointer to the approval queue in the Message center. Deliberately a
   single row: the drafts are actioned there, not here. */
.au-queue-link {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  color: inherit;
  text-decoration: none;
}

.au-queue-link:hover { border-color: var(--rbpg-primary, #2563eb); color: inherit; }

.au-queue-figure {
  flex: 0 0 auto;
  min-width: 2.4rem;
  padding: 0.15rem 0.5rem;
  border-radius: 0.5rem;
  background: var(--rbpg-surface-2, #f1f5f9);
  color: var(--rbpg-muted);
  font-weight: 700;
  font-size: 1.05rem;
  text-align: center;
}

/* Something is actually waiting on a person — say so in the colour used for
   everything else that is overdue. */
.au-queue-link--waiting .au-queue-figure { background: #fee2e2; color: #b91c1c; }

.au-queue-text { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.au-queue-text span { font-size: 0.82rem; }

.au-wf { border-top: 1px solid var(--rbpg-border); }
.au-wf:first-child { border-top: 0; }
/* An off workflow sends nothing, so its step switches are context, not controls. */
.au-wf--off .au-step { opacity: 0.55; }

.au-wf-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1rem;
  background: var(--rbpg-surface-2, #f8fafc);
}

.au-step {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 1rem 0.7rem 2rem;
  border-top: 1px solid var(--rbpg-border);
}

.au-step-main { min-width: 0; }
.au-step-main .au-strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.au-step-mode { flex: 0 0 11rem; }

@media (max-width: 767.98px) {
  .au-step { align-items: flex-start; flex-direction: column; padding-left: 1rem; }
  .au-step-mode { flex: none; }
}

/* ==========================================================================
   Card payments panel (RBPGPaymentAccount, EST-4 §3.12)

   One row per capability Stripe was asked about, each carrying its own pill.
   The shape is the QC checklist's, because an operator reading "did this pass?"
   down a column should not have to learn a second layout to do it.
   ========================================================================== */

.pa-checks {
  margin-top: 1rem;
  border-top: 1px solid var(--rbpg-border);
}

/* After the facts there is already a hairline closing the last row, so the
   checklist continues the same ruled column instead of drawing a second line
   1px away from the first. */
.pa-facts + .pa-checks { margin-top: 0; border-top: 0; }

.pa-check {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--rbpg-border);
  font-size: 0.8125rem;
}

.pa-check-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.pa-check-note {
  color: var(--rbpg-muted);
  font-size: 0.75rem;
}

.pa-check-state { flex: none; }

/* A second checklist under an unrelated one (the print card carries the printers
   and then what the traveller shows) needs air and a heading, or the two read as
   one list of six things. The margin is deliberately larger than the row gap. */
.pa-checks-sep { margin-top: 1.6rem; }

.pa-check-head {
  padding-bottom: 0.45rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--rbpg-muted);
}

/* A switch used as a row's control, rather than beside its own label: the label
   is the row's text on the left, so the switch itself must not reserve the
   indent Bootstrap's form-check keeps for one. */
.pa-check-state .pa-switch .form-check { padding-left: 0; min-height: 0; }

/* ---- The facts, once connected ------------------------------------------
   Label left, answer right, hairline between. This replaced a Bootstrap
   `dl.row`, whose col-sm-4 / col-sm-8 split put a two-word answer at the far
   end of an eight-column cell — so a one-word status appeared to span the card
   with nothing to anchor it. A two-column flex row sizes to its content. */
.pa-facts {
  margin-top: 0.9rem;
  border-top: 1px solid var(--rbpg-border);
  font-size: 0.8125rem;
}

.pa-fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--rbpg-border);
}

.pa-fact-k { color: var(--rbpg-muted); }
.pa-fact-v { flex: none; text-align: right; }
/* A date is a fact, not a finding — muted, so the eye passes over it and stops
   on the two rows that say whether this thing works. */
.pa-fact-quiet, .pa-fact-none { color: var(--rbpg-muted); }

/* Status as a mark and a word. `align-items: center` on an inline-flex keeps the
   icon on the text's optical centre rather than its baseline, where a check
   glyph sits noticeably low. */
.pa-ok, .pa-bad, .pa-none {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-weight: 500;
  white-space: nowrap;
}
.pa-ok { color: #15803d; }
.pa-bad { color: #b45309; }
.pa-none { color: var(--rbpg-muted); font-weight: 400; }
.pa-i { flex: none; }

/* The last four of the stored key. Monospaced so the digits line up against the
   same four read off the Stripe dashboard, which is the only thing it is for. */
.pa-mask {
  font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
  letter-spacing: 0.05em;
}

.pa-warn-list {
  padding-left: 1.1rem;
  font-size: 0.875rem;
  color: var(--rbpg-muted);
}
.pa-warn-list li { margin-bottom: 0.35rem; }

/* ---- Taking cards: on or off --------------------------------------------
   A switch, not the three-way select this used to be. Test versus live is a
   property of the key and was never this control's to change, so what is left
   is one decision and it gets the shape of one. */
.pa-switch { display: inline-flex; align-items: center; }
.pa-switch .form-check { display: inline-flex; align-items: center; gap: 0.55rem; padding-left: 0; }
.pa-switch .form-check-input { margin: 0; flex: none; cursor: pointer; }
.pa-switch-label {
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

/* ---- Lead routing (ROUTE-15) ---------------------------------------------------
   A switch row: what the switch does on the left with what is happening now under it,
   the mono switch on the right, a hairline between rows. It saves on its own, so the
   right gutter shows saving / Saved, and a failed save is said under its own row. */
.lr-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.lr-row + .lr-row { margin-top: 0.85rem; padding-top: 0.85rem; border-top: 1px solid var(--rbpg-border); }
/* An option of the switch above it: indented under it, shown only while that switch is on. */
.lr-row + .lr-row.lr-row--sub { margin: 0.75rem 0 0 0.25rem; padding: 0 0 0 1rem; border-top: 0; border-left: 2px solid var(--rbpg-border); }
.lr-row__text { flex: 1 1 auto; min-width: 0; }
.lr-row__title { display: block; margin: 0; font-size: var(--type-row); font-weight: var(--weight-strong); line-height: 1.35; color: var(--rbpg-text); cursor: pointer; }
.lr-row__state { margin-top: 0.2rem; font-size: var(--type-meta); line-height: 1.4; color: var(--rbpg-muted); }
.lr-row__state strong { color: var(--rbpg-text); font-weight: var(--weight-strong); }
.lr-row__error { margin-top: 0.3rem; font-size: var(--type-meta); line-height: 1.4; font-weight: var(--weight-strong); color: var(--tone-bad-ink); }
.lr-row__control { flex: none; display: flex; align-items: center; gap: 0.5rem; min-height: 1.35rem; }
.lr-row__note { font-size: var(--type-meta); color: var(--rbpg-muted); white-space: nowrap; }
.lr-row .form-switch { padding-left: 0; margin: 0; min-height: 0; }
.lr-row .form-check-input { float: none; width: 2.25rem; height: 1.25rem; margin: 0; cursor: pointer; }
.lr-row .form-check-input:checked { background-color: #3f3f46; border-color: #3f3f46; }
.lr-row .form-check-input:focus { border-color: #3f3f46; box-shadow: 0 0 0 0.2rem rgba(63, 63, 70, 0.14); }

/* Every number on the page is a Pipeline tile. A tile that only shows keeps its border on
   hover; one that filters the list shows it is picked the way an option card does. */
.rbpg-floor .lr-tile .ws-card-age { display: block; font-weight: 400; line-height: 1.35; }
.rbpg-floor div.lr-tile { cursor: default; }
.rbpg-floor div.lr-tile.ws-card--muted:hover { border-color: var(--rbpg-border); }
.rbpg-floor div.lr-tile.ws-card--ok:hover { border-color: #bbf7d0; }
.rbpg-floor div.lr-tile.ws-card--warn:hover { border-color: #fde68a; }
.rbpg-floor div.lr-tile.ws-card--bad:hover { border-color: #fecaca; }
.rbpg-floor a.lr-tile.is-active { border-color: #3f3f46; box-shadow: inset 0 0 0 1px #3f3f46; }
/* The option in force: the Pipeline tile's pale-yellow hover, grey border, with a check. */
.rbpg-floor .lr-tile.is-current, .rbpg-floor div.lr-tile.is-current:hover { background: #fefce8; border-color: var(--rbpg-border); }
.lr-tile__current { font-size: var(--type-meta); font-weight: var(--weight-strong); color: var(--rbpg-text); white-space: nowrap; }
@media (min-width: 992px) {
  .rbpg-floor__groups.rbpg-floor__groups--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rbpg-floor__groups.rbpg-floor__groups--3.lr-groups--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Learning off: its rules are not in force, so they read as one quiet sentence, not live figures. */
.rbpg-floor__stats.lr-rules { display: block; }
.lr-rules__text { margin: 0; max-width: 46rem; font-size: var(--type-body); line-height: 1.5; color: var(--rbpg-muted); }
.lr-row__warn { margin-top: 0.3rem; font-size: var(--type-meta); line-height: 1.4; font-weight: var(--weight-strong); color: var(--tone-warn-ink); }
.lr-row__warn a { color: inherit; }

/* The health bands as one strip, 0 to 100: names over it, thresholds under it. */
.rbpg-bandbar__names, .rbpg-bandbar__ticks { position: relative; height: 1.1rem; font-size: var(--type-meta); line-height: 1.1rem; color: var(--rbpg-muted); }
.rbpg-bandbar__names > span, .rbpg-bandbar__ticks > span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.rbpg-bandbar__names > span { font-weight: var(--weight-strong); color: var(--rbpg-text); }
.rbpg-bandbar__ticks { margin-top: 0.3rem; font-variant-numeric: tabular-nums; }
.rbpg-bandbar__ticks > span:first-child { transform: none; }
.rbpg-bandbar__ticks > span:last-child { transform: translateX(-100%); }
.rbpg-bandbar__track { display: flex; gap: 2px; height: 8px; margin-top: 0.3rem; }
.rbpg-bandbar__seg { display: block; height: 100%; }
.rbpg-bandbar__seg:first-child { border-radius: 999px 0 0 999px; }
.rbpg-bandbar__seg:last-child { border-radius: 0 999px 999px 0; }
.rbpg-bandbar__seg--ok { background: var(--meter-ok); }
.rbpg-bandbar__seg--warn { background: var(--meter-warn); }
.rbpg-bandbar__seg--bad { background: var(--meter-bad); }

/* Edit health score: one row per part, weight and scale side by side, the vendor
   editors' dashed rule between rows. */
.rbpg-setgrid { display: grid; grid-template-columns: minmax(0, 1fr) 6.5rem 7.5rem 7.5rem; gap: 0.25rem 0.75rem; align-items: center; padding: 0.55rem 0; }
.rbpg-setgrid + .rbpg-setgrid { border-top: 1px dashed var(--rbpg-border); }
.rbpg-setgrid--head { padding: 0 0 0.25rem; }
.rbpg-setgrid.rbpg-setgrid--head + .rbpg-setgrid { border-top: 0; }
.rbpg-setgrid + .rbpg-setgrid.rbpg-setgrid--total { border-top-style: solid; }
.rbpg-setgrid .form-hint { margin-top: 0.15rem; }
.rbpg-setgrid__error { grid-column: 1 / -1; margin-top: 0; }
/* Learning's pause rule reads as the sentence it is, with its two numbers in it. */
.lr-sentence { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.5rem; font-size: 0.86rem; }
.lr-sentence__input { width: 4.5rem; }
/* One size for every number box in these editors: the SLA editor's small select. */
.rbpg-modal .rbpg-setgrid .form-control-sm,
.rbpg-modal .ve-sl-control .form-control-sm,
.rbpg-modal .lr-sentence .form-control-sm { font-size: 0.84rem; padding: 0.3rem 0.6rem; }
.rbpg-modal.ve-modal .modal-body .input-group-sm > .input-group-text { padding: 0.3rem 0.6rem; font-size: 0.84rem; }
.rbpg-modal.ve-modal .invalid-feedback:empty { display: none !important; }

/* ---- Option cards as a radio group (CUST-CLEAN-2, the Contact tidy modal) ----
   Three cards side by side with the same parts in the same order, so they compare at a glance. The selected one has
   the mono border and a filled dot; the group is the radiogroup, each card a radio. */
.rbpg-choice-group { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; }
@media (max-width: 767px) { .rbpg-choice-group { grid-template-columns: 1fr; } }
.rbpg-choice { border: 1px solid var(--rbpg-border, #e4e4e7); border-radius: 10px; padding: 0.85rem 0.9rem; cursor: pointer; background: #fff; transition: background-color .12s, border-color .12s; }
.rbpg-choice:hover { background: #fafafa; }
.rbpg-choice.is-locked { opacity: .55; cursor: not-allowed; }
.rbpg-choice:focus-visible { outline: 0; box-shadow: 0 0 0 0.2rem rgba(63, 63, 70, 0.18); }
.rbpg-choice.is-selected { border-color: #3f3f46; box-shadow: inset 0 0 0 1px #3f3f46; }
/* Softer pick for the Workshop set-up cards: pale warn field, thin border, dark dot as before.
   A modifier on the group, so the contact-tidy cards keep their dark outline. */
.rbpg-choice-group--soft .rbpg-choice.is-selected { background: var(--tone-warn-tint); border-color: var(--tone-warn-lit); box-shadow: none; }
.rbpg-choice__head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.35rem; }
.rbpg-choice__dot { flex: none; width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid #a1a1aa; position: relative; }
.rbpg-choice.is-selected .rbpg-choice__dot { border-color: #3f3f46; }
.rbpg-choice.is-selected .rbpg-choice__dot::after { content: ''; position: absolute; inset: 2.5px; border-radius: 50%; background: #3f3f46; }
.rbpg-choice__title { font-weight: 700; font-size: 0.875rem; }
.rbpg-choice__tag { margin-left: auto; font-size: 0.68rem; }
.rbpg-choice__line { font-size: 0.8125rem; font-weight: 600; margin: 0 0 0.5rem; }
.rbpg-choice__parts { margin: 0; font-size: 0.775rem; line-height: 1.4; }
.rbpg-choice__parts dt { font-weight: 600; color: var(--rbpg-muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: .03em; margin-top: 0.45rem; }
.rbpg-choice__parts dd { margin: 0.1rem 0 0; }
.rbpg-choice__parts code { font-size: 0.75rem; color: inherit; background: #f4f4f5; padding: 0 0.2rem; border-radius: 3px; }
.rbpg-choice__never { font-size: 0.8125rem; padding-left: 1.1rem; }
/* Workshop set-up: Best for sits on the card's floor under a dotted rule, level across the row. */
.rbpg-choice-group--soft .rbpg-choice { display: flex; flex-direction: column; }
.rbpg-choice__best { margin-top: auto; }
.rbpg-choice__best > dl { margin-top: 0.75rem; padding-top: 0.1rem; border-top: 1px dotted #a1a1aa; }

/* ---- Contact tidy feed card (CUST-CLEAN-2) -------------------------------
   Same chrome as the enquiry card (`pq-intake`). One row per change: what, was → now, then the row's buttons or
   state. Values are masked by the server; the card only lays them out. */
.pq-tidy-row { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) auto; gap: 0.15rem 0.75rem; align-items: baseline; padding: 0.3rem 0; font-size: 0.82rem; }
.pq-tidy-row + .pq-tidy-row { border-top: 1px dashed var(--rbpg-border, #e4e4e7); }
.pq-tidy-label { font-weight: 600; color: var(--rbpg-muted); }
.pq-tidy-vals { min-width: 0; overflow-wrap: anywhere; }
.pq-tidy-was { color: var(--rbpg-muted); }
.pq-tidy-arrow { color: var(--rbpg-muted); margin: 0 0.3rem; }
.pq-tidy-note { grid-column: 2 / -1; font-size: 0.75rem; color: var(--rbpg-muted); }
/* Buttons sit at the end of the row, so Undo lands at the end like Apply did. A value never breaks inside itself. */
.pq-tidy-acts { display: flex; gap: 0.35rem; justify-content: flex-end; white-space: nowrap; }
.pq-tidy-was, .pq-tidy-now { white-space: nowrap; }
.pq-intake-pill.pq-tidy-pill--done { color: var(--tone-ok-ink); }
.pq-tidy-state { font-size: 0.75rem; color: var(--rbpg-muted); white-space: nowrap; }
.pq-tidy-err { grid-column: 2 / -1; font-size: 0.75rem; color: var(--tone-bad-ink, #b91c1c); }
.pq-tidy-head-acts { margin-left: auto; }

/* ---- Who does the Stripe sign-up (admin only) ---------------------------
   The same block as the lock at the top of the "What they repair" editor: a
   small bold label beside the switch, the consequence in a hint indented to
   clear it. The sizes are stated here because `.form-hint` is only dressed
   inside a modal, and this panel is a card. */
.pa-grant {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rbpg-border);
}
.pa-grant .form-check-label {
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}
.pa-grant .form-hint {
  margin: 0.15rem 0 0;
  /* rem, not em: it has to clear Bootstrap's 2.5em switch indent, which is
     measured against the row's font size rather than this smaller one. */
  padding-left: 2.5rem;
  font-size: 0.775rem;
  line-height: 1.4;
  color: var(--rbpg-muted);
}

/* Which Stripe environment the keys are for. Only test earns a chip: live is
   the unremarkable case, and "no real money is moving" is the part worth
   saying out loud beside the account name. */
.pa-kind-chip {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid rgba(99, 91, 255, 0.35);
  border-radius: 0.25rem;
  background: rgba(99, 91, 255, 0.08);
  color: #4f46e5;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  vertical-align: middle;
}

.pa-actions { margin-top: 1.25rem; }

/* ---- Not connected: an empty state, not a table with one row ------------
   Deliberately no status pill. A badge reading "Not connected" above a button
   reading "Connect Stripe" restates the button and spends the full width of
   the card on one grey word. What earns the space is what connecting does. */
.pa-empty {
  padding: 0.25rem 0 0;
}
.pa-empty-lead {
  margin: 0 0 0.35rem;
  font-weight: 600;
  color: var(--rbpg-ink, #18181b);
}
.pa-empty-note {
  margin: 0 0 1.1rem;
  max-width: 60ch;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--rbpg-muted);
}
/* SUP-14: the "don't have an account yet" steps under the Connect button on
   the vendor's own settings page. Same voice and measure as the note above. */
.pa-empty-help {
  margin: 1.1rem 0 0;
  max-width: 60ch;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--rbpg-muted);
}
.pa-empty-help-lead {
  margin: 0 0 0.35rem;
  font-weight: 600;
  color: var(--rbpg-ink, #18181b);
}
.pa-empty-help ol {
  margin: 0;
  padding-left: 1.25rem;
}
.pa-empty-help li + li {
  margin-top: 0.25rem;
}

/* ---- Connected: identity and state in one strip -------------------------
   The two things worth seeing without reading — whose account, and whether it
   is taking real money. Everything you only look up when something is wrong
   stays in the table below. */
.pa-head {
  /* The two lines' type, declared once, because the mark beside them is sized
     from it. Change a line's size here and the mark follows. */
  --pa-head-lh: 1.25;
  --pa-head-name-size: 0.875rem;
  --pa-head-acct-size: 0.75rem;
  --pa-head-mark-size: calc(var(--pa-head-lh) * (var(--pa-head-name-size) + var(--pa-head-acct-size)));

  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--rbpg-border);
}
.pa-head-id {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
}
/* Stripe's indigo on the mark only. The button is the coloured thing on this
   card; a second filled block of it would compete with the action. */
/* Square, and exactly as tall as the two lines beside it, top edge to bottom
   edge. It was a fixed 30px against a 32.5px text block, and on a card where
   every other row lines up that 2.5px reads as a mistake. The size is computed
   from the same type as the text rather than written out again, so it cannot
   drift. (`align-self: stretch` with `aspect-ratio: 1` looks like the tidier
   answer and is not: flexbox will not take a width from a stretched height, so
   the box ends up the right height and the wrong width.) */
.pa-head-mark {
  flex: none;
  display: grid;
  place-items: center;
  width: var(--pa-head-mark-size);
  height: var(--pa-head-mark-size);
  border-radius: 8px;
  background: rgba(99, 91, 255, 0.1);
  color: #635bff;
}
/* A carrier's own wordmark in the mark slot (RM-1): no tinted square, the logo
   carries its own colour block. */
.pa-head-mark--logo { width: auto; background: none; border-radius: 0; }
/* Bank transfer (EST-50): the card's own mark, mono rather than Stripe indigo. */
.pa-head-mark--bank { background: var(--rbpg-hover, #f4f4f5); color: var(--rbpg-ink, #18181b); }
/* A masked value and the eye that shows it, in a fact row or a case panel. */
.ba-secret { display: inline-flex; align-items: center; gap: 0.35rem; }
.ba-eye {
  display: inline-grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--rbpg-muted, #71717a);
  cursor: pointer;
}
.ba-eye:hover, .ba-eye[aria-pressed="true"] { background: var(--rbpg-hover, #f4f4f5); color: var(--rbpg-ink, #18181b); }
/* The read-only account, as the case page's Show opens it. */
.ba-view { border: 1px solid var(--rbpg-border, #e4e4e7); border-radius: 10px; }
.ba-view-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.75rem;
  border-top: 1px solid var(--rbpg-border, #e4e4e7);
}
.ba-view-row:first-child { border-top: 0; }
.ba-view-k { flex: 0 0 8.5rem; font-size: 0.8125rem; color: var(--rbpg-muted, #71717a); }
.ba-view-v { flex: 1; min-width: 0; font-weight: 500; overflow-wrap: anywhere; }
.ba-view-v.is-mono { font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace); }
.rbpg-carrier-logo {
  display: inline-block;
  height: 1.25rem;
  width: auto;
  border-radius: 3px;
  vertical-align: middle;
  flex: none;
}
.pa-head-mark--logo .rbpg-carrier-logo { height: 1.5rem; }
.rbpg-title-logo { display: inline-flex; align-items: center; gap: 0.5rem; }
.pa-head-text { min-width: 0; display: flex; flex-direction: column; line-height: var(--pa-head-lh); }
.pa-head-name {
  font-size: var(--pa-head-name-size);
  font-weight: 600;
  color: var(--rbpg-ink, #18181b);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pa-head-acct {
  font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: var(--pa-head-acct-size);
  color: var(--rbpg-muted);
}
.pa-head-mode { flex: none; }

/* On a phone the pill drops under the label rather than squeezing the sentence
   that explains what failed into a two-word column. */
@media (max-width: 575.98px) {
  .pa-check { align-items: flex-start; flex-direction: column; gap: 0.35rem; }
  /* The switch drops under the account name rather than being squeezed beside
     it, which on a narrow phone would truncate whichever of the two is longer. */
  .pa-head { align-items: flex-start; }
  .pa-head-mode { width: 100%; }
}

/* ---- Workshop lanes (WF-3 settings) --------------------------------------
   The lane editor is a form laid out as a table, which is why it needs its own
   rules rather than the list-table defaults.

   It shipped on a bare `.table.table-sm` inside `.card-body.p-0`, so the first
   column's inputs sat flush against the card's left edge with nothing between
   text and border. `.rbpg-table` is the app's padded-table convention and fixes
   that at a stroke; everything below is what a table of CONTROLS needs on top of
   a table of text. */
.wl-table { table-layout: fixed; min-width: 40rem; }

/* Widths are declared once here rather than as inline `style` on each `th`, so
   the header and the body cannot disagree. Fixed layout means these are the
   truth and the inputs fit them, instead of the inputs setting the width. */
.wl-table th:nth-child(1), .wl-table td:nth-child(1) { width: 34%; }
.wl-table th:nth-child(2), .wl-table td:nth-child(2) { width: 32%; }
.wl-table th:nth-child(3), .wl-table td:nth-child(3) { width: 16%; }
.wl-table th:nth-child(4), .wl-table td:nth-child(4) { width: 18%; text-align: right; }

/* Rows of inputs need less vertical padding than rows of text: a `form-control`
   brings its own, and the convention's 0.95rem on top of it makes the six lanes
   taller than the screen. The horizontal 1.1rem is the point of the exercise and
   is left exactly as it is. */
.wl-table tbody td { padding-top: 0.6rem; padding-bottom: 0.6rem; vertical-align: middle; }

/* The number and its unit are one answer — "four weeks" — so they are one
   control. Roughly a third of the column for the figure leaves the unit enough
   room that "weeks" never clips. */
.wl-target { max-width: 15rem; }
.wl-target > .form-control { flex: 0 0 36%; }

/* Locked lane (`parts`): readable, and visibly not yours to change. Bootstrap
   leaves a readonly input white, which invites the click that does nothing. */
.wl-row--locked input[readonly] {
  background: var(--rbpg-grey);
  color: var(--rbpg-muted);
  cursor: default;
}

/* Switched off. Enough fade to read as inactive at a glance, without dimming the
   switch itself — that is the control you need in order to undo it, and a faded
   toggle is the one thing on the row that must not look unavailable.
   The exclusion is by column because opacity cannot be cancelled by a child. */
.wl-row--hidden td:not(:nth-child(3)) { opacity: 0.5; }

/* Job counts are compared down the column, so they line up on the digit. */
.wl-jobs { font-variant-numeric: tabular-nums; font-weight: 600; }

/* The tray's turnaround: stated, not editable. Reads as a value rather than an empty
   input, because a box here would imply this screen owns a number it does not (WF-14). */
.wl-fixed-target {
  font-size: 0.85rem;
  color: var(--rbpg-muted);
}

/* The card's one-line explanation, under its title. Matches `.modal-subtitle` so
   a heading with a sentence beneath it looks the same wherever it appears. */
.wl-subtitle {
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--rbpg-muted);
  max-width: 62ch;
}

/* Matched to `.app-content .card-header`: the theme restyles the header but leaves
   the footer on Bootstrap's tighter padding and tinted cap, so a card with both
   is lopsided top to bottom. */
.wl-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1.15rem 1.4rem;
  background: transparent;
  border-top: 1px solid var(--rbpg-border);
}

/* Sits beside Save and changes as you type, so it needs a fixed idea of its own
   size — otherwise the button shifts sideways when the hiding warning appears. */
.wl-status { font-size: 0.82rem; line-height: 1.4; color: var(--rbpg-muted); flex: 1 1 18rem; }
.wl-status--warn { color: var(--tone-warn-ink); font-weight: 600; }

/* Explanatory prose, not a form. Wider line height and a measure that stops the
   lines running the full width of a 1280px page. Darker than `--rbpg-muted`,
   which is sized for one-line hints: three paragraphs of it is hard going. */
.wl-note { font-size: 0.875rem; line-height: 1.6; color: #52525b; }
.wl-note strong { color: var(--rbpg-text); font-weight: 600; }
/* About your floor is a short list, full width: no measure on it. */
.wl-note__list { margin: 0; padding-left: 1.15rem; }
.wl-note__list li { margin-bottom: 0.5rem; }
.wl-note__list li:last-child { margin-bottom: 0; }

/* Everything the Workshop set-up component draws (`rbpg-workshop-setup.js`) sits in `.wl-host`: on the
   vendor's page, inside `.app-content`, and in the staff modal, where `.app-content`'s card rules
   do not reach. So the card spacing is stated here too, and the switches are mono (the global
   checked switch is `--rbpg-primary`). `.form-hint` is only dressed inside `.rbpg-modal` and
   `.pa-grant`, so every hint here is small and muted. */
.wl-host .card { margin-bottom: 1.5rem; }
.wl-host .card-header { background: transparent; border-bottom: 1px solid var(--rbpg-border); padding: 1.15rem 1.4rem; }
.wl-host .card-header .card-title { font-size: 1.02rem; font-weight: 700; }
.wl-host .card-body { padding: 1.4rem; }
.wl-host .card-body.p-0 { padding: 0; }
.wl-host .form-check-input:checked { background-color: #3f3f46; border-color: #3f3f46; }
.wl-host .form-hint { font-size: 0.775rem; line-height: 1.4; color: var(--rbpg-muted); }

/* The staff modal (full screen): the sections at the page's content width, centred. */
.ws-setup-wrap { max-width: calc(1280px - 3.5rem); margin: 0 auto; }
/* The confirm that moves jobs opens over it; all modals share a z-index, so say which is on top. */
body.ws-setup-open .modal-backdrop ~ .modal-backdrop { z-index: 3610; }
body.ws-setup-open #rbpgConfirm { z-index: 3620; }

/* Below this the four columns cannot hold an input each, so the table scrolls
   sideways inside its card rather than crushing the controls. */
@media (max-width: 767.98px) {
  .wl-table { min-width: 34rem; }
  .wl-table tbody td { padding-left: 0.75rem; padding-right: 0.75rem; }
  .wl-table thead th { padding-left: 0.75rem; padding-right: 0.75rem; }
}

/* Admin dashboard feeds: five-row cards with the pager pinned under the table.
   Not `.rbpg-list-card` — that one is a full-page list with a 460px floor. */
.dash-feed { display: flex; flex-direction: column; overflow: hidden; }
.dash-feed > .table-responsive { flex: 1 1 auto; }
.dash-feed > .rbpg-pager {
  flex: 0 0 auto;
  border-top: 1px solid var(--rbpg-border);
  padding: 0.55rem 1rem;
  gap: 0.5rem;
}
.dash-feed > .rbpg-pager .page-info { font-size: 0.75rem; }
.dash-feed > .rbpg-pager .btn {
  padding: 0.3rem 0.65rem;
  border-radius: 0.45rem;
  font-size: 0.75rem;
  line-height: 1.2;
}
.dash-feed > .card-header {
  gap: 0.6rem 1rem;
  flex-wrap: wrap;
}
.dash-attn {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.15rem 0.55rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--rbpg-muted);
}
.dash-attn a {
  color: inherit;
  text-decoration: none;
}
.dash-attn a:hover { text-decoration: underline; }
.dash-attn-link--warn { color: var(--tone-warn-ink); }
.dash-attn-link--alert { color: var(--tone-bad-ink); }

/* Same type as Recent cases (`.rbpg-table--cases`): 0.68rem headers, 0.78rem cells. */
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) thead th {
  font-size: 0.68rem;
  padding: 0.7rem 1.1rem;
}
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) tbody td,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .rbpg-case-link,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .rbpg-case-title,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .rbpg-who-name,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .rbpg-who-sub,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .rbpg-age,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .qcq-verdict {
  font-size: 0.78rem;
  line-height: 1.3;
}
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) tbody td { padding: 0.7rem 1.1rem; }

/* Bench camera. The preview is the dialog; the shutter is the only large control. */
.rbpg-modal.rbpg-modal--camera .modal-dialog { max-width: 960px; }
.rbpg-cam-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 420px;
  background: #18181b;
  border-radius: var(--rbpg-radius);
  overflow: hidden;
}
.rbpg-cam-stage video,
.rbpg-cam-still {
  width: 100%;
  max-height: 62vh;
  object-fit: contain;
  background: #18181b;
  display: block;
}
.rbpg-cam-still { position: absolute; inset: 0; height: 100%; }
.rbpg-cam-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to right, transparent 33.33%, rgba(255,255,255,.55) 33.33%, rgba(255,255,255,.55) calc(33.33% + 1px), transparent calc(33.33% + 1px), transparent 66.66%, rgba(255,255,255,.55) 66.66%, rgba(255,255,255,.55) calc(66.66% + 1px), transparent calc(66.66% + 1px)),
    linear-gradient(to bottom, transparent 33.33%, rgba(255,255,255,.55) 33.33%, rgba(255,255,255,.55) calc(33.33% + 1px), transparent calc(33.33% + 1px), transparent 66.66%, rgba(255,255,255,.55) 66.66%, rgba(255,255,255,.55) calc(66.66% + 1px), transparent calc(66.66% + 1px));
}
.rbpg-cam-grid.is-off { display: none; }
.rbpg-cam-status {
  position: absolute;
  margin: 0;
  color: #e4e4e7;
  font-size: .9rem;
}
.rbpg-cam-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: .75rem;
}
.rbpg-cam-device-name { font-size: .82rem; font-weight: 600; color: var(--rbpg-text); }
.rbpg-cam-devices {
  position: absolute;
  top: calc(100% + .25rem);
  left: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: .2rem;
  min-width: 240px;
  padding: .35rem;
  background: #fff;
  border: 1px solid var(--rbpg-border);
  border-radius: var(--rbpg-radius);
  box-shadow: 0 8px 24px rgba(24, 24, 27, .08);
}
.rbpg-cam-devices .btn { text-align: left; }
.rbpg-cam-devices .btn[aria-current="true"] { font-weight: 700; }
.rbpg-cam-size {
  font-size: .75rem;
  font-weight: 700;
  color: var(--rbpg-muted);
  font-variant-numeric: tabular-nums;
}
.rbpg-cam-size.is-low { color: #b45309; }
.rbpg-cam-light {
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #a16207;
}
.rbpg-cam-stage { --rbpg-cam-crop: 1; --rbpg-cam-mag: 1; }
.rbpg-cam-stage video {
  transform: scale(calc(var(--rbpg-cam-crop) * var(--rbpg-cam-mag)));
  transform-origin: center center;
}
.rbpg-cam-stage.is-magnify { --rbpg-cam-mag: 2; }
.rbpg-cam-stage.is-magnify .rbpg-cam-still { transform: scale(2); transform-origin: center center; }
.rbpg-cam-tools {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin-top: .65rem;
}
.rbpg-cam-tools label {
  display: flex;
  align-items: center;
  gap: .45rem;
  flex: 1;
  margin: 0;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--rbpg-muted);
}
.rbpg-cam-tools input[type="range"] { flex: 1; min-width: 0; }
.rbpg-cam-focus {
  margin-left: auto;
  font-size: .95rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.rbpg-cam-focus.is-sharp { color: #166534; }
.rbpg-cam-focus.is-soft { color: #a16207; }
.rbpg-cam-notice { margin: .45rem 0 0; font-size: .8rem; color: var(--rbpg-muted); }
.rbpg-cam-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .75rem;
  min-height: 76px;
  margin-top: .85rem;
}
.rbpg-cam-shutter {
  width: 76px;
  height: 76px;
  padding: 0;
  border-radius: 50%;
  border: 4px solid #3f3f46;
  background: #fff;
  box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 6px #3f3f46;
  cursor: pointer;
}
.rbpg-cam-shutter:disabled { opacity: .35; cursor: default; }
.rbpg-cam-shutter:focus-visible { outline: 2px solid #3f3f46; outline-offset: 3px; }
.rbpg-cam-full { margin: .35rem 0 0; text-align: center; font-size: .8rem; color: var(--rbpg-muted); }
.rbpg-cam-strip { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
.rbpg-cam-thumb {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--rbpg-border);
}
.rbpg-cam-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rbpg-cam-thumb-x {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(24, 24, 27, .78);
  color: #fff;
  line-height: 1;
  cursor: pointer;
}
.rbpg-cam-err { margin: .6rem 0 0; font-size: .84rem; color: #b91c1c; }
.rbpg-cam-retry { margin-top: .5rem; }
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .pill,
.dash-feed .table.rbpg-table:not(.rbpg-table--cases) .pq-kind {
  font-size: 0.72rem;
}


/* ==========================================================================
   Vendor cards (SUP-8): the admin's vendor page and the vendor's own Business
   details page draw the same cards from RBPGVendorCards, and share these so the
   two cannot drift apart in height or spacing.
   ========================================================================== */
/* Hero: identity on the left, what you can do on the right. */
.vn-hero { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 1rem; }
/* A logo well, not an avatar. A workshop's logo is a wide lockup far more
   often than a square mark, and the PDF header already fits it into a 200x30pt
   slot WITHOUT cropping (rbpgroupdocs chrome/brand-header.js, which falls back
   to supplier.logo_url when the Brand has none). A 64px square on
   `object-fit: cover` therefore showed the vendor a centre-crop of something
   that prints whole — so the preview was both small and wrong. 240x96 contains
   a wide lockup at full width and still renders a square mark at 96px. */
.vn-logo {
  width: 240px; height: 96px; border-radius: 12px; margin-bottom: .75rem;
  object-fit: contain; padding: 10px; box-sizing: border-box;
}
/* White behind the image because logos are drawn for white; the empty state
   keeps the grey it inherits, so a missing logo still reads as a gap. */
img.vn-logo { background: #fff; }
.vn-sub { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; color: var(--rbpg-muted); font-size: .9rem; }
.vn-hours { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .3rem .9rem; font-size: .9rem; }
.vn-hours .vn-day { display: inline-block; min-width: 2.4rem; color: var(--rbpg-muted); font-weight: 600; }
/* Each card says what it is for before it shows a value. */
.vn-hint { color: var(--rbpg-muted); font-size: .85rem; margin: 0 0 1rem; }
/* Rows that carry a sub-line need a rule between them to read as rows. */
.vn-props > dt, .vn-props > dd { padding-top: .55rem; padding-bottom: .55rem; margin: 0; border-bottom: 1px dotted #ddd; }
.vn-props > dt:nth-last-child(2), .vn-props > dd:last-child { border-bottom: 0; }
@media (max-width: 575.98px) { .vn-props > dt { border-bottom: 0; padding-bottom: 0; } }
/* One value size across every card, links included. */
.vn-cards dl.row > dd { font-size: .9rem; }
/* A card RBP Group owns: the caption sits where the Edit button would be. */
.vn-owned { display: inline-flex; align-items: center; gap: .35rem; color: var(--rbpg-muted); font-size: .8rem; white-space: nowrap; }
.vn-owned svg { width: 13px; height: 13px; }
.rbpg-caps-list { list-style: none; padding: 0; margin: 0 0 .5rem; font-size: .9rem; }
.rbpg-caps-list li { padding: .35rem 0; border-bottom: 1px dotted #ddd; }
.rbpg-caps-list li:last-child { border-bottom: 0; }
/* Set-up checklist (SUP-6): a tone dot, the item, why it matters, one button. */
.rbpg-setup { list-style: none; padding: 0; margin: 0; }
.rbpg-setup li { display: flex; align-items: center; gap: .75rem; padding: .55rem 0; border-bottom: 1px dotted #ddd; font-size: .9rem; }
.rbpg-setup li:last-child { border-bottom: 0; }
.rbpg-setup .dot { width: 9px; height: 9px; border-radius: 999px; flex: 0 0 auto; }
.rbpg-setup li.blocking .dot { background: var(--tone-bad-dot); }
.rbpg-setup li.recommended .dot { background: var(--tone-neutral-dot); }
.rbpg-setup .body { flex: 1 1 auto; min-width: 0; }
.rbpg-setup .why { color: var(--rbpg-muted); font-size: .8rem; }
.rbpg-setup .btn { flex: 0 0 auto; }
/* SUP-12: the sections of the set-up card — the ladder, then what is blocking,
   then what is recommended — separated by a rule that runs the full width of
   the card, not the width of the text. `--bleed` is the card padding it has to
   cancel (`.app-content .card-body`), named so it is obvious what to change if
   that padding ever moves.

   Both bands are open. Recommended was a closed <details>, which hid half the
   card behind a disclosure and left two counts sitting next to each other with
   rows under only one of them. */
.rbpg-band {
  --bleed: 1.4rem;
  margin: 1.35rem calc(-1 * var(--bleed)) 0;
  padding: 1.35rem var(--bleed) 0;
  border-top: 1px solid var(--rbpg-border);
}
.rbpg-band > .ve-sec-title { color: var(--rbpg-muted); margin-bottom: .35rem; }
.rbpg-setup-note { margin: 1rem 0 0; font-size: .8rem; color: var(--rbpg-muted); }

/* ---- The agreement, read and signed (SUP-12 slice B) --------------------
   The document itself in a scrollable panel, with the act underneath it. The
   published page is written for a browser tab, so its headings are sized for a
   full page; they come down here to read as one continuous document. */
/* The agreement, pulled out of its published page and dropped into the signing
   modal. This is a deliberate duplicate of www/assets/css/rbpg-legal.css —
   what you sign and what you re-read afterwards have to look like the same
   document, and the published page cannot bring its own stylesheet through a
   fetch. Change one, change the other.

   `.rbpg-modal .modal-body` sets a uniform 1.6rem padding above; this needs the
   same two-class weight to widen the side margins for a long read. */
.rbpg-modal .modal-body.rbpg-agreement {
  background: #fff;
  padding: 1.9rem 2.1rem;
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #1a1a1a;
  -webkit-font-smoothing: antialiased;
}
.rbpg-agreement h1 { font-size: 1.5em; font-weight: 650; line-height: 1.25; margin: 0 0 .4rem; letter-spacing: -.01em; }
.rbpg-agreement h2 { font-size: 1em; font-weight: 650; margin: 2em 0 .5em; letter-spacing: -.005em; }
.rbpg-agreement p { margin: 0 0 .9em; }
.rbpg-agreement a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

.rbpg-agreement .clause,
.rbpg-agreement .sub {
  padding-left: 3.4em; text-indent: -3.4em; margin-bottom: .75em;
}
.rbpg-agreement .clause > .num,
.rbpg-agreement .sub > .num,
.rbpg-agreement h2 > .num {
  display: inline-block; width: 3.4em; text-indent: 0;
  font-variant-numeric: tabular-nums;
}
.rbpg-agreement .sub { margin-left: 2.4em; }
.rbpg-agreement h2 > .num { font-weight: 650; }

.rbpg-agreement table {
  width: 100%; border-collapse: collapse; margin: 1.25em 0 1.75em;
  font-size: .857em; line-height: 1.45;
}
.rbpg-agreement th,
.rbpg-agreement td {
  border: 1px solid #d8d4cc; padding: .55em .7em;
  text-align: left; vertical-align: top;
}
.rbpg-agreement th { font-weight: 650; background: #faf9f7; }

.rbpg-agreement .legal-meta {
  font-size: .857em; color: #6b6b6b; margin: 0 0 1.8em;
  padding-bottom: 1.4em; border-bottom: 1px solid #d8d4cc;
  font-variant-numeric: tabular-nums;
}
.rbpg-agreement .legal-note {
  font-size: .857em; line-height: 1.5; color: #6b6b6b; margin: 0 0 1.8em;
  padding: .8em 1em; border-left: 3px solid #d8d4cc; background: #faf9f7;
}
.rbpg-agreement .legal-foot {
  margin: 3em 0 0; padding-top: 1.2em;
  border-top: 1px solid #d8d4cc; font-size: .857em; color: #6b6b6b;
}

/* Several contracts signed by one act, read as one scroll. The divide between
   them has to be unmistakable: between two legal documents a thin rule reads as
   a section break, and a vendor who thinks the NDA is clause 1 of the Terms has
   not been shown the NDA. Hence a heavy rule, a counted label, and a closing
   line on the document above it. */
.rbpg-ag-part-label {
  display: flex; flex-wrap: wrap; gap: .5rem;
  text-transform: uppercase; letter-spacing: .07em; font-size: .68rem;
  font-weight: 700; color: #8a8a8a; margin: 0 0 1.1rem;
}
.rbpg-ag-part-n { color: #1a1a1a; }
.rbpg-ag-part + .rbpg-ag-part {
  margin-top: 2.6rem; padding-top: 1.8rem; border-top: 3px solid #1a1a1a;
}
/* Says the document above has finished, so the band below is a new one and not
   an appendix to it. */
.rbpg-ag-part-end {
  margin: 2.4rem 0 0; padding-top: 1.1rem; border-top: 1px solid #d8d4cc;
  font-size: .78em; font-weight: 600; color: #8a8a8a;
  text-transform: uppercase; letter-spacing: .07em;
}
/* The stitched documents each bring their own <h1>; the first one no longer
   sits at the top of the panel, so it does not need to carry the top margin. */
.rbpg-ag-part > h1:first-of-type { margin-top: 0; }

/* Stacked, not a flex row: the gate line, the note and the buttons are three
   paragraphs of a sentence, in that order. Specific enough to beat both
   Bootstrap's `.modal-footer` and the structural fallback above it, which are
   each flex and would otherwise wrap these into a scrambled row on a phone. */
.rbpg-modal .modal-footer.rbpg-agreement-foot { display: block; }
.rbpg-agreement-note { font-size: .78rem; color: var(--rbpg-muted); line-height: 1.45; }
.rbpg-agreement-note > div + div { margin-top: .2rem; }
/* Why the button is not lit yet, and how to get past it. Louder than the
   note below, because a disabled button with no explanation is how people
   get stranded. Goes quiet once they are through the gate. */
.rbpg-agreement-gate {
  font-size: .82rem; line-height: 1.45; color: var(--rbpg-muted); margin-bottom: .35rem;
}
.rbpg-agreement-gate.locked { color: var(--rbpg-text); font-weight: 600; }
.rbpg-agreement-gate [data-ag="pct"] { font-variant-numeric: tabular-nums; }
.rbpg-agreement-err {
  margin-top: .5rem; font-size: .8rem;
  color: var(--tone-bad-ink); background: var(--tone-bad-tint);
  border-radius: 8px; padding: .4rem .6rem;
}
.rbpg-agreement-acts { display: flex; justify-content: flex-end; gap: .5rem; margin-top: .75rem; }

/* Back out of a schedule read inside the agreement panel. Styled as a link,
   not a button: it moves the reader, it does not commit anything. */
.rbpg-agreement-back {
  margin: .3rem 0 0; padding: 0; border: 0; background: none;
  font-size: .85rem; color: var(--rbpg-muted); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.rbpg-agreement-back:hover { color: var(--rbpg-text); }

/* Reading a published document without leaving the card you were looking at. */
/* The viewer frames the published page, which brings its own white background
   and margins — so the frame sits flush and the document does the spacing. */
.rbpg-doc-frame {
  display: block; width: 100%; height: min(76vh, 720px);
  border: 0; background: #fff;
}

/* The re-ask. A banner above the page, not a lock on it — the vendor is still
   trading while they get round to signing. */
.rbpg-terms-banner {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  margin: 0 0 1.25rem; padding: .8rem 1rem;
  border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius);
  background: var(--tone-warn-tint); color: var(--tone-warn-ink);
}
.rbpg-terms-banner .body { flex: 1 1 18rem; min-width: 0; font-size: .86rem; line-height: 1.45; }
.rbpg-terms-banner .acts { flex: 0 0 auto; display: flex; gap: .5rem; }

/* What was signed, read back. Admin Documents tab and the vendor's own card. */
.rbpg-legal { list-style: none; padding: 0; margin: 0; }
.rbpg-legal li {
  display: flex; align-items: baseline; gap: .75rem;
  padding: .5rem 0; border-bottom: 1px dotted #ddd; font-size: .88rem;
}
.rbpg-legal li:last-child { border-bottom: 0; }
.rbpg-legal .doc { flex: 1 1 auto; min-width: 0; }
.rbpg-legal .ver { color: var(--rbpg-muted); font-size: .78rem; }
.rbpg-legal .when { flex: 0 0 auto; color: var(--rbpg-muted); font-size: .8rem; text-align: right; }

/* ---- Accept invite (SUP-11) ------------------------------------------
   The page that turns an invite into a login. The logo is the headline;
   under it, what is being created and who asked. Nothing on it is a grey
   badge: the invited address is a locked input, the role a chip row. */
.ai-head { margin-bottom: 1.25rem; }
.ai-from { margin-bottom: 0; }
.ai-locked { position: relative; }
.ai-locked .form-control { padding-right: 2.5rem; background: var(--rbpg-grey, #f4f4f5); color: var(--rbpg-text); }
.ai-locked .form-control:disabled { opacity: 1; }
.ai-lock { position: absolute; right: .9rem; top: 50%; transform: translateY(-50%); color: var(--rbpg-muted); pointer-events: none; }
.ai-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.ai-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .32rem .7rem; border-radius: 999px;
  font-size: .8rem; font-weight: 600; line-height: 1.2;
  background: var(--tone-neutral-tint); color: var(--tone-neutral-ink);
  border: 1px solid var(--rbpg-border);
}
.ai-chip--key { background: var(--tone-info-tint); color: var(--tone-info-ink); border-color: transparent; }
.ai-chip--owner { background: #3f3f46; color: #fff; border-color: #3f3f46; }
.ai-state { padding: .5rem 0; }
.ai-state-title { font-weight: 700; font-size: 1.05rem; color: var(--rbpg-text); }
.ai-refusal strong { display: block; margin-bottom: .25rem; }
.ai-refusal .btn { margin-top: .6rem; }

/* ---- Key-contact welcome (SUP-11) ------------------------------------
   The modal a key contact meets on sign-in until their details and ID are
   in. A checklist, then the fields it asks for. */
.kcw-list { list-style: none; padding: 0; margin: 0 0 1rem; }
.kcw-list li { display: flex; align-items: center; gap: .6rem; padding: .35rem 0; font-size: .92rem; }
.kcw-list .kcw-dot {
  width: 18px; height: 18px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid var(--rbpg-border-strong, #c4c4c8); display: inline-flex; align-items: center; justify-content: center;
  font-size: .7rem; font-weight: 700; color: #fff;
}
.kcw-list li.done .kcw-dot { background: #3f3f46; border-color: #3f3f46; }
.kcw-list li.pending .kcw-dot { background: #a1a1aa; border-color: #a1a1aa; }
.kcw-list li.bad .kcw-dot { background: var(--tone-bad-dot); border-color: var(--tone-bad-dot); }
.kcw-list .kcw-note { color: var(--rbpg-muted); font-size: .82rem; margin-left: .25rem; }
.kcw-privacy { color: var(--rbpg-muted); font-size: .82rem; }
.rbpg-modal .kcw-list li { font-size: .88rem; padding: .25rem 0; }

/* Dashboard notice: a quiet white strip with a thin amber edge, for "this needs
   doing" items that should be seen without shouting. Replaces the full orange
   alert for approval and key-contact asks. */
.rbpg-notice {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .5rem .75rem;
  margin: 0 0 .75rem; padding: .5rem .8rem;
  background: #fff; color: var(--rbpg-text);
  border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius-ctl);
  font-size: .8rem; line-height: 1.4;
}
.rbpg-notice strong { font-weight: 600; }
.rbpg-notice .btn { padding: .2rem .65rem; font-size: .75rem; white-space: nowrap; }
/* The headline on its own line, the detail under it, muted; the button sits to
   the right, centred against both. On narrow screens the button drops below. */
.rbpg-notice { align-items: center; }
.rbpg-notice > :first-child { flex: 1 1 0; min-width: 0; padding-right: 1rem; color: var(--rbpg-muted); }
.rbpg-notice__title { display: block; color: var(--rbpg-text); }
.rbpg-notice > .btn { flex: 0 0 auto; margin-left: auto; }
/* Something the vendor has to act on. Information (Learning) stays white. */
.rbpg-notice--warn { background: var(--tone-warn-tint); }
@media (max-width: 575.98px) {
  .rbpg-notice > :first-child { flex-basis: 100%; padding-right: 0; }
}

/* Radio cards: one choice from a few, each with its consequence spelled out.
   The whole card is the label, so the target is the card, not a 13px dot.
   Mono like the rest of the modal system: the chosen card takes the text
   colour as its border, never the blue (blue is the page's one primary). */
.rbpg-opts { display: grid; gap: .5rem; }
.rbpg-opt {
  display: grid; grid-template-columns: auto 1fr; gap: .15rem .7rem; align-items: start;
  margin: 0; padding: .75rem .9rem; cursor: pointer;
  background: #fff; border: 1px solid var(--rbpg-border-strong); border-radius: var(--rbpg-radius);
  transition: border-color .12s, background-color .12s;
}
.rbpg-opt:hover { border-color: var(--rbpg-text); }
.rbpg-opt:has(input:checked) { border-color: var(--rbpg-text); background: var(--rbpg-grey); box-shadow: inset 0 0 0 1px var(--rbpg-text); }
.rbpg-opt:has(input:focus-visible) { outline: 2px solid var(--rbpg-text); outline-offset: 2px; }
.rbpg-opt input[type="radio"] { grid-row: 1 / span 3; margin: .2rem 0 0; width: 1rem; height: 1rem; accent-color: var(--rbpg-text); cursor: pointer; }
.rbpg-opt-title { font-size: .9rem; font-weight: 600; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.rbpg-opt-desc { font-size: .8rem; color: var(--rbpg-muted); line-height: 1.45; }
.rbpg-opt-note { font-size: .78rem; color: var(--rbpg-text); line-height: 1.4; }
.rbpg-opt.is-disabled { cursor: not-allowed; background: var(--rbpg-grey); opacity: .65; }
.rbpg-opt.is-disabled:hover { border-color: var(--rbpg-border-strong); }
.rbpg-opt.is-disabled input { cursor: not-allowed; }

/* ---- Auth pages (sign-in): mono -------------------------------------------
   The global theme keeps blue for the app's one hero action. Sign-in has no hero
   action to compete with, so it goes fully mono: grey links, grey focus rings, a
   dark-grey checkbox. Scoped to body.auth-page so nothing else changes. */
body.auth-page a { color: var(--rbpg-text); }
body.auth-page .form-control:focus,
body.auth-page .form-select:focus {
  border-color: var(--rbpg-text);
  box-shadow: 0 0 0 0.2rem rgba(63, 63, 70, 0.14);
}
/* Chrome paints autofilled fields pale blue; keep them white like the rest. */
body.auth-page .form-control:-webkit-autofill,
body.auth-page .form-control:-webkit-autofill:hover,
body.auth-page .form-control:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--rbpg-text);
  -webkit-box-shadow: 0 0 0 1000px var(--rbpg-surface) inset;
  box-shadow: 0 0 0 1000px var(--rbpg-surface) inset;
  caret-color: var(--rbpg-text);
}
body.auth-page .form-control { background-color: var(--rbpg-surface); }
body.auth-page .login-mark { max-height: 32px; }
/* Invite page: the locked email stays grey (it is not editable), and the "key"
   role chip loses its blue tint so the page is mono like sign-in. */
body.auth-page .ai-locked .form-control { background-color: var(--rbpg-grey); }
body.auth-page .ai-chip--key { background: var(--rbpg-grey); color: var(--rbpg-text); border-color: var(--rbpg-border-strong); }
body.auth-page .form-check-input:checked { background-color: #3f3f46; border-color: #3f3f46; }
body.auth-page .form-check-input:focus { border-color: #3f3f46; box-shadow: 0 0 0 0.2rem rgba(63, 63, 70, 0.14); }
body.auth-page .btn:focus,
body.auth-page .btn:focus-visible { box-shadow: 0 0 0 0.2rem rgba(63, 63, 70, 0.18); }

/* "By continuing you agree to REPIID's ..." under the card: small and quiet. */
.auth-legal {
  margin: 1rem 0 0;
  text-align: center;
  font-size: .75rem;
  line-height: 1.5;
  color: var(--rbpg-muted);
}
.auth-legal[hidden], .auth-legal a[hidden] { display: none; }
body.auth-page .auth-legal a { color: var(--rbpg-muted); text-decoration: underline; text-underline-offset: 2px; }
body.auth-page .auth-legal a:hover { color: var(--rbpg-text); }

/* ---- Document review (SUP-17) ---------------------------------------------
   The file on the left, what to check on the right, the decision in the footer.
   Wide, because a PDF needs room to be read beside the panel; the panel scrolls
   on its own so the document never moves while the reviewer works down it. */
.rbpg-modal.rbpg-modal--review .modal-dialog { max-width: 1180px; }
.rbpg-modal--review .modal-header { align-items: center; padding: 1rem 1.25rem 1rem 1.5rem; }
.rbpg-modal--review .modal-title { font-size: 1.05rem; }
.rbpg-modal--review .modal-subtitle { margin-top: .15rem; font-size: .8rem; }
.rbpg-modal--review .btn-close { margin: 0; }
.docreview__head { min-width: 0; flex: 1 1 auto; }
.docreview__head .modal-subtitle { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.docreview__nav { display: flex; align-items: center; gap: .3rem; flex: none; }
.docreview__pos { font-size: .78rem; color: var(--rbpg-muted); margin-right: .35rem; font-variant-numeric: tabular-nums; }
.docreview__navbtn { padding: .25rem .4rem; line-height: 1; }
.docreview__navbtn svg { width: 16px; height: 16px; display: block; }

.docreview { display: grid; grid-template-columns: minmax(0, 1fr) 360px; height: min(74vh, 760px); }
.docreview__preview {
  position: relative; min-height: 0; display: flex; flex-direction: column;
  background: var(--rbpg-grey); border-right: 1px solid var(--rbpg-border);
}
.docreview__stage {
  flex: 1 1 auto; min-height: 0; overflow: auto;
  display: flex; align-items: center; justify-content: center; padding: 1.25rem;
}
.docreview__stage--frame { padding: 0; }
.docreview__stage iframe { display: block; width: 100%; height: 100%; border: 0; background: #fff; }
.docreview__stage img {
  max-width: 100%; max-height: 100%; object-fit: contain; display: block;
  background: #fff; border-radius: 6px; box-shadow: 0 1px 3px rgba(24, 24, 27, .12);
  transition: transform .18s ease;
}
.docreview__stage.is-actual { align-items: flex-start; justify-content: flex-start; }
.docreview__stage.is-actual img { max-width: none; max-height: none; }
.docreview__empty { text-align: center; color: var(--rbpg-muted); font-size: .85rem; }
.docreview__empty svg { width: 36px; height: 36px; margin-bottom: .5rem; }
.docreview__empty p { margin: 0; }

.docreview__tools {
  position: absolute; left: 50%; bottom: .85rem; transform: translateX(-50%);
  display: flex; gap: .15rem; padding: .2rem;
  background: #fff; border: 1px solid var(--rbpg-border); border-radius: 999px;
  box-shadow: 0 4px 14px rgba(24, 24, 27, .10);
}
.docreview__tool {
  display: inline-flex; align-items: center; gap: .35rem;
  border: 0; background: transparent; border-radius: 999px;
  padding: .3rem .7rem; font-size: .75rem; font-weight: 600; color: var(--rbpg-text); cursor: pointer;
}
.docreview__tool:hover, .docreview__tool:focus-visible { background: var(--rbpg-grey); outline: 0; }
.docreview__tool svg { width: 14px; height: 14px; }

.docreview__panel {
  min-height: 0; overflow-y: auto; padding: 1.15rem 1.25rem 1.35rem;
  display: flex; flex-direction: column; gap: 1.1rem;
  font-size: .85rem; color: var(--rbpg-text); background: var(--rbpg-surface);
}
.docreview__panel section { margin: 0; }
.docreview__status { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.docreview__meta { font-size: .78rem; color: var(--rbpg-muted); }
.docreview__h {
  margin: 0 0 .5rem; font-size: .68rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--rbpg-muted);
}
.docreview__hint { margin: -.2rem 0 .6rem; font-size: .78rem; color: var(--rbpg-muted); }
.docreview__note { margin: 0; font-size: .8rem; color: var(--rbpg-muted); }

.docreview__checks { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.docreview__checks li { display: flex; gap: .55rem; line-height: 1.4; }
.docreview__checks svg { flex: none; width: 15px; height: 15px; margin-top: .1rem; color: var(--rbpg-muted); }

.docreview__link {
  background: none; border: 0; padding: 0; font: inherit; font-size: .8rem; font-weight: 600; cursor: pointer;
  color: var(--rbpg-text); text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--rbpg-border-strong);
}
.docreview__link:hover, .docreview__link:focus-visible { color: var(--rbpg-text); text-decoration-color: currentColor; }
.docreview__ext { display: inline-flex; align-items: center; gap: .3rem; margin-top: .7rem; }
.docreview__ext svg { width: 12px; height: 12px; }

.docreview__history { list-style: none; margin: 0; padding: 0; }
.docreview__history li {
  display: flex; align-items: center; gap: .55rem; padding: .5rem 0;
  border-top: 1px solid var(--rbpg-border); font-size: .8rem;
}
.docreview__history li:last-child { border-bottom: 1px solid var(--rbpg-border); }
.docreview__history .pill { font-size: .62rem; padding: .16rem .45rem; }
.docreview__history .pill::before { width: 6px; height: 6px; }
.docreview__hdate { min-width: 5.5rem; font-variant-numeric: tabular-nums; }

.docreview__notice { padding: .8rem .9rem; border-radius: 10px; background: var(--tone-bad-tint); }
.docreview__notice-title { margin: 0 0 .35rem; font-size: .78rem; font-weight: 700; color: var(--tone-bad-ink); }
.docreview__notice ul { margin: 0; padding-left: 1.05rem; }
.docreview__notice li { line-height: 1.45; }
.docreview__notice li + li { margin-top: .2rem; }
.docreview__quote { margin: .5rem 0 0; font-style: italic; color: var(--rbpg-text); }
.docreview__mailstate { margin: .6rem 0 0; font-size: .76rem; color: var(--rbpg-muted); }
.docreview__mailstate.is-bad { color: var(--tone-bad-ink); font-weight: 600; }
.docreview__notice .btn { margin-top: .5rem; }

.docreview__reasons {
  display: grid; background: #fff; border: 1px solid var(--rbpg-border-strong); border-radius: 10px; overflow: hidden;
}
.docreview__reason {
  display: grid; grid-template-columns: auto 1fr; gap: .55rem; align-items: start; margin: 0;
  padding: .45rem .7rem; line-height: 1.38; font-size: .8rem; cursor: pointer;
  border-top: 1px solid var(--rbpg-border); transition: background-color .12s;
}
.docreview__reason:first-child { border-top: 0; }
.docreview__reason:hover { background: var(--rbpg-grey); }
.docreview__reason:has(input:checked) { background: var(--rbpg-grey); font-weight: 600; }
.docreview__reason:has(input:focus-visible) { outline: 2px solid var(--rbpg-text); outline-offset: -2px; }
.docreview__reason input { width: 1rem; height: 1rem; margin: .1rem 0 0; accent-color: #3f3f46; cursor: pointer; }
.docreview__panel .form-block .form-label { display: flex; align-items: baseline; gap: .4rem; }
.docreview__panel .form-control:not(.form-control-sm) { padding: .5rem .7rem; font-size: .875rem; }
.docreview__panel textarea { resize: vertical; }
.docreview__opt { font-size: .7rem; font-weight: 600; color: var(--rbpg-muted); text-transform: uppercase; letter-spacing: .05em; }
.docreview__opt.is-required { color: var(--tone-bad-ink); }

.docreview__mail {
  margin-top: .6rem; padding: .75rem .85rem; max-height: 280px; overflow: auto;
  background: var(--rbpg-grey); border: 1px solid var(--rbpg-border); border-radius: 10px; font-size: .76rem;
}
.docreview__mail dl { display: grid; grid-template-columns: auto 1fr; gap: .15rem .6rem; margin: 0 0 .6rem; }
.docreview__mail dt { color: var(--rbpg-muted); font-weight: 600; }
.docreview__mail dd { margin: 0; font-weight: 600; word-break: break-word; }
.docreview__mail pre { margin: 0; white-space: pre-wrap; font: inherit; line-height: 1.5; color: var(--rbpg-text); }

.docreview__strip {
  padding: .55rem .8rem; border-radius: 8px; font-size: .8rem; font-weight: 600;
  background: var(--tone-ok-tint); color: var(--tone-ok-ink);
  transition: opacity .3s ease;
}
.docreview__strip.is-bad { background: var(--tone-bad-tint); color: var(--tone-bad-ink); }
.docreview__strip.is-gone { opacity: 0; }

.docreview__done { padding: 3.5rem 1.5rem; text-align: center; }
.docreview__done-icon {
  display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px;
  margin-bottom: .9rem; border-radius: 50%; background: var(--tone-ok-tint); color: var(--tone-ok-ink);
}
.docreview__done-icon svg { width: 24px; height: 24px; }
.docreview__done h6 { margin: 0 0 .35rem; font-size: 1rem; font-weight: 700; }
.docreview__done p { margin: 0 auto; max-width: 420px; font-size: .875rem; color: var(--rbpg-muted); }

.rbpg-modal--review .modal-footer { padding: .85rem 1.25rem; }
.docreview__foot-left { margin-right: auto; display: inline-flex; align-items: center; gap: .4rem; }
.docreview__foot-left svg { width: 14px; height: 14px; }
.docreview__actions { display: flex; gap: .6rem; }
.docreview__keys { font-size: .72rem; color: var(--rbpg-muted); margin-right: .5rem; }
.docreview__keys kbd {
  display: inline-block; min-width: 1.15rem; margin: 0 .1rem; padding: .05rem .3rem; text-align: center;
  font: 600 .66rem/1.4 inherit; color: var(--rbpg-text);
  background: #fff; border: 1px solid var(--rbpg-border-strong); border-bottom-width: 2px; border-radius: 4px;
}

@media (max-width: 991.98px) {
  .docreview { grid-template-columns: 1fr; height: auto; }
  .docreview__preview { height: 56vh; border-right: 0; border-bottom: 1px solid var(--rbpg-border); }
  .docreview__panel { overflow: visible; }
  .docreview__keys { display: none !important; }
}

/* The Documents table (SUP-17): one row per thing we asked for. */
.kyc-doc-name { font-weight: 600; }
.kyc-doc-sub { font-size: .78rem; color: var(--rbpg-muted); margin-top: .1rem; max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kyc-doc-why { font-size: .76rem; color: var(--rbpg-muted); margin-top: .25rem; }
.kyc-doc-why.is-bad { color: var(--tone-bad-ink); }
.kyc-docs-group td {
  padding-top: 1rem !important; padding-bottom: .4rem !important;
  font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--rbpg-muted);
  background: transparent !important;
}
.kyc-docs-count { font-size: .8rem; color: var(--rbpg-muted); font-weight: 500; }

/* The vendor's Verification cards (SUP-17): why it was turned down, above
   the button that fixes it, and what we accept, folded until asked for. */
.doc-card .doc-rejected { margin: 0 0 .85rem; padding: .7rem .85rem; border-radius: 10px; background: var(--tone-bad-tint); font-size: .82rem; }
.doc-rejected-title { margin: 0 0 .3rem; font-size: .75rem; font-weight: 700; color: var(--tone-bad-ink); }
.doc-rejected-list { margin: 0; padding-left: 1.05rem; color: var(--rbpg-text); line-height: 1.45; }
.doc-rejected-list:empty { display: none; }
.doc-rejected-list li + li { margin-top: .15rem; }
.doc-rejected-note { margin: .4rem 0 0; color: var(--rbpg-text); font-style: italic; }
.doc-card .doc-accept { margin-top: .85rem; font-size: .82rem; }
.doc-card .doc-accept summary {
  display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; list-style: none;
  font-weight: 600; color: var(--rbpg-text);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--rbpg-border-strong);
}
.doc-card .doc-accept summary::-webkit-details-marker { display: none; }
.doc-card .doc-accept summary::after {
  content: ''; width: 6px; height: 6px; margin-left: .15rem;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px); transition: transform .15s;
}
.doc-card .doc-accept[open] summary::after { transform: rotate(-135deg) translateY(-1px); }
.doc-card .doc-accept summary:hover { text-decoration-color: currentColor; }
.doc-card .doc-accept ul { margin: .55rem 0 0; padding-left: 1.05rem; color: var(--rbpg-muted); line-height: 1.5; }
.doc-card .doc-accept li + li { margin-top: .25rem; }
.doc-card { transition: box-shadow .3s ease, border-color .3s ease; }
.doc-card--focus { border-color: var(--rbpg-text); box-shadow: 0 0 0 3px rgba(63, 63, 70, .14); }
/* Account verification (SUP-18): where the vendor stands, the decision beside
   it, and what is still open. The Approve dialog draws the same lists. */
.approval-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.approval-sentence { flex: 1 1 18rem; margin: 0; font-size: .88rem; color: var(--rbpg-text); line-height: 1.5; }
.approval-actions { display: flex; gap: .5rem; flex-shrink: 0; }
.approval-actions:not(:has(.btn:not(.d-none))) { display: none; }
.approval-heading { margin: 1.1rem 0 .45rem; font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--rbpg-muted); }
#av-done .approval-heading,
#av-done:empty + #av-todo .approval-heading:first-child { margin-top: 0; }
.approval-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--rbpg-border); border-radius: 10px; }
.approval-list li { display: flex; align-items: center; gap: .65rem; padding: .55rem .75rem; font-size: .84rem; }
.approval-list li + li { border-top: 1px solid var(--rbpg-border); }
.approval-label { flex: 1 1 auto; min-width: 0; color: var(--rbpg-text); }
.approval-why { display: block; font-size: .76rem; color: var(--rbpg-muted); }
.approval-who { font-size: .72rem; font-weight: 600; color: var(--rbpg-muted); white-space: nowrap; }
.approval-mark { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--tone-warn-dot); }
.approval-tick { display: inline-flex; width: 1rem; flex-shrink: 0; justify-content: center; font-weight: 700; color: var(--tone-ok-ink); }
.approval-list--done { border: 0; }
.approval-list--done li { padding: .3rem 0; }
.approval-list--done li + li { border-top: 0; }
.approval-clear { margin: 1rem 0 0; font-size: .84rem; color: var(--rbpg-text); display: flex; gap: .4rem; }
.modal-body .approval-clear { margin-top: .75rem; }
.approval-also { margin: .6rem 0 0; font-size: .78rem; color: var(--rbpg-muted); }
#av-to { margin-top: 1rem !important; }

/* ---- Royal Mail label settings (RM-8) ---------------------------------------
   The send-in label sample and the return-postage picker under the Click & Drop
   card. The sample is drawn like a 6x4 thermal label — black on white, a heavy
   rule under the carrier band — so it reads as "what prints", not as UI. */
.row > .rml-cards > .rml-card:first-child { margin-top: 0 !important; }
.rml-edit { display: inline-flex; align-items: center; gap: .35rem; }

.rml-sendin { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 1.5rem; align-items: start; }
.rml-sendin-facts { margin-top: 0; }
@media (max-width: 767.98px) { .rml-sendin { grid-template-columns: 1fr; } }

.rml-label {
  margin: 0; max-width: 320px; background: #fff; color: #111;
  border: 1.5px solid #111; border-radius: 6px;
  box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 8px 24px -12px rgba(0,0,0,.25);
  font-family: Arial, Helvetica, sans-serif; overflow: hidden;
}
.rml-label-top {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  padding: .55rem .75rem; border-bottom: 3px solid #111;
}
.rml-label-top img { height: 20px; width: auto; }
.rml-label-svc { font-weight: 700; font-size: .78rem; letter-spacing: .02em; text-transform: uppercase; }
.rml-label-body { padding: .7rem .75rem .8rem; }
.rml-label-k { display: block; font-size: .62rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #555; margin-bottom: .3rem; }
.rml-label-addr { display: flex; flex-direction: column; font-size: .86rem; line-height: 1.35; text-transform: uppercase; }
.rml-label-name { font-weight: 700; font-size: .95rem; }
.rml-label-name--co { font-weight: 600; font-size: .86rem; }
.rml-label-pc { font-weight: 700; font-size: 1.05rem; letter-spacing: .04em; margin-top: .15rem; }
.rml-label-missing { color: var(--tone-bad-ink); text-transform: none; font-size: .8rem; }
.rml-label-foot { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: .5rem .75rem; border-top: 1px dashed #bbb; }
.rml-label-bars {
  flex: 1; max-width: 150px; height: 26px;
  background: repeating-linear-gradient(90deg, #111 0 2px, transparent 2px 4px, #111 4px 5px, transparent 5px 8px, #111 8px 11px, transparent 11px 12px);
}
.rml-label-ref { font-size: .62rem; color: #777; white-space: nowrap; }

.rml-preview-k { font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--rbpg-muted); margin-bottom: .5rem; }
.rml-preview { display: flex; justify-content: center; padding: 1.25rem; background: var(--rbpg-grey); border-radius: var(--rbpg-radius); }
.rml-preview .rml-label { width: 100%; }
.rml-preview.is-flash .rml-label-name { animation: rml-flash .7s ease-out; }
@keyframes rml-flash { from { background: var(--tone-warn-lit); } to { background: transparent; } }

.rml-choices { display: flex; flex-direction: column; gap: .6rem; }
.rml-choice {
  position: relative; display: flex; gap: .75rem; align-items: flex-start; cursor: pointer;
  padding: .85rem 1rem; border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius);
  background: var(--rbpg-surface); transition: border-color .15s, box-shadow .15s;
}
.rml-choice:hover { border-color: var(--rbpg-border-strong); }
.rml-choice input { position: absolute; opacity: 0; pointer-events: none; }
.rml-choice.is-on { border-color: var(--rbpg-text); box-shadow: 0 0 0 1px var(--rbpg-text); }
.rml-choice:focus-within { box-shadow: 0 0 0 3px var(--tone-info-lit); }
.rml-choice.is-off { opacity: .5; cursor: not-allowed; }
.rml-choice-dot { flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: 50%; border: 1.5px solid var(--rbpg-border-strong); background: #fff; }
.rml-choice.is-on .rml-choice-dot { border: 5px solid var(--rbpg-text); }
.rml-choice-text { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.rml-choice-title { font-weight: 600; font-size: .9rem; }
.rml-choice-rec { margin-left: .35rem; padding: .05rem .45rem; border-radius: 999px; font-size: .66rem; font-weight: 600; background: var(--tone-ok-tint); color: var(--tone-ok-ink); vertical-align: 1px; }
.rml-choice-lines { font-size: .8rem; font-weight: 600; text-transform: uppercase; line-height: 1.35; color: var(--rbpg-text); }
.rml-choice-note { font-size: .78rem; color: var(--rbpg-muted); }

.rml-test-out:empty { display: none; }
.rml-test-out { margin-top: .75rem; font-size: .82rem; }
.rml-test-ok { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; justify-content: space-between; padding: .6rem .8rem; border-radius: var(--rbpg-radius-ctl); background: var(--tone-ok-tint); color: var(--tone-ok-ink); }
.rml-test-ok a { font-weight: 600; color: inherit; }
.rml-test-bad { display: flex; gap: .4rem; align-items: center; padding: .6rem .8rem; border-radius: var(--rbpg-radius-ctl); background: var(--tone-bad-tint); color: var(--tone-bad-ink); }

.rml-chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.rml-chip {
  display: inline-flex; align-items: center; gap: .45rem; padding: .35rem .75rem;
  border: 1px solid var(--rbpg-border); border-radius: 999px; background: var(--rbpg-surface);
  font-size: .8rem; font-weight: 500;
}
.rml-chip.is-default { border-color: var(--rbpg-text); }
.rml-chip-tag { padding: .02rem .4rem; border-radius: 999px; font-size: .64rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; background: var(--rbpg-text); color: #fff; }
.rml-out-empty { padding: 1rem 1.1rem; border: 1px dashed var(--rbpg-border-strong); border-radius: var(--rbpg-radius); background: var(--rbpg-grey); }

.rml-out-intro { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between; margin-bottom: 1rem; }
.rml-out-quick { display: flex; gap: .4rem; flex: none; }
@media (max-width: 575.98px) { .rml-out-intro { flex-direction: column; } }
.rml-group { border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius); margin-bottom: .75rem; overflow: hidden; }
.rml-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .15rem .6rem; padding: .65rem 1rem; background: var(--rbpg-grey); border-bottom: 1px solid var(--rbpg-border); }
.rml-group--fold:not([open]) > .rml-group-head { border-bottom: 0; }
.rml-group--fold > summary { cursor: pointer; list-style: none; }
.rml-group--fold > summary::-webkit-details-marker { display: none; }
.rml-group--fold > summary::before { content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); margin-right: .3rem; align-self: center; transition: transform .15s; }
.rml-group--fold[open] > summary::before { transform: rotate(45deg); }
.rml-group-title { font-weight: 600; font-size: .86rem; }
.rml-group-note { font-size: .76rem; color: var(--rbpg-muted); }
.rml-group-count { margin-left: auto; font-size: .74rem; color: var(--rbpg-muted); }
.rml-svc { display: flex; align-items: center; gap: .75rem; padding: .55rem 1rem; border-top: 1px solid var(--rbpg-border); transition: background .12s; }
.rml-group-rows > .rml-svc:first-child { border-top: 0; }
.rml-svc.is-on { background: var(--tone-info-tint); }
.rml-svc-main { flex: 1; display: flex; align-items: center; gap: .65rem; min-width: 0; cursor: pointer; margin: 0; }
.rml-svc-main .form-check-input { margin: 0; flex: none; }
.rml-svc-name { font-size: .86rem; font-weight: 500; }
.rml-svc-cover { font-size: .74rem; color: var(--rbpg-muted); }
.rml-svc-code { margin-left: auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .72rem; color: var(--rbpg-muted); }
.rml-svc-def { display: inline-flex; align-items: center; gap: .3rem; margin: 0; font-size: .74rem; color: var(--rbpg-muted); cursor: pointer; white-space: nowrap; }
.rml-svc-def input:disabled + span { opacity: .4; }
.rml-svc-def input:checked + span { color: var(--rbpg-text); font-weight: 600; }
.rml-out-count { font-size: .8rem; color: var(--rbpg-muted); }

/* SUP-19 — contact tile */
/* A person (or the company) as a business card: drawn by RBPGVendorCards.contactTile on the
   vendor Dashboard and Settings, the staff vendor page and the Profile preview. A panel inside
   its card, so a border and no shadow. The photo sits left of everything, so the
   tile is as tall as its text and no taller. Tiles go two across whenever each
   gets 280px, rather than at rbpg-split's 1280px. */
.rbpg-contact-row {
  display: grid; gap: .75rem; align-items: stretch;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.rbpg-contact-row > * { min-width: 0; }
.rbpg-contact {
  display: flex; align-items: flex-start; gap: .75rem; height: 100%; min-width: 0;
  padding: .75rem .9rem; background: #fff;
  border: 1px solid var(--rbpg-border); border-radius: var(--rbpg-radius);
}
.rbpg-contact-role { margin-bottom: .1rem; font-size: var(--type-eyebrow); font-weight: var(--weight-strong); line-height: 1.3; letter-spacing: .06em; text-transform: uppercase; color: var(--rbpg-muted); }
.rbpg-contact-avatar {
  width: 44px; height: 44px; flex: none; border-radius: 50%; overflow: hidden;
  border: 1px solid var(--rbpg-border); background: #e4e4e7; color: #3f3f46;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .85rem; font-weight: 700; text-transform: uppercase;
}
.rbpg-contact-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rbpg-contact-avatar--team svg { width: 20px; height: 20px; }
.rbpg-contact-who { flex: 1 1 auto; min-width: 0; }
/* Name and title share a line; the title gives way first. */
.rbpg-contact-nameline { display: flex; align-items: baseline; gap: .4rem; min-width: 0; line-height: 1.3; }
.rbpg-contact-nameline .pill { flex: none; align-self: center; }
.rbpg-contact-name { flex: 0 1 auto; min-width: 0; font-size: var(--type-row); font-weight: var(--weight-strong); color: var(--rbpg-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rbpg-contact-title { flex: 0 10000 auto; min-width: 0; font-size: var(--type-label); color: var(--rbpg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rbpg-contact-title::before { content: '\00b7'; margin-right: .4rem; }
.rbpg-contact-lines { display: flex; flex-direction: column; margin-top: .3rem; }
.rbpg-contact-line { display: flex; align-items: center; gap: .45rem; min-width: 0; min-height: 24px; font-size: var(--type-body); color: var(--rbpg-text); }
.rbpg-contact-line > svg { width: 14px; height: 14px; flex: none; color: var(--rbpg-muted); }
.rbpg-contact-line .vn-owned { flex: none; }
.rbpg-contact-value { flex: 1 1 auto; min-width: 0; color: var(--rbpg-text); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
a.rbpg-contact-value:hover, a.rbpg-contact-value:focus { color: var(--rbpg-text); text-decoration: underline; }
.rbpg-contact-copy {
  flex: none; width: 24px; height: 24px; padding: 0; border: 0; background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--rbpg-muted); border-radius: var(--rbpg-radius-ctl-sm);
}
.rbpg-contact-copy:hover { background: var(--rbpg-grey); color: var(--rbpg-text); }
.rbpg-contact-copy svg { width: 13px; height: 13px; }
/* A mouse finds the copy button on hover; touch and keyboard always see it. */
@media (hover: hover) {
  .rbpg-contact-copy { opacity: 0; transition: opacity .12s; }
  .rbpg-contact:hover .rbpg-contact-copy,
  .rbpg-contact-line:focus-within .rbpg-contact-copy { opacity: 1; }
}
.rbpg-contact-gaps { margin-top: .3rem; font-size: .78rem; color: var(--rbpg-muted); }
.rbpg-contact-gaps a { color: var(--rbpg-muted); text-decoration: underline; }
.rbpg-contact-gaps a:hover { color: var(--rbpg-text); }
.rbpg-contact--empty { border-style: dashed; }
.rbpg-contact--empty { align-items: center; }
.rbpg-contact-empty { display: flex; align-items: center; justify-content: space-between; gap: .75rem; min-height: 30px; font-size: .85rem; color: var(--rbpg-muted); }
.rbpg-contact--skeleton .rbpg-contact-avatar,
.rbpg-contact--skeleton .rbpg-contact-bar {
  background: linear-gradient(90deg, #f0f0f0 25%, #e4e4e7 50%, #f0f0f0 75%);
  background-size: 200% 100%; animation: rbpg-shimmer 1.4s infinite;
}
.rbpg-contact--skeleton .rbpg-contact-avatar { border-color: transparent; }
.rbpg-contact-bar { display: block; width: 70%; height: .75rem; border-radius: 5px; }
.rbpg-contact--skeleton .rbpg-contact-role,
.rbpg-contact--skeleton .rbpg-contact-nameline { padding: .2rem 0; }
.rbpg-contact-bar--short { width: 35%; height: .6rem; }