/* public/css/houji-shell.css — the Houji dashboard shell, shared by two hosts.
 *
 * MEMBER_DASHBOARD (C1). Every rule below was EXTRACTED VERBATIM from the inline <style>
 * of public/dashboard.html — not rewritten, not tidied, not "improved" on the way out.
 * That is deliberate: the arc's promise is that the dashboard does not change by a pixel,
 * and a rule that was edited in transit is a rule whose behaviour has to be re-argued.
 * The pin is a MEASUREMENT, not a reading: test/member-dashboard/dashboard-parity.test.js
 * drives the real page in chromium and requires getComputedStyle over ~55 properties on
 * 67 elements at two viewports to be byte-equal to a baseline captured before this file
 * existed (test/member-dashboard/fixtures/dashboard-shell-baseline.json).
 *
 * ORDER. Moving a rule out of an inline block and into a linked sheet changes where it
 * sits in the cascade. These rules keep their original relative order among themselves,
 * and dashboard.html links this file IMMEDIATELY BEFORE the <style> that holds everything
 * that stayed — so every moved rule still precedes every rule that followed it, which
 * makes the extraction order-preserving BY CONSTRUCTION rather than by argument.
 *
 * Measured, so the claim is not a guess: linking this file AFTER that <style> instead
 * changes nothing (0 differing properties) — the moved set and the retained set do not
 * collide today. The placement is therefore insurance, not a live fix, and it stops
 * being merely that the moment someone adds a rule here that a host also declares. Put
 * host-specific rules in the host.
 *
 * WHAT LIVES HERE: the app shell (sidebar, topbar, content), buttons, tables and the call
 * log's column geometry, badges, the filter bar, pagination, message cards, tabs, and the
 * mobile drawer. WHAT DOES NOT: anything only one host renders — the Config Hub, the
 * prompt-history cards, the transcript panel, the setup checklist, the feedback modal.
 * Those stay inline in public/dashboard.html.
 *
 * MEMBER_CARD_PARITY (§2.6) added the tooltip + help-popover group at the foot of this
 * file. It was "help popovers stay inline" until the member page started rendering the
 * same card the dashboard does — and the same "?" with it. Same rule as the rest: moved
 * verbatim, in order, and measured.
 *
 * NOT LINKED BY public/translation-dashboard.html — the interpreter host keeps its own
 * copy of these rules and is out of this arc's scope (MEMBER_DASHBOARD §8). Unifying it
 * is a later pass, and it needs its own measured baseline.
 */

*{box-sizing:border-box;margin:0;padding:0}
:root{
  --navy:#1a2e4a;--navy-mid:#243d60;--navy-light:#2e4f7a;
  --bg:#f4f3f0;--surface:#ffffff;--surface2:#f9f8f6;--surface3:#f2f1ee;
  --border:#e4e2dc;--border2:#d0cec7;
  --text:#181714;--text2:#4a4840;--text3:#8a8880;--text4:#b0aea8;
  --blue:#1a4a8a;--blue-bg:#edf2fb;--blue-border:#bdd0ef;
  --green:#1a5c38;--green-bg:#eaf4ee;--green-border:#a8d8bc;
  --amber:#7a4a10;--amber-bg:#fdf4e8;--amber-border:#e8c898;
  --red:#8a1a1a;--red-bg:#faeaea;--red-border:#e8b8b8;
  --teal:#0f5a5a;--teal-bg:#e8f4f4;--teal-border:#a0d0d0;
  --radius:6px;--radius-lg:10px;--radius-xl:14px;
  --sidebar:220px;--header:56px;
  --content-max:1400px;
  /* The scrolling area's own padding. ONE home, because the Conflicts bar sticks at its negative
     (CONFLICTS_BY_CLIENT §2 A1): a sticky box stops at the padding edge, not the scrolling edge. */
  --content-pad:24px;
}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
  background:var(--bg);color:var(--text);font-size:14px;line-height:1.5}
a{color:inherit;text-decoration:none}
button{font-family:inherit;font-size:13px;cursor:pointer;border:none;background:none}

/* ── Layout ──────────────────────────────────────────── */
.app{display:flex;height:100vh;overflow:hidden}

/* ── Sidebar ──────────────────────────────────────────── */
.sidebar{width:var(--sidebar);background:var(--navy);display:flex;flex-direction:column;flex-shrink:0;overflow-y:auto}
.sidebar-brand{padding:18px 16px 14px;border-bottom:1px solid rgba(255,255,255,.08)}
.brand-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:#4a9eff;margin-right:7px}
.brand-name{color:#fff;font-size:15px;font-weight:500;letter-spacing:-.2px}
.brand-sub{font-size:11px;color:rgba(255,255,255,.38);margin-top:2px;padding-left:15px}

.nav{padding:10px 0;flex:1}
.nav-section{padding:14px 16px 6px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.28);font-weight:500}
.nav-item{display:flex;align-items:center;gap:9px;padding:8px 16px;color:rgba(255,255,255,.62);font-size:13px;transition:all .12s;cursor:pointer;border-radius:0;position:relative}
.nav-item:hover{color:rgba(255,255,255,.88);background:rgba(255,255,255,.05)}
.nav-item.active{color:#fff;background:rgba(255,255,255,.1)}
.nav-item.active::before{content:'';position:absolute;left:0;top:4px;bottom:4px;width:2px;background:#4a9eff;border-radius:0 2px 2px 0}
.nav-icon{font-size:14px;width:16px;text-align:center;flex-shrink:0}
.nav-badge{margin-left:auto;background:#dc4444;color:#fff;font-size:10px;font-weight:600;padding:1px 6px;border-radius:10px;min-width:18px;text-align:center}
/* Suggestions nav count chip + subtle pulse (SUGGESTIONS_UI_POLISH) */
.nav-count-badge{position:absolute;right:12px;top:50%;transform:translateY(-50%);min-width:18px;height:18px;padding:0 5px;border-radius:9px;font-size:11px;font-weight:600;display:flex;align-items:center;justify-content:center;background:#4a9eff;color:#fff}
@keyframes sugPulse{0%,100%{box-shadow:inset 0 0 0 0 rgba(74,158,255,0)}50%{box-shadow:inset 0 0 0 1px rgba(74,158,255,.22)}}
@keyframes sugPulseStrong{0%,100%{box-shadow:inset 0 0 0 0 rgba(74,158,255,0)}50%{box-shadow:inset 0 0 0 2px rgba(74,158,255,.34)}}
.nav-item.sug-pulse{animation:sugPulse 2s ease-in-out infinite}
.nav-item.sug-pulse-strong{animation:sugPulseStrong 1.4s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){.nav-item.sug-pulse,.nav-item.sug-pulse-strong{animation:none}}
.nav-divider{margin:6px 16px;border:none;border-top:1px solid rgba(255,255,255,.08)}

.sidebar-footer{padding:12px 16px;border-top:1px solid rgba(255,255,255,.08)}
.firm-pill{display:flex;align-items:center;gap:8px}
/* CALLER_CONFIRMATIONS_CLEANUP Part B — min-width:0 is the load-bearing declaration.
   A flex item defaults to min-width:auto, so the text wrapper took its INTRINSIC width
   from a long firm name and grew past the sidebar, where the main panel painted over it.
   The old ellipsis on .firm-name could never fire, because the element was always as wide
   as its own text. With min-width:0 the wrapper is finally allowed to be narrower than its
   content, so the name wraps; the clamp caps it at two lines and the footer grows upward
   on its own (the sidebar is a flex column). Third+ lines clip — the title attribute set
   by the hydrator carries the full name. Kept byte-parallel with translation-dashboard.html. */
.firm-pill-text{min-width:0;flex:1 1 auto}
.firm-avatar{width:28px;height:28px;border-radius:6px;background:rgba(255,255,255,.12);color:rgba(255,255,255,.7);font-size:11px;font-weight:600;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.firm-name{color:rgba(255,255,255,.75);font-size:12px;font-weight:500;line-height:1.3;white-space:normal;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
.firm-plan{font-size:10px;color:rgba(255,255,255,.35)}

/* ── Main ─────────────────────────────────────────────── */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}

.topbar{height:var(--header);border-bottom:1px solid var(--border);background:var(--surface);display:flex;align-items:center;padding:0 24px;gap:16px;flex-shrink:0}
.topbar-title{font-size:15px;font-weight:500;color:var(--text)}
.topbar-sub{font-size:12px;color:var(--text3);margin-left:4px}
.topbar-actions{margin-left:auto;display:flex;gap:8px;align-items:center}

.content{flex:1;overflow-y:auto;padding:var(--content-pad)}
/* DASH_LAYOUT_POLISH D1 — one shared content ceiling for every tab (replaces the
   per-section 720px/900px caps); only bites on very wide monitors. */
.content>section{max-width:var(--content-max)}

/* ── Buttons ──────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border-radius:var(--radius);font-size:13px;font-weight:500;transition:all .12s;border:1px solid transparent}
.btn-primary{background:var(--navy);color:#fff;border-color:var(--navy)}
.btn-primary:hover{background:var(--navy-mid)}
.btn-secondary{background:var(--surface);color:var(--text2);border-color:var(--border2)}
.btn-secondary:hover{border-color:var(--border2);background:var(--surface3)}
.btn-ghost{background:transparent;color:var(--text3);border-color:transparent}
.btn-ghost:hover{background:var(--surface3);color:var(--text2)}
.btn-danger{background:var(--red-bg);color:var(--red);border-color:var(--red-border)}
.btn-danger:hover{background:#f5d5d5}
.btn-sm{padding:4px 10px;font-size:12px}
.btn-icon{padding:6px;border-radius:var(--radius);color:var(--text3);border:1px solid transparent}
.btn-icon:hover{background:var(--surface3);border-color:var(--border)}
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed;pointer-events:none}

/* ── Table ────────────────────────────────────────────── */
.table-wrap{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}
table{width:100%;border-collapse:collapse}
thead th{padding:10px 16px;text-align:left;font-size:11px;font-weight:500;color:var(--text3);text-transform:uppercase;letter-spacing:.05em;background:var(--surface3);border-bottom:1px solid var(--border);white-space:nowrap}
tbody tr{border-bottom:1px solid var(--border);transition:background .1s}
tbody tr:last-child{border-bottom:none}
tbody tr:hover{background:var(--surface2)}
tbody td{padding:11px 16px;color:var(--text2);font-size:13px}
tbody td.primary{color:var(--text);font-weight:500}
.table-empty{padding:40px;text-align:center;color:var(--text4);font-size:13px}

/* ── Badges / tags ────────────────────────────────────── */
.badge{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:20px;font-size:11px;font-weight:500}
.badge-blue{background:var(--blue-bg);color:var(--blue);border:1px solid var(--blue-border)}
.badge-green{background:var(--green-bg);color:var(--green);border:1px solid var(--green-border)}
.badge-amber{background:var(--amber-bg);color:var(--amber);border:1px solid var(--amber-border)}
.badge-red{background:var(--red-bg);color:var(--red);border:1px solid var(--red-border)}
.badge-teal{background:var(--teal-bg);color:var(--teal);border:1px solid var(--teal-border)}
.badge-gray{background:var(--surface3);color:var(--text3);border:1px solid var(--border)}

/* ── Search / filter bar ──────────────────────────────── */
.filter-bar{display:flex;gap:8px;margin-bottom:14px;align-items:center}
.search-wrap{position:relative;flex:1;max-width:280px}
.search-wrap input{width:100%;padding:7px 12px 7px 32px;border:1px solid var(--border2);border-radius:var(--radius);font-size:13px;background:var(--surface);color:var(--text);outline:none;font-family:inherit}
.search-wrap input:focus{border-color:var(--blue)}
.search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text4);font-size:13px}
.filter-select{padding:7px 10px;border:1px solid var(--border2);border-radius:var(--radius);font-size:13px;background:var(--surface);color:var(--text2);outline:none;font-family:inherit}
.filter-select:focus{border-color:var(--blue)}

/* ── Pagination ───────────────────────────────────────── */
.pagination{display:flex;align-items:center;gap:8px;padding:12px 16px;border-top:1px solid var(--border);justify-content:flex-end}
.page-info{font-size:12px;color:var(--text3);margin-right:auto}

/* ── Message card ─────────────────────────────────────── */
.message-list{display:flex;flex-direction:column;gap:8px}
.message-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:16px 18px;display:flex;gap:14px;align-items:flex-start;transition:border-color .12s}
.message-card:hover{border-color:var(--border2)}
.message-card.unread{border-left:3px solid var(--blue)}
.message-card.follow_up{border-left:3px solid var(--amber)}
.msg-avatar{width:36px;height:36px;border-radius:50%;background:var(--surface3);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;color:var(--text3);flex-shrink:0}
.msg-body{flex:1;min-width:0}
.msg-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.msg-name{font-weight:500;color:var(--text);font-size:13px}
.msg-phone{font-size:12px;color:var(--text3)}
.phone-link{color:var(--gold,#c4a45c);text-decoration:none;font-size:12px;cursor:pointer}
.phone-link:hover{text-decoration:underline}
.msg-time{font-size:11px;color:var(--text4);margin-left:auto;white-space:nowrap}
.msg-text{font-size:13px;color:var(--text2);line-height:1.55;margin-bottom:8px}
.msg-actions{display:flex;gap:6px}

/* ── Tabs ──────────────────────────────────────────────── */
.tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:18px}
.tab{padding:9px 16px;font-size:13px;color:var(--text3);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:all .12s}
.tab:hover{color:var(--text2)}
.tab.active{color:var(--navy);border-bottom-color:var(--navy);font-weight:500}
.tab-count{font-size:11px;background:var(--surface3);color:var(--text4);padding:1px 6px;border-radius:10px;margin-left:5px}
.tab.active .tab-count{background:var(--blue-bg);color:var(--blue)}

.nav-account {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
}
.nav-firm-name {
  font-size: 12px;
  color: var(--text3, #9b9890);
}
.btn-logout {
  padding: 6px 14px;
  background: transparent;
  border: 1px solid var(--border, #e4e2dc);
  border-radius: 6px;
  font-size: 12px;
  color: var(--text2, #4a4840);
  cursor: pointer;
  font-family: inherit;
  transition: all .15s;
}
.btn-logout:hover {
  background: var(--cream, #f4f3f0);
  border-color: var(--navy, #1a2e4a);
  color: var(--navy, #1a2e4a);
}

/* ── Misc ──────────────────────────────────────────────── */
.divider{height:1px;background:var(--border);margin:16px 0}
.notice{padding:10px 14px;border-radius:var(--radius);font-size:13px;margin-bottom:16px;border:1px solid}
.notice-amber{background:var(--amber-bg);border-color:var(--amber-border);color:var(--amber)}
.notice-blue{background:var(--blue-bg);border-color:var(--blue-border);color:var(--blue)}
.hidden{display:none!important}

/* FIX-17: call log overflow safety net */
.call-log-container { overflow-x: auto; }

/* CALL_LOG_SUMMARY_COLUMN (Tim, 2026-09-15) — deterministic column layout, and WHICH column
   is the flexible one. Tim, reading his own Call Log: "The 'Caller' column in 'Call Logs' in
   the dashboard is way too wide, and the 'View' on the right hand side is way too narrow, and
   then has to open up something underneath it … all the room should go to the 'View' column on
   the right. But yes, it should be renamed 'summary'."

   So on the DESKTOP tier the four narrow columns AND Caller carry fixed widths, and Summary is
   the one with none: table-layout:fixed hands the widthless column the remainder, so the thing
   that grows with the monitor is the summary text. Below that tier the rule INVERTS — Summary
   is the 64px View button again and Caller is the flexible one — which is the layout a phone
   has always had.

   THE DESKTOP TIER IS THE ADDITIVE ONE (min-width), not the phone tier. Written the other way
   round, restoring the phone's ▶ costs an explicit `display` that is not the one .btn (:116)
   gives it — inline-block where the button is inline-flex — so "the phone stays exactly as it
   is" would have been false by a measurable property. Everything below 1101px is therefore the
   UNTOUCHED default, and 1101 is complementary to the existing max-width:1100 rule below: no
   viewport matches both, none matches neither.

   DASH_LAYOUT_POLISH D3's disposition ("fill the container") is true again: the table fills the
   tab's full width and wide-monitor bounding lives uniformly in --content-max (:71). */
.call-log-table { table-layout: fixed; }
/* DASH_LAYOUT_POLISH D3 — call-log density. SCOPED overrides only; the global
   thead th/tbody td padding (:103/:107) stays untouched for every other table. */
.call-log-table thead th { padding: 7px 12px; }
.call-log-table tbody td { padding: 7px 12px; }
.col-time     { width: 170px; }
.col-duration { width: 110px; }
.col-badges   { width: 150px; }
.col-summary  { width: 64px; text-align: center; }
/* A fixed-layout cell cannot be widened by its content, so an unbroken string (a long email,
   a pasted URL) would otherwise paint straight through its neighbour. */
.call-log-table td.primary { overflow-wrap: anywhere; }
/* The caller's name is a door to the same card the ✎ opens; the shell's own `a` rule is
   colour:inherit, so the link has to say it is one. */
.call-log-table .cl-name, .msg-header .cl-name { color: var(--blue); cursor: pointer; }
.call-log-table .cl-name:hover, .msg-header .cl-name:hover { text-decoration: underline; }
/* The last cell carries BOTH the summary block and the ▶, and CSS picks which is on screen.
   No JS reads the viewport: a width read at render time is right once and wrong after a
   resize. .cl-desk/.cl-mob are the two halves of the header's own word. */
.call-log-table .cl-summary, .call-log-table .cl-desk { display: none; }
@media (min-width: 1101px) {
  .col-caller  { width: 240px; }
  .col-summary { width: auto; text-align: left; }
  .call-log-table .cl-summary { display: block; }
  .call-log-table .cl-desk    { display: inline; }
  .call-log-table .cl-mob,
  .call-log-table .call-expand-btn { display: none; }
}

/* FIX-17: responsive column hiding */
@media (max-width: 1100px) {
  .call-log-table .col-time { display: none; }
}
@media (max-width: 900px) {
  .call-log-table .col-duration { display: none; }
}

/* ── MOBILE_DASH — off-canvas nav drawer below 768px (visual D1) ─────────
   The 220px sidebar is flex-shrink:0, so at 390px it ate 56% of the viewport and
   every dashboard surface (including the whole Config Hub, which renders inside
   this same shell) was unusable. Below 768px the sidebar leaves the flow and
   slides in over a scrim; content gets the full width.

   THE FENCE IS THE INVARIANT: everything here is either inert at ≥769px (the
   hamburger is display:none, the scrim is pointer-events:none at opacity 0) or
   lives inside the max-width:768px query. Desktop rendering is unchanged. */
#nav-hamburger{display:none;width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius);
  background:var(--surface);color:var(--text);font-size:15px;line-height:1;cursor:pointer;flex-shrink:0}
#nav-hamburger:hover{background:var(--bg)}
/* Mirrors .panel-overlay (:177) — opacity + pointer-events, never display, so the
   transition can actually run. */
#nav-scrim{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:60;opacity:0;pointer-events:none;transition:opacity .22s}

@media (max-width:768px){
  .sidebar{position:fixed;left:0;top:0;bottom:0;z-index:70;transform:translateX(-100%);
    transition:transform .22s ease;box-shadow:2px 0 12px rgba(0,0,0,.25)}
  .sidebar.open{transform:translateX(0)}
  body.drawer-open #nav-scrim{opacity:1;pointer-events:auto}
  body.drawer-open .content{overflow:hidden}          /* touch-scroll lock behind the drawer */
  #nav-hamburger{display:flex;align-items:center;justify-content:center}
  /* The topbar can't hold these plus title + help + account at 390px — and both
     are literal duplicates of nav items now reachable in the drawer. */
  .topbar-shortcut{display:none}
}

@media (prefers-reduced-motion: reduce){.sidebar,#nav-scrim{transition:none}}

/* ══════════════════════════════════════════════════════════════════════════════════
 * Tooltips + the help "?" and its popover — MEMBER_CARD_PARITY (§2.6).
 *
 * Extracted VERBATIM and in order from public/dashboard.html's inline <style>, where
 * they had been since UX_CLARITY Phase 1. They live here because the shared member-card
 * definition (public/js/member-card-form.js) emits both kinds of icon — help-pop, driven
 * by help-content.js, and one bare data-tooltip on "Urgent oversight" — and the member
 * page renders that markup too. Before this move it had a rule for neither, so both would
 * have drawn a bare unstyled "?" that did nothing: worse than absent, because it teaches
 * a reader the "?" is not worth clicking (the D6 amendment).
 *
 * [data-tooltip] moves WITH them, and it is not optional: .help-icon has no cursor of its
 * own, and the "?" reads as inert without cursor:help. Measured — __pt-help-icon
 * answers cursor:help, from exactly this group.
 * ══════════════════════════════════════════════════════════════════════════════════ */

/* ── Tooltips ─────────────────────────────────────────── */
[data-tooltip] {
  position: relative;
  cursor: help;
}
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--navy);
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.5;
  padding: 7px 11px;
  border-radius: 6px;
  white-space: normal;
  width: max-content;
  max-width: 260px;
  text-align: left;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 9999;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18);
}
[data-tooltip]:hover::after {
  opacity: 1;
}
[data-tooltip].tooltip-below::after {
  bottom: auto;
  top: calc(100% + 8px);
}
.help-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--surface3);
  color: var(--text3);
  font-size: 10px;
  font-weight: 700;
  font-style: normal;
  margin-left: 5px;
  vertical-align: middle;
  flex-shrink: 0;
  position: relative;
  z-index: 50;
}
/* ── Help popover (UX_CLARITY Phase 1 — click/tap-toggle, same visual language) ── */
.help-pop { cursor: pointer; }
.help-popover {
  position: absolute;
  background: var(--navy);
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.5;
  padding: 9px 12px;
  border-radius: 6px;
  max-width: 300px;
  text-align: left;
  z-index: 9999;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18);
}
.help-popover-title { font-weight: 700; margin-bottom: 4px; }
/* Pair a help icon's visibility to its preceding toggled control, so a "?" next to a
   display:none button (Change plan, Reactivate) hides with it. Covers both inline
   serializations ("display:none" from HTML, "display: none" from el.style.display). */
.btn[style*="display:none"] + .help-pop,
.btn[style*="display: none"] + .help-pop { display: none !important; }

/* ── CONFLICT_INTAKE §5.7 — the Conflicts screen, one definition for both hosts ────────
   Every selector is prefixed `cui-`. Both hosts keep every section mounted and bind with
   document-wide selectors, so an unprefixed `.tab` here would have its `active` stripped by
   the Inbox's own tab handler; `.conflict-*` is already taken by the Config Hub's
   practice-area card. */
/* ⛔ `isolation: isolate` IS WHAT LETS THE BAR BELOW BE SAFE. The "?" icons carry `z-index: 50`
   (the help rules above), so a sticky bar at a lower level would let every "?" in a scrolling
   list paint OVER it; isolating the root keeps the bar's own level local to this screen, so it
   can sit above those icons without ever climbing over the dashboard's fixed panels. */
.cui-root { max-width: 900px; isolation: isolate; }
.cui-h2 { margin: 0 0 2px; font-size: 18px; }
.cui-h3 { margin: 0 0 8px; font-size: 16px; }
.cui-sub { margin: 0 0 14px; color: var(--text3); font-size: 13px; line-height: 1.5; }
.cui-label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.cui-label-sm { display: block; font-size: 12px; color: var(--text2); margin: 8px 0 4px; }
.cui-row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.cui-row-end { justify-content: flex-end; margin-top: 12px; }
.cui-col { flex: 1 1 140px; }
.cui-input { flex: 1 1 240px; padding: 8px 10px; border: 1px solid var(--border);
  border-radius: 6px; font: inherit; background: var(--surface); color: var(--text); }
.cui-input-sm { padding: 6px 8px; font-size: 13px; width: 100%; }
.cui-result { margin-top: 12px; }
.cui-clean { font-size: 14px; font-weight: 600; }
.cui-fine { font-size: 12px; color: var(--text3); line-height: 1.5; margin-top: 6px; }
.cui-muted { color: var(--text4); font-size: 13px; padding: 12px 0; }
.cui-empty { color: var(--text3); font-size: 13px; padding: 20px 0; line-height: 1.6; }
/* CHECK_HISTORY_AS_RECORD §3.2 — the history's toggle sits on the search box's line, and a record
   row's decision reads a shade darker than the fine print above it: it is what the row is FOR. */
.cui-toolbar .cui-checks-all { align-self: center; font-size: 13px; }
.cui-decided { color: var(--text2); }
.cui-hit { border-left: 3px solid var(--amber, #b7791f); padding-left: 12px; }
.cui-hit-certain { border-left-color: var(--red, #c53030); }
.cui-hit-head { font-weight: 700; font-size: 14px; margin-bottom: 8px; }
.cui-cand { padding: 8px 0; border-top: 1px solid var(--border); }
.cui-cand-name { font-size: 14px; }
.cui-cand-why, .cui-cand-matter, .cui-cand-facts { font-size: 12px; color: var(--text3); margin-top: 2px; }
.cui-decide { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.cui-notice:empty { display: none; }
.cui-notice { font-size: 13px; padding: 8px 0; }
.cui-notice.cui-bad { color: var(--red, #c53030); }
/* CONFLICTS_BY_CLIENT §2 A1 — THE TITLE LINE, THEN ONE BAR THAT STAYS AT THE TOP. Tim, 09-22:
   the tabs *"move down when 'check a name' and 'Import a conflict list' are clicked"* and
   *"should be fixed on the very top of the page"*. So the three tabs (CONFLICTS_PAGE_TABS §1 —
   a tab IS the collapse) and the three buttons share ONE sticky bar, every button opens a
   pop-up, and nothing can sit between the bar and the tab panels. The bar sticks to the top of
   `.content`, which is the scrolling area on both hosts; its opaque background is what the list
   scrolls under. Under 720px the buttons take a second line beneath the tabs.
   ⛔ `top` IS THE NEGATIVE OF `.content`'s PADDING, and a measurement put it there: a sticky box
   stops at its scroll container's PADDING edge, so `top: 0` left the bar 24px below the top of
   the scrolling area with the list showing through the strip above it (page-frame.test.js A1.2
   measured 80 against 56). */
.cui-titleline { display: flex; align-items: center; gap: 2px; margin: 0 0 6px; }
.cui-titleline .cui-h2 { margin: 0; }
.cui-bar { position: sticky; top: calc(-1 * var(--content-pad)); z-index: 60; background: var(--bg);
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 6px 16px; padding-top: 4px;
  border-bottom: 1px solid var(--border); }
.cui-bar-acts { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-left: auto; padding: 0 0 7px; }
.cui-tabs { display: flex; gap: 2px; align-items: stretch; margin: 4px 0 0;
  border-bottom: 1px solid var(--border); overflow-x: auto; }
/* In the bar, the bar's own line is the strip's line. */
.cui-bar .cui-tabs { margin: 0; border-bottom: none; }
@media (max-width: 720px) {
  .cui-bar { flex-direction: column; align-items: stretch; gap: 0; }
  .cui-bar .cui-tabs { border-bottom: 1px solid var(--border); }
  /* ONE line beneath the tabs, not two: the bar stays on screen the whole time, so every row it
     takes is a row of the list the reader cannot see. MEASURED at 390px (ADD_A_CONTACT §4.3, the
     first button now "Add a contact"): the three need 344.8px of the 342px there is at 7px sides
     and a 6px gap, and 336.8px at 6px sides and a 5px gap. */
  .cui-bar-acts { margin-left: 0; padding: 8px 0; gap: 5px; }
  .cui-bar-acts .btn-sm { padding-left: 6px; padding-right: 6px; }
}
.cui-tab { background: none; border: none; border-bottom: 2px solid transparent;
  padding: 8px 14px; font: inherit; font-size: 14px; font-weight: 500; color: var(--text3);
  cursor: pointer; white-space: nowrap; display: flex; align-items: center; gap: 6px; }
.cui-tab:hover { color: var(--text); }
.cui-tab-on { color: var(--navy, #1a2e4a); border-bottom-color: var(--navy, #1a2e4a); }
.cui-tab:focus-visible { outline: 2px solid var(--navy, #1a2e4a); outline-offset: -2px; }
/* The pill a tab carries. Grey says how many are there; red says how many are WAITING — and
   §1.3 gives neither one a zero to render, so an empty pill is hidden rather than padded. */
.cui-tab-count { font-size: 12px; font-weight: 600; line-height: 1; padding: 3px 7px;
  border-radius: 999px; background: var(--surface3); color: var(--text2); }
.cui-tab-count-alert { background: var(--red, #c53030); color: #fff; }
.cui-panel { padding-top: 4px; }
/* One toolbar row per panel — the filter, the sort, and (firm host only) the download at the
   far end. It replaces the heading-row tools the collapsed sections needed. */
.cui-toolbar { display: flex; gap: 8px; align-items: flex-start; flex-wrap: wrap;
  margin: 10px 0 12px; }
.cui-toolbar .cui-input-sm { width: auto; flex: 0 1 200px; }
.cui-toolbar-end { margin-left: auto; }
/* §2 A5 — the box reads Search and the line under it says what it covers, so the two are one
   column. ⛔ THE BASIS WOULD BE A HEIGHT IN HERE (the `.cui-col-sub` lesson below): the toolbar
   rule above gives the box `flex: 0 1 200px`, which in a column lands on the vertical axis. */
.cui-search { display: flex; flex-direction: column; gap: 2px; flex: 1 1 260px; min-width: 0; }
.cui-toolbar .cui-search .cui-input-sm { flex: 0 0 auto; width: 100%; }
.cui-search-says { margin-top: 0; }
/* CONFLICTS_BY_CLIENT §3 B1 — the list by client. The Show menu keeps its "?" beside it; the
   A–Z row sits DIRECTLY under the search box (agreed 09-22: you pick a letter before you
   scroll), a letter with nobody under it is greyed, and the chosen one reads as chosen. */
.cui-show { display: inline-flex; align-items: center; gap: 2px; }
.cui-toolbar .cui-show .cui-input-sm { flex: 0 1 200px; }
.cui-az { display: flex; flex-wrap: wrap; gap: 2px; margin: -4px 0 12px; }
.cui-az-btn { min-width: 24px; padding: 3px 5px; font: inherit; font-size: 12px; line-height: 1.2;
  background: var(--surface); border: 1px solid var(--border); border-radius: 4px;
  color: var(--text2); cursor: pointer; }
.cui-az-btn:hover:not(:disabled) { border-color: var(--navy, #1a2e4a); color: var(--navy, #1a2e4a); }
.cui-az-btn:disabled { color: var(--text4); background: transparent; border-color: transparent;
  cursor: default; }
.cui-az-on { background: var(--navy, #1a2e4a); border-color: var(--navy, #1a2e4a); color: #fff; }
/* Settled B6 — ‹ Previous · 26–50 of 312 · Next ›, under the list. */
.cui-pager { display: flex; align-items: center; justify-content: center; gap: 12px;
  margin: 14px 0 4px; }
.cui-pager .cui-fine { margin-top: 0; }
/* Settled B9 — the list is holding the people one check named, and the way back to everyone. */
.cui-banner { font-size: 13px; padding: 8px 12px; margin: 0 0 10px; border-radius: var(--radius);
  background: var(--surface3); color: var(--text2); }
/* A card's matter lines (settled B12), and what a search found: the matched line is marked, and
   somebody else it found on that matter is named under it. */
.cui-mlines { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.cui-mline { font-size: 13px; color: var(--text2); }
.cui-mline-hit { color: var(--text); font-weight: 600; }
.cui-match { margin-top: 2px; }
.cui-hit-name { text-decoration: underline; text-decoration-thickness: 2px;
  text-underline-offset: 3px; }
/* In the client box a line IS the door to its matter box — a button that reads as a line. */
.cui-mline-btn { display: block; width: 100%; text-align: left; background: none; border: none;
  border-bottom: 1px solid var(--border); padding: 7px 2px; font: inherit; font-size: 13px;
  color: var(--navy, #1a2e4a); cursor: pointer; }
.cui-mline-btn:hover { background: var(--surface3); }
#cui-cb-add-matter, #cui-cb-first-matter { margin-top: 8px; }
/* The client box's company tick, the matter box's parties' tick, and its two questions. */
.cui-check { display: flex; align-items: center; gap: 6px; font-size: 13px; margin: 4px 0 2px; }
.cui-check-sm { font-size: 12px; color: var(--text2); margin-top: 4px; }
.cui-fieldset { border: none; margin: 0; padding: 0; min-width: 0; display: flex;
  flex-wrap: wrap; align-items: center; gap: 4px 14px; }
.cui-fieldset legend { padding: 0; width: 100%; }
.cui-radio { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.cui-date-inline { width: auto; flex: 0 1 170px; }
/* Settled B13 — the checks that named this person, collapsed until asked for. */
.cui-details { margin: 14px 0 6px; }
.cui-details > summary { font-size: 13px; font-weight: 600; color: var(--text2); cursor: pointer; }
.cui-details[open] > summary { margin-bottom: 8px; }
.cui-to-list { margin-top: 8px; }
.cui-section { border-top: 1px solid var(--border); padding: 16px 0 4px; }
.cui-section:first-of-type { border-top: none; }
.cui-sec-head { display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
.cui-count { color: var(--text3); font-size: 13px; font-weight: 400; }
.cui-sec-body { display: flex; flex-direction: column; gap: 8px; }
/* §1.4 frame B3 — what *Needs attention* says when nothing does. A dashed card, because it is
   a report rather than a row: nothing is waiting, and here is the scale of the list and when a
   check last ran. */
.cui-nothing { border: 1px dashed var(--border); border-radius: var(--radius);
  padding: 20px 16px; margin-top: 14px; }
.cui-nothing-head { font-size: 15px; font-weight: 600; }
/* A link that is a <button> because it performs an act on this page rather than going
   anywhere — it shows the Check history tab. */
.cui-linkbtn { background: none; border: none; padding: 0; font: inherit; font-size: 12px;
  cursor: pointer; text-decoration: underline; }
.cui-h4 { margin: 14px 0 6px; font-size: 13px; font-weight: 600; color: var(--text2); }
.cui-link { color: var(--navy, #1a2e4a); }
.cui-card { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; }
/* Tim's ruling 3 (09-16): the WHOLE group card opens the matter — "we can't click on any of
   this information to open it up" was said about a card with a link in the corner. */
.cui-card-click { cursor: pointer; }
.cui-card-click:hover { border-color: var(--navy, #1a2e4a); }
.cui-card-click:focus-visible { outline: 2px solid var(--navy, #1a2e4a); outline-offset: 2px; }
.cui-card-flag { border-left: 3px solid var(--amber, #b7791f); }
/* CONFLICT_MERGE §4.4 — one possible duplicate: the two people side by side, why they may be one
   across the whole card, and each one's matters and calls under their own name. Two columns at
   every width: a name wraps inside its column rather than the pair coming apart. */
.cui-dup-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2px 16px; }
.cui-dup-side { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; min-width: 0; }
.cui-dup-side .cui-fine { margin-top: 0; }
/* CONFLICT_MERGE §5.1 — the names are words from Stage C; **Compare** opens the two together. */
.cui-dup-name { font-size: 14px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.cui-dup-why { grid-column: 1 / -1; color: var(--text2); }
/* COMBINE_SAME_NUMBER_RECORDS §3 B4 — names that differ on one number: the second line, across the card. */
.cui-dup-differ { grid-column: 1 / -1; color: var(--text2); margin-top: 0; }
.cui-dup-acts { justify-content: flex-end; margin-top: 8px; }
/* CONFLICT_MERGE §5.7 — what a merge or an Undo just did: a line of its own at the foot of the
   sticky bar, so it is in view however far down the merge was made, with its ✕ at the end. */
.cui-bar .cui-merge-banner { flex-basis: 100%; display: flex; align-items: baseline; gap: 8px;
  margin: 0 0 8px; }
.cui-merge-banner-text { flex: 1 1 auto; min-width: 0; }
.cui-merge-banner .cui-linkbtn { font-size: 13px; }
/* CONFLICT_MERGE §5.1 — the two records side by side, and STACKED on a phone: a column's basis is
   wider than half a phone's box, so at 390px the second one wraps under the first. Each row is a
   label and its lines, one number or email per line; an empty row reads "—".
   ⚠ `.cui-row.cui-cmp`, not `.cui-cmp`: the box is also a `.cui-row-3`, whose 150px basis is declared
   further down at the same weight and WON — two 173px columns side by side at 390px, measured by
   test/conflict-merge/merge-screen.test.js MV6 before this was right. */
.cui-row.cui-cmp > .cui-col { flex: 1 1 280px; min-width: 0; }
.cui-cmp-col { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; }
.cui-cmp-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; margin-bottom: 6px; }
.cui-cmp-head .cui-fine { margin-top: 0; }
.cui-cmp-rows { display: grid; grid-template-columns: minmax(0, 7.5em) minmax(0, 1fr); gap: 4px 10px;
  margin: 0 0 8px; font-size: 13px; }
.cui-cmp-rows dt { color: var(--text3); }
.cui-cmp-rows dd { margin: 0; color: var(--text); overflow-wrap: anywhere; }
.cui-cmp-open { font-size: 13px; }
/* §5.2 — the merge step: one question per field that differs, the value and where it came from. */
.cui-merge-q { margin: 0 0 10px; }
.cui-merge-opt { width: 100%; flex-wrap: wrap; gap: 2px 6px; }
.cui-merge-opt .cui-fine { margin-top: 0; }
.cui-merge-dob { border-left: 3px solid var(--amber, #7a4a10); background: var(--amber-bg, #fdf4e8);
  color: var(--text); font-size: 13px; padding: 6px 10px; margin: 4px 0 6px; border-radius: var(--radius); }
.cui-merge-signal { font-size: 13px; line-height: 1.45; color: var(--text); }
/* §5.7 — at the foot of a person's record, the merges that made it what it is. */
.cui-merges { margin-top: 10px; }
.cui-merge-line { margin-top: 4px; }
.cui-people { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.cui-person-pill { font-size: 13px; color: var(--text2); }
.cui-qrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 0; border-top: 1px solid var(--border); }
.cui-cand-with { font-size: 12px; color: var(--text2); margin-top: 2px; }
.cui-pill-certain { background: rgba(197,48,48,.1); color: var(--red, #c53030); }
.cui-pill-possible { background: rgba(183,121,31,.12); color: var(--amber, #b7791f); }
/* The intake card's own sections (§5.1): the person, the matter, the other parties. */
.cui-card-sec { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 12px; }
.cui-card-sec:first-of-type { border-top: none; margin-top: 6px; }
.cui-row-3 { align-items: flex-start; }
.cui-row-3 > .cui-col { flex: 1 1 150px; min-width: 0; }
.cui-col-end { display: flex; align-items: flex-end; justify-content: flex-end; }
.cui-party { border: 1px dashed var(--border); border-radius: var(--radius, 6px);
  padding: 8px 10px; margin-bottom: 8px; }
/* ADD_A_CONTACT §4.1 — the person's Notes: four rows, growing with what is written (growNotes);
   the call's summary OFFERED to a record whose notes are empty reads grey, a suggestion, until the
   one click that takes it. */
.cui-notes-box { width: 100%; box-sizing: border-box; resize: vertical; overflow: hidden;
  font-family: inherit; line-height: 1.45; }
.cui-notes-offer { margin-top: 6px; padding: 8px 10px; border: 1px dashed var(--border);
  border-radius: var(--radius, 6px); }
.cui-notes-suggest { color: var(--text4, #9a988f); font-style: italic; margin-top: 0; }
/* §4.2 — a caller the call left awaiting confirmation, with Confirm beside the line. */
.cui-awaiting { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; color: var(--text2); }
/* §4.1 — the banner once a new contact is saved. */
.cui-notice.cui-ok { color: var(--text2); }
.cui-card-top { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; }
/* CONFLICT_CHECK_REWORK B2 — the tag in a call's own view (both hosts; conflicts-ui.js callTagHtml). */
.cui-call-tag { margin-top: 14px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius, 6px);
  font-size: 13px; line-height: 1.5; color: var(--text); }
.cui-call-tag-acts { margin-top: 8px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cui-call-tag-marked { margin-top: 6px; }
/* CONFLICTS_FIRST_USE_FIXES A4 — the "Who is this?" header. The title and the number sit on
   the left, the way into Conflicts on the right (Tim, 09-20: "comfortably to the right").
   The sub-line's own 14px bottom margin is what separates the header from the form, so the
   title's margin goes and the gap is kept where it already was. */
.cui-c-head { align-items: baseline; }
/* In the box's header (CONFLICTS_BY_CLIENT §2 A3) the same alignment, over the header's own. */
.cui-modal-head.cui-c-head { align-items: baseline; }
.cui-c-head .cui-h3 { margin-top: 0; }
.cui-c-head .cui-sub { margin-bottom: 0; }
.cui-c-head #cui-c-open { flex-shrink: 0; white-space: nowrap; font-size: 13px; }
.cui-card-acts { display: flex; gap: 6px; flex-shrink: 0; }
.cui-name { font-weight: 600; font-size: 14px; }
.cui-matter { font-size: 13px; color: var(--text2); margin-top: 2px; }
.cui-notes { font-size: 12px; color: var(--text2); margin-top: 6px; white-space: pre-wrap; }
.cui-pill { display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: var(--surface3); color: var(--text2); }
.cui-pill-soft { background: transparent; border: 1px dashed var(--border); color: var(--text3); }
.cui-pill-warn { background: rgba(197,48,48,.1); color: var(--red, #c53030); }
/* CHECK_HISTORY_AS_RECORD §3.4 — a Flagged card somebody handed on (*needs review*): amber, the
   possible-match tone, because it is still waiting for a person. */
.cui-pill-review { background: rgba(183,121,31,.12); color: var(--amber, #b7791f); }
.cui-hidden { display: none !important; }
/* CONFLICT_REGISTER C — bringing in a list. On the Conflicts page the panel sits in a pop-up of
   its own (CONFLICTS_BY_CLIENT §2 A2); in Configure → Uploaded Documents it is the section itself
   (a .cui-card, inline). Its heading picker is a plain two-column grid that collapses to one at
   phone width (the screen is read on a phone as often as not). */
/* Settled A7a — the rows that attach to a matter the firm already has, one line per matter. */
.cui-attaches { margin: 0 0 12px; padding-left: 18px; font-size: 13px; color: var(--text2); }
.cui-attaches li { margin: 2px 0; }
/* CONFLICTS_PAGE_TABS §2.2/§2.7 — ONE ROW PER COLUMN IN THE FIRM'S FILE. The firm's heading and
   two of their own values on the left, what we read it as on the right; a two-column grid at
   desktop that stacks at phone width. Tim called the screen this replaces "quite a bit of white
   rectangles" — it was twenty unlabelled selects, which is a labelling problem and not a colour
   one, so the control here is the ordinary .cui-input.cui-input-sm and the words carry it. */
.cui-cols { display: grid; gap: 2px; margin: 10px 0 6px; }
.cui-col-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 6px 16px; align-items: start; padding: 9px 0; border-top: 1px solid var(--border); }
.cui-col-row:first-child { border-top: none; }
.cui-col-name { font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.cui-col-samples { font-size: 12px; color: var(--text3); margin-top: 2px;
  overflow-wrap: anywhere; }
.cui-col-read { display: grid; gap: 6px; }
.cui-col-sub { display: flex; flex-direction: column; gap: 3px; font-size: 12px;
  color: var(--text2); }
/* ⛔ THE BASIS IS A HEIGHT IN HERE. `.cui-input` carries `flex: 1 1 240px` for the horizontal
   rows it was written for; in a column-direction label that 240px lands on the MAIN axis,
   which is now the height — every select rendered about 120px tall, measured. The control
   sizes itself. */
.cui-col-sub .cui-input { flex: 0 0 auto; }
/* The two controls a column reveals when it says it names another person. Dashed, because they
   belong to the row above rather than standing on their own. */
.cui-col-party { border-left: 2px dashed var(--border); padding-left: 10px; display: grid;
  gap: 5px; }
/* One sentence, and only while nothing reads as Role (§2.5). The select sits INSIDE it, so the
   whole thing reads as a sentence rather than as a labelled control. */
.cui-defrole { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 6px 0 4px; }
.cui-defrole .cui-input-sm { width: auto; flex: 0 1 190px; }
.cui-table { width: 100%; border-collapse: collapse; font-size: 12px; margin: 10px 0; }
.cui-table th { text-align: left; font-weight: 600; color: var(--text2);
  border-bottom: 1px solid var(--border); padding: 5px 8px 5px 0; }
.cui-table td { padding: 5px 8px 5px 0; border-bottom: 1px solid var(--border2, var(--border));
  vertical-align: top; }
.cui-suggested { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; }
@media (max-width: 640px) {
  /* CONFLICTS_PAGE_TABS — all three tabs on one phone screen. The strip scrolls either way
     (`overflow-x: auto`), but a third tab a reader has to discover by swiping is a third tab
     most readers never find. MEASURED at 390px, in the offline render harness: 406px of tabs
     in a 342px strip without this rule (Check history clipped), 342px with it. Narrower than
     390 still scrolls, which is the right way to run out of room. */
  .cui-tab { padding: 8px 6px; font-size: 13px; gap: 5px; }
  .cui-tab-count { padding: 2px 6px; font-size: 11px; }
  /* §2.7 — the heading and what we read it as stack on a phone. (The rules that stood here
     styled the retired field-per-row grid and the two Additional-party slots; `.cui-parties`
     as a CLASS is emitted by nothing — the intake card's own `#cui-parties` is an id.) */
  .cui-col-row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  /* A preview of somebody else's spreadsheet is the one thing here that legitimately
     outgrows a phone; it scrolls in its own box rather than pushing the page sideways. */
  .cui-table { display: block; overflow-x: auto; }
}
/* CONFLICTS_BY_CLIENT §2 A2/A3 — every box this screen opens, from ONE builder (`overlay()` in
   conflicts-ui.js). A column: a header that never scrolls (the title and the ✕), a middle that is
   the only part that scrolls, and a footer that never scrolls (the box's own buttons) — the shape
   TEAM_ALERTS_AND_CARD_FIXES A5 gave the member card with inline styles, built here as rules. The
   middle can shrink below its content because it is itself a scroll container, whose automatic
   minimum height is zero (measured in A5), so no `min-height: 0` is written. `dvh` after `vh`: on
   a phone the visible height is smaller than 100vh while the address bar shows, and a browser
   without dvh keeps the vh line. A box opened from a box gets a higher z-index inline. */
.cui-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 9998;
  display: flex; align-items: center; justify-content: center; padding: 16px; }
.cui-modal { position: relative; background: var(--surface); border-radius: var(--radius);
  max-width: 480px; width: 100%; max-height: 88vh; max-height: 88dvh;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 10px 30px rgba(0,0,0,.25); }
.cui-modal-mid { max-width: 640px; }
.cui-modal-wide { max-width: 880px; }
.cui-modal-head { flex: none; display: flex; align-items: center; gap: 12px;
  padding: 14px 14px 10px 18px; border-bottom: 1px solid var(--border); }
.cui-modal-titles { flex: 1 1 auto; min-width: 0; }
/* ADD_A_CONTACT §6 — a box's "?" beside its title, outside the heading the dialog is named by. */
.cui-box-titleline { display: flex; align-items: center; gap: 4px; }
.cui-modal-head .cui-h3 { margin: 0; }
.cui-modal-x { flex: none; background: none; border: none; cursor: pointer; font-size: 20px;
  line-height: 1; color: var(--text3); padding: 4px 6px; border-radius: 4px; }
.cui-modal-x:hover { color: var(--text); background: var(--surface3); }
.cui-modal-body { flex: 1 1 auto; overflow-y: auto; padding: 12px 18px 16px; }
/* A lone box straight in the middle (the check's name box) takes the width — it is not in a
   row, so the row's flex sizing never reaches it. */
.cui-modal-body > .cui-input { display: block; width: 100%; }
.cui-modal-foot { flex: none; padding: 10px 18px 14px; border-top: 1px solid var(--border); }
.cui-modal-foot:empty { display: none; }
.cui-modal-foot .cui-row-end { margin-top: 0; }
/* CONFLICTS_BY_CLIENT §3 B3 — the matter box opens ON TOP of the client box, and on a phone it
   FILLS the screen (Tim's phone idea, 09-22: "maybe the matters box comes above the client's
   box until it is closed out"). Its header and footer stay fixed exactly as every box's do. */
@media (max-width: 720px) {
  .cui-overlay-full { padding: 0; }
  .cui-modal-full { max-width: none; width: 100%; height: 100%; max-height: 100%;
    border-radius: 0; box-shadow: none; }
}
/* §2 A4 — the unsaved-changes question, asked inside the box it is about. The layer covers the
   box and not the page, so the reader can still see the work they would be leaving. Its level is
   above the "?" icons' 50 (the help rules above), which share the box's stacking context — below
   that, a "?" under the question would paint on top of it. */
.cui-confirm-layer { position: absolute; inset: 0; z-index: 100; background: rgba(255,255,255,.72);
  display: flex; align-items: center; justify-content: center; padding: 16px; }
.cui-confirm { background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 8px 24px rgba(0,0,0,.18); padding: 16px 18px;
  max-width: 360px; width: 100%; }
.cui-confirm-q { margin: 0 0 12px; font-size: 14px; font-weight: 600; line-height: 1.45; }
.cui-confirm .cui-row-end { margin-top: 0; }
/* CONFLICTS_BY_CLIENT §4 (Stage C) — duplicates caught while typing. A note sits DIRECTLY beneath
   the field that matched, inside the scrolling middle, so nothing on the page moves (R-e 1). One
   that must be answered before Save carries the amber edge the conflict colours already use; the
   informational kind (C3e) and the linked row (C4b) the navy one. */
.cui-dup-notes { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.cui-dup-notes:empty { display: none; }
.cui-dup-note { border: 1px solid var(--border2); border-left: 3px solid var(--navy, #1a2e4a);
  border-radius: var(--radius); background: var(--surface3); padding: 8px 10px; }
.cui-dup-block { border-left-color: var(--amber, #7a4a10); background: var(--amber-bg, #fdf4e8); }
.cui-dup-text { margin: 0 0 6px; font-size: 13px; line-height: 1.45; color: var(--text); }
.cui-dup-linked .cui-dup-text { margin: 0; color: var(--text2); }
.cui-dup-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.cui-dup-x { margin-left: auto; background: none; border: none; cursor: pointer; font-size: 14px;
  line-height: 1; color: var(--text3); padding: 4px 6px; border-radius: 4px; }
.cui-dup-x:hover { color: var(--text); background: var(--surface); }
/* Save stopped at a note nobody answered: it is scrolled into view and flashes once (R-e 3). */
.cui-dup-attn { animation: cui-dup-attn 1.2s ease-out 1; }
@keyframes cui-dup-attn { from { box-shadow: 0 0 0 3px var(--amber-border, #e8c898); }
  to { box-shadow: 0 0 0 0 transparent; } }
/* Settled C3d — what was typed filled a record's blanks, and each such box is marked unsaved. */
.cui-dup-filled { background: var(--amber-bg, #fdf4e8); color: var(--text2); border-radius: var(--radius);
  padding: 8px 10px; margin: 0 0 8px; }
.cui-input.cui-filled { border-color: var(--amber-border, #e8c898); background: var(--amber-bg, #fdf4e8); }
/* Settled C4b — a party row linked to a record: its own boxes are the record's, and read-only. */
.cui-input.cui-linked[readonly] { background: var(--surface3); color: var(--text2); }
/* R-e 4 — THE CONFLICT WARNING LIVES IN THE FIXED FOOTER, directly above Cancel · Save, where a
   person typing an other party at the bottom of a long box can see it. Collapsed it is one line;
   opened, its list scrolls within itself, capped at about 40% of the box's height (the box is at
   most 88vh, and a phone's matter box the whole screen). */
.cui-warn { border: 1px solid var(--amber-border, #e8c898); border-left: 3px solid var(--amber, #7a4a10);
  border-radius: var(--radius); background: var(--amber-bg, #fdf4e8); padding: 7px 10px; margin: 0 0 8px; }
.cui-warn-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; font-size: 13px; }
.cui-warn-title { font-weight: 600; color: var(--text); }
.cui-warn-count { color: var(--text2); }
.cui-warn-head .cui-linkbtn { margin-left: auto; font-size: 13px; }
.cui-warn-body { max-height: 35vh; overflow-y: auto; margin-top: 6px; }
.cui-warn-cand { padding-bottom: 4px; }
.cui-warn-cand .cui-cand { padding-top: 6px; }
.cui-warn-more { margin: 2px 0 4px 10px; }
.cui-warn-more .cui-fine { margin-top: 2px; }
.cui-warn-line { margin-top: 8px; }
/* CHECK_HISTORY_AS_RECORD §3.5 — the note that goes on the record with a save made after the warning. */
.cui-warn .cui-warn-note { display: block; width: 100%; box-sizing: border-box; margin-top: 6px; }
@media (max-width: 720px) {
  .cui-modal-full .cui-warn-body { max-height: 40vh; max-height: 40dvh; }
}
@media (max-width: 768px) {
  .cui-input { flex-basis: 100%; }
}

/* ── The phone tier's own squeeze (CONFLICT_REGISTER §6.6, kept; its table cap RETIRED by
   CALL_LOG_SUMMARY_COLUMN 2026-09-15) ────────────────────────────────────────────────────
   Below 900px the time AND duration columns are hidden, so the caller competes only with the
   badges and the 64px View button — measured at 128px against the badge column's 150px, which
   is the one column a phone reader actually needs coming second to a pair of pills. That is
   still true and this rule still does that job. What went with it was the whole-table cap the
   same arc added: capping the TABLE shrank the log instead of the column and left a 232px band
   of unused space at 1440 (measured: a 940px table in a 1172px section), which is the thing
   Tim then complained about. The remainder is governed by a width on Caller now, not by a
   ceiling on the table. */
@media (max-width: 900px) {
  .call-log-table .col-badges { width: 104px; }
}
