/* ═════════════════════════════════════════════════════════════════════════════
   js/comms-dock.css — WIP-UI-COMMS-HUB-01 (mockup-exact)
   Global Comms Dock — fixed bottom-right bubbles + inbox panel + SMS thread.

   Classes match `spartancommshubredesign_1.html` verbatim where they don't
   collide with the global CSS namespace. The dock container scopes all child
   selectors so `.bubble`, `.timer`, `.msg` etc. only apply inside the dock.

   prefers-reduced-motion: reduce gates the four pulse animations.
   ═════════════════════════════════════════════════════════════════════════════ */

/* ── Tokens local to the dock (mirror spartan-tokens.css with fallbacks) ── */
/* .sc-panel is included so the Team-chat sheet's deck-style header (.sc-h-deck)
   resolves the same --cdh-* tokens as the comms deck. */
.comms-dock,
.thread-panel,
.inbox-panel,
.sc-panel {
  --cdh-red: #a16207;
  --cdh-red-dark: #854d0e;
  /* A MISSED CALL IS NOT THE BRAND. It read red only because --cdh-red used to
     be #C41230; the dark theme has always hard-coded its own #F87171, so after
     the rebrand the same state was yellow in one theme and red in the other. */
  --cdh-missed: #DC2626;
  --cdh-pale-red: #fefce8;
  --cdh-ink: #0A0A0A;
  --cdh-s50: #FAFAF9;
  --cdh-s100: #F5F5F4;
  --cdh-s200: #E7E5E4;
  --cdh-s300: #D6D3D1;
  --cdh-s400: #A8A29E;
  --cdh-s500: #78716C;
  --cdh-s600: #57534E;
  --cdh-s700: #44403C;
  --cdh-s900: #1C1917;
  --cdh-q-hot: #15803D;
  --cdh-q-warm: #D97706;
  --cdh-info-bg: #DBEAFE;
  --cdh-info-fg: #1D4ED8;
  --cdh-shadow-bubble: 0 8px 24px -4px rgba(10,10,10,.28), 0 2px 6px rgba(10,10,10,.08);
  --cdh-shadow-bubble-hover: 0 12px 32px -4px rgba(10,10,10,.38), 0 3px 8px rgba(10,10,10,.12);
  --cdh-shadow-panel: 0 24px 60px -12px rgba(10,10,10,.35), 0 6px 16px rgba(10,10,10,.12);
  --cdh-shadow-rest: 0 1px 2px rgba(10,10,10,.03), 0 1px 1px rgba(10,10,10,.02);
  --cdh-ease: cubic-bezier(.4,0,.2,1);
  --cdh-t: 180ms var(--cdh-ease);
}

/* ── Pulse keyframes (mockup-exact rgba + ring radii) ─────────────────── */
@keyframes cdh-pulse-call   { 0%, 100% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 0  rgba(250,204,21,.5); }  70% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 16px rgba(250,204,21,0); } }
@keyframes cdh-pulse-unread { 0%, 100% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 0  rgba(21,128,61,.5); }  70% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 14px rgba(21,128,61,0); } }
@keyframes cdh-pulse-missed { 0%, 100% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 0  rgba(220,38,38,.45); } 70% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 14px rgba(220,38,38,0); } }
@keyframes cdh-pulse-badge  { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }
@keyframes cdh-fade-in-up   { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .comms-dock .bubble-call,
  .comms-dock .bubble-inbox.has-unread,
  .comms-dock .bubble-inbox.has-missed,
  .comms-dock .bubble-badge {
    animation: none !important;
  }
  .thread-panel, .inbox-panel { animation: none !important; }
}

/* ── Dock container ───────────────────────────────────────────────────── */
.comms-dock {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  z-index: 60;
  align-items: flex-end;
  font-family: var(--ff-sans, 'Archivo', system-ui, sans-serif);
}

/* ── Bubble base + variants ───────────────────────────────────────────── */
.comms-dock .bubble {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  transition: all var(--cdh-t);
  box-shadow: var(--cdh-shadow-bubble);
  border: none;
  color: #fff;
  padding: 0;
  font-family: inherit;
}
.comms-dock .bubble:hover {
  transform: translateY(-2px) scale(1.04);
  box-shadow: var(--cdh-shadow-bubble-hover);
}
.comms-dock .bubble .ico {
  width: 22px;
  height: 22px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.comms-dock .bubble-inbox { background: var(--cdh-ink); }
.comms-dock .bubble-inbox:hover { background: var(--cdh-s900); }
.comms-dock .bubble-inbox.has-unread { animation: cdh-pulse-unread 1.8s infinite; }
.comms-dock .bubble-inbox.has-missed { animation: cdh-pulse-missed 1.8s infinite; }
/* When both: missed (red) wins visually */
.comms-dock .bubble-inbox.has-unread.has-missed { animation: cdh-pulse-missed 1.8s infinite; }

/* Phone bubble — dark ink background, red pulse ring when missed. */
.comms-dock .bubble-phone { background: var(--cdh-ink); }
.comms-dock .bubble-phone:hover { background: var(--cdh-s900); }
.comms-dock .bubble-phone.has-missed { animation: cdh-pulse-missed 1.8s infinite; }
.comms-dock .bubble-phone .bubble-badge { background: var(--cdh-red); }

/* Messages bubble — dark ink background, green pulse ring when unread.
   The mockup screenshot shows this as a black bubble with a green badge
   below the active-call bubble. */
.comms-dock .bubble-messages { background: var(--cdh-ink); }
.comms-dock .bubble-messages:hover { background: var(--cdh-s900); }
.comms-dock .bubble-messages.has-unread { animation: cdh-pulse-unread 1.8s infinite; }
.comms-dock .bubble-messages .bubble-badge { background: var(--cdh-q-hot); }

/* Email bubble — per-user inbox; pulses blue when unread.
   Same ink background + hover treatment as phone + messages so the three
   bubbles stack visually consistent. Blue accent because it sits
   alongside the red (phone) + green (messages) family already in use.
   Active state (.active = aria-current="page") draws a thin blue ring
   so the rep can tell at a glance they're already on the email page.
   Focus-visible adds the same ring for keyboard nav.
   WIP-V2.1-PAGES-POLISH-02. */
@keyframes cdh-pulse-email { 0%, 100% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 0 rgba(29,78,216,.5); } 70% { box-shadow: var(--cdh-shadow-bubble), 0 0 0 14px rgba(29,78,216,0); } }
.comms-dock .bubble-email { background: var(--cdh-ink); }
.comms-dock .bubble-email:hover { background: var(--cdh-s900); }
.comms-dock .bubble-email.has-unread-email { animation: cdh-pulse-email 1.8s infinite; }
.comms-dock .bubble-email.active {
  box-shadow: var(--cdh-shadow-bubble), 0 0 0 2px var(--cdh-info-fg);
}
.comms-dock .bubble-email:focus-visible {
  outline: none;
  box-shadow: var(--cdh-shadow-bubble), 0 0 0 3px rgba(29,78,216,.5);
}
.comms-dock .bubble-email .bubble-badge { background: var(--cdh-info-fg); }
.comms-dock .bubble-badge.blue { background: var(--cdh-info-fg); }

@media (prefers-reduced-motion: reduce) {
  .comms-dock .bubble-phone.has-missed,
  .comms-dock .bubble-messages.has-unread,
  .comms-dock .bubble-email.has-unread-email {
    animation: none !important;
  }
}

.comms-dock .bubble-call {
  background: var(--cdh-red);
  animation: cdh-pulse-call 1.4s infinite;
}
.comms-dock .bubble-call:hover { background: var(--cdh-red-dark); }
.comms-dock .bubble-call .timer {
  position: absolute;
  top: -26px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--cdh-ink);
  color: #fff;
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.02em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 4px 12px -2px rgba(10,10,10,.3);
}
.comms-dock .bubble-call .timer::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -3px;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid var(--cdh-ink);
  transform: translateX(-50%);
}

.comms-dock .bubble-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 22px;
  height: 22px;
  border-radius: 11px;
  background: var(--cdh-red);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  border: 3px solid var(--cdh-s50);
  letter-spacing: -0.005em;
  animation: cdh-pulse-badge 2s ease-in-out infinite;
}
.comms-dock .bubble-badge.green { background: var(--cdh-q-hot); }
.comms-dock .bubble-inbox .bubble-badge { background: var(--cdh-q-hot); }
.comms-dock .bubble-inbox.has-missed .bubble-badge { background: var(--cdh-missed); }

.comms-dock .bubble-tooltip {
  position: absolute;
  right: 64px;
  top: 50%;
  transform: translateY(-50%);
  background: var(--cdh-ink);
  color: #fff;
  padding: 5px 10px;
  border-radius: 7px;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  box-shadow: 0 4px 12px -2px rgba(10,10,10,.3);
  pointer-events: none;
  opacity: 0;
  transition: all var(--cdh-t);
}
.comms-dock .bubble:hover .bubble-tooltip { opacity: 1; right: 70px; }
.comms-dock .bubble-tooltip::after {
  content: '';
  position: absolute;
  right: -4px;
  top: 50%;
  width: 0;
  height: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 4px solid var(--cdh-ink);
  transform: translateY(-50%);
}

/* ── Identity chip ────────────────────────────────────────────────────── */
.comms-dock .dock-identity {
  background: #fff;
  border: 1px solid var(--cdh-s200);
  border-radius: 14px;
  padding: 8px 12px 8px 8px;
  display: flex;
  align-items: center;
  gap: 9px;
  box-shadow: var(--cdh-shadow-bubble);
  margin-top: 4px;
  cursor: pointer;
  transition: all var(--cdh-t);
  font-family: inherit;
  color: var(--cdh-ink);
}
.comms-dock .dock-identity:hover {
  border-color: var(--cdh-ink);
  transform: translateY(-1px);
  box-shadow: var(--cdh-shadow-bubble-hover);
}
.comms-dock .dock-id-av {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--cdh-red);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  letter-spacing: -0.005em;
}
.comms-dock .dock-id-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  align-items: flex-start;
}
.comms-dock .dock-id-name {
  font-size: 11.5px;
  font-weight: 800;
  color: var(--cdh-ink);
  letter-spacing: -0.005em;
  line-height: 1.1;
}
.comms-dock .dock-id-num {
  font-size: 10px;
  font-weight: 700;
  color: var(--cdh-s500);
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}
.comms-dock .dock-id-num.warn { color: var(--cdh-red); }

/* ── Inbox panel (rendered when dock open) ────────────────────────────── */
.inbox-panel {
  position: fixed;
  bottom: 24px;
  right: 96px;
  width: 400px;
  height: 580px;
  background: #fff;
  border: 1px solid var(--cdh-s200);
  border-radius: 18px;
  box-shadow: var(--cdh-shadow-panel);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 61;
  animation: cdh-fade-in-up .22s var(--cdh-ease);
  font-family: var(--ff-sans, 'Archivo', system-ui, sans-serif);
}
.inbox-panel .ip-h {
  padding: 14px 16px;
  border-bottom: 1px solid var(--cdh-s100);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: #fff;
}
.inbox-panel .ip-h-l { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.inbox-panel .ip-h-l .ico { color: var(--cdh-s500); width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.inbox-panel .ip-title { font-size: 14px; font-weight: 800; color: var(--cdh-ink); letter-spacing: -0.015em; }
.inbox-panel .ip-title b { color: var(--cdh-red); font-weight: 800; }
.inbox-panel .ip-close {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: none;
  border: 1px solid var(--cdh-s200);
  color: var(--cdh-s500);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  transition: all var(--cdh-t);
}
.inbox-panel .ip-close:hover { background: var(--cdh-s100); color: var(--cdh-ink); }

.inbox-panel .ip-tabs {
  display: flex;
  gap: 4px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--cdh-s100);
  background: var(--cdh-s50);
}
.inbox-panel .ip-tab {
  flex: 1;
  padding: 6px 8px;
  background: none;
  border: none;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--cdh-s500);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: all var(--cdh-t);
  font-family: inherit;
}
.inbox-panel .ip-tab:hover { color: var(--cdh-ink); }
.inbox-panel .ip-tab.on {
  background: #fff;
  color: var(--cdh-ink);
  box-shadow: var(--cdh-shadow-rest);
}
.inbox-panel .ip-tab-c {
  font-size: 9px;
  font-weight: 800;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--cdh-s200);
  color: var(--cdh-s700);
}
.inbox-panel .ip-tab.on .ip-tab-c { background: var(--cdh-ink); color: #fff; }

.inbox-panel .ip-body {
  flex: 1;
  min-height: 0;   /* let flex:1 shrink below content height so overflow-y actually scrolls
                      (without this the tall dial keypad overflowed and the panel's
                      overflow:hidden clipped the Call/Text buttons behind the tab bar) */
  overflow-y: auto;
  background: #fff;
}
.inbox-panel .ip-empty {
  padding: 40px 20px;
  text-align: center;
  font-size: 12.5px;
  color: var(--cdh-s500);
  font-weight: 600;
  line-height: 1.5;
}
.inbox-panel .ip-empty-sub {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  color: var(--cdh-s400);
  font-weight: 500;
}

/* Inbox row — clickable, with inline call + text quick-action buttons */
.inbox-panel .ip-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--cdh-s100);
  background: none;
  border-left: none;
  border-right: none;
  border-top: none;
  width: 100%;
  text-align: left;
  font-family: inherit;
  transition: background var(--cdh-t);
  position: relative;
  cursor: pointer;
}
.inbox-panel .ip-row:hover { background: var(--cdh-s50); }
.inbox-panel .ip-row.unread::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--cdh-q-hot);
}
.inbox-panel .ip-row.missed::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--cdh-missed);
}
.inbox-panel .ip-av {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--cdh-s200);
  color: var(--cdh-s700);
  font-size: 12px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  letter-spacing: -0.01em;
}
.inbox-panel .ip-mid { flex: 1; min-width: 0; }
.inbox-panel .ip-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 3px;
}
.inbox-panel .ip-name {
  font-size: 12.5px;
  font-weight: 800;
  color: var(--cdh-ink);
  letter-spacing: -0.005em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 6px;
}
.inbox-panel .ip-name .ico {
  width: 11px;
  height: 11px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  flex-shrink: 0;
}
.inbox-panel .ip-name .missed-ico { color: var(--cdh-missed); }
.inbox-panel .ip-name .sms-ico    { color: var(--cdh-q-hot); }
.inbox-panel .ip-name .vm-ico     { color: var(--cdh-info-fg); }
.inbox-panel .ip-time {
  font-size: 10px;
  color: var(--cdh-s400);
  font-weight: 700;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
/* Read / unread treatment for SMS-history rows. Unread rows get a green wash,
   a bold dark name, a left accent bar (from .ip-row.unread::before) and a NEW
   pill; read rows are dimmed so the contrast reads at a glance. */
.inbox-panel .ip-row.sms-row.unread {
  background: rgba(21, 128, 61, 0.07);
}
.inbox-panel .ip-row.sms-row.unread:hover {
  background: rgba(21, 128, 61, 0.12);
}
.inbox-panel .ip-row.sms-row.unread .ip-name {
  color: var(--cdh-ink);
  font-weight: 800;
}
.inbox-panel .ip-row.sms-row.unread .ip-snippet {
  color: var(--cdh-s700);
  font-weight: 700;
}
.inbox-panel .ip-row.sms-row.read .ip-name { color: var(--cdh-s700); font-weight: 700; }
.inbox-panel .ip-row.sms-row.read .ip-snippet { color: var(--cdh-s400); }
.inbox-panel .ip-new-pill {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--cdh-q-hot);
  color: #fff;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.06em;
  line-height: 1.5;
  vertical-align: middle;
  flex-shrink: 0;
}
.inbox-panel .ip-snippet {
  font-size: 11px;
  color: var(--cdh-s500);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-bottom: 4px;
}
.inbox-panel .ip-snippet b { color: var(--cdh-s700); font-weight: 700; }

/* Per-row quick actions — pulse-out call/text buttons for missed/unread */
.inbox-panel .ip-actions {
  display: flex;
  gap: 6px;
  margin-top: 2px;
}
.inbox-panel .ip-qa {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: 7px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.02em;
  cursor: pointer;
  border: 1px solid var(--cdh-s200);
  background: #fff;
  color: var(--cdh-s700);
  transition: all var(--cdh-t);
  font-family: inherit;
}
.inbox-panel .ip-qa:hover {
  border-color: var(--cdh-ink);
  color: var(--cdh-ink);
  transform: translateY(-1px);
  box-shadow: var(--cdh-shadow-rest);
}
.inbox-panel .ip-qa .ico {
  width: 11px;
  height: 11px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}
.inbox-panel .ip-qa.call-back {
  background: var(--cdh-red);
  color: #fff;
  border-color: var(--cdh-red);
  box-shadow: 0 1px 2px rgba(250,204,21,.2), 0 4px 10px -3px rgba(250,204,21,.4);
}
.inbox-panel .ip-qa.call-back:hover {
  background: var(--cdh-red-dark);
  box-shadow: 0 2px 4px rgba(250,204,21,.3), 0 8px 16px -4px rgba(250,204,21,.5);
}
.inbox-panel .ip-qa.reply-text {
  background: var(--cdh-ink);
  color: #fff;
  border-color: var(--cdh-ink);
  box-shadow: 0 1px 2px rgba(10,10,10,.15), 0 4px 10px -3px rgba(10,10,10,.3);
}
.inbox-panel .ip-qa.reply-text:hover {
  background: var(--cdh-s900);
}

/* ── Thread panel (SMS) ───────────────────────────────────────────────── */
.thread-panel {
  position: fixed;
  bottom: 24px;
  right: 96px;
  width: 400px;
  height: 580px;
  background: #fff;
  border: 1px solid var(--cdh-s200);
  border-radius: 18px;
  box-shadow: var(--cdh-shadow-panel);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 61;
  animation: cdh-fade-in-up .22s var(--cdh-ease);
  font-family: var(--ff-sans, 'Archivo', system-ui, sans-serif);
}
.thread-panel .tp-h {
  padding: 13px 16px;
  background: linear-gradient(135deg, #1A0E12 0%, #0A0A0A 100%);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 11px;
  position: relative;
  overflow: hidden;
}
.thread-panel .tp-h::before {
  content: '';
  position: absolute;
  left: -30%;
  top: -50%;
  width: 60%;
  height: 200%;
  background: radial-gradient(circle, rgba(250,204,21,.25) 0%, transparent 60%);
  pointer-events: none;
}
.thread-panel .tp-back {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: rgba(255,255,255,.08);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: all var(--cdh-t);
  position: relative;
  z-index: 1;
  border: none;
  font-family: inherit;
}
.thread-panel .tp-back:hover { background: rgba(255,255,255,.16); }
.thread-panel .tp-back .ico { width: 14px; height: 14px; stroke: currentColor; stroke-width: 2; fill: none; }
.thread-panel .tp-av {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #7C3AED;
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}
.thread-panel .tp-info { flex: 1; min-width: 0; position: relative; z-index: 1; }
.thread-panel .tp-name {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.2;
  display: flex;
  align-items: center;
  gap: 7px;
}
.thread-panel .tp-name .stage-badge {
  font-size: 8.5px;
  padding: 2px 6px;
  background: var(--cdh-red);
  color: #fff;
  letter-spacing: 0.1em;
  border-radius: 4px;
  text-transform: uppercase;
  font-weight: 800;
}
.thread-panel .tp-phone {
  font-size: 11px;
  color: rgba(255,255,255,.6);
  margin-top: 2px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: center;
  gap: 5px;
}
.thread-panel .tp-phone .status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #22C55E;
}
.thread-panel .tp-actions {
  display: flex;
  align-items: center;
  gap: 5px;
  position: relative;
  z-index: 1;
}
.thread-panel .tp-action {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(255,255,255,.08);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: all var(--cdh-t);
  border: none;
  font-family: inherit;
}
.thread-panel .tp-action:hover { background: rgba(255,255,255,.16); }
.thread-panel .tp-action .ico { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }

.thread-panel .tp-linked {
  padding: 9px 16px;
  background: var(--cdh-s50);
  border-bottom: 1px solid var(--cdh-s100);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 10.5px;
  color: var(--cdh-s600);
  font-weight: 700;
  letter-spacing: 0.01em;
  flex-wrap: wrap;
}
.thread-panel .tp-linked .ico {
  width: 11px;
  height: 11px;
  color: var(--cdh-s400);
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  flex-shrink: 0;
}
.thread-panel .tp-linked b { color: var(--cdh-ink); font-weight: 800; }

/* AUTO-ATTACH pill — small red rectangle next to the linked entity label
   indicating the comm will auto-attach to that stage on save. Matches the
   mockup screenshot Phoenix sent on 2026-05-22. */
.thread-panel .auto-attach-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 6px;
  background: var(--cdh-red);
  color: #fff;
  border-radius: 4px;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-left: 4px;
}

/* JOB / DEAL / LEAD stage badge inside the thread header — small coloured
   rectangle next to the customer name. The colour is set inline by the
   hydrate step so each stage stays distinct (red for JOB, purple for DEAL,
   blue for LEAD). */
.thread-panel .stage-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 6px;
  background: var(--cdh-red);
  color: #fff;
  border-radius: 4px;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-left: 6px;
}

.thread-panel .tp-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background: var(--cdh-s50);
  display: flex;
  flex-direction: column;
  gap: 8px;
  background-image: radial-gradient(circle at 20% 20%, rgba(250,204,21,.02) 0%, transparent 50%),
                    radial-gradient(circle at 80% 80%, rgba(21,128,61,.02) 0%, transparent 50%);
}
.thread-panel .tp-date-divider {
  align-self: center;
  font-size: 10px;
  font-weight: 700;
  color: var(--cdh-s400);
  background: #fff;
  padding: 3px 10px;
  border-radius: 11px;
  border: 1px solid var(--cdh-s200);
  letter-spacing: 0.04em;
  margin: 8px 0 4px;
}
.thread-panel .msg {
  display: flex;
  flex-direction: column;
  max-width: 78%;
  animation: cdh-fade-in-up .2s var(--cdh-ease);
}
.thread-panel .msg.in  { align-self: flex-start; align-items: flex-start; }
.thread-panel .msg.out { align-self: flex-end;   align-items: flex-end;   }
.thread-panel .msg-bubble {
  padding: 8px 12px;
  border-radius: 14px;
  font-size: 12.5px;
  line-height: 1.45;
  font-weight: 500;
  word-wrap: break-word;
  box-shadow: 0 1px 1px rgba(10,10,10,.04);
}
.thread-panel .msg.in .msg-bubble {
  background: #fff;
  color: var(--cdh-ink);
  border: 1px solid var(--cdh-s200);
  border-bottom-left-radius: 5px;
}
.thread-panel .msg.out .msg-bubble {
  background: var(--cdh-red);
  color: #fff;
  border-bottom-right-radius: 5px;
  box-shadow: 0 1px 2px rgba(250,204,21,.2);
}
.thread-panel .msg-meta {
  font-size: 9.5px;
  color: var(--cdh-s400);
  font-weight: 600;
  margin-top: 3px;
  padding: 0 6px;
  display: flex;
  align-items: center;
  gap: 5px;
  letter-spacing: 0.02em;
}
.thread-panel .msg-meta.delivered { color: var(--cdh-info-fg); }
.thread-panel .msg-meta.read      { color: var(--cdh-q-hot); }

.thread-panel .tp-compose {
  padding: 12px 14px;
  border-top: 1px solid var(--cdh-s100);
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.thread-panel .tp-input-row {
  display: flex;
  align-items: flex-end;
  gap: 7px;
}
.thread-panel .tp-input {
  flex: 1;
  padding: 10px 12px;
  background: var(--cdh-s50);
  border: 1px solid var(--cdh-s200);
  border-radius: 11px;
  font-size: 13px;
  line-height: 1.4;
  min-height: 42px;
  color: var(--cdh-ink);
  resize: none;
  transition: all var(--cdh-t);
  font-family: inherit;
}
.thread-panel .tp-input:focus {
  outline: none;
  background: #fff;
  border-color: var(--cdh-ink);
  box-shadow: 0 0 0 3px rgba(10,10,10,.05);
}
.thread-panel .tp-send {
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--cdh-ink);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all var(--cdh-t);
  flex-shrink: 0;
  border: none;
  font-family: inherit;
}
.thread-panel .tp-send:hover {
  background: var(--cdh-red);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -2px rgba(250,204,21,.5);
}
.thread-panel .tp-send .ico { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; }
.thread-panel .tp-send:disabled { opacity: .5; cursor: wait; transform: none; box-shadow: none; }

/* ── A-358 MMS: attach button + preview chips + bubble media ─────────────── */
.thread-panel .tp-attach {
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--cdh-s50);
  color: var(--cdh-s700, #44403C);
  border: 1px solid var(--cdh-s200);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all var(--cdh-t);
  flex-shrink: 0;
  font-family: inherit;
}
.thread-panel .tp-attach:hover { background: #fff; border-color: var(--cdh-ink); color: var(--cdh-ink); transform: translateY(-1px); }
.thread-panel .tp-attach .ico { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; }
.thread-panel.cd-dark .tp-attach { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.14); color: rgba(255,255,255,.75); }
.thread-panel.cd-dark .tp-attach:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.3); color: #fff; }

.thread-panel .tp-attach-chips { display: none; }
.thread-panel .tp-attach-chips.has-chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 2px 0 4px;
}
.thread-panel .tp-attach-chip {
  position: relative;
  width: 58px;
  height: 58px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--cdh-s200);
  background: var(--cdh-s50);
  flex-shrink: 0;
}
.thread-panel.cd-dark .tp-attach-chip { border-color: rgba(255,255,255,.18); background: rgba(255,255,255,.08); }
.thread-panel .tp-attach-chip .tp-chip-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.thread-panel .tp-attach-chip .tp-chip-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 16px; text-shadow: 0 1px 4px rgba(0,0,0,.7); pointer-events: none;
}
.thread-panel .tp-attach-chip .tp-chip-x {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: rgba(0,0,0,.65); color: #fff; border: none;
  font-size: 13px; line-height: 1; display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
}
.thread-panel .tp-attach-chip .tp-chip-x:hover { background: var(--cdh-red, #a16207); }
.thread-panel .tp-attach-chip.uploading .tp-chip-thumb { opacity: .4; }
.thread-panel .tp-attach-chip .tp-chip-spin {
  position: absolute; top: 50%; left: 50%; width: 16px; height: 16px; margin: -8px 0 0 -8px;
  border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; border-radius: 50%;
  animation: tp-chip-spin .7s linear infinite;
}
@keyframes tp-chip-spin { to { transform: rotate(360deg); } }

/* Media inside chat bubbles (in + out, incl. failed) */
.thread-panel .msg-bubble .msg-media-wrap { display: flex; flex-direction: column; gap: 4px; }
.thread-panel .msg-bubble.has-media { padding: 6px; }
.thread-panel .msg-bubble .msg-media {
  display: block;
  max-width: 220px;
  max-height: 260px;
  width: 100%;
  border-radius: 9px;
  object-fit: cover;
  background: rgba(0,0,0,.08);
}
.thread-panel .msg-bubble .msg-media-link { display: block; text-decoration: none; }
.thread-panel .msg-bubble .msg-media-fallback {
  display: inline-block; padding: 8px 10px; border-radius: 8px;
  background: rgba(0,0,0,.08); color: inherit; font-size: 12px; font-weight: 700;
}

/* Telephony provisioning panel — reuses .inbox-panel chrome with a centred
   body of form controls. Mounted when the rep clicks "Set up Twilio number"
   on the identity chip. */
.inbox-panel.telephony-panel { height: auto; max-height: 460px; }
.inbox-panel.telephony-panel select:focus {
  outline: none;
  border-color: var(--cdh-ink) !important;
  box-shadow: 0 0 0 3px rgba(10,10,10,.05);
}
.inbox-panel.telephony-panel code {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10.5px;
  background: var(--cdh-s100);
  padding: 1px 5px;
  border-radius: 4px;
  color: var(--cdh-s700);
}

/* Inbox row aliases — the WIP-UI-COMMS-FIX-01 prompt uses these class names
   for the delegated handler. Aliased onto the existing .ip-* rules so the
   inline onclick + the delegated handler both find the same buttons. */
.inbox-panel .inbox-row { /* alias of .ip-row */ }
.inbox-panel .inbox-row-actions { /* alias of .ip-actions */ }
.inbox-panel .comm-btn {
  /* identical to .ip-qa — already styled above via shared selector */
}

/* Small screens — full-width panels */
@media (max-width: 540px) {
  .inbox-panel, .thread-panel {
    right: 16px;
    bottom: 16px;
    width: calc(100vw - 32px);
  }
}

/* ── Collapse / expand controls ─────────────────────────────────────────────
   The full bubble stack covered invoice totals + form footers, so users can
   hide it. `.comms-dock-mini` is the tiny floating chip shown when collapsed;
   `.comms-dock-collapse` is the small chevron on the expanded dock.
   ─────────────────────────────────────────────────────────────────────────── */

.comms-dock-mini {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  background: #1a1a1a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18), 0 2px 4px rgba(0,0,0,0.12);
  z-index: 60;
  padding: 0;
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
  font-family: inherit;
  /* Draggable: stop the browser from panning/scrolling or selecting while the
     chip is being dragged (see _initMiniDrag in comms-dock.js). */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
.comms-dock-mini:hover {
  transform: translateY(-1px) scale(1.05);
  box-shadow: 0 6px 16px rgba(0,0,0,0.22), 0 2px 6px rgba(0,0,0,0.15);
  background: #facc15; color: #000;
}
.comms-dock-mini .ico { width: 18px; height: 18px; }
.comms-dock-mini.has-activity { background: #facc15; color: #000; }
.comms-dock-mini.has-activity::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid #a16207;
  opacity: 0.6;
  /* A-806 — briefly gated to the boot window, then un-gated at Graham's request
     ("The chat button can pulse thats fine"). It is a live-comms affordance: an
     unread message should keep asking for attention until it is read. */
  animation: comms-dock-mini-pulse 1.6s ease-out infinite;
  pointer-events: none;
}
@keyframes comms-dock-mini-pulse {
  0%   { transform: scale(1);   opacity: 0.6; }
  100% { transform: scale(1.5); opacity: 0;   }
}
.comms-dock-mini-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: #facc15;
  color: #000;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}

/* Chevron handle on the expanded dock — top-right of the .comms-dock aside.
   IMPORTANT: don't re-declare `position` here. The base .comms-dock rule
   above uses `position: fixed` to pin the dock to the viewport's bottom-
   right corner; overriding it back to relative drops the dock into normal
   flow and it lands at the bottom of the document body instead of the
   bottom of the viewport. We only add padding-top here to make room for
   the absolutely-positioned chevron. */
.comms-dock { padding-top: 22px; }
.comms-dock-collapse {
  position: absolute;
  top: -4px;
  right: 4px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: rgba(26,26,26,0.85);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  z-index: 2;
  opacity: 0.7;
  transition: opacity .15s ease, background-color .15s ease, transform .15s ease;
}
.comms-dock-collapse:hover { opacity: 1; background: #facc15; color: #000; transform: scale(1.06); }
.comms-dock-collapse .ico { width: 14px; height: 14px; }

/* ═══════════════════════════════════════════════════════════════════════════
   Phone-page dialpad — matches the Comms dock action language.
   Call pulses RED (the action reps should take first), Text pulses GREEN.
   Self-contained box-shadows (no --cdh-* vars) so the pulse works on the Phone
   page, which isn't inside a .comms-dock container.
   ═══════════════════════════════════════════════════════════════════════════ */
@keyframes spk-pulse-red {
  0%, 100% { box-shadow: 0 1px 2px rgba(250,204,21,.25), 0 6px 16px -4px rgba(250,204,21,.45), 0 0 0 0  rgba(250,204,21,.55); }
  70%      { box-shadow: 0 1px 2px rgba(250,204,21,.25), 0 6px 16px -4px rgba(250,204,21,.45), 0 0 0 13px rgba(250,204,21,0); }
}
@keyframes spk-pulse-green {
  0%, 100% { box-shadow: 0 1px 2px rgba(21,128,61,.25), 0 6px 16px -4px rgba(21,128,61,.45), 0 0 0 0  rgba(21,128,61,.55); }
  70%      { box-shadow: 0 1px 2px rgba(21,128,61,.25), 0 6px 16px -4px rgba(21,128,61,.45), 0 0 0 13px rgba(21,128,61,0); }
}

/* Number display — big, bold, monospace; turns red on focus. */
.spartan-dialpad .spk-num {
  flex: 1;
  font-family: 'SF Mono', ui-monospace, 'Roboto Mono', monospace;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: #0A0A0A;
  padding: 11px 13px;
  border: 2px solid #E7E5E4;
  border-radius: 12px;
  outline: none;
  background: #fff;
  transition: border-color 140ms cubic-bezier(.4,0,.2,1);
}
.spartan-dialpad .spk-num:focus { border-color: #a16207; }
.spartan-dialpad .spk-num::placeholder { color: #D6D3D1; font-weight: 600; letter-spacing: .5px; }

/* Keys — same key treatment as the in-call dialpad (renderCallUIv2): tall
   rounded-rect keys, big numeral, no A-B-C letters. Light-gray fill here (the
   light-surface mirror of the in-call screen's translucent-on-dark keys),
   since the dock sheet stays white. */
.spartan-dialpad .spk-key {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: .01em;
  padding: 16px 0;
  min-height: 64px;
  background: #F5F5F4;
  border: 1px solid #E7E5E4;
  border-radius: 16px;
  color: #1C1917;
  cursor: pointer;
  font-family: inherit;
  user-select: none;
  transition: transform 90ms cubic-bezier(.4,0,.2,1), background 120ms, border-color 120ms, box-shadow 120ms;
}
.spartan-dialpad .spk-key:hover { background: #FAFAF9; border-color: #D6D3D1; }
.spartan-dialpad .spk-key:active {
  transform: scale(.93);
  background: #fefce8;
  border-color: #a16207;
  box-shadow: inset 0 0 0 1.5px rgba(161,98,7,.35);
}

/* Call / Text — pulsing action buttons (red / green). */
.spartan-dialpad .spk-action {
  width: 100%;
  padding: 15px;
  border: none;
  border-radius: 14px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .02em;
  color: #fff;
  cursor: pointer;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  transition: transform 120ms cubic-bezier(.4,0,.2,1), filter 120ms;
}
.spartan-dialpad .spk-action .ico { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; }
.spartan-dialpad .spk-call { background: #facc15; color: #000; animation: spk-pulse-red 1.5s infinite; }
.spartan-dialpad .spk-text { background: #15803D; animation: spk-pulse-green 1.5s infinite; }
.spartan-dialpad .spk-hangup { background: #ef4444; }
.spartan-dialpad .spk-action:hover  { transform: translateY(-1px); filter: brightness(1.05); }
.spartan-dialpad .spk-action:active { transform: translateY(0) scale(.99); }
.cdh-dialpad .cdh-dial-hangup { margin-top: 8px; }

@media (prefers-reduced-motion: reduce) {
  .spartan-dialpad .spk-call,
  .spartan-dialpad .spk-text { animation: none !important; }
  .spartan-dialpad .spk-key  { transition: none !important; }
}

/* In-dock dialpad layout (the 'Dial' tab). Reuses the .spk-* button visuals
   above; this only lays out the input row, key grid, and action row to fit
   the dock panel. */
.cdh-dialpad { padding: 14px 16px 18px; }
.cdh-dialpad .cdh-dial-input-row { display: flex; gap: 6px; align-items: stretch; margin-bottom: 12px; }
.cdh-dialpad .spk-num { flex: 1; min-width: 0; }
.cdh-dialpad .cdh-dial-back {
  padding: 0 14px;
  background: #F5F5F4;
  border: 1px solid #E7E5E4;
  border-radius: 12px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #44403C;
  transition: background 120ms;
}
.cdh-dialpad .cdh-dial-back:hover { background: #E7E5E4; }
.cdh-dialpad .cdh-dial-back .ico { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; }
.cdh-dialpad .cdh-dial-keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.cdh-dialpad .cdh-dial-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

/* Contacts picker inside the Dial tab — call/text straight from the directory. */
.cdh-dialpad .cdh-contacts { margin-top: 16px; border-top: 1px solid #E7E5E4; padding-top: 12px; }
.cdh-dialpad .cdh-contacts-h { font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: #A8A29E; margin-bottom: 8px; }
.cdh-dialpad .cdh-contact-search {
  width: 100%; padding: 9px 12px; border: 1px solid #E7E5E4; border-radius: 10px; font-size: 13px;
  background: #FAFAF9; color: #1C1917; font-family: inherit; margin-bottom: 8px; box-sizing: border-box;
}
.cdh-dialpad .cdh-contact-search:focus { outline: none; border-color: #0A0A0A; background: #fff; box-shadow: 0 0 0 3px rgba(10,10,10,.05); }
.cdh-dialpad .cdh-contact-list { max-height: 200px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.cdh-dialpad .cdh-contact-empty { padding: 16px; text-align: center; font-size: 12px; color: #A8A29E; font-weight: 600; }
.cdh-dialpad .cdh-contact-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 8px; border-radius: 10px; cursor: pointer;
  background: none; border: none; width: 100%; text-align: left; transition: background 140ms;
}
.cdh-dialpad .cdh-contact-row:hover { background: #F5F5F4; }
.cdh-dialpad .cdh-contact-av {
  width: 32px; height: 32px; border-radius: 50%; background: #E7E5E4; color: #44403C; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 800;
}
.cdh-dialpad .cdh-contact-meta { flex: 1; min-width: 0; }
.cdh-dialpad .cdh-contact-name { font-size: 12.5px; font-weight: 700; color: #1C1917; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cdh-dialpad .cdh-contact-num { font-size: 11px; color: #78716C; font-variant-numeric: tabular-nums; }
.cdh-dialpad .cdh-contact-acts { display: inline-flex; gap: 5px; flex-shrink: 0; }
.cdh-dialpad .cdh-cact {
  width: 30px; height: 30px; border-radius: 8px; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center;
  color: #fff; transition: filter 140ms, transform 120ms;
}
.cdh-dialpad .cdh-cact:hover { filter: brightness(1.08); transform: translateY(-1px); }
.cdh-dialpad .cdh-cact.call { background: #facc15; color: #000; }
.cdh-dialpad .cdh-cact.text { background: #15803D; }
.cdh-dialpad .cdh-cact .ico { width: 14px; height: 14px; stroke: currentColor; stroke-width: 2; fill: none; }

/* Header right cluster (minimise + close). Harmless on desktop — wraps the
   existing close button; the close stays right-aligned via .ip-h space-between. */
.ip-h-r { display: inline-flex; align-items: center; gap: 8px; }

/* ════════════════════════════════════════════════════════════════════════
   MOBILE (native sales app only — gated on .cd-mobile, set by comms-dock.js
   via isNativeWrapper()). Mobile mirrors the DESKTOP vertical bubble stack +
   chevron toggle, but the panels go FULL-SCREEN and the bubbles float ON TOP.
   The desktop CRM dock is completely unaffected (it never gets .cd-mobile).
   ════════════════════════════════════════════════════════════════════════ */

/* The floating bubble dock (and the restore mini chip) must sit ABOVE the
   full-screen panel (z-index 61) — unlike desktop where the panel is beside the
   dock. Anchored bottom-right like the web; lifted clear of the home bar. */
.cd-mobile .comms-dock { z-index: 63; bottom: calc(24px + env(safe-area-inset-bottom)); }
.cd-mobile .comms-dock-mini { z-index: 63; bottom: calc(20px + env(safe-area-inset-bottom)); }

/* S-149 (Phoenix audit 2026-07-05): the mobile comms FAB is z-index:63 — above
   the z-[60] modal sheets (keypad, quick-quote, app-lock, etc.). It was drawn
   ON TOP of those sheets, overlapping the keypad backspace, the quick-quote
   colour chips and the App Lock toggle, and intercepting taps meant for them.
   When ANY modal sheet is open, hide the FAB + bubble stack. The modal-backdrop
   and #comms-dock-root(.cd-mobile) are both direct children of <body>, so
   body:has(.modal-backdrop) is the correct ancestor test. */
body:has(.modal-backdrop) .cd-mobile .comms-dock,
body:has(.modal-backdrop) .cd-mobile .comms-dock-mini { display: none !important; }

/* A-264 (Phoenix screenshot 2026-07-15): the floating bubble stack was drawn
   ON TOP of the dialpad sheet, covering the 6/9/# keys. Nothing may ever
   float over a keypad — while the mobile sheet is in Dial mode, hide the
   bubbles entirely (same :has() ancestor-test idiom as S-149 above; covers
   BOTH entry paths — openDialpad() and an in-place tab switch — because it
   keys off the panel's cd-sheet-dial class, not JS state). */
.cd-mobile:has(.inbox-panel.cd-sheet-dial) .comms-dock,
.cd-mobile:has(.inbox-panel.cd-sheet-dial) .comms-dock-mini { display: none !important; }

/* A-679b — the rule above fixed this for the DIAL sheet ONLY, because in A-264
   the dial tab was the only full-screen one. A-679 then made EVERY tab a
   full-screen sheet, and the same bug walked straight back in on All / SMS /
   Calls / Voicemail: measured at 412x915, the restore chip sits at 358,787 with
   z-index 63 against the panel's 61, i.e. drawn ON TOP of the sheet's own list.
   That is Phoenix's "call box is floating", one tab across.

   On a full-screen sheet the chip has no job at all — it exists to restore the
   bubble stack next to a side-docked panel, and there is no page beside a sheet
   that covers the viewport. Hide it on every tab.

   Deliberately NOT `.comms-dock` wholesale: `.cd-call-float` carries the live
   call's controls, and on a non-dial tab it is the rep's ONLY hangup button —
   hiding it would strand someone mid-call who tapped SMS. The dial sheet can
   keep hiding it (rule above) because that sheet renders its own in-call UI. */
.cd-mobile:has(.inbox-panel) .comms-dock-mini,
.cd-mobile:has(.inbox-panel) .comms-dock:not(.cd-call-float) { display: none !important; }

/* A-679b — the header title was ellipsising to "Admin's d…" on a phone.
   Measured at 412px: .ip-title needs 123px and gets 94, because .ip-h-l (180px)
   plus .ip-h-r (188px — theme toggle + "Mark all read" + close) already spend
   368 of the 412 available. The possessive is the part carrying no information:
   on a phone a rep only ever sees their OWN dock, so "Admin's" is 62px spent
   telling them something they know, at the cost of the one word that says which
   tab they are on. Drop it below md and let the suffix render in full. */
.cd-mobile .inbox-panel .ip-title b { display: none; }
.cd-mobile .inbox-panel .ip-title #cdh-ip-suffix { text-transform: capitalize; }

/* Full-screen sheet — fills the ENTIRE viewport, squared corners, floats up.
   (Was an 80vh rounded bottom sheet; full-screen requested to match the web CRM.
   height:100vh is the fallback for webviews without dvh support.) */
.cd-mobile .inbox-panel,
.cd-mobile .thread-panel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-height: 100dvh;
  border-radius: 0;
  z-index: 61;
  animation: cd-sheet-up .26s var(--cdh-ease);
}
@keyframes cd-sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* Anti-flicker: when render() rebuilds an ALREADY-open panel (badge tick /
   realtime / 30s poll), it gets .cd-no-anim so the entrance animation does NOT
   replay — otherwise the open deck visibly slides bottom→top on every refresh.
   Covers both the mobile slide-up and the desktop fade-in; first open animates. */
.cd-mobile .inbox-panel.cd-no-anim,
.cd-mobile .thread-panel.cd-no-anim,
.inbox-panel.cd-no-anim,
.thread-panel.cd-no-anim { animation: none; }

/* Full-screen headers clear the status bar / notch (safe-area top inset). The
   header backgrounds (white .ip-h, dark .tp-h) extend up behind the status bar so
   the close X and profile/back controls sit below the notch. Mobile-only. */
.cd-mobile .ip-h { padding-top: calc(14px + env(safe-area-inset-top)); }
.cd-mobile .tp-h { padding-top: calc(13px + env(safe-area-inset-top)); }

/* Active-call timer floats top-right above the sheet (keeps the live call). */
.cd-mobile .cd-call-float {
  position: fixed;
  top: calc(env(safe-area-inset-top) + 12px);
  right: 12px;
  bottom: auto;
  z-index: 62;
}

/* Profile header (name + mobile number) at the top of the mobile sheet —
   replaces the old "Santosh's inbox" title; tap = telephony settings. */
.cd-mobile .cd-prof-h { gap: 10px; }
.cd-prof {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1;
  background: none;
  border: none;
  padding: 0;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}
.cd-prof-av {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--cdh-ink);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 800;
  flex-shrink: 0;
}
.cd-prof-meta { min-width: 0; }
.cd-prof-name {
  font-size: 15px;
  font-weight: 800;
  color: var(--cdh-ink);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cd-prof-num { font-size: 12px; color: var(--cdh-s500); }
.cd-prof-num.warn { color: var(--cdh-red); font-weight: 700; }

/* Mobile dial keypad — shrink keys/actions so the input + 12 keys + the Call/Text
   action row all fit inside the sheet body above the tab bar (the contacts list
   scrolls below). Previously the 58px keys pushed the action buttons off-screen,
   clipped behind the tab bar (only their tops showed). */
.cd-mobile .cdh-dialpad { padding: 10px 14px 12px; }
.cd-mobile .cdh-dialpad .cdh-dial-input-row { margin-bottom: 9px; }
.cd-mobile .cdh-dialpad .cdh-dial-keys { gap: 7px; margin-bottom: 10px; }
.cd-mobile .spartan-dialpad .spk-key { min-height: 52px; padding: 11px 0; font-size: 22px; border-radius: 16px; }
.cd-mobile .spartan-dialpad .spk-action { min-height: 46px; padding: 12px; font-size: 14px; }
.cd-mobile .cdh-dialpad .cdh-contacts { margin-top: 12px; padding-top: 10px; }

/* Email tab — Connect Gmail prompt when not connected on this device. */
.cd-email-empty-t { font-size: 14px; font-weight: 800; color: var(--cdh-ink); margin-bottom: 6px; }
.cd-connect-gmail {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 14px; padding: 11px 18px;
  background: var(--cdh-red, #a16207); color: #fff;
  border: none; border-radius: 12px;
  font-family: inherit; font-size: 13px; font-weight: 800; cursor: pointer;
  transition: filter 120ms, transform 120ms;
}
.cd-connect-gmail:hover { filter: brightness(1.06); transform: translateY(-1px); }
.cd-connect-gmail:active { transform: translateY(0) scale(.99); }
.cd-connect-gmail .ico { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; pointer-events: none; }

/* Call-history recording player (Calls / VM tabs). */
.cd-call-rec { display: block; width: 100%; height: 34px; margin-top: 6px; }
/* Play button shares the actions row with "Call" — inline, no extra top gap.
   Once playback loads, the slot holds an <audio> player; let it claim the full
   row width on its own line so the controls aren't cramped next to Call. */
.inbox-panel .inbox-row .ip-actions { flex-wrap: wrap; align-items: center; row-gap: 6px; }
.inbox-panel .inbox-row .cd-call-rec-slot { display: inline-flex; align-items: center; }
.inbox-panel .inbox-row .cd-call-rec-slot:has(audio) { flex: 1 1 100%; }
.inbox-panel .inbox-row .cd-call-rec-slot audio { display: block; width: 100%; height: 30px; }
.cd-call-rec-off { margin-top: 6px; }
.cd-call-rec-off {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 5px; font-size: 11px; font-weight: 600; color: var(--cdh-s500);
}
.cd-call-rec-off .ico { width: 13px; height: 13px; stroke: currentColor; stroke-width: 2; fill: none; }

/* Scroll isolation — the sheet's body scrolls; nothing chains to the page.
   Paired with the JS body-pin (html.cd-bg-locked) so the background is frozen
   while the sheet is open, and fully restored on close. */
.cd-mobile .ip-body { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.cd-mobile .inbox-panel,
.cd-mobile .thread-panel { overscroll-behavior: contain; }
html.cd-bg-locked,
html.cd-bg-locked body { overflow: hidden; }

/* ── Auto-hide while a modal / drawer / overlay is open ─────────────────────
   When any .ovl / .panel / .modal-bg / .cw-modal-overlay appears inside #app
   the JS adds comms-dock--overlay-open to #comms-dock-root.  Both the expanded
   dock and the collapsed mini-chip are hidden so they can never block a form
   footer (e.g. the "Create lead" button in the add-lead drawer — S-043).
   pointer-events:none alone is insufficient because the dock still occupies
   visual space and can cover the button; visibility:hidden + opacity:0 removes
   it from view while keeping it in the DOM so no layout side-effects occur.
   ─────────────────────────────────────────────────────────────────────────── */
#comms-dock-root.comms-dock--overlay-open .comms-dock,
#comms-dock-root.comms-dock--overlay-open .comms-dock-mini,
#comms-dock-root.comms-dock--overlay-open .inbox-panel,
#comms-dock-root.comms-dock--overlay-open .thread-panel {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease, visibility 0s 120ms;
}

/* ── Dial tab: white sheet, subtle light-gray number keys ────────────────────
   The Dial tab uses the same white sheet + light header as every other tab. The
   keys mirror the in-call dialpad design (renderCallUIv2) — tall rounded-rect
   keys with a big dark numeral — adapted to the white surface (light-gray fill
   instead of the dark screen's translucent-white). Call/Text keep their
   red/green pulse (see .spk-call / .spk-text above). Toggled by comms-dock.js
   (cd-sheet-dial on the .inbox-panel when filter==='dial'). */
.cd-sheet-dial .spartan-dialpad .spk-key {
  background: #F5F5F4;
  border-color: #E7E5E4;
  color: #1C1917;
}
.cd-sheet-dial .spartan-dialpad .spk-key:hover {
  background: #EFEEEC;
  border-color: #D6D3D1;
}
.cd-sheet-dial .spartan-dialpad .spk-key:active {
  background: #fefce8;
  border-color: #a16207;
  box-shadow: inset 0 0 0 1.5px rgba(161,98,7,.35);
}

/* ═══ A-264 — iPhone-style dial sheet (app + desktop) ════════════════════════
   Phoenix (2026-07-15): "Still old dial pad on app, not high UI one." then
   "Fix the desktop Dialpad. Looks terrible." Every dial surface now speaks
   the SAME design language as the A-138 full-screen call screens
   (renderCallUIv2, 08z-sales-v2.js): dark stone gradient, white type,
   translucent circular keys, one green circular Call control. Scoped
   `.inbox-panel.cd-sheet-dial` — the class the panel carries ONLY in Dial
   mode — so every other tab keeps the light GP-074 palette untouched. */
.inbox-panel.cd-sheet-dial {
  background: linear-gradient(160deg, #1C1917 0%, #292524 52%, #1C1917 100%);
  border: 0;
}
/* Panel chrome (header + tab strip) goes translucent-dark. */
.inbox-panel.cd-sheet-dial .ip-h { background: transparent; border-bottom-color: rgba(255,255,255,.08); }
.inbox-panel.cd-sheet-dial .ip-title { color: #fff; }
.inbox-panel.cd-sheet-dial .ip-title b { color: #F87171; }
.inbox-panel.cd-sheet-dial .ip-h-l .ico { color: rgba(255,255,255,.6); }
.inbox-panel.cd-sheet-dial .ip-h .ip-close { border-color: rgba(255,255,255,.22); color: rgba(255,255,255,.75); background: none; }
.inbox-panel.cd-sheet-dial .ip-tabs { background: transparent; border-bottom-color: rgba(255,255,255,.08); }
.inbox-panel.cd-sheet-dial .ip-tab { color: rgba(255,255,255,.5); }
.inbox-panel.cd-sheet-dial .ip-tab:hover { color: #fff; }
.inbox-panel.cd-sheet-dial .ip-tab.on { background: rgba(255,255,255,.14); color: #fff; box-shadow: none; }
.inbox-panel.cd-sheet-dial .ip-tab-c { background: rgba(255,255,255,.16); color: rgba(255,255,255,.8); }
.inbox-panel.cd-sheet-dial .ip-tab.on .ip-tab-c { background: #fff; color: #1C1917; }
.inbox-panel.cd-sheet-dial .ip-body { background: transparent; }

/* The dock card dissolves into the dark screen. The lone "Dial" tab strip is
   double chrome everywhere (the panel's ip-tabs already shows Dial) — dropped.
   The "Spartan Phone" mini-header is dropped on MOBILE only; on desktop it
   carries the master volume control (the only volume UI), so it stays,
   dark-styled below. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock { background: transparent; border: 0; box-shadow: none; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .tabs { display: none; }
.cd-mobile .inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top { display: none; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top .dock-title { color: #fff; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top .dock-title small { color: rgba(255,255,255,.45); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top .icon-btn { color: rgba(255,255,255,.65); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top .icon-btn:hover { background: rgba(255,255,255,.1); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top .vol { accent-color: #34D399; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .body { padding: 18px 20px 0; } /* A-289 B0e: side gutters */
/* A-289 B0g — themed divider under the desktop "Spartan Phone" mini-header. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .dock-top { border-bottom-color: rgba(255,255,255,.08); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .dock-top { border-bottom-color: rgba(0,0,0,.08); }

/* Desktop dial tab — same dark design inside the 400px floating panel; the
   panel grows a little (viewport-capped) and the pad tightens so keys, Call
   circle, pills and contacts fit without feeling cramped. */
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-sheet-dial { height: 700px; max-height: calc(100vh - 48px); }
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .keys { max-width: 264px; gap: 10px 18px; }
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .key { font-size: 22px; }
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .num { font-size: 24px; }
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.dial-go { width: 56px; height: 56px; }
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.dial-go .ico { width: 22px; height: 22px; }

/* Number readout — big, borderless, centred (iPhone). A-289 B0b: app SANS
   (was inheriting the --gp74-mono typewriter face). tabular-nums still inherited. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .num {
  background: transparent; border: 0; color: #fff; text-align: center;
  font-family: var(--ff-sans, 'Archivo', system-ui, sans-serif);
  font-size: 30px; font-weight: 400; letter-spacing: .02em; caret-color: #34D399;
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .num::placeholder { color: rgba(255,255,255,.28); font-size: 20px; font-weight: 400; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .icon-btn.back { background: rgba(255,255,255,.08); border: 0; color: rgba(255,255,255,.7); border-radius: 50%; }
/* A-289 B0f — center the number across the full row; float backspace at the right. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .num-row { position: relative; justify-content: center; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .num { flex: 0 1 auto; width: 100%; box-sizing: border-box; padding-left: 44px; padding-right: 44px; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .icon-btn.back { position: absolute; right: 0; top: 50%; transform: translateY(-50%); }
/* A-289 B0h — hide the backspace when the field is empty (single-space placeholder keeps :placeholder-shown matching). */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .num-row:has(.num:placeholder-shown) .icon-btn.back { opacity: 0; pointer-events: none; }

/* Keys — translucent white circles, big numerals, letter sublabels. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .keys {
  max-width: 300px; margin: 0 auto 14px; gap: 12px 22px;
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .key {
  aspect-ratio: 1 / 1; border-radius: 50%; border: 0;
  background: rgba(255,255,255,.09); color: #fff;
  font-size: 26px; font-weight: 400; line-height: 1;
  /* A-289 B0a — pin two fixed grid rows (digit + reserved letter band) and
     center the block, so the digit lands at the SAME height on every key incl.
     1/*/# (which have no <small>). Kills the ragged, top-heavy digits. */
  grid-template-rows: 1.05em 0.72em; align-content: center; row-gap: 0;
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .key small {
  align-self: start; line-height: 1; margin-top: 0;
  color: rgba(255,255,255,.45); font-size: 9.5px; letter-spacing: .14em;
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .key:hover { border: 0; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .key:active { background: rgba(255,255,255,.28); }

/* The green Call — a centred circle (the A-138 accept green), icon only. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .call-split.single { display: flex; justify-content: center; margin-top: 2px; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.dial-go {
  width: 68px; height: 68px; border-radius: 50%; padding: 0; font-size: 0; gap: 0;
  background: #10B981; box-shadow: 0 10px 26px rgba(16,185,129,.35);
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.dial-go .ico { width: 27px; height: 27px; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.dial-go:active { background: #0E9F6E; }

/* Text (SMS) — quiet ghost pill under the call circle. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .row-text { display: flex; justify-content: center; margin-top: 12px; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.text {
  width: auto; flex-direction: row; gap: 7px; padding: 9px 24px; border-radius: 999px;
  color: rgba(255,255,255,.85); border: 1px solid rgba(255,255,255,.25); background: rgba(255,255,255,.06);
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .btn.text .ico { color: #34D399; }

/* Contacts — dark rows; the search input still opens the A-137 full-screen
   overlay on focus (that overlay keeps its own light styling). */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contacts { border-top: 1px solid rgba(255,255,255,.08); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contacts-h { color: rgba(255,255,255,.45); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contact-search {
  background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.14); color: #fff;
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contact-search::placeholder { color: rgba(255,255,255,.35); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-section-label { color: rgba(255,255,255,.4); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contact-row:hover { background: rgba(255,255,255,.07); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contact-name { color: #fff; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contact-num { color: rgba(255,255,255,.5); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-contact-empty { color: rgba(255,255,255,.45); }

/* Incoming/in-call bodies inside the dial sheet inherit the dark screen too —
   avatar/name/status read white, and the control cluster mirrors A-138's
   translucent circles. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .who .nm { color: #fff; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .who .nn { color: rgba(255,255,255,.55); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .status-line { color: rgba(255,255,255,.75); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .ctl {
  background: rgba(255,255,255,.09); border: 0; color: #fff;
}
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .ctl.on { background: #fff; color: #1C1917; }

/* ═══ Dial sheet — LIGHT theme (A-286) ═══════════════════════════════════════
   Phoenix (2026-07-17): "Light mode does not work on all menus. Including dial
   pad." The dialpad kept the dark iPhone skin regardless of the user's Light/
   Dark toggle. cd-sheet-dial now carries the iPhone LAYOUT for both themes;
   cd-sheet-light (added when the theme resolver says light) flips the palette to
   an iPhone light keypad — light-grey circular keys, dark numerals, white sheet
   — while the green Call circle stays green in both. Higher specificity (extra
   class) + later source order than the dark rules above, so these win. */
.inbox-panel.cd-sheet-dial.cd-sheet-light {
  background: linear-gradient(160deg, #FFFFFF 0%, #F4F3F1 52%, #FFFFFF 100%);
}
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-h { border-bottom-color: rgba(0,0,0,.08); }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-title { color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-title b { color: #a16207; }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-h-l .ico { color: rgba(0,0,0,.5); }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-h .ip-close { border-color: rgba(0,0,0,.16); color: rgba(0,0,0,.6); }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-tabs { border-bottom-color: rgba(0,0,0,.08); }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-tab { color: rgba(0,0,0,.5); }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-tab:hover { color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-tab.on { background: rgba(0,0,0,.06); color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-tab-c { background: rgba(0,0,0,.09); color: rgba(0,0,0,.7); }
.inbox-panel.cd-sheet-dial.cd-sheet-light .ip-tab.on .ip-tab-c { background: #1C1917; color: #fff; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .dock-top .dock-title { color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .dock-top .dock-title small { color: rgba(0,0,0,.5); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .dock-top .icon-btn { color: rgba(0,0,0,.55); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .dock-top .icon-btn:hover { background: rgba(0,0,0,.06); }
/* Number readout + backspace */
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .num { color: #1C1917; caret-color: #10B981; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .num::placeholder { color: rgba(0,0,0,.3); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .icon-btn.back { background: rgba(0,0,0,.05); color: rgba(0,0,0,.55); }
/* Keys — light-grey circles, dark numerals */
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .key { background: rgba(0,0,0,.05); color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .key small { color: rgba(0,0,0,.42); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .key:active { background: rgba(0,0,0,.13); }
/* Text pill (Call circle stays green from the dark rules) */
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .btn.text {
  color: rgba(0,0,0,.75); border-color: rgba(0,0,0,.18); background: rgba(0,0,0,.03);
}
/* Contacts */
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contacts { border-top-color: rgba(0,0,0,.08); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contacts-h { color: rgba(0,0,0,.45); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contact-search {
  background: rgba(0,0,0,.04); border-color: rgba(0,0,0,.12); color: #1C1917;
}
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contact-search::placeholder { color: rgba(0,0,0,.35); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-section-label { color: rgba(0,0,0,.4); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contact-row:hover { background: rgba(0,0,0,.04); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contact-name { color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contact-num { color: rgba(0,0,0,.5); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-contact-empty { color: rgba(0,0,0,.45); }
/* Incoming / in-call bodies */
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .who .nm { color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .who .nn { color: rgba(0,0,0,.55); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .status-line { color: rgba(0,0,0,.7); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .ctl { background: rgba(0,0,0,.05); color: #1C1917; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .ctl.on { background: #1C1917; color: #fff; }

/* ═══ Light/Dark theme toggle chip (A-273) — comms dock header ═══════════════ */
.inbox-panel .ip-theme-toggle {
  background: none; border: 1px solid var(--cdh-s200); border-radius: 8px;
  font-size: 13px; line-height: 1; padding: 4px 7px; margin-right: 8px;
  cursor: pointer; font-family: inherit; flex: 0 0 auto;
}
.inbox-panel .ip-theme-toggle:hover { background: var(--cdh-s50); }
.inbox-panel.cd-dark .ip-theme-toggle { border-color: rgba(255,255,255,.22); }
.inbox-panel.cd-dark .ip-theme-toggle:hover { background: rgba(255,255,255,.1); }
/* On the email deck the toggle rides the sc-deck-icbtn base; just size the glyph. */
.cd-theme-toggle { font-size: 14px; line-height: 1; }

/* ═══ Calls tab — dark iPhone-style call log (phones only) ═══════════════════
   Phoenix (2026-07-17): bring the comms-desk "Calls" tab up to the same dark
   high-UI standard as the dialpad / Team Chat — "dark on phones, light on
   desktop". Scoped `.inbox-panel.cd-dark`, the class the panel carries ONLY on
   a phone surface with the Calls tab active (see _isPhoneSurface + the panelCls
   / _syncInboxChrome hooks in comms-dock.js). Every other tab + all of desktop
   keep the light GP-074 palette untouched. Same dark stone gradient + red/green
   accent language as cd-sheet-dial so the surfaces feel like one app. */
.inbox-panel.cd-dark {
  background: linear-gradient(160deg, #1C1917 0%, #292524 52%, #1C1917 100%);
  border: 0;
}
/* Chrome: header + tab strip + scope bar go translucent-dark. */
.inbox-panel.cd-dark .ip-h { background: transparent; border-bottom-color: rgba(255,255,255,.08); }
.inbox-panel.cd-dark .ip-title { color: #fff; }
.inbox-panel.cd-dark .ip-title b { color: #F87171; }
.inbox-panel.cd-dark .ip-h-l .ico { color: rgba(255,255,255,.6); }
.inbox-panel.cd-dark .ip-h .ip-close { border-color: rgba(255,255,255,.22); color: rgba(255,255,255,.75); background: none; }
.inbox-panel.cd-dark .ip-markread { background: none !important; border-color: rgba(255,255,255,.22) !important; color: rgba(255,255,255,.75) !important; }
.inbox-panel.cd-dark .ip-tabs { background: transparent; border-bottom-color: rgba(255,255,255,.08); }
.inbox-panel.cd-dark .ip-tab { color: rgba(255,255,255,.5); }
.inbox-panel.cd-dark .ip-tab:hover { color: #fff; }
.inbox-panel.cd-dark .ip-tab.on { background: rgba(255,255,255,.14); color: #fff; box-shadow: none; }
.inbox-panel.cd-dark .ip-tab-c { background: rgba(255,255,255,.16); color: rgba(255,255,255,.8); }
.inbox-panel.cd-dark .ip-tab.on .ip-tab-c { background: #fff; color: #1C1917; }
.inbox-panel.cd-dark .ip-body { background: transparent; }
.inbox-panel.cd-dark .ip-phone-status { color: rgba(255,255,255,.55) !important; }

/* Empty state. */
.inbox-panel.cd-dark .ip-empty { color: rgba(255,255,255,.7); }
.inbox-panel.cd-dark .ip-empty-sub { color: rgba(255,255,255,.4); }

/* Call rows — iPhone Recents feel: hairline separators, white name, muted
   secondary line, right-aligned tabular time, a coloured direction glyph. */
.inbox-panel.cd-dark .ip-row {
  border-bottom-color: rgba(255,255,255,.07);
  background: none;
}
.inbox-panel.cd-dark .ip-row:hover { background: rgba(255,255,255,.05); }
.inbox-panel.cd-dark .ip-row:active { background: rgba(255,255,255,.09); }
/* Missed calls read red — the row name + a red rail on the left, iOS-style. */
.inbox-panel.cd-dark .ip-row.missed::before { background: #F87171; }
.inbox-panel.cd-dark .ip-row.missed .ip-name { color: #F87171; }

.inbox-panel.cd-dark .ip-av {
  background: rgba(255,255,255,.12);
  color: rgba(255,255,255,.92);
}
.inbox-panel.cd-dark .ip-name { color: #fff; }
.inbox-panel.cd-dark .ip-name .ico { color: rgba(255,255,255,.55); }
/* Direction/status glyph colours: received/outgoing = green, missed = red,
   voicemail = amber — the at-a-glance iPhone colour code. */
.inbox-panel.cd-dark .ip-name .missed-ico { color: #F87171; }
.inbox-panel.cd-dark .ip-name .vm-ico { color: #FBBF24; }
.inbox-panel.cd-dark .ip-time { color: rgba(255,255,255,.45); }
.inbox-panel.cd-dark .ip-snippet { color: rgba(255,255,255,.5); }
.inbox-panel.cd-dark .ip-snippet b { color: rgba(255,255,255,.8); }

/* Recording note (offline) + transcript preview go light-on-dark. */
.inbox-panel.cd-dark .cd-call-rec-off { color: rgba(255,255,255,.45); }

/* Quick actions — translucent pills; the Call CTA stays the one green control
   (iPhone's single green call affordance), Play stays a quiet translucent pill. */
.inbox-panel.cd-dark .ip-qa {
  background: rgba(255,255,255,.08);
  border-color: rgba(255,255,255,.14);
  color: rgba(255,255,255,.85);
}
.inbox-panel.cd-dark .ip-qa:hover {
  background: rgba(255,255,255,.14);
  border-color: rgba(255,255,255,.28);
  color: #fff;
  box-shadow: none;
}
.inbox-panel.cd-dark .ip-qa.call-back {
  background: #22C55E;
  border-color: #22C55E;
  color: #06210F;
  box-shadow: 0 1px 2px rgba(34,197,94,.25), 0 4px 12px -4px rgba(34,197,94,.5);
}
.inbox-panel.cd-dark .ip-qa.call-back:hover { background: #16A34A; border-color: #16A34A; }
/* Disposition picker + set-label — dark inputs. A native <select> keeps its
   light UA chrome unless we both repaint it and drop the default appearance. */
.inbox-panel.cd-dark .ip-dispo-picker {
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255,255,255,.08) !important;
  border: 1px solid rgba(255,255,255,.18) !important;
  color: #fff !important;
}
.inbox-panel.cd-dark .ip-dispo-picker option { color: #1C1917; }
.inbox-panel.cd-dark .ip-dispo-set { color: rgba(255,255,255,.6); }

/* ADMIN scope bar — the "Viewing: All users" strip is inline-styled white in
   the render, so the dark overrides need !important. The red ADMIN chip stays
   red (reads fine on dark); the select + label + bar go dark. */
.inbox-panel.cd-dark .ip-scope {
  background: rgba(255,255,255,.04) !important;
  border-bottom-color: rgba(255,255,255,.08) !important;
}
.inbox-panel.cd-dark .ip-scope span { color: rgba(255,255,255,.6) !important; }
.inbox-panel.cd-dark .ip-scope span[style*="C41230"] { color: #F87171 !important; border-color: #F87171 !important; }
.inbox-panel.cd-dark #cdh-scope-select {
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255,255,255,.08) !important;
  color: #fff !important;
  border-color: rgba(255,255,255,.18) !important;
}
.inbox-panel.cd-dark #cdh-scope-select option { color: #1C1917; }

/* ═══ Call transcript — high-UI "Transcript" button + expandable panel ═══════
   Phoenix (2026-07-17): "No need to have Set Outcome. Have a high UI button to
   see transcription." The Calls-tab row now carries a Transcript button that
   opens the AI summary + key points + full transcript inline. Styled for both
   the light desktop dock and the dark phone Calls tab. */
.inbox-panel .cd-tx-btn.on { border-color: var(--cdh-ink); color: var(--cdh-ink); background: var(--cdh-s50); }
.inbox-panel .cd-tx-panel {
  margin-top: 9px;
  padding: 12px 13px;
  background: var(--cdh-s50);
  border: 1px solid var(--cdh-s100);
  border-radius: 12px;
  max-height: 260px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  animation: cd-tx-in .16s ease both;
}
@keyframes cd-tx-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.inbox-panel .cd-tx-summary { font-size: 12.5px; font-weight: 700; color: var(--cdh-s900); line-height: 1.55; margin-bottom: 8px; }
.inbox-panel .cd-tx-text { font-size: 12px; color: var(--cdh-s600); line-height: 1.65; white-space: pre-wrap; word-break: break-word; }
.inbox-panel .cd-ci-keypoints { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.inbox-panel .cd-ci-kp-chip {
  font-size: 10.5px; font-weight: 700; color: var(--cdh-s700);
  background: #fff; border: 1px solid var(--cdh-s200); border-radius: 999px; padding: 2px 9px;
}
@media (prefers-reduced-motion: reduce) { .inbox-panel .cd-tx-panel { animation: none; } }

/* Dark (phone Calls tab). */
.inbox-panel.cd-dark .cd-tx-btn.on { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.32); color: #fff; }
.inbox-panel.cd-dark .cd-tx-panel { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.1); }
.inbox-panel.cd-dark .cd-tx-summary { color: #fff; }
.inbox-panel.cd-dark .cd-tx-text { color: rgba(255,255,255,.72); }
.inbox-panel.cd-dark .cd-ci-kp-chip { background: rgba(255,255,255,.1); color: rgba(255,255,255,.85); border-color: rgba(255,255,255,.16); }
.inbox-panel.cd-dark .cd-vm-transcript { color: rgba(255,255,255,.72); }
.inbox-panel.cd-dark .cd-vm-transcript--muted { color: rgba(255,255,255,.45); }

/* ═══ Texts / SMS — dark high-UI (phones only) ═══════════════════════════════
   Phoenix: the comms-desk SMS surfaces get the WhatsApp-dark treatment to match
   the Calls tab + Team Chat. Two surfaces:
     1. the SMS thread LIST (the 'messages' tab, in the .inbox-panel.cd-dark);
     2. the SMS conversation .thread-panel.cd-dark (bubbles + composer).
   Both gated to phone surfaces; desktop keeps the light GP-074 palette. */
/* --- 1. thread list rows (green = unread, matching the light behaviour) --- */
.inbox-panel.cd-dark .ip-name .sms-ico { color: #34D399; }
.inbox-panel.cd-dark .ip-row.sms-row.unread { background: rgba(34,197,94,.1); }
.inbox-panel.cd-dark .ip-row.sms-row.unread:hover { background: rgba(34,197,94,.16); }
.inbox-panel.cd-dark .ip-row.sms-row.unread .ip-name { color: #fff; }
.inbox-panel.cd-dark .ip-row.sms-row.unread .ip-snippet { color: rgba(255,255,255,.82); }
.inbox-panel.cd-dark .ip-row.sms-row.read .ip-name { color: rgba(255,255,255,.85); }
.inbox-panel.cd-dark .ip-row.sms-row.read .ip-snippet { color: rgba(255,255,255,.45); }
.inbox-panel.cd-dark .ip-new-pill { background: #22C55E; color: #06210F; }
.inbox-panel.cd-dark .ip-failed-pill { background: #7f1d1d; color: #FCA5A5; }
.inbox-panel.cd-dark .ip-qa.reply-text { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.2); color: #fff; }
.inbox-panel.cd-dark .ip-qa.reply-text:hover { background: rgba(255,255,255,.2); }

/* --- 2. conversation thread panel (header is already dark; darken the rest) --- */
.thread-panel.cd-dark { background: #14100F; }
.thread-panel.cd-dark .tp-linked { background: rgba(255,255,255,.05); color: rgba(255,255,255,.6); border-bottom-color: rgba(255,255,255,.08); }
.thread-panel.cd-dark .tp-linked .ico { color: rgba(255,255,255,.5); }
.thread-panel.cd-dark .tp-linked b { color: #fff; }
.thread-panel.cd-dark .tp-messages {
  background: #14100F;
  background-image: radial-gradient(circle at 20% 18%, rgba(250,204,21,.06) 0%, transparent 55%),
                    radial-gradient(circle at 82% 86%, rgba(255,255,255,.03) 0%, transparent 55%);
}
.thread-panel.cd-dark .tp-date-divider { background: rgba(255,255,255,.08); color: rgba(255,255,255,.6); border-color: rgba(255,255,255,.1); }
.thread-panel.cd-dark .msg.in .msg-bubble { background: #262524; color: #ECE9E7; border-color: rgba(255,255,255,.06); }
.thread-panel.cd-dark .msg.out .msg-bubble { background: #7E1122; color: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.35); }
.thread-panel.cd-dark .msg-bubble--failed { background: #7f1d1d !important; color: #fff; }
.thread-panel.cd-dark .msg-meta { color: rgba(255,255,255,.4); }
.thread-panel.cd-dark .msg-meta.delivered { color: rgba(255,255,255,.55); }
.thread-panel.cd-dark .msg-meta.read { color: #34D399; }
.thread-panel.cd-dark .tp-compose { background: #1C1917; border-top-color: rgba(255,255,255,.08); }
.thread-panel.cd-dark .tp-input { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.14); color: #fff; }
.thread-panel.cd-dark .tp-input::placeholder { color: rgba(255,255,255,.4); }
.thread-panel.cd-dark .tp-input:focus { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); box-shadow: none; }
.thread-panel.cd-dark .tp-send { background: #22C55E; color: #06210F; }
.thread-panel.cd-dark .tp-send:hover { background: #16A34A; box-shadow: 0 4px 12px -2px rgba(34,197,94,.5); }
.thread-panel.cd-dark .tp-foot-hint { color: rgba(255,255,255,.4) !important; }
.thread-panel.cd-dark .tp-foot-hint b { color: rgba(255,255,255,.75) !important; }

/* ═══ Voicemail — dark high-UI (phones only) ═════════════════════════════════
   Phoenix: Voicemail next. The Personal box reuses the (already-dark) Calls
   row incl. the Transcript button; per-endpoint boxes reuse `.ip-row`. Only the
   voicemail-specific chrome (the inline-styled box selector + a couple of
   inline greys) needs dark overrides — hence the !important. */
.inbox-panel.cd-dark .cd-vm-selector { background: rgba(255,255,255,.04) !important; border-bottom-color: rgba(255,255,255,.08) !important; }
.inbox-panel.cd-dark .cd-vm-radio { color: rgba(255,255,255,.85) !important; background: rgba(255,255,255,.06) !important; border-color: rgba(255,255,255,.14) !important; }
.inbox-panel.cd-dark .cd-vm-radio-sel { color: #fff !important; background: rgba(59,130,246,.22) !important; border-color: #3B82F6 !important; }
.inbox-panel.cd-dark .cd-vm-path { color: rgba(255,255,255,.5) !important; }
.inbox-panel.cd-dark .cd-vm-rec-none { color: rgba(255,255,255,.4) !important; }
.inbox-panel.cd-dark .cd-vm-box-row .ip-name .ico { color: #FBBF24; }

/* ── Email deck (mobile email view) — extends the StaffChat sc-* sheet ──────── */
.cd-email-deck .cd-em-search{display:flex;align-items:center;gap:8px;padding:8px 14px;border-bottom:1px solid #E7E5E4;background:#fff}
.cd-email-deck .cd-em-search .ico{width:16px;height:16px;color:#9CA3AF;flex:0 0 auto}
.cd-email-deck .cd-em-search input{flex:1;border:none;outline:none;font:inherit;font-size:14px;background:transparent;color:#0A0A0A}
.cd-em-trk{font-size:10px;font-weight:800;color:#15803D;background:#DCFCE7;border-radius:10px;padding:1px 7px;white-space:nowrap;flex:0 0 auto;align-self:center}
.cd-em-read{display:block;padding:18px 16px 36px}
.cd-em-subj{font-family:Syne,sans-serif;font-size:17px;font-weight:800;color:#0A0A0A;line-height:1.3;margin-bottom:6px}
.cd-em-meta{font-size:12px;color:#9CA3AF;margin-bottom:14px}
.cd-em-body{font-size:14px;line-height:1.7;color:#374151;word-break:break-word;overflow-wrap:anywhere}
.cd-em-body img{max-width:100%!important;height:auto}
.cd-em-body a{color:#1D4ED8;word-break:break-all}
.cd-em-body table{max-width:100%!important;width:auto!important}
.cd-em-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:22px;padding-top:16px;border-top:1px solid #F0F0F0}
.cd-em-btn{display:inline-flex;align-items:center;gap:6px;font:inherit;font-size:13px;font-weight:700;color:#44403C;background:#fff;border:1px solid #E7E5E4;border-radius:10px;padding:9px 16px;cursor:pointer}
.cd-em-btn .ico{width:14px;height:14px}
.cd-em-btn.primary{color:#000;background:#facc15;border-color:#a16207}
.cd-em-btn:active{transform:translateY(1px)}

/* ── Email composer (in-dock reply / forward / new) ────────────────────────── */
.cd-em-compose{display:flex;flex-direction:column;padding:0 0 28px}
.cd-emc-row{display:flex;align-items:center;gap:10px;padding:11px 16px;border-bottom:1px solid #F0F0F0}
.cd-emc-row span{flex:0 0 54px;font-size:12px;font-weight:700;color:#9CA3AF;text-transform:uppercase;letter-spacing:.04em}
.cd-emc-row input{flex:1;border:none;outline:none;font:inherit;font-size:14px;color:#0A0A0A;background:transparent}
.cd-emc-body{border:none;outline:none;resize:none;min-height:200px;padding:14px 16px;font:inherit;font-size:14px;line-height:1.6;color:#0A0A0A;background:transparent}
.cd-emc-quote{margin:0 16px;padding:10px 12px;border-left:3px solid #E7E5E4;color:#9CA3AF;font-size:12.5px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:160px;overflow:auto}

/* ── Email deck — dark overrides (phones / dark theme). The deck rides on the
   StaffChat sc-panel + sc-dark theme, so the header, folder tabs, rows and empty
   states darken for free; only the email-specific cd-em-* / cd-emc-* chrome
   (search, read view, composer) needs these rules. ─────────────────────────── */
.sc-panel.sc-dark .cd-em-search { background: transparent; border-bottom-color: rgba(255,255,255,.08); }
.sc-panel.sc-dark .cd-em-search input { color: #EDEAE8; }
.sc-panel.sc-dark .cd-em-search input::placeholder { color: rgba(255,255,255,.4); }
.sc-panel.sc-dark .cd-em-subj { color: #fff; }
.sc-panel.sc-dark .cd-em-meta { color: rgba(255,255,255,.45); }
.sc-panel.sc-dark .cd-em-body { color: rgba(255,255,255,.78); }
.sc-panel.sc-dark .cd-em-body a { color: #7FB5FF; }
.sc-panel.sc-dark .cd-em-actions { border-top-color: rgba(255,255,255,.08); }
.sc-panel.sc-dark .cd-em-btn { color: #EDEAE8; background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.16); }
.sc-panel.sc-dark .cd-em-btn.primary { color: #000; background: #facc15; border-color: #facc15; }
.sc-panel.sc-dark .cd-emc-row { border-bottom-color: rgba(255,255,255,.08); }
.sc-panel.sc-dark .cd-emc-row span { color: rgba(255,255,255,.5); }
.sc-panel.sc-dark .cd-emc-row input { color: #fff; }
.sc-panel.sc-dark .cd-emc-body { color: #EDEAE8; }
.sc-panel.sc-dark .cd-emc-quote { border-left-color: rgba(255,255,255,.18); color: rgba(255,255,255,.5); }

/* ── Email dashboard: unread pulse + Clients/Staff tabs ─────────────────────── */
.cd-em-tabs{scrollbar-width:none}
.cd-em-tabs::-webkit-scrollbar{display:none}
.cd-email-deck .sc-row{position:relative}
/* UNREAD = unmissable: a pulsing red halo radiating off the sender avatar, a
   thick glowing left bar, and a soft brand wash on the row. The row wash is a
   STATIC tint; the sentiment pulse below ANIMATES the bg, so they don't clash. */
@keyframes cdEmUnreadRing{0%{box-shadow:0 0 0 0 rgba(250,204,21,.55)}70%{box-shadow:0 0 0 11px rgba(250,204,21,0)}100%{box-shadow:0 0 0 0 rgba(250,204,21,0)}}
@keyframes cdEmUnreadBar{0%,100%{opacity:1;transform:scaleY(1)}50%{opacity:.4;transform:scaleY(.55)}}
.cd-email-deck .sc-row.unread{background:#fefce8}
.cd-email-deck .sc-row.unread .sc-av{animation:cdEmUnreadRing 1.5s ease-out infinite}
.cd-email-deck .sc-row.unread::before{content:'';position:absolute;left:0;top:7px;bottom:7px;width:4px;border-radius:0 4px 4px 0;background:#a16207;box-shadow:0 0 6px rgba(250,204,21,.55);animation:cdEmUnreadBar 1.4s ease-in-out infinite}
/* ── Reserved for the AI sentiment pulse (Graham) ───────────────────────────
   Tag a row with data-sentiment="negative" | "positive" and it pulses red/green.
   Kept separate from the unread accent above so the two can coexist. */
@keyframes cdEmSentNeg{0%,100%{background:transparent}50%{background:rgba(220,38,38,.10)}}
@keyframes cdEmSentPos{0%,100%{background:transparent}50%{background:rgba(21,128,61,.10)}}
.cd-email-deck .sc-row[data-sentiment="negative"]{animation:cdEmSentNeg 1.8s ease-in-out infinite}
.cd-email-deck .sc-row[data-sentiment="positive"]{animation:cdEmSentPos 1.8s ease-in-out infinite}

/* ── Reply-urgency escalation (Phoenix): unreplied client/staff mail ─────────
   Escalates the avatar halo + left bar: yellow → red (24h) → intense (48h).
   These rules come AFTER the plain unread pulse so they win for urgent rows
   (which may be READ-but-unreplied, hence keyed on data-urgency not .unread). */
@keyframes cdUrgY{0%{box-shadow:0 0 0 0 rgba(217,119,6,.55)}70%{box-shadow:0 0 0 11px rgba(217,119,6,0)}100%{box-shadow:0 0 0 0 rgba(217,119,6,0)}}
@keyframes cdUrgR{0%{box-shadow:0 0 0 0 rgba(220,38,38,.6)}70%{box-shadow:0 0 0 13px rgba(220,38,38,0)}100%{box-shadow:0 0 0 0 rgba(220,38,38,0)}}
.cd-email-deck .sc-row[data-urgency="yellow"]{background:#FFFBEB}
.cd-email-deck .sc-row[data-urgency="red"],.cd-email-deck .sc-row[data-urgency="intense"]{background:#FEF2F2}
.cd-email-deck .sc-row[data-urgency] .sc-time{font-weight:800}
.cd-email-deck .sc-row[data-urgency="yellow"] .sc-av{animation:cdUrgY 1.8s ease-out infinite}
.cd-email-deck .sc-row[data-urgency="red"] .sc-av{animation:cdUrgR 1.4s ease-out infinite}
.cd-email-deck .sc-row[data-urgency="intense"] .sc-av{animation:cdUrgR .6s ease-out infinite}
.cd-email-deck .sc-row[data-urgency]::before{content:'';position:absolute;left:0;top:7px;bottom:7px;width:4px;border-radius:0 4px 4px 0;animation:cdEmUnreadBar 1.4s ease-in-out infinite}
.cd-email-deck .sc-row[data-urgency="yellow"]::before{background:#D97706;box-shadow:0 0 6px rgba(217,119,6,.55)}
.cd-email-deck .sc-row[data-urgency="red"]::before,.cd-email-deck .sc-row[data-urgency="intense"]::before{background:#DC2626;box-shadow:0 0 7px rgba(220,38,38,.6)}
.cd-email-deck .sc-row[data-urgency="intense"]::before{animation-duration:.6s}

/* ── Voicemail transcript line (Spec 6) ──────────────────────────────────── */
.cd-vm-transcript {
  margin-top: 5px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--cdh-s700);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
  max-height: 96px;
  overflow-y: auto;
}
.cd-vm-transcript--muted {
  color: var(--cdh-s400);
  font-style: italic;
}

/* ── A-137 — FULL-SCREEN dialpad contact search (mobile) ─────────────────────
   Tapping the dialpad's Contacts search on the mobile app expands into this
   body-level overlay: big autofocused input + ✕ close at the top, Staff/
   Contacts results filling the whole screen. z-index above every dock layer
   (63) and modal. Desktop keeps the small inline search (never renders this). */
.cdh-search-overlay {
  position: fixed; inset: 0; z-index: 100000;
  background: #fff; display: flex; flex-direction: column;
  padding-top: env(safe-area-inset-top, 0px);
}
.cdh-search-top {
  display: flex; align-items: center; gap: 10px; flex-shrink: 0;
  padding: 14px 16px 12px; border-bottom: 1px solid #F0F0EF; background: #fff;
}
.cdh-search-input {
  flex: 1; min-width: 0; box-sizing: border-box;
  font-size: 17px; /* ≥16px stops iOS auto-zoom on focus */
  font-family: inherit; color: #1C1917;
  padding: 13px 16px; border: 1.5px solid #0A0A0A; border-radius: 14px;
  background: #FAFAF9;
}
.cdh-search-input:focus { outline: none; background: #fff; box-shadow: 0 0 0 3px rgba(10,10,10,.06); }
.cdh-search-close {
  width: 46px; height: 46px; flex-shrink: 0;
  border: none; border-radius: 50%; background: #F5F5F4; color: #1C1917;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background 140ms;
}
.cdh-search-close:hover { background: #E7E5E4; }
.cdh-search-close .ico { width: 22px; height: 22px; }
.cdh-search-results {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 8px 12px calc(24px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 2px;
}
/* Roomier touch targets than the cramped in-dock list. */
.cdh-search-results .cdh-contact-row { padding: 12px 10px; border-radius: 12px; }
.cdh-search-results .cdh-contact-name { font-size: 15px; }
.cdh-search-results .cdh-contact-num { font-size: 13px; }
.cdh-search-results .cdh-section-label { padding: 12px 10px 4px; font-size: 12px; }

/* ═══ Contacts search — dark (black) UI on phones (A-277) ════════════════════
   Phoenix: "make the contacts bar better with the black UI theme." Same dark
   stone gradient + red-call/green-text language as the rest of the comms desk;
   the red/green action buttons stay (their contrast reads fine on dark). */
.cdh-search-overlay.cd-dark { background: linear-gradient(160deg, #1C1917 0%, #292524 52%, #1C1917 100%); }
.cdh-search-overlay.cd-dark .cdh-search-top { background: transparent; border-bottom-color: rgba(255,255,255,.08); }
.cdh-search-overlay.cd-dark .cdh-search-input {
  color: #fff; background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.22);
}
.cdh-search-overlay.cd-dark .cdh-search-input::placeholder { color: rgba(255,255,255,.4); }
.cdh-search-overlay.cd-dark .cdh-search-input:focus { background: rgba(255,255,255,.12); box-shadow: 0 0 0 3px rgba(255,255,255,.08); }
.cdh-search-overlay.cd-dark .cdh-search-close { background: rgba(255,255,255,.1); color: #fff; }
.cdh-search-overlay.cd-dark .cdh-search-close:hover { background: rgba(255,255,255,.18); }
.cdh-search-overlay.cd-dark .cdh-section-label { color: rgba(255,255,255,.45); }
.cdh-search-overlay.cd-dark .cdh-contact-row:hover { background: rgba(255,255,255,.06); }
.cdh-search-overlay.cd-dark .cdh-contact-av { background: rgba(255,255,255,.12); color: rgba(255,255,255,.92); }
.cdh-search-overlay.cd-dark .cdh-contact-name { color: #fff; }
.cdh-search-overlay.cd-dark .cdh-contact-num { color: rgba(255,255,255,.5); }
.cdh-search-overlay.cd-dark .cdh-contact-empty { color: rgba(255,255,255,.45); }
/* Call = Spartan red, Text = green — unchanged, they pop on the dark rows. */

/* ═══════════════════════════════════════════════════════════════════════════
   GP-074 W11 — Dialpad v2 (docs/design/gp074/UI-CONTRACT-mockup.html port)
   ADDITIVE ONLY — no rule above this block is touched, so flag-OFF v1 dialpad
   (`.spartan-dialpad` / `.cdh-dialpad`, rendered by _renderDialpadBodyV1) stays
   byte-identical.

   _renderDialpadBodyV2 (comms-dock.js) renders a `.dock` block (mockup-exact
   class names) INSIDE the existing `.inbox-panel`'s `#cdh-inbox-body` (the
   panel's real `.ip-h`/`.ip-tabs` chrome still wraps it — that's the frozen W8
   markup, not this file's concern). Every selector below is therefore scoped
   under `#cdh-inbox-body .dock` so nothing here can collide with the dock's
   existing bubble/panel/thread CSS above, or with app-wide classes of the same
   generic name (`.btn`, `.key`, `.body`, `.tab`, …) — no bare global rule is
   introduced.

   Class names verified verbatim against comms-dock.js:
   _dockHeaderSoundControls (.spk/.icon-btn/.vol), _renderDialpadIncoming
   (.dock/.dock-top/.dock-title/.body/.ring-badge/.callee/.avatar/.who/.nm/.nn/
   .answer-split/.btn.decline/.btn.accept), _renderDialpadIdle (adds .tabs/.tab/
   .num-row/.num/.icon-btn.back/.keys/.key/.call-split/.btn.browser/.btn.mobile/
   .row-text/.btn.text.full), _renderDialpadInCall (.status-line/.live-dot/
   .status-txt/.timer/.cluster/.ctl/.hangup-row/.btn.hangup.full). `.js-call-*`
   classes (F3) are styled implicitly — they sit on `.status-txt`/`.timer`/`.ctl`
   elements above and 28-twilio.js only swaps textContent/innerHTML in place.

   Theme: the dock has no dark-mode/data-theme support today (grep confirmed),
   so this ports the mockup's LIGHT palette only as local custom properties
   scoped to `.dock` (prefixed --gp74- to guarantee no collision with the
   existing --cdh-* token set already scoped on .inbox-panel).
   ═══════════════════════════════════════════════════════════════════════════ */
#cdh-inbox-body .dock {
  --gp74-ink: #16202b;
  --gp74-ink-soft: #55636f;
  --gp74-ink-faint: #8b97a3;
  --gp74-line: #dde3ea;
  --gp74-line-strong: #cbd4de;
  --gp74-panel-2: #f4f6f9;
  --gp74-accent: #2b6cb0;
  --gp74-browser: #0f8a6b;
  --gp74-mobile: #4f52c9;
  --gp74-danger: #d23b45;
  --gp74-key: #f4f6f9;
  --gp74-key-ink: #23303d;
  --gp74-mono: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", Menlo, Consolas, monospace;
  color: var(--gp74-ink);
}

/* ── header (dock-top): title + speaker/volume master-mute controls ──────── */
#cdh-inbox-body .dock .dock-top { display: flex; align-items: center; gap: 10px; }
#cdh-inbox-body .dock .dock-title { font-weight: 700; font-size: 14px; color: var(--gp74-ink); }
#cdh-inbox-body .dock .dock-title small { display: block; font-weight: 500; font-size: 11px; color: var(--gp74-ink-faint); letter-spacing: .02em; }
#cdh-inbox-body .dock .spk { margin-left: auto; display: flex; align-items: center; gap: 6px; }
#cdh-inbox-body .dock .icon-btn {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid transparent;
  background: transparent; color: var(--gp74-ink-soft); display: grid; place-items: center; cursor: pointer;
  flex: none;
}
#cdh-inbox-body .dock .icon-btn:hover { background: rgba(10,10,10,.06); }
#cdh-inbox-body .dock .vol {
  width: 90px; height: 4px; cursor: pointer; accent-color: var(--gp74-accent);
}
#cdh-inbox-body .dock .ico { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; fill: none; }
/* [F3] mute icon written by twilioMute() carries an inline "ico ico-xs" SVG
   (see 28-twilio.js _muteSvg) into .js-call-mute — sized here so it matches
   the header/back icons instead of ballooning to the 18px default above. */
#cdh-inbox-body .dock .ico-xs { width: 14px; height: 14px; }

/* ── dial tab strip (Idle state only — a single "Dial" tab) ──────────────── */
#cdh-inbox-body .dock .tabs { display: flex; padding: 0 2px; }
#cdh-inbox-body .dock .tab { padding: 8px 10px; font-size: 12.5px; color: var(--gp74-ink-faint); font-weight: 600; border-bottom: 2px solid transparent; }
#cdh-inbox-body .dock .tab.on { color: var(--gp74-accent); border-bottom-color: var(--gp74-accent); }

#cdh-inbox-body .dock .body { padding: 12px 0 0; }

/* ── number display + backspace ───────────────────────────────────────────── */
#cdh-inbox-body .dock .num-row { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
#cdh-inbox-body .dock .num {
  flex: 1; font-family: var(--gp74-mono); font-size: 20px; letter-spacing: .02em; color: var(--gp74-ink);
  padding: 8px 12px; border: 1px solid var(--gp74-line); border-radius: 10px; background: var(--gp74-panel-2);
  font-variant-numeric: tabular-nums; min-width: 0;
}
#cdh-inbox-body .dock .icon-btn.back { width: 40px; height: 40px; }

/* ── keypad ────────────────────────────────────────────────────────────────── */
#cdh-inbox-body .dock .keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
#cdh-inbox-body .dock .key {
  aspect-ratio: 1 / .72; border: 1px solid var(--gp74-line); border-radius: 11px; background: var(--gp74-key);
  color: var(--gp74-key-ink); font-size: 19px; font-weight: 600; cursor: pointer;
  display: grid; place-items: center; font-variant-numeric: tabular-nums;
}
#cdh-inbox-body .dock .key:hover { border-color: var(--gp74-line-strong); }

/* ── action buttons: Call from Browser / Mobile / Text / Decline / Accept /
   Hang up ─────────────────────────────────────────────────────────────────── */
#cdh-inbox-body .dock .call-split { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
#cdh-inbox-body .dock .answer-split { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 4px; }
#cdh-inbox-body .dock .row-text { margin-top: 8px; }
#cdh-inbox-body .dock .btn {
  border: 0; border-radius: 11px; padding: 11px 8px; font-family: inherit;
  font-size: 13px; font-weight: 700; color: #fff; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; line-height: 1.15;
  transition: filter 120ms;
}
#cdh-inbox-body .dock .btn small { font-weight: 600; font-size: 10px; opacity: .85; letter-spacing: .01em; }
#cdh-inbox-body .dock .btn.full { width: 100%; }
#cdh-inbox-body .dock .btn:hover { filter: brightness(1.05); }
#cdh-inbox-body .dock .btn.browser { background: var(--gp74-browser); }
#cdh-inbox-body .dock .btn.mobile  { background: var(--gp74-mobile); }
/* A-264 — ONE green circular Call control (iPhone language) on every dial
   surface — app AND desktop. .row-text.dual carries the desktop's quiet
   "Ring my phone" + Text pills (the app renders Text only). */
#cdh-inbox-body .dock .call-split.single { display: flex; justify-content: center; margin-top: 2px; }
#cdh-inbox-body .dock .btn.dial-go {
  width: 64px; height: 64px; border-radius: 50%; padding: 0; font-size: 0; gap: 0;
  background: #10B981; box-shadow: 0 10px 26px rgba(16,185,129,.35);
}
#cdh-inbox-body .dock .btn.dial-go .ico { width: 25px; height: 25px; }
#cdh-inbox-body .dock .btn.dial-go:hover { filter: brightness(1.07); }
#cdh-inbox-body .dock .btn.dial-go:active { background: #0E9F6E; }
#cdh-inbox-body .dock .row-text { display: flex; justify-content: center; gap: 8px; margin-top: 12px; }
#cdh-inbox-body .dock .row-text .btn.text { width: auto; flex-direction: row; gap: 7px; padding: 9px 20px; border-radius: 999px; }
#cdh-inbox-body .dock .btn.text {
  background: transparent; color: var(--gp74-browser); border: 1px solid var(--gp74-browser);
}
#cdh-inbox-body .dock .btn.accept  { background: var(--gp74-browser); }
#cdh-inbox-body .dock .btn.decline,
#cdh-inbox-body .dock .btn.hangup { background: var(--gp74-danger); }

/* ── incoming card: ring badge + callee identity ──────────────────────────── */
#cdh-inbox-body .dock .ring-badge {
  display: inline-block; font-size: 10.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 999px; color: var(--gp74-accent);
  background: rgba(43,108,176,.16); margin-bottom: 12px;
  animation: gp74-soft 1.6s ease-in-out infinite;
}
@keyframes gp74-soft { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }

/* ── callee identity (incoming + in-call) ─────────────────────────────────── */
#cdh-inbox-body .dock .callee { display: flex; align-items: center; gap: 11px; margin-bottom: 4px; }
#cdh-inbox-body .dock .avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none; display: grid; place-items: center;
  font-weight: 700; font-size: 15px; color: #fff; background: linear-gradient(150deg, var(--gp74-mobile), var(--gp74-accent));
}
#cdh-inbox-body .dock .who { min-width: 0; }
#cdh-inbox-body .dock .nm { font-weight: 700; font-size: 15px; color: var(--gp74-ink); }
#cdh-inbox-body .dock .nn { font-size: 12.5px; color: var(--gp74-ink-faint); font-variant-numeric: tabular-nums; }

/* ── in-call status line + live timer (F3: .js-call-status / .js-call-timer
   are the classed elements 28-twilio.js writes textContent into in place) ─── */
#cdh-inbox-body .dock .status-line { display: flex; align-items: center; gap: 8px; margin: 10px 0 16px; }
#cdh-inbox-body .dock .live-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--gp74-browser); flex: none;
  animation: gp74-live-pulse 1.8s infinite;
}
@keyframes gp74-live-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(15,138,107,.55); }
  70%  { box-shadow: 0 0 0 7px rgba(15,138,107,0); }
  100% { box-shadow: 0 0 0 0 rgba(15,138,107,0); }
}
#cdh-inbox-body .dock .status-txt { font-size: 12.5px; color: var(--gp74-ink-soft); font-weight: 600; }
#cdh-inbox-body .dock .timer { margin-left: auto; font-family: var(--gp74-mono); font-size: 14px; font-weight: 600; color: var(--gp74-ink); font-variant-numeric: tabular-nums; }

/* ── in-call control cluster (F3: .js-call-mute / .js-call-hold live-updated
   in place by twilioMute/twilioHold) ─────────────────────────────────────── */
#cdh-inbox-body .dock .cluster { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
#cdh-inbox-body .dock .ctl {
  border: 1px solid var(--gp74-line); border-radius: 12px; background: var(--gp74-panel-2); color: var(--gp74-ink-soft);
  padding: 10px 4px 8px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; cursor: pointer;
  font-size: 10.5px; font-weight: 600;
}
#cdh-inbox-body .dock .ctl:hover { border-color: var(--gp74-line-strong); }
#cdh-inbox-body .dock .hangup-row { margin-top: 10px; }

@media (prefers-reduced-motion: reduce) {
  #cdh-inbox-body .dock .live-dot,
  #cdh-inbox-body .dock .ring-badge { animation: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   GP-074 W11b — mockup-parity reconciliation (visual gate, ux).
   ADDITIVE ONLY, scoped under #cdh-inbox-body .dock. Closes the CSS-side gaps
   the visual diff found vs UI-CONTRACT-mockup.html:
     • header band (dock-top) + brandmark + per-state badge-src
     • keypad letter sublabels (.key small) + placeholder number (.num.ph)
     • button/control inline-SVG sizing (.btn .ico / .ctl .ico) + active .ctl.on
     • CONTACTS PICKER reconciliation — W11 note flagged these were styled under
       the old `.cdh-dialpad` ancestor (v1) but v2 renders them under `.dock`,
       so none applied. Re-scoped here so the contacts list looks right in v2.
   Rules for elements not yet in the v2 markup (brandmark/badge-src/.key small/
   button icons) are harmless no-ops until that markup lands — see handback.
   ═══════════════════════════════════════════════════════════════════════════ */

/* header band — matches mockup .dock-top (panel-2 fill + bottom rule) */
#cdh-inbox-body .dock .dock-top {
  padding: 12px 0 12px; margin-bottom: 4px; border-bottom: 1px solid var(--gp74-line);
}
#cdh-inbox-body .dock .brandmark {
  width: 26px; height: 26px; border-radius: 7px; flex: none; display: grid; place-items: center;
  color: #fff; background: linear-gradient(150deg, var(--gp74-accent), #7db4ea);
}
#cdh-inbox-body .dock .brandmark .ico { width: 15px; height: 15px; }
#cdh-inbox-body .dock .badge-src {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; background: rgba(15,138,107,.16); color: var(--gp74-browser);
}

/* keypad letter sublabels + placeholder number */
#cdh-inbox-body .dock .key small {
  display: block; font-size: 8.5px; letter-spacing: .12em; color: var(--gp74-ink-faint);
  font-weight: 700; margin-top: 1px;
}
#cdh-inbox-body .dock .num.ph, #cdh-inbox-body .dock .num::placeholder { color: var(--gp74-ink-faint); }

/* inline-SVG icons on action buttons + control cluster */
#cdh-inbox-body .dock .btn .ico { width: 18px; height: 18px; }
#cdh-inbox-body .dock .btn.text .ico { color: var(--gp74-browser); }
#cdh-inbox-body .dock .ctl .ico { width: 19px; height: 19px; }
#cdh-inbox-body .dock .ctl.on {
  background: rgba(43,108,176,.16); border-color: rgba(43,108,176,.45); color: var(--gp74-accent);
}
#cdh-inbox-body .dock .ctl.on .ico { color: var(--gp74-accent); }

/* answer-split spacing to match mockup (16px, not 4px) */
#cdh-inbox-body .dock .answer-split { margin-top: 16px; }

/* ── CONTACTS PICKER (idle) — re-scoped from `.cdh-dialpad` to `.dock` ─────── */
#cdh-inbox-body .dock .cdh-contacts {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--gp74-line);
}
#cdh-inbox-body .dock .cdh-contacts-h {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--gp74-ink-faint); font-weight: 700; margin-bottom: 8px;
}
#cdh-inbox-body .dock .cdh-contact-search {
  width: 100%; padding: 8px 10px; border: 1px solid var(--gp74-line); border-radius: 9px;
  background: var(--gp74-panel-2); font-family: inherit; font-size: 13px; color: var(--gp74-ink);
  margin-bottom: 8px; box-sizing: border-box;
}
#cdh-inbox-body .dock .cdh-contact-list { display: flex; flex-direction: column; gap: 2px; max-height: 240px; overflow-y: auto; }
#cdh-inbox-body .dock .cdh-section-label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--gp74-ink-faint); font-weight: 700; margin: 6px 2px 4px;
}
#cdh-inbox-body .dock .cdh-contact-row {
  display: flex; align-items: center; gap: 10px; padding: 6px; border-radius: 9px; cursor: pointer;
}
#cdh-inbox-body .dock .cdh-contact-row:hover { background: var(--gp74-panel-2); }
#cdh-inbox-body .dock .cdh-contact-av {
  width: 32px; height: 32px; border-radius: 50%; flex: none; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: #fff; background: linear-gradient(150deg, var(--gp74-mobile), var(--gp74-accent));
}
#cdh-inbox-body .dock .cdh-contact-meta { min-width: 0; flex: 1; }
#cdh-inbox-body .dock .cdh-contact-name { font-size: 13px; font-weight: 600; color: var(--gp74-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#cdh-inbox-body .dock .cdh-contact-num { font-size: 11.5px; color: var(--gp74-ink-faint); font-variant-numeric: tabular-nums; }
#cdh-inbox-body .dock .cdh-contact-acts { display: flex; gap: 4px; margin-left: auto; flex: none; }
#cdh-inbox-body .dock .cdh-cact {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--gp74-line);
  background: var(--gp74-panel-2); color: var(--gp74-ink-soft); display: grid; place-items: center; cursor: pointer;
}
#cdh-inbox-body .dock .cdh-cact:hover { border-color: var(--gp74-line-strong); }
#cdh-inbox-body .dock .cdh-cact.call { color: var(--gp74-browser); }
#cdh-inbox-body .dock .cdh-cact .ico { width: 15px; height: 15px; }
#cdh-inbox-body .dock .cdh-contact-empty { font-size: 12.5px; color: var(--gp74-ink-faint); padding: 8px 2px; }

/* ═══ A-289 — comms-dock high-UI shared chrome polish ════════════════════════
   Phoenix: "go through everything clean … super high UI well built." Shared,
   theme-aware chrome fixes applied once across every tab. See the audit spec. */

/* A1 — kill the scrollbar app-wide. Hidden entirely on phone + the dial sheet
   (which never visually scrolls like a real phone); a subtle thin bar remains on
   desktop list/message bodies only (NOT the dial sheet — excluded below). */
.inbox-panel.cd-sheet-dial .ip-body,
.cd-mobile .inbox-panel .ip-body,
.cd-mobile .thread-panel .tp-messages,
.cdh-dialpad .cdh-contact-list,
#cdh-inbox-body .dock .cdh-contact-list,
.cdh-search-results,
.inbox-panel .cd-tx-panel,
.cd-vm-transcript,
.cd-emc-quote { scrollbar-width: none; -ms-overflow-style: none; }
.inbox-panel.cd-sheet-dial .ip-body::-webkit-scrollbar,
.cd-mobile .inbox-panel .ip-body::-webkit-scrollbar,
.cd-mobile .thread-panel .tp-messages::-webkit-scrollbar,
.cdh-dialpad .cdh-contact-list::-webkit-scrollbar,
#cdh-inbox-body .dock .cdh-contact-list::-webkit-scrollbar,
.cdh-search-results::-webkit-scrollbar,
.inbox-panel .cd-tx-panel::-webkit-scrollbar,
.cd-vm-transcript::-webkit-scrollbar,
.cd-emc-quote::-webkit-scrollbar { width: 0; height: 0; display: none; }
/* Desktop: subtle thin bar on the scrolling list/message bodies (dial sheet excluded). */
#comms-dock-root:not(.cd-mobile) .inbox-panel:not(.cd-sheet-dial) .ip-body,
#comms-dock-root:not(.cd-mobile) .thread-panel .tp-messages {
  scrollbar-width: thin; scrollbar-color: rgba(120,113,108,.3) transparent;
}
#comms-dock-root:not(.cd-mobile) .inbox-panel:not(.cd-sheet-dial) .ip-body::-webkit-scrollbar,
#comms-dock-root:not(.cd-mobile) .thread-panel .tp-messages::-webkit-scrollbar { width: 6px; }
#comms-dock-root:not(.cd-mobile) .inbox-panel:not(.cd-sheet-dial) .ip-body::-webkit-scrollbar-thumb,
#comms-dock-root:not(.cd-mobile) .thread-panel .tp-messages::-webkit-scrollbar-thumb { background: rgba(120,113,108,.3); border-radius: 3px; }
/* ID-prefixed so these outrank the desktop thin-bar rules above (which carry
   #comms-dock-root) — otherwise the dark thumb stayed light stone-grey. */
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-dark .ip-body { scrollbar-color: rgba(255,255,255,.26) transparent; }
#comms-dock-root:not(.cd-mobile) .inbox-panel.cd-dark .ip-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,.24); }

/* A2 — header controls (theme toggle / Mark-all-read) legible on the dark dial
   sheet (which uses cd-sheet-dial, never cd-dark). Gated so the LIGHT dial sheet
   keeps its light chrome. */
.inbox-panel.cd-sheet-dial:not(.cd-sheet-light) .ip-theme-toggle { border-color: rgba(255,255,255,.22); color: rgba(255,255,255,.8); }
.inbox-panel.cd-sheet-dial:not(.cd-sheet-light) .ip-theme-toggle:hover { background: rgba(255,255,255,.1); }
.inbox-panel.cd-sheet-dial:not(.cd-sheet-light) .ip-markread { background: none !important; border-color: rgba(255,255,255,.22) !important; color: rgba(255,255,255,.75) !important; }
.inbox-panel.cd-sheet-dial:not(.cd-sheet-light) .ip-markread:hover { background: rgba(255,255,255,.1) !important; }

/* A3 — the 5-tab strip fits on one line at 390–400px. */
.inbox-panel .ip-tabs { gap: 3px; padding: 8px 10px; }
.inbox-panel .ip-tab { padding: 6px 4px; font-size: 10.5px; letter-spacing: -0.01em; white-space: nowrap; min-width: 0; gap: 4px; }
.inbox-panel .ip-tab-c { padding: 1px 4px; font-size: 8.5px; }

/* A4 — admin scope <select> chevron visible on dark. */
.inbox-panel.cd-dark #cdh-scope-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important; background-position: right 9px center !important; padding-right: 28px !important;
}

/* A5 — phone touch targets ≥ iOS minimum. */
.cd-mobile .inbox-panel .ip-close { width: 36px; height: 36px; font-size: 20px; }
.cd-mobile .comms-dock-mini { width: 44px; height: 44px; }
.cd-mobile .comms-dock-mini .ico { width: 20px; height: 20px; }
.cd-mobile .comms-dock-collapse { width: 34px; height: 34px; }
.cd-mobile .comms-dock-collapse .ico { width: 16px; height: 16px; }

/* A7 — header spacing + title truncation (no clipped/overflowing title). */
.inbox-panel .ip-h-r .ip-theme-toggle { margin-right: 0; }
.inbox-panel .ip-h-r .ip-markread { margin-right: 0 !important; }
.inbox-panel .ip-h-l { flex: 1; min-width: 0; }
.inbox-panel .ip-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* A10 — dark native-phone status line contrast. */
.inbox-panel.cd-dark .cd-phone-status,
.inbox-panel.cd-sheet-dial:not(.cd-sheet-light) .cd-phone-status { color: rgba(255,255,255,.55) !important; }

/* ═══ A-290 — comms-dock list-surface high-UI polish ═════════════════════════
   Phoenix: "each text call voicemail super high UI well built." Avatars, row
   separators, unread accents + the dark-mode email empty/urgency backgrounds. */

/* A8 — shared avatar system. Named → colour-hashed monogram; number-only/unknown
   → neutral person silhouette (kills the "+4" gibberish from _ipAvatar). */
.inbox-panel .ip-av-named {
  background: linear-gradient(135deg, hsl(var(--av-h) 62% 52%), hsl(calc(var(--av-h) + 24) 58% 42%));
  color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,.18);
}
/* Re-assert the gradient under cd-dark: the generic `.cd-dark .ip-av`
   (specificity 0,3,0) would otherwise reset our 0,2,0 gradient to flat grey,
   killing the colour-hash on the dark phone tabs where it matters most. */
.inbox-panel.cd-dark .ip-av-named {
  background: linear-gradient(135deg, hsl(var(--av-h) 62% 52%), hsl(calc(var(--av-h) + 24) 58% 42%));
  text-shadow: 0 1px 2px rgba(0,0,0,.35);
}
.inbox-panel .ip-av-anon { color: var(--cdh-s500); }
.inbox-panel .ip-av-anon .ico { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.inbox-panel.cd-dark .ip-av-anon { background: rgba(255,255,255,.10); color: rgba(255,255,255,.62); }

/* B1.5 — inset iOS hairline separators (avatar-aligned) instead of full-width
   borders; last row none. ::after only, so the failed/unread ::before rails are
   untouched. */
.inbox-panel .ip-row { position: relative; border-bottom: none; }
.inbox-panel .ip-row::after { content: ''; position: absolute; left: 61px; right: 0; bottom: 0; height: 1px; background: var(--cdh-s200); }
.inbox-panel .ip-row:last-child::after { display: none; }
.inbox-panel.cd-dark .ip-row::after { background: rgba(255,255,255,.09); }

/* B1.6 — dark unread rail visible (green). */
.inbox-panel.cd-dark .ip-row.unread::before { background: #34D399; }

/* B1.7 / B3.4 — missed call name reads red in light. */
.inbox-panel .ip-row.missed .ip-name { color: var(--cdh-missed); }

/* B1.10 — perceptible light hover/active on rows. */
.inbox-panel .ip-row:hover { background: var(--cdh-s100); }
.inbox-panel .ip-row:active { background: var(--cdh-s200); }

/* B2.7 — unread SMS time accent. */
.inbox-panel .ip-row.sms-row.unread .ip-time { color: var(--cdh-q-hot); font-weight: 800; }
.inbox-panel.cd-dark .ip-row.sms-row.unread .ip-time { color: #34D399; }

/* A9 — empty-state typography (both themes). */
.inbox-panel .ip-empty { padding: 44px 24px; max-width: 320px; margin: 0 auto; }
.inbox-panel .ip-empty-sub { max-width: 260px; margin-left: auto; margin-right: auto; }

/* A-290 — the Email TAB now joins the dark list tabs on phone (was a jarring
   white panel in dark mode). Its "Inbox not available" heading uses dark ink →
   flip it light under cd-dark. */
.inbox-panel.cd-dark .cd-email-empty-t { color: #fff; }

/* B5.1 — EMAIL deck: dark unread/urgency backgrounds (were hard-coded light hex,
   illegible on the dark deck). The email empty state also inherits the dark deck. */
.cd-email-deck.sc-dark .sc-row.unread { background: rgba(250,204,21,.14); }
.cd-email-deck.sc-dark .sc-row[data-urgency="yellow"] { background: rgba(217,119,6,.16); }
.cd-email-deck.sc-dark .sc-row[data-urgency="red"],
.cd-email-deck.sc-dark .sc-row[data-urgency="intense"] { background: rgba(220,38,38,.16); }

/* B5.4 — honour reduced-motion (a11y + the repo's render-budget mandate): stop
   the email deck's infinite urgency pulses. */
@media (prefers-reduced-motion: reduce) {
  .cd-email-deck [class*="cdEm"], .cd-email-deck [class*="cdUrg"],
  .cd-email-deck .sc-row[data-urgency] { animation: none !important; }
}

/* ─────────────────────────────────────────────────────────────────────────
   A-314 — touch: kill "sticky hover" MOVEMENT (Phoenix, on the phone:
   "commsdeck buttons fly around, all over the place").
   Mobile browsers EMULATE :hover and leave it applied after a tap until you
   tap somewhere else, so every hover rule that MOVES an element (transform /
   offset) leaves the tapped bubble/button displaced — tap a few and several
   bubbles are stuck out of position + the tooltip flaps open: exactly the
   "flying around" look. Desktop mouse (hover:hover / pointer:fine) is
   untouched and keeps the lift; this only neutralises hover-MOVEMENT on
   coarse / no-hover pointers. Colour / background / filter hovers are left
   alone — a brief tint isn't motion, so it never reads as "flying". */
@media (hover: none), (pointer: coarse) {
  .comms-dock .bubble:hover,
  .comms-dock .dock-identity:hover,
  .comms-dock-mini:hover,
  .comms-dock-collapse:hover,
  .spartan-dialpad .spk-action:hover,
  .cdh-dialpad .cdh-cact:hover,
  .cd-connect-gmail:hover {
    transform: none !important;
  }
  /* the tooltip only makes sense on a real hover — never slide it out on touch */
  .comms-dock .bubble:hover .bubble-tooltip { opacity: 0 !important; right: 64px !important; }
}

/* ═══ GP-168 — staff + installer directory: row affordances + contact card ═══
   The scroller now shows ONE ROW PER PERSON carrying N numbers, so a row needs
   to say "there are more" (+N) and, for the 24 installers and 3 staff who have
   no number at all today, say so out loud with a way to fix it. Those
   number-less rows are deliberate: they are how the roster fills itself in. */

/* "+2" chip beside the primary number. */
.cdh-dialpad .cdh-num-more {
  display: inline-block; margin-left: 6px; padding: 0 5px;
  border-radius: 999px; background: #E7E5E4; color: #57534E;
  font-size: 9.5px; font-weight: 800; line-height: 14px; vertical-align: 1px;
}
.cdh-dialpad .cdh-num-none { color: #A8A29E; font-style: italic; }

/* Dark surfaces: the in-dock sheet on mobile, and the full-screen search. */
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-num-more,
.cdh-search-overlay.cd-dark .cdh-num-more { background: rgba(255,255,255,.14); color: rgba(255,255,255,.75); }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-num-none,
.cdh-search-overlay.cd-dark .cdh-num-none { color: rgba(255,255,255,.42); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-num-more { background: rgba(0,0,0,.08); color: rgba(0,0,0,.6); }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-num-none { color: rgba(0,0,0,.42); }

/* ── The card itself ──────────────────────────────────────────────────────
   z-index sits ABOVE .cdh-search-overlay (100000): the card is opened FROM the
   full-screen search on mobile, so it must land on top of it rather than
   behind. Bottom sheet on a phone, centred panel on desktop. */
.cdh-card-overlay {
  position: fixed; inset: 0; z-index: 100010;
  background: rgba(12,10,9,.55);
  display: flex; align-items: flex-end; justify-content: center;
}
.cdh-card-sheet {
  width: 100%; max-width: 460px; max-height: 88vh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: #fff; color: #1C1917;
  border-radius: 18px 18px 0 0;
  padding: 16px 16px calc(20px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 40px rgba(0,0,0,.28);
}
@media (min-width: 768px) {
  .cdh-card-overlay { align-items: center; }
  .cdh-card-sheet { border-radius: 18px; padding-bottom: 20px; }
}

.cdh-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.cdh-card-av { width: 44px; height: 44px; font-size: 15px; }
.cdh-card-id { flex: 1; min-width: 0; }
.cdh-card-name { font-size: 17px; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cdh-card-sub { font-size: 12px; color: #78716C; text-transform: capitalize; }

.cdh-card-nums { display: flex; flex-direction: column; gap: 6px; }
.cdh-card-empty {
  padding: 14px; border-radius: 12px; background: #FAFAF9;
  border: 1px dashed #E7E5E4; color: #78716C; font-size: 13px; text-align: center;
}
.cdh-card-num {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 12px; background: #FAFAF9; border: 1px solid #F0F0EF;
}
.cdh-card-num.is-primary { border-color: #D6D3D1; background: #fff; }
.cdh-card-num-meta { flex: 1; min-width: 0; }
.cdh-card-label { font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: #78716C; }
.cdh-card-primary {
  margin-left: 6px; padding: 0 6px; border-radius: 999px;
  background: #1C1917; color: #fff; font-size: 9px; font-weight: 800; line-height: 14px;
  text-transform: uppercase; letter-spacing: .04em;
}
.cdh-card-numval { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.cdh-card-badnum { font-size: 11px; color: #B45309; font-weight: 700; }
.cdh-card-acts { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
.cdh-card-acts .cdh-cact {
  width: 34px; height: 34px; border-radius: 9px; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center; color: #fff;
}
.cdh-card-acts .cdh-cact.call { background: #facc15; color: #000; }
.cdh-card-acts .cdh-cact.text { background: #15803D; }
.cdh-card-acts .cdh-cact .ico { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; }
.cdh-card-del {
  width: 28px; height: 28px; border-radius: 8px; border: none; cursor: pointer;
  background: transparent; color: #A8A29E; font-size: 20px; line-height: 1;
}
.cdh-card-del:hover { background: #FEE2E2; color: #B91C1C; }

.cdh-card-add { margin-top: 16px; padding-top: 14px; border-top: 1px solid #F0F0EF; }
.cdh-card-add-h { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: #78716C; margin-bottom: 8px; }
.cdh-card-add-row { display: flex; gap: 8px; }
.cdh-card-in {
  box-sizing: border-box; min-width: 0;
  font-size: 16px; /* >=16px stops iOS auto-zoom on focus */
  font-family: inherit; color: #1C1917;
  padding: 10px 12px; border: 1px solid #E7E5E4; border-radius: 10px; background: #FAFAF9;
}
.cdh-card-in.label { flex: 0 1 38%; }
.cdh-card-in.num { flex: 1 1 auto; }
.cdh-card-in:focus { outline: none; border-color: #0A0A0A; background: #fff; box-shadow: 0 0 0 3px rgba(10,10,10,.05); }
.cdh-card-save {
  flex-shrink: 0; padding: 10px 16px; border: none; border-radius: 10px; cursor: pointer;
  background: #0A0A0A; color: #fff; font-size: 13px; font-weight: 800; font-family: inherit;
}
.cdh-card-save:disabled { opacity: .55; cursor: default; }
.cdh-card-err:empty { display: none; }
.cdh-card-err { margin-top: 8px; font-size: 12px; font-weight: 700; color: #B91C1C; }

/* Dark card — matches the A-277 comms-desk language. */
.cdh-card-overlay.cd-dark .cdh-card-sheet { background: #1C1917; color: #fff; }
.cdh-card-overlay.cd-dark .cdh-card-sub { color: rgba(255,255,255,.5); }
.cdh-card-overlay.cd-dark .cdh-card-av { background: rgba(255,255,255,.12); color: rgba(255,255,255,.92); }
.cdh-card-overlay.cd-dark .cdh-card-num { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.08); }
.cdh-card-overlay.cd-dark .cdh-card-num.is-primary { background: rgba(255,255,255,.09); border-color: rgba(255,255,255,.2); }
.cdh-card-overlay.cd-dark .cdh-card-empty { background: rgba(255,255,255,.04); border-color: rgba(255,255,255,.14); color: rgba(255,255,255,.55); }
.cdh-card-overlay.cd-dark .cdh-card-label { color: rgba(255,255,255,.5); }
.cdh-card-overlay.cd-dark .cdh-card-primary { background: #fff; color: #1C1917; }
.cdh-card-overlay.cd-dark .cdh-card-badnum { color: #FCD34D; }
.cdh-card-overlay.cd-dark .cdh-card-del:hover { background: rgba(185,28,28,.28); color: #FCA5A5; }
.cdh-card-overlay.cd-dark .cdh-card-add { border-top-color: rgba(255,255,255,.1); }
.cdh-card-overlay.cd-dark .cdh-card-add-h { color: rgba(255,255,255,.5); }
.cdh-card-overlay.cd-dark .cdh-card-in {
  background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.18); color: #fff;
}
.cdh-card-overlay.cd-dark .cdh-card-in::placeholder { color: rgba(255,255,255,.4); }
.cdh-card-overlay.cd-dark .cdh-card-in:focus { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.4); box-shadow: none; }
.cdh-card-overlay.cd-dark .cdh-card-save { background: #fff; color: #0A0A0A; }
.cdh-card-overlay.cd-dark .cdh-search-close { background: rgba(255,255,255,.1); color: #fff; }
.cdh-card-overlay.cd-dark .cdh-card-err { color: #FCA5A5; }
.cdh-dialpad .cdh-cact.card { background: #E7E5E4; color: #44403C; font-size: 15px; font-weight: 800; line-height: 1; }
.inbox-panel.cd-sheet-dial #cdh-inbox-body .dock .cdh-cact.card,
.cdh-search-overlay.cd-dark .cdh-cact.card { background: rgba(255,255,255,.14); color: #fff; }
.inbox-panel.cd-sheet-dial.cd-sheet-light #cdh-inbox-body .dock .cdh-cact.card { background: rgba(0,0,0,.08); color: rgba(0,0,0,.7); }
