:root{
  --ink:#1c2430; --muted:#6b7684; --line:#e3e7ec; --bg:#f6f7f9; --card:#fff;
  --accent:#175cd3; --accent-dark:#0f4cb0; --danger:#b42318; --danger-bg:#fef3f2;
  --warn:#b54708; --warn-bg:#fffaeb; --ok:#067647; --ok-bg:#ecfdf3;
}
*{box-sizing:border-box}
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--bg);color:var(--ink);font-size:15px;line-height:1.45}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}

/* top bar */
.topbar{background:#101828;color:#fff;padding:10px 16px;display:flex;flex-wrap:wrap;gap:10px;
  align-items:center;position:sticky;top:0;z-index:20}
.topbar .brand{font-weight:700;font-size:17px;letter-spacing:.2px;margin-right:6px}
.topbar nav{display:flex;gap:4px;flex-wrap:wrap}
.topbar nav a{color:#d0d5dd;padding:6px 10px;border-radius:6px;font-size:14px}
.topbar nav a:hover{background:#1d2939;text-decoration:none;color:#fff}
.topbar nav a.active{background:#1d2939;color:#fff}
.topbar .spacer{flex:1}
.topbar select{background:#1d2939;color:#fff;border:1px solid #344054;border-radius:6px;padding:6px 8px;font-size:14px}
.topbar .user{font-size:13px;color:#d0d5dd}
.topbar button.logout{background:transparent;border:1px solid #344054;color:#d0d5dd;border-radius:6px;
  padding:5px 10px;cursor:pointer;font-size:13px}

.wrap{max-width:1200px;margin:0 auto;padding:18px 14px 40px}
h1{font-size:22px;margin:6px 0 14px}
h2{font-size:16px;margin:22px 0 10px}
.card{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:14px 16px;margin-bottom:14px}

/* KPI cards */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.kpi{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:14px}
.kpi .num{font-size:28px;font-weight:700;line-height:1.1}
.kpi .lbl{color:var(--muted);font-size:13px;margin-top:2px}
.kpi.alert{border-color:#fecdca;background:var(--danger-bg)}
.kpi.alert .num{color:var(--danger)}
.kpi.warn{border-color:#fedf89;background:var(--warn-bg)}
.kpi.warn .num{color:var(--warn)}
a.kpi{display:block;color:inherit;text-decoration:none;cursor:pointer}
a.kpi:hover{border-color:var(--accent);text-decoration:none;box-shadow:0 1px 5px rgba(16,24,40,.12)}

/* tables & lists */
table{width:100%;border-collapse:collapse;font-size:14px}
th,td{text-align:left;padding:8px 8px;border-bottom:1px solid var(--line);vertical-align:top}
th{color:var(--muted);font-weight:600;font-size:12.5px;text-transform:uppercase;letter-spacing:.04em}
.badge{display:inline-block;padding:1px 8px;border-radius:999px;font-size:12px;font-weight:600}
.badge.open{background:#eef4ff;color:var(--accent-dark)}
.badge.in_progress{background:#fffaeb;color:var(--warn)}
.badge.blocked{background:var(--danger-bg);color:var(--danger)}
.badge.done{background:var(--ok-bg);color:var(--ok)}
.badge.overdue{background:var(--danger-bg);color:var(--danger)}

/* forms & buttons */
button,.btn{background:var(--accent);color:#fff;border:none;border-radius:7px;padding:8px 14px;
  font-size:14px;cursor:pointer;display:inline-block}
button:hover,.btn:hover{background:var(--accent-dark);text-decoration:none}
button.secondary,.btn.secondary{background:#fff;color:var(--ink);border:1px solid var(--line)}
button.secondary:hover{background:#f2f4f7}
button.small{padding:4px 9px;font-size:12.5px}
input,select,textarea{width:100%;padding:8px 10px;border:1px solid var(--line);border-radius:7px;
  font-size:14px;font-family:inherit;background:#fff;color:var(--ink)}
label{font-size:13px;font-weight:600;color:var(--muted);display:block;margin:10px 0 4px}
.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:0 14px}
.error{background:var(--danger-bg);color:var(--danger);border:1px solid #fecdca;border-radius:8px;
  padding:9px 12px;font-size:14px;margin-bottom:12px;display:none}
#msg, #dMsg{background:var(--ok-bg);color:var(--ok);border:1px solid #a6f4c5;border-radius:8px;
  padding:9px 12px;font-size:14px;margin-bottom:12px;display:none}

/* kanban */
.board{margin-bottom:26px}
.board h2{margin-bottom:4px}
.board .entity-tag{color:var(--muted);font-size:13px;font-weight:400}
.columns{display:flex;gap:12px;overflow-x:auto;padding:6px 2px 12px;align-items:flex-start}
.column{background:#eef1f4;border-radius:10px;min-width:240px;width:240px;padding:10px;flex-shrink:0}
.column h3{margin:2px 2px 10px;font-size:13.5px;color:#344054;display:flex;justify-content:space-between}
.column h3 .cnt{color:var(--muted);font-weight:400}
.deal{background:#fff;border:1px solid var(--line);border-radius:8px;padding:9px 10px;margin-bottom:9px;
  box-shadow:0 1px 2px rgba(16,24,40,.05)}
.deal .t{font-weight:600;font-size:14px}
.deal .v{color:var(--ok);font-weight:600;font-size:13.5px;margin-top:2px}
.deal .n{color:var(--muted);font-size:12.5px;margin-top:3px}
.deal .c{color:var(--muted);font-size:12.5px}
.deal .moves{display:flex;gap:6px;margin-top:8px}
.deal .moves button{background:#f2f4f7;color:#344054;border:1px solid var(--line);padding:3px 8px;font-size:12px}
.deal .moves button:hover{background:#e4e7ec}
.deal.dragging{opacity:.5}
.column.dragover{outline:2px dashed var(--accent);outline-offset:-4px}
/* pointer drag (mos14) */
.deal{cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none}
.deal.drag-src{opacity:.35}
.drag-clone{position:fixed;z-index:1000;pointer-events:none;margin:0;cursor:grabbing;
  box-shadow:0 14px 30px rgba(16,24,40,.28);transform:rotate(2deg) scale(1.02)}
.drop-line{height:5px;border-radius:3px;background:var(--accent);margin-bottom:9px}
body.dragging-board{cursor:grabbing}
body.dragging-board .column{min-height:170px}

/* timeline */
.timeline{list-style:none;margin:0;padding:0}
.timeline li{border-left:3px solid var(--line);padding:2px 0 12px 14px;position:relative}
.timeline li::before{content:"";position:absolute;left:-6px;top:7px;width:9px;height:9px;border-radius:50%;background:var(--accent)}
.timeline .meta{color:var(--muted);font-size:12.5px}
.timeline .kind{font-weight:700;text-transform:capitalize}
.empty{color:var(--muted);font-size:14px;padding:8px 0}

/* conversations inbox */
.unread-dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:var(--danger);
  margin-right:7px;vertical-align:middle;flex-shrink:0}
.inbox{display:grid;grid-template-columns:minmax(280px,380px) 1fr;gap:14px;align-items:start}
@media (max-width:820px){ .inbox{grid-template-columns:1fr} }
.thread-list{padding:6px}
.trow{display:block;width:100%;text-align:left;background:transparent;color:var(--ink);border:none;
  border-bottom:1px solid var(--line);padding:10px 10px;border-radius:0;cursor:pointer}
.trow:hover{background:#f2f4f7}
.trow.selected{background:#eef4ff}
.trow .t-head{display:flex;align-items:baseline;gap:8px}
.trow .t-name{font-weight:600;font-size:14.5px}
.trow.unread .t-name{font-weight:700}
.trow .t-time{margin-left:auto;color:var(--muted);font-size:12px;white-space:nowrap}
.trow .t-prev{color:var(--muted);font-size:13px;margin-top:2px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.trow.unread .t-prev{color:var(--ink)}
.badge.sms{background:#fdf6e3;color:#8a6d00}
.badge.email{background:#eef4ff;color:var(--accent-dark)}
.badge.call{background:var(--ok-bg);color:var(--ok)}
.badge.note{background:#eef1f4;color:#344054}
.msg-flow{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.msg{max-width:78%;padding:8px 12px;border-radius:12px;font-size:14px;white-space:pre-wrap;
  overflow-wrap:anywhere}
.msg .m-meta{display:block;color:var(--muted);font-size:11.5px;margin-top:4px}
.msg.in{align-self:flex-start;background:#eef1f4;border-bottom-left-radius:3px}
.msg.out{align-self:flex-end;background:var(--accent);color:#fff;border-bottom-right-radius:3px}
.msg.out .m-meta{color:#cfdefc}
.msg .m-delivery{display:block;color:var(--muted);font-size:11px;margin-top:2px}
.msg.out .m-delivery{color:#cfdefc}
.msg .m-delivery.failed{color:var(--danger);font-weight:600}
.msg.out .m-delivery.failed{color:#ffc9c0}
.msg.note{align-self:center;background:var(--warn-bg);color:var(--warn);font-style:italic;
  max-width:92%;text-align:center}
.login-box{max-width:380px;margin:9vh auto;background:#fff;border:1px solid var(--line);
  border-radius:12px;padding:26px 24px}

/* calendar */
.badge.scheduled{background:#eef4ff;color:var(--accent-dark)}
.badge.showed{background:var(--ok-bg);color:var(--ok)}
.badge.no_show{background:var(--danger-bg);color:var(--danger)}
.badge.cancelled{background:#eef1f4;color:var(--muted)}
.badge.rescheduled{background:#fffaeb;color:var(--warn)}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.cal-dow{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;
  letter-spacing:.04em;text-align:center;padding:2px 0}
.cal-cell{border:1px solid var(--line);border-radius:8px;min-height:88px;padding:5px 6px;
  background:#fff;cursor:pointer;overflow:hidden}
.cal-cell:hover{border-color:var(--accent)}
.cal-cell.other{background:#fafbfc;color:var(--muted)}
.cal-cell.today{outline:2px solid var(--accent);outline-offset:-2px}
.cal-cell.selected{background:#eef4ff}
.cal-cell .dnum{font-size:12.5px;font-weight:600;margin-bottom:3px}
.appt-chip{display:block;font-size:11.5px;line-height:1.35;padding:2px 5px;border-radius:5px;
  margin-bottom:3px;background:#eef4ff;color:var(--accent-dark);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.appt-chip.showed{background:var(--ok-bg);color:var(--ok)}
.appt-chip.no_show{background:var(--danger-bg);color:var(--danger)}
.appt-chip.rescheduled{background:#fffaeb;color:var(--warn)}
.appt-chip.cancelled{background:#eef1f4;color:var(--muted);text-decoration:line-through}
/* calendar view switcher + day columns (mos25) */
.view-switch{display:inline-flex;margin-left:10px;border:1px solid var(--line);
  border-radius:8px;overflow:hidden;vertical-align:middle}
.view-switch button{border:0;border-radius:0}
.view-switch button.active{background:var(--accent);color:#fff}
.view-switch button.active:hover{background:var(--accent-dark)}
.cal-col-head{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;
  letter-spacing:.04em;text-align:center;padding:2px 0;cursor:pointer;border-radius:6px}
.cal-col-head .dnum{display:block;font-size:16px;font-weight:700;color:var(--ink);
  text-transform:none;letter-spacing:0}
.cal-col-head.today .dnum{color:var(--accent)}
.cal-col-head.selected{background:#eef4ff}
.cal-col{border:1px solid var(--line);border-radius:8px;min-height:180px;padding:5px 6px;
  background:#fff;cursor:pointer;overflow:hidden}
.cal-col:hover{border-color:var(--accent)}
.cal-col.today{outline:2px solid var(--accent);outline-offset:-2px}
.cal-col.selected{background:#eef4ff}
.appt-row{display:block;font-size:11.5px;line-height:1.35;padding:3px 5px;border-radius:5px;
  margin-bottom:3px;background:#eef4ff;color:var(--accent-dark);cursor:pointer;overflow:hidden}
.appt-row .who{display:block;font-size:10.5px;opacity:.75;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.appt-row.showed{background:var(--ok-bg);color:var(--ok)}
.appt-row.no_show{background:var(--danger-bg);color:var(--danger)}
.appt-row.rescheduled{background:#fffaeb;color:var(--warn)}
.appt-row.cancelled{background:#eef1f4;color:var(--muted);text-decoration:line-through}
select.status-sel{width:auto;padding:2px 6px;font-size:12.5px;border-radius:6px}
/* modal (mos13) */
.modal-backdrop{position:fixed;inset:0;background:rgba(16,24,40,.5);z-index:60;
  display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;padding:5vh 12px}
.modal-card{background:#fff;border-radius:12px;max-width:560px;width:100%;
  padding:22px 24px;box-shadow:0 18px 50px rgba(16,24,40,.35)}
.modal-card h3{margin:0 0 14px}
.past-appt{opacity:.6}
@media (max-width:640px){ .cal-cell{min-height:62px;padding:4px} .appt-chip{font-size:10.5px} .cal-col{min-height:120px;padding:4px} .appt-row{font-size:10.5px} .view-switch{margin-left:0} }
/* users & permissions (mos10) */
.perm-grid td,.perm-grid th{text-align:center}
.perm-grid td:first-child,.perm-grid th:first-child{text-align:left}
.perm-grid input[type=checkbox]{width:18px;height:18px}
.inline-check{display:flex;align-items:center;gap:8px;font-weight:400;color:var(--ink);
  margin:8px 0;text-transform:none;letter-spacing:0;font-size:14px}
.inline-check input[type=checkbox]{width:18px;height:18px;flex-shrink:0}
.badge.inactive{background:#eef1f4;color:var(--muted)}
.login-box h1{margin-top:0}
.check{display:flex;gap:10px;align-items:flex-start}
.check input[type=checkbox]{width:18px;height:18px;margin-top:2px;flex-shrink:0}
.strike{color:var(--muted);text-decoration:line-through}
.small{font-size:12.5px;color:var(--muted)}
@media (max-width:640px){ .kpi .num{font-size:23px} table{font-size:13px} }

/* finance (mos20): trailing-12 expense bars on the Finance page */
.fin-bars{display:flex;align-items:flex-end;gap:8px;overflow-x:auto;padding-top:4px}
.fin-bar-col{flex:1 0 52px;text-align:center}
.fin-bar-num{font-size:11px;color:var(--muted);min-height:14px}
.fin-bar{background:var(--accent);border-radius:4px 4px 0 0;margin:2px auto 0;width:70%}
.fin-bar-lbl{font-size:11px;color:var(--muted);margin-top:4px}
/* mos26b: projected bars are GHOSTS — striped fill + dashed outline,
   never the solid of an actual, so a projection can never be mistaken
   for money that exists. Paired bars sit side by side in one column:
   actual solid on the left, projected ghost on the right. */
.fin-bar.proj{background:repeating-linear-gradient(45deg,rgba(23,92,211,.38) 0 5px,rgba(23,92,211,.07) 5px 10px);
  border:1.5px dashed var(--accent);border-bottom:none}
.fin-bar-pair{display:flex;gap:4px;align-items:flex-end;justify-content:center}
.fin-bar-pair .fin-bar{margin:2px 0 0;width:32%}
.fin-legend{font-size:12.5px;color:var(--muted);display:flex;gap:16px;flex-wrap:wrap;margin-top:8px}
.fin-legend .sw{display:inline-block;width:14px;height:10px;border-radius:2px;background:var(--accent);
  vertical-align:middle;margin-right:5px}
.fin-legend .sw.proj{background:repeating-linear-gradient(45deg,rgba(23,92,211,.38) 0 4px,rgba(23,92,211,.07) 4px 8px);
  border:1px dashed var(--accent)}
.badge.proj{background:#eef4ff;color:var(--accent-dark);border:1px dashed var(--accent)}
td.proj-cell{background:#fbfcfe;color:var(--muted)}

/* notes boxes (mos29): every notes/description field is a real box —
   wide, corner-resizable, auto-growing while you type (app.js), and
   notes render in full wherever they're displayed. */
textarea.notesbox{resize:both;min-height:66px;line-height:1.45}
.notes-full{white-space:pre-wrap;overflow-wrap:break-word}

/* universal attachments (mos27) */
.attach-box{border:1px dashed transparent;border-radius:8px;padding:6px}
.attach-box.attach-drop{border-color:var(--accent);background:#eef4ff}
.attach-row{display:flex;gap:10px;align-items:flex-start;padding:7px 0;
  border-bottom:1px solid var(--line)}
.attach-row:last-child{border-bottom:none}
.attach-main{flex:1;min-width:0;overflow-wrap:break-word}
.attach-thumb{width:56px;height:56px;object-fit:cover;border-radius:6px;
  border:1px solid var(--line);display:block}
.attach-edit{display:inline-flex;gap:6px;align-items:center;flex-wrap:wrap}
.attach-edit .attach-name{width:auto;min-width:160px;flex:1}
.attach-ext{color:var(--muted);font-size:13px}
.attach-controls{margin-top:10px}
.attach-strip .attach-row{padding:4px 0}
.attach-strip .attach-thumb{width:36px;height:36px}
tr.attach-drop-row td, .attach-drop-row{background:#eef4ff !important;
  outline:2px dashed var(--accent);outline-offset:-4px}

/* inline edit (mos31): values on record pages edit where they sit.
   .inline-val is added by app.js only for users who may edit — for
   everyone else the value is plain text with no affordance at all. */
.inline-val{cursor:pointer;border-radius:4px}
.inline-val:hover{background:#eef4ff;box-shadow:0 0 0 3px #eef4ff}
.inline-val:not(:has(.inline-pencil)):hover::after{content:" ✎";
  color:var(--accent);font-size:.85em}
h1.inline-val:hover::after{font-size:.45em}
.inline-pencil{display:none;color:var(--accent);font-size:.85em}
.inline-val .inline-pencil{display:inline}
.inline-val.inline-open{cursor:default;background:transparent;box-shadow:none}
.inline-val.inline-open::after{content:none}
.inline-ed{display:inline-flex;gap:6px;align-items:flex-start;flex-wrap:wrap;
  max-width:100%}
.inline-ed .inline-input{width:auto;min-width:180px}
.inline-ed textarea.inline-input{min-width:280px;width:100%}
.inline-ed input[type="date"].inline-input{min-width:150px}
.inline-err{color:var(--danger);font-size:12.5px;flex-basis:100%}
.inline-saved{color:var(--ok);font-size:12.5px;font-weight:600;margin-left:8px}

/* CSV import (mos17): the drop zone mirrors the attachment drop
   highlight; mapping rows carry their state as a tinted first cell —
   green when mapped, amber while unmapped, grey when deliberately
   skipped, red when the same field is claimed twice. */
.import-drop{border:2px dashed var(--line);border-radius:10px;
  padding:28px 16px;text-align:center;cursor:pointer}
.import-drop.over{border-color:var(--accent);background:#eef4ff}
.map-table td.samples{color:var(--muted);font-size:13px;max-width:340px;
  overflow-wrap:break-word}
.map-table tr td:first-child{border-left:4px solid transparent}
.map-table tr.map-mapped td:first-child{border-left-color:var(--ok)}
.map-table tr.map-unmapped td:first-child{border-left-color:#fedf89}
.map-table tr.map-unmapped{background:var(--warn-bg)}
.map-table tr.map-skipped{opacity:.55}
.map-table tr.map-dup td:first-child{border-left-color:var(--danger)}
.map-table tr.map-dup{background:var(--danger-bg)}
.import-summary .num{font-size:22px;font-weight:700}

/* Receipts (mos21): thumbnail + list card on the receipts page. */
.receipt-thumb{max-width:140px;max-height:140px;border-radius:8px;border:1px solid var(--line)}
.receipt-card{display:flex;gap:14px;align-items:flex-start;padding:12px 0;border-bottom:1px solid var(--line)}
.receipt-card:last-child{border-bottom:0}

/* Invoices (mos22): status chips follow the spec's colours — Sent
   blue, Overdue red, Verified Paid green, Draft grey, Void struck —
   plus the direction tabs on the board. */
.badge.inv-sent{background:#eef4ff;color:var(--accent-dark)}
.badge.inv-overdue{background:var(--danger-bg);color:var(--danger)}
.badge.inv-paid{background:var(--ok-bg);color:var(--ok)}
.badge.inv-draft{background:#eef1f4;color:#344054}
.badge.inv-void{background:#eef1f4;color:var(--muted);text-decoration:line-through}

/* E-sign (mos24): envelope status chips — Draft grey, Sent blue,
   Viewed purple, Signed green, Declined red, Expired grey, Void
   struck — plus the script face used for typed signatures. */
.badge.es-draft{background:#eef1f4;color:#344054}
.badge.es-sent{background:#eef4ff;color:var(--accent-dark)}
.badge.es-viewed{background:#f4f0ff;color:#6941c6}
.badge.es-signed{background:var(--ok-bg);color:var(--ok)}
.badge.es-declined{background:var(--danger-bg);color:var(--danger)}
.badge.es-expired{background:#eef1f4;color:var(--muted)}
.badge.es-void{background:#eef1f4;color:var(--muted);text-decoration:line-through}
.sig-script{font-family:'Segoe Script','Brush Script MT','Lucida Handwriting',cursive}
.dir-tabs{display:flex;gap:8px;margin:0 0 12px}
.dir-tabs button.active{background:var(--accent);color:#fff;border-color:var(--accent)}
.over-budget{color:var(--danger);font-weight:700}

/* Documents (mos23): the vault reuses the .attach-row shape; these are
   the extras — a kind-icon box for non-image files, the Unallocated
   bucket's accent edge, the inline move panel, and the merged
   one-card Timeline's add-form divider on the contact page. */
.doc-icon{width:56px;height:56px;flex:none;display:flex;align-items:center;
  justify-content:center;border:1px solid var(--line);border-radius:6px;
  background:#eef1f4;color:#344054;font-size:11px;font-weight:700;
  text-transform:uppercase;text-decoration:none}
.card.unallocated{border-left:4px solid #f79009}
.doc-move{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:6px}
.timeline-add{border-top:1px solid var(--line);margin-top:12px;padding-top:12px}

/* Team inbox (mos32): the Conversations tab as a 3-pane inbox —
   list | thread | contact details. Desktop-first; the details pane
   drops below the thread on medium screens and everything stacks on
   narrow ones. Panes keep the house .card chrome; message bubbles and
   channel badges are the mos6 ones above. */
.wrap-wide{max-width:1440px}
.inbox3{display:grid;grid-template-columns:330px minmax(0,1fr) 320px;gap:14px;align-items:start}
@media (max-width:1120px){
  .inbox3{grid-template-columns:300px minmax(0,1fr)}
  .col-details{grid-column:1/-1}
}
@media (max-width:760px){
  .inbox3{grid-template-columns:minmax(0,1fr)}
  .col-details{grid-column:auto}
}
.col-list{padding:0;overflow:hidden}
.inbox-title{font-size:16px;font-weight:700;padding:12px 14px 8px}
.inbox-tabs{display:flex;gap:2px;padding:0 8px;border-bottom:1px solid var(--line)}
.inbox-tab{background:transparent;color:var(--muted);border:none;border-radius:7px 7px 0 0;
  padding:7px 10px;font-size:13.5px;font-weight:600;cursor:pointer;display:inline-flex;
  align-items:center;gap:6px}
.inbox-tab:hover{background:#f2f4f7;color:var(--ink)}
.inbox-tab.active{color:var(--accent-dark);box-shadow:inset 0 -2px 0 var(--accent)}
.tab-cnt{background:var(--danger);color:#fff;border-radius:999px;font-size:11px;font-weight:700;
  min-width:19px;height:19px;line-height:19px;text-align:center;padding:0 5px}
.inbox-search{padding:10px 12px;border-bottom:1px solid var(--line)}
.inbox-search input{margin:0}
.trows{max-height:56vh;overflow-y:auto}
@media (max-width:760px){ .trows{max-height:none} }
.trow2{display:flex;gap:10px;width:100%;text-align:left;background:transparent;color:var(--ink);
  border:none;border-bottom:1px solid var(--line);padding:10px 12px;border-radius:0;cursor:pointer;
  font-size:14px;align-items:flex-start}
.trow2:hover{background:#f2f4f7}
.trow2.selected{background:#eef4ff}
.trow2 .t-main{flex:1;min-width:0}
.trow2 .t-head{display:flex;align-items:baseline;gap:8px}
.trow2 .t-name{font-weight:600;font-size:14.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.trow2.unread .t-name{font-weight:700}
.trow2 .t-time{margin-left:auto;color:var(--muted);font-size:12px;white-space:nowrap;flex-shrink:0}
.trow2 .t-prev{display:block;color:var(--muted);font-size:13px;margin-top:2px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.trow2.unread .t-prev{color:var(--ink)}
.trow2 .t-side{display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex-shrink:0}
.avatar{width:38px;height:38px;border-radius:50%;background:#eef4ff;color:var(--accent-dark);
  font-weight:700;font-size:14px;display:flex;align-items:center;justify-content:center;
  position:relative;flex-shrink:0}
.avatar .chan{position:absolute;right:-4px;bottom:-4px;width:18px;height:18px;border-radius:50%;
  background:#fff;border:1px solid var(--line);font-size:10px;line-height:1;display:flex;
  align-items:center;justify-content:center}
.avatar.lg{width:52px;height:52px;font-size:19px}
.unread-badge{background:var(--danger);color:#fff;border-radius:999px;font-size:11px;font-weight:700;
  min-width:19px;height:19px;line-height:19px;text-align:center;padding:0 5px}
.star-btn{background:transparent;border:none;color:#98a2b3;font-size:17px;line-height:1;
  padding:1px 3px;cursor:pointer;border-radius:5px}
.star-btn:hover{background:#eef1f4;color:#f79009}
.star-btn.on{color:#f79009}
.trash-btn{background:transparent;border:none;color:#98a2b3;font-size:14px;line-height:1;
  padding:1px 3px;cursor:pointer;border-radius:5px}
.trash-btn:hover{background:#fef3f2;color:var(--danger)}
.fail-dot{color:var(--danger);font-size:12px;margin-left:6px}
.retry-link{background:none;border:none;padding:0;margin-left:6px;color:inherit;
  text-decoration:underline;cursor:pointer;font-size:12px;font-weight:600}
.col-thread{display:flex;flex-direction:column;padding:0;overflow:hidden}
.thread-head{display:flex;gap:11px;align-items:center;padding:12px 16px;border-bottom:1px solid var(--line)}
.thread-head .th-name{font-weight:700;font-size:16px}
.thread-head .th-sub{color:var(--muted);font-size:13px}
.thread-subject{padding:8px 16px 0;font-weight:600}
.col-thread .msg-flow{padding:14px 16px;overflow-y:auto;max-height:52vh;margin-bottom:0}
@media (max-width:760px){ .col-thread .msg-flow{max-height:none} }
.day-pill{align-self:center;background:#eef1f4;color:var(--muted);border-radius:999px;
  padding:2px 12px;font-size:12px;font-weight:600;margin:6px 0 2px}
.composer{border-top:1px solid var(--line);padding:10px 16px 12px;background:#fbfcfe}
.composer .form-grid{grid-template-columns:170px 1fr}
/* Unified contact stream (mos34): one chronological stream per contact
   across every channel, one send box, logging only for conversations
   that happened outside the system. */
.inbox-title{display:flex;align-items:center}
.msg.logline{align-self:center;background:transparent;color:var(--muted);font-size:12.5px;
  max-width:92%;text-align:center;padding:2px 10px}
.msg.logline .m-meta{display:inline;margin:0 0 0 6px}
.msg.flash{outline:2px solid var(--accent);outline-offset:2px}
.composer-box{border-top:1px solid var(--line);padding:10px 16px 12px;background:#fbfcfe}
.composer-top{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;margin-bottom:8px}
.composer-top label{margin-bottom:4px}
.composer-actions{display:flex;gap:10px;align-items:center;margin-top:8px}
.logbox{border-top:1px dashed var(--line);margin-top:10px;padding-top:10px}
.logbox .form-grid{grid-template-columns:1fr 1fr}
.col-details{padding:14px 16px}
.cd-head{display:flex;gap:11px;align-items:center;margin-bottom:6px}
.cd-head .cd-name{font-size:17px;font-weight:700;line-height:1.25}
.cd-head .cd-ent{color:var(--muted);font-size:13px}
.cd-fields{font-size:13.5px}
.cd-fields th{width:82px;text-transform:none;letter-spacing:0;font-size:12.5px;padding:6px 6px 6px 0}
.cd-fields td{padding:6px 0}
.cd-sec{margin-top:14px}
.cd-sec h3{font-size:12.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);
  margin:0 0 6px}
.cd-sec ul{list-style:none;margin:0;padding:0;font-size:13.5px}
.cd-sec li{padding:3px 0;border-bottom:1px solid var(--line)}
.cd-sec li:last-child{border-bottom:0}
.cd-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}

/* Contact page (mos36): GHL-style three panes — details | stream |
   quick panels. Fixed panes on desktop, each scrolling internally so
   the page itself barely scrolls; everything about the contact is one
   click from the center. Stacks vertically on narrow screens. */
.contact3{display:grid;grid-template-columns:350px minmax(0,1fr) 330px;gap:14px;
  align-items:stretch;height:calc(100vh - 126px)}
.contact3 .cpane{overflow-y:auto;min-height:0;min-width:0}
.contact3 .cpane-left{padding-right:2px}
.contact3 .cpane-left h1{margin-top:0}
.contact3 .cpane-mid{display:flex;flex-direction:column;margin-bottom:0}
.contact3 .cpane-mid .msg-flow{flex:1;max-height:none;margin-bottom:0}
.contact3 .cpane-right .card{margin-bottom:0}
@media (max-width:1120px){
  .contact3{grid-template-columns:300px minmax(0,1fr);height:auto}
  .contact3 .cpane{overflow:visible}
  .contact3 .cpane-right{grid-column:1/-1}
  .contact3 .cpane-mid .msg-flow{flex:none;max-height:52vh}
}
@media (max-width:760px){
  .contact3{grid-template-columns:minmax(0,1fr)}
  .contact3 .cpane-mid .msg-flow{max-height:none}
}
/* Quick panels: the button stack is always in reach; one panel open
   at a time beneath it. Counts ride on the buttons themselves. */
.qp-buttons{display:flex;flex-direction:column;gap:6px;margin-bottom:4px}
.qp-btn{display:flex;justify-content:space-between;align-items:center;width:100%;
  background:#fff;color:var(--ink);border:1px solid var(--line);border-radius:7px;
  padding:8px 12px;font-size:14px;font-weight:600;text-align:left;cursor:pointer}
.qp-btn:hover{background:#f2f4f7}
.qp-btn.active{background:#eef4ff;border-color:var(--accent);color:var(--accent-dark)}
.qp-cnt{background:#eef1f4;color:#344054;border-radius:999px;padding:0 8px;
  font-size:12px;font-weight:700;line-height:19px;min-width:19px;text-align:center}
.qp-btn.active .qp-cnt{background:#fff}
.qp-panel{border-top:1px solid var(--line);margin-top:10px;padding-top:10px}
.qp-panel h2{margin-top:0}

/* mos37: dashboard widget boxes — the dashboard's same data in a
   compact grid of titled boxes (GHL-style) instead of full-width
   stacked cards. Stat tiles shrink; boxes size to their content. */
.dw-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));
  gap:10px;margin-bottom:12px}
.dw-stats .kpi{padding:9px 11px}
.dw-stats .kpi .num{font-size:21px}
.dw-stats .kpi .lbl{font-size:12px;margin-top:1px}
.dw-grid{display:grid;grid-template-columns:1fr;gap:12px;align-items:start}
@media (min-width:960px){.dw-grid{grid-template-columns:1fr 1fr}
  .dw-span2{grid-column:1/-1}}
.dw-stack{display:flex;flex-direction:column;gap:12px}
.dw-box{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:13px 15px}
.dw-title{font-size:15px;margin:0 0 9px}
.dw-title a{color:inherit}
.dw-title a:hover{color:var(--accent);text-decoration:underline}
.dw-box .empty{padding:2px 0}
.dw-box table{width:100%}
.dw-pipe{margin-bottom:13px}
.dw-pipe:last-child{margin-bottom:0}
.dw-pipe-head{display:flex;align-items:baseline;gap:7px;
  border-bottom:1px solid var(--line);padding-bottom:4px;margin-bottom:6px}
.dw-pipe-name{font-weight:700}
.dw-pipe-total{margin-left:auto;font-weight:600;font-size:13px;white-space:nowrap}
.dw-stage{margin:5px 0}
.dw-srow{display:flex;justify-content:space-between;gap:10px;font-size:13px}
.dw-sval{color:var(--muted);white-space:nowrap}
.dw-bar{height:6px;background:#eef1f4;border-radius:3px;overflow:hidden;margin-top:3px}
.dw-bar i{display:block;height:100%;background:var(--accent)}
.dw-fin-lbl{color:var(--muted);font-size:12.5px}
.dw-fin-num{font-size:23px;font-weight:700;line-height:1.15}

/* mos37b — primary-button contrast (Jacob, 2026-10-24): blue buttons carry
   white text, guaranteed. Element-level on purpose: every light-background
   button variant (.secondary, .deal .moves, .view-switch, .trash-btn…)
   overrides this with its own more specific rule. */
button{color:#fff}

/* mos38 — Reports Center: GHL-style category tabs on top, a saved-
   report gallery, computed insight cards, and the honest "not
   connected" ads panels. Appended only; the banner rule (#msg, #dMsg)
   and the mos37b button reinforcement above are untouched. */
.rt-tabs{display:flex;gap:6px;flex-wrap:wrap;border-bottom:2px solid var(--line);
  padding-bottom:0;margin:14px 0 16px}
.rt-tab{background:#fff;color:var(--ink);border:1px solid var(--line);
  border-bottom:none;border-radius:8px 8px 0 0;padding:8px 14px;font-weight:600}
.rt-tab:hover{background:#f2f4f7}
.rt-tab.active{background:var(--accent);color:#fff;border-color:var(--accent)}
.rt-panel h2:first-child{margin-top:4px}
.rt-range{font-size:13px;font-weight:600;color:var(--muted)}
.rt-range select{margin-left:6px}
.rt-insights{display:grid;grid-template-columns:1fr;gap:12px;margin-bottom:8px}
@media (min-width:820px){.rt-insights{grid-template-columns:1fr 1fr}}
.rt-insight{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:12px 15px}
.rt-ins-t{font-size:13px;font-weight:700;text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted)}
.rt-ins-h{font-size:23px;font-weight:700;line-height:1.2;margin:3px 0}
.rt-ins-d{font-size:13.5px}
.rt-ins-b{font-size:12px;color:var(--muted);margin-top:5px}
.rt-form{display:grid;grid-template-columns:1fr;gap:4px 14px}
@media (min-width:820px){.rt-form{grid-template-columns:1fr 1fr}}
.rt-checks{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:4px}
.rt-check{font-weight:400;color:var(--ink);margin:0;display:inline-flex;
  align-items:center;gap:5px}
.rt-grid{display:grid;grid-template-columns:1fr;gap:12px}
@media (min-width:820px){.rt-grid{grid-template-columns:1fr 1fr}}
.rt-card{margin:0}
.rt-card-extra{margin-top:10px}
.rt-card-extra:empty{display:none}
.rt-notconn{border:2px dashed var(--line);border-radius:10px;padding:22px;
  text-align:center;color:var(--muted);background:#fafbfc}
.rt-notconn h3{color:var(--ink);margin-top:0}

/* mos39 — Internal comments + composer attachments. The internal
   block is a tinted staff-only note inside the stream (never a
   bubble: it went nowhere); Internal composer mode tints the whole
   composer box to match, so the mode is unmistakable; staged files
   ride as chips above the actions row. Appended only — the banner
   rule (#msg, #dMsg) and the mos37b button rule above are untouched. */
.msg.internal{align-self:stretch;max-width:96%;background:var(--warn-bg);
  color:var(--ink);border:1px dashed var(--warn);border-radius:10px;
  font-size:13.5px}
.msg.internal .m-meta{color:var(--warn)}
.m-inttag{display:inline-block;font-weight:700;font-size:11px;
  text-transform:uppercase;letter-spacing:.04em;color:var(--warn);
  margin-right:6px}
.m-atts{display:block;margin-top:6px}
.m-att{display:inline-block;margin-right:10px;font-weight:600}
.m-att-note{display:block;color:var(--muted);font-size:11px;margin-top:2px}
.msg.out .m-att{color:#fff}
.msg.out .m-att-note{color:#cfdefc}
.composer-box.internal-mode{background:var(--warn-bg)}
.att-chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.att-chip{display:inline-flex;align-items:center;gap:6px;background:#eef1f4;
  border:1px solid var(--line);border-radius:999px;padding:3px 6px 3px 10px;
  font-size:12.5px}
.att-chip button{background:transparent;color:var(--muted);border:none;
  padding:0 4px;font-size:12px;cursor:pointer}
.att-chip button:hover{color:var(--danger)}

/* mos41 — collapsible boxes (contact left pane + dashboard widgets).
   One reusable pattern: [data-collapse] box, [data-collapse-head]
   header row, [data-collapse-body] content; MOS.initCollapsibles
   (app.js) injects the chevron and toggles .is-collapsed. The head
   becomes a flex row so the chevron sits at the right end; a head
   that is itself a link keeps navigating — only the button toggles.
   Appended only — the banner rule (#msg, #dMsg) and the mos37b
   button rule above are untouched. */
[data-collapse-head]{display:flex;align-items:center;gap:8px}
.collapsible-chev{margin-left:auto;flex:none;background:transparent;
  color:var(--muted);border:1px solid var(--line);border-radius:6px;
  padding:1px 9px;font-size:13px;line-height:1.55;cursor:pointer}
.collapsible-chev:hover{color:var(--ink);background:#f2f4f7}
[data-collapse].is-collapsed [data-collapse-body]{display:none}
.dw-box.is-collapsed .dw-title{margin-bottom:0}

/* mos42 — Activity feed (contact page): filter chips above the one
   unified timeline + a tinted row for internal comments (visible
   only to users with the internal capability — the server filters
   everyone else). Appended only; the banner rule (#msg, #dMsg) and
   the mos37b button rule above are untouched. */
.feed-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.feed-chip{background:#fff;color:var(--ink);border:1px solid var(--line);
  border-radius:999px;padding:2px 11px;font-size:12.5px;font-weight:600;
  cursor:pointer}
.feed-chip:hover{background:#f2f4f7}
.feed-chip.active{background:#eef4ff;border-color:var(--accent);
  color:var(--accent-dark)}
.timeline li.is-internal{background:#fff8e1;border-left-color:#d97706;
  padding-right:8px;border-radius:0 6px 6px 0}

/* mos50 — "Bring email into the CRM" card (Conversations + Intake
   review): the forwarding address in a readonly input (always
   selectable by hand — the manual fallback), a Copy button, and
   entity chips that swap the tagged address. Chips mirror the mos42
   feed-chip styling. Appended only; the banner rule (#msg, #dMsg)
   and the mos37b button rule above are untouched. */
.intake-card-head{font-weight:700;margin-bottom:8px}
.intake-row{display:flex;flex-wrap:wrap;gap:8px}
.intake-addr{flex:1 1 260px;width:auto;font-size:14.5px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.intake-copy{white-space:nowrap}
.intake-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.intake-chip{background:#fff;color:var(--ink);border:1px solid var(--line);
  border-radius:999px;padding:2px 11px;font-size:12.5px;font-weight:600;
  cursor:pointer}
.intake-chip:hover{background:#f2f4f7}
.intake-chip.active{background:#eef4ff;border-color:var(--accent);
  color:var(--accent-dark)}
.intake-help{margin:10px 0 0}
.intake-help p{margin:0 0 4px}
.intake-help p:last-child{margin-bottom:0}

/* mos44 — mobile containment pass (Jacob, 2026-10-24, iPhone): the
   page body never scrolls sideways at phone width. Wide tables become
   their own sideways scrollers (the Pipelines .columns pattern),
   grids get minmax(0,…) tracks so wide content can't stretch them,
   and the topbar keeps its dark band full-width with the nav
   scrolling inside itself. Table containment engages at ≤1150px,
   the rest at ≤900px — desktop layout
   is untouched. Appended only; the banner rule (#msg, #dMsg) and the
   mos37b button rule above are untouched. */
@media (max-width:1150px){
  html,body{overflow-x:clip}
  /* every table scrolls inside its own box instead of stretching
     the page; columns stay reachable by swiping the table */
  table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;
    max-width:100%}
}
@media (max-width:900px){
  /* grid tracks that wide content must not stretch */
  .dw-grid{grid-template-columns:minmax(0,1fr)}
  .dw-box{min-width:0}
  .rt-grid,.rt-insights{grid-template-columns:minmax(0,1fr)}
  .inbox{grid-template-columns:minmax(0,1fr)}
  .inbox3>*{min-width:0}
  /* topbar: brand + nav on one row, the nav scrolls within itself;
     workspace switch / user / log out wrap beneath, band stays dark
     and full-width */
  .topbar{padding:8px 10px;gap:6px 8px}
  .topbar nav{flex-wrap:nowrap;overflow-x:auto;min-width:0;max-width:100%;
    scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .topbar nav::-webkit-scrollbar{display:none}
  .topbar nav a{white-space:nowrap;flex:none}
  .topbar select{max-width:46vw}
  .topbar .user{max-width:40vw;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
}
@media (min-width:821px) and (max-width:900px){
  /* keep the mos38 two-column reports grids in the tablet band,
     just with tracks that can't be stretched */
  .rt-grid,.rt-insights{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
@media (max-width:420px){
  .login-box{margin-left:12px;margin-right:12px}
}

/* mos45 — Automations: draft bubbles read as what they are (written
   by a recipe, NOT sent): dashed amber outline, the out-bubble blue
   softened; the Draft line and its Send button sit under the text.
   Rule rows on the Automations tab are separated inside one card. */
.msg.out.draft{background:#fdf6e0;color:#4a3d08;border:1.5px dashed var(--warn,#b8860b)}
.msg.out.draft .m-meta{color:#8a6d1a}
.msg .m-delivery.draft{color:var(--warn,#b8860b);font-weight:600}
.msg.out.draft .m-delivery.draft{color:#8a6d1a}
.auto-rule{padding:12px 0;border-bottom:1px solid var(--line)}
.auto-rule:first-child{padding-top:0}
.auto-rule:last-child{border-bottom:none;padding-bottom:0}
