﻿/* ─── Shell layout (left rail + 3-panel) ───────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

/* Visibility helper used by the rail popovers, language switcher, and modals.
   Defined here (in the foundational dashboard CSS) so every page that mounts
   the rail gets it without needing to load Bootstrap. */
.d-none { display: none !important; }

body.inbox-shell {
    margin: 0;
    height: 100dvh;
    display: flex;
    background: var(--bg-page);
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    font-size: 14px;
    color: var(--text);
    overflow: hidden;
}

/* ─── LEFT RAIL — labeled, parchment, sage active pill ─────────────── */
/* The expanded/collapsed presentation is driven by the variables below rather
   than by duplicated rule blocks. Two things collapse the rail — the user's
   toggle and any viewport too narrow to spend 224px on navigation — and when
   those were written as separate rule sets they drifted: the phone breakpoint
   set only `width: 56px` and left the wordmark and labels rendering, which
   squeezed the labels to zero width and pushed the icons 8px off-centre in a
   strip too narrow to hold them. Collapsing is now four variables, so a new
   trigger only has to restate the state, never the styling. */
.rail {
    --rail-w:            224px;
    --rail-pad-x:        14px;
    --rail-text:         inline;      /* wordmark, labels, language code */
    --rail-row:          flex;        /* the workspace pill (a flex row) */
    --rail-brand:        inline-flex;
    --rail-head-justify: space-between;
    --rail-link-justify: flex-start;
    --rail-link-gap:     12px;
    --rail-link-pad-x:   12px;
    --rail-toggle-rot:   0deg;

    width: var(--rail-w);
    flex-shrink: 0;
    background: var(--bg-page);
    border-right: 1px solid var(--border-soft);
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 18px var(--rail-pad-x) 14px;
    gap: 4px;
}

.rail-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 4px 10px;
    margin-bottom: 22px;
    text-decoration: none;
    color: var(--text);
    font-family: 'Fraunces', 'Times New Roman', serif;
    font-weight: 600;
    font-size: 22px;
    letter-spacing: -0.01em;
}

/* The wordmark carries the whole lockup, so it is sized by height and the width
   follows whatever aspect the export has. See wwwroot/img/README.md. */
.rail-brand-logo {
    display: block;
    height: 32px;
    width: auto;
    flex-shrink: 0;
}
.rail-brand-text { line-height: 1; }

.rail-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    width: 100%;
    align-items: stretch;
    /* Brand (above) and rail-bottom (Profile/Sign out) stay pinned; only the links scroll
       when they exceed the height (e.g. short screens / many nav items). min-height:0 is
       required for a flex child to become scrollable. */
    min-height: 0;
    overflow-y: auto;
    overflow-x: visible;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
/* The nav scrolls when the links don't fit, but on touch there is no visible
   scrollbar to say so — the list simply appeared to stop, and the items past
   the cut (Templates, AI Agents, Settings) read as missing rather than below.
   Raising the touch targets to 44px made that overflow worse, so the cut has
   to announce itself.
   The fade is unconditional and that is what makes it safe: .rail-nav is a
   flex:1 child, so when the links fit, the faded 22px sit over empty space and
   nothing is visible; it only lands on content when there IS content below,
   which is exactly when the hint is wanted. No JS, no scroll-position tracking,
   nothing to get out of sync.

   Painted as a sticky pseudo-element rather than a mask on .rail-nav. A mask
   clips everything inside the element, and the settings popover is a
   position:fixed child of this scroller — masking the nav made the popover
   invisible and un-hittable. A sticky ::after draws the same fade over the
   content and clips nothing. Negative margin so it overlays the last row
   instead of adding height. */
.rail-nav::after {
    content: '';
    position: sticky;
    bottom: 0;
    flex: none;
    height: 22px;
    margin-top: -22px;
    pointer-events: none;
    background: linear-gradient(to bottom, transparent, var(--bg-page));
}
/* A visible scrollbar already says "more below", so drop the fade where one is
   drawn and keep the last item at full contrast. */
@media (hover: hover) and (pointer: fine) {
    .rail-nav::after { display: none; }
}

/* Short viewports — a landscape phone, mostly. Keeping the brand row and the
   Profile/Sign-out block pinned costs ~290px of a 360px screen and leaves the
   nav 67px: one and a half items visible, with ten more behind a scroll nobody
   would guess is there. Below this height the rail scrolls as ONE column
   instead, so every item is reachable by the same gesture. */
@media (max-height: 480px) {
    .rail { overflow-y: auto; overscroll-behavior: contain; }
    .rail-nav { overflow-y: visible; flex: 0 0 auto; min-height: auto; }
    .rail-nav::after { display: none; }   /* nothing is clipped now */
    .rail-bottom { padding-top: 6px; }
}

.rail-nav::-webkit-scrollbar { width: 6px; }
.rail-nav::-webkit-scrollbar-track { background: transparent; }
.rail-nav::-webkit-scrollbar-thumb { background: var(--border); border-radius: 6px; }
.rail-nav::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }

.rail-bottom {
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: stretch;
    padding-top: 8px;
    border-top: 1px solid var(--border-soft);
}

.rail-link {
    width: 100%;
    height: auto;
    min-height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    padding: 8px 12px;
    border-radius: 12px;
    color: var(--text-muted);
    text-decoration: none;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    text-align: left;
}

.rail-link .icon,
.rail-link svg { flex-shrink: 0; }

.rail-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.2;
}

.rail-link:hover {
    background: var(--bg-muted);
    color: var(--text);
}

.rail-link.active {
    background: #e3ecd9;
    color: var(--brand);
    font-weight: 600;
    box-shadow: inset 0 0 0 1px rgba(170, 187, 164, 0.45);
}

.rail-link.active .icon,
.rail-link.active svg { color: var(--brand); }

/* ─── Collapsible rail ─────────────────────────────────────────────── */
.rail-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 18px;
}
.rail-head .rail-brand { margin-bottom: 0; } /* spacing now lives on .rail-head */

.rail-toggle {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--bg-panel);
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.rail-toggle:hover { background: var(--bg-muted); color: var(--text); }
.rail-toggle .icon { transition: transform var(--spring-bounce-ms) var(--spring-bounce); }

/* ── The collapsed state: four variables, no restated styling ─────── */
.rail.rail-collapsed {
    --rail-w:            64px;
    --rail-pad-x:        8px;
    --rail-text:         none;
    --rail-row:          none;
    --rail-brand:        none;   /* hide the wordmark, centre the expand toggle */
    --rail-head-justify: center;
    --rail-link-justify: center;
    --rail-link-gap:     0;
    --rail-link-pad-x:   0;
    --rail-toggle-rot:   180deg;
}

/* ── Where those variables are actually consumed ──────────────────── */
.rail-brand-text,
.rail-label,
.lang-code,
.lang-chevron          { display: var(--rail-text); }

/* Workspace pill — moved off a style attribute so the collapsed rail can
   actually hide it (an inline `display` beats every stylesheet rule). */
.rail-org {
    display: var(--rail-row);
    align-items: center;
    gap: 6px;
    /* No horizontal inset: the refer CTA directly below and the nav links below that both run to
       the rail's own padding, and 10px of extra margin here left the pill visibly narrower than
       the thing stacked under it. Bottom margin is tight so pill + CTA read as one group. */
    margin: 0 0 8px;
    padding: 5px 9px;
    border-radius: 8px;
    background: rgba(124, 58, 237, .08);
    border: 1px solid rgba(124, 58, 237, .18);
}
.rail-org-tag {
    font-size: 9px; font-weight: 700; letter-spacing: .5px;
    color: #7c3aed; background: rgba(124, 58, 237, .14);
    padding: 1px 5px; border-radius: 4px; flex: 0 0 auto;
}
.rail-org-name {
    font-size: 12px; font-weight: 600; color: #5b21b6;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Refer & earn CTA — holds the workspace pill's slot ──────────────
   The one thing in this rail that pays the user, competing with a nav
   list they already know by heart. So it is the only gradient here and
   the only thing that moves. Sized off the same --rail-link-* variables
   as a nav link, which is what lets it shrink to a centred icon in the
   64px strip instead of vanishing the way the pill does. */
.rail-refer {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: var(--rail-link-justify);
    gap: var(--rail-link-gap);
    padding: 10px var(--rail-link-pad-x);
    margin-bottom: 12px;
    border-radius: 11px;
    text-decoration: none;
    background: linear-gradient(118deg, #6d3be0 0%, #8b5cf6 42%, #15895d 100%);
    box-shadow: 0 7px 20px -9px rgba(109, 59, 224, .8);
    transition: transform .16s ease, box-shadow .16s ease;
}
.rail-refer:hover {
    transform: translateY(-1px);
    box-shadow: 0 11px 26px -9px rgba(109, 59, 224, .95);
}
.rail-refer:active { transform: translateY(0); }

/* The sweep. Long pause, short pass — a glance, not a disco. Driven by
   transform so it stays on the compositor and never lays anything out. */
.rail-refer::after {
    content: "";
    position: absolute;
    top: -60%;
    bottom: -60%;
    left: 0;
    width: 38%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .42), transparent);
    transform: translateX(-160%) skewX(-18deg);
    animation: railReferSweep 4.6s ease-in-out infinite;
    pointer-events: none;
}
@keyframes railReferSweep {
    0%, 62%   { transform: translateX(-160%) skewX(-18deg); }
    88%, 100% { transform: translateX(420%) skewX(-18deg); }
}

.rail-refer-ic {
    flex: 0 0 auto;
    display: inline-flex;
    color: #fff;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .25));
    animation: railReferNudge 4.6s ease-in-out infinite;
}
@keyframes railReferNudge {
    0%, 55%, 100% { transform: scale(1) rotate(0deg); }
    63%           { transform: scale(1.16) rotate(-9deg); }
    71%           { transform: scale(1.16) rotate(9deg); }
    79%           { transform: scale(1) rotate(0deg); }
}

/* Rides --rail-row (the pill's own flex-or-hidden switch) so the collapsed
   rail and the phone breakpoint drop the wording without a new variable. */
.rail-refer-txt {
    display: var(--rail-row);
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.rail-refer-title {
    font-size: 12.5px; font-weight: 800; color: #fff;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rail-refer-sub {
    font-size: 10.5px; font-weight: 700; color: rgba(255, 255, 255, .86);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Reduced motion: keep the colour and the hover lift, drop the loops. */
@media (prefers-reduced-motion: reduce) {
    .rail-refer::after { display: none; }
    .rail-refer-ic { animation: none; }
}
.rail .rail-brand      { display: var(--rail-brand); }
.rail .rail-head       { justify-content: var(--rail-head-justify); }
.rail .rail-toggle .icon { transform: rotate(var(--rail-toggle-rot)); }

.rail .rail-link,
.rail .lang-switcher-btn {
    justify-content: var(--rail-link-justify);
    gap: var(--rail-link-gap);
    padding-left: var(--rail-link-pad-x);
    padding-right: var(--rail-link-pad-x);
}

/* ─── 3-PANEL LAYOUT ───────────────────────────────────────────────── */
.inbox-layout {
    flex: 1;
    display: flex;
    overflow: hidden;
    background: var(--bg-page);
}

/* ─── PANEL 1: Sidebar ─────────────────────────────────────────────── */
.inbox-sidebar {
    width: 320px;
    min-width: 280px;
    background: var(--bg-panel);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    flex-shrink: 0;
    transition: width 0.18s ease;
}

/* When the contact panel is open on desktop (in-flow, toggled via d-none), hand space
   back to the conversation so the chat column stays comfortable. Below 1100px the panel
   overlays instead, so this only bites where it should. Graceful where :has() is absent. */
body.inbox-shell:has(.contact-panel:not(.d-none)) .inbox-sidebar { width: 280px; }

.inbox-header {
    padding: 16px 16px 0;
    flex-shrink: 0;
}

.inbox-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
    position: relative;
}

.inbox-title {
    font-size: 20px;
    font-weight: 700;
    margin: 0;
    color: var(--text);
    letter-spacing: -0.2px;
}

.instance-pick-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px 5px 8px;
    background: var(--bg-muted);
    border: 1px solid transparent;
    border-radius: 14px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
    max-width: 55%;
    overflow: hidden;
}

.instance-pick-btn:hover {
    background: var(--bg-soft);
    border-color: var(--border);
    color: var(--text);
}

.instance-pick-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Inbox filter tabs */
.inbox-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 0;
    border-bottom: 1px solid var(--border-soft);
    position: relative;
    margin-left: -16px;
    margin-right: -16px;
    padding: 0 16px;
    /* Safety net for longer localized tab labels: scroll rather than overflow
       the sidebar (mirrors .cp-tabs). English labels still fit without scroll. */
    overflow-x: auto;
    scrollbar-width: none;
}
.inbox-tabs::-webkit-scrollbar { display: none; }

.inbox-tab {
    flex: 1;
    padding: 9px 6px 11px;
    text-align: center;
    text-decoration: none;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-muted);
    border-bottom: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-bottom: -1px;
}

.inbox-tab:hover { color: var(--text); }
.inbox-tab.active {
    color: var(--brand);
    border-bottom-color: var(--brand);
    font-weight: 600;
}

.tab-count {
    font-size: 10.5px;
    background: var(--bg-muted);
    color: var(--text-muted);
    padding: 1px 7px;
    border-radius: 9px;
    font-weight: 600;
    min-width: 18px;
    text-align: center;
    line-height: 1.5;
}

.inbox-tab.active .tab-count {
    background: var(--brand-100);
    color: var(--brand-text);
}

.sidebar-search {
    position: relative;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-soft);
}

.sidebar-search-input {
    width: 100%;
    padding: 7px 12px 7px 32px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-soft);
    font-size: 13px;
    outline: none;
    color: var(--text);
    transition: background 0.15s, border-color 0.15s;
}

.sidebar-search-input:focus {
    background: var(--bg-panel);
    border-color: var(--brand-200);
    box-shadow: 0 0 0 3px var(--brand-ring);
}

.sidebar-search-input::placeholder { color: var(--text-dim); }

.search-icon {
    left: 10px;
    width: 14px;
    height: 14px;
}

.search-icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: #9ca3af;
}

/* Conversation rows — denser, with channel pills */
.conversation-list {
    flex: 1;
    overflow-y: auto;
    padding: 4px 0;
}

.conv-item {
    display: flex;
    gap: 10px;
    padding: 10px 14px;
    cursor: pointer;
    transition: background 0.12s;
    border-bottom: 1px solid #f5f5f5;
    user-select: none;
}

.conv-item:hover { background: var(--bg-soft); }
.conv-item.active { background: var(--bg-soft); border-left: 3px solid var(--brand); padding-left: 11px; }

.conv-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, #6f8a64, #4a5d47);
    color: #f6f1e3;
    font-weight: 600;
    font-size: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
}

.conv-avatar img { width: 100%; height: 100%; object-fit: cover; }

.conv-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }

.conv-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px;
}

.conv-name {
    font-weight: 600;
    font-size: 14px;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.conv-time {
    font-size: 11px;
    color: var(--text-dim);
    flex-shrink: 0;
}

.conv-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}

.conv-preview {
    font-size: 12.5px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

/* Unsent text waiting in a conversation takes the preview line over from the last
   message, so a chat left mid-sentence is obvious from the list. Colour is set on the
   tag itself, which keeps it readable inside .conv-item.is-closed (that rule only
   dims the inherited colour). */
.conv-draft-tag {
    color: var(--danger);
    font-weight: 600;
    margin-right: 3px;
}

.unread-badge {
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    background: var(--brand);
    color: #f6f1e3;
    font-size: 10.5px;
    font-weight: 700;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.conv-meta {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    margin-top: 2px;
}

.channel-pill, .assignee-pill {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 1px 7px;
    border-radius: 8px;
    font-size: 10.5px;
    font-weight: 500;
    line-height: 1.4;
    background: var(--brand-50);
    color: var(--brand-text);
    max-width: 130px;
}

.channel-pill span,
.assignee-pill span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.assignee-pill {
    background: var(--bg-muted);
    color: var(--text);
}

.empty-sidebar {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 50px 20px;
    text-align: center;
    color: var(--text-dim);
}

.empty-sidebar p { font-size: 14px; font-weight: 600; color: var(--text-muted); margin: 6px 0 0; }
.empty-sidebar span { font-size: 12px; }

/* ─── PANEL 2: Chat main ──────────────────────────────────────────── */
.chat-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--bg-page);
    min-width: 0;
}

.chat-empty {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.chat-empty-inner {
    text-align: center;
    color: var(--text-dim);
}

.chat-empty-inner h3 { font-size: 18px; font-weight: 600; color: var(--text-muted); margin-top: 10px; }
.chat-empty-inner p { font-size: 13px; margin: 4px 0 0; }

.chat-window {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--bg-page);
}

.chat-header {
    display: flex;
    align-items: center;
    gap: 12px;
    row-gap: 8px;
    flex-wrap: wrap;              /* narrow chat column (e.g. contact panel open) → actions drop to a 2nd row */
    padding: 10px 16px;
    background: var(--bg-panel);
    border-bottom: 1px solid var(--border);
}

/* Contact target (avatar + name) — shrinks and truncates instead of forcing the header wider. */
.chat-header-target {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 200px;
    min-width: 0;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    text-align: start;
    color: inherit;
    font: inherit;
}

.chat-header-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: linear-gradient(135deg, #6f8a64, #4a5d47);
    color: #f6f1e3;
    font-weight: 700;
    font-size: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.chat-header-info { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.chat-header-info strong { font-size: 14px; color: var(--text); }
.chat-header-info span  { font-size: 12px; color: var(--text-muted); }
/* Name + phone truncate with an ellipsis rather than wrapping to several lines when the column narrows. */
#chatHeaderName, #chatHeaderPhone { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.chat-header-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    margin-left: auto;           /* keep actions right-aligned; they wrap as a block when space is tight */
}

/* Long owner names/emails must not blow up the header width. */
#assignLabel {
    display: inline-block;
    max-width: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.header-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 12.5px;
    color: var(--text);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.header-btn:hover { background: var(--bg-soft); border-color: var(--text-muted); }
.header-btn-icon { padding: 7px; border-radius: 8px; }

.status-pill-mini {
    background: var(--brand-100);
    color: var(--brand-text);
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.status-pill-mini.snoozed { background: var(--warn-bg); color: var(--warn-text); }
.status-pill-mini.closed  { background: var(--danger-bg); color: var(--danger-text); }

/* Dropdowns (assign / status) */
.dropdown-wrap { position: relative; }

.cm-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 4px);
    min-width: 180px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(31, 41, 28, 0.12);
    z-index: 50;
    padding: 4px;
    max-height: 300px;
    overflow-y: auto;
}

.cm-item {
    width: 100%;
    text-align: left;
    padding: 7px 10px;
    background: transparent;
    border: none;
    border-radius: 8px;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    transition: background 0.12s;
}

.cm-item:hover { background: var(--bg-muted); }

/* Unified assignee dropdown: AI agents section under the team members. */
.cm-sep { height: 1px; background: var(--border-soft); margin: 5px 4px; }
.cm-label {
    padding: 5px 10px 3px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-dim);
}
.cm-item-agent { display: flex; align-items: center; gap: 8px; }
.cm-agent-ava {
    width: 20px; height: 20px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-50); font-size: 12px; overflow: hidden; flex-shrink: 0;
}
.cm-agent-ava img { width: 100%; height: 100%; object-fit: cover; }

/* Compose mode bar */
.compose-mode-bar {
    display: flex;
    background: var(--bg-soft);
    border-bottom: 1px solid var(--border);
    padding: 4px 12px;
    gap: 4px;
}

.compose-mode-btn {
    padding: 6px 12px;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    font-size: 12.5px;
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-bottom: -1px;
}

.compose-mode-btn.active { color: var(--text); border-bottom-color: var(--brand); font-weight: 600; }
.compose-mode-btn[data-mode="note"].active { border-bottom-color: var(--warn); }

.chat-input-bar.note-mode { background: var(--warn-bg); }
.chat-input-bar.note-mode .chat-input { background: var(--bg-panel); border-color: rgba(200, 169, 106, 0.45); }
.chat-input-bar.note-mode .send-btn { background: var(--warn); }
.chat-input-bar.note-mode .send-btn:hover { background: #a78344; }
/* Recording an INTERNAL voice note — the recorder wears the same gold as the note composer. */
.chat-input-bar.note-mode .voice-recorder { background: var(--bg-panel); border-color: rgba(200, 169, 106, 0.45); }
.chat-input-bar.note-mode .vr-send { background: var(--warn); }
.chat-input-bar.note-mode .vr-send:hover { background: #a78344; }

/* Messages feed */
.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.msg {
    display: flex;
    flex-direction: column;
    max-width: 65%;
    animation: fadeUp 0.18s ease;
}

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

.msg.incoming { align-self: flex-start; }
.msg.outgoing { align-self: flex-end; }
.msg.note     { align-self: center; max-width: 80%; }

.msg-bubble {
    padding: 8px 12px;
    border-radius: 8px;
    font-size: 14px;
    line-height: 1.5;
    word-break: break-word;
}

.msg.incoming .msg-bubble {
    background: var(--bubble-incoming);
    border: 1px solid var(--border-soft);
    border-top-left-radius: 4px;
    box-shadow: 0 1px 1px rgba(31, 41, 28, 0.04);
}

.msg.outgoing .msg-bubble {
    background: var(--bubble-outgoing);
    border-top-right-radius: 4px;
    box-shadow: 0 1px 1px rgba(31, 41, 28, 0.05);
}

.msg.note .msg-bubble {
    background: var(--bubble-note);
    border: 1px solid rgba(200, 169, 106, 0.45);
    color: var(--warn-text);
    font-size: 13px;
    font-style: italic;
    box-shadow: none;
}

.msg.note .msg-author {
    font-size: 11px;
    color: var(--warn-text);
    font-style: normal;
    font-weight: 600;
    margin-bottom: 2px;
    display: flex;
    align-items: center;
    gap: 4px;
}

.msg-meta {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
    font-size: 11px;
    color: var(--text-dim);
}

.msg.incoming .msg-meta { padding-left: 4px; }
.msg.outgoing .msg-meta { align-self: flex-end; padding-right: 4px; }
.msg.note .msg-meta { align-self: center; }

.messages-loading {
    display: flex;
    justify-content: center;
    padding: 40px;
}

.spinner {
    width: 26px;
    height: 26px;
    border: 3px solid var(--border-soft);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* Compose input */
.chat-input-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--bg-panel);
    border-top: 1px solid var(--border);
}

.chat-input {
    flex: 1;
    min-width: 0;   /* inputs have an intrinsic min-width — this lets the composer shrink on mobile */
    padding: 11px 16px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-soft);
    font-size: 14px;
    color: var(--text);
    outline: none;
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.chat-input:focus { background: var(--bg-panel); border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-ring); }
.chat-input::placeholder { color: var(--text-dim); }

.send-btn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: var(--brand);
    color: #f6f1e3;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, box-shadow 0.15s;
    box-shadow: 0 6px 14px -6px rgba(46, 63, 44, 0.55);
}

.send-btn:hover { background: var(--brand-hover); }
.send-btn:disabled { background: var(--border); cursor: not-allowed; box-shadow: none; }

/* ─── PANEL 3: Right contact panel ────────────────────────────────── */
.contact-panel {
    width: 300px;
    background: var(--bg-panel);
    border-left: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    overflow: hidden;
}

.cp-header {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.cp-header h3 { font-size: 15px; font-weight: 700; margin: 0; color: var(--text); }

.cp-close {
    background: transparent;
    border: none;
    color: var(--text-dim);
    cursor: pointer;
    padding: 4px;
    border-radius: 8px;
}
.cp-close:hover { background: var(--bg-muted); color: var(--text); }

.cp-tabs {
    display: flex;
    border-bottom: 1px solid var(--border);
    /* Safety net if labels ever exceed the panel width — scroll instead of overflowing. */
    overflow-x: auto;
    scrollbar-width: none;
}
.cp-tabs::-webkit-scrollbar { display: none; }

.cp-tab {
    flex: 1 1 0;
    min-width: 0;               /* let tabs shrink so a 4th tab never spills past the panel */
    padding: 10px 6px;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    transition: color 0.15s, border-color 0.15s;
}

.cp-tab:hover { color: var(--text); }
.cp-tab.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

.cp-tab-count {
    background: var(--bg-muted);
    color: var(--text-muted);
    padding: 1px 6px;
    border-radius: 8px;
    font-size: 10px;
    flex: none;
    font-weight: 600;
}

.cp-tab.active .cp-tab-count { background: var(--brand-100); color: var(--brand-text); }

.cp-body {
    flex: 1;
    overflow-y: auto;
}

.cp-pane { padding: 18px 16px; }

.cp-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: linear-gradient(135deg, #6f8a64, #4a5d47);
    color: #f6f1e3;
    font-weight: 700;
    font-size: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 12px;
}

.cp-name {
    text-align: center;
    font-size: 15px;
    font-weight: 700;
    color: var(--text);
}

.cp-phone {
    text-align: center;
    font-size: 13px;
    color: var(--brand);
    margin-bottom: 16px;
    font-weight: 500;
}

.cp-section {
    border-top: 1px solid var(--border-soft);
    padding-top: 14px;
}

.cp-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 6px 0;
    font-size: 13px;
}

.cp-row-key {
    color: var(--text-muted);
    font-weight: 500;
}

.cp-row-val {
    color: var(--text);
    font-weight: 500;
    text-align: right;
    max-width: 60%;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cp-empty {
    color: var(--text-dim);
    font-size: 13px;
    text-align: center;
    padding: 30px 16px;
}

.cp-notes-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* ── Tasks tab (tasks created on this contact's chat) ─────────────────── */
.cp-tasks-list { display: flex; flex-direction: column; gap: 8px; }
.cp-tasks-loading { padding: 20px 16px; font-size: 13px; color: var(--text-dim); text-align: center; }
.cp-task-row {
    display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 10px 12px;
    border: 1px solid var(--border, #e9ece7); border-radius: 12px; background: var(--surface, #fff);
    cursor: pointer; text-align: start; transition: border-color var(--dur-quick) var(--ease-out), box-shadow var(--dur-quick) var(--ease-out), transform var(--dur-instant) var(--ease-out);
}
.cp-task-row:hover { border-color: var(--brand); box-shadow: 0 6px 18px -12px rgba(20,28,18,.4); transform: translateY(-1px); }
.cp-task-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; margin-top: 5px; background: var(--task-dot, var(--brand)); }
.cp-task-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cp-task-title { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.35; overflow-wrap: anywhere; }
.cp-task-row.is-done .cp-task-title { text-decoration: line-through; color: var(--text-dim); }
.cp-task-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; font-size: 11px; color: var(--text-dim); }
.cp-task-pill { padding: 1px 7px; border-radius: 999px; background: var(--brand-50, #f1f3ef); white-space: nowrap; }
.cp-task-pill.is-overdue { background: color-mix(in srgb, var(--danger, #b23c3c) 14%, transparent); color: var(--danger, #b23c3c); font-weight: 600; }
.cp-task-avatars { display: flex; align-items: center; flex: none; }
.cp-task-avatar {
    width: 22px; height: 22px; border-radius: 50%; margin-inline-start: -6px; box-shadow: 0 0 0 2px var(--surface, #fff);
    background: var(--brand-100, #e6ebe1); color: var(--brand-text, #2e3f2c); font-size: 9px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; background-size: cover; background-position: center;
}
.cp-task-avatar:first-child { margin-inline-start: 0; }

.cp-note {
    background: var(--warn-bg);
    border: 1px solid rgba(200, 169, 106, 0.45);
    border-radius: 10px;
    padding: 10px 12px;
}

.cp-note-author {
    font-size: 11px;
    color: var(--warn-text);
    font-weight: 600;
    margin-bottom: 4px;
}

.cp-note-body {
    font-size: 13px;
    color: var(--warn-text);
    line-height: 1.4;
}

.cp-note-time {
    font-size: 10.5px;
    color: var(--warn-text);
    opacity: 0.75;
    margin-top: 4px;
}

/* ─── Responsive ──────────────────────────────────────────────────── */
/* Back-to-list control. Hidden by default and switched on inside the phone
   breakpoint below — declared here, ahead of that block, so the media query's
   `display: inline-flex` is the later rule and wins. */
.chat-back {
    display: none;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-inline-start: -6px;
    border: none;
    border-radius: 12px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.chat-back:hover { background: var(--bg-muted); color: var(--text); }

@media (max-width: 1100px) {
    .contact-panel { display: none; }
    .contact-panel.show { display: flex; position: absolute; right: 0; top: 0; bottom: 0; z-index: 30; box-shadow: -8px 0 24px rgba(0,0,0,0.08); }
}

@media (max-width: 768px) {
    /* Collapsed is the only sensible default here — 224px of labelled rail is
       well over half a 390px screen. Stated as the same variables the toggle
       uses, so the icons are centred and the labels genuinely removed rather
       than squeezed to zero width. */
    .rail {
        --rail-w:            64px;
        --rail-pad-x:        8px;
        --rail-text:         none;
        --rail-row:          none;
        --rail-brand:        none;
        --rail-head-justify: center;
        --rail-link-justify: center;
        --rail-link-gap:     0;
        --rail-link-pad-x:   0;
        --rail-toggle-rot:   180deg;
    }

    /* Expanding on a phone floats the rail OVER the content rather than taking
       a permanent share of the width — there isn't any to give. It leaves from
       the same edge it arrived at, so the panel returns where it came from. */
    .rail.rail-mobile-open {
        --rail-w:            min(268px, 82vw);
        --rail-pad-x:        14px;
        --rail-text:         inline;
        --rail-row:          flex;
        --rail-brand:        inline-flex;
        --rail-head-justify: space-between;
        --rail-link-justify: flex-start;
        --rail-link-gap:     12px;
        --rail-link-pad-x:   12px;
        --rail-toggle-rot:   0deg;

        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        z-index: 80;
        overflow-y: auto;
        overscroll-behavior: contain;
        box-shadow: var(--elev-3);
    }

    /* Dim the content behind an open rail: this is a modal task, and the scrim
       is what says the rest of the page is not currently the thing you're on. */
    .rail-scrim {
        position: fixed;
        inset: 0;
        z-index: 79;
        background: var(--scrim);
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--dur-quick) var(--ease-out);
    }
    .rail-scrim.is-open { opacity: 1; pointer-events: auto; }

    /* ── Inbox on a phone: one screen, two panes ──────────────────────
       The list and the conversation cannot sit side by side at this width,
       so they take turns. Previously .chat-main was display:none with a
       .show class that nothing ever added, and the sidebar's width:100%
       left the chat 0px wide — the conversation was reachable in the DOM
       and impossible to see. (chat.css also carries rules for a
       `.chat-sidebar` class that does not exist in the markup; the sidebar
       is .inbox-sidebar. Those rules have never applied.)

       Both panes are absolutely positioned and slide: the list leaves to
       the left, the chat arrives from the right, and going back retraces
       exactly that path. Something that left one way has to come back the
       way it went, or the two directions read as unrelated screens. */
    .inbox-layout { position: relative; overflow: hidden; }

    .inbox-sidebar,
    .chat-main {
        position: absolute;
        inset: 0;
        width: 100%;
        max-width: none;
        transition: transform var(--spring-sheet-ms) var(--spring-sheet);
    }

    .chat-main {
        display: flex;
        transform: translateX(100%);
        visibility: hidden;
        z-index: 2;                     /* above the list it covers */
        /* Visibility flips only once the pane has finished leaving, so the
           exit is still drawn while it animates but nothing off-screen is
           focusable afterwards. */
        transition: transform var(--spring-sheet-ms) var(--spring-sheet),
                    visibility 0s linear var(--spring-sheet-ms);
    }

    .inbox-layout.show-chat .chat-main {
        transform: translateX(0);
        visibility: visible;
        transition: transform var(--spring-sheet-ms) var(--spring-sheet),
                    visibility 0s;
    }
    .inbox-layout.show-chat .inbox-sidebar { transform: translateX(-100%); }

    /* The back control only exists in this arrangement. */
    .chat-back { display: inline-flex; }

    /* The contact panel is a third pane; at this width it covers the chat
       rather than sitting beside it — full-width, so it never leaves a thin
       un-dimmed sliver of chat (and never overflows on <364px phones). */
    .contact-panel.show { z-index: 3; width: 100%; max-width: none; }
}


/* Above the breakpoint the overlay state is meaningless — make sure a stale
   class from a resized window can never pin the rail over the content. */
@media (min-width: 769px) {
    .rail.rail-mobile-open { position: static; box-shadow: none; }
    .rail-scrim { display: none; }
}

/* ─── Channel filter bar (platform-level) ────────────────────────── */
.ch-bar-wrap {
    margin: 0 -16px;
    padding: 0 16px;
    border-bottom: 1px solid var(--border-soft);
    /* The chip row grows with each connected channel/label; let it scroll
       sideways rather than overflow the narrow sidebar on mobile. */
    overflow-x: auto;
    scrollbar-width: none;
}
.ch-bar-wrap::-webkit-scrollbar { display: none; }

.ch-bar {
    display: flex;
    gap: 4px;
    padding: 6px 0 10px;
}

.ch-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 8px;
    border-radius: 14px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    flex-shrink: 0;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}

.ch-chip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: inherit;
}

.ch-chip-label {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Keep every channel on one clean row: channel chips are icon-only (name in tooltip); only the
   ACTIVE channel reveals its label. The "All" chip has no icon, so its label always shows. */
.ch-chip-whatsapp .ch-chip-label,
.ch-chip-instagram .ch-chip-label,
.ch-chip-messenger .ch-chip-label { display: none; }
.ch-chip.is-active .ch-chip-label { display: inline; }

.ch-chip:hover {
    background: var(--bg-muted);
    color: var(--text);
}

.ch-chip.is-active {
    background: var(--brand-50);
    color: var(--brand-text);
    border-color: var(--brand-100);
    font-weight: 600;
}

/* WhatsApp chip — keep the icon green so the platform identity reads even when inactive */
.ch-chip.ch-chip-whatsapp:not(.is-active) .ch-chip-icon { color: var(--channel-whatsapp); }

.ch-chip.ch-chip-whatsapp.is-active {
    background: #ecfdf5;
    color: #047857;
    border-color: rgba(37, 211, 102, 0.45);
}
.ch-chip.ch-chip-whatsapp.is-active .ch-chip-icon { color: var(--channel-whatsapp); }

/* Disabled (coming-soon) chips — subtle dashed border + dim text. The browser title
   attribute provides the "Coming soon" hint on hover. */
.ch-chip.is-disabled {
    color: var(--text-dim);
    cursor: not-allowed;
    pointer-events: none;
    border-color: transparent;
    background: transparent;
    opacity: 0.85;
}

.ch-chip.is-disabled .ch-chip-icon  { opacity: 0.5; }
.ch-chip.is-disabled .ch-chip-label { text-decoration: line-through; text-decoration-color: rgba(148, 163, 184, 0.45); }

/* Mini-dot on the WhatsApp chip indicating Personal vs Business integration. The browser
   title attribute carries the full explanation on hover. */
.ch-chip-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    margin-left: 2px;
}
.ch-chip-dot.is-personal { background: var(--warn);  box-shadow: 0 0 0 2px var(--warn-bg); }
.ch-chip-dot.is-business { background: var(--ok);    box-shadow: 0 0 0 2px var(--ok-bg); }

/* ─── Integration pill (Personal / Business) — shown per-instance on the WhatsApp Numbers
   page so users can see the type of each connected number, not just the channel as a whole. */
.integration-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1px;
    line-height: 1.4;
    margin-left: auto;            /* push to the end of any flex container (e.g. card head) */
    cursor: help;
    border: 1px solid transparent;
    vertical-align: middle;
    flex-shrink: 0;
}
.integration-pill::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
}
.integration-pill.is-personal {
    background: var(--warn-bg);
    color: var(--warn-text);
    border-color: rgba(245, 158, 11, 0.25);
}
.integration-pill.is-personal::before { background: var(--warn); }
.integration-pill.is-business {
    background: var(--ok-bg);
    color: var(--ok-text);
    border-color: rgba(22, 163, 74, 0.22);
}
.integration-pill.is-business::before { background: var(--ok); }

/* ─── Avatar wrap with channel badge overlay ─────────────────────── */
.conv-avatar-wrap {
    position: relative;
    flex-shrink: 0;
}

.conv-channel-badge {
    position: absolute;
    bottom: -2px;
    right: -2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--bg-panel);
    border: 1.5px solid var(--bg-panel);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 3px rgba(31, 41, 28, 0.15);
}

.conv-channel-badge .icon { width: 10px !important; height: 10px !important; }

.conv-channel-badge.ch-whatsapp  { background: var(--channel-whatsapp); color: #fff; }
.conv-channel-badge.ch-instagram { background: var(--channel-instagram); color: #fff; }
.conv-channel-badge.ch-messenger { background: var(--channel-messenger); color: #fff; }
.conv-channel-badge.ch-default   { background: var(--text-muted); color: #fff; }

/* ─── Toast notifications ─────────────────────────────────────────── */
.toast-stack {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

.toast {
    pointer-events: auto;
    background: var(--text);
    color: #fff;
    padding: 10px 14px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 220px;
    max-width: 360px;
    animation: toastIn 0.18s cubic-bezier(0.4, 0, 0.2, 1);
}

.toast.toast-out { animation: toastOut 0.18s cubic-bezier(0.4, 0, 0.2, 1) forwards; }
.toast.toast-success { background: var(--ok); }
.toast.toast-error   { background: var(--danger); }
.toast.toast-info    { background: var(--brand); }

.toast .icon { width: 16px; height: 16px; }

@keyframes toastIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
@keyframes toastOut {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(8px); }
}

/* ─── Lifecycle stage chip ────────────────────────────────────────── */
.lifecycle-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 9px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
    white-space: nowrap;
}

.lifecycle-chip:hover { background: var(--bg-muted); border-color: var(--brand-100); color: var(--text); }

.lifecycle-chip-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-dim);
    flex-shrink: 0;
}

/* Stage-specific dots — warm palette across the funnel (cool greys → sage greens). */
.lifecycle-stage-0 .lifecycle-chip-dot { background: #8a9085; }     /* New Client     */
.lifecycle-stage-1 .lifecycle-chip-dot { background: #b34141; }     /* Not Responding */
.lifecycle-stage-2 .lifecycle-chip-dot { background: #6a8aa3; }     /* Interested     */
.lifecycle-stage-3 .lifecycle-chip-dot { background: #8e7aa3; }     /* Thinking       */
.lifecycle-stage-4 .lifecycle-chip-dot { background: #6f9a99; }     /* Wants Meeting  */
.lifecycle-stage-5 .lifecycle-chip-dot { background: #5f8aa6; }     /* Waiting Mtg    */
.lifecycle-stage-6 .lifecycle-chip-dot { background: #6a7d9c; }     /* Discussed      */
.lifecycle-stage-7 .lifecycle-chip-dot { background: #c8a96a; }     /* Potential      */
.lifecycle-stage-8 .lifecycle-chip-dot { background: #d2b66f; }     /* Will Pay       */
.lifecycle-stage-9 .lifecycle-chip-dot { background: #aabba4; }     /* Wait Contract  */
.lifecycle-stage-10 .lifecycle-chip-dot { background: #4a7c45; }    /* Our Client     */

/* Lifecycle dropdown menu */
#lifecycleMenu {
    min-width: 220px;
    max-height: 360px;
    overflow-y: auto;
}

#lifecycleMenu .cm-item {
    display: flex;
    align-items: center;
    gap: 8px;
}

#lifecycleMenu .lc-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Lifecycle row in right contact panel */
.cp-lifecycle-display {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    background: var(--bg-muted);
    border-radius: 12px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text);
}

.cp-lifecycle-display .lc-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* ─── Closed conversation styling ─────────────────────────────────── */
.conv-item.is-closed .conv-name,
.conv-item.is-closed .conv-preview {
    color: var(--text-muted);
}

.conv-item.is-closed .conv-avatar { opacity: 0.65; }

.closed-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 8px;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    background: var(--bg-muted);
    color: var(--text-muted);
    line-height: 1.5;
}

/* ─── Settings popover (rail) ─────────────────────────────────────── */
.rail-link-wrap { position: relative; width: 100%; display: flex; justify-content: center; }

.settings-popover {
    /* Fixed (not absolute) so it escapes the .rail-nav scroll container and is never clipped.
       Its left/bottom are set in JS from the trigger button's viewport rect on open. */
    position: fixed;
    background: var(--bg-panel);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 16px 36px rgba(0, 0, 0, 0.14);
    padding: 4px;
    min-width: 200px;
    z-index: 200;
    /* No `animation` here. This file loads after foundation.css, so an
       animation declared on this class outranks .fluid-materialize /
       .fluid-dematerialize (same specificity, later wins) and shadows them.
       The exit then never ran, animationend never fired, and the close
       handler — which waits for that event before hiding the menu — left the
       popover stuck open. Fluid.materialize() drives the motion instead, and
       scales it from the rail button rather than from the popover's own edge. */
}

.settings-popover-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border-radius: 6px;
    color: var(--text);
    text-decoration: none;
    font-size: 13.5px;
    transition: background 0.12s;
}

.settings-popover-item:hover { background: var(--bg-muted); color: var(--text); }
.settings-popover-item .icon { color: var(--text-muted); flex-shrink: 0; }

/* ════════════════════════════════════════════════════════════════════
   Shared form/button components — available on every dashboard page
   ════════════════════════════════════════════════════════════════════ */

/* Primary soft button (indigo-tinted). Used for "Add user", "Add role",
   "Export to Excel", and other non-destructive primary actions. */
.btn-primary-soft {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    background: var(--brand);
    color: #f6f1e3;
    border: 1px solid var(--brand);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.14s ease, border-color 0.14s ease, box-shadow 0.14s ease;
    box-shadow: 0 6px 14px -6px rgba(46, 63, 44, 0.55);
}
.btn-primary-soft:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.btn-primary-soft:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--brand-ring); }
.btn-primary-soft:disabled { opacity: 0.6; cursor: not-allowed; }

.btn-primary-soft .btn-spinner {
    width: 12px;
    height: 12px;
    border: 2px solid rgba(246, 241, 227, 0.35);
    border-top-color: #f6f1e3;
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

/* Search input wrapper + icon. */
.filter-search { position: relative; flex: 1; min-width: 240px; max-width: 380px; }
.filter-search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-dim); }

.filter-search input {
    width: 100%;
    padding: 8px 12px 8px 32px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-panel);
    font-size: 13px;
    outline: none;
    color: var(--text);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.filter-search input:focus {
    border-color: var(--brand-200);
    box-shadow: 0 0 0 3px var(--brand-ring);
}
.filter-search input::placeholder { color: var(--text-dim); }

/* Generic select with chevron. */
.filter-select {
    padding: 8px 28px 8px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-panel);
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    appearance: none;
    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='%2364748b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 9px center;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.filter-select:focus { outline: none; border-color: var(--brand-200); box-shadow: 0 0 0 3px var(--brand-ring); }

/* ─── Language switcher ──────────────────────────────────────────── */
.lang-switcher { position: relative; display: inline-block; }

.lang-switcher-btn {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    width: 100%;
    height: 38px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 12px;
    color: var(--text-muted);
    font: inherit;
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
    padding: 0 12px;
}
.lang-switcher-btn:hover { background: var(--bg-muted); color: var(--text); }
.lang-flag { font-size: 16px; line-height: 1; }
.lang-code { letter-spacing: 0.5px; font-size: 11px; font-weight: 600; opacity: 0.8; }
.lang-chevron { display: inline-flex; margin-left: auto; opacity: 0.55; }

.lang-switcher-menu {
    position: absolute;
    bottom: 0;
    left: calc(100% + 12px);
    min-width: 200px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 16px 40px rgba(31, 41, 28, 0.16), 0 2px 6px rgba(31, 41, 28, 0.04);
    padding: 6px;
    z-index: 1100;
    animation: msgMenuIn 0.14s cubic-bezier(.2,.8,.3,1);
}
.lang-switcher-form { display: block; margin: 0; }
.lang-switcher-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    border: none;
    background: transparent;
    padding: 8px 10px;
    border-radius: 8px;
    text-align: left;
    font: inherit;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    transition: background 0.1s ease;
}
.lang-switcher-item:hover { background: var(--bg-muted); }
.lang-switcher-item.active { color: var(--brand); background: var(--bg-soft); }
.lang-switcher-item .lang-name { flex: 1; }
.lang-switcher-item svg { color: var(--brand); }

/* ───────────────────────────────────────────────────────────────
   UI POLISH (non-color) — app-wide overflow safety on the dashboard
   shell. No colors changed: image bounds only. Every raster image
   (avatars, media, uploaded logos) is capped to its container so a
   broken or oversized image can never break a layout.
   ─────────────────────────────────────────────────────────────── */
.inbox-shell img { max-width: 100%; }

/* ── @mention autocomplete (internal notes) ─────────────────────────── */
.mention-menu {
    position: fixed; z-index: 1400; background: var(--bg-panel, #fff);
    border: 1px solid var(--border, #e5e7eb); border-radius: 10px;
    box-shadow: 0 10px 30px -8px rgba(20,28,18,.35); overflow: hidden; padding: 4px;
}
.mention-opt { padding: 7px 12px; border-radius: 7px; font-size: 13.5px; color: var(--text); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mention-opt.active, .mention-opt:hover { background: var(--brand-200, #e6ebe1); color: var(--brand-text, #2e3f2c); }

/* ─── Quoted reply ──────────────────────────────────────────────────
   A small quote strip at the top of a bubble (click to jump to the source),
   the composer preview bar, and the flash when you land on the quoted message. */
.msg-quote {
    display: flex;
    flex-direction: column;
    gap: 1px;
    border-inline-start: 3px solid var(--brand-200);
    background: rgba(46, 63, 44, 0.06);
    border-radius: 6px;
    padding: 5px 9px;
    margin-bottom: 5px;
    cursor: pointer;
    max-width: 100%;
    transition: filter 0.12s ease;
}
.msg-quote:hover { filter: brightness(0.97); }
.msg-quote-to {
    font-size: 12px;
    font-weight: 700;
    color: var(--brand);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.msg-quote-snip {
    font-size: 12.5px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Our own bubble is a light sage (#e3ecd9), so the quote stays dark-on-light — just a
   slightly deeper tint + brand accent to set it apart from the bubble. */
.msg.outgoing .msg-quote { background: rgba(46, 63, 44, 0.10); border-inline-start-color: var(--brand); }
.msg.outgoing .msg-quote-to { color: var(--brand); }
.msg.outgoing .msg-quote-snip { color: var(--text-muted); }

/* Composer preview — the strip above the input while a reply is being composed. */
.reply-bar {
    display: flex;
    align-items: stretch;
    gap: 10px;
    margin: 0 12px;
    padding: 8px 10px;
    background: var(--bg-soft);
    border: 1px solid var(--border-soft);
    border-bottom: none;
    border-radius: 12px 12px 0 0;
}
.reply-bar[hidden] { display: none; }
.reply-bar-accent { width: 3px; border-radius: 3px; background: var(--brand-200); flex: 0 0 auto; }
.reply-bar-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; justify-content: center; }
.reply-bar-to { font-size: 12px; font-weight: 700; color: var(--brand); }
.reply-bar-snip { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.reply-bar-x {
    flex: 0 0 auto;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 15px;
    cursor: pointer;
    padding: 0 6px;
    border-radius: 6px;
}
.reply-bar-x:hover { background: var(--bg-muted); color: var(--text); }

/* Land-on-quote flash. */
.msg-flash .msg-bubble { animation: msgFlash 1.3s ease; }
@keyframes msgFlash {
    0%, 100% { box-shadow: 0 0 0 0 rgba(46, 63, 44, 0); }
    25%      { box-shadow: 0 0 0 3px var(--brand-ring); }
}

/* ── Dark theme overrides ──────────────────────────────────────────────
   Additive only — nothing above is touched. Each rule re-points a
   hardcoded LIGHT hex from the rules above onto a design token, which
   already carries the dark value under [data-theme="dark"] (see tokens.css).
   Rail selectors carry a SECOND selector under [data-theme="mix"] .rail so
   the rail is dark in "Mix" mode too; Mix keeps page content light, so
   non-rail selectors only need the [data-theme="dark"] rule.
   Left intentionally light: categorical/status hues (channel purples/blues,
   lifecycle dots, WhatsApp green), colored avatar gradients, and cream/white
   TEXT sitting on colored buttons & badges. */

/* Rail — dark theme AND Mix mode's dark rail */
/* The wordmark's deep green vanishes against the dark rail, so reverse the whole
   lockup out to white. The chevron knocked out of the B is transparent in the
   export, so it keeps reading as a notch rather than filling in. */
:root[data-theme="dark"] .rail-brand-logo,
:root[data-theme="mix"] .rail .rail-brand-logo { filter: brightness(0) invert(1); opacity: .92; }

:root[data-theme="dark"] .rail-link.active,
:root[data-theme="mix"] .rail .rail-link.active { background: var(--ok-bg); }

/* Content surfaces / text / structural borders — dark theme only */
:root[data-theme="dark"] .search-icon { color: var(--text-muted); }
:root[data-theme="dark"] .conv-item { border-bottom-color: var(--border-soft); }
:root[data-theme="dark"] .chat-input-bar.note-mode .send-btn:hover { background: var(--warn); }
:root[data-theme="dark"] .chat-input-bar.note-mode .vr-send:hover { background: var(--warn); }
:root[data-theme="dark"] .cp-task-row { background: var(--bg-panel); }
:root[data-theme="dark"] .cp-task-avatar { box-shadow: 0 0 0 2px var(--bg-panel); }
/* Neutral toast only: its base uses background:var(--text)+color:#fff (an inverse chip that
   flips wrong in dark). The :not() guards keep the coloured success/error/info toasts intact. */
:root[data-theme="dark"] .toast:not(.toast-success):not(.toast-error):not(.toast-info) { background: var(--bg-panel); color: var(--text); border: 1px solid var(--border); }

/* ── Contact-panel Activity timeline (token-based → themes for light/dark/mix automatically) ── */
.cp-act-feed { padding: 4px 2px 14px; }
.cp-act-loading { padding: 22px; text-align: center; color: var(--text-muted); font-size: 13px; }
.cp-act-day { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); margin: 14px 0 8px 40px; }
.cp-act-feed .cp-act-day:first-child { margin-top: 2px; }
.cp-act { position: relative; display: flex; gap: 12px; }
.cp-act-rail { position: relative; width: 28px; flex: 0 0 auto; display: flex; justify-content: center; }
.cp-act-rail::before { content: ""; position: absolute; top: 4px; bottom: -12px; width: 2px; background: var(--border); left: 50%; transform: translateX(-50%); }
.cp-act:last-child .cp-act-rail::before { display: none; }
.cp-act-node { position: relative; z-index: 1; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--bg-soft); border: 1px solid var(--border); color: var(--text-muted); }
.cp-act-node svg { width: 15px; height: 15px; }
.cp-act-node.n-brand  { background: var(--ok-bg);     border-color: transparent; color: var(--brand); }
.cp-act-node.n-ok     { background: var(--ok-bg);     border-color: transparent; color: var(--ok); }
.cp-act-node.n-warn   { background: var(--warn-bg);   border-color: transparent; color: var(--warn); }
.cp-act-node.n-danger { background: var(--danger-bg); border-color: transparent; color: var(--danger); }
.cp-act-node.n-info   { background: var(--bg-muted);  border-color: transparent; color: #5b82c4; }
.cp-act-node.n-ai     { background: var(--bg-muted);  border-color: transparent; color: #9575d6; }
.cp-act-body { flex: 1 1 auto; min-width: 0; padding-bottom: 14px; }
.cp-act-text { font-size: 13px; color: var(--text); line-height: 1.45; }
.cp-act-time { font-size: 11px; color: var(--text-dim); margin-top: 3px; }
.cp-act-ava { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: var(--brand); color: #fff; font-size: 8.5px; font-weight: 700; vertical-align: -3px; margin-right: 3px; }
.cp-act-ai { color: #9575d6; font-weight: 600; }
.cp-act-chips { display: inline-flex; align-items: center; gap: 5px; margin-top: 5px; flex-wrap: wrap; }
.cp-act-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; background: var(--bg-muted); color: var(--text-muted); white-space: nowrap; }
.cp-act-chip.to { background: var(--ok-bg); color: var(--ok-text); }
.cp-act-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.cp-act-arrow { color: var(--text-dim); font-size: 12px; }
.cp-act-note { margin-top: 6px; padding: 8px 11px; background: var(--warn-bg); border-radius: 10px; font-size: 12.5px; color: var(--text); white-space: pre-wrap; word-break: break-word; }

/* ── Page back link ─────────────────────────────────────────────────────────
   The rail only ever points at top-level destinations, so a page one level
   below one — top-up and analytics under billing, task settings under tasks,
   lifecycle stages under the pipeline — has nothing in the chrome that leads
   back to where it was opened from. This is that link, above the page title.

   Labelled rather than a bare arrow, matching the channel connect pages: it
   names where "back" goes, which a lone glyph can't, and the label is what
   makes it a target worth aiming at. Mirrored under RTL so the arrow points
   the way the reader travels. */
.page-back { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 12px; font-size: 13px; font-weight: 600; color: var(--text-dim); text-decoration: none; }
.page-back:hover { color: var(--text); }
[dir="rtl"] .page-back svg { transform: scaleX(-1); }

/* ── Contact-panel Tasks tab: "Create a task" button (same flow as the chat menu item) ── */
.cp-tasks-head { display: flex; justify-content: flex-end; padding: 2px 2px 10px; }
.cp-task-create-btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 9px; border: 1px solid var(--brand); background: var(--brand); color: #fff; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: filter .15s, background .15s; }
.cp-task-create-btn:hover { filter: brightness(1.08); }
.cp-empty .cp-task-create-btn { margin-top: 12px; }

/* The contact's own @handle, where a WhatsApp contact shows a phone number. Click-to-copy, so it
   gets the affordances of something clickable — otherwise it reads as plain text and nobody tries. */
.cp-phone.cp-handle {
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: color-mix(in srgb, var(--brand) 45%, transparent);
    transition: text-decoration-color 0.14s ease, filter 0.14s ease;
}
.cp-phone.cp-handle:hover {
    filter: brightness(1.15);
    text-decoration-color: var(--brand);
}
.cp-phone.cp-handle:active { filter: brightness(0.95); }

/* The contact's profile link, where the channel has one. Same weight as the phone number it
   replaces — it is the identity line, not a call to action. */
.cp-profile-link {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: color-mix(in srgb, var(--brand) 45%, transparent);
    transition: text-decoration-color 0.14s ease, filter 0.14s ease;
}
.cp-profile-link:hover {
    filter: brightness(1.15);
    text-decoration-color: var(--brand);
}
