:root {
    --bg: #070b12;
    --surface: #0f1622;
    --surface-2: #121c2b;
    --surface-3: #18263a;
    --text: #ecf3ff;
    --muted: #9db1cc;
    --accent: #66d6ff;
    --accent-2: #8c7dff;
    --danger: #ff7b9c;
    --danger-ink: #ffe4e4; /* danger emphasis text — light-pink on dark red tints */
    --shadow-rgb: 4, 10, 16; /* neutral box-shadow color (near-black) */
    --border: rgba(148, 196, 255, 0.2);
    --glow: 0 0 0 1px rgba(102, 214, 255, 0.2), 0 0 35px rgba(102, 214, 255, 0.18);
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
    min-height: 100%;
    background: radial-gradient(1200px 700px at 20% -10%, rgba(102, 214, 255, 0.15), transparent 60%), var(--bg);
    color: var(--text);
    font-family: "Plus Jakarta Sans", "Segoe UI", sans-serif;
}
/* Always reserve scrollbar space so navigating from a viewport-locked
   page (e.g. /messages inbox) to a scrollable one (e.g. /messages/rules)
   doesn't reflow the layout horizontally as the scrollbar appears. */
html {
    scrollbar-gutter: stable;
    /* Backstop: a stray wide element can never force a whole-page horizontal
       scrollbar on a phone. `clip` (not `hidden`) preserves position:sticky.
       Wide DATA tables get their own scroll wrapper below so their columns
       stay reachable rather than being clipped by this. */
    overflow-x: clip;
}

a {
    color: var(--accent);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

.top-nav {
    position: sticky;
    top: 0;
    z-index: 20;
    border-bottom: 1px solid var(--border);
    background: rgba(9, 14, 22, 0.88);
    backdrop-filter: blur(10px);
}

/* Collapsed state — entire nav becomes a 22px strip with a small
   "Show nav" pill. Toggled by [data-topnav-hide] / [data-topnav-show]
   buttons and the `\` key (see top_nav.php). */
html[data-topnav="collapsed"] .top-nav .top-nav-inner {
    display: none;
}
html[data-topnav="collapsed"] .top-nav {
    padding: 0;
    border-bottom: 1px solid rgba(148, 196, 255, 0.18);
}
.top-nav-collapsed-toggle {
    display: none;
    width: 100%;
    padding: 0.18rem 0.65rem;
    background: rgba(15, 23, 35, 0.85);
    border: 0;
    border-bottom: 1px solid rgba(148, 196, 255, 0.18);
    color: var(--muted);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 700;
    cursor: pointer;
    text-align: left;
    line-height: 1.3;
}
.top-nav-collapsed-toggle:hover {
    background: rgba(28, 42, 60, 0.85);
    color: var(--text);
}
/* Desktop: the old strip is NOT used when collapsed — the minimized inner bar
   stays instead. Only mobile (≤720px, further down) shows this strip. */
html[data-topnav="collapsed"] .top-nav-collapsed-toggle {
    display: none;
}

/* Mobile (≤720px): the collapsed-nav opener was a 22px-tall strip with a
   tiny "≡ Show nav" label that operators routinely missed. Bump it to a
   proper 44px+ tap target, larger hamburger glyph, and a more obvious
   active-button look so it reads as something to press. */
@media (max-width: 720px) {
    .top-nav-collapsed-toggle {
        min-height: 44px;
        padding: 0.65rem 1rem;
        font-size: 0.95rem;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text);
        background: rgba(28, 42, 60, 0.92);
        /* display stays `none` (base) until collapsed — the collapsed rule
           below flips it to flex. These flex props just lay it out when shown. */
        align-items: center;
        gap: 0.55rem;
    }
    html[data-topnav="collapsed"] .top-nav-collapsed-toggle { display: flex; }
    .top-nav-collapsed-toggle::first-letter {
        /* Make the leading "≡" hamburger glyph pop visually so the button
           reads as a hamburger menu instead of a label. */
        font-size: 1.4rem;
        line-height: 1;
    }
    html[data-topnav="collapsed"] .top-nav-collapsed-toggle {
        display: flex;
    }
}

.top-nav-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0.45rem 1rem 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.top-nav-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-width: 0;
}

.top-nav-bar-right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.top-nav-hide-btn {
    height: 28px;
    padding-inline: 0.55rem;
    font-size: 0.78rem;
}

.brand-block {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    min-width: 0;
}

.brand-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.45);
    color: #9fe6ff;
    font-weight: 700;
    letter-spacing: 0.07em;
    font-size: 0.7rem;
    box-shadow: var(--glow);
}

.brand-title {
    font-size: 0.86rem;
    font-weight: 700;
    line-height: 1.2;
}

.brand-subtle {
    font-size: 0.7rem;
    color: var(--muted);
    line-height: 1.2;
}

.top-nav-pager {
    display: flex;
    align-items: stretch;
    gap: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--border);
    min-width: 0;
}

.top-nav-pager-viewport {
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.top-nav-pager.is-scrollable .top-nav-links {
    flex-wrap: nowrap;
}

.top-nav-pager-side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    gap: 0.15rem;
    flex-shrink: 0;
}

.top-nav-page-btn {
    border: 1px solid var(--border);
    border-radius: 8px;
    background: rgba(148, 196, 255, 0.08);
    color: var(--text);
    font-size: 1.15rem;
    line-height: 1;
    width: 2rem;
    height: 2rem;
    padding: 0;
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color 0.15s ease, background 0.15s ease, opacity 0.15s ease;
}

.top-nav-page-btn:hover:not(:disabled) {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(148, 196, 255, 0.14);
}

.top-nav-page-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.top-nav-page-label {
    font-size: 0.72rem;
    color: var(--muted);
    white-space: nowrap;
    line-height: 1.2;
}

.top-nav-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.45rem;
    min-width: min-content;
    min-height: 2.15rem;
}

.top-nav-link {
    color: var(--muted);
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 0.22rem 0.5rem;
    font-size: 0.8rem;
    white-space: nowrap;
}

.top-nav-link.is-active,
.top-nav-link:hover {
    color: var(--text);
    border-color: var(--border);
    background: rgba(148, 196, 255, 0.08);
    text-decoration: none;
}

.logout-form {
    display: flex;
    align-items: center;
    gap: 0.65rem;
}

.welcome-text {
    color: var(--muted);
    font-size: 0.78rem;
}

.layout-main {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1.5rem 1rem 2rem;
}
/* Data-dense pages (database, disposition, confirmation) deserve the
   full viewport — capping at 1200px wastes the right half of any
   modern monitor when the table needs every column to breathe.
   Messaging admin pages also opt out so the shared sub-nav stays
   aligned with the inbox (which is also full-bleed). Each messaging
   page's own .smsauto-page / .smsq-page / etc. caps content at 1280px
   internally, so the layout-main just hosts the subnav + that frame. */
.layout-main.is-database,
.layout-main.is-disposition,
.layout-main.is-confirmation {
    max-width: none;
    padding: 0.85rem 0.85rem 1.25rem;
}
/* Messaging admin pages: layout-main is full-bleed (matching inbox)
   with no padding, so the shared sub-nav sits flush and each page's
   own .smsauto-page / .smsq-page / etc. provides the content padding +
   1280px max-width frame. Keeps the subnav tab positions identical
   between inbox and admin pages — no horizontal jump on tab clicks. */
.layout-main.is-messages-automations,
.layout-main.is-messages-automations-queue,
.layout-main.is-messages-automations-activity,
.layout-main.is-messages-templates,
.layout-main.is-messages-health {
    max-width: none;
    padding: 0;
}

.auth-shell {
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 1rem;
}

.auth-card {
    width: 100%;
    max-width: 420px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, rgba(18, 28, 43, 0.9), rgba(13, 20, 32, 0.94));
    border-radius: 16px;
    padding: 1.2rem;
    box-shadow: var(--glow);
}

.auth-heading h1 {
    margin: 0.6rem 0 0.2rem;
}

.auth-heading p {
    margin: 0;
    color: var(--muted);
}

.auth-form {
    margin-top: 1rem;
    display: grid;
    gap: 0.45rem;
}

.auth-form label {
    color: var(--muted);
    font-size: 0.86rem;
}

.auth-form input {
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.58rem 0.7rem;
}

.btn {
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text);
    background: linear-gradient(180deg, rgba(23, 34, 51, 0.9), rgba(16, 24, 36, 0.92));
    padding: 0.5rem 0.8rem;
    cursor: pointer;
    box-shadow: 0 6px 14px rgba(var(--shadow-rgb), 0.34);
    transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}

.btn:hover {
    background: linear-gradient(180deg, rgba(30, 46, 70, 0.95), rgba(20, 31, 47, 0.96));
    border-color: rgba(102, 214, 255, 0.5);
    transform: translateY(-1px);
    box-shadow: 0 10px 20px rgba(var(--shadow-rgb), 0.42);
}

.btn-primary {
    border-color: rgba(102, 214, 255, 0.5);
    background: linear-gradient(180deg, rgba(27, 124, 150, 0.85), rgba(15, 84, 121, 0.94));
}

.btn-primary:hover {
    background: linear-gradient(180deg, rgba(32, 140, 170, 0.95), rgba(20, 98, 137, 1));
}

.btn-ghost {
    background: transparent;
}

.page-header {
    position: relative;
    margin-bottom: 1.1rem;
    border-radius: 14px;
    border: 1px solid rgba(148, 196, 255, 0.18);
    background: linear-gradient(135deg, rgba(22, 34, 52, 0.82), rgba(16, 24, 36, 0.82));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 14px 30px rgba(var(--shadow-rgb), 0.36);
    padding: 0.9rem 1rem;
    overflow: hidden;
}

.page-header::after {
    content: "";
    position: absolute;
    top: -60px;
    right: -40px;
    width: 180px;
    height: 180px;
    border-radius: 999px;
    background: radial-gradient(circle, rgba(102, 214, 255, 0.28), rgba(102, 214, 255, 0));
    pointer-events: none;
}

.page-header.workspace.hero {
    border-color: rgba(140, 125, 255, 0.25);
}

.page-header h1 {
    margin: 0;
    font-size: 1.45rem;
    letter-spacing: 0.01em;
}

.page-header p {
    margin: 0.45rem 0 0;
    color: var(--muted);
}

.grid-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.grid-3 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.panel {
    position: relative;
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1rem;
    background: linear-gradient(160deg, rgba(20, 31, 47, 0.84), rgba(13, 20, 31, 0.84));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 14px 30px rgba(var(--shadow-rgb), 0.35);
    overflow: hidden;
}

.panel::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 14px;
    border: 1px solid rgba(102, 214, 255, 0.08);
    pointer-events: none;
}

.panel h2,
.panel h1 {
    margin: 0 0 0.75rem;
}


.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.chip {
    border: 1px solid rgba(102, 214, 255, 0.4);
    border-radius: 999px;
    padding: 0.3rem 0.66rem;
    font-size: 0.84rem;
    color: #aeeeff;
    background: linear-gradient(135deg, rgba(29, 74, 98, 0.55), rgba(45, 52, 129, 0.48));
    box-shadow: 0 0 0 1px rgba(102, 214, 255, 0.14), 0 0 18px rgba(102, 214, 255, 0.12);
}

.chip-shared {
    color: #d7c7ff;
    border-color: rgba(140, 125, 255, 0.5);
    background: rgba(54, 43, 94, 0.32);
}

.table {
    width: 100%;
    border-collapse: collapse;
    border-radius: 12px;
    overflow: hidden;
}

.table th,
.table td {
    border-bottom: 1px solid rgba(148, 196, 255, 0.14);
    text-align: left;
    padding: 0.62rem 0.5rem;
    vertical-align: top;
    font-size: 0.92rem;
}

.table th {
    color: #bad0e8;
    font-weight: 600;
    background: linear-gradient(180deg, rgba(32, 49, 73, 0.8), rgba(21, 32, 48, 0.8));
}

.table tbody tr:nth-child(2n) td {
    background: rgba(148, 196, 255, 0.03);
}

.table tbody tr:hover td {
    background: rgba(102, 214, 255, 0.08);
}

.alert {
    border-radius: 10px;
    border: 1px solid var(--border);
    padding: 0.6rem 0.7rem;
    margin: 0.75rem 0;
    font-size: 0.9rem;
}

.alert-success {
    border-color: rgba(102, 214, 255, 0.5);
    background: rgba(20, 79, 99, 0.45);
    color: #dcf6ff;
}

.alert-error {
    border-color: rgba(255, 123, 156, 0.5);
    background: rgba(88, 24, 46, 0.5);
    color: #ffd7e4;
}

.muted-line {
    color: var(--muted);
    font-size: 0.9rem;
}

.admin-context {
    margin-top: 0.9rem;
}

.admin.context-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.admin.context-row h2 {
    margin: 0.1rem 0 0.2rem;
}

.admin.quick-links {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.admin-availability-counts {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin: 1rem 0;
    align-items: flex-end;
}

.admin-availability-counts label {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 8rem;
}

.admin.users-layout {
    display: grid;
    grid-template-columns: minmax(320px, 1.3fr) minmax(280px, 1fr);
    gap: 1rem;
    margin-top: 0.8rem;
}

.admin.users-list.panel,
.admin.user-actions.panel,
.admin-create-user.panel {
    background: linear-gradient(160deg, rgba(20, 31, 47, 0.92), rgba(13, 20, 31, 0.92));
}

.admin.users-list h3,
.admin.user-actions h3,
.admin-create-user h3 {
    margin: 0 0 0.6rem;
}

.admin.users-list input[type="search"] {
    width: 100%;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.55rem 0.7rem;
    margin-bottom: 0.7rem;
}

.admin-users-table tbody tr.is-selected td {
    background: rgba(102, 214, 255, 0.12);
}

.admin-users-table td:last-child {
    white-space: nowrap;
    width: 1%;
}

.admin.user-actions .auth-form {
    margin-top: 0.9rem;
    padding-top: 0.7rem;
    border-top: 1px solid rgba(148, 196, 255, 0.16);
}

.admin-create-user {
    margin-top: 1rem;
}

.employee.stats-tabs {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5rem;
    margin: 0 0 1rem;
    padding: 0.4rem;
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(20, 31, 47, 0.92), rgba(12, 19, 30, 0.92));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 10px 24px rgba(var(--shadow-rgb), 0.45);
}

.employee.stats-view-tabs {
    margin-bottom: 0.75rem;
}

.employee.stats-tab {
    display: inline-flex;
    position: relative;
    flex: 1 1 0;
    align-items: center;
    justify-content: center;
    min-width: 0;
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.18);
    padding: 0.5rem 1rem;
    font-size: 0.89rem;
    font-weight: 650;
    letter-spacing: 0.01em;
    color: var(--muted);
    background: linear-gradient(180deg, rgba(17, 26, 40, 0.8), rgba(13, 20, 31, 0.8));
    text-decoration: none;
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.employee.stats-tab:hover {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.55);
    background: linear-gradient(180deg, rgba(28, 43, 64, 0.92), rgba(19, 30, 45, 0.92));
    transform: translateY(-1px);
    box-shadow: 0 6px 14px rgba(var(--shadow-rgb), 0.45);
    text-decoration: none;
}

.employee.stats-tab.is-active {
    color: #08111d;
    background: linear-gradient(120deg, var(--accent), var(--accent-2));
    border-color: rgba(220, 244, 255, 0.42);
    box-shadow: 0 10px 22px rgba(65, 139, 235, 0.36), inset 0 1px 0 rgba(255, 255, 255, 0.38);
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
}

.employee.stats-tab:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.75);
    outline-offset: 1px;
}

/* Confirmation page is viewport-fit: the entire UI (hero, chips, toolbar,
   filters, drawer) is always visible at once. Only the inbox table body
   scrolls — that's the queue you're paging through. Everything else stays
   pinned. Height math is `100dvh` to play nice with mobile address-bar
   resizing. The body is a flex column so the sticky top-nav and the main
   region cleanly partition the viewport — main fills whatever's left. */
body.is-confirmation-page {
    height: 100dvh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
body.is-confirmation-page .top-nav {
    flex: 0 0 auto;
}
body.is-confirmation-page .layout-main.is-confirmation {
    flex: 1 1 auto;
    min-height: 0;
}

.layout-main.is-confirmation {
    max-width: none;
    height: 100%;
    min-height: 0;
    min-width: 0;
    overflow: hidden;
    padding: 0.45rem 0.5rem 0.35rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.confirmation.page-root {
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.confirmation.page-root .confirmation.flash {
    flex: 0 0 auto;
    margin-bottom: 0.45rem;
}

.confirmation.inbox-shell {
    margin-top: 0;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0.6rem 0.75rem 0.7rem;
}

/* Filter strip — compact pattern. Visual rules consolidated below in
   the .confirmation.inbox-toolbar block (~line 4720). Scope-specific
   visibility helpers stay here because they're not layout-related. */
.confirmation.page-root[data-confirmation-scope="queue"] .confirmation.inbox-scope-line {
    display: none;
}

.confirmation.page-root[data-confirmation-scope="confirmed"] .confirmation-only-for-queue,
.confirmation.page-root[data-confirmation-scope="reminders"] .confirmation-only-for-queue,
.confirmation.page-root[data-confirmation-scope="not_confirmed"] .confirmation-only-for-queue {
    display: none;
}

/* Inbox now takes the full width — the detail drawer was extracted into
   a popup (see `.confirmation.detail-modal-backdrop` below) so the
   layout no longer needs a 2nd column. */
.confirmation.inbox-layout {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.confirmation.inbox-list-wrap {
    overflow-x: auto;
    border-radius: 12px;
}

.confirmation.inbox-table {
    table-layout: fixed;
    /* Sticky thead requires border-collapse: separate to render reliably
       in all browsers — collapsed borders disappear on scroll. Also clear
       the overflow:hidden inherited from .table since it interferes with
       sticky positioning inside the table element. The wrap already
       provides clipping/border-radius. */
    border-collapse: separate;
    border-spacing: 0;
    overflow: visible;
}

.confirmation.inbox-table th,
.confirmation.inbox-table td {
    padding: 0.72rem 0.6rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.confirmation.inbox-col-time {
    width: 110px;
}

/* Inbox segment column — sized for the chip labels (Call Now / Past Due
   / 3 Day / Future / Remind / No Date / Confirmed / No Go). */
.confirmation.inbox-col-segment {
    width: 110px;
}
.confirmation.inbox-cell.segment {
    overflow: visible;
}
.confirmation.segment-chip {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 0.16rem 0.55rem;
    line-height: 1.25;
    white-space: nowrap;
}

.confirmation.inbox-col-marketer {
    width: 150px;
}
.confirmation.inbox-cell.marketer {
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.confirmation.inbox-col-first {
    width: 220px;
}

.confirmation.inbox-col-last {
    width: 150px;
}

.confirmation.inbox-col-address {
    width: auto;
}

.confirmation.inbox-col-product {
    width: 170px;
}

.confirmation.inbox-row {
    cursor: pointer;
}

/* ---- Confirmation inbox row states — popup-based, hover only ----
   No persistent "selected" highlight. Each row glows with its own
   neon accent on hover, keyed to its segment. New-lead rows carry a
   faint baseline tint so they read as fresh at a glance. */

/* New-lead baseline tint (faint green wash behind every cell) */
.confirmation.inbox-row.is-new-lead td {
    background: rgba(74, 214, 125, 0.07);
}

/* Generic hover — neon cyan sweep, no segment context needed */
.confirmation.inbox-row:hover td {
    background: rgba(102, 214, 255, 0.10);
}

/* Segment-aware hover neons — override generic on hover when segment
   can be read from the row's data-segment attribute. */

/* Call-now (overdue reminder) → hot magenta */
.confirmation.inbox-row[data-segment*="call"]:hover td {
    background: rgba(255, 0, 180, 0.11);
}
/* Same-day → electric orange */
.confirmation.inbox-row[data-segment*="same"]:hover td {
    background: rgba(255, 140, 0, 0.13);
}
/* 3-day window → vivid cyan-green */
.confirmation.inbox-row[data-segment*="three"]:hover td {
    background: rgba(0, 255, 200, 0.10);
}
/* Future → soft violet */
.confirmation.inbox-row[data-segment*="future"]:hover td {
    background: rgba(180, 100, 255, 0.11);
}
/* Past-due → neon red */
.confirmation.inbox-row[data-segment*="past"]:hover td {
    background: rgba(255, 50, 50, 0.11);
}
/* Reminders → amber-gold */
.confirmation.inbox-row[data-segment*="remind"]:hover td {
    background: rgba(255, 200, 0, 0.10);
}
/* No start date → muted slate */
.confirmation.inbox-row[data-segment*="no-start"]:hover td {
    background: rgba(148, 163, 184, 0.10);
}

/* New-lead hover boosts the green tint slightly */
.confirmation.inbox-row.is-new-lead:hover td {
    background: rgba(74, 214, 125, 0.15);
}

/* is-active kept as a no-op — popup model means nothing stays "selected" */
.confirmation.inbox-row.is-active td {
    /* intentionally no persistent highlight */
}

.confirmation.inbox-row:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.75);
    outline-offset: -2px;
}

.confirmation.inbox-cell {
    font-size: 0.9rem;
}

.confirmation.inbox-cell.time {
    font-weight: 650;
    color: var(--text);
    white-space: normal;
}

.confirmation.inbox-cell.product {
    color: var(--muted);
}

.confirmation.inbox-time-main {
    display: block;
    line-height: 1.25;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.005em;
}

.confirmation.inbox-time-sub {
    display: block;
    margin-top: 0.14rem;
    font-size: 0.74rem;
    line-height: 1.2;
    color: var(--muted);
    font-weight: 600;
}

/* Compact "lead received" pill ("📥 5/1 12:18p"). Sub-line beneath the
   appointment date/dayofweek so operators can see lead freshness at a
   glance without opening the detail modal. Tight enough to fit inside
   the 110px desktop time column; full timestamp lives in the title
   attribute and the detail modal's "Received" row. */
.confirmation.inbox-lead-received {
    display: inline-block;
    margin-top: 0.2rem;
    padding: 0.04rem 0.36rem;
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.18);
    background: rgba(102, 214, 255, 0.06);
    font-size: 0.62rem;
    line-height: 1.3;
    color: rgba(174, 204, 232, 0.82);
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

.confirmation.detail-drawer {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
}

.confirmation.detail-drawer h2 {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
}

.confirmation.detail-grid {
    margin: 0.55rem 0;
    display: grid;
    grid-template-columns: minmax(120px, 0.9fr) minmax(0, 1.2fr);
    gap: 0.35rem 0.6rem;
}

.confirmation.detail-grid dt {
    color: var(--muted);
    font-size: 0.82rem;
}

.confirmation.detail-grid dd {
    margin: 0;
}

.confirmation.detail-id {
    margin-top: 0.1rem;
}

.confirmation.detail-time-sub {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.8rem;
    color: var(--muted);
}

.confirmation.detail-actions {
    margin: 0.65rem 0;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.confirmation.drawer-subheading {
    width: 100%;
    margin: 0 0 0.35rem;
    font-size: 0.84rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--muted);
}

.confirmation.action-status {
    width: 100%;
    margin-top: 0.2rem;
}

.confirmation.call-history-section {
    margin: 0.75rem 0 0;
}

.confirmation.call-history-list {
    list-style: none;
    margin: 0.35rem 0 0;
    padding: 0;
    max-height: 220px;
    overflow-y: auto;
}

.confirmation.call-history-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid rgba(148, 196, 255, 0.12);
    font-size: 0.88rem;
}

.confirmation.call-history-item:last-child {
    border-bottom: none;
}

.confirmation.call-history-time {
    flex: 1;
    min-width: 0;
    color: var(--text, #e8eef7);
}

.confirmation.call-history-by {
    flex-shrink: 0;
    color: var(--muted);
    font-size: 0.82rem;
}

.confirmation.slot-options {
    display: grid;
    gap: 0.45rem;
    margin-top: 0.65rem;
}

.confirmation.slot-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 10px;
    padding: 0.5rem 0.6rem;
    background: rgba(18, 28, 43, 0.44);
}

.confirmation.slot-option input[type="radio"] {
    margin: 0;
}

.confirmation.slot-option em {
    font-style: normal;
    color: var(--muted);
}

.confirmation.slot-option.is-disabled {
    opacity: 0.55;
}

.confirmation.remind-form,
.confirmation.notes-form {
    margin-top: 0.65rem;
    padding-top: 0.6rem;
    border-top: 1px solid rgba(148, 196, 255, 0.16);
}

.confirmation.notes-form {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
}

.confirmation.notes-form label {
    display: grid;
}

.confirmation.remind-form[hidden] {
    display: none;
}

.confirmation.remind-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.55rem;
    margin-bottom: 0.7rem;
}

.confirmation.remind-grid label {
    display: grid;
    gap: 0.3rem;
}

.confirmation.remind-grid span,
.confirmation.notes-form label span {
    color: var(--muted);
    font-size: 0.82rem;
}

.confirmation.remind-grid input,
.confirmation.remind-grid textarea,
.confirmation.notes-form textarea {
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.52rem 0.62rem;
    font: inherit;
}

.confirmation.remind-note {
    grid-column: 1 / -1;
}

.confirmation.notes-actions {
    margin-top: 0.55rem;
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.confirmation.notes-form textarea {
    flex: 1 1 auto;
    min-height: 170px;
}

.confirmation.reminder-preview {
    margin-top: 0.5rem;
    padding: 0.6rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 10px;
    background: rgba(18, 28, 43, 0.5);
}

.confirmation.reminder-preview-text {
    margin: 0.15rem 0 0;
    white-space: pre-wrap;
    word-break: break-word;
    font-size: 0.9rem;
}

.confirmation.reminder-preview-meta {
    margin: 0.35rem 0 0;
}

.confirmation.board-shell {
    margin-top: 0.2rem;
    width: 100%;
    padding-inline: 0.35rem;
    flex: 0 0 auto;
    min-height: 0;
    min-width: 0;
}

.confirmation.board-scroll {
    overflow: visible;
    height: auto;
    padding: 0.15rem 0 0.5rem;
    border-radius: 14px;
}

.confirmation.board-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(340px, 1fr));
    gap: 0.9rem;
    min-width: 0;
    height: auto;
    align-items: stretch;
}

.confirmation.lane {
    display: flex;
    flex-direction: column;
    height: 440px;
    min-height: 440px;
    overflow: hidden;
    padding: 0.72rem;
    border: 1px solid rgba(148, 196, 255, 0.28);
    background: linear-gradient(180deg, rgba(19, 29, 44, 0.95), rgba(12, 20, 31, 0.95));
    box-shadow: 0 12px 28px rgba(var(--shadow-rgb), 0.44);
}

.confirmation.lane-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.65rem;
    padding: 0.15rem 0.15rem 0.35rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.16);
    position: sticky;
    top: 0;
    z-index: 2;
    background: linear-gradient(180deg, rgba(19, 29, 44, 0.98), rgba(19, 29, 44, 0.9));
    backdrop-filter: blur(2px);
}

.confirmation.lane-header h2 {
    margin: 0;
    font-size: 0.98rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: 0.02em;
}

.confirmation.lane-count {
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.35);
    background: rgba(28, 43, 64, 0.62);
    color: var(--text);
    font-size: 0.76rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.22rem 0.5rem;
}

.confirmation.lane-call-now .confirmation.lane-count {
    border-color: rgba(255, 194, 130, 0.55);
    color: #ffe7c8;
}

.confirmation.lane-past-due .confirmation.lane-count {
    border-color: rgba(255, 123, 156, 0.55);
    color: #ffd6e2;
}

.confirmation.lane-body {
    display: flex;
    flex-direction: column;
    gap: 0.62rem;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.2rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(124, 190, 255, 0.65) rgba(9, 14, 24, 0.9);
}

.confirmation.job-card {
    display: grid;
    gap: 0.38rem;
    width: 100%;
    border-radius: 12px;
    border: 1px solid rgba(148, 196, 255, 0.24);
    background: linear-gradient(170deg, rgba(20, 31, 47, 0.92), rgba(12, 20, 31, 0.92));
    color: var(--text);
    text-align: left;
    padding: 0.72rem;
    cursor: pointer;
    box-shadow: 0 10px 20px rgba(var(--shadow-rgb), 0.36);
    transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
    text-decoration: none;
}

.confirmation.job-card:hover {
    transform: translateY(-1px);
    border-color: rgba(102, 214, 255, 0.52);
    box-shadow: 0 14px 26px rgba(var(--shadow-rgb), 0.45);
}

.confirmation.card-title-row {
    display: flex;
    align-items: center;
    gap: 0.42rem;
    min-width: 0;
}

.confirmation.card-call-symbol {
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    font-weight: 800;
    background: rgba(255, 152, 88, 0.25);
    color: #ffdcb9;
    border: 1px solid rgba(255, 197, 129, 0.48);
    flex: 0 0 auto;
}

.confirmation.card-title {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.confirmation.card-title-row .confirmation.id-pill {
    margin-top: 0;
    flex: 0 1 48%;
    min-width: 68px;
    max-width: 48%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.confirmation.card-employee {
    margin: 0;
    color: var(--text);
    font-size: 0.85rem;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.confirmation.card-schedule {
    margin: 0;
    color: var(--text);
    font-size: 0.82rem;
    display: flex;
    align-items: center;
    gap: 0.34rem;
    flex-wrap: wrap;
    line-height: 1.3;
}

.confirmation.card-location {
    margin: 0;
    color: #b6cae0;
    font-size: 0.79rem;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.confirmation.card-note {
    margin: 0.15rem 0 0;
    color: var(--text);
    font-size: 0.79rem;
    line-height: 1.34;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}

.confirmation.save-toast {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 10050;
    border-radius: 10px;
    border: 1px solid rgba(102, 214, 255, 0.45);
    background: linear-gradient(170deg, rgba(26, 94, 122, 0.94), rgba(22, 62, 124, 0.94));
    color: var(--text);
    padding: 0.5rem 0.75rem;
    box-shadow: 0 12px 24px rgba(var(--shadow-rgb), 0.45);
    font-size: 0.84rem;
    font-weight: 650;
}

.confirmation.save-toast.is-error {
    border-color: rgba(255, 123, 156, 0.5);
    background: linear-gradient(170deg, rgba(131, 44, 73, 0.94), rgba(89, 28, 55, 0.94));
}

.confirmation.id-pill {
    display: inline-flex;
    margin-top: 0.25rem;
    border-radius: 999px;
    border: 1px solid rgba(140, 125, 255, 0.45);
    background: rgba(54, 43, 94, 0.35);
    color: #d9cbff;
    font-size: 0.72rem;
    padding: 0.13rem 0.5rem;
    letter-spacing: 0.01em;
}

.confirmation.time-bubble {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 84px;
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.5);
    background: linear-gradient(135deg, rgba(25, 90, 115, 0.72), rgba(46, 52, 137, 0.7));
    color: #dff6ff;
    font-weight: 650;
    font-size: 0.82rem;
    padding: 0.2rem 0.55rem;
    box-shadow: 0 0 0 1px rgba(102, 214, 255, 0.18), 0 0 16px rgba(102, 214, 255, 0.2);
}

.confirmation.flash {
    margin-bottom: 0.8rem;
}

.confirmation.action-form {
    margin: 0;
}

.confirmation.action-btn {
    font-size: 0.82rem;
    font-weight: 650;
    padding: 0.35rem 0.55rem;
}

.confirmation.modal-actions .confirmation.action-btn {
    width: auto;
    min-width: 104px;
}

/* Action-button color semantics — pinned to the Semantic Color Reservations
   table in docs/AI_STYLE_GUIDE.md.
     * is-cfm                → GREEN (success / confirm)
     * is-nogo               → RED (destructive)
     * is-cancel-disposition → RED ghost (also destructive, slightly cooler)
     * is-remind             → NEON ORANGE (warning / "needs follow-up")
     * is-cancel             → neutral close/back. */
.confirmation.action-btn.is-cfm {
    border-color: rgba(34, 197, 94, 0.6);
    background: linear-gradient(170deg, rgba(22, 122, 60, 0.92), rgba(20, 84, 50, 0.92));
    color: var(--success-bg);
}
.confirmation.action-btn.is-cfm:hover:not(:disabled) {
    border-color: rgba(34, 197, 94, 0.85);
    background: linear-gradient(170deg, rgba(28, 150, 75, 0.95), rgba(24, 104, 60, 0.95));
}

.confirmation.action-btn.is-nogo {
    border-color: rgba(239, 68, 68, 0.6);
    background: linear-gradient(170deg, rgba(143, 38, 50, 0.9), rgba(92, 24, 40, 0.9));
    color: var(--danger-ink);
}
.confirmation.action-btn.is-nogo:hover:not(:disabled) {
    border-color: rgba(239, 68, 68, 0.85);
    background: linear-gradient(170deg, rgba(168, 48, 60, 0.95), rgba(118, 32, 50, 0.95));
}

.confirmation.action-btn.is-remind {
    border-color: rgba(255, 122, 0, 0.6);
    background: linear-gradient(170deg, rgba(160, 70, 10, 0.9), rgba(110, 50, 12, 0.9));
    color: var(--warning-bg);
}
.confirmation.action-btn.is-remind:hover:not(:disabled) {
    border-color: rgba(255, 122, 0, 0.85);
    background: linear-gradient(170deg, rgba(190, 90, 18, 0.95), rgba(140, 64, 18, 0.95));
}

.confirmation.action-btn.is-cancel {
    border-color: rgba(148, 196, 255, 0.32);
    background: linear-gradient(170deg, rgba(34, 52, 76, 0.88), rgba(22, 33, 49, 0.88));
}
.confirmation.action-btn.is-cancel:hover:not(:disabled) {
    border-color: rgba(148, 196, 255, 0.55);
    background: linear-gradient(170deg, rgba(46, 68, 96, 0.92), rgba(30, 44, 64, 0.92));
}

.confirmation.action-btn.is-cancel-disposition {
    border-color: rgba(248, 113, 113, 0.5);
    background: linear-gradient(170deg, rgba(120, 38, 36, 0.9), rgba(78, 28, 30, 0.9));
    color: var(--danger-bg);
}
.confirmation.action-btn.is-cancel-disposition:hover:not(:disabled) {
    border-color: rgba(248, 113, 113, 0.75);
    background: linear-gradient(170deg, rgba(140, 50, 50, 0.92), rgba(96, 38, 40, 0.92));
}

.confirmation.note-modal-label {
    display: grid;
    gap: 0.35rem;
    margin-top: 0.65rem;
}

.confirmation.note-modal-label span {
    color: var(--muted);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-weight: 620;
}

.confirmation.note-modal-textarea {
    width: 100%;
    min-height: 96px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.56rem 0.66rem;
    font: inherit;
    line-height: 1.35;
    resize: vertical;
}

.confirmation.note-modal-error {
    margin: 0.35rem 0 0;
    color: #ffb4b4;
    font-size: 0.85rem;
}

.confirmation.remind-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin: 0.65rem 0 0.85rem;
}

.confirmation.remind-preset-btn {
    font-size: 0.78rem;
    padding: 0.32rem 0.5rem;
}

.confirmation.detail-hit {
    display: block;
    width: 100%;
    margin: 0;
    padding: 0.2rem 0.35rem;
    text-align: left;
    background: transparent;
    border: none;
    border-radius: 8px;
    color: inherit;
    font: inherit;
    line-height: 1.35;
    cursor: pointer;
}

.confirmation.detail-hit:hover,
.confirmation.detail-hit:focus-visible {
    background: rgba(102, 214, 255, 0.1);
    outline: none;
}

.confirmation.detail-hit-inline {
    display: inline;
    width: auto;
    padding: 0.05rem 0.2rem;
}

.confirmation.detail-hit-main {
    display: block;
    font-weight: 650;
}

.confirmation.detail-hit-sub {
    display: block;
    margin-top: 0.15rem;
}

.confirmation.detail-cell.is-readonly {
    padding: 0.2rem 0.35rem;
    opacity: 0.92;
}

.confirmation.detail-edit-body {
    margin-top: 0.5rem;
}

.confirmation.detail-edit-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.65rem;
}

.confirmation.detail-edit-grid.is-stack {
    grid-template-columns: 1fr;
}

@media (max-width: 520px) {
    .confirmation.detail-edit-grid {
        grid-template-columns: 1fr;
    }
}

.confirmation.time-bubble.is-remind-at {
    border-color: rgba(140, 125, 255, 0.52);
    background: linear-gradient(140deg, rgba(87, 67, 178, 0.86), rgba(42, 40, 112, 0.84));
    box-shadow: 0 0 0 1px rgba(140, 125, 255, 0.2), 0 0 16px rgba(140, 125, 255, 0.28);
}

.confirmation.time-bubble.is-created-at {
    border-color: rgba(255, 194, 130, 0.5);
    background: linear-gradient(140deg, rgba(120, 82, 36, 0.78), rgba(85, 62, 31, 0.78));
    color: #ffe9cf;
    box-shadow: 0 0 0 1px rgba(255, 194, 130, 0.2), 0 0 14px rgba(255, 194, 130, 0.2);
}

.confirmation.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(4, 9, 16, 0.74);
    isolation: isolate;
}

.confirmation.modal-backdrop[hidden] {
    display: none;
}

.confirmation.modal-card {
    position: relative;
    z-index: 1;
    width: min(460px, calc(100vw - 1.5rem));
    max-height: calc(100vh - 1.5rem);
    overflow: auto;
    border: 1px solid rgba(148, 196, 255, 0.3);
    border-radius: 14px;
    padding: 1rem;
    background: linear-gradient(180deg, rgba(21, 33, 50, 0.98), rgba(14, 22, 34, 0.98));
    box-shadow: 0 20px 48px rgba(var(--shadow-rgb), 0.65);
    pointer-events: auto;
}

/* Block clicks on inbox/drawer while a modal is open (prevents click-through). */
body.confirmation-modal-open {
    overflow: hidden;
}

body.confirmation-modal-open .confirmation.page-root {
    pointer-events: none;
    user-select: none;
}

.confirmation.modal-card.is-large {
    width: min(920px, calc(100vw - 1.5rem));
}

.confirmation.modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}

.confirmation.modal-head h3 {
    margin: 0;
}

.confirmation.modal-grid {
    margin-top: 0.75rem;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.68rem;
}

.confirmation.form-field.is-full {
    grid-column: 1 / -1;
}

.confirmation .js-readonly {
    opacity: 0.88;
}

.confirmation.modal-card h3 {
    margin: 0;
}

.confirmation.modal-form {
    margin-top: 0.75rem;
}

.confirmation.form-field {
    display: grid;
    gap: 0.35rem;
    margin-bottom: 0;
    min-width: 0;
}

.confirmation.form-field span {
    color: var(--muted);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-weight: 620;
}

.confirmation.form-field input,
.confirmation.form-field textarea {
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.56rem 0.66rem;
    font: inherit;
    line-height: 1.35;
    width: 100%;
    min-width: 0;
}

.confirmation.form-field textarea {
    resize: vertical;
    min-height: 96px;
}

.confirmation.modal-actions {
    margin-top: 0.9rem;
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}

.confirmation.lane-body::-webkit-scrollbar {
    width: 7px;
    height: 7px;
}

.confirmation.lane-body::-webkit-scrollbar-track {
    background: rgba(10, 16, 27, 0.9);
    border-radius: 999px;
}

.confirmation.lane-body::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(114, 203, 255, 0.85), rgba(119, 130, 255, 0.82));
    border-radius: 999px;
    border: 1px solid rgba(10, 16, 27, 0.85);
}

.confirmation.lane-body::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, rgba(138, 214, 255, 0.95), rgba(141, 150, 255, 0.94));
}

@media (min-width: 1024px) {
    .layout-main.is-confirmation .confirmation.flash,
    .layout-main.is-confirmation .confirmation.board-shell {
        width: 100%;
        max-width: none;
        margin-left: 0;
    }
}

@media (max-width: 640px) {
    .admin.users-layout {
        grid-template-columns: 1fr;
    }

    .admin.quick-links {
        width: 100%;
    }

    .admin.quick-links .btn {
        flex: 1 1 auto;
        text-align: center;
    }

    .employee.stats-tabs {
        flex-wrap: wrap;
    }

    .employee.stats-tab {
        flex: 1 1 calc(50% - 0.25rem);
    }

    .confirmation.modal-grid {
        grid-template-columns: 1fr;
    }

    .confirmation.modal-actions {
        justify-content: stretch;
    }

    .confirmation.modal-actions .confirmation.action-btn {
        width: 100%;
    }

    .confirmation.board-grid {
        grid-template-columns: 1fr;
    }

    .confirmation.lane {
        height: 400px;
        min-height: 400px;
    }

    .confirmation.remind-grid {
        grid-template-columns: 1fr;
    }

    .confirmation.inbox-filters {
        width: 100%;
    }

    .confirmation.inbox-filter {
        min-width: 0;
        flex: 1 1 100%;
    }

    .confirmation.notes-actions .btn {
        width: 100%;
    }
}

@media (max-width: 1080px) {
    .layout-main.is-confirmation {
        padding: 0.45rem 0.2rem 0.3rem;
    }

    .confirmation.board-grid {
        grid-template-columns: repeat(2, minmax(300px, 1fr));
    }

    .confirmation.modal-card.is-large {
        width: min(860px, calc(100vw - 1rem));
    }

    .confirmation.inbox-layout {
        grid-template-columns: 1fr;
    }

    .confirmation.detail-drawer {
        position: static;
        min-height: 0;
    }

    .confirmation.inbox-col-time {
        width: 98px;
    }

    .confirmation.inbox-col-jnstatus {
        width: 120px;
        max-width: 22%;
    }

    .confirmation.inbox-col-first {
        width: 190px;
    }

    .confirmation.inbox-col-last {
        width: 130px;
    }

    .confirmation.inbox-col-product {
        width: 150px;
    }
}

@media (max-width: 860px) {
    .confirmation.board-grid {
        grid-template-columns: 1fr;
    }
}

.employee.stats-dept-hint {
    margin: 0 0 1rem;
    font-size: 0.88rem;
}

.employee.stats-dept-hint code {
    font-size: 0.82em;
}

.employee.stats-filters {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 0.8rem;
    align-items: end;
}

.employee.stats-filter-panel {
    position: relative;
    z-index: 4;
    overflow: visible;
}

.employee.field-group {
    display: grid;
    gap: 0.35rem;
}

.employee.calendar-group {
    min-width: 280px;
}

.employee.field-group label {
    color: var(--muted);
    font-size: 0.84rem;
}

.employee.field-group input,
.employee.field-group select {
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.58rem 0.7rem;
}

.employee.week-picker {
    position: relative;
}

.employee.week-picker-toggle {
    width: 100%;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.58rem 0.7rem;
    text-align: left;
    cursor: pointer;
}

.employee.week-picker-toggle:hover,
.employee.week-picker-toggle:focus-visible {
    border-color: rgba(102, 214, 255, 0.55);
    outline: none;
}

.employee.week-picker-menu {
    position: absolute;
    top: calc(100% + 0.45rem);
    left: 0;
    z-index: 20;
    width: min(100%, 360px);
    min-width: 300px;
    border-radius: 12px;
    border: 1px solid rgba(148, 196, 255, 0.24);
    background: rgba(15, 24, 38, 0.98);
    box-shadow: 0 14px 30px rgba(var(--shadow-rgb), 0.28);
    padding: 0.6rem;
}

.employee.week-picker-toolbar {
    display: grid;
    grid-template-columns: 2rem 1fr 2rem;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.45rem;
}

.employee.week-picker-nav {
    border: 1px solid rgba(148, 196, 255, 0.24);
    border-radius: 8px;
    background: rgba(24, 38, 58, 0.88);
    color: var(--text);
    min-height: 1.9rem;
    cursor: pointer;
}

.employee.week-picker-nav:hover {
    border-color: rgba(102, 214, 255, 0.62);
    background: rgba(33, 50, 76, 0.95);
}

.employee.week-picker-month-label {
    text-align: center;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
}

.employee.week-picker-head {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.2rem;
    margin-bottom: 0.35rem;
    color: var(--muted);
    font-size: 0.74rem;
    letter-spacing: 0.04em;
    text-align: center;
}

.employee.week-picker-hint {
    margin: 0 0 0.45rem;
    font-size: 0.76rem;
}

.employee.week-picker-weeks {
    display: grid;
    gap: 0.22rem;
}

.employee.week-picker-row {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.2rem;
    border: 1px solid transparent;
    border-radius: 9px;
    background: rgba(27, 42, 64, 0.6);
    color: var(--text);
    padding: 0.2rem;
}

.employee.week-picker-row:hover {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(35, 53, 80, 0.82);
}

.employee.week-picker-row.is-selected {
    border-color: rgba(102, 214, 255, 0.78);
    background: rgba(102, 214, 255, 0.2);
}

.employee.week-picker-daybtn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 1.75rem;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--text);
    padding: 0;
    cursor: pointer;
}

.employee.week-picker-daybtn:hover {
    background: rgba(102, 214, 255, 0.12);
}

.employee.week-picker-daybtn.is-selected {
    background: rgba(102, 214, 255, 0.2);
}

.employee.week-picker-daynum {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 1.45rem;
    min-width: 1.45rem;
    border-radius: 7px;
    font-size: 0.82rem;
    font-weight: 600;
}

.employee.week-picker-daybtn.is-outside {
    opacity: 0.45;
    font-weight: 500;
}

.employee.week-picker-noscript {
    display: grid;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.employee.filter-actions {
    display: flex;
    justify-content: flex-start;
}

.employee.stats-cards {
    margin-top: 1rem;
}

.employee.stats-body {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin-top: 1rem;
}

.employee.stats-section-title {
    margin: 0 0 0.35rem;
    font-size: 1.15rem;
    font-weight: 650;
}

.employee.stats-section-intro {
    margin: 0 0 1rem;
}

.employee.stats-subpanel {
    margin-top: 1rem;
}

.employee.stats-subheading {
    margin: 0 0 0.6rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
}

/* Employee-stats jobs table: kept compact + readable. The Job ID
   column is demoted (muted color, tabular-num) so the eye lands on
   Customer / Date / status labels first. */
.employee.stats-jobs-table th,
.employee.stats-jobs-table td {
    vertical-align: middle;
}

.employee.stats-jobs-id-col {
    color: rgba(180, 196, 220, 0.55);
    font-feature-settings: "tnum" 1;
    font-variant-numeric: tabular-nums;
    font-size: 0.9em;
    text-align: right;
    white-space: nowrap;
}

.employee.stats-channel-cards {
    margin-top: 0.25rem;
}

.employee.stats-section .stats.card {
    background: linear-gradient(180deg, rgba(20, 31, 47, 0.78), rgba(14, 23, 35, 0.78));
    border-color: rgba(148, 196, 255, 0.2);
}

.stats.card h2,
.stats.card h3 {
    margin-bottom: 0.35rem;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--muted);
}

.stats.value {
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1.1;
}

.progress.track {
    width: 100%;
    height: 0.8rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: rgba(148, 196, 255, 0.14);
    overflow: hidden;
}

.progress.fill {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, var(--accent), var(--accent-2));
}

.stats.progress-meta {
    margin-top: 0.55rem;
    display: flex;
    align-items: center;
    gap: 0.32rem;
    color: var(--muted);
}

.employee.goal-person-line {
    margin: 0 0 0.2rem;
}

.employee.goal-range-line {
    margin: 0 0 0.6rem;
}

.employee.goal-progress-block + .employee.goal-progress-block {
    margin-top: 0.8rem;
}

.progress.pct {
    margin-left: auto;
    color: var(--text);
    font-weight: 600;
}

/* ATSB workspace — shared tokens for the `/atsb-availability/test` remake and calendar UI */
.atsb-ws {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.atsb-ws-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (min-width: 1280px) {
    .atsb-ws-grid {
        grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
    }
}

.atsb-ws-col {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0;
}

.atsb-ws-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.75rem;
    align-items: center;
    margin: 0.55rem 0 0;
    font-size: 0.88rem;
    color: var(--muted);
}

.atsb-ws-links a {
    color: var(--accent);
}

.atsb-ws-links-sep {
    opacity: 0.5;
}

.atsb-ws-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin: 0 0 0.6rem;
}

.atsb-ws-section-head h2 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.atsb-ws-section-sub {
    margin: 0;
    color: var(--muted);
    font-size: 0.86rem;
}

.atsb-ws-sync-out {
    font-size: 0.88rem;
    color: var(--muted);
}

.atsb-ws-sync-out.is-ok {
    color: #a7f3d0;
}

.atsb-ws-sync-out.is-err {
    color: var(--danger);
}

/* Slots panel */
.atsb-slots-panel {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.atsb-slots-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.atsb-slots-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.atsb-slots-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

.atsb-slots-meta {
    margin: 0;
    font-size: 0.86rem;
    color: var(--muted);
}

.atsb-slots-hint {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted);
}

.atsb-slots-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: rgba(12, 18, 28, 0.55);
}

.atsb-slots-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.atsb-slots-table thead th {
    position: sticky;
    top: 0;
    background: linear-gradient(180deg, rgba(18, 28, 43, 0.95), rgba(13, 20, 31, 0.92));
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    font-size: 0.72rem;
}

.atsb-slots-table th,
.atsb-slots-table td {
    text-align: left;
    padding: 0.55rem 0.75rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.1);
}

.atsb-slots-table tbody tr:nth-child(odd) td {
    background: rgba(102, 214, 255, 0.025);
}

.atsb-slots-table tbody tr:hover td {
    background: rgba(102, 214, 255, 0.06);
}

.atsb-slots-table tbody tr:last-child td {
    border-bottom: none;
}

.atsb-slots-table td code {
    font-size: 0.82em;
    color: var(--accent);
}

.atsb-slots-placeholder td {
    color: var(--muted);
    font-style: italic;
}

/* ATSB-style availability planner — Mon–Sun week grid with 2×2 slot blocks per period/day.
   Mirrors the original ATSB UI (atsb-ui.js / atsb-ui.css): 6 rows × 14 cols, 3 periods (M/A/E)
   rowspanned by 2, 7 weekdays colspanned by 2, each slot a toggleable "X" button.            */

.atsb-planner {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.atsb-planner-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.atsb-planner-title {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    color: var(--accent);
}

.atsb-planner-sub {
    margin: 0.2rem 0 0;
    color: var(--muted);
    font-size: 0.9rem;
    max-width: 68ch;
    line-height: 1.5;
}

.atsb-planner-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.atsb-planner-settings {
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(19, 31, 47, 0.85), rgba(12, 19, 30, 0.78));
    padding: 0.9rem;
    display: grid;
    gap: 0.75rem;
}

.atsb-planner-settings[hidden] {
    display: none;
}

.atsb-planner-settings-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.atsb-planner-settings-head h3 {
    margin: 0;
    font-size: 1rem;
    color: var(--text);
}

.atsb-planner-settings-sub {
    margin: 0;
    color: var(--muted);
    font-size: 0.84rem;
}

.atsb-planner-settings-grid {
    display: grid;
    grid-template-columns: minmax(120px, 260px);
    gap: 0.75rem;
}

.atsb-planner-settings-grid label {
    display: grid;
    gap: 0.35rem;
    font-size: 0.8rem;
    color: var(--muted);
}

.atsb-planner-settings-grid input {
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text);
    padding: 0.42rem 0.55rem;
    font-size: 0.9rem;
}

.atsb-planner-settings-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.atsb-planner-monthrow {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.atsb-planner-monthlabel {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 700;
    color: var(--muted);
}

.atsb-planner-monthinput {
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text);
    padding: 0.4rem 0.6rem;
    font-size: 0.95rem;
    font-family: inherit;
    min-width: 10rem;
}

.atsb-planner-monthinput:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.25);
}

.atsb-planner-hint {
    font-size: 0.8rem;
    color: var(--muted);
    margin-left: auto;
}

.atsb-planner-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.atsb-planner-tab {
    appearance: none;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.35rem 0.75rem;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.atsb-planner-tab:hover {
    border-color: var(--accent);
    color: var(--text);
}

.atsb-planner-tab.is-active {
    background: linear-gradient(180deg, rgba(91, 158, 255, 0.24), rgba(91, 158, 255, 0.12));
    border-color: rgba(140, 188, 255, 0.7);
    color: var(--text);
    box-shadow: 0 0 0 1px rgba(140, 188, 255, 0.28);
}

.atsb-planner-weeknav {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 0.75rem;
}

.atsb-planner-weeklabel {
    margin: 0;
    text-align: center;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    color: var(--text);
}

.atsb-planner-gridwrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: rgba(12, 18, 28, 0.6);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
    /* Right-edge fade — only visible while there's still horizontal room
       to scroll. Tells operators on mobile that Sat/Sun continue past
       the visible viewport. */
    position: relative;
    background-image:
        linear-gradient(to right, transparent calc(100% - 36px), rgba(7, 11, 18, 0.55) 100%);
    background-attachment: local, scroll;
    background-repeat: no-repeat;
}

@media (max-width: 720px) {
    /* On phones, drop the day-column min-width so 4–5 days are visible
       at a time instead of 3 — and the right-edge fade still hints
       there's more to scroll to. */
    .atsb-planner-dayhead {
        min-width: 4.4rem;
    }
    .atsb-planner-corner {
        width: 2.4rem;
    }
    .atsb-planner-grid {
        font-size: 0.82rem;
    }
}

.atsb-planner-grid {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.92rem;
    table-layout: fixed;
}

.atsb-planner-grid thead th {
    padding: 0.55rem 0.3rem 0.7rem;
    background: linear-gradient(180deg, rgba(18, 28, 43, 0.95), rgba(13, 20, 31, 0.9));
    border-bottom: 1px solid var(--border);
    text-align: center;
    vertical-align: middle;
}

.atsb-planner-corner {
    width: 3.2rem;
}

.atsb-planner-dayhead {
    color: var(--text);
    font-weight: 600;
    min-width: 5.5rem;
}

.atsb-planner-dayhead.is-pad {
    opacity: 0.42;
}

.atsb-planner-dayhead.is-today {
    background: linear-gradient(180deg, rgba(91, 158, 255, 0.16), rgba(91, 158, 255, 0.05));
    box-shadow: inset 0 -2px 0 rgba(140, 188, 255, 0.55);
}

.atsb-planner-dayhead-text {
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--text);
    margin-top: 0.35rem;
}

.atsb-planner-dayhead.is-pad .atsb-planner-dayhead-text {
    color: var(--muted);
}

.atsb-planner-send {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: rgba(18, 28, 43, 0.6);
    color: var(--muted);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    cursor: pointer;
    user-select: none;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.atsb-planner-send input {
    appearance: none;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 3px;
    border: 1px solid var(--border);
    background: rgba(10, 16, 24, 0.8);
    margin: 0;
    position: relative;
    cursor: pointer;
}

.atsb-planner-send input:checked {
    background: #5b9eff;
    border-color: #8cbcff;
}

.atsb-planner-send input:checked::after {
    content: "";
    position: absolute;
    left: 0.15rem;
    top: 0.02rem;
    width: 0.18rem;
    height: 0.38rem;
    border: solid #0a0e14;
    border-width: 0 0.1rem 0.1rem 0;
    transform: rotate(45deg);
}

.atsb-planner-send.is-on {
    border-color: rgba(140, 188, 255, 0.6);
    background: rgba(91, 158, 255, 0.14);
    color: var(--text);
}

.atsb-planner-send.is-disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.atsb-planner-grid tbody th.atsb-planner-period {
    text-align: center;
    padding: 0.4rem 0.3rem;
    font-size: 0.9rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--muted);
    background: rgba(91, 158, 255, 0.04);
    border-right: 1px solid var(--border);
    white-space: nowrap;
    vertical-align: middle;
}

.atsb-planner-cell {
    position: relative;
    padding: 0.2rem;
    text-align: center;
    vertical-align: middle;
    border-bottom: 1px solid rgba(148, 196, 255, 0.08);
    border-left: 1px solid rgba(148, 196, 255, 0.04);
    background: rgba(12, 18, 28, 0.35);
    transition: background 0.1s ease;
}

.atsb-planner-cell.is-pad {
    background: rgba(8, 12, 18, 0.55);
}

.atsb-planner-cell.is-today {
    background: rgba(91, 158, 255, 0.05);
}

.atsb-planner-cell.is-active {
    background: linear-gradient(165deg, rgba(56, 20, 34, 0.42), rgba(32, 14, 22, 0.42));
}

.atsb-planner-slot {
    display: block;
    width: 100%;
    min-height: 2.1rem;
    padding: 0.15rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: rgba(18, 28, 43, 0.6);
    color: transparent;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.1s ease, border-color 0.1s ease, color 0.1s ease, transform 0.06s ease;
}

.atsb-planner-slot:hover:not(:disabled) {
    border-color: rgba(140, 188, 255, 0.55);
    background: rgba(91, 158, 255, 0.14);
}

.atsb-planner-slot:active:not(:disabled) {
    transform: scale(0.96);
}

.atsb-planner-slot:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.3);
}

.atsb-planner-slot[data-active="true"] {
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.38), rgba(188, 46, 46, 0.42));
    border-color: rgba(248, 113, 113, 0.7);
    color: var(--danger-ink);
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}

.atsb-planner-slot:disabled {
    cursor: not-allowed;
    opacity: 0.35;
}

.atsb-planner-summary {
    margin: 0;
    padding: 0.7rem 0.85rem;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: rgba(12, 18, 28, 0.45);
    font-size: 0.92rem;
    color: var(--text);
    line-height: 1.5;
}

.atsb-planner-summary em {
    color: var(--accent);
    font-style: normal;
    font-weight: 700;
}

.atsb-planner-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.atsb-planner-dirty {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.55rem;
    border-radius: 999px;
    background: rgba(255, 197, 96, 0.12);
    border: 1px solid rgba(255, 197, 96, 0.3);
    color: #ffd291;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    margin-right: auto;
}
/* Honour the HTML `hidden` attribute — without this rule the
   `display: inline-flex` above wins over the user-agent default
   `[hidden] { display: none }`, so the dirty badge would render
   on a fresh planner load even though `setDirty(false)` set
   `hidden=true`. */
.atsb-planner-dirty[hidden] {
    display: none;
}

.atsb-planner-dirty::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: #ffc460;
    box-shadow: 0 0 8px rgba(255, 197, 96, 0.6);
}

.atsb-planner-status {
    font-size: 0.82rem;
    color: var(--muted);
}

.atsb-planner-status[data-state="success"] { color: #86efac; }
.atsb-planner-status[data-state="error"]   { color: #fecaca; }
.atsb-planner-status[data-state="sending"] { color: #fcd34d; }

@media (max-width: 720px) {
    .atsb-planner-settings-grid {
        grid-template-columns: 1fr;
    }
}

/* =========================================================================
   ATSB TEST PAGE REDESIGN
   --------------------------------------------------------------------------
   Scoped strictly under `.atsb-ws` (the wrapper used only by
   /atsb-availability/test). Live `/atsb-calendar` is NOT wrapped in
   `.atsb-ws`, so none of these rules affect the live planner.
   --------------------------------------------------------------------------
   Redesign goals:
     - Trim hero to a single-line title + tagline.
     - Consolidate week picker, week navigation, settings, and clear into
       one toolbar bar above the grid.
     - Make the grid the visual focus (taller cells, clearer Send pill,
       per-period color hint, stronger today indicator).
     - Sticky publish bar at the bottom of the planner card.
     - Mobile: stack toolbar groups full-width, keep the grid scrollable.
   ========================================================================= */

/* Hero compaction (test page only) */
.atsb-ws-hero {
    padding-bottom: 0.4rem;
}
.atsb-ws-hero-row {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    flex-wrap: wrap;
}
.atsb-ws-hero-row h1 {
    margin: 0;
}
.atsb-ws-hero-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    border: 1px solid rgba(140, 188, 255, 0.45);
    background: rgba(91, 158, 255, 0.14);
    color: var(--text);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.atsb-ws-hero-sub {
    margin: 0.35rem 0 0;
    color: var(--muted);
    font-size: 0.92rem;
    line-height: 1.45;
    max-width: 70ch;
}

/* Test wrapper: a little extra breathing room */
.atsb-ws-test {
    gap: 1rem;
}

/* Allow viewport-sticky publish bar to escape the panel's clip context */
.atsb-ws .atsb-test-planner.panel {
    overflow: visible;
}

/* Hide the legacy planner head (replaced by titlebar + toolbar) */
.atsb-ws .atsb-planner-head {
    display: none;
}
/* Hide the legacy week-nav row (its controls are now inside the toolbar) */
.atsb-ws .atsb-planner-weeknav {
    display: none;
}

/* Title bar */
.atsb-ws .atsb-test-titlebar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.08);
}
.atsb-ws .atsb-test-titlebar-main {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}
.atsb-ws .atsb-test-title {
    margin: 0;
    font-size: 1.25rem;
    color: var(--accent);
}
.atsb-ws .atsb-test-tagline {
    margin: 0;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.4;
}
.atsb-ws .atsb-test-tagline em {
    color: var(--text);
    font-style: normal;
    font-weight: 600;
}
.atsb-ws .atsb-test-hint {
    margin: 0;
    font-size: 0.78rem;
    color: var(--muted);
    white-space: nowrap;
}

/* Toolbar */
.atsb-ws .atsb-test-toolbar {
    display: grid;
    grid-template-columns: minmax(220px, 1.1fr) minmax(220px, 1.4fr) auto;
    align-items: center;
    gap: 0.6rem 0.9rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(18, 28, 43, 0.7), rgba(13, 20, 31, 0.65));
}
.atsb-ws .atsb-test-toolbar-group {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
}
.atsb-ws .atsb-test-toolbar-picker {
    justify-content: flex-start;
}
.atsb-ws .atsb-test-toolbar-picker .employee.week-picker {
    width: 100%;
}
.atsb-ws .atsb-test-toolbar-picker .employee.week-picker-toggle {
    width: 100%;
    justify-content: space-between;
}
.atsb-ws .atsb-test-toolbar-nav {
    justify-content: center;
}
.atsb-ws .atsb-test-weekstep {
    min-width: 2.4rem;
    padding-inline: 0.65rem;
    font-size: 1.1rem;
    line-height: 1;
}
.atsb-ws .atsb-test-weeklabel {
    margin: 0;
    flex: 1;
    text-align: center;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.atsb-ws .atsb-test-toolbar-actions {
    justify-content: flex-end;
    flex-wrap: wrap;
}

/* Settings panel: render as a popover-style card under the toolbar */
.atsb-ws .atsb-test-settings {
    margin: -0.4rem 0 0;
    border-radius: 12px;
    border-color: rgba(140, 188, 255, 0.35);
    box-shadow: 0 8px 24px rgba(var(--shadow-rgb), 0.35);
}

/* Grid wrapper polish */
.atsb-ws .atsb-test-gridwrap {
    border-radius: 14px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.04),
        0 4px 16px rgba(var(--shadow-rgb), 0.25);
}

/* Grid: taller, easier to scan */
.atsb-ws .atsb-test-grid {
    font-size: 0.95rem;
}
.atsb-ws .atsb-test-grid .atsb-planner-corner {
    width: 2.8rem;
}
.atsb-ws .atsb-test-grid .atsb-planner-dayhead {
    min-width: 5.2rem;
    padding-block: 0.6rem 0.7rem;
}
/* Active source day = the day actually being planned for (defaults to
   tomorrow). The cue is a TOP accent + a "Setting" chip — never a bottom
   bar — so it doesn't visually collide with the period dividers below
   the header. The literal "today" indicator is intentionally retired on
   the test page (the planning day is what matters here). */
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-today {
    /* Neutralize the inherited "today" bottom bar from the global rule. */
    background: transparent;
    box-shadow: none;
}
/* SETTING band — the next 3 days the user is actively planning for.
   Uses GREEN (34, 197, 94) — see Semantic Color Reservations in
   docs/AI_STYLE_GUIDE.md. The visual treatment is intentionally split:
     * Day HEADER carries the top accent stripe + edge glows so the band
       reads as one continuous block above the grid.
     * Body CELLS only get a translucent background tint — NO box-shadow,
       because the per-period (M/A/E) horizontal dividers are themselves
       drawn with `box-shadow` on every <td>. Adding a competing shadow on
       the cells would override the period rail and produce stray colored
       horizontal stripes inside the band. */
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-active-day {
    background: linear-gradient(180deg,
        rgba(34, 197, 94, 0.22),
        rgba(34, 197, 94, 0.04));
    box-shadow: inset 0 3px 0 rgba(34, 197, 94, 0.9);
}
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-active-day.is-active-day-first {
    box-shadow:
        inset 0 3px 0 rgba(34, 197, 94, 0.9),
        inset 2px 0 0 rgba(34, 197, 94, 0.6);
}
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-active-day.is-active-day-last {
    box-shadow:
        inset 0 3px 0 rgba(34, 197, 94, 0.9),
        inset -2px 0 0 rgba(34, 197, 94, 0.6);
}
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-active-day.is-active-day-first.is-active-day-last {
    box-shadow:
        inset 0 3px 0 rgba(34, 197, 94, 0.9),
        inset 2px 0 0 rgba(34, 197, 94, 0.6),
        inset -2px 0 0 rgba(34, 197, 94, 0.6);
}
/* Body cells: background tint only — must NOT set box-shadow (period rails
   live on td.box-shadow and would be overridden). */
.atsb-ws .atsb-test-grid .atsb-planner-cell.is-active-day {
    background-color: rgba(34, 197, 94, 0.06);
}
.atsb-ws .atsb-test-setting-chip {
    display: inline-block;
    margin-top: 0.3rem;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    /* Saturated green to clearly read as the SETTING color (matches the
       green band that spans the next 3 days). Pale text colors on a low-
       alpha background were reading as teal — a brighter hue + heavier
       background fixes the perceived hue. */
    background: rgba(34, 197, 94, 0.45);
    border: 1px solid rgba(34, 197, 94, 0.85);
    color: var(--success-bg);
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1.3;
}

/* Invisible chip placeholder — matches the dimensions of a real SETTING /
   SAME DAY chip so day-headers without a chip keep the same overall height
   and the day-text label aligns vertically across all 7 columns. */
.atsb-ws .atsb-test-chip-placeholder {
    display: inline-block;
    margin-top: 0.3rem;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    border: 1px solid transparent;
    color: transparent;
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1.3;
    visibility: hidden;
    pointer-events: none;
    user-select: none;
}

/* SAME DAY column — today. NEON ORANGE (255, 122, 0) — distinct from
   morning amber (255, 200, 102). Same split treatment as SETTING:
   header carries the accent + edge glows, cell only carries a tint. */
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-same-day {
    background: linear-gradient(180deg,
        rgba(255, 122, 0, 0.28),
        rgba(255, 122, 0, 0.06));
    box-shadow:
        inset 0 3px 0 rgba(255, 122, 0, 0.95),
        inset 2px 0 0 rgba(255, 122, 0, 0.5),
        inset -2px 0 0 rgba(255, 122, 0, 0.5);
}
.atsb-ws .atsb-test-grid .atsb-planner-cell.is-same-day {
    background-color: rgba(255, 122, 0, 0.08);
}
.atsb-ws .atsb-test-grid .atsb-planner-cell.is-spillover.is-same-day {
    background-color: rgba(255, 122, 0, 0.1);
}
.atsb-ws .atsb-test-sameday-chip {
    display: inline-block;
    margin-top: 0.3rem;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    background: rgba(255, 122, 0, 0.22);
    border: 1px solid rgba(255, 122, 0, 0.7);
    color: var(--warning-bg);
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1.3;
}

/* Spillover days — calendar cells that belong to the prior/next month but
   are part of the current Mon-Sun week (e.g. May 1 shown inside April's
   week of Apr 27 – May 3). They stay fully editable; the dimmer is just a
   visual hint that they are "guests" from a neighbouring month. */
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-spillover {
    opacity: 0.78;
}
.atsb-ws .atsb-test-grid .atsb-planner-dayhead.is-spillover .atsb-planner-dayhead-text {
    font-style: italic;
    color: var(--text);
}
.atsb-ws .atsb-test-grid .atsb-planner-cell.is-spillover {
    background-color: rgba(91, 158, 255, 0.04);
}
.atsb-ws .atsb-test-grid .atsb-planner-cell.is-spillover.is-active-day {
    background-color: rgba(34, 197, 94, 0.1);
}
/* Override the picker's inherited `disabled` look — spillover picker days
   are now clickable (the planner shows the same week regardless of month). */
.employee.week-picker-daybtn.is-outside:not([disabled]) {
    cursor: pointer;
}
.employee.week-picker-daybtn.is-outside:not([disabled]):hover {
    opacity: 0.85;
}
/* (Old cyan `.atsb-test-setting-chip` rule removed — the canonical green
   rule lives further up next to the SETTING band styles. Two definitions
   were present and the later one was silently winning the cascade.) */
.atsb-ws .atsb-test-grid .atsb-planner-dayhead-text {
    font-size: 0.85rem;
}

/* Per-period color identity — kept entirely on the LEFT RAIL plus a
   thick divider between periods. Cells and slot buttons remain neutral so
   colors never stack/clash inside the grid.
   --period-tint is an `R, G, B` triplet (varied alpha at each use site).
   Each tbody row is now a full period (M / A / E) with N rep-squares per
   cell, so the per-row tint maps cleanly onto child rows 1/2/3. */
.atsb-ws .atsb-test-grid tbody tr:nth-child(1) {
    --period-tint: 255, 200, 102; /* Morning — amber */
}
.atsb-ws .atsb-test-grid tbody tr:nth-child(2) {
    --period-tint: 102, 214, 255; /* Afternoon — cyan */
}
.atsb-ws .atsb-test-grid tbody tr:nth-child(3) {
    --period-tint: 167, 139, 250; /* Evening — violet */
}

/* Bold colored rail on the period label (one row per period now). */
.atsb-ws .atsb-test-grid tbody th.atsb-planner-period {
    width: 2.8rem;
    padding-block: 0.5rem;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--text);
    background: linear-gradient(180deg,
        rgba(var(--period-tint), 0.28),
        rgba(var(--period-tint), 0.14));
    box-shadow: inset 4px 0 0 rgba(var(--period-tint), 0.9);
    border-right: 1px solid rgba(var(--period-tint), 0.45);
}

/* Cells: roomier and explicitly NO borders. Each cell now hosts a small
   rep-grid (1–4 squares) so the cell itself is just a padded container. */
.atsb-ws .atsb-test-grid .atsb-planner-cell {
    padding: 0.32rem;
    border: 0;
    vertical-align: middle;
}

/* Rep-grid layout inside each (period, day) cell. data-reps drives the
   shape so each rep stays visually chunky regardless of how many fit per
   slot. Small N stack horizontally; larger N break into compact 2×N rows
   so individual squares don't shrink to dust. */
.atsb-ws .atsb-test-grid .atsb-planner-cell-grid {
    display: grid;
    gap: 3px;
    align-items: stretch;
    justify-items: stretch;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="1"] .atsb-planner-cell-grid {
    grid-template-columns: 1fr;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="2"] .atsb-planner-cell-grid {
    grid-template-columns: 1fr 1fr;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="3"] .atsb-planner-cell-grid {
    grid-template-columns: 1fr 1fr 1fr;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="4"] .atsb-planner-cell-grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="5"] .atsb-planner-cell-grid,
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="6"] .atsb-planner-cell-grid {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="7"] .atsb-planner-cell-grid,
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="8"] .atsb-planner-cell-grid {
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: 1fr 1fr;
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="9"] .atsb-planner-cell-grid {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
}
.atsb-ws .atsb-test-grid .atsb-planner-cell[data-reps="10"] .atsb-planner-cell-grid {
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: 1fr 1fr;
}

/* Strong horizontal divider at the TOP of every period — painted on rows
   1/2/3 using THAT period's color. Rendered as an outset `box-shadow` so
   it sits ON TOP of any neighboring cell content (no double-line artifact
   from row-above borders). */
.atsb-ws .atsb-test-grid tbody tr > td {
    box-shadow:
        0 -2px 0 0 rgba(var(--period-tint), 0.85),
        inset 0 2px 0 rgba(var(--period-tint), 0.6);
}
/* The period TH already carries the rail (inset 4px left). Stack the
   outset divider on top of it so the corner reads continuously. */
.atsb-ws .atsb-test-grid tbody tr > th.atsb-planner-period {
    box-shadow:
        inset 4px 0 0 rgba(var(--period-tint), 0.9),
        inset 0 2px 0 rgba(var(--period-tint), 0.6),
        0 -2px 0 0 rgba(var(--period-tint), 0.85);
}

/* Slots: neutral base; blocked = red text mark, hover/focus uses accent.
   aspect-ratio keeps each rep square, with a sensible min-height floor. */
.atsb-ws .atsb-test-grid .atsb-planner-slot {
    aspect-ratio: 1 / 1;
    min-height: 1.1rem;
    padding: 0;
    border-radius: 5px;
    font-size: 0.7rem;
    color: rgba(255, 255, 255, 0);
    /* Center the glyph (X on blocked, marketer initials on taken) both ways —
       block-flow left the content top-flush, which the smaller two-letter
       initials made conspicuous. Harmless for empty squares (transparent). */
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease, transform 0.06s ease;
}
.atsb-ws .atsb-test-grid .atsb-planner-slot.is-pad {
    visibility: hidden;
}
.atsb-ws .atsb-test-grid .atsb-planner-slot[data-active="true"] {
    color: var(--danger-ink);
}

/* Slot is TAKEN by an assigned Job (Job.atsb_* set). Shows the job's MARKETER
   initials (set as the button text in buildBody) on the same red fill a manual
   block uses — the red still reads "this rep is booked" at a glance and the
   initials say WHO set the lead (Joseph's request, 2026-06-01). A manual block
   keeps the bare "X" (no job → no marketer). Right-click still opens the
   slot-jobs popover; the data-taken attribute distinguishes the two states. */
.atsb-ws .atsb-test-grid .atsb-planner-slot.is-taken {
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.38), rgba(188, 46, 46, 0.42));
    border-color: rgba(248, 113, 113, 0.7);
    color: var(--danger-ink);
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
    /* Two-letter initials must fit a small square — tighten the type. */
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    overflow: hidden;
}
.atsb-ws .atsb-test-grid .atsb-planner-slot.is-taken:hover:not(:disabled) {
    border-color: rgba(248, 113, 113, 0.95);
    background: linear-gradient(180deg, rgba(255, 96, 96, 0.5), rgba(210, 60, 60, 0.55));
}

/* Send pill: clearer + more obvious */
.atsb-ws .atsb-test-grid .atsb-planner-send {
    gap: 0.35rem;
    padding: 0.18rem 0.6rem;
    font-size: 0.66rem;
}
.atsb-ws .atsb-test-grid .atsb-planner-send.is-on {
    background: rgba(34, 197, 94, 0.18);
    border-color: rgba(134, 239, 172, 0.6);
    color: #d6fbe5;
}
.atsb-ws .atsb-test-grid .atsb-planner-send.is-on input:checked {
    background: #22c55e;
    border-color: #86efac;
}

/* Summary card */
.atsb-ws .atsb-test-summary {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.75rem 0.9rem;
    background: linear-gradient(180deg, rgba(19, 31, 47, 0.7), rgba(12, 19, 30, 0.55));
}
.atsb-ws .atsb-test-summary-label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    color: var(--muted);
}

/* Sticky publish bar at the bottom of the planner */
.atsb-ws .atsb-test-publishbar {
    position: sticky;
    bottom: 0;
    z-index: 4;
    margin: 0 -0.5rem -0.5rem;
    padding: 0.7rem 0.85rem;
    border-top: 1px solid rgba(148, 196, 255, 0.18);
    background: linear-gradient(180deg, rgba(13, 20, 31, 0.92), rgba(8, 13, 21, 0.96));
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border-bottom-left-radius: 14px;
    border-bottom-right-radius: 14px;
}
.atsb-ws .atsb-test-publish {
    min-width: 8rem;
}
.atsb-ws .atsb-test-publish-silent {
    min-width: 8rem;
    opacity: 0.85;
}
.atsb-ws .atsb-test-publish-silent:hover:not(:disabled) {
    opacity: 1;
}
.atsb-ws .atsb-test-status {
    font-size: 0.85rem;
}

/* Mobile / narrow viewports (tablets + phones).
   Two big mobile problems this band fixes — both measured live:
   (1) the 7-day grid shrank its rep-squares to ~18px (un-tappable, below the
       44px HIG floor) to cram all 7 days into a ~687px iPad-portrait width;
   (2) the toolbar stacked into 3 rows (~143px tall) eating the height-locked
       board. Strategy mirrors the proven ≤480 phone pattern but applies it up
       to the side-by-side cutoff so EVERY iPad gets it: the grid scrolls
       horizontally with a sticky period column, and rep-squares keep a
       tappable floor (table-layout:auto sizes columns to that floor, so the
       table grows + scrolls at high rep counts and simply fits at low ones).

       The `(pointer: coarse)` arm extends the SAME treatment to touch devices
       at ANY width — notably landscape iPads (1024–1366px) that are wider than
       960 but still finger-driven, where 27px squares were mis-tap-prone. A
       mouse laptop at the same width keeps the dense desktop grid. */
@media (max-width: 960px), (pointer: coarse) {
    /* --- Toolbar: 2 rows (picker on top, nav + actions below) ---------- */
    .atsb-ws .atsb-test-toolbar {
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "picker picker"
            "nav actions";
        gap: 0.5rem 0.6rem;
    }
    .atsb-ws .atsb-test-toolbar-picker { grid-area: picker; }
    .atsb-ws .atsb-test-toolbar-nav { grid-area: nav; }
    .atsb-ws .atsb-test-toolbar-actions {
        grid-area: actions;
        justify-content: flex-end;
    }
    .atsb-ws .atsb-test-titlebar {
        align-items: flex-start;
    }
    .atsb-ws .atsb-test-hint {
        white-space: normal;
    }
    /* Reclaim vertical space on the height-locked board — the instructional
       tagline's actions are surfaced contextually when a slot is tapped. */
    .atsb-ws .atsb-test-tagline {
        display: none;
    }

    /* --- 44px touch targets on toolbar controls (Apple HIG) ------------ */
    .atsb-ws .atsb-test-weekstep,
    .atsb-ws .atsb-test-toolbar-actions .btn,
    .atsb-ws .atsb-test-toolbar-picker .employee.week-picker-toggle {
        min-height: 44px;
    }
    /* The week-picker calendar's day buttons were 28px tall — bump them for
       touch. Scoped to the ATSB picker so the shared week-picker component
       used elsewhere keeps its compact desktop size. */
    .atsb-ws .atsb-test-toolbar-picker .employee.week-picker-daybtn {
        min-height: 2.2rem;
    }

    /* --- Week grid: horizontal scroll + sticky period column ----------- */
    .atsb-ws .atsb-test-grid {
        /* Override the base `table-layout: fixed; width: 100%` (which forced
           7 equal columns that shrank squares to fit). auto + min-width lets
           the table size to content — the rep-square floor below — so it
           grows past the viewport and the wrap's overflow-x scrolls. */
        width: auto;
        min-width: 100%;
        table-layout: auto;
    }
    /* Tappable rep-square floor. The cell-grid tracks inherit this as their
       min size, so the day column → table widen to keep squares ~32px at any
       rep count (instead of 18px at 10 reps on an iPad). */
    .atsb-ws .atsb-test-grid .atsb-planner-slot {
        min-width: 2rem;
        min-height: 2rem;
    }
    .atsb-ws .atsb-test-grid .atsb-planner-dayhead {
        min-width: 4.5rem;
    }
    /* Sticky the top-left corner + the M/A/E period labels so the row
       context stays pinned while the operator scrolls sideways. Higher
       background opacity than desktop so scrolling day-cells don't bleed
       through. */
    .atsb-ws .atsb-test-grid thead .atsb-planner-corner,
    .atsb-ws .atsb-test-grid tbody th.atsb-planner-period {
        position: sticky;
        left: 0;
        z-index: 2;
        background: rgba(13, 20, 31, 0.97);
        border-right: 1px solid var(--border);
    }
}

@media (max-width: 600px) {
    .atsb-ws-hero-sub {
        font-size: 0.88rem;
    }
    /* (grid day-head / slot sizing now handled by the ≤960 scroll pattern) */
    .atsb-ws .atsb-test-publishbar {
        flex-wrap: wrap;
    }
    .atsb-ws .atsb-test-publish,
    .atsb-ws .atsb-test-publish-silent {
        flex: 1 1 calc(50% - 0.4rem);
        min-width: 0;
    }
    .atsb-ws .atsb-test-publish {
        order: -1;
    }
}

/* =========================================================================
   ATSB TEST — PROFESSIONAL POLISH
   --------------------------------------------------------------------------
   Layered ON TOP of the ATSB TEST PAGE REDESIGN block above. Same scoping
   rule (`.atsb-ws` only) so the live /atsb-calendar planner is untouched.

   Tone: calm, professional. No bounce easing, no infinite pulses, no
   gradient text. Motion is limited to short crossfades on state change so
   the UI feels responsive without drawing attention to itself. Honors
   prefers-reduced-motion via the global block at the end of file.
   ========================================================================= */

/* ---- Slot squares: idle period-tint, calm hover/press feedback ----------- */

/* Idle (empty, available) slot picks up the row's period color at very low
   alpha so each period row reads as a faint color band even when nothing's
   filled in. Hover slightly raises the tint + brightens the border — no
   lift, no shadow flare; just a clear "this is interactive" cue. */
/* Idle tint is scoped with `:not([data-active="true"]):not(.is-taken)` so
   the original red-X rules (manually-blocked + job-backed) win cleanly
   without us having to re-apply red here at higher specificity. */
.atsb-ws .atsb-test-grid .atsb-planner-slot:not([data-active="true"]):not(.is-taken) {
    background: rgba(var(--period-tint, 102, 214, 255), 0.10);
    border: 1px solid rgba(var(--period-tint, 102, 214, 255), 0.55);
    transition:
        background 0.12s ease,
        border-color 0.12s ease,
        color 0.12s ease;
}
.atsb-ws .atsb-test-grid .atsb-planner-slot:not([data-active="true"]):not(.is-taken):hover:not(:disabled) {
    background: rgba(var(--period-tint, 102, 214, 255), 0.22);
    border-color: rgba(var(--period-tint, 102, 214, 255), 0.85);
}
.atsb-ws .atsb-test-grid .atsb-planner-slot:not([data-active="true"]):not(.is-taken):active:not(:disabled) {
    transform: none;
    background: rgba(var(--period-tint, 102, 214, 255), 0.32);
}

/* ---- Period rail (M/A/E) — a touch more depth, no animation ------------- */

.atsb-ws .atsb-test-grid tbody th.atsb-planner-period {
    background: linear-gradient(180deg,
        rgba(var(--period-tint), 0.30) 0%,
        rgba(var(--period-tint), 0.16) 55%,
        rgba(var(--period-tint), 0.10) 100%);
    box-shadow:
        inset 4px 0 0 rgba(var(--period-tint), 0.9),
        inset -1px 0 0 rgba(var(--shadow-rgb), 0.3),
        inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

/* ---- Day header — typographic refinement only --------------------------- */

.atsb-ws .atsb-test-grid .atsb-planner-dayhead-text {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

/* ---- Send pill: short crossfade on hover, no transform ------------------ */

.atsb-ws .atsb-test-grid .atsb-planner-send {
    transition:
        background 0.12s ease,
        border-color 0.12s ease,
        color 0.12s ease;
}

/* ---- Week navigation: tabular numerals, color-only hover ---------------- */

.atsb-ws .atsb-test-weeklabel {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.005em;
}
.atsb-ws .atsb-test-weekstep {
    transition:
        background 0.12s ease,
        border-color 0.12s ease,
        color 0.12s ease;
}
.atsb-ws .atsb-test-weekstep:hover:not(:disabled) {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(102, 214, 255, 0.08);
    color: var(--text);
}

/* ---- Status hint: static pill, no pulse --------------------------------- */

.atsb-ws .atsb-test-hint {
    display: inline-flex;
    align-items: center;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    background: rgba(148, 196, 255, 0.06);
    border: 1px solid rgba(148, 196, 255, 0.18);
    color: var(--muted);
    font-weight: 600;
    font-size: 0.74rem;
    letter-spacing: 0.02em;
}

/* ---- Settings panel: focus ring matches workspace ----------------------- */

.atsb-ws .atsb-test-settings input#atsb-settings-reps {
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.atsb-ws .atsb-test-settings input#atsb-settings-reps:focus {
    border-color: rgba(102, 214, 255, 0.6);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.10);
    outline: none;
}

/* ---- Summary card: tabular numerals so totals don't jitter -------------- */
/* The text is set by JS as "Morning: 0 | Afternoon: 0 | Evening: 0" — we
   can't restructure it without touching shared JS, so just make the line
   read cleanly. */
.atsb-ws .atsb-test-summary {
    border-color: rgba(148, 196, 255, 0.22);
}
.atsb-ws .atsb-test-summary #atsb-planner-summary-value {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--text);
    letter-spacing: 0.02em;
}

/* ---- Sticky publish bar: subtle drop shadow only ------------------------ */

.atsb-ws .atsb-test-publishbar {
    box-shadow: 0 -8px 18px rgba(var(--shadow-rgb), 0.28);
}
.atsb-ws .atsb-test-publish {
    transition:
        background 0.12s ease,
        border-color 0.12s ease,
        color 0.12s ease;
}

/* Slot jobs popover — surfaces the list of jobs assigned to a (date, period)
   ATSB slot when the user right-clicks a rep-square on /atsb-availability/test.
   Pinned to top-center of the viewport so it always opens in the same spot
   regardless of which square the user clicked or how far the page is
   scrolled. Width/height clamp to the viewport so it never overflows on
   small screens. */
.atsb-test-jobs-popover {
    position: fixed;
    top: 4rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 50;
    width: 26rem;
    max-width: calc(100vw - 2rem);
    max-height: calc(100vh - 6rem);
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, rgba(15, 23, 35, 0.98), rgba(10, 16, 25, 0.98));
    border: 1px solid rgba(102, 214, 255, 0.35);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(var(--shadow-rgb), 0.55), 0 0 0 1px rgba(var(--shadow-rgb), 0.4);
    color: var(--text);
    overflow: hidden;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}
.atsb-test-jobs-popover[hidden] {
    display: none;
}
.atsb-test-jobs-popover-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.65rem;
    background: rgba(102, 214, 255, 0.08);
    border-bottom: 1px solid rgba(102, 214, 255, 0.2);
}
.atsb-test-jobs-popover-title {
    flex: 1 1 auto;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--accent-pale);
}
.atsb-test-jobs-popover-close {
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    color: var(--muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}
.atsb-test-jobs-popover-close:hover {
    background: rgba(248, 113, 113, 0.18);
    color: var(--danger-ink);
    border-color: rgba(248, 113, 113, 0.55);
}
.atsb-test-jobs-popover-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 0.35rem;
}
.atsb-test-jobs-popover-empty {
    padding: 0.85rem 0.6rem;
    margin: 0;
    color: var(--muted);
    font-size: 0.82rem;
    text-align: center;
}
.atsb-test-jobs-popover-tag-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 0.4rem;
    padding: 0 0.2rem;
}
.atsb-test-jobs-popover-cur {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
    font-size: 0.65rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.atsb-test-jobs-popover-cur.is-empty {
    background: rgba(148, 196, 255, 0.08);
    border-color: rgba(148, 196, 255, 0.28);
    color: var(--muted);
}
.atsb-test-jobs-popover-primary {
    margin: 0 0 0.5rem;
    padding: 0.55rem 0.6rem;
    border: 1px solid rgba(102, 214, 255, 0.4);
    border-radius: 8px;
    background: rgba(102, 214, 255, 0.06);
    box-shadow: inset 3px 0 0 rgba(102, 214, 255, 0.7);
}
.atsb-test-jobs-popover-others-label {
    margin: 0.4rem 0.2rem 0.25rem;
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
}
.atsb-test-jobs-popover-list {
    list-style: decimal inside;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.atsb-test-jobs-popover-list .atsb-test-jobs-popover-item.is-current {
    border-color: rgba(102, 214, 255, 0.6);
    box-shadow: inset 3px 0 0 rgba(102, 214, 255, 0.7);
    background: rgba(102, 214, 255, 0.08);
}
.atsb-test-jobs-meta-time {
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.atsb-test-jobs-popover-item {
    padding: 0.45rem 0.55rem;
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 7px;
    background: rgba(18, 28, 43, 0.55);
    transition: background 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease, transform 0.08s ease;
}
/* Items in the "Other jobs in this slot" list are clickable — hover +
   focus give a clear affordance, and the cursor change tells the user
   they can pick another job to focus without leaving the panel. */
.atsb-test-jobs-popover-item.is-clickable {
    cursor: pointer;
}
.atsb-test-jobs-popover-item.is-clickable:hover {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(28, 44, 66, 0.78);
    box-shadow: inset 3px 0 0 rgba(102, 214, 255, 0.55);
}
.atsb-test-jobs-popover-item.is-clickable:active {
    transform: translateY(1px);
}
.atsb-test-jobs-popover-item.is-clickable:focus-visible {
    outline: none;
    border-color: rgba(102, 214, 255, 0.70);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.35), inset 3px 0 0 rgba(102, 214, 255, 0.7);
}
.atsb-test-jobs-popover-row1 {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}
.atsb-test-jobs-popover-who {
    flex: 1 1 auto;
    font-weight: 700;
    color: var(--text);
    font-size: 0.88rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.atsb-test-jobs-popover-jobid {
    flex: 0 0 auto;
    color: var(--muted);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
.atsb-test-jobs-popover-addr {
    margin-top: 0.15rem;
    color: var(--muted);
    font-size: 0.76rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.atsb-test-jobs-popover-meta {
    margin-top: 0.25rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
    font-size: 0.72rem;
    color: var(--muted);
}
.atsb-test-jobs-tag {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.14);
    border: 1px solid rgba(102, 214, 255, 0.4);
    color: var(--accent-pale);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-size: 0.62rem;
}
.atsb-test-jobs-meta-em {
    color: var(--text);
    font-weight: 600;
}
.atsb-test-jobs-meta-id {
    font-variant-numeric: tabular-nums;
    opacity: 0.85;
}
.atsb-test-jobs-popover-notes {
    margin-top: 0.3rem;
    padding-top: 0.3rem;
    border-top: 1px dashed rgba(148, 196, 255, 0.18);
    color: var(--text);
    font-size: 0.74rem;
    line-height: 1.35;
    white-space: normal;
}

/* "Change slot" affordance on the primary card + the inline editor that
   replaces the card when the user clicks it. The editor mirrors the same
   cyan-rimmed primary-card chrome so swapping in/out feels like a single
   surface, just with form controls instead of a job summary.
   All three action buttons (Reassign / Open in Database / Remove) share
   the same height + padding + font so they read as a uniform action row;
   color carries the semantic difference (cyan = primary, neutral = link
   out, red = destructive) instead of size. */
.atsb-test-jobs-popover-actions {
    margin-top: 0.6rem;
    padding-top: 0.55rem;
    border-top: 1px dashed rgba(148, 196, 255, 0.18);
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.45rem;
}
.atsb-test-jobs-popover-actions .btn,
.atsb-test-jobs-popover-actions .atsb-test-jobs-reassign-btn,
.atsb-test-jobs-popover-actions .atsb-test-jobs-remove-btn {
    height: 2.1rem;
    padding: 0 0.85rem;
    border-radius: 8px;
    font-size: 0.82rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.01em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease, box-shadow 0.12s ease, transform 0.08s ease;
}
.atsb-test-jobs-popover-actions .btn:active:not(:disabled),
.atsb-test-jobs-popover-actions .atsb-test-jobs-reassign-btn:active:not(:disabled),
.atsb-test-jobs-popover-actions .atsb-test-jobs-remove-btn:active:not(:disabled) {
    transform: translateY(1px);
}
.atsb-test-jobs-popover-actions .atsb-test-jobs-reassign-btn {
    border: 1px solid rgba(102, 214, 255, 0.55);
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.18), rgba(102, 214, 255, 0.10));
    color: #ecf6ff;
    box-shadow: 0 1px 0 rgba(102, 214, 255, 0.18) inset;
}
.atsb-test-jobs-popover-actions .atsb-test-jobs-reassign-btn:hover:not(:disabled) {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.30), rgba(102, 214, 255, 0.16));
    border-color: rgba(102, 214, 255, 0.80);
    color: var(--white);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.18);
}
/* Make the Open-in-Database link button's chrome match the others
   regardless of what the global .btn-ghost rule sets, since it lives
   inside this popover-only action row. */
.atsb-test-jobs-popover-actions .btn.btn-ghost {
    border: 1px solid rgba(148, 196, 255, 0.30);
    background: rgba(15, 24, 38, 0.72);
    color: var(--text);
}
.atsb-test-jobs-popover-actions .btn.btn-ghost:hover:not(:disabled) {
    background: rgba(20, 33, 51, 0.92);
    border-color: rgba(148, 196, 255, 0.55);
    color: var(--text);
}
.atsb-test-jobs-reassign {
    padding: 0.55rem 0.6rem;
}
.atsb-test-jobs-reassign-form {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}
.atsb-test-jobs-reassign-field {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.atsb-test-jobs-reassign-label {
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
}
.atsb-test-jobs-reassign-date,
.atsb-test-jobs-reassign-period {
    width: 100%;
    padding: 0.35rem 0.5rem;
    background: rgba(8, 13, 21, 0.7);
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.85rem;
    font-family: inherit;
}
.atsb-test-jobs-reassign-date:focus,
.atsb-test-jobs-reassign-period:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.25);
}
.atsb-test-jobs-reassign-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.2rem;
}
.atsb-test-jobs-reassign-status {
    margin: 0;
    font-size: 0.78rem;
    color: var(--muted);
}
.atsb-test-jobs-reassign-status.is-error {
    color: var(--danger-bg);
}

/* ----- Slot panel redesign (assign / assigned / blocked) -----
   Header now carries a status pill next to the title. Body switches
   between three clearly-themed sections so the user always knows what
   the slot currently is and what actions are available. Reuses the
   semantic palette from docs/AI_STYLE_GUIDE.md:
     * Cyan (102, 214, 255)  — accent / assigned state
     * Green (34, 197, 94)   — assign-flow OK / save-success
     * Red   (239, 68, 68)   — destructive (Remove from slot)
     * Amber (255, 200, 102) — manually-blocked rail
*/
.atsb-test-jobs-popover-headline {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}
.atsb-test-jobs-popover-pill {
    flex: 0 0 auto;
    display: inline-block;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    background: rgba(148, 196, 255, 0.12);
    border: 1px solid rgba(148, 196, 255, 0.28);
    color: var(--muted);
    line-height: 1.4;
}
.atsb-test-jobs-popover-pill.is-assigned {
    background: rgba(102, 214, 255, 0.18);
    border-color: rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
}
.atsb-test-jobs-popover-pill.is-empty {
    background: rgba(34, 197, 94, 0.18);
    border-color: rgba(34, 197, 94, 0.55);
    color: #d3f7df;
}
.atsb-test-jobs-popover-pill.is-blocked {
    background: rgba(255, 200, 102, 0.18);
    border-color: rgba(255, 200, 102, 0.55);
    color: #ffe7ba;
}

.atsb-test-jobs-popover-section {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.55rem 0.6rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    background: rgba(18, 28, 43, 0.55);
    margin-bottom: 0.5rem;
}
.atsb-test-jobs-popover-section.is-primary {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(102, 214, 255, 0.06);
    box-shadow: inset 3px 0 0 rgba(102, 214, 255, 0.7);
}
.atsb-test-jobs-popover-section.is-blocked {
    border-color: rgba(255, 200, 102, 0.45);
    background: rgba(255, 200, 102, 0.06);
    box-shadow: inset 3px 0 0 rgba(255, 200, 102, 0.7);
}
.atsb-test-jobs-popover-section.is-assign {
    border-color: rgba(34, 197, 94, 0.4);
    background: rgba(34, 197, 94, 0.05);
    box-shadow: inset 3px 0 0 rgba(34, 197, 94, 0.65);
}

.atsb-test-jobs-popover-card {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}
.atsb-test-jobs-popover-card.is-dense {
    padding: 0.4rem 0.5rem;
    border: 1px solid rgba(148, 196, 255, 0.14);
    border-radius: 7px;
    background: rgba(18, 28, 43, 0.55);
}
.atsb-test-jobs-popover-card.is-dense .atsb-test-jobs-popover-who {
    font-size: 0.8rem;
}

.atsb-test-jobs-popover-others {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.atsb-test-jobs-popover-blocked-msg {
    margin: 0;
    color: #ffe7ba;
    font-size: 0.82rem;
    line-height: 1.35;
}

/* Assign-mode candidate list + search */
.atsb-test-jobs-popover-search {
    position: sticky;
    top: -0.55rem;
    margin: -0.55rem -0.6rem 0.4rem;
    padding: 0.45rem 0.6rem 0.4rem;
    background: rgba(8, 13, 21, 0.85);
    border-bottom: 1px solid rgba(148, 196, 255, 0.18);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 1;
}
.atsb-test-jobs-popover-search-input {
    width: 100%;
    padding: 0.4rem 0.55rem;
    background: rgba(8, 13, 21, 0.7);
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    color: var(--text);
    font-size: 0.85rem;
    font-family: inherit;
}
.atsb-test-jobs-popover-search-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.25);
}
.atsb-test-jobs-popover-candlist {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    max-height: 22rem;
    overflow-y: auto;
}
.atsb-test-jobs-popover-candgroup {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.atsb-test-jobs-popover-candgroup-h {
    margin: 0.1rem 0.1rem 0.05rem;
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
}
.atsb-test-jobs-candidate {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.15rem 0.45rem;
    padding: 0.45rem 0.55rem;
    text-align: left;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 7px;
    background: rgba(18, 28, 43, 0.55);
    color: var(--text);
    cursor: pointer;
    font-family: inherit;
    transition: background 0.1s ease, border-color 0.1s ease, color 0.1s ease;
}
.atsb-test-jobs-candidate:hover:not(:disabled) {
    background: rgba(34, 197, 94, 0.1);
    border-color: rgba(34, 197, 94, 0.55);
}
.atsb-test-jobs-candidate:disabled {
    opacity: 0.55;
    cursor: progress;
}
.atsb-test-jobs-candidate-who {
    grid-column: 1;
    grid-row: 1;
    font-weight: 700;
    color: var(--text);
    font-size: 0.85rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.atsb-test-jobs-candidate-id {
    grid-column: 2;
    grid-row: 1;
    color: var(--muted);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
.atsb-test-jobs-candidate-meta {
    grid-column: 1 / -1;
    grid-row: 2;
    color: var(--muted);
    font-size: 0.72rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.atsb-test-jobs-popover-tertiary {
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px dashed rgba(148, 196, 255, 0.18);
    display: flex;
    justify-content: flex-end;
}

/* Destructive Remove-from-slot button — red border + soft red wash,
   fills on hover. Sized + padded to match the other action buttons via
   the shared rules above; this block carries only the destructive-color
   semantics. */
.atsb-test-jobs-remove-btn {
    border: 1px solid rgba(239, 68, 68, 0.55);
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.16), rgba(239, 68, 68, 0.08));
    color: var(--danger-bg);
    box-shadow: 0 1px 0 rgba(239, 68, 68, 0.18) inset;
}
.atsb-test-jobs-remove-btn:hover:not(:disabled) {
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.28), rgba(239, 68, 68, 0.14));
    border-color: rgba(239, 68, 68, 0.85);
    color: #ffeaea;
    box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.22);
}
.atsb-test-jobs-remove-btn:disabled {
    opacity: 0.55;
    cursor: progress;
}

/* Inline reassign editor — rendered BELOW the job card (hidden by
   default; toggled by the Reassign button). Indented sub-card so the
   relationship to the parent card is visible without taking over. */
.atsb-test-jobs-popover-editor {
    margin: -0.25rem 0 0.5rem;
    padding: 0.55rem 0.6rem;
    border: 1px solid rgba(102, 214, 255, 0.35);
    border-top-width: 0;
    border-radius: 0 0 8px 8px;
    background: rgba(102, 214, 255, 0.05);
}
.atsb-test-jobs-popover-editor-h {
    margin: 0 0 0.4rem;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-pale);
    font-weight: 800;
}
.atsb-test-jobs-reassign-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
}

/* ----- Planner confirm/alert modal -----
   Replaces native window.confirm / window.alert inside the planner so
   destructive prompts (Remove from slot, Block manually, etc.) and error
   notices (assign failed) match the rest of the workspace UI. Visual
   palette mirrors the slot-jobs popover (dark card, cyan accent border)
   plus a `.is-danger` modifier that swaps the primary button to red for
   destructive flows. */
.atsb-test-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 5rem 1rem 2rem;
    background: rgba(4, 8, 14, 0.55);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}
.atsb-test-modal-backdrop[hidden] {
    display: none;
}
.atsb-test-modal-card {
    width: 24rem;
    max-width: calc(100vw - 2rem);
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, rgba(15, 23, 35, 0.98), rgba(10, 16, 25, 0.98));
    border: 1px solid rgba(102, 214, 255, 0.4);
    border-radius: 10px;
    box-shadow: 0 16px 36px rgba(var(--shadow-rgb), 0.6), 0 0 0 1px rgba(var(--shadow-rgb), 0.4);
    color: var(--text);
    overflow: hidden;
}
.atsb-test-modal-backdrop.is-danger .atsb-test-modal-card {
    border-color: rgba(239, 68, 68, 0.55);
}
.atsb-test-modal-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.7rem;
    background: rgba(102, 214, 255, 0.08);
    border-bottom: 1px solid rgba(102, 214, 255, 0.2);
}
.atsb-test-modal-backdrop.is-danger .atsb-test-modal-head {
    background: rgba(239, 68, 68, 0.1);
    border-bottom-color: rgba(239, 68, 68, 0.32);
}
.atsb-test-modal-title {
    flex: 1 1 auto;
    margin: 0;
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: #ecf6ff;
}
.atsb-test-modal-backdrop.is-danger .atsb-test-modal-title {
    color: var(--danger-ink);
}
.atsb-test-modal-close {
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    color: var(--muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}
.atsb-test-modal-close:hover {
    background: rgba(248, 113, 113, 0.18);
    color: var(--danger-ink);
    border-color: rgba(248, 113, 113, 0.55);
}
.atsb-test-modal-body {
    padding: 0.85rem 0.85rem 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}
.atsb-test-modal-line {
    margin: 0;
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.45;
    word-break: break-word;
}
.atsb-test-modal-line + .atsb-test-modal-line {
    color: var(--muted);
    font-size: 0.82rem;
}
.atsb-test-modal-line-muted {
    color: var(--muted);
}
.atsb-test-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.45rem;
    padding: 0.55rem 0.85rem 0.75rem;
    border-top: 1px solid rgba(148, 196, 255, 0.12);
    background: rgba(8, 13, 21, 0.4);
}
.atsb-test-modal-actions .btn {
    min-width: 5rem;
}
.atsb-test-modal-backdrop.is-danger .atsb-test-modal-confirm {
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.85), rgba(188, 46, 46, 0.85));
    border-color: rgba(248, 113, 113, 0.85);
    color: #fff5f5;
}
.atsb-test-modal-backdrop.is-danger .atsb-test-modal-confirm:hover:not(:disabled) {
    background: linear-gradient(180deg, rgba(255, 96, 96, 0.95), rgba(210, 60, 60, 0.95));
    border-color: rgba(255, 138, 138, 0.95);
}

/* ATSB HTTP pull sync panel — reused legacy tokens (used by atsb_availability_test.php). */
.atsb-cal-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    margin-top: 0.25rem;
    flex-wrap: wrap;
}

.atsb-cal-actions .muted,
.atsb-cal-actions .atsb-cal-legend {
    margin-right: auto;
}

.atsb-cal-actions .atsb-cal-dirty {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.55rem;
    border-radius: 999px;
    background: rgba(255, 197, 96, 0.12);
    border: 1px solid rgba(255, 197, 96, 0.3);
    color: #ffd291;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.atsb-cal-actions .atsb-cal-dirty::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: #ffc460;
    box-shadow: 0 0 8px rgba(255, 197, 96, 0.6);
}

.input-readonly {
    opacity: 0.85;
}

.muted {
    color: var(--muted);
}

/* ATSB workspace embed: solid shell so page gradient does not show through; one border, no iframe chrome */
.atsb-embed-panel {
    padding: 0;
    overflow: hidden;
    background: var(--surface);
}

.atsb-embed-frame {
    line-height: 0;
    background: #0a0e14;
}

.atsb-embed-panel iframe.atsb-embed {
    display: block;
    width: 100%;
    min-height: 900px;
    border: 0;
    border-radius: 0;
    background: #0a0e14;
    vertical-align: top;
}

:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.8);
    outline-offset: 1px;
}

.employee.onboarding-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 0.85rem;
    margin: 0.9rem 0 1rem;
}

.employee.onboarding-grid .employee.field-group label .muted-line {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.78rem;
}

/* Routing board: Sun–Sat × M/A/E */
body.is-routing-page .layout-main.is-routing {
    max-width: none;
}

.routing.page-root {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.routing.toolbar .routing.toolbar-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
}

.routing.title {
    margin: 0;
    font-size: 1.32rem;
}

.routing.subtitle {
    margin: 0.2rem 0 0;
}

.routing.week-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.routing.week-label {
    font-weight: 600;
    min-width: 12rem;
    text-align: center;
}

.routing.layout {
    display: grid;
    grid-template-columns: minmax(220px, 280px) 1fr;
    gap: 0.75rem;
    align-items: start;
}

@media (max-width: 960px) {
    .routing.layout {
        grid-template-columns: 1fr;
    }
}

.routing.sidebar .routing.field {
    display: grid;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.routing.job-select {
    min-height: 38px;
}

.routing.assign-btn {
    margin-top: 0.65rem;
    width: 100%;
}

.routing.selected-cell {
    margin-top: 0.5rem;
    font-size: 0.88rem;
}

.routing.grid-scroll {
    overflow-x: auto;
}

.routing.grid-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}

.routing.grid-table th,
.routing.grid-table td {
    border: 1px solid rgba(148, 196, 255, 0.15);
    padding: 0.35rem;
    vertical-align: top;
}

.routing.corner {
    width: 2.25rem;
    background: rgba(17, 26, 40, 0.6);
}

.routing.day-head {
    text-align: center;
    font-weight: 600;
    background: rgba(17, 26, 40, 0.75);
}

.routing.period-head {
    text-align: center;
    font-weight: 700;
    background: rgba(17, 26, 40, 0.85);
    width: 2.25rem;
}

.routing.grid-cell {
    min-width: 7.5rem;
    min-height: 4.5rem;
    cursor: pointer;
    background: rgba(13, 20, 31, 0.45);
    transition: background 0.15s ease, box-shadow 0.15s ease;
}

.routing.grid-cell:hover {
    background: rgba(28, 43, 64, 0.55);
}

.routing.grid-cell.is-selected {
    outline: 2px solid rgba(102, 214, 255, 0.85);
    outline-offset: -2px;
    background: rgba(28, 55, 88, 0.5);
}

.routing.cell-inner {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.routing.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    max-width: 100%;
    padding: 0.2rem 0.45rem;
    border-radius: 6px;
    background: rgba(65, 139, 235, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.22);
    font-size: 0.8rem;
}

.routing.chip-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}

.routing.chip-remove {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.1rem;
}

.routing.chip-remove:hover {
    color: var(--text);
}

/* =========================================================================
   ATSB TEST — PHONE / NARROW VIEWPORT (≤ 480px)
   --------------------------------------------------------------------------
   The existing @media (max-width: 600px) block above shrinks day-column
   widths so 7 days still fit in a tablet portrait viewport. Below 480px
   (iPhone-ish) the 7-day grid no longer fits even when cramped — table-
   layout:fixed + width:100% causes each column to shrink to ≈40px which
   is below Apple HIG's 44px touch-target minimum and forces the slot
   labels to clip.

   Strategy: at ≤480px the grid table becomes width:auto so it can EXCEED
   its container, the gridwrap's existing overflow-x:auto engages, and we
   sticky-pin the period column (M/A/E labels) to the left edge so the
   row context stays visible while the operator scrolls horizontally
   through the week. Touch targets bump to ≈44px. The verbose tagline
   above the toolbar is hidden — same hints are reachable from the slot
   panel when the operator actually engages a square.

   Scoped to `.atsb-ws` so the live /atsb-calendar planner is untouched.
   ========================================================================= */
@media (max-width: 480px) {
    /* Phone-specific tweaks layered on the ≤960 tablet/mobile rules above
       (horizontal-scroll grid + sticky period column + tagline hidden +
       44px toolbar targets all live there now). Here we only nudge values
       that should differ on a phone: slightly larger SQUARE rep-targets,
       tighter chrome, and a full-width stacked publish bar. */
    .atsb-ws .atsb-test-grid .atsb-planner-slot {
        min-width: 2.4rem;
        min-height: 2.4rem;
    }
    .atsb-ws .atsb-test-grid .atsb-planner-dayhead {
        min-width: 3.8rem;
    }
    .atsb-ws .atsb-test-titlebar {
        gap: 0.4rem;
        padding-bottom: 0.15rem;
    }
    .atsb-ws .atsb-test-toolbar {
        padding: 0.45rem 0.5rem;
    }
    .atsb-ws .atsb-test-weekstep {
        min-width: 2.8rem;
    }
    /* The week-nav label ("June 2026 — Week 2 (8 – 14)") is too long for a
       phone's nav row and only truncated to "J…". The picker button directly
       above already names the selected week, so drop the redundant label and
       keep just the ‹ › step arrows — the nav stays compact, no truncation. */
    .atsb-ws .atsb-test-weeklabel {
        display: none;
    }

    /* --- Publish bar: full-width stacked buttons ---------------------- */
    .atsb-ws .atsb-test-publishbar {
        gap: 0.4rem;
    }
    .atsb-ws .atsb-test-publish,
    .atsb-ws .atsb-test-publish-silent {
        flex: 1 1 100%;
        min-height: 2.8rem;
    }
}

/* =============================================================================
   /routing page (v2) — map-focused split view.
   Header bar + 380px scrollable job list (period sections) + Leaflet map
   with CartoDB Dark Matter tiles, OSRM road polyline, and hover-synced leg
   highlight. Built off the existing controller payload (RoutingController::
   buildDayPayload), so per-job fields stay job_id / customer_name /
   address_* / time_label / time_sort_key / period / primary_rep_*  /
   latitude / longitude. The legacy .routing-day-* + .routing-tl-* blocks
   were retired in favour of this set.
   ========================================================================== */

body.is-routing-page .layout-main.is-routing {
    max-width: none;
    /* Drop the workspace shell's vertical padding so the split pane fills
       the viewport edge-to-edge — operators want as much map as possible. */
    padding: 0;
}

body.is-routing-page {
    overflow: hidden;
}

.routing-v2 {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--cwdb-topnav-height, 64px));
    height: calc(100dvh - var(--cwdb-topnav-height, 64px)); /* dvh: full board height without URL-bar clip */
    min-height: 0;
    overflow: hidden;
}

/* ── Header bar ─────────────────────────────────────────────────────────── */
.routing-v2-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.7rem 1.1rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.14);
    background: rgba(10, 16, 26, 0.7);
    backdrop-filter: blur(8px);
    flex-shrink: 0;
    flex-wrap: wrap;
}

.routing-v2-header-left {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    min-width: 0;
}

.routing-v2-title {
    margin: 0;
    font-size: 1.32rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--text);
}

.routing-v2-meta {
    font-size: 0.78rem;
    color: var(--muted);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.routing-v2-meta-text {
    color: var(--muted);
}

.routing-v2-loading { color: var(--accent); }

.routing-v2-live {
    color: rgba(34, 197, 94, 0.9);
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 800;
}

.routing-v2-todaybadge {
    display: inline-flex;
    align-items: center;
    background: rgba(102, 214, 255, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.45);
    color: #aeeeff;
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
}
/* Honour the HTML `hidden` attribute — without this the explicit
   `display: inline-flex` above overrides the user-agent default
   `[hidden] { display: none }` and the TODAY badge would render on
   non-today views (same pattern as the /atsb planner dirty badge). */
.routing-v2-todaybadge[hidden] { display: none; }

.routing-v2-status {
    margin: 0;
    font-size: 0.74rem;
    color: var(--muted);
    flex-basis: 100%;
    min-height: 0.95rem;
}

.routing-v2-status.is-error { color: #ff9c9c; }

/* ── Header buttons ─────────────────────────────────────────────────────── */
.routing-v2-nav {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}
/* The day-nav cluster wrapper is transparent on desktop — its buttons lay
   out as direct flex children of .routing-v2-nav exactly as before. On
   narrow viewports (below) it becomes the horizontal scroll zone so the
   pinned Send-to-JobNimbus action can sit outside it. */
.routing-v2-nav-scroll {
    display: contents;
}

.routing-v2-btn {
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 8px;
    background: rgba(18, 28, 43, 0.6);
    color: var(--text);
    padding: 0.32rem 0.65rem;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease, transform 0.08s ease;
}

.routing-v2-btn:hover:not(:disabled) {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(28, 43, 64, 0.7);
}
.routing-v2-btn:active:not(:disabled) { transform: translateY(1px); }
.routing-v2-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.routing-v2-btn.is-primary {
    border-color: rgba(102, 214, 255, 0.55);
    background: linear-gradient(180deg, rgba(27, 124, 150, 0.92), rgba(15, 84, 121, 0.96));
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.routing-v2-btn.is-danger {
    border-color: rgba(255, 120, 120, 0.42);
    background: rgba(50, 16, 20, 0.55);
    color: var(--danger-bg);
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}
/* Re-state the user-agent [hidden] rule — `display: inline-flex` above
   would otherwise leave the buttons visible when JS sets `hidden`. */
.routing-v2-btn[hidden] { display: none !important; }
.routing-v2-btn.is-danger:hover:not(:disabled) {
    border-color: rgba(255, 120, 120, 0.75);
    background: rgba(74, 20, 26, 0.75);
}

.routing-v2-count-pill {
    background: rgba(7, 11, 18, 0.5);
    border: 1px solid rgba(102, 214, 255, 0.35);
    border-radius: 999px;
    padding: 0.05rem 0.42rem;
    font-size: 0.7rem;
    font-weight: 700;
    color: #aeeeff;
    font-variant-numeric: tabular-nums;
}
.routing-v2-count-pill.is-danger {
    border-color: rgba(255, 120, 120, 0.45);
    color: #ffc4c4;
}

.routing-v2-pickerlabel {
    display: inline-flex;
    align-items: center;
}
.routing-v2-picker {
    background: rgba(18, 28, 43, 0.6);
    color: var(--text);
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 8px;
    padding: 0.28rem 0.5rem;
    font: 600 0.78rem "Plus Jakarta Sans", system-ui, sans-serif;
    color-scheme: dark;
}
.routing-v2-picker:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.55);
    outline-offset: 1px;
}

/* ── Split pane ─────────────────────────────────────────────────────────── */
.routing-v2-split {
    flex: 1;
    display: grid;
    grid-template-columns: 380px 1fr;
    min-height: 0;
}

.routing-v2-list {
    overflow: auto;
    border-right: 1px solid rgba(148, 196, 255, 0.14);
    padding: 0.5rem 0.7rem;
    background: rgba(7, 11, 18, 0.4);
}

.routing-v2-empty {
    padding: 1.5rem 0.5rem;
    text-align: center;
    color: var(--muted);
}

.routing-v2-mapwrap {
    position: relative;
    overflow: hidden;
    background: #0a1018;
    min-height: 0;
}

.routing-v2-map {
    position: absolute;
    inset: 0;
    background: #0a1018;
}

/* ── Period section ─────────────────────────────────────────────────────── */
.routing-v2-period { margin-bottom: 0.9rem; }

.routing-v2-period-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: rgba(7, 11, 18, 0.95);
    backdrop-filter: blur(4px);
    padding: 0.5rem 0.2rem 0.4rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.routing-v2-period-dot {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    flex-shrink: 0;
}

.routing-v2-period-count {
    color: var(--muted);
    font-weight: 600;
    letter-spacing: 0.01em;
}

.routing-v2-period[data-period="morning"]   .routing-v2-period-head { color: #ffc866; }
.routing-v2-period[data-period="afternoon"] .routing-v2-period-head { color: var(--accent); }
.routing-v2-period[data-period="evening"]   .routing-v2-period-head { color: #a78bfa; }
.routing-v2-period[data-period="morning"]   .routing-v2-period-dot  { background: #ffc866; }
.routing-v2-period[data-period="afternoon"] .routing-v2-period-dot  { background: var(--accent); }
.routing-v2-period[data-period="evening"]   .routing-v2-period-dot  { background: #a78bfa; }

/* ── Job card ───────────────────────────────────────────────────────────── */
.routing-v2-card {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.55rem;
    padding: 0.5rem 0.55rem;
    margin-bottom: 0.3rem;
    border-radius: 10px;
    border: 1px solid rgba(148, 196, 255, 0.15);
    background: rgba(15, 22, 34, 0.55);
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease;
    min-width: 0;
}
.routing-v2-card:hover,
.routing-v2-card:focus-visible,
.routing-v2-card.is-hover {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(28, 43, 64, 0.7);
    outline: 0;
}

/* Two-segment pin: left = time (period color), right = rep initials (rep
   color). When unassigned, only the time segment is rendered. */
.routing-v2-card-pin {
    display: flex;
    align-items: stretch;
    height: 22px;
    border-radius: 11px;
    overflow: hidden;
    flex-shrink: 0;
    margin-top: 0.05rem;
    color: #0b111b;
    font-size: 0.7rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
}
.routing-v2-card-pin-time,
.routing-v2-card-pin-rep {
    display: flex;
    align-items: center;
    padding: 0 7px;
    white-space: nowrap;
}
.routing-v2-card-pin-time {
    min-width: 22px;
    justify-content: center;
}
.routing-v2-card-pin-rep {
    border-left: 1px solid rgba(11, 17, 27, 0.55);
    /* background applied inline (rep palette color) */
}
.routing-v2-card[data-period="morning"]   .routing-v2-card-pin-time { background: #ffc866; }
.routing-v2-card[data-period="afternoon"] .routing-v2-card-pin-time { background: var(--accent); }
.routing-v2-card[data-period="evening"]   .routing-v2-card-pin-time { background: #a78bfa; }

.routing-v2-card-body { min-width: 0; }

.routing-v2-card-row1 {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
}

.routing-v2-card-name {
    font-size: 0.86rem;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.routing-v2-card-time {
    font-size: 0.72rem;
    color: #bad0e8;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.routing-v2-card-time-ampm {
    color: var(--muted);
    font-size: 0.6rem;
    margin-left: 1px;
}

.routing-v2-card-sub {
    font-size: 0.74rem;
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.routing-v2-card-row3 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 0.25rem;
    gap: 0.4rem;
}

.routing-v2-card-rep {
    font-size: 0.7rem;
    font-weight: 600;
    color: #aeeeff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.routing-v2-card-rep.is-empty { color: #ff9c9c; }

.routing-v2-card-drive {
    font-size: 0.66rem;
    font-variant-numeric: tabular-nums;
    color: #7d8fa6;
    font-weight: 500;
    flex-shrink: 0;
}
.routing-v2-card-drive.is-live {
    color: #aeeeff;
    font-weight: 600;
}

/* ── Map overlays ───────────────────────────────────────────────────────── */
.routing-v2-legend {
    position: absolute;
    bottom: 14px;
    left: 14px;
    z-index: 500;
    background: rgba(7, 11, 18, 0.85);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 10px;
    padding: 0.55rem 0.7rem;
    display: flex;
    gap: 0.85rem;
    font-size: 0.7rem;
}

.routing-v2-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #bad0e8;
    text-transform: capitalize;
}
.routing-v2-legend-dot { width: 9px; height: 9px; border-radius: 999px; }
.routing-v2-legend-item[data-period="morning"]   .routing-v2-legend-dot { background: #ffc866; }
.routing-v2-legend-item[data-period="afternoon"] .routing-v2-legend-dot { background: var(--accent); }
.routing-v2-legend-item[data-period="evening"]   .routing-v2-legend-dot { background: #a78bfa; }

.routing-v2-day-total {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 500;
    background: rgba(7, 11, 18, 0.85);
    backdrop-filter: blur(8px);
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 10px;
    padding: 0.5rem 0.75rem;
    font-size: 0.74rem;
    color: #bad0e8;
    font-variant-numeric: tabular-nums;
    min-width: 130px;
}

.routing-v2-day-total-label {
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 2px;
}
.routing-v2-day-total-error { color: #ff9c9c; font-size: 0.66rem; margin-top: 4px; }

/* Leaflet pin div (assigned via L.divIcon className="cwdb-pin"). The
   colored disc is built inline by the JS so this CSS just clears the
   default Leaflet outline/background that would otherwise sit behind
   the disc and turn it into an awkward rectangle on hover. */
.cwdb-pin { background: transparent; border: 0; }

/* Hover-leg label pill — placed by JS as a non-interactive marker. */
.cwdb-leg-label { background: transparent; border: 0; }
.cwdb-leg-label-inner {
    background: rgba(7, 11, 18, 0.94);
    border: 1px solid rgba(102, 214, 255, 0.5);
    border-radius: 999px;
    padding: 4px 10px;
    font: 700 11px "Plus Jakarta Sans", sans-serif;
    color: #aeeeff;
    white-space: nowrap;
    box-shadow: 0 4px 12px rgba(var(--shadow-rgb), 0.5);
}

/* Leaflet's default tooltip is light-themed; force dark so it reads on
   the CartoDB Dark Matter tiles. */
.leaflet-container .leaflet-tooltip {
    background: rgba(7, 11, 18, 0.92);
    border: 1px solid rgba(102, 214, 255, 0.35);
    color: var(--text);
    font: 600 0.74rem "Plus Jakarta Sans", sans-serif;
    box-shadow: 0 4px 12px rgba(var(--shadow-rgb), 0.5);
}
.leaflet-container .leaflet-tooltip-top::before { border-top-color: rgba(102, 214, 255, 0.35); }
.leaflet-container .leaflet-control-attribution {
    background: rgba(7, 11, 18, 0.6);
    color: var(--muted);
}
.leaflet-container .leaflet-control-attribution a { color: #aeeeff; }

/* ── Responsive (narrow viewports stack list above map) ─────────────────── */
@media (max-width: 880px) {
    .routing-v2-split {
        grid-template-columns: 1fr;
        grid-template-rows: minmax(220px, 38vh) 1fr;
    }
    .routing-v2-list {
        max-height: 38vh;
        border-right: 0;
        border-bottom: 1px solid rgba(148, 196, 255, 0.14);
    }
}

/* Mobile List | Map view toggle — only visible at <=720px. Hidden on
   tablets+ where both panes can fit side-by-side. The toggle sets a
   data-routing-view attribute on .routing-v2-split which CSS uses to
   hide the inactive pane. */
.routing-v2-viewtoggle {
    display: none;
}
.routing-v2-viewtoggle-btn {
    appearance: none;
    flex: 1 1 50%;
    background: rgba(18, 28, 43, 0.6);
    border: 1px solid rgba(148, 196, 255, 0.22);
    color: var(--text);
    padding: 0.45rem 0.85rem;
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
}
.routing-v2-viewtoggle-btn.is-active {
    background: linear-gradient(180deg, rgba(27, 124, 150, 0.92), rgba(15, 84, 121, 0.96));
    border-color: rgba(102, 214, 255, 0.55);
}
.routing-v2-viewtoggle-btn:first-child { border-radius: 8px 0 0 8px; }
.routing-v2-viewtoggle-btn:last-child  { border-radius: 0 8px 8px 0; border-left: 0; }

/* The List | Map toggle covers everything up to the side-by-side cutoff
   (880px). Portrait iPads (mini 768, Pro 11" 834) used to fall into the
   721-880 band that got a cramped 38vh stacked grid with NO toggle and no
   way to focus either pane; widening this to 880 hands them the same
   full-list / full-map control phones already had. setRoutingView() is
   width-agnostic and already calls invalidateSize() on the map switch, so
   this is a pure-CSS change — no JS touched. */
@media (max-width: 880px) {
    .routing-v2-viewtoggle {
        display: flex;
        margin: 0 0.6rem 0.5rem;
    }
    /* Switch the split from a stacked grid to a single full-height pane
       — whichever view is active fills it. The other is hidden. */
    .routing-v2-split {
        grid-template-rows: 1fr;
    }
    .routing-v2-split[data-routing-view="list"] .routing-v2-list {
        max-height: none;
        height: 100%;
    }
    .routing-v2-split[data-routing-view="list"] .routing-v2-mapwrap {
        display: none;
    }
    .routing-v2-split[data-routing-view="map"] .routing-v2-list {
        display: none;
    }
    .routing-v2-split[data-routing-view="map"] .routing-v2-mapwrap {
        height: 100%;
    }
}

/* ==========================================================================
   Routing — touch + compact mobile chrome (polish 2026-06-12)

   The board is height-locked (body.is-routing-page{overflow:hidden}), so
   vertical space is precious on phones/tablets. Two fixes: (1) the header
   wrapped to ~158px (page title + 7 buttons across 3 rows) on BOTH iPad
   portrait and phones — measured live — and (2) every control sat below
   Apple's 44px touch minimum (~28-33px). All rules are scoped to
   .routing- selectors so nothing leaks to other pages.
   ========================================================================== */
@media (max-width: 880px) {
    /* Compact header: stack a single meta row over one swipeable nav row.
       The page H1 is redundant on mobile — the top nav already labels the
       page "Routing" — so hiding it reclaims a whole row. */
    .routing-v2-header {
        flex-direction: column;
        /* nowrap is load-bearing: the base header is flex-wrap:wrap, and a
           column+wrap container flows children into NEW COLUMNS and stretches
           each to its own content width — so the nav would size to 689px and
           overflow. nowrap makes it a single column where align-items:stretch
           constrains the nav to the header width. */
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 0.45rem;
        padding: 0.5rem 0.7rem;
    }
    .routing-v2-title {
        display: none;
    }
    .routing-v2-meta {
        font-size: 0.8rem;
    }

    /* The day-nav cluster scrolls horizontally; the primary Send-to-JN
       action is pinned beside it so it never scrolls off — it's the last
       step of the routing flow and must always be reachable. */
    .routing-v2-nav {
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 0.45rem;
        min-width: 0;                     /* constrain nav to header width so the
                                             cluster (not the page) scrolls */
    }
    .routing-v2-nav-scroll {
        display: flex;
        /* flex-basis 0 (not auto) is load-bearing: with `auto` the cluster's
           base size is its content width, so it never collapses and the nav
           overflows the viewport, pushing the pinned button off-screen. With
           0 it grows from nothing to fill only the space left beside the
           pinned action, then scrolls internally. */
        flex: 1 1 0;
        min-width: 0;                     /* allow the cluster to shrink + scroll */
        gap: 0.45rem;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;            /* Firefox — keep the row clean */
        padding-bottom: 2px;
    }
    .routing-v2-nav-scroll::-webkit-scrollbar { height: 0; }   /* WebKit — hide bar */
    .routing-v2-nav-scroll > * {
        flex: 0 0 auto;                   /* don't shrink — scroll instead */
    }
    /* Pinned primary action (the only direct .routing-v2-nav button child
       once the cluster is wrapped). */
    .routing-v2-nav > .routing-v2-btn.is-primary {
        flex: 0 0 auto;
        align-self: stretch;
    }

    /* 44px-minimum touch targets (Apple HIG). Buttons grow vertically and
       center their content; the date picker + view toggle match. */
    .routing-v2-btn {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        padding-left: 0.85rem;
        padding-right: 0.85rem;
    }
    .routing-v2-picker {
        min-height: 44px;
        padding-top: 0;
        padding-bottom: 0;
    }
    .routing-v2-viewtoggle-btn {
        min-height: 44px;
    }

    /* Modal close button — easy to hit on all four routing modals. */
    .routing-modal-close {
        min-width: 44px;
        min-height: 44px;
    }
}

/* Phone: color-settings swatches were one row of 12 tiny squares — wrap to
   a 6-column grid of 40px tappable swatches. */
@media (max-width: 720px) {
    .routing-settings-swatches {
        display: grid;
        grid-template-columns: repeat(6, 1fr);
        gap: 0.4rem;
    }
    .routing-settings-swatch {
        min-width: 40px;
        min-height: 40px;
        width: auto;
        height: auto;
    }
}

/* On touch devices a tap leaves :hover stuck on the card until the next tap.
   Neutralize the sticky hover — but ONLY when the card isn't keyboard-
   focused (:focus-visible) or actively cross-highlighted (.is-hover), so
   those intentional states still paint. */
@media (hover: none) {
    .routing-v2-card:hover:not(:focus-visible):not(.is-hover) {
        border-color: rgba(148, 196, 255, 0.15);
        background: rgba(15, 22, 34, 0.55);
    }
}

.routing-modal-addr-stack {
    display: inline-flex;
    flex-direction: column;
    gap: 0.1rem;
}

.routing-modal-addr-line.is-street {
    font-weight: 600;
}

.routing-modal-addr-line.is-city {
    font-size: 0.85rem;
    color: var(--muted);
}

#routingModalProduct.is-empty {
    color: var(--muted);
    font-style: italic;
}

/* Modal overlay used for the assignment popup. */
.routing-modal-backdrop {
    position: fixed;
    inset: 0;
    /* Leaflet's internal panes/controls climb up to z-index ~700, so the
       map ends up rendering above modals that sit at low z-indexes. Park
       the modal layer well above anything Leaflet stacks. */
    z-index: 1500;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 4rem 1rem 2rem;
    background: rgba(4, 8, 14, 0.6);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

.routing-modal-backdrop[hidden] {
    display: none;
}

body.routing-modal-open {
    overflow: hidden;
}

.routing-modal {
    width: 28rem;
    max-width: calc(100vw - 2rem);
    max-height: calc(100vh - 6rem);
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, rgba(20, 30, 46, 0.98), rgba(12, 18, 28, 0.98));
    border: 1px solid rgba(102, 214, 255, 0.4);
    border-radius: 12px;
    box-shadow: 0 20px 50px rgba(var(--shadow-rgb), 0.6);
    overflow: hidden;
    color: var(--text);
}

.routing-modal-head {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.7rem 0.85rem;
    background: rgba(102, 214, 255, 0.08);
    border-bottom: 1px solid rgba(102, 214, 255, 0.2);
}

.routing-modal-head > div {
    flex: 1 1 auto;
    min-width: 0;
}

.routing-modal-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: #ecf6ff;
    line-height: 1.25;
    word-break: break-word;
}

.routing-modal-subtitle {
    margin: 0.2rem 0 0;
    font-size: 0.8rem;
    color: var(--muted);
}

.routing-modal-close {
    flex: 0 0 auto;
    width: 1.8rem;
    height: 1.8rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    color: var(--muted);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}

.routing-modal-close:hover {
    background: rgba(248, 113, 113, 0.18);
    color: var(--danger-ink);
    border-color: rgba(248, 113, 113, 0.55);
}

/* Header actions row — groups "Open in database" link + close button.
   Matches the /database drawer's history-link visual treatment so the
   two app-wide "↗ jump to other page" affordances feel consistent. */
.routing-modal-head-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.routing-modal-head-link {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.6rem;
    border: 1px solid rgba(148, 196, 255, 0.3);
    border-radius: 6px;
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 600;
    text-decoration: none;
    background: rgba(18, 28, 43, 0.4);
    transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
    white-space: nowrap;
}
.routing-modal-head-link:hover {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.55);
    background: rgba(102, 214, 255, 0.08);
}
.routing-modal-head-link[hidden] {
    display: none;
}

.routing-modal-body {
    padding: 0.85rem 0.95rem 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    overflow-y: auto;
}

.routing-modal-summary {
    margin: 0;
    display: grid;
    grid-template-columns: minmax(4rem, 6rem) 1fr;
    column-gap: 0.75rem;
    row-gap: 0.35rem;
    font-size: 0.86rem;
    background: rgba(13, 20, 31, 0.5);
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 8px;
    padding: 0.6rem 0.75rem;
}

.routing-modal-summary-row {
    display: contents;
}

.routing-modal-summary dt {
    margin: 0;
    color: var(--muted);
    font-weight: 600;
}

.routing-modal-summary dd {
    margin: 0;
    color: var(--text);
    word-break: break-word;
}

.routing-modal-fields {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.routing-modal-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.routing-modal-field-label {
    font-size: 0.83rem;
    font-weight: 600;
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.routing-modal-required {
    color: #ffb1b1;
    font-weight: 500;
    font-size: 0.78rem;
}

.routing-modal-optional {
    color: var(--muted);
    font-weight: 500;
    font-size: 0.78rem;
}

.routing-modal-select {
    appearance: none;
    -webkit-appearance: none;
    background-color: rgba(13, 20, 31, 0.7);
    /* Custom caret (matches the app's other styled selects) so the native
       OS combobox arrow doesn't clash with the dark modal. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%2366d6ff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.65rem center;
    background-size: 14px;
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    color: var(--text);
    /* Render the native option popup dark to match the modal. */
    color-scheme: dark;
    cursor: pointer;
    width: 100%;
    box-sizing: border-box;
    padding: 0.45rem 2rem 0.45rem 0.6rem;
    font: inherit;
}

.routing-modal-select:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.7);
    outline-offset: 1px;
    border-color: rgba(102, 214, 255, 0.7);
}

.routing-modal-error {
    margin: 0;
    padding: 0.5rem 0.7rem;
    background: rgba(248, 113, 113, 0.14);
    border: 1px solid rgba(248, 113, 113, 0.4);
    border-radius: 6px;
    color: #ffd9d9;
    font-size: 0.84rem;
}

.routing-modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0.7rem 0.95rem 0.85rem;
    border-top: 1px solid rgba(148, 196, 255, 0.12);
    background: rgba(8, 13, 21, 0.4);
}

.routing-modal-foot .btn {
    min-width: 6rem;
}

/* ----- Send to JobNimbus modal ----- */

.routing-jnmodal {
    width: min(620px, 100%);
}

.routing-jnmodal-body {
    gap: 0.75rem;
    padding-block: 0.85rem;
}

.routing-jnmodal-summary {
    margin: 0;
    font-size: 0.88rem;
    color: rgba(208, 220, 240, 0.78);
}

.routing-jnmodal-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-height: 50vh;
    overflow-y: auto;
}

.routing-jnrow {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.85rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid rgba(148, 196, 255, 0.14);
    border-radius: 8px;
    background: rgba(13, 21, 33, 0.55);
    transition: border-color 0.15s ease, background 0.15s ease;
}

.routing-jnrow.is-empty {
    justify-content: flex-start;
    background: transparent;
    border-style: dashed;
}

.routing-jnrow.is-pending {
    border-color: rgba(102, 214, 255, 0.35);
    background: rgba(102, 214, 255, 0.06);
}

.routing-jnrow.is-ok {
    border-color: rgba(132, 204, 168, 0.4);
    background: rgba(132, 204, 168, 0.08);
}

.routing-jnrow.is-error {
    border-color: rgba(248, 113, 113, 0.5);
    background: rgba(248, 113, 113, 0.08);
}

.routing-jnrow-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}

.routing-jnrow-headline {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    flex-wrap: wrap;
}

.routing-jnrow-customer {
    font-weight: 600;
    color: #f4f7fb;
    font-size: 0.95rem;
}

.routing-jnrow-time {
    font-size: 0.78rem;
}

.routing-jnrow-meta {
    font-size: 0.78rem;
}

.routing-jnrow-rep {
    font-size: 0.85rem;
    color: rgba(220, 230, 245, 0.85);
}

.routing-jnrow-second {
    color: rgba(170, 185, 210, 0.8);
    font-size: 0.78rem;
    margin-left: 0.25rem;
}

.routing-jnrow-detail {
    margin: 0.15rem 0 0;
    font-size: 0.78rem;
    color: rgba(200, 215, 235, 0.75);
}

.routing-jnrow.is-error .routing-jnrow-detail {
    color: #ffd9d9;
}

.routing-jnrow-state {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    color: rgba(170, 185, 210, 0.85);
    padding-top: 0.15rem;
    white-space: nowrap;
}

.routing-jnrow-statedot {
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: rgba(170, 185, 210, 0.45);
}

.routing-jnrow.is-pending .routing-jnrow-statedot {
    background: var(--accent);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.18);
    animation: routing-jnrow-pulse 1.2s ease-in-out infinite;
}

.routing-jnrow.is-ok .routing-jnrow-statedot {
    background: #84cca8;
}

.routing-jnrow.is-error .routing-jnrow-statedot {
    background: #f87171;
}

@keyframes routing-jnrow-pulse {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.25); opacity: 0.65; }
}

/* ----- Color settings modal ----- */
.routing-settings-modal {
    width: min(560px, 100%);
}
.routing-settings-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-height: 60vh;
    overflow-y: auto;
    padding-right: 0.2rem;
}
.routing-settings-row {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 8px;
    background: rgba(15, 22, 34, 0.55);
}
.routing-settings-row-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.6rem;
}
.routing-settings-rep-name {
    font-size: 0.92rem;
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color 0.12s ease;
}
.routing-settings-reset {
    background: transparent;
    border: 1px solid rgba(148, 196, 255, 0.18);
    color: #bad0e8;
    font: 600 0.7rem "Plus Jakarta Sans", system-ui, sans-serif;
    padding: 0.18rem 0.5rem;
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.routing-settings-reset:hover:not(:disabled) {
    border-color: rgba(102, 214, 255, 0.45);
    color: var(--text);
    background: rgba(28, 43, 64, 0.6);
}
.routing-settings-reset:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.routing-settings-swatches {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 0.32rem;
}
.routing-settings-swatch {
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
    transition: transform 0.08s ease, border-color 0.12s ease, box-shadow 0.12s ease;
    box-shadow: inset 0 0 0 1px rgba(var(--shadow-rgb), 0.35);
}
.routing-settings-swatch:hover {
    transform: scale(1.12);
    border-color: rgba(255, 255, 255, 0.4);
}
.routing-settings-swatch.is-selected {
    border-color: var(--text);
    box-shadow: 0 0 0 2px rgba(11, 17, 27, 0.95), 0 0 0 4px rgba(102, 214, 255, 0.55);
}

/* ----- Drive-preview line in the assignment modal ----- */
.routing-modal-drive-preview {
    margin: 0.6rem 0 0;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    background: rgba(28, 43, 64, 0.5);
    border: 1px solid rgba(102, 214, 255, 0.2);
    font-size: 0.82rem;
    color: #d6e4f5;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
/* `display: flex` overrides the user-agent `[hidden] { display: none }`,
   so re-state the rule explicitly here. */
.routing-modal-drive-preview[hidden] { display: none; }
.routing-modal-drive-icon {
    font-size: 1.05rem;
    color: var(--accent);
    font-weight: 800;
    flex-shrink: 0;
}
.routing-modal-drive-text {
    line-height: 1.35;
}

/* ----- Leaflet route polyline tooltip ----- */
.cwdb-route-tip-wrap.leaflet-tooltip {
    background: rgba(11, 17, 27, 0.95);
    border: 1px solid rgba(102, 214, 255, 0.45);
    color: var(--text);
    padding: 0.45rem 0.6rem;
    border-radius: 8px;
    box-shadow: 0 6px 16px rgba(var(--shadow-rgb), 0.55);
    font-family: "Plus Jakarta Sans", system-ui, sans-serif;
}
.cwdb-route-tip-wrap.leaflet-tooltip::before { display: none; }
.cwdb-route-tip {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    font-size: 0.78rem;
}
.cwdb-route-tip strong { font-size: 0.85rem; font-weight: 700; }
.cwdb-route-tip-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid rgba(11, 17, 27, 0.85);
    flex-shrink: 0;
}
.cwdb-route-tip-meta {
    color: #bad0e8;
    font-variant-numeric: tabular-nums;
}

/* ----- Clear-all routing confirmation modal ----- */
.routing-clear-modal {
    width: min(480px, 100%);
}
.routing-clear-modal-summary {
    margin: 0 0 0.4rem 0;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
}
.routing-clear-modal-warn {
    margin: 0;
    font-size: 0.85rem;
    color: rgba(255, 198, 198, 0.85);
}
.routing-clear-modal-backdrop .btn-danger {
    background: linear-gradient(180deg, #b94550, #8a2630);
    border: 1px solid rgba(255, 120, 120, 0.55);
    color: #fff5f5;
    font-weight: 700;
}
.routing-clear-modal-backdrop .btn-danger:hover:not(:disabled) {
    background: linear-gradient(180deg, #cc4f5b, #9d2c37);
}
.routing-clear-modal-backdrop .btn-danger:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 720px) {
    .routing-modal {
        width: 100%;
    }
}

/* =============================================================================
   /disposition page — UI/UX pass.
   Compact hero, stats strip, inline filter toolbar, redesigned table with a
   Time slot column, per-row dirty indicator + undo, and a sticky save bar.
   ========================================================================== */

.disp-hero {
    padding-block: 0.9rem 0.7rem;
}
.disp-hero-row {
    display: flex;
    align-items: baseline;
    gap: 0.65rem;
    flex-wrap: wrap;
}
.disp-hero-row h1 {
    margin: 0;
    font-size: 1.45rem;
    line-height: 1.15;
}
.disp-hero-tag {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.disp-hero-sub {
    margin: 0.4rem 0 0;
    color: var(--muted);
    font-size: 0.92rem;
    max-width: 60ch;
}
.disp-flash {
    margin-bottom: 0.75rem;
}

.disp-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: 0.6rem;
    margin: 0.25rem 0 0.85rem;
}
.disp-stat {
    padding: 0.55rem 0.7rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 9px;
    background: linear-gradient(180deg, rgba(19, 31, 47, 0.7), rgba(12, 19, 30, 0.55));
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.disp-stat.is-warn {
    border-color: rgba(248, 113, 113, 0.5);
    background: linear-gradient(180deg, rgba(60, 22, 22, 0.55), rgba(40, 14, 14, 0.45));
}
.disp-stat-label {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
}
.disp-stat-value {
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.disp-stat.is-warn .disp-stat-value {
    color: var(--danger-ink);
}

.disp-toolbar-panel {
    padding: 0.65rem 0.85rem;
    margin-bottom: 0.85rem;
}
.disp-toolbar {
    display: grid;
    grid-template-columns: minmax(12rem, 1.4fr) minmax(8rem, 0.8fr) minmax(8rem, 0.8fr) auto;
    gap: 0.6rem;
    align-items: end;
}
.disp-toolbar-label {
    display: block;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.2rem;
    font-weight: 700;
}
.disp-toolbar input[type="text"],
.disp-toolbar select {
    width: 100%;
}
.disp-toolbar-apply {
    align-self: end;
}

.disp-form.has-pending .disp-table-panel {
    border-color: rgba(255, 200, 102, 0.45);
}

.disp-slot-warning {
    margin: 0 0 0.75rem;
    padding: 0.6rem 0.8rem;
    border: 1px dashed rgba(255, 200, 102, 0.5);
    border-radius: 8px;
    background: rgba(60, 45, 18, 0.4);
    color: #fff1cc;
    font-size: 0.85rem;
}
.disp-slot-warning code {
    background: rgba(0, 0, 0, 0.3);
    padding: 0.05rem 0.3rem;
    border-radius: 4px;
}

.disp-table-panel {
    padding: 0;
    overflow: hidden;
}
/* Bounded height turns this into a real scroll container, which is what
   `position: sticky` on the thead needs to actually engage. Without a
   max-height, this element expanded to fit content and the document body
   did the scrolling instead — meaning the sticky thead scrolled away
   with the rest of the table. The 280px subtraction accounts for the
   top-nav, hero/toolbar, slot-warning area, and the bottom savebar. */
.disp-table-scroll {
    overflow: auto;
    max-height: calc(100dvh - 280px);
    min-height: 200px;
}
@media (max-width: 880px) {
    .disp-table-scroll {
        max-height: calc(100dvh - 360px);
    }
}
.disp-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin: 0;
    font-size: 0.88rem;
}
.disp-table thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    background: rgba(13, 20, 31, 0.97);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    text-align: left;
    padding: 0.55rem 0.7rem;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    border-bottom: 1px solid rgba(148, 196, 255, 0.18);
    font-weight: 700;
}
.disp-table tbody td {
    padding: 0.55rem 0.7rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.08);
    vertical-align: middle;
}
.disp-table tbody tr.disp-row:hover {
    background: rgba(91, 158, 255, 0.04);
}
.disp-table tbody tr.disp-row.is-dirty {
    background: linear-gradient(90deg, rgba(255, 200, 102, 0.08), rgba(255, 200, 102, 0.02));
    box-shadow: inset 3px 0 0 rgba(255, 200, 102, 0.85);
}
.disp-table tbody tr.disp-row.is-dirty:hover {
    background: linear-gradient(90deg, rgba(255, 200, 102, 0.12), rgba(255, 200, 102, 0.04));
}

.disp-col-job   { min-width: 14rem; }
.disp-col-start { min-width: 7.5rem; }
.disp-col-slot  { min-width: 14rem; }
.disp-col-status { min-width: 8.5rem; }
.disp-col-undo  { width: 2.4rem; }

.disp-job-name {
    font-weight: 700;
    color: var(--text);
    line-height: 1.2;
}
.disp-job-meta {
    margin-top: 0.18rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    color: var(--muted);
    font-size: 0.74rem;
}
.disp-job-jnid {
    font-variant-numeric: tabular-nums;
}
.disp-job-id {
    font-variant-numeric: tabular-nums;
    opacity: 0.65;
}

.disp-cell-start {
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}
.disp-start-rel {
    margin-top: 0.15rem;
    font-size: 0.72rem;
    color: var(--muted);
}
.disp-empty {
    color: var(--muted);
}

/* Time-slot column: date input + period select side-by-side. The cell shows
   a left accent stripe that picks up the active period's color so populated
   slots stand out at a glance. */
.disp-cell-slot {
    position: relative;
    padding-left: 0.85rem;
}
.disp-cell-slot::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55rem;
    bottom: 0.55rem;
    width: 3px;
    border-radius: 3px;
    background: rgba(148, 196, 255, 0.15);
    transition: background 0.15s ease;
}
.disp-cell-slot.has-slot[data-period="morning"]::before   { background: rgba(255, 200, 102, 0.85); }
.disp-cell-slot.has-slot[data-period="afternoon"]::before { background: rgba(102, 214, 255, 0.85); }
.disp-cell-slot.has-slot[data-period="evening"]::before   { background: rgba(167, 139, 250, 0.85); }
.disp-slot-controls {
    display: grid;
    grid-template-columns: minmax(7rem, 1fr) minmax(5.5rem, auto);
    gap: 0.4rem;
    align-items: center;
}
.disp-slot-date,
.disp-slot-period {
    width: 100%;
}

.disp-status-select {
    width: 100%;
}

.disp-cell-undo {
    text-align: center;
}
.disp-undo-btn {
    width: 1.9rem;
    height: 1.9rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 6px;
    color: var(--muted);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease, opacity 0.15s ease;
}
.disp-row.is-dirty .disp-undo-btn {
    opacity: 1;
    pointer-events: auto;
    color: var(--text);
    border-color: rgba(255, 200, 102, 0.6);
}
.disp-undo-btn:hover {
    background: rgba(255, 200, 102, 0.12);
    color: #fff1cc;
}

.disp-empty-row {
    text-align: center;
    color: var(--muted);
    padding: 1.2rem 0;
}

/* Sticky save bar — pinned to the viewport bottom while the user scrolls
   through hundreds of rows. Unobtrusive when there are no pending changes,
   highlighted (amber rail) the moment the form goes dirty. */
.disp-savebar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin: 0.85rem 0 0;
    padding: 0.7rem 0.95rem;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    flex-wrap: wrap;
    background: linear-gradient(180deg, rgba(13, 20, 31, 0.92), rgba(8, 13, 21, 0.96));
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 12px;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 -8px 18px rgba(var(--shadow-rgb), 0.35);
    transition: border-color 0.15s ease, background 0.15s ease;
}
.disp-form.has-pending .disp-savebar {
    border-color: rgba(255, 200, 102, 0.55);
    background: linear-gradient(180deg, rgba(40, 30, 12, 0.85), rgba(22, 16, 8, 0.92));
}
.disp-savebar-status {
    font-size: 0.85rem;
    color: var(--muted);
    flex: 1 1 auto;
    min-width: 0;
}
.disp-form.has-pending .disp-savebar-status {
    color: #fff1cc;
    font-weight: 700;
}
.disp-savebar-actions {
    display: flex;
    gap: 0.5rem;
    flex: 0 0 auto;
}

/* Mobile / narrow viewports — collapse the table into stacked cards so the
   8 editable controls per row stop overflowing horizontally. */
@media (max-width: 880px) {
    .disp-toolbar {
        grid-template-columns: 1fr 1fr;
    }
    .disp-toolbar-search {
        grid-column: 1 / -1;
    }
    .disp-toolbar-apply {
        grid-column: 1 / -1;
    }
    .disp-table thead {
        display: none;
    }
    .disp-table,
    .disp-table tbody,
    .disp-table tr,
    .disp-table td {
        display: block;
        width: 100%;
    }
    .disp-table tbody tr.disp-row {
        padding: 0.7rem 0.85rem;
        border-bottom: 1px solid rgba(148, 196, 255, 0.12);
    }
    .disp-table tbody tr.disp-row.is-dirty {
        box-shadow: inset 3px 0 0 rgba(255, 200, 102, 0.85);
    }
    .disp-table tbody td {
        padding: 0.35rem 0;
        border: 0;
        display: grid;
        grid-template-columns: 6.5rem 1fr;
        gap: 0.6rem;
        align-items: center;
    }
    .disp-table tbody td::before {
        content: attr(data-mobile-label);
        font-size: 0.7rem;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--muted);
        font-weight: 700;
    }
    .disp-cell-job::before    { content: "Job"; }
    .disp-cell-start::before  { content: "Start"; }
    .disp-cell-slot::before   { content: "Time slot"; position: static; width: auto; height: auto; background: transparent; border-radius: 0; padding: 0; }
    .disp-cell-jn::before     { content: "JN"; }
    .disp-cell-lead::before   { content: "Lead"; }
    .disp-cell-cfm::before    { content: "CFM"; }
    .disp-cell-demo::before   { content: "Demo"; }
    .disp-cell-sold::before   { content: "Sold"; }
    .disp-cell-undo {
        justify-content: end;
    }
    .disp-cell-undo::before { content: ""; }
    .disp-cell-slot {
        padding-left: 0;
    }
    /* Restore the period accent as a left border on the stacked cell. */
    .disp-cell-slot.has-slot[data-period="morning"]   { border-left: 3px solid rgba(255, 200, 102, 0.85); padding-left: 0.5rem; }
    .disp-cell-slot.has-slot[data-period="afternoon"] { border-left: 3px solid rgba(102, 214, 255, 0.85); padding-left: 0.5rem; }
    .disp-cell-slot.has-slot[data-period="evening"]   { border-left: 3px solid rgba(167, 139, 250, 0.85); padding-left: 0.5rem; }
}

/* Phone breakpoint (≤720px): the 880px stack still has an inner-row
   horizontal scroll because the label column is 6.5rem wide and the
   slot date+period controls are 200px+ side-by-side — together they
   exceed a 390px viewport. Tighten the label column, force inputs
   to shrink with min-width:0, and stack the slot date over the period
   so neither piece needs to wrap or overflow. */
@media (max-width: 720px) {
    .disp-table tbody td {
        grid-template-columns: 4.2rem minmax(0, 1fr);
        gap: 0.45rem;
    }
    .disp-table tbody td::before {
        font-size: 0.62rem;
    }
    /* Stack the date picker over the period select on phones — they
       don't fit horizontally in the ~250px content column. */
    .disp-slot-controls {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.35rem;
    }
    .disp-slot-date,
    .disp-slot-period,
    .disp-status-select {
        min-width: 0;
        max-width: 100%;
    }
    /* Inputs/selects need a 32px minimum tap target on mobile. */
    .disp-slot-date,
    .disp-slot-period,
    .disp-status-select {
        height: 36px;
        font-size: 0.88rem;
    }
    .disp-table tbody tr.disp-row {
        padding: 0.7rem 0.65rem;
    }
}

/* =============================================================================
   /confirmation page — UI/UX pass.
   Compact hero, scope chip pills (replaces the dropdown), inbox table polish
   (sticky thead, accent rails, segment color stripes), drawer reorganisation,
   modal chrome polish. Color semantics aligned with the Semantic Color
   Reservations table in docs/AI_STYLE_GUIDE.md.

   Action-button color overrides (Confirm green / NoGo red / Remind orange /
   Cancel red ghost) live higher up next to their original definitions so the
   cascade hits them at the same specificity as the legacy rules.
   ========================================================================== */

/* Compact hero — title, count, and scope chips share ONE horizontal row so
   the top of the page is a single tight band of controls. Wraps cleanly to
   two rows on narrow viewports (chips drop below the title group). */
.confirm-hero {
    padding: 0.4rem 0.7rem;
    margin-bottom: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.85rem;
    flex-wrap: wrap;
    flex: 0 0 auto;
}
.confirm-hero-main {
    display: inline-flex;
    align-items: baseline;
    gap: 0.6rem;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: wrap;
}
.confirm-hero-row {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    margin: 0;
}
.confirm-hero-row h1 {
    margin: 0;
    font-size: 1.25rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 800;
}
.confirm-hero-tag {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.confirm-hero-sub {
    margin: 0;
    color: var(--muted);
    font-size: 0.78rem;
    line-height: 1.3;
    white-space: nowrap;
}
.confirm-hero-sub strong {
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
/* The hero now hosts the chips on its right edge, so they no longer take
   their own row of vertical space. The .confirm-scope-chips block below
   stays selector-compatible — flex sizing inherits from .confirm-hero. */
.confirm-hero .confirm-scope-chips {
    margin-left: auto;
}

/* Live clock — prominent right-edge pill in the confirmation hero. The
   tick script in templates/partials/top_nav.php updates it via the
   data-clock-day / data-clock-time hooks. Sized noticeably bigger than
   inline body text so an operator can glance up and read it from across
   the room. */
.confirm-hero-clock {
    display: inline-flex;
    align-items: baseline;
    gap: 0.55rem;
    margin-left: 0.8rem;
    padding: 0.32rem 0.7rem;
    border-radius: 10px;
    border: 1px solid rgba(102, 214, 255, 0.4);
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.12), rgba(102, 214, 255, 0.04));
    color: var(--accent-pale);
    flex: 0 0 auto;
}
.confirm-hero-clock-day {
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.confirm-hero-clock-time {
    color: #ecf6ff;
    font-size: 1.35rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    white-space: nowrap;
    min-width: 7.6rem;
    text-align: right;
}
.confirm-hero-clock-tz {
    color: var(--muted);
    font-size: 0.6rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 800;
    padding-left: 0.1rem;
}
@media (max-width: 640px) {
    .confirm-hero-clock-day { display: none; }
    .confirm-hero-clock-time { font-size: 1.15rem; min-width: 6.4rem; }
}
.confirm-flash {
    margin: 0;
    flex: 0 0 auto;
}

/* Scope chip pills — drive the legacy hidden <select id="confirmationScopeSelect">.
   Tones are pulled from the Semantic Color Reservations table:
     queue → cyan (informational), confirmed → green (success),
     reminders → orange (follow-up), did-not-confirm → red (closed/lost). */
.confirm-scope-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0;
    flex: 0 0 auto;
}
.confirm-scope-chip {
    appearance: none;
    border-radius: 999px;
    padding: 0.3rem 0.75rem;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    cursor: pointer;
    background: rgba(18, 28, 43, 0.55);
    border: 1px solid rgba(148, 196, 255, 0.22);
    color: var(--muted);
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease, transform 0.06s ease;
}
.confirm-scope-chip:hover:not(.is-active) {
    color: var(--text);
    border-color: rgba(148, 196, 255, 0.45);
    background: rgba(28, 42, 60, 0.7);
}
.confirm-scope-chip:active {
    transform: scale(0.97);
}
.confirm-scope-chip:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.35);
}
.confirm-scope-chip.is-active[data-tone="cyan"] {
    background: rgba(102, 214, 255, 0.18);
    border-color: rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
}
.confirm-scope-chip.is-active[data-tone="green"] {
    background: rgba(34, 197, 94, 0.22);
    border-color: rgba(34, 197, 94, 0.7);
    color: var(--success-bg);
}
.confirm-scope-chip.is-active[data-tone="amber"] {
    background: rgba(255, 122, 0, 0.22);
    border-color: rgba(255, 122, 0, 0.7);
    color: var(--warning-bg);
}
.confirm-scope-chip.is-active[data-tone="red"] {
    background: rgba(239, 68, 68, 0.22);
    border-color: rgba(239, 68, 68, 0.65);
    color: var(--danger-bg);
}

/* Compact inbox filter strip — matches the /database filter bar pattern
   (28px controls, inline label+control, single horizontal band) so the
   two pages feel like one app. The hero already carries the scope label
   + count, so the inbox-meta block is gone — the strip is filters only. */
.confirmation.inbox-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.5rem;
    padding: 0.4rem 0.55rem;
    margin-bottom: 0.5rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 10px;
    background: linear-gradient(180deg, rgba(20, 31, 47, 0.55), rgba(13, 20, 31, 0.5));
    flex: 0 0 auto;
}
.confirmation.inbox-filter {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
}
.confirmation.inbox-filter-search {
    flex: 1 1 240px;
    min-width: 200px;
}
.confirmation.inbox-filter label {
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--muted);
    white-space: nowrap;
    flex-shrink: 0;
}
.confirmation.inbox-filter select,
.confirmation.inbox-filter input[type="search"] {
    height: 28px;
    min-width: 110px;
    padding: 0 0.45rem;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: 0.82rem;
}
.confirmation.inbox-filter-search input[type="search"] {
    flex: 1 1 auto;
    min-width: 160px;
}
.confirmation.inbox-refresh-btn {
    height: 28px;
    padding-inline: 0.8rem;
    font-size: 0.8rem;
    font-weight: 600;
    margin-left: auto;
    border: 1px solid rgba(102, 214, 255, 0.32);
    background: rgba(102, 214, 255, 0.06);
    color: #cfeaff;
    border-radius: 7px;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.confirmation.inbox-refresh-btn:hover {
    background: rgba(102, 214, 255, 0.13);
    border-color: rgba(102, 214, 255, 0.55);
}

/* JN-status chip in the inbox table cell + drawer detail. Reuses the
   `.db-chip` tone palette so a chip means the same thing across pages. */
.confirmation.jnstatus-chip {
    font-size: 0.72rem;
    padding: 0.14rem 0.5rem;
    max-width: 100%;
}
.confirmation.inbox-cell.jnstatus {
    overflow: visible;
}

/* ---- Cell with edit affordance ----
   Used by Phone + Marketer rows in the detail popup. The cell shows the
   value (which itself may contain interactive children like tel: links)
   and a tiny pencil button at the right that opens the edit modal. The
   pencil uses the same `.detail-hit` event hook as the other editable
   cells so we don't need a separate handler. */
.confirmation.detail-cell-with-edit {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.confirmation.detail-cell-with-edit > #detailPhones,
.confirmation.detail-cell-with-edit > #detailMarketer {
    flex: 1 1 auto;
    min-width: 0;
}
.confirmation.detail-edit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.55rem;
    height: 1.55rem;
    padding: 0;
    border-radius: 6px;
    border: 1px solid rgba(148, 196, 255, 0.25);
    background: rgba(148, 196, 255, 0.06);
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    flex: 0 0 auto;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.confirmation.detail-edit-btn:hover,
.confirmation.detail-edit-btn:focus-visible {
    background: rgba(102, 214, 255, 0.18);
    border-color: rgba(102, 214, 255, 0.55);
    color: #ecf6ff;
    outline: none;
}
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ---- New-lead notifications ----
   Browser Notification API only — no in-page toast, no sound, no popover.
   The hero hosts a one-shot "Enable notifications" button that's visible
   only while permission is "default"; once "granted" it disappears and
   the auto-refresh poll fires Notifications for any newly-detected job
   IDs. When permission is "denied" the button is replaced with a muted
   hint so it's obvious why nothing fires. */
.confirm-notify-prompt {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    flex: 0 0 auto;
}
.confirm-notify-prompt[hidden] { display: none; }
.confirm-notify-enable {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 30px;
    padding-inline: 0.7rem;
    font-size: 0.8rem;
    border-radius: 8px;
}
.confirm-notify-blocked {
    color: var(--muted);
    font-size: 0.78rem;
    font-style: italic;
}

/* ---- Phone tel: links in the detail popup ----
   Each phone (Mobile / Home / Work) renders as a tappable pill so
   operators on iPad / phone can tap to dial. Uses the cyan accent so
   it reads as an interactive control, not body text. */
.confirmation.detail-phones {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 0.4rem;
    align-items: center;
}
.confirmation.phone-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.16rem 0.5rem 0.16rem 0.32rem;
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.4);
    background: rgba(102, 214, 255, 0.08);
    color: var(--accent-pale);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    font-size: 0.82rem;
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
    line-height: 1.2;
}
.confirmation.phone-link:hover,
.confirmation.phone-link:focus-visible {
    background: rgba(102, 214, 255, 0.18);
    border-color: rgba(102, 214, 255, 0.65);
    color: #ecf6ff;
    text-decoration: none;
    outline: none;
}
.confirmation.phone-tag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.22);
    color: #ecf6ff;
    font-size: 0.62rem;
    letter-spacing: 0.04em;
    font-weight: 800;
}
.confirmation.phone-number {
    color: inherit;
}

/* ---- Detail popup (was a sidebar drawer; now a centered modal) ----
   Standard modal behavior: backdrop captures clicks so clicking outside
   the card closes the popup. The user has to dismiss it before clicking
   another inbox row — matches expectations from every other modal in
   the app and prevents click-through to controls hidden behind. */
/* ---- Detail popup — wider, two-panel, neon dark-mode ---- */
.confirmation.detail-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: grid;
    place-items: center;
    padding: 4rem 1rem 1rem;
    background: rgba(3, 8, 18, 0.68);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}
.confirmation.detail-modal-backdrop[hidden] {
    display: none;
}
.confirmation.detail-drawer.is-modal {
    width: min(900px, calc(100vw - 1.5rem));
    max-height: calc(100vh - 5.5rem);
    border-radius: 14px;
    overflow-y: auto;
    padding-top: 0 !important;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow:
        0 24px 60px rgba(var(--shadow-rgb), 0.8),
        0 0 0 1px rgba(var(--shadow-rgb), 0.4);
}
/* Sticky header — solid surface so scrolled content can't bleed through */
.confirmation.detail-modal-head {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.95rem 1.15rem 0.8rem;
    margin: 0;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
/* Single thin cyan accent line — uses theme accent only, no color shifts */
.confirmation.detail-modal-head::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--accent);
    opacity: 0.55;
    border-radius: 14px 14px 0 0;
}
.confirmation.detail-modal-titleblock {
    flex: 1 1 auto;
    min-width: 0;
}
.confirmation.detail-modal-titleblock h2 {
    margin: 0;
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.8;
    font-weight: 800;
}
.confirmation.detail-modal-titleblock p,
.confirmation.detail-modal-titleblock p#detailMetaLine {
    margin: 0.25rem 0 0;
    font-size: 1.15rem;
    color: var(--text);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.01em;
}
.confirmation.detail-modal-close {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: 8px;
    font-size: 1.1rem;
    line-height: 1;
    border: 1px solid var(--border);
    color: var(--muted);
    background: transparent;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.confirmation.detail-modal-close:hover {
    border-color: rgba(255, 123, 156, 0.55);
    background: rgba(255, 123, 156, 0.10);
    color: var(--danger);
}

/* Wider inbox now that the drawer is gone. The colgroup widths still
   apply, but we can give First/Last/Address a touch more room since
   there's no side panel competing for horizontal space. */
@media (min-width: 1100px) {
    .confirmation.inbox-col-address { width: auto; }
    .confirmation.inbox-col-product { width: auto; }
}

/* Inbox + drawer fill the remaining viewport via flex (the layout-main is a
   100dvh flex column). Only the inbox table body scrolls — that's the queue
   you're paging through. Drawer scrolls internally only if absolutely
   necessary; with the compaction below it should fit on most screens. */
.confirmation.inbox-list-wrap {
    border: 1px solid rgba(148, 196, 255, 0.12);
    background: rgba(8, 13, 21, 0.4);
    height: 100%;
    min-height: 0;
    overflow-y: auto;
    overflow-x: auto;
}
.confirmation.inbox-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: rgba(13, 20, 31, 0.96);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border-bottom: 1px solid rgba(148, 196, 255, 0.2);
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 700;
}
.confirmation.inbox-table tbody tr {
    transition: background 0.1s ease;
}
.confirmation.inbox-table tbody td {
    border-bottom: 1px solid rgba(148, 196, 255, 0.06);
}

/* Segment color rail — glowing left-border stripe keyed to segment.
   Each segment gets its own neon hue so rows self-sort visually even
   when the section headers scroll out of view. Stripe is 4px wide
   with a box-shadow glow so it reads on dark backgrounds. */

/* Call-now → hot magenta */
.confirmation.inbox-row[data-segment*="call"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(255, 0, 180, 0.9),
                inset 8px 0 8px rgba(255, 0, 180, 0.08);
}
/* Same-day → electric orange */
.confirmation.inbox-row[data-segment*="same"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(255, 140, 0, 0.95),
                inset 8px 0 8px rgba(255, 140, 0, 0.10);
}
/* 3-day window → cyan-green */
.confirmation.inbox-row[data-segment*="three"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(0, 255, 200, 0.85),
                inset 8px 0 8px rgba(0, 255, 200, 0.08);
}
/* Future → violet */
.confirmation.inbox-row[data-segment*="future"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(180, 100, 255, 0.85),
                inset 8px 0 8px rgba(180, 100, 255, 0.08);
}
/* Past-due → neon red */
.confirmation.inbox-row[data-segment*="past"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(255, 50, 50, 0.90),
                inset 8px 0 8px rgba(255, 50, 50, 0.08);
}
/* Reminders → amber-gold */
.confirmation.inbox-row[data-segment*="remind"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(255, 200, 0, 0.85),
                inset 8px 0 8px rgba(255, 200, 0, 0.08);
}
/* No start date → muted slate */
.confirmation.inbox-row[data-segment*="no-start"] td:first-child {
    box-shadow: inset 4px 0 0 rgba(148, 163, 184, 0.60);
}
/* New-lead indicator — green right-edge dot via outline on last td */
.confirmation.inbox-row.is-new-lead td:last-child {
    position: relative;
}
.confirmation.inbox-row.is-new-lead td:last-child::after {
    content: '';
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: rgba(74, 214, 125, 1);
    box-shadow: 0 0 6px rgba(74, 214, 125, 0.9);
}
/* is-active is a no-op in popup mode — no persistent rail override. */

/* Detail drawer — popup card body. Padding reduced at top since sticky
   head owns the top space; sections carry their own padding/margin. */
.confirmation.detail-drawer {
    padding: 0 0 1rem;
    gap: 0;
    overflow-y: auto;
    min-height: 0;
}
.confirmation.detail-drawer h2 {
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.8;
    font-weight: 800;
    margin: 0;
}
.confirmation.detail-drawer p#detailMetaLine {
    margin: 0;
    font-size: 0.74rem;
}
/* ---- Popup interior — readable dark-mode layout ---- */

/* Section divider headings — soft cyan eyebrow, no border decoration so
   the section labels blend into the page rhythm without competing with
   the sticky header accent line. */
.confirmation.drawer-subheading {
    margin: 1rem 0.6rem 0.35rem;
    padding: 0;
    border-top: none;
    border-left: none;
    background: none;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.75;
}
.confirmation.detail-drawer > .confirmation.drawer-subheading:first-of-type {
    margin-top: 0.85rem;
}

/* Detail data grid — two columns, label | value. Labels live in their own
   column so values stay aligned regardless of label length. */
.confirmation.detail-grid {
    margin: 0 0.6rem 0.5rem;
    grid-template-columns: minmax(110px, 0.5fr) minmax(0, 1.5fr);
    gap: 0 0.9rem;
    row-gap: 0;
}
.confirmation.detail-grid dt,
.confirmation.detail-grid dd {
    padding: 0.5rem 0.55rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.06);
}
.confirmation.detail-grid dt {
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-size: 0.66rem;
    font-weight: 700;
    color: var(--muted);
    align-self: center;
}
.confirmation.detail-grid dd {
    color: var(--text);
    font-size: 0.92rem;
    line-height: 1.35;
    font-weight: 500;
}
/* Alternating pair tint — pair 1 (children 1+2) and pair 3 (5+6) tinted,
   pairs 2 and 4 left bare. Uses a single subtle white tint so it doesn't
   fight the cyan accent. */
.confirmation.detail-grid dt:nth-child(4n+1),
.confirmation.detail-grid dd:nth-child(4n+2) {
    background: rgba(255, 255, 255, 0.022);
}

.confirmation.detail-id {
    margin: 0.35rem 0.6rem 0.5rem;
    font-size: 0.72rem;
    color: var(--muted);
    opacity: 0.7;
    padding: 0;
    font-variant-numeric: tabular-nums;
}

/* Action buttons — semantic colors with quiet borders, no glow on hover */
.confirmation.detail-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.2rem 0 0.5rem;
    padding: 0 0.6rem;
}
.confirmation.detail-actions .confirmation.drawer-subheading {
    flex: 0 0 100%;
    margin: 0 0 0.1rem;
    border-top: none;
    padding: 0;
}
.confirmation.detail-actions .confirmation.action-btn {
    flex: 1 1 auto;
    min-width: 100px;
    padding: 0.6rem 0.85rem;
    font-size: 0.82rem;
    font-weight: 700;
    border-radius: 8px;
    letter-spacing: 0.02em;
    transition: background 0.12s ease, border-color 0.12s ease;
}
/* Confirm — green */
.confirmation.detail-actions .confirmation.action-btn.is-cfm {
    background: rgba(74, 214, 125, 0.14);
    border: 1px solid rgba(74, 214, 125, 0.45);
    color: #b8f2cc;
}
.confirmation.detail-actions .confirmation.action-btn.is-cfm:hover {
    background: rgba(74, 214, 125, 0.22);
    border-color: rgba(74, 214, 125, 0.65);
}
/* NoGo — red */
.confirmation.detail-actions .confirmation.action-btn.is-nogo {
    background: rgba(255, 123, 156, 0.10);
    border: 1px solid rgba(255, 123, 156, 0.40);
    color: #ffd0dc;
}
.confirmation.detail-actions .confirmation.action-btn.is-nogo:hover {
    background: rgba(255, 123, 156, 0.18);
    border-color: rgba(255, 123, 156, 0.6);
}
/* Cancel disposition — red. This is also a destructive action (cancels
   the appointment) so it carries the same red weight as NoGo. Earlier
   it rendered muted-slate which made operators miss it; the user
   explicitly asked for red. */
.confirmation.detail-actions .confirmation.action-btn.is-cancel-disposition {
    background: rgba(255, 123, 156, 0.10);
    border: 1px solid rgba(255, 123, 156, 0.40);
    color: #ffd0dc;
}
.confirmation.detail-actions .confirmation.action-btn.is-cancel-disposition:hover {
    background: rgba(255, 123, 156, 0.18);
    border-color: rgba(255, 123, 156, 0.6);
}
/* Remind — amber */
.confirmation.detail-actions .confirmation.action-btn.is-remind {
    background: rgba(255, 180, 0, 0.10);
    border: 1px solid rgba(255, 180, 0, 0.38);
    color: #ffe5a0;
}
.confirmation.detail-actions .confirmation.action-btn.is-remind:hover {
    background: rgba(255, 180, 0, 0.18);
    border-color: rgba(255, 180, 0, 0.55);
}
.confirmation.detail-actions .confirmation.action-status {
    flex: 0 0 100%;
    margin-top: 0;
    font-size: 0.74rem;
    color: var(--muted);
}

/* Call log + history */
.confirmation.call-log-block,
.confirmation.call-history-section {
    margin-top: 0.1rem;
    padding: 0 0.6rem;
}
.confirmation.call-log-block .confirmation.action-btn {
    padding: 0.5rem 0.85rem;
    font-size: 0.8rem;
    border-radius: 8px;
    background: rgba(102, 214, 255, 0.06);
    border: 1px solid rgba(102, 214, 255, 0.30);
    color: var(--text);
    font-weight: 600;
}
.confirmation.call-log-block .confirmation.action-btn:hover {
    background: rgba(102, 214, 255, 0.13);
    border-color: rgba(102, 214, 255, 0.55);
}
.confirmation.call-history-list {
    max-height: 120px;
    margin: 0.25rem 0 0;
}
.confirmation.call-history-item {
    padding: 0.3rem 0;
    font-size: 0.8rem;
    color: var(--muted);
    border-bottom: 1px solid rgba(148, 196, 255, 0.06);
}

/* Reminder preview card — amber accent, no glow */
.confirmation.reminder-preview {
    background: rgba(255, 180, 0, 0.06);
    border: 1px solid rgba(255, 180, 0, 0.30);
    border-left: 3px solid rgba(255, 180, 0, 0.65);
    border-radius: 8px;
    padding: 0.6rem 0.75rem;
    margin: 0.4rem 0.6rem;
    box-shadow: none;
}
.confirmation.reminder-preview-text {
    color: #ffe5a0;
    font-size: 0.88rem;
    margin-top: 0.1rem;
    line-height: 1.4;
}

/* Notes — clean bordered textarea, soft cyan focus ring */
.confirmation.notes-form {
    flex: 1 1 auto;
    min-height: 0;
    margin-top: 0.25rem;
    padding: 0.5rem 0.6rem 0.6rem;
}
/* Inline variant — used when the notes form sits between dl sections (i.e.
   directly under the Marketer row) instead of as the drawer's tail block.
   It must NOT flex-grow into the surrounding content; otherwise the textarea
   spills over the rows below. */
.confirmation.notes-form.notes-form-inline {
    flex: 0 0 auto;
    min-height: auto;
    margin: 0.25rem 0.6rem 0.75rem;
    padding: 0.4rem 0;
    display: block;
}
.confirmation.notes-form.notes-form-inline textarea {
    flex: 0 0 auto;
    min-height: 92px;
    max-height: 160px;
    width: 100%;
    display: block;
    resize: vertical;
}
.confirmation.notes-form.notes-form-inline .confirmation.notes-actions {
    margin-top: 0.45rem;
}
.confirmation.notes-form label {
    display: block;
    flex: 0 0 auto;
    font-size: 0.66rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 0.35rem;
}
.confirmation.notes-form textarea {
    flex: 1 1 auto;
    min-height: 120px;
    line-height: 1.5;
    font-size: 0.88rem;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    padding: 0.6rem 0.7rem;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.confirmation.notes-form textarea:focus {
    border-color: rgba(102, 214, 255, 0.55);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.10);
    outline: none;
}
.confirmation.notes-actions {
    margin-top: 0.4rem;
    flex: 0 0 auto;
}

/* Modals — consistent chrome across slot picker, NoGo, Cancel, Call attempt,
   Remind, Detail edit. JS keeps the same flow; only the visual shell changes. */
.confirmation.modal-backdrop {
    background: rgba(4, 8, 14, 0.62);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.confirmation.modal-card {
    border-radius: 14px;
    border: 1px solid rgba(148, 196, 255, 0.22);
    background: linear-gradient(180deg, rgba(20, 30, 45, 0.98), rgba(12, 19, 30, 0.98));
    box-shadow: 0 18px 40px rgba(var(--shadow-rgb), 0.55);
    padding: 1rem 1.1rem 0.95rem;
}
.confirmation.modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.65rem;
    margin-bottom: 0.65rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.16);
}
.confirmation.modal-head h3 {
    margin: 0;
    font-size: 1.05rem;
    color: var(--text);
}
.confirmation.modal-actions {
    margin-top: 0.85rem;
    padding-top: 0.65rem;
    border-top: 1px solid rgba(148, 196, 255, 0.14);
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* Slot picker chip + Remind preset chips — match the new chip language. */
.confirmation.slot-option {
    transition: background 0.12s ease, border-color 0.12s ease;
}
.confirmation.slot-option:hover:not(.is-disabled) {
    border-color: rgba(102, 214, 255, 0.55);
    background: rgba(28, 42, 60, 0.7);
}
.confirmation.slot-option:has(input:checked) {
    border-color: rgba(34, 197, 94, 0.7);
    background: rgba(34, 197, 94, 0.12);
}
/* Overbooked = open > 0 but every rep is already pinned to a job. The radio
   is still selectable; choosing it triggers the overbook confirm() prompt
   on Save. The amber rim signals "needs deliberate confirmation". */
.confirmation.slot-option.is-overbooked {
    border-color: rgba(255, 122, 0, 0.55);
    background: rgba(255, 122, 0, 0.08);
}
.confirmation.slot-option.is-overbooked:hover {
    border-color: rgba(255, 122, 0, 0.75);
    background: rgba(255, 122, 0, 0.12);
}
.confirmation.slot-option.is-overbooked em {
    color: var(--warning-bg);
    font-weight: 700;
}
.confirmation.slot-option.is-overbooked:has(input:checked) {
    border-color: rgba(255, 122, 0, 0.85);
    background: rgba(255, 122, 0, 0.18);
}
.confirmation.remind-preset-btn {
    border-color: rgba(255, 122, 0, 0.32);
    background: rgba(255, 122, 0, 0.05);
}
.confirmation.remind-preset-btn:hover {
    border-color: rgba(255, 122, 0, 0.6);
    background: rgba(255, 122, 0, 0.14);
}

/* Mobile — drop the viewport-fit constraint when stacking vertically. The
   page returns to its natural scrollable layout; otherwise the inbox + drawer
   become tiny scroll boxes inside one tiny column. */
@media (max-width: 880px) {
    body.is-confirmation-page {
        height: auto;
        min-height: 100dvh;
        overflow: auto;
        display: block;
    }
    .layout-main.is-confirmation {
        height: auto;
        overflow: visible;
        display: block;
    }
    .confirmation.page-root,
    .confirmation.inbox-shell {
        flex: 0 0 auto;
        display: block;
        /* Clear the overflow:hidden inherited from .panel — it would
           otherwise act as a scroll container per CSS spec and trap
           the sticky thead inside this element (which never scrolls).
           Letting overflow be visible here lets the sticky thead's
           nearest scroll ancestor become the document body. */
        overflow: visible;
    }
    .confirmation.inbox-layout {
        grid-template-columns: 1fr;
        flex: 0 0 auto;
    }
    .confirmation.inbox-list-wrap {
        height: auto;
        max-height: none;
        overflow: visible;
    }
    /* Sticky thead now sticks to the document body. Offset by the
       top-nav height so the labels park just below it instead of
       hiding behind it. */
    .confirmation.inbox-table thead th {
        top: 48px;
        z-index: 4;
    }
    .confirmation.detail-drawer {
        position: static;
        height: auto;
        max-height: none;
        overflow: visible;
        min-height: 0;
    }
    /* When the drawer is shown as a modal (.is-modal) on mobile, restore
       its own scroll container instead of inheriting `overflow: visible`
       from the rule above. Without this the notes textarea + Save button
       at the bottom of the form get pushed off the viewport with no way
       to scroll to them — operators couldn't see all of long notes or
       reach the Save button. dvh handles iOS Safari's dynamic address
       bar so the modal sizes to the actually-visible viewport. */
    .confirmation.detail-drawer.is-modal {
        max-height: calc(100dvh - 4rem);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    .confirmation.detail-modal-backdrop {
        padding: 2.5rem 0.75rem 0.75rem;
    }
    /* Give the textarea a fixed height on mobile so it doesn't try to
       flex-grow and push the Save button off-screen. Notes longer than
       this scroll inside the textarea naturally. */
    .confirmation.notes-form textarea {
        flex: 0 0 auto;
        min-height: 140px;
        max-height: 40vh;
    }
    .confirmation.detail-actions {
        grid-template-columns: 1fr;
    }
    .confirm-scope-chips {
        gap: 0.35rem;
    }
    .confirm-scope-chip {
        padding: 0.36rem 0.7rem;
        font-size: 0.8rem;
    }
}

/* Employee Stats — wrap the wide totals table in a horizontal scroll
   container so the 12+ stat columns can pan instead of forcing the page
   to grow horizontally. Right-edge gradient hints that more content
   exists when the user hasn't yet scrolled to the rightmost column. */
.empstats-table-scroll {
    position: relative;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 8px;
}
.empstats-table-scroll .empstats-table {
    min-width: 720px;
}
.empstats-table-scroll::after {
    content: "";
    position: sticky;
    top: 0;
    right: 0;
    width: 32px;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(to left, rgba(7, 11, 18, 0.6), rgba(7, 11, 18, 0));
    /* Hide once user has scrolled all the way right (CSS-only via
       `overflow-x: clip` on the inner content would be ideal, but the
       gradient is faint enough to be unobtrusive when shown over
       the last column). */
}
@media (max-width: 720px) {
    /* On phones, narrow the first-column padding and tighten cell
       padding so the table feels less luxurious — fits more columns
       on screen before scroll kicks in. */
    .empstats-table th,
    .empstats-table td {
        padding: 0.45rem 0.55rem;
        font-size: 0.85rem;
    }
    .empstats-table-scroll .empstats-table {
        min-width: 640px;
    }
}

/* Mobile (≤720px): collapse the inbox table rows into stacked "cards"
   so operators on a phone see TIME, customer name, address, marketer,
   and product per job without horizontal scroll. The 7-column table
   layout used on desktop clips after MARKETER on a 390px screen — the
   data is reachable but visually unhelpful. We keep the same <table>
   markup (no template changes needed) and just override display rules:
   thead is hidden, tr becomes a flex/grid card, td cells are placed
   into named grid areas. Hover state is moved from per-cell to the
   whole row so the segment-tinted glow still works.

   This block also compacts the hero + filter toolbar — without it the
   sticky chrome eats ~470px of a 780px viewport, leaving room for less
   than one job above the fold. */
@media (max-width: 720px) {
    /* `.confirmation.inbox-filter` uses `display: inline-flex`, which
       overrides the user-agent `[hidden] { display: none }` rule.
       Without this fix the hidden legacy `LIST` shim renders as a
       visible 28-tall row on every page. Same bug pattern as the
       routing drive-preview / atsb dirty / today badge overrides. */
    .confirmation.inbox-filter[hidden],
    .confirm-scope-select-shim[hidden] {
        display: none !important;
    }

    /* Compact the hero so it doesn't eat 244px on a 780px screen.
       Title block stays tight, clock shrinks, the giant
       "Enable new-lead notifications" pill is hidden on mobile —
       operators can grant the permission from a desktop session. */
    .confirm-hero {
        padding: 0.4rem 0.55rem;
        gap: 0.45rem;
    }
    .confirm-hero-row h1 {
        font-size: 1.05rem;
    }
    .confirm-hero-sub {
        font-size: 0.78rem;
    }
    .confirm-hero-clock {
        margin-left: 0;
        padding: 0.22rem 0.5rem;
    }
    .confirm-hero-clock-time {
        font-size: 1.05rem;
        min-width: 5.2rem;
    }
    /* Compact the new-lead notification permission prompt on mobile —
       keep it accessible (operators do enable from phones too) but
       drop the descriptive label so it shrinks to a 🔔 icon button. */
    .confirm-notify-prompt {
        flex: 0 0 auto;
    }
    .confirm-notify-enable {
        padding: 0.28rem 0.55rem;
        font-size: 0;             /* hide the text label */
        gap: 0;
    }
    .confirm-notify-enable > span[aria-hidden="true"] {
        font-size: 1rem;          /* keep the bell emoji visible */
    }
    .confirm-notify-enable > span:not([aria-hidden="true"]) {
        display: none;            /* hide the "Enable new-lead notifications" text */
    }

    /* Compact the filter toolbar. Tightens padding, lets the search
       input claim its own row at full width so segment/sort/refresh
       can pack into a single wrap row underneath. */
    .confirmation.inbox-toolbar {
        padding: 0.4rem 0.5rem;
        gap: 0.3rem 0.45rem;
    }
    .confirmation.inbox-filter-search {
        flex: 1 1 100%;
    }
    .confirmation.inbox-filter label {
        font-size: 0.6rem;
    }
    .confirmation.inbox-filter select,
    .confirmation.inbox-filter input[type="search"] {
        height: 32px;          /* tap-target */
        font-size: 0.85rem;
    }
    .confirmation.inbox-refresh-btn {
        height: 32px;
        margin-left: auto;
    }

    /* Move the segment color rail from the first <td> (which is .time on
       mobile) onto the outer card itself. On desktop the rail lives on
       td:first-child, which works because there's plenty of padding-left
       inside the cell. On mobile td has padding: 0 so the rail draws
       directly under the time text — "3:00 PM" was clipping into the
       green bar. The card already provides the visual frame, so giving
       it the rail looks better and clears the time text in one go. */
    .confirmation.inbox-row[data-segment] > td:first-child {
        box-shadow: none !important;
    }
    .confirmation.inbox-row[data-segment] {
        /* Clear the 4px segment rail with a generous buffer so the time (and
           the rest of the card) has real breathing room off the color bar. */
        padding-left: 2.35rem;
    }
    .confirmation.inbox-row[data-segment*="call"]     { box-shadow: inset 4px 0 0 rgba(255,   0, 180, 0.90); }
    .confirmation.inbox-row[data-segment*="same"]     { box-shadow: inset 4px 0 0 rgba(255, 140,   0, 0.95); }
    .confirmation.inbox-row[data-segment*="three"]    { box-shadow: inset 4px 0 0 rgba(  0, 255, 200, 0.85); }
    .confirmation.inbox-row[data-segment*="future"]   { box-shadow: inset 4px 0 0 rgba(180, 100, 255, 0.85); }
    .confirmation.inbox-row[data-segment*="past"]     { box-shadow: inset 4px 0 0 rgba(255,  50,  50, 0.90); }
    .confirmation.inbox-row[data-segment*="remind"]   { box-shadow: inset 4px 0 0 rgba(255, 200,   0, 0.85); }
    .confirmation.inbox-row[data-segment*="no-start"] { box-shadow: inset 4px 0 0 rgba(148, 163, 184, 0.60); }

    .confirmation.inbox-table,
    .confirmation.inbox-table tbody {
        display: block;
        width: 100%;
    }
    .confirmation.inbox-table thead,
    .confirmation.inbox-table colgroup,
    .confirmation.inbox-table col {
        display: none;
    }

    /* Three explicit columns: auto-sized first name | flexible space |
       auto-sized segment chip. Each <td> is placed by row + column lines
       so two cells never share a grid area (which was making first + last
       overlap in v1). */
    .confirmation.inbox-row {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        column-gap: 0.45rem;
        row-gap: 0.32rem;
        padding: 0.85rem 0.9rem;
        margin-bottom: 0.5rem;
        border: 1px solid rgba(148, 196, 255, 0.18);
        border-radius: 12px;
        background: rgba(15, 22, 34, 0.55);
    }
    .confirmation.inbox-row > td {
        padding: 0;
        border: 0;
        background: transparent !important;
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        font-size: 0.86rem;
        /* Allow long unbreakable strings (test data, weird customer
           names without spaces, long URLs in notes) to wrap mid-word
           instead of forcing horizontal page overflow. Without this
           a row with "Testingdbheurhdjdnnamaknab" pushes the table
           ~80px past the viewport edge. */
        overflow-wrap: anywhere;
        word-break: break-word;
        min-width: 0;
    }
    /* Row 1: time spans the left two columns, segment chip pinned right */
    .confirmation.inbox-cell.time {
        grid-row: 1;
        grid-column: 1 / 3;
        align-self: start;
    }
    .confirmation.inbox-cell.segment {
        grid-row: 1;
        grid-column: 3;
        justify-self: end;
        align-self: start;
    }
    /* Row 2: first name in col 1, last name in cols 2–3 (flush left) so
       they read like "Kari Chatwin" with a single column-gap between. */
    .confirmation.inbox-cell.first {
        grid-row: 2;
        grid-column: 1;
        font-weight: 700;
        font-size: 1rem;
        color: var(--text);
        justify-self: start;
    }
    .confirmation.inbox-cell.last {
        grid-row: 2;
        grid-column: 2 / 4;
        font-weight: 700;
        font-size: 1rem;
        color: var(--text);
        justify-self: start;
    }
    /* Row 3: address full-width */
    .confirmation.inbox-cell.address {
        grid-row: 3;
        grid-column: 1 / 4;
        font-size: 0.82rem;
        color: rgba(214, 226, 245, 0.85);
        line-height: 1.35;
    }
    /* Row 4: marketer left, product right */
    .confirmation.inbox-cell.marketer {
        grid-row: 4;
        grid-column: 1 / 3;
        font-size: 0.74rem;
        font-weight: 500;
        color: var(--muted);
    }
    .confirmation.inbox-cell.product {
        grid-row: 4;
        grid-column: 3;
        font-size: 0.74rem;
        font-weight: 500;
        color: var(--muted);
        justify-self: end;
    }

    /* Hover/new-lead state moves from <td> to the row card itself.
       The desktop rules paint cell backgrounds, which are transparent
       in this card layout — re-route the same visual effects to the
       <tr>. */
    .confirmation.inbox-row:hover > td,
    .confirmation.inbox-row.is-new-lead > td,
    .confirmation.inbox-row.is-active > td {
        background: transparent !important;
    }
    .confirmation.inbox-row.is-new-lead {
        background: rgba(74, 214, 125, 0.07);
    }
    .confirmation.inbox-row:hover {
        background: rgba(102, 214, 255, 0.10);
        border-color: rgba(102, 214, 255, 0.32);
    }
    .confirmation.inbox-row.is-new-lead:hover {
        background: rgba(74, 214, 125, 0.15);
    }
    .confirmation.inbox-row[data-segment*="call"]:hover   { background: rgba(255, 0, 180, 0.11); }
    .confirmation.inbox-row[data-segment*="same"]:hover   { background: rgba(255, 140, 0, 0.13); }
    .confirmation.inbox-row[data-segment*="three"]:hover  { background: rgba(0, 255, 200, 0.10); }
    .confirmation.inbox-row[data-segment*="future"]:hover { background: rgba(180, 100, 255, 0.11); }
    .confirmation.inbox-row[data-segment*="past"]:hover   { background: rgba(255,  50,  50, 0.11); }
    .confirmation.inbox-row[data-segment*="remind"]:hover { background: rgba(255, 200,   0, 0.10); }
    .confirmation.inbox-row[data-segment*="no-start"]:hover { background: rgba(148, 163, 184, 0.10); }

    /* Empty-state row: "No confirmation rows available." stays a normal
       block of text instead of a grid card. */
    .confirmation.inbox-table tbody tr:not(.confirmation.inbox-row) {
        display: block;
        padding: 1rem 0.9rem;
        text-align: center;
    }
    .confirmation.inbox-table tbody tr:not(.confirmation.inbox-row) > td {
        display: block;
        padding: 0;
    }

    /* Allow the scope chip strip to wrap and shrink labels so all 4
       fit. "Did not confirm" was clipping at the right edge; with
       smaller padding + font on mobile they now line-wrap cleanly. */
    .confirm-scope-chips {
        flex-wrap: wrap;
        width: 100%;
    }
    .confirm-scope-chip {
        padding: 0.32rem 0.6rem;
        font-size: 0.75rem;
    }
}

/* ============================================================================
   /database page — full UI/UX + functionality remodel.
   Viewport-fit split-screen: filterable list on the left, deep-dive drawer on
   the right. Only the inbox table body scrolls; everything else stays pinned.
   Color semantics + chip language follow docs/AI_STYLE_GUIDE.md.
   ============================================================================ */

body.is-database-page {
    height: 100dvh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
body.is-database-page .top-nav {
    flex: 0 0 auto;
}
body.is-database-page .layout-main.is-database {
    flex: 1 1 auto;
    min-height: 0;
}
.layout-main.is-database {
    max-width: none;
    height: 100%;
    min-height: 0;
    min-width: 0;
    overflow: hidden;
    padding: 0.5rem 0.6rem 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

/* Compact hero — same shape as the confirmation hero so the workspace
   header style stays consistent across pages. */
.db-hero {
    padding: 0.4rem 0.7rem;
    margin-bottom: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.85rem;
    flex-wrap: wrap;
    flex: 0 0 auto;
}
.db-hero-main {
    display: inline-flex;
    align-items: baseline;
    gap: 0.55rem;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: wrap;
}
.db-hero-row {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    margin: 0;
}
.db-hero-row h1 {
    margin: 0;
    font-size: 1.25rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 800;
}
.db-hero-tag {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.db-hero-sub {
    margin: 0;
    color: var(--muted);
    font-size: 0.78rem;
    line-height: 1.3;
    white-space: nowrap;
}
.db-hero-sub strong {
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Filter bar — compact horizontal band. Filters are inline label+control
   so each filter takes ~half the vertical space the stacked layout did.
   Every control normalised to 28px so the bar reads as one quiet strip
   instead of a busy form. */
.db-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.5rem;
    align-items: center;
    padding: 0.4rem 0.55rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 10px;
    background: linear-gradient(180deg, rgba(20, 31, 47, 0.55), rgba(13, 20, 31, 0.5));
    flex: 0 0 auto;
}
.db-filter {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
}
.db-filter-search {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: 1 1 260px;
    min-width: 220px;
}
.db-filter-narrow .db-filter-label {
    /* Narrow filters (Per page, Sort) don't need their label inline; the
       select itself carries enough context. Keep label visually but let
       the control collapse to its content. */
}
.db-filter-label {
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--muted);
    white-space: nowrap;
    flex-shrink: 0;
}
.db-filter select,
.db-filter input,
.db-filter-search input {
    height: 28px;
    min-width: 110px;
    padding: 0 0.45rem;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: 0.82rem;
}
.db-filter-search input {
    flex: 1 1 auto;
    min-width: 160px;
}
.db-filter-narrow select,
.db-filter-narrow input {
    min-width: 0;
    width: auto;
}
.db-filter-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-left: auto;
}
.db-filter-actions .btn {
    height: 28px;
    padding-inline: 0.7rem;
    font-size: 0.8rem;
}

/* Body grid — fills remaining viewport, splits into list + drawer. */
.db-body-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(320px, 0.9fr);
    gap: 0.6rem;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0;
}

/* List panel — outer container, owns the scrollable table + sticky pager. */
.db-list-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0.55rem 0.65rem 0.6rem;
}
.db-list-wrap {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 8px;
    background: rgba(8, 13, 21, 0.4);
}

.db-list-table {
    margin: 0;
    width: 100%;
    /* See note on .confirmation.inbox-table — sticky thead reliability fix. */
    border-collapse: separate;
    border-spacing: 0;
    overflow: visible;
}
.db-list-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: rgba(13, 20, 31, 0.96);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border-bottom: 1px solid rgba(148, 196, 255, 0.2);
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    color: var(--muted);
    text-align: left;
    padding: 0.6rem 0.65rem;
    font-weight: 700;
}
.db-list-table tbody td {
    padding: 0.62rem 0.65rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.06);
    vertical-align: top;
    font-size: 0.85rem;
}
/* Subtle zebra — improves row scannability without colored hover collisions
   since the database list has no segment-tinted rows. */
.db-list-table tbody tr:nth-child(even) td {
    background-color: rgba(255, 255, 255, 0.018);
}
.db-row {
    cursor: pointer;
    transition: background 0.12s ease;
}
.db-row:hover td {
    background: rgba(102, 214, 255, 0.07);
}
.db-row.is-selected td {
    background: rgba(102, 214, 255, 0.12);
}
.db-row.is-selected td:first-child {
    box-shadow: inset 3px 0 0 var(--accent);
}
.db-row:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.6);
    outline-offset: -2px;
}

.db-cell-job-name {
    font-weight: 700;
    color: var(--text);
    line-height: 1.2;
    letter-spacing: -0.005em;
}
.db-cell-job-sub {
    margin-top: 0.2rem;
    color: var(--muted);
    font-size: 0.7rem;
    display: flex;
    gap: 0.35rem;
    flex-wrap: wrap;
    font-variant-numeric: tabular-nums;
}
.db-cell-job-sep {
    opacity: 0.5;
}
.db-cell-start {
    /* Cell carries a two-line value: "Mon, Apr 27\n9:30 AM" — `pre`
       (not `pre-line`) preserves the explicit newline AND prevents the
       date or time from wrapping mid-string when the column is narrow.
       The min-width on .db-col-start below reserves enough horizontal
       space so neither line gets ellipsised. */
    white-space: pre;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    font-size: 0.78rem;
    color: var(--text);
    font-weight: 600;
}
.db-col-start,
.db-cell-start {
    min-width: 6.5rem;
    width: 1%;
}
.db-cell-marketer {
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.db-cell-contact-name {
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.db-cell-contact-sub {
    margin-top: 0.12rem;
    color: var(--muted);
    font-size: 0.72rem;
    white-space: nowrap;
}
.db-cell-address {
    max-width: 380px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--muted);
}
.db-cell-status {
    color: var(--text);
    font-size: 0.78rem;
}
.db-empty {
    color: var(--muted);
    opacity: 0.6;
}
.db-empty-row {
    text-align: center;
    color: var(--muted);
    padding: 1.5rem 0;
}

/* Pager footer — pinned to the bottom of the list panel. */
.db-pager {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.55rem 0.45rem 0.1rem;
    border-top: 1px solid rgba(148, 196, 255, 0.14);
    margin-top: 0.5rem;
    flex: 0 0 auto;
}
.db-pager-summary {
    color: var(--muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}
.db-pager-summary strong {
    color: var(--text);
    font-weight: 700;
}
.db-pager-nav {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-left: auto;
}
.db-pager-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 8px;
    border: 1px solid rgba(148, 196, 255, 0.28);
    background: rgba(18, 28, 43, 0.55);
    color: var(--text);
    font-size: 1rem;
    line-height: 1;
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.db-pager-btn:hover:not(.is-disabled) {
    border-color: rgba(102, 214, 255, 0.55);
    background: rgba(28, 42, 60, 0.75);
}
.db-pager-btn.is-disabled {
    opacity: 0.4;
    pointer-events: none;
}
.db-pager-position {
    font-size: 0.78rem;
    color: var(--muted);
    padding: 0 0.35rem;
}
.db-pager-position strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.db-export-btn {
    height: 36px;
    padding-inline: 0.85rem;
    text-decoration: none;
}
/* Footer action cluster — Print Table + Export CSV sit together at the far
   right of the pager (after .db-pager-nav, which carries margin-left:auto). */
.db-footer-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.db-print-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 36px;
    padding-inline: 0.85rem;
    text-decoration: none;
}
.db-print-ico {
    flex: 0 0 auto;
    opacity: 0.85;
}

/* Detail drawer — six grouped sections with subtle dividers. Scrolls
   internally only if its content overflows the viewport row height. */
.db-detail-drawer {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
    padding: 0.7rem 0.85rem 0.75rem;
    gap: 0.45rem;
}
.db-drawer-head {
    flex: 0 0 auto;
    border-bottom: 1px solid rgba(148, 196, 255, 0.14);
    padding-bottom: 0.45rem;
    margin-bottom: 0.15rem;
}
.db-drawer-title {
    margin: 0;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 800;
}
.db-drawer-meta {
    margin: 0.22rem 0 0;
    color: var(--text);
    font-weight: 800;
    font-size: 1.05rem;
    line-height: 1.2;
    letter-spacing: -0.01em;
}
.db-drawer-form {
    display: block;
}
.db-drawer-section {
    padding: 0.45rem 0 0.35rem;
    border-top: 1px solid rgba(148, 196, 255, 0.1);
}
.db-drawer-section:first-of-type {
    border-top: none;
    padding-top: 0.15rem;
}
/* Notes section is a normal block — no flex grow. Letting the textarea
   fight Actions for vertical space caused the textarea content to bleed
   over the next section. The drawer itself (`.db-detail-drawer`) already
   handles overflow with internal scrolling, so a fixed-height textarea
   keeps every section clearly separated regardless of content length. */
.db-drawer-section-notes {
    display: block;
}
.db-section-h {
    margin: 0 0 0.4rem;
    font-size: 0.66rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.75;
    font-weight: 800;
}
.db-field {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
    margin-bottom: 0.35rem;
}
.db-field-label {
    font-size: 0.62rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    opacity: 0.85;
}
.db-field input[type="text"],
.db-field input[type="date"],
.db-field select {
    height: 34px;
    padding: 0 0.55rem;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
}
.db-field-readonly .db-field-value {
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 600;
    word-break: break-word;
}
.db-field-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
    margin-bottom: 0.35rem;
}
.db-field-row .db-field {
    margin-bottom: 0;
}
.db-field-row-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.db-field-narrow {
    max-width: 110px;
}
.db-field-hint {
    margin: 0.2rem 0 0;
    font-size: 0.7rem;
    color: var(--muted);
    font-style: italic;
}

/* ---- Click-to-edit input field treatment ----
   Inputs that auto-save on blur look like a relaxed text line until the
   user hovers or focuses, at which point they reveal an edit affordance.
   Distinct from native form inputs so the read-only-feeling drawer stays
   visually quiet but every value is still a one-click edit. */
.db-edit-input {
    width: 100%;
    box-sizing: border-box;
    height: 32px;
    padding: 0 0.55rem;
    border-radius: 7px;
    border: 1px solid transparent;
    background: rgba(18, 28, 43, 0.35);
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
    font-weight: 600;
    transition: background 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
    cursor: text;
}
.db-edit-input::placeholder {
    color: var(--muted);
    font-weight: 400;
    opacity: 0.7;
}
.db-edit-input:hover:not(:focus):not(:disabled) {
    background: rgba(28, 42, 60, 0.55);
    border-color: rgba(148, 196, 255, 0.22);
}
.db-edit-input:focus {
    outline: none;
    background: rgba(8, 13, 21, 0.7);
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.22);
}
.db-edit-input:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
select.db-edit-input,
.db-edit-select {
    cursor: pointer;
}
.db-edit-textarea {
    height: 120px;
    padding: 0.5rem 0.6rem;
    line-height: 1.4;
    font-weight: 500;
    resize: vertical;
}

/* Drawer status chip row — five evenly-spaced columns. Auto-fit so the row
   gracefully drops to 3 then 2 columns on narrow drawer widths instead of
   producing the lopsided 3+2 wrap a flex layout caused. Each slot has a
   consistent label + chip vertical layout. */
.db-drawer-chiprow {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.55rem 0.65rem;
    align-items: end;
}
@media (max-width: 880px) {
    .db-drawer-chiprow { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 540px) {
    .db-drawer-chiprow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.db-drawer-chipfield {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
    min-width: 0;
}
.db-drawer-chipslot {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
}
.db-drawer-chipslot .db-chip-cell {
    width: 100%;
}
.db-drawer-chipslot .db-chip {
    width: 100%;
    justify-content: flex-start;
}

/* ---- Status chip + chip-picker editor ----
   A `.db-chip-cell` is a label that wraps a visible chip face and an
   invisible native <select> overlay. Click the chip → native dropdown
   opens. The chip face renders the current status with its semantic tone.
   Same component used in the list table cells AND the drawer chip row. */
.db-chip-cell {
    position: relative;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    line-height: 1;
}
.db-chip-edit {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    background: transparent;
    /* The chip <span> renders the visible label, so we hide the native
       select's own text via `color: transparent`. CRITICAL: undo this on
       the <option> children — when the dropdown opens, the option list
       inherits this color and every entry renders blank. */
    color: transparent;
}
/* Make the OPENED dropdown panel readable. Browsers render <option>s with
   their own widget styling, but they DO honor color/background-color on
   options. Without these the dropdown looks blank/white-on-white. */
.db-chip-edit option {
    color: var(--text);
    background-color: var(--surface-2);
    font-weight: 600;
    font-size: 0.85rem;
}
.db-chip-edit option:checked {
    background-color: rgba(102, 214, 255, 0.22);
    color: #ecf6ff;
}
.db-chip-edit:focus + .db-chip,
.db-chip-cell:hover .db-chip {
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.28);
}
.db-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.28);
    background: rgba(148, 196, 255, 0.08);
    color: var(--text);
    font-size: 0.74rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: 0.02em;
    white-space: nowrap;
    max-width: 14rem;
    overflow: hidden;
}
.db-chip-icon {
    font-weight: 800;
    line-height: 1;
    opacity: 0.9;
}
.db-chip-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.db-chip-caret {
    margin-left: 0.1rem;
    opacity: 0.55;
    font-size: 0.65rem;
}

/* Tone variants — mapped from StatusPresenter::tones() and the
   docs/AI_STYLE_GUIDE.md Semantic Color Reservations table. Each chip uses
   the reserved triplet to keep colour meaning consistent across the app. */
.db-chip-green {
    background: rgba(34, 197, 94, 0.16);
    border-color: rgba(34, 197, 94, 0.55);
    color: #d3f7df;
}
.db-chip-red {
    background: rgba(239, 68, 68, 0.16);
    border-color: rgba(239, 68, 68, 0.55);
    color: var(--danger-bg);
}
.db-chip-amber {
    background: rgba(255, 200, 102, 0.18);
    border-color: rgba(255, 200, 102, 0.55);
    color: #ffe4b3;
}
.db-chip-cyan {
    background: rgba(102, 214, 255, 0.18);
    border-color: rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
}
.db-chip-violet {
    background: rgba(173, 116, 240, 0.18);
    border-color: rgba(173, 116, 240, 0.55);
    color: #ead7ff;
}
.db-chip-orange {
    background: rgba(255, 122, 0, 0.18);
    border-color: rgba(255, 122, 0, 0.55);
    color: var(--warning-bg);
}
.db-chip-neutral {
    background: rgba(148, 196, 255, 0.1);
    border-color: rgba(148, 196, 255, 0.32);
    color: var(--text);
}
.db-chip-empty,
.db-chip.is-empty {
    background: transparent;
    border-color: rgba(148, 196, 255, 0.22);
    border-style: dashed;
    color: var(--muted);
    font-weight: 600;
}

/* Drawer save status — small pill above the form that flashes save
   success / failure messages without disturbing the drawer layout. */
.db-drawer-savetip {
    display: inline-block;
    margin-top: 0.18rem;
    min-height: 1rem;
    font-size: 0.72rem;
    color: var(--muted);
    line-height: 1;
}
.db-drawer-savetip.is-success {
    color: #d3f7df;
}
.db-drawer-savetip.is-error {
    color: var(--danger-bg);
}

.db-action-hint {
    color: var(--muted);
    font-size: 0.74rem;
    font-style: italic;
}

.db-drawer-section-notes textarea {
    display: block;
    width: 100%;
    box-sizing: border-box;
    height: 140px;
    padding: 0.5rem 0.6rem;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    line-height: 1.4;
    resize: vertical;
}

/* Action / cross-page link rows. Save = green (primary), Reset = neutral
   ghost. Jump links share the ghost button look but use the cyan accent
   border so they read as navigation, not data writes. */
.db-drawer-section-actions {
    flex: 0 0 auto;
    border-top: 1px solid rgba(148, 196, 255, 0.14);
}
.db-action-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin-bottom: 0.45rem;
}
.db-save-btn {
    background: linear-gradient(170deg, rgba(22, 122, 60, 0.92), rgba(20, 84, 50, 0.92));
    border-color: rgba(34, 197, 94, 0.6);
    color: var(--success-bg);
}
.db-save-btn:hover:not(:disabled) {
    background: linear-gradient(170deg, rgba(28, 150, 75, 0.95), rgba(24, 104, 60, 0.95));
    border-color: rgba(34, 197, 94, 0.85);
}
.db-save-btn:disabled,
.db-reset-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.db-save-status {
    font-size: 0.78rem;
    color: var(--muted);
    margin-left: auto;
}
.db-save-status.is-success {
    color: var(--success-bg);
}
.db-save-status.is-error {
    color: var(--danger-bg);
}
/* Cross-page deep-link landing flash on /disposition rows. The flash is a
   one-shot animation triggered by the `is-focus-flash` class added by the
   focus snippet at the bottom of the page. */
@keyframes dbFocusFlash {
    0%   { background: rgba(102, 214, 255, 0.35); }
    100% { background: transparent; }
}
.disp-row.is-focus-flash > td {
    animation: dbFocusFlash 2.4s ease-out;
}

/* Mobile — drop the viewport-fit constraint when stacking vertically.
   Drawer falls below the table; both expand naturally. */
@media (max-width: 1024px) {
    .db-body-layout {
        grid-template-columns: 1fr;
    }
}
@media (max-width: 880px) {
    body.is-database-page {
        height: auto;
        min-height: 100dvh;
        overflow: auto;
        display: block;
    }
    .layout-main.is-database {
        height: auto;
        overflow: visible;
        display: block;
    }
    .db-body-layout {
        grid-template-columns: 1fr;
        flex: 0 0 auto;
    }
    .db-list-panel,
    .db-detail-drawer {
        height: auto;
        max-height: none;
        overflow: visible;
        min-height: 0;
    }
    .db-list-wrap {
        max-height: 60vh;
    }
    .db-filter-actions {
        margin-left: 0;
        width: 100%;
        justify-content: flex-end;
    }
    .db-cell-address {
        max-width: 180px;
    }
}

/* Mobile (≤720px): collapse the 5-column job table into stacked cards.
   Same approach as the Confirmation inbox — keeps the markup intact,
   overrides display rules so each <tr> becomes a card and each <td>
   gets explicit grid placement. The desktop side-pane behavior was
   already gone (now a popup modal) so the list reclaims full width. */
@media (max-width: 720px) {
    .db-list-table,
    .db-list-table tbody {
        display: block;
        width: 100%;
    }
    .db-list-table thead,
    .db-list-table colgroup,
    .db-list-table col {
        display: none;
    }

    .db-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: 0.5rem;
        row-gap: 0.32rem;
        padding: 0.85rem 0.9rem;
        margin-bottom: 0.5rem;
        border: 1px solid rgba(148, 196, 255, 0.18);
        border-radius: 12px;
        background: rgba(15, 22, 34, 0.55);
        cursor: pointer;
        min-width: 0;
    }
    .db-row > td {
        padding: 0;
        border: 0;
        background: transparent !important;
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        font-size: 0.86rem;
        overflow-wrap: anywhere;
        word-break: break-word;
        min-width: 0;
    }
    /* Row 1: Job (col 1, left) + Start date (col 2, right) */
    .db-cell-job {
        grid-row: 1;
        grid-column: 1;
        min-width: 0;
    }
    .db-cell-start {
        grid-row: 1;
        grid-column: 2;
        justify-self: end;
        align-self: start;
        font-size: 0.78rem;
        color: var(--muted);
        /* Force the start date to render as one line. The parent rule
           uses `word-break: break-word` + `min-width: 0` which lets
           grid items shrink below their content's min-content — that
           was collapsing this cell to ~20px wide regardless of the
           ~115px column. Restoring max-content min-width gives the
           cell the room to display "Fri, May 15 2:00 PM" in full. */
        white-space: nowrap !important;
        word-break: keep-all !important;
        overflow-wrap: normal !important;
        min-width: max-content !important;
        /* Server returns "Fri, May 15\n2:00 PM" with a literal newline
           between the date and time. Render the time on its own line
           (looks better than a single 140px-wide line + adds visual
           hierarchy). pre-line preserves the newline AND collapses
           runs of whitespace. */
        white-space: pre-line !important;
        text-align: right;
    }
    .db-cell-job-name {
        font-weight: 700;
        font-size: 0.95rem;
        color: var(--text);
        line-height: 1.3;
    }
    .db-cell-job-sub {
        font-size: 0.7rem;
        color: var(--muted);
        margin-top: 0.15rem;
    }
    /* Rows 2–4: each meta cell on its own row, full width. */
    .db-cell-marketer {
        grid-row: 2;
        grid-column: 1 / 3;
        font-size: 0.78rem;
        color: rgba(214, 226, 245, 0.85);
    }
    .db-cell-contact {
        grid-row: 3;
        grid-column: 1 / 3;
        font-size: 0.78rem;
        color: rgba(214, 226, 245, 0.85);
    }
    .db-cell-contact-name {
        display: inline;
        font-weight: 600;
    }
    .db-cell-contact-sub {
        display: inline;
        margin-left: 0.4rem;
        color: var(--muted);
    }
    .db-cell-address {
        grid-row: 4;
        grid-column: 1 / 3;
        font-size: 0.78rem;
        color: rgba(174, 204, 232, 0.78);
        max-width: none;
        line-height: 1.35;
    }

    .db-row.is-selected {
        border-color: rgba(102, 214, 255, 0.45);
        background: rgba(28, 43, 64, 0.7);
    }
    .db-row:hover {
        border-color: rgba(102, 214, 255, 0.32);
    }
    .db-row:hover td:first-child {
        box-shadow: none;
    }

    /* Compact the filter strip — search spans the full row, then
       JN / CFM / Demo / Sold / Marketer / Per Page / Sort each take
       half a row on phones (2-up grid). Apply / Reset actions share
       a full-width row at the bottom. */
    .db-filter-bar {
        display: grid !important;
        grid-template-columns: 1fr 1fr;
        gap: 0.4rem 0.5rem;
    }
    .db-filter-bar .db-filter-search {
        grid-column: 1 / 3;
    }
    .db-filter-bar .db-filter-actions {
        grid-column: 1 / 3;
    }
    .db-filter-bar .db-filter,
    .db-filter-bar .db-filter-narrow {
        min-width: 0;
    }
    .db-filter-bar .db-filter-label {
        font-size: 0.6rem;
    }
    .db-filter-bar select,
    .db-filter-bar input[type="search"] {
        height: 32px;
        font-size: 0.85rem;
        min-width: 0;
        max-width: 100%;
    }
}

/* ============================================================
 * ANIMATION PASS — tasteful micro-interactions
 *
 * Goals:
 *   - Subtle (most ≤180ms), no bounce, no overshoot, no glow pulses.
 *   - Theme cyan only — never adds a new color.
 *   - Honors prefers-reduced-motion (everything disabled below).
 *   - Purely additive: layered on top of existing styles via
 *     transitions or short keyframe entrances. Removing this block
 *     leaves the app fully functional and visually intact.
 * ============================================================ */

@keyframes cwdbFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes cwdbModalIn {
    from { opacity: 0; transform: translateY(6px) scale(0.985); }
    to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@keyframes cwdbRowIn {
    from { opacity: 0; transform: translateY(3px); }
    to   { opacity: 1; transform: translateY(0); }
}
@keyframes cwdbSavedPulse {
    0%   { background: rgba(74, 214, 125, 0.0); }
    35%  { background: rgba(74, 214, 125, 0.18); }
    100% { background: rgba(74, 214, 125, 0.0); }
}
/* --- Modal entrance: backdrop fades, drawer floats up + scales gently --- */
.confirmation.detail-modal-backdrop:not([hidden]) {
    animation: cwdbFadeIn 140ms ease-out both;
}
.confirmation.detail-modal-backdrop:not([hidden]) .confirmation.detail-drawer.is-modal {
    animation: cwdbModalIn 180ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
/* Same treatment for the secondary modals (slot picker, NoGo, Cancel, etc.) */
.confirmation.modal-backdrop:not([hidden]) {
    animation: cwdbFadeIn 140ms ease-out both;
}
.confirmation.modal-backdrop:not([hidden]) > * {
    animation: cwdbModalIn 180ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

/* --- Row hover: smooth bg transition. Inbox keeps its segment rail
   (set elsewhere); only database rows get a hover rail since they have none. --- */
.confirmation.inbox-table tbody tr,
.db-row {
    transition: background 0.14s ease, box-shadow 0.18s ease;
}
.db-row:not(.is-selected):hover td:first-child {
    box-shadow: inset 3px 0 0 rgba(102, 214, 255, 0.5);
}

/* --- Buttons: tactile press --- */
.btn,
.btn-primary,
.btn-ghost,
.confirmation.action-btn,
.confirmation.inbox-refresh-btn,
.db-pager-btn,
.db-jump-btn {
    transition: background 0.12s ease, border-color 0.12s ease,
                color 0.12s ease, transform 0.08s ease,
                box-shadow 0.12s ease;
}
.btn:active,
.btn-primary:active,
.btn-ghost:active,
.confirmation.action-btn:active,
.confirmation.inbox-refresh-btn:active,
.db-pager-btn:active,
.db-jump-btn:active {
    transform: translateY(1px);
}

/* --- Top nav pill links: smoother bg/border transition --- */
.top-nav-link {
    transition: color 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}

/* --- Inputs/selects: smoother focus ring fade --- */
input[type="text"],
input[type="search"],
input[type="email"],
input[type="tel"],
input[type="number"],
select,
textarea {
    transition: border-color 0.12s ease, box-shadow 0.14s ease,
                background 0.12s ease;
}

/* --- Saved indicator: brief green wash on the row that just saved.
   Hook: any element with .is-just-saved gets a one-shot pulse.
   The JS doesn't need to add this yet; it's available for future use. */
.is-just-saved {
    animation: cwdbSavedPulse 900ms ease-out;
}

/* --- New inbox lead entrance: gentle slide-in.
   The new-lead row is already styled elsewhere; this adds motion only. */
.confirmation.inbox-row.is-new-lead {
    animation: cwdbRowIn 220ms ease-out both;
}

/* --- Confirmation hero clock: smoother color baseline --- */
.confirm-hero-clock {
    transition: color 0.18s ease;
}

/* --- Section headings: tiny opacity bump on hover (purely decorative) --- */
.confirmation.drawer-subheading,
.db-section-h {
    transition: opacity 0.15s ease;
}
.confirmation.detail-drawer:hover .confirmation.drawer-subheading,
.db-detail-drawer:hover .db-section-h {
    opacity: 0.95;
}

/* =========================================================================
   SITE-WIDE THEME CONVERGENCE
   --------------------------------------------------------------------------
   Pulls every page (besides the off-limits live ATSB embed at /atsb-calendar)
   onto the visual conventions established by the Confirmation page so the
   site stops feeling jumpy when navigating between modules.

   What this block normalizes:
     1. Hero typography  — single H1 token (1.25rem / 800 / -0.01em / 1.15)
        applied to every page-header H1 + page-specific hero variants.
     2. Hero tag         — single chip token shared by confirm/disp/atsb-ws.
     3. Layout width     — disposition gets the same full-bleed padding as
        database/confirmation (paired with controller binding the
        `is-disposition` layout class).
     4. Buttons          — defines `.btn-secondary` and `.btn-sm` (referenced
        by employee_stats but previously undefined).
     5. Tabs             — gives `.tabs` (admin + settings) a concrete look
        instead of relying on `.chip` defaults.
     6. Admin panels     — drops the duplicate background on nested
        `.admin.users-list.panel` etc. so admin stops looking "double
        carded" vs the rest of the site.
     7. ATSB test modal  — backdrop matches the confirmation modal backdrop.
   ========================================================================= */

/* ---- 1 + 2: hero typography + tag chip ---------------------------------- */

/* Default page-header H1 — was 1.45rem with no weight bump; pulls in line
   with the confirmation hero so home, reports, admin, employee stats,
   onboarding, and settings all lead with the same H1 voice. */
.page-header h1 {
    font-size: 1.25rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 800;
}
.page-header p {
    font-size: 0.92rem;
    line-height: 1.4;
}

/* Disposition hero — was 1.45rem; tag was oversized vs confirm. */
.disp-hero-row h1 {
    font-size: 1.25rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 800;
}
.disp-hero-tag {
    padding: 0.1rem 0.45rem;
    font-size: 0.58rem;
}

/* Routing in-panel title — was 1.32rem and not aligned. Pulls into line
   without removing its in-panel placement. */
.routing.title {
    font-size: 1.25rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 800;
}

/* ATSB test page (`.atsb-ws`) hero — was inheriting 1.45rem from
   `.page-header h1`. Now that we've shrunk the parent token, restate the
   compact hero values explicitly so changes here aren't accidentally
   tied to the global rule. */
.atsb-ws-hero-row h1 {
    font-size: 1.25rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 800;
}
/* Match the cyan-on-dark pill the rest of the site uses for hero tags
   (was using a violet-leaning border / blue background). */
.atsb-ws-hero-tag {
    border-color: rgba(102, 214, 255, 0.55);
    background: rgba(102, 214, 255, 0.18);
    color: var(--accent-pale);
    font-size: 0.58rem;
    padding: 0.1rem 0.45rem;
}

/* ---- 3: layout width — disposition joins the data-page club ------------ */
/* Already declared as a comma-list in the layout-main rule near the top of
   this file (`.layout-main.is-disposition` is referenced there); this just
   adds a body-class hook so the page can opt into viewport tweaks like
   the other data pages do. */
body.is-disposition-page .layout-main {
    max-width: none;
}

/* ---- 4: button family — fill in the missing variants ------------------- */
/* `.btn-secondary` is referenced by employee_stats print buttons but was
   never defined. Render it as a clean ghost variant so the workspace
   doesn't show a half-styled button. `.btn-sm` is also referenced and
   simply trims the padding for compact toolbars. */
.btn-secondary {
    border-color: var(--border);
    background: transparent;
    color: var(--text);
}
.btn-secondary:hover {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(102, 214, 255, 0.08);
}
.btn-sm {
    padding: 0.35rem 0.6rem;
    font-size: 0.84rem;
    border-radius: 8px;
}

/* ---- 5: shared tab strip for admin / settings -------------------------- */
/* Both pages render `<nav class="settings tabs">` with `.chip` links
   inside. Without dedicated CSS the wrapper had no spacing/box and the
   chips floated awkwardly. This gives them a consistent pill-row look
   that matches the scope-chip pattern used elsewhere. */
.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0.4rem;
    margin: 0 0 0.85rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: rgba(13, 20, 31, 0.55);
}
.tabs .chip {
    box-shadow: none;
    background: transparent;
    border-color: rgba(148, 196, 255, 0.18);
    color: var(--muted);
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.tabs .chip:hover {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(102, 214, 255, 0.06);
    color: var(--text);
}
.tabs .chip.is-active,
.tabs .chip[aria-current="page"] {
    background: rgba(102, 214, 255, 0.16);
    border-color: rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
}

/* ---- 6: admin — drop the nested-panel "card in card" feel -------------- */
/* The admin user-list / actions / create-user blocks added a second
   gradient on top of the standard `.panel` background, producing a
   visible double-card. Letting `.panel` paint the surface alone keeps
   admin in line with the rest of the site. */
.admin.users-list.panel,
.admin.user-actions.panel,
.admin-create-user.panel {
    background: linear-gradient(160deg, rgba(20, 31, 47, 0.84), rgba(13, 20, 31, 0.84));
}

/* ---- 7: ATSB test modal backdrop — match confirmation ------------------- */
/* Was `rgba(4, 8, 14, 0.55)` with no blur; pulls into line with the
   confirmation detail modal so popups feel like one system. */
.atsb-test-modal-backdrop {
    background: rgba(3, 8, 18, 0.68);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

/* ---- 8: page-header — soften the default so simple pages match the
        compact, flatter hero used by the data pages (database,
        confirmation, disposition, ATSB test). The data-page heroes
        already override padding/margin/border to compact values; this
        change brings the *default* (home, reports, settings, admin,
        employee_stats, employee_onboarding) closer to that footprint
        instead of feeling like a different, chunkier component. */
.page-header {
    padding: 0.7rem 0.95rem;
    margin-bottom: 0.85rem;
    border-radius: 12px;
    border-color: rgba(148, 196, 255, 0.18);
    background: linear-gradient(135deg, rgba(20, 31, 47, 0.78), rgba(14, 22, 33, 0.78));
}
.page-header::after {
    width: 140px;
    height: 140px;
    top: -50px;
    right: -30px;
    background: radial-gradient(circle, rgba(102, 214, 255, 0.18), rgba(102, 214, 255, 0));
}
.page-header.workspace.hero {
    border-color: rgba(148, 196, 255, 0.22);
}

/* ---- 9: shared hero row + tag chip ------------------------------------- */
/* Lets simple pages wear the same "h1 + uppercase pill + sub" rhythm as
   the data pages (db-hero, confirm-hero, disp-hero, atsb-ws-hero) without
   inventing yet another bespoke `*-hero-tag` class.

   Markup:
     <section class="page-header workspace hero">
         <div class="page-header-row">
             <h1>Reports</h1>
             <span class="page-tag">Insights</span>
         </div>
         <p class="page-sub">…</p>
     </section>

   Visual is identical to .db-hero-tag / .confirm-hero-tag (same padding,
   font-size, weight, letter-spacing, cyan pill) so the four bespoke
   classes and this shared one all read as one design token. */
.page-header-row {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    flex-wrap: wrap;
    margin: 0;
}
.page-header-row h1 {
    margin: 0;
}
.page-tag {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: rgba(102, 214, 255, 0.18);
    border: 1px solid rgba(102, 214, 255, 0.55);
    color: var(--accent-pale);
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.4;
}
.page-sub {
    margin: 0.4rem 0 0;
    color: var(--muted);
    font-size: 0.88rem;
    line-height: 1.4;
    max-width: 70ch;
}

/* ---- 10: legacy `.chip` — flatten to match the rest of the site -------- */
/* The original `.chip` (used on the home page's "Workspace Modules" row)
   was a glowy neon pill from the early visual pass. Every other chip in
   the app (`.tabs .chip`, `.confirm-scope-chip`, `.db-chip`) is a flat
   muted pill that brightens on hover. Bringing this in line removes the
   "phase 1 vs phase 2" feeling between home and the rest of the app.
   `.chip-shared` is left intact for callers that explicitly want the
   violet shared-component variant. */
.chips {
    gap: 0.4rem;
}
.chip:not(.chip-shared) {
    background: rgba(13, 20, 31, 0.55);
    border-color: rgba(148, 196, 255, 0.22);
    color: var(--muted);
    box-shadow: none;
    padding: 0.35rem 0.7rem;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.chip:not(.chip-shared):hover {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(102, 214, 255, 0.08);
    color: var(--text);
}

/* ---- 11: disposition toolbar — same surface as db / confirmation ------- */
/* `.disp-toolbar-panel` was using its own padding/margin while every other
   filter strip on the site shares the `.db-filter-bar` /
   `.confirmation.inbox-toolbar` chrome. Aligning the wrapper (border,
   background, radius, padding) makes navigating between disposition,
   database, and confirmation feel like one continuous toolbar idiom even
   though the internal control layouts differ. */
.disp-toolbar-panel {
    padding: 0.4rem 0.55rem;
    margin-bottom: 0.5rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 10px;
    background: linear-gradient(180deg, rgba(20, 31, 47, 0.55), rgba(13, 20, 31, 0.5));
}
.disp-toolbar-label {
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    margin-bottom: 0.18rem;
}

/* =========================================================================
   12: ATSB TEST — slot panel as a confirmation-style modal
   --------------------------------------------------------------------------
   Replaces the old top-anchored floating popover with a centered modal that
   matches the `.confirmation.detail-modal-*` chrome:
     - Dim/blur backdrop, click-outside dismisses.
     - Wider, taller card with a sticky header that has the same thin
       cyan accent line.
     - Eyebrow + bold title pattern instead of the small all-caps label.
   Visibility is driven entirely by CSS (`:has(...)`) so the existing JS
   still toggles `jobsPopover.hidden` and nothing else.
   Scoped under `.atsb-ws` so the live `/atsb-calendar` planner is untouched.
   ========================================================================= */

.atsb-ws .atsb-test-jobs-popover-backdrop {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: grid;
    place-items: start center;
    padding: 4rem 1rem 1rem;
    background: rgba(3, 8, 18, 0.68);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.16s ease;
}
.atsb-ws .atsb-test-jobs-popover-backdrop:has(.atsb-test-jobs-popover:not([hidden])) {
    opacity: 1;
    pointer-events: auto;
}

/* Card itself — drop the fixed positioning, become a centered modal that the
   backdrop lays out for us. Width / radius / shadow lifted from
   `.confirmation.detail-drawer.is-modal` so the two modals feel like the
   same component family. */
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover {
    position: relative;
    top: auto;
    left: auto;
    transform: none;
    width: min(640px, calc(100vw - 1.5rem));
    max-width: calc(100vw - 1.5rem);
    max-height: calc(100vh - 5.5rem);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow:
        0 24px 60px rgba(var(--shadow-rgb), 0.8),
        0 0 0 1px rgba(var(--shadow-rgb), 0.4);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    overflow: hidden;
}

/* Sticky header that mirrors `.confirmation.detail-modal-head`. */
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-head {
    position: sticky;
    top: 0;
    z-index: 5;
    padding: 0.95rem 1.15rem 0.8rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    /* needs to be a positioning context for the accent ::before below */
}
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-head::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--accent);
    opacity: 0.55;
    border-radius: 14px 14px 0 0;
}
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-headline {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    align-items: flex-start;
}

/* Eyebrow ("SLOT PANEL") + bold title (the date/period) — matches the
   `.confirmation.detail-modal-titleblock h2` + `p` pattern. */
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-eyebrow {
    margin: 0;
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.8;
    font-weight: 800;
    line-height: 1.2;
}
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-title {
    margin: 0;
    font-size: 1.15rem;
    color: var(--text);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

/* Close button matches `.confirmation.detail-modal-close`. */
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-close {
    width: 2rem;
    height: 2rem;
    border-radius: 8px;
    font-size: 1.1rem;
    line-height: 1;
    border: 1px solid var(--border);
    color: var(--muted);
    background: transparent;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-close:hover {
    border-color: rgba(255, 123, 156, 0.55);
    background: rgba(255, 123, 156, 0.10);
    color: var(--danger-ink);
}

/* Body — bigger padding so the wider card breathes properly. */
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-body {
    padding: 0.9rem 1.15rem 1.15rem;
}

/* Pill sits to the right of the title block, aligned with the eyebrow. */
.atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-pill {
    align-self: flex-start;
}

/* Mobile: shrink padding, allow full-bleed card. */
@media (max-width: 640px) {
    .atsb-ws .atsb-test-jobs-popover-backdrop {
        padding: 1rem 0.5rem 0.5rem;
    }
    .atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover {
        width: calc(100vw - 1rem);
        max-height: calc(100vh - 1.5rem);
    }
    .atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-head {
        padding: 0.75rem 0.85rem 0.65rem;
    }
    .atsb-ws .atsb-test-jobs-popover-backdrop .atsb-test-jobs-popover-body {
        padding: 0.7rem 0.85rem 0.95rem;
    }
}

/* =========================================================================
   13: DATABASE — detail drawer becomes a modal popup
   --------------------------------------------------------------------------
   The database page used to be a 2-column split (job list + always-visible
   detail drawer on the right). The drawer now lives inside a backdrop that
   only shows when a row is clicked; the list panel takes full width
   underneath. Visual chrome of the drawer-as-modal mirrors the confirmation
   detail modal so the two feel like the same component.
   ========================================================================= */

/* List takes the full layout width. Original `.db-body-layout` is a 2-col
   grid; we collapse it (drawer is no longer a layout child anyway once it's
   reparented under the backdrop in the DOM, but keeping the override makes
   sure the grid track for the second column doesn't reserve empty space). */
.db-body-layout {
    grid-template-columns: 1fr;
}

/* Backdrop — fixed/blurred overlay matching `.confirmation.detail-modal-backdrop`. */
.db-detail-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: grid;
    place-items: start center;
    /* 1.5rem top + 1rem bottom = 2.5rem total backdrop padding. The
       modal can grow to viewport - 2.5rem and still have breathing
       room from the screen edges. Closer than this and click-to-
       dismiss-by-clicking-outside the modal becomes awkward. */
    padding: 1.5rem 1rem 1rem;
    background: rgba(3, 8, 18, 0.68);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}
.db-detail-modal-backdrop[hidden] {
    display: none;
}

/* Drawer-as-modal — mirrors `.confirmation.detail-drawer.is-modal`. */
.db-detail-drawer.is-modal {
    width: min(960px, calc(100vw - 1.5rem));
    max-width: calc(100vw - 1.5rem);
    /* Loosened from 100vh-5.5rem to 100vh-2.5rem so the form fits without
       internal scroll on typical 900px+ viewports. Backdrop's reduced
       top padding above gives this room without clipping the top. */
    max-height: calc(100vh - 2.5rem);
    overflow-y: auto;
    padding: 0 !important;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow:
        0 24px 60px rgba(var(--shadow-rgb), 0.8),
        0 0 0 1px rgba(var(--shadow-rgb), 0.4);
    /* Restore vertical layout (the base `.db-detail-drawer` already sets
       flex column, but `padding: 0 !important` collapses sections — we
       restore section padding via the form below). */
}

/* The actual sections are inside `.db-drawer-form`; give it normal padding
   so the modal-card itself can stay flush at the edges. */
.db-detail-drawer.is-modal .db-drawer-form {
    padding: 0.7rem 1.05rem 1rem;
}

/* Sticky head with the cyan accent line. */
.db-detail-drawer.is-modal .db-drawer-head {
    position: sticky;
    top: 0;
    z-index: 5;
    margin: 0;
    padding: 0.95rem 1.15rem 0.8rem;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
}
.db-detail-drawer.is-modal .db-drawer-head::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--accent);
    opacity: 0.55;
    border-radius: 14px 14px 0 0;
}

.db-detail-drawer.is-modal .db-drawer-titleblock {
    flex: 1 1 auto;
    min-width: 0;
}
.db-detail-drawer.is-modal .db-drawer-title {
    margin: 0;
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.8;
    font-weight: 800;
    line-height: 1.2;
}
.db-detail-drawer.is-modal .db-drawer-meta {
    margin: 0.25rem 0 0;
    font-size: 1.15rem;
    color: var(--text);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.01em;
    text-transform: none;
}
.db-detail-drawer.is-modal .db-drawer-savetip {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.78rem;
    color: var(--muted);
    font-weight: 500;
    line-height: 1.3;
}

/* Close button — same as `.confirmation.detail-modal-close`. */
.db-drawer-close {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: 8px;
    font-size: 1.1rem;
    line-height: 1;
    border: 1px solid var(--border);
    color: var(--muted);
    background: transparent;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.db-drawer-close:hover {
    border-color: rgba(255, 123, 156, 0.55);
    background: rgba(255, 123, 156, 0.10);
    color: var(--danger-ink);
}

/* Lock the underlying page scroll while the modal is open. */
body.db-modal-open {
    overflow: hidden;
}

/* Mobile: the database list normally lets the body scroll on small screens
   (see `body.is-database-page`); modal layout still works there with a
   smaller padding. */
@media (max-width: 880px) {
    .db-detail-modal-backdrop {
        padding: 1rem 0.5rem 0.5rem;
    }
    .db-detail-drawer.is-modal {
        width: calc(100vw - 1rem);
        max-height: calc(100vh - 1.5rem);
    }
    .db-detail-drawer.is-modal .db-drawer-head {
        padding: 0.75rem 0.9rem 0.65rem;
    }
    .db-detail-drawer.is-modal .db-drawer-form {
        padding: 0.6rem 0.85rem 0.85rem;
    }
}

/* --- Reduced motion: kill everything decorative ----------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

/* ==========================================================================
   Admin Panel redesign (tabbed layout)
   Source: cwdb-design-system/project/Admin Panel.html (handoff bundle)
   Scoped under .admin-* classes — does not affect other pages.
   ========================================================================== */

.admin-hero {
    position: relative;
    overflow: hidden;
    border-color: rgba(140, 125, 255, 0.25);
}
.admin-hero::after {
    content: "";
    position: absolute;
    top: -60px;
    right: -40px;
    width: 180px;
    height: 180px;
    border-radius: 999px;
    background: radial-gradient(circle, rgba(102, 214, 255, 0.22), rgba(102, 214, 255, 0));
    pointer-events: none;
}

/* Tabs */
.admin-tabs {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    padding: 0.35rem;
    margin: 0.85rem 0 0.75rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(18, 28, 43, 0.92), rgba(11, 17, 27, 0.92));
}
.admin-tab {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    padding: 0.42rem 0.75rem;
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 8px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: all 0.18s ease;
}
.admin-tab:hover {
    border-color: rgba(148, 196, 255, 0.28);
    color: var(--text);
}
.admin-tab.is-active {
    border-color: rgba(220, 244, 255, 0.38);
    background: linear-gradient(120deg, var(--accent), var(--accent-2));
    color: #08111d;
    font-weight: 700;
    box-shadow: 0 8px 18px rgba(65, 139, 235, 0.32),
                inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.admin-tabpanel { display: none; }
.admin-tabpanel.is-active { display: block; }

/* Inputs scoped to admin tabpanels (excludes checkboxes intentionally) */
.admin-tabpanel input[type="text"],
.admin-tabpanel input[type="search"],
.admin-tabpanel input[type="password"],
.admin-tabpanel input[type="number"],
.admin-tabpanel input[type="email"],
.admin-tabpanel input[type="date"],
.admin-tabpanel select {
    width: 100%;
    padding: 0.52rem 0.68rem;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: rgba(9, 14, 22, 0.7);
    color: var(--text);
    font: inherit;
    font-size: 0.86rem;
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.admin-tabpanel input:focus,
.admin-tabpanel select:focus {
    border-color: rgba(102, 214, 255, 0.5);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.08);
}

/* ── Users + Roles tab ─────────────────────────────────────── */
.admin-users-grid {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 0.85rem;
    padding: 1rem;
}
@media (max-width: 900px) { .admin-users-grid { grid-template-columns: 1fr; } }

.admin-users-list,
.admin-user-actions {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    min-width: 0;
}

.admin-user-cards {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.admin-user-card {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 0.8rem;
    border-radius: 10px;
    border: 1px solid rgba(148, 196, 255, 0.14);
    background: rgba(14, 21, 33, 0.5);
    text-decoration: none;
    color: var(--text);
    transition: all 0.15s ease;
}
.admin-user-card:hover {
    border-color: rgba(148, 196, 255, 0.28);
    background: rgba(20, 30, 46, 0.65);
    text-decoration: none;
}
.admin-user-card.is-selected {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(14, 88, 120, 0.25);
}

.admin-avatar {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.25);
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.25), rgba(140, 125, 255, 0.25));
    color: #aeeeff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
}
.admin-avatar-lg {
    width: 44px;
    height: 44px;
    font-size: 1rem;
    border-color: rgba(102, 214, 255, 0.4);
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.3), rgba(140, 125, 255, 0.3));
}

.admin-user-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.12rem;
}
.admin-user-name {
    font-weight: 700;
    font-size: 0.88rem;
    color: var(--text);
}
.admin-user-sub {
    font-size: 0.74rem;
    color: var(--muted);
}
.admin-user-badges {
    display: flex;
    gap: 0.4rem;
    flex-shrink: 0;
    align-items: center;
}

.admin-badge {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 0.12rem 0.45rem;
    border: 1px solid rgba(148, 196, 255, 0.2);
    background: rgba(28, 43, 64, 0.4);
    color: var(--muted);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.admin-badge-violet {
    border-color: rgba(140, 125, 255, 0.45);
    background: rgba(54, 43, 94, 0.35);
    color: #d9cbff;
}
.admin-badge-green {
    border-color: rgba(34, 197, 94, 0.4);
    background: rgba(22, 122, 60, 0.2);
    color: #b8ffcc;
}

/* Selected user card */
.admin-selected-user {
    border-color: rgba(102, 214, 255, 0.28);
}
.admin-selected-header {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 0.85rem;
}
.admin-selected-header h3 {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
}
.admin-selected-header .muted-line {
    font-size: 0.76rem;
    margin: 0;
}
.admin-selected-actions {
    border-top: 1px solid rgba(148, 196, 255, 0.1);
    padding: 0.75rem 0.85rem;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.admin-action-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.admin-action-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* Section heading inside panels */
.admin-section-head {
    padding: 0.85rem 1rem 0.6rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.1);
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.admin-section-head h3 {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text);
}
.admin-count-pill {
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.28);
    background: rgba(20, 32, 48, 0.6);
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.12rem 0.45rem;
}
.admin-section-body {
    padding: 0.85rem 1rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* Field label/value */
.admin-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.admin-field-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--muted);
}
.admin-field-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.84rem;
    color: var(--muted);
}
.admin-field-checkbox input[type="checkbox"] {
    width: auto;
    margin: 0;
}

.admin-create-user-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.6rem;
}
.admin-create-user-grid > .admin-field-full { grid-column: 1 / -1; }
@media (max-width: 600px) {
    .admin-create-user-grid { grid-template-columns: 1fr; }
}

.admin-empty {
    padding: 1.5rem;
    text-align: center;
    color: var(--muted);
    font-size: 0.86rem;
}

/* Toggle switch (renders as the form's submit button) */
.admin-switch {
    width: 36px;
    height: 20px;
    padding: 0;
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.25);
    background: rgba(18, 28, 43, 0.7);
    position: relative;
    cursor: pointer;
    flex-shrink: 0;
    transition: all 0.2s ease;
}
.admin-switch::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 999px;
    background: var(--muted);
    transition: left 0.2s ease, background 0.2s ease;
}
.admin-switch.is-on {
    border-color: rgba(102, 214, 255, 0.55);
    background: linear-gradient(90deg, rgba(27, 124, 150, 0.9), rgba(102, 214, 255, 0.7));
}
.admin-switch.is-on::after {
    left: 17px;
    background: var(--text);
}

/* ── Component Access tab ──────────────────────────────────── */
.admin-access-grid {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 0.85rem;
    padding: 1rem;
}
@media (max-width: 800px) { .admin-access-grid { grid-template-columns: 1fr; } }

.admin-access-userpicker {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.admin-pick-user {
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    border: 1px solid rgba(148, 196, 255, 0.14);
    background: rgba(14, 21, 33, 0.5);
    text-decoration: none;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}
.admin-pick-user:hover {
    border-color: rgba(148, 196, 255, 0.28);
    background: rgba(20, 30, 46, 0.65);
    text-decoration: none;
}
.admin-pick-user.is-selected {
    border-color: rgba(102, 214, 255, 0.45);
    background: rgba(14, 88, 120, 0.25);
}
.admin-pick-user strong { font-weight: 700; font-size: 0.86rem; }
.admin-pick-user .muted-line { font-size: 0.72rem; margin: 0; }

.admin-component-rows {
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
}
.admin-component-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.08);
}
.admin-component-row:last-child { border-bottom: none; }
.admin-component-row.is-on { background: rgba(102, 214, 255, 0.03); }

.admin-component-info { flex: 1; min-width: 0; }
.admin-component-label {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--muted);
}
.admin-component-row.is-on .admin-component-label { color: var(--text); }
.admin-component-route {
    font-size: 0.72rem;
    color: var(--muted);
    font-family: var(--font-mono, "Consolas", monospace);
}

.admin-component-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-shrink: 0;
}
.admin-component-state {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--muted);
    letter-spacing: 0.04em;
}
.admin-component-row.is-on .admin-component-state { color: var(--accent); }

.admin-sort-form {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}
.admin-sort-form input[type="number"] {
    width: 70px;
}

/* Write-permission toggle, sits between the access switch and sort form. */
.admin-write-form { display: inline-flex; align-items: center; }
.admin-write-toggle {
    border: 1px solid var(--border);
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.02);
    color: var(--muted);
    padding: 0.3rem 0.65rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
    white-space: nowrap;
}
.admin-write-toggle:hover:not(:disabled) {
    border-color: var(--accent);
    color: var(--text);
    background: rgba(102, 214, 255, 0.06);
}
.admin-write-toggle.is-on {
    background: rgba(102, 214, 255, 0.18);
    border-color: rgba(102, 214, 255, 0.55);
    color: var(--accent);
}
.admin-write-toggle.is-on:hover:not(:disabled) {
    background: rgba(102, 214, 255, 0.28);
}
.admin-write-toggle.is-disabled,
.admin-write-toggle:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* ── Availability tab ──────────────────────────────────────── */
.admin-availability-wrap {
    padding: 1rem;
    max-width: 560px;
}
.admin-availability-help {
    font-size: 0.86rem;
    color: var(--muted);
    margin: 0 0 1rem;
    line-height: 1.5;
}
.admin-availability-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.65rem;
    margin: 0.75rem 0;
}
@media (max-width: 540px) {
    .admin-availability-grid { grid-template-columns: 1fr; }
}

.admin-period-card {
    padding: 0.85rem;
    border-radius: 14px;
    border: 1px solid var(--admin-period-border, var(--border));
    background: linear-gradient(160deg, rgba(20, 31, 47, 0.84), rgba(13, 20, 31, 0.84));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04),
                0 14px 30px rgba(var(--shadow-rgb), 0.32);
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    cursor: text;
}
.admin-period-card[data-period="morning"]   { --admin-period-color: rgba(255, 200, 102, 1); --admin-period-border: rgba(255, 200, 102, 0.45); }
.admin-period-card[data-period="afternoon"] { --admin-period-color: rgba(102, 214, 255, 1); --admin-period-border: rgba(102, 214, 255, 0.45); }
.admin-period-card[data-period="evening"]   { --admin-period-color: rgba(167, 139, 250, 1); --admin-period-border: rgba(167, 139, 250, 0.45); }

.admin-period-label {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--admin-period-color);
}
.admin-period-card input[type="number"] {
    font-size: 1.4rem;
    font-weight: 800;
    text-align: center;
    color: var(--admin-period-color);
    background: transparent;
    border: 1px solid var(--admin-period-border);
    padding: 0.4rem;
}
.admin-period-card input[type="number"]:focus {
    box-shadow: 0 0 0 3px var(--admin-period-border);
}
.admin-period-unit {
    font-size: 0.68rem;
    color: var(--muted);
    text-align: center;
    letter-spacing: 0.02em;
}

/* ── Webhook ops tab ───────────────────────────────────────── */
.admin-webhooks-wrap {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.admin-stat-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.65rem;
}
@media (max-width: 700px) { .admin-stat-grid { grid-template-columns: repeat(2, 1fr); } }

.admin-stat-card {
    padding: 0.75rem;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: linear-gradient(160deg, rgba(20, 31, 47, 0.84), rgba(13, 20, 31, 0.84));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04),
                0 14px 30px rgba(var(--shadow-rgb), 0.32);
}
.admin-stat-value {
    font-size: 1.6rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--text);
    line-height: 1.1;
}
.admin-stat-card[data-stat="pending"]    .admin-stat-value { color: rgba(255, 200, 102, 1); }
.admin-stat-card[data-stat="processing"] .admin-stat-value { color: var(--muted); }
.admin-stat-card[data-stat="processed"]  .admin-stat-value { color: rgba(34, 197, 94, 1); }
.admin-stat-card[data-stat="failed"]     .admin-stat-value { color: rgba(239, 68, 68, 1); }

.admin-stat-label {
    font-size: 0.74rem;
    color: var(--muted);
    margin-top: 2px;
    letter-spacing: 0.04em;
}

.admin-status-badge {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 0.15rem 0.5rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.admin-status-badge[data-status="processed"]  { background: rgba(34, 197, 94, 0.15);  border: 1px solid rgba(34, 197, 94, 0.4);   color: #b8ffcc; }
.admin-status-badge[data-status="failed"]     { background: rgba(239, 68, 68, 0.15);   border: 1px solid rgba(239, 68, 68, 0.4);    color: var(--danger-bg); }
.admin-status-badge[data-status="pending"]    { background: rgba(255, 200, 102, 0.15); border: 1px solid rgba(255, 200, 102, 0.4);  color: #ffe8aa; }
.admin-status-badge[data-status="processing"] { background: rgba(148, 196, 255, 0.1);  border: 1px solid rgba(148, 196, 255, 0.3);  color: var(--muted); }

/* ── Diagnostics tab ───────────────────────────────────────── */
.admin-diag-wrap {
    padding: 1rem;
    max-width: 480px;
}
.admin-diag-rows {
    list-style: none;
    margin: 0;
    padding: 0.35rem 0;
}
.admin-diag-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.08);
}
.admin-diag-row:last-child { border-bottom: none; }
.admin-diag-label {
    font-size: 0.86rem;
    color: var(--muted);
}
.admin-diag-value {
    font-size: 1rem;
    font-weight: 800;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

/* ── Workspace settings + Data tools ───────────────────────── */
.admin-settings-wrap {
    padding: 1rem;
    max-width: 480px;
}
.admin-data-tools-wrap {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.admin-data-tools-form {
    display: flex;
    gap: 0.5rem;
    align-items: flex-end;
    flex-wrap: wrap;
}
.admin-data-tools-form .admin-field { min-width: 180px; flex: 1 1 220px; }
.admin-data-tools-form .admin-data-tools-submit { flex: 0 0 auto; }

/* End admin redesign block ============================================== */

/* ==========================================================================
   Messages (texting) page — Variation A from
   cwdb-design-system/project/Texting UI.html
   Scoped under .msg-* / .is-messages-page so it can't leak elsewhere.
   ========================================================================== */

body.is-messages-page:has(.layout-main.is-messages) {
    /* Lock the messages page to the viewport so the flex chain below
       (.layout-main → .msg-page → .msg-shell) actually has a fixed parent
       height to fill. Without `display:flex; height:100vh`, body collapses
       to content height and the page renders 3/4 up the viewport.
       Scoped via :has(.is-messages) so only the SMS inbox itself gets
       the viewport lock — the automations / queue / activity / templates
       sub-pages (which share is-messages-page for nav styling) keep their
       natural block flow and scroll normally. */
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh; /* dvh: keep the SMS composer above the iOS URL bar */
    overflow: hidden;
}
body.is-messages-page .layout-main.is-messages {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
}

.msg-page {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--text);
    overflow: hidden;
}

.msg-shell {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    background: var(--bg);
    overflow: hidden;
}

/* ── Sidebar (conversation list) ──────────────────────────────── */
.msg-sidebar {
    flex-shrink: 0;
    width: 300px;
    display: flex;
    flex-direction: column;
    border-right: 1px solid rgba(148, 196, 255, 0.14);
    background: rgba(9, 14, 22, 0.95);
    min-height: 0;
}

.msg-side-head {
    padding: 0.7rem 0.85rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.12);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.msg-title-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.msg-title {
    font-size: 0.92rem;
    font-weight: 800;
    color: var(--text);
}
.msg-count {
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.4);
    background: rgba(14, 88, 120, 0.3);
    color: var(--accent);
    font-size: 0.68rem;
    font-weight: 800;
    padding: 0.1rem 0.45rem;
}

.msg-search {
    width: 100%;
    border-radius: 8px;
    border: 1px solid rgba(148, 196, 255, 0.2);
    background: rgba(14, 21, 33, 0.8);
    color: var(--text);
    padding: 0.42rem 0.65rem;
    font: inherit;
    font-size: 0.82rem;
    outline: none;
    transition: border-color 0.15s ease;
}
.msg-search:focus {
    border-color: rgba(102, 214, 255, 0.5);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.08);
}

.msg-convo-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin;
}
.msg-convo-list::-webkit-scrollbar {
    width: 8px;
}
.msg-convo-list::-webkit-scrollbar-thumb {
    background: rgba(148, 196, 255, 0.18);
    border-radius: 999px;
}

.msg-convo {
    display: flex;
    width: 100%;
    gap: 0.7rem;
    padding: 0.7rem 0.85rem 0.75rem;
    border: 0;
    border-left: 2px solid transparent;
    border-bottom: 1px solid rgba(148, 196, 255, 0.07);
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.14s ease, border-color 0.14s ease;
    position: relative;
}
.msg-convo:hover {
    background: rgba(148, 196, 255, 0.04);
}
.msg-convo.is-active {
    background: linear-gradient(90deg, rgba(14, 88, 120, 0.32), rgba(14, 88, 120, 0.08));
    border-left-color: var(--accent);
}

.msg-avatar {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 999px;
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.22), rgba(140, 125, 255, 0.22));
    border: 1px solid rgba(148, 196, 255, 0.28);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #aeeeff;
    position: relative;
    font-weight: 800;
    font-size: 0.92rem;
    line-height: 1;
}
.msg-avatar-md {
    width: 36px;
    height: 36px;
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.2), rgba(140, 125, 255, 0.2));
    border-color: rgba(148, 196, 255, 0.25);
    font-size: 0.9rem;
}
.msg-avatar-letter {
    pointer-events: none;
}
.msg-unread-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 14px;
    height: 14px;
    border-radius: 999px;
    background: var(--accent);
    border: 2px solid #0a131e;
    box-shadow: 0 0 8px rgba(102, 214, 255, 0.7);
    color: #07111d;
    font-size: 0.55rem;
    font-weight: 800;
    padding: 0 3px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.msg-convo-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}
.msg-convo-row1 {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}
.msg-convo-name {
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    letter-spacing: -0.005em;
}
.msg-convo.has-unread .msg-convo-name {
    font-weight: 800;
}
.msg-convo-time {
    flex-shrink: 0;
    font-size: 0.68rem;
    color: #7d92ad;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}
.msg-convo.has-unread .msg-convo-time {
    color: var(--accent);
    font-weight: 700;
}

.msg-convo-row2 {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
}
.msg-convo-phone {
    flex-shrink: 0;
    font-size: 0.72rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.msg-product-chip {
    display: inline-flex;
    align-items: center;
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--msg-product-color, rgba(148, 196, 255, 0.95));
    background: var(--msg-product-bg, rgba(148, 196, 255, 0.1));
    border: 1px solid var(--msg-product-border, rgba(148, 196, 255, 0.28));
    line-height: 1.4;
}
.msg-product-chip[data-product="windows"] {
    --msg-product-color:  rgba(102, 214, 255, 0.95);
    --msg-product-bg:     rgba(102, 214, 255, 0.1);
    --msg-product-border: rgba(102, 214, 255, 0.28);
}
.msg-product-chip[data-product="siding"] {
    --msg-product-color:  rgba(255, 200, 102, 0.95);
    --msg-product-bg:     rgba(255, 200, 102, 0.1);
    --msg-product-border: rgba(255, 200, 102, 0.28);
}
.msg-product-chip[data-product="roofing"] {
    --msg-product-color:  rgba(167, 139, 250, 0.95);
    --msg-product-bg:     rgba(167, 139, 250, 0.1);
    --msg-product-border: rgba(167, 139, 250, 0.28);
}

.msg-convo-row3 {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.7rem;
    color: #7d92ad;
    overflow: hidden;
}
.msg-pin {
    flex-shrink: 0;
    opacity: 0.7;
}
.msg-convo-address {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.msg-convo-last {
    margin-top: 0.12rem;
    font-size: 0.76rem;
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.msg-convo.has-unread .msg-convo-last {
    color: #dce8f5;
    font-weight: 600;
}

.msg-side-foot {
    padding: 0.55rem 0.85rem;
    border-top: 1px solid rgba(148, 196, 255, 0.12);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
}
.msg-from-line {
    font-size: 0.72rem;
    color: var(--muted);
}
.msg-new-btn {
    border-radius: 7px;
    border: 1px solid rgba(102, 214, 255, 0.45);
    background: linear-gradient(180deg, rgba(27, 124, 150, 0.85), rgba(15, 84, 121, 0.94));
    color: var(--text);
    padding: 0.28rem 0.55rem;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    cursor: pointer;
    transition: opacity 0.15s ease;
}
.msg-new-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* ── Thread pane (middle column) ──────────────────────────────── */
.msg-thread {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    position: relative;
}

.msg-thread-pane {
    flex: 1 1 auto;
    min-height: 0;
    display: none;
    flex-direction: column;
}
.msg-thread-pane.is-active {
    display: flex;
}

.msg-thread-head {
    padding: 0.65rem 0.9rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.12);
    background: rgba(9, 14, 22, 0.95);
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-shrink: 0;
}
.msg-thread-meta {
    flex: 1;
    min-width: 0;
}
.msg-thread-name {
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.msg-thread-phone {
    font-size: 0.72rem;
    color: var(--muted);
}

.msg-context-toggle {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 7px;
    border: 1px solid rgba(148, 196, 255, 0.2);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    font: inherit;
    font-size: 0.78rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s ease;
}
.msg-context-toggle.is-on {
    border-color: rgba(102, 214, 255, 0.4);
    background: rgba(14, 88, 120, 0.25);
    color: var(--accent);
}
.msg-context-toggle-arrow {
    line-height: 1;
    transition: transform 0.18s ease;
}
.msg-context-toggle:not(.is-on) .msg-context-toggle-arrow {
    transform: rotate(180deg);
}

/* Bubbles */
.msg-bubbles {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0.85rem;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
    scrollbar-width: thin;
}
.msg-bubbles::-webkit-scrollbar {
    width: 8px;
}
.msg-bubbles::-webkit-scrollbar-thumb {
    background: rgba(148, 196, 255, 0.18);
    border-radius: 999px;
}

.msg-bubble-row {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-bottom: 0.15rem;
}
.msg-bubble-row.msg-bubble-in {
    align-items: flex-start;
}
.msg-bubble-row.msg-bubble-out {
    align-items: flex-end;
}

.msg-bubble-body {
    max-width: 72%;
    padding: 0.55rem 0.8rem;
    color: var(--text);
    font-size: 0.86rem;
    line-height: 1.45;
    word-break: break-word;
}
.msg-bubble-in .msg-bubble-body {
    background: rgba(22, 34, 52, 0.88);
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 14px 14px 14px 4px;
}
.msg-bubble-out .msg-bubble-body {
    background: linear-gradient(135deg, rgba(27, 124, 150, 0.9), rgba(46, 52, 137, 0.85));
    border: 1px solid rgba(102, 214, 255, 0.35);
    border-radius: 14px 14px 4px 14px;
}

.msg-bubble-time {
    font-size: 0.65rem;
    color: var(--muted);
    padding: 0 4px;
}

/* Composer */
.msg-composer {
    border-top: 1px solid rgba(148, 196, 255, 0.14);
    padding: 0.65rem;
    background: rgba(7, 11, 18, 0.9);
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex-shrink: 0;
}

.msg-templates {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.4rem;
    background: rgba(14, 21, 33, 0.95);
    border-radius: 10px;
    border: 1px solid rgba(148, 196, 255, 0.2);
}
.msg-templates[hidden] {
    display: none;
}
.msg-template-item {
    padding: 0.4rem 0.55rem;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #b0c8e0;
    font: inherit;
    font-size: 0.78rem;
    line-height: 1.35;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s ease;
}
.msg-template-item:hover {
    background: rgba(102, 214, 255, 0.08);
    color: var(--text);
}

.msg-composer-row {
    display: flex;
    gap: 0.45rem;
    align-items: flex-end;
}
.msg-templates-toggle {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid rgba(148, 196, 255, 0.22);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    font-size: 0.9rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s ease;
}
.msg-templates-toggle.is-on {
    background: rgba(102, 214, 255, 0.15);
    color: var(--accent);
    border-color: rgba(102, 214, 255, 0.4);
}
.msg-input {
    flex: 1;
    border-radius: 10px;
    border: 1px solid rgba(148, 196, 255, 0.22);
    background: rgba(14, 21, 33, 0.8);
    color: var(--text);
    padding: 0.5rem 0.65rem;
    font: inherit;
    font-size: 0.86rem;
    line-height: 1.4;
    resize: none;
    outline: none;
    min-height: 36px;
    max-height: 120px;
    overflow-y: auto;
    transition: border-color 0.15s ease;
}
.msg-input:focus {
    border-color: rgba(102, 214, 255, 0.45);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.08);
}
.msg-send {
    flex-shrink: 0;
    height: 36px;
    padding: 0 0.85rem;
    border-radius: 10px;
    border: 1px solid rgba(102, 214, 255, 0.5);
    background: linear-gradient(180deg, rgba(27, 124, 150, 0.9), rgba(15, 84, 121, 0.96));
    color: var(--text);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.15s ease;
}
.msg-send:disabled {
    background: rgba(18, 28, 43, 0.5);
    border-color: rgba(148, 196, 255, 0.2);
    color: var(--muted);
    cursor: default;
}

/* ── Right context panel ──────────────────────────────────────── */
.msg-context {
    flex-shrink: 0;
    width: 220px;
    overflow: hidden;
    border-left: 1px solid rgba(148, 196, 255, 0.12);
    background: rgba(9, 14, 22, 0.9);
    transition: width 0.22s cubic-bezier(0.22, 1, 0.36, 1);
    min-height: 0;
}
.msg-shell.is-context-collapsed .msg-context {
    width: 0;
    border-left: 0;
}

.msg-context-pane {
    width: 220px;
    height: 100%;
    overflow-y: auto;
    padding: 0.85rem;
    display: none;
    flex-direction: column;
    gap: 0.65rem;
}
.msg-context-pane.is-active {
    display: flex;
}

.msg-context-block {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}
.msg-context-divided {
    border-top: 1px solid rgba(148, 196, 255, 0.1);
    padding-top: 0.65rem;
}

.msg-context-label {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 700;
    color: var(--muted);
    margin-bottom: 0.15rem;
}
.msg-context-value-strong {
    font-weight: 700;
    font-size: 0.86rem;
    color: var(--text);
}
.msg-context-value {
    font-size: 0.82rem;
    color: var(--text);
}
.msg-context-sub {
    font-size: 0.74rem;
    color: #b0c8e0;
    line-height: 1.35;
    margin-top: 4px;
}
.msg-context-phone {
    color: var(--muted);
}

.msg-action-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.5rem;
    border-radius: 8px;
    border: 1px solid rgba(102, 214, 255, 0.3);
    background: rgba(14, 88, 120, 0.18);
    color: var(--accent);
    font-size: 0.76rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.msg-action-link:hover {
    background: rgba(14, 88, 120, 0.32);
    border-color: rgba(102, 214, 255, 0.5);
    text-decoration: none;
}
.msg-action-arrow {
    font-size: 0.7rem;
    opacity: 0.75;
}

/* Empty states */
.msg-empty {
    color: var(--muted);
    font-size: 0.86rem;
    text-align: center;
    padding: 1.5rem 1rem;
}
.msg-empty-thread {
    margin: auto;
}

/* Stub banner (legacy fallback for when the SMS backend is not connected) */
.msg-stub-banner {
    flex-shrink: 0;
    text-align: center;
    padding: 0.35rem 0.75rem;
    background: rgba(255, 200, 102, 0.1);
    border-top: 1px solid rgba(255, 200, 102, 0.3);
    color: rgba(255, 200, 102, 0.95);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

/* Inline send-error banner inside the composer when /messages/send fails. */
.msg-send-error {
    margin: 0 0 0.5rem;
    padding: 0.45rem 0.75rem;
    background: rgba(220, 53, 69, 0.12);
    border: 1px solid rgba(220, 53, 69, 0.4);
    border-radius: 6px;
    color: rgba(255, 138, 138, 0.95);
    font-size: 0.78rem;
    font-weight: 500;
}
.msg-send-error[hidden] { display: none; }

/* Responsive: collapse context panel and shrink sidebar on narrow viewports */
@media (max-width: 900px) {
    .msg-context {
        width: 0;
        border-left: 0;
    }
    .msg-shell.is-context-collapsed .msg-context {
        width: 0;
    }
    .msg-context-toggle {
        display: none;
    }
}
@media (max-width: 600px) {
    .msg-sidebar {
        width: 240px;
    }
}

/* Mobile (≤720px): swap the side-by-side two-pane layout for a single-
   pane phone UX. Tapping a conversation flips to the thread view; a
   "‹ Back" button in the thread head returns to the list. Standard
   iOS/Android messaging app pattern. */
.msg-back-btn {
    display: none;
}
@media (max-width: 720px) {
    .msg-page[data-msg-view="list"] .msg-thread,
    .msg-page[data-msg-view="list"] .msg-context {
        display: none !important;
    }
    .msg-page[data-msg-view="thread"] .msg-sidebar {
        display: none !important;
    }
    /* Whichever pane is active claims the full viewport width. */
    .msg-sidebar,
    .msg-thread {
        width: 100% !important;
        min-width: 0;
        max-width: 100%;
        border-right: 0;
        border-left: 0;
    }
    .msg-shell {
        flex-direction: column;
    }
    /* Show the Back button. Sized as a 44x44 tap target so operators
       can hit it without aiming carefully. */
    .msg-back-btn {
        display: inline-flex;
        align-items: center;
        gap: 0.2rem;
        min-height: 36px;
        padding: 0.4rem 0.6rem 0.4rem 0.4rem;
        margin-right: 0.4rem;
        background: transparent;
        border: 1px solid rgba(148, 196, 255, 0.18);
        border-radius: 8px;
        color: var(--text);
        font-size: 0.88rem;
        font-weight: 600;
        cursor: pointer;
        flex-shrink: 0;
    }
    .msg-back-btn:hover {
        background: rgba(28, 42, 60, 0.6);
        border-color: rgba(102, 214, 255, 0.45);
    }
    .msg-back-btn > span {
        font-size: 1.2rem;
        line-height: 1;
    }
    /* Hide the right-side context (job details) panel on mobile —
       there's no room and it duplicates info already in the thread. */
    .msg-context,
    .msg-context-toggle {
        display: none !important;
    }
}

/* End messages page block ============================================== */

/* Confirmer presence bar ================================================
 * Compact "On now" strip at the top of /confirmation. Pills are users
 * with write access to the confirmation component; the green dot
 * pulses while is_confirmer_active=1.
 *
 * Compact variant (the only one shipped — chosen 2026-05-14): tighter
 * padding, first-name labels, smaller dots so the bar takes minimal
 * vertical space above the inbox.
 */
.confirmer-bar {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 14px 18px;
    margin: 0 0 12px;
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.confirmer-bar.is-compact {
    padding: 8px 14px;
    gap: 10px;
}

/* Inline variant: dropped into .confirm-hero alongside the clock + scope
 * chips. Strips the panel chrome (background/border/radius) so the bar
 * reads as part of the hero strip rather than a stacked card. */
.confirmer-bar.is-inline-hero {
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
    margin: 0;
    align-self: center;
    flex: 0 1 auto;
    min-width: 0;
}
.confirmer-bar.is-inline-hero .confirmer-bar-label {
    margin-right: 2px;
}
.confirmer-bar.is-inline-hero .confirmer-bar-counts {
    padding-left: 8px;
    border-left: 1px solid var(--border);
}

.confirmer-bar-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    font-weight: 600;
}

.confirmer-pills {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    flex: 1;
    min-width: 0;
}

.confirmer-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 4px 11px 4px 8px;
    cursor: pointer;
    user-select: none;
    transition: background 120ms ease, border-color 120ms ease, opacity 120ms ease;
    font-size: 12px;
    color: var(--text);
    font-family: inherit;
    line-height: 1;
}

.confirmer-pill:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: rgba(148, 196, 255, 0.4);
}

.confirmer-pill:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.confirmer-pill.is-inactive {
    opacity: 0.5;
}
.confirmer-pill.is-inactive .confirmer-name {
    color: var(--muted);
}

/* Read-only pills (everyone except the logged-in user). Use the
 * default cursor instead of pointer so it's obvious you can't click. */
.confirmer-pill.is-readonly,
.confirmer-pill:disabled {
    cursor: default;
}

/* The current user's pill gets an accent-tinted border + a small "you"
 * chip so they immediately spot themselves. */
.confirmer-pill.is-self {
    border-color: rgba(102, 214, 255, 0.55);
}
.confirmer-pill.is-self::before {
    content: "you";
    font-size: 9px;
    letter-spacing: 0.1em;
    color: var(--accent);
    background: rgba(102, 214, 255, 0.14);
    padding: 2px 6px;
    border-radius: 999px;
    margin-right: 1px;
    text-transform: uppercase;
    line-height: 1;
}

.confirmer-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #4b5a73;
    flex-shrink: 0;
    transition: box-shadow 200ms ease, background 200ms ease;
}
.confirmer-pill:not(.is-inactive) .confirmer-dot {
    background: #4ade80;
    box-shadow: 0 0 0 1px rgba(74, 222, 128, 0.4), 0 0 10px rgba(74, 222, 128, 0.45);
    animation: confirmerPulse 2.4s ease-in-out infinite;
}
@keyframes confirmerPulse {
    0%, 100% { box-shadow: 0 0 0 1px rgba(74,222,128,0.4), 0 0 7px rgba(74,222,128,0.45); }
    50%      { box-shadow: 0 0 0 1px rgba(74,222,128,0.6), 0 0 14px rgba(74,222,128,0.45); }
}

.confirmer-name {
    font-weight: 500;
}

.confirmer-bar-counts {
    color: var(--muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    padding-left: 10px;
    border-left: 1px solid var(--border);
    margin-left: auto;
    white-space: nowrap;
}
.confirmer-bar-counts strong {
    color: var(--text);
    font-weight: 600;
}
/* End confirmer presence bar ============================================ */

/* Top nav v2 — single-row modern layout =================================
 *
 * Replaces the two-row brand/links stack with a single compact strip:
 *   [ brand mark + workspace ] [ icon+label links ………… ] [ avatar + signout ]
 *
 * Coexists with the v1 .top-nav-inner block via the `.top-nav-v2` parent
 * class — both can exist on the page, but only the v2 inner renders in
 * the current template. v1 rules above are kept so legacy partials don't
 * suddenly look broken if someone reverts the template.
 */

.top-nav.top-nav-v2 {
    /* Same sticky-blurry chrome as v1 — just a different inner layout. */
    border-bottom: 1px solid var(--border);
    background: linear-gradient(180deg, rgba(15,22,34,0.92), rgba(9,14,22,0.85));
}

.top-nav-inner-v2 {
    max-width: 1568px;
    margin: 0 auto;
    padding: 0.5rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    min-width: 0;
}

/* Brand cluster (left) ---------------------------------------------------- */
.brand-block-v2 {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding-right: 0.85rem;
    border-right: 1px solid var(--border);
    flex-shrink: 0;
}
.brand-mark {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    color: #0a1320;
    box-shadow: 0 4px 14px rgba(102, 214, 255, 0.18);
    flex-shrink: 0;
}
.brand-info { line-height: 1.15; min-width: 0; }
.brand-info .brand-title {
    font-size: 0.88rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 240px;
}
.brand-info .brand-subtle {
    font-size: 0.65rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    line-height: 1.2;
    margin-top: 1px;
}

/* Grouped nav (2026-06 redesign) ----------------------------------------- *
 * brand · Home chip · group dropdown chips (Operations/Sales/Admin/More) ·
 * pencil edit-mode for per-user reorder. Replaces the flat pill row + the
 * "More" overflow measurer. Same dark/cyan tokens — structure-only rebuild.
 * Group membership is a PHP route→group map in top_nav.php; single-item
 * groups collapse to a plain chip. The container must NOT clip (dropdowns
 * escape it), so no overflow:hidden here (unlike the old flat link row). */
.top-nav-groups {
    display: flex;
    align-items: center;
    gap: var(--space-1, 0.25rem);
    flex: 1 1 auto;
    min-width: 0;
    min-height: 40px;
    overflow: visible;
}

/* A chip = the Home link, a single-item group link, OR a group toggle. */
.top-nav-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    border-radius: 999px;
    color: var(--muted);
    text-decoration: none;
    font-family: inherit;
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    background: transparent;
    border: 1px solid transparent;
    cursor: pointer;
    min-width: 0; /* allow the chip to shrink so its label can ellipsis under
                     pressure (narrow desktop) instead of overflowing the row */
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
/* Chip label truncates under width pressure rather than forcing the row to
   overflow under the right cluster. At wide widths there's room — no clip. */
.top-nav-chip-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.top-nav-chip:hover {
    background: rgba(148, 196, 255, 0.08);
    color: var(--text);
    text-decoration: none;
}
.top-nav-chip.is-active {
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.20), rgba(140, 125, 255, 0.16));
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.40);
    font-weight: var(--weight-semibold, 600);
    box-shadow: 0 0 22px rgba(102, 214, 255, 0.12), inset 0 -2px 0 var(--accent);
}
.top-nav-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.top-nav-link-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--muted);
    transition: color 120ms ease;
}
.top-nav-chip:hover .top-nav-link-icon,
.top-nav-chip.is-active .top-nav-link-icon { color: var(--accent); }

.top-nav-group-caret {
    width: 13px; height: 13px;
    flex-shrink: 0;
    opacity: 0.8;
    transition: transform 150ms ease;
}
.top-nav-group-toggle[aria-expanded="true"] .top-nav-group-caret { transform: rotate(180deg); }

/* Group wrapper anchors the absolutely-positioned dropdown. min-width:0 lets
   the wrapper (the flex child of .top-nav-groups) shrink so its toggle chip's
   label can ellipsis under width pressure instead of overflowing the row —
   without it, only the bare Home chip could shrink and the group chips spilled
   over the bell/avatar on a narrow desktop. */
.top-nav-group { position: relative; display: inline-flex; min-width: 0; }

.top-nav-group-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 224px;
    max-height: 72vh;
    overflow-y: auto;
    padding: 0.3rem;
    background: var(--surface, #11203a);
    border: 1px solid var(--border, #2b3a55);
    border-radius: var(--radius-card, 12px);
    box-shadow: var(--shadow-md, 0 14px 30px rgba(var(--shadow-rgb), 0.35));
    max-width: calc(100vw - 1.5rem); /* never exceed the viewport at small widths */
    z-index: 9998;
}
.top-nav-group-menu[hidden] { display: none; }
.top-nav-group-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.top-nav-group-item-row { display: flex; align-items: center; gap: 2px; border-radius: var(--radius-sm, 8px); }
.top-nav-group-item-row.is-dragging { opacity: 0.6; background: rgba(148, 196, 255, 0.12); }

.top-nav-group-item {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-sm, 8px);
    color: var(--text);
    text-decoration: none;
    font-size: var(--text-sm, 0.8rem);
}
.top-nav-group-item .top-nav-link-icon { width: 16px; height: 16px; }
.top-nav-group-item:hover { background: rgba(148, 196, 255, 0.08); text-decoration: none; }
.top-nav-group-item.is-active { background: rgba(102, 214, 255, 0.12); }
.top-nav-group-item.is-active .top-nav-link-icon { color: var(--accent); }

/* Edit-mode head (Drag to reorder · Reset) — only shown while editing. */
.top-nav-group-menu-head {
    display: none;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem 0.45rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 0.25rem;
}
.top-nav-group-menu-hint { font-size: var(--text-micro, 0.7rem); color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
.top-nav-reset-btn {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--muted);
    border-radius: var(--radius-pill, 999px);
    padding: 3px 10px;
    font-family: inherit;
    font-size: var(--text-micro, 0.7rem);
    cursor: pointer;
}
.top-nav-reset-btn:hover { color: var(--text); border-color: rgba(102, 214, 255, 0.4); background: rgba(148, 196, 255, 0.10); }
[data-nav-editing="1"] .top-nav-group-menu-head { display: flex; }

/* Drag grip — hidden until edit mode; works for mouse-drag, touch-drag
   (touch-action:none stops the menu from scrolling under the finger) AND
   keyboard (focusable, ↑/↓ moves the row). */
.top-nav-grip {
    display: none;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 32px;
    color: var(--muted);
    cursor: grab;
    border-radius: 6px;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
}
.top-nav-grip svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.top-nav-grip:hover { color: var(--text); background: rgba(148, 196, 255, 0.10); }
.top-nav-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.top-nav-grip:active { cursor: grabbing; }
[data-nav-editing="1"] .top-nav-grip { display: inline-flex; }
[data-nav-editing="1"] .top-nav-group-item { cursor: default; }

/* Pencil / edit toggle — swaps to a check while editing; flashes the save. */
.top-nav-edit-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-left: 2px;
    border-radius: var(--radius-pill, 999px);
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
    cursor: pointer;
    flex-shrink: 0;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.top-nav-edit-toggle svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.top-nav-edit-toggle:hover { background: rgba(148, 196, 255, 0.10); color: var(--text); border-color: var(--border); }
.top-nav-edit-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.top-nav-edit-check { display: none; }
[data-nav-editing="1"] .top-nav-edit-toggle { background: rgba(102, 214, 255, 0.16); color: var(--accent); border-color: rgba(102, 214, 255, 0.4); }
[data-nav-editing="1"] .top-nav-edit-toggle .top-nav-edit-check { display: block; }
[data-nav-editing="1"] .top-nav-edit-toggle .top-nav-edit-pencil { display: none; }
.top-nav-edit-toggle.is-saved { color: var(--success, #57d9a3); border-color: rgba(87, 217, 163, 0.5); }
.top-nav-edit-toggle.is-error { color: var(--danger, #ff5d5d); border-color: rgba(255, 93, 93, 0.5); }

/* Compact desktop — driven by the JS overflow measurer in top_nav.php, which
   adds .is-cramped to .top-nav-inner-v2 whenever the grouped chip row would
   otherwise overflow the right cluster. This is measured, NOT a fixed
   breakpoint, because the fit threshold depends on the viewer's label widths +
   how many groups they're granted. When cramped, drop the redundant-on-desktop
   chrome so the meaningful group labels (Operations/Sales/Admin) stay
   un-truncated — no ugly "Oper…", no overlap, at any width or grant set:
     • the wordmark (the CW mark still links home),
     • the username (the avatar remains),
     • back/reload (a real browser window has its own; they exist for the
       fullscreen/standalone PWA where there's no browser chrome),
     • the collapse button (the `\` shortcut still toggles it),
     • the Home label (its house icon + `title` tooltip suffice). */
.top-nav-inner-v2.is-cramped .brand-info { display: none; }
.top-nav-inner-v2.is-cramped .user-name { display: none; }
.top-nav-inner-v2.is-cramped .nav-history { display: none; }
.top-nav-inner-v2.is-cramped .user-collapse-btn { display: none; }
.top-nav-inner-v2.is-cramped .top-nav-chip-home .top-nav-chip-label { display: none; }
.top-nav-inner-v2.is-cramped .top-nav-chip-home { padding-left: 10px; padding-right: 10px; }
.top-nav-inner-v2.is-cramped .top-nav-group-toggle { padding-left: 8px; padding-right: 8px; }

/* User cluster (right) --------------------------------------------------- */
.user-block-v2 {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding-left: 0.85rem;
    border-left: 1px solid var(--border);
    flex-shrink: 0;
}
.user-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.45), rgba(140, 125, 255, 0.45));
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 0.72rem;
    color: var(--text);
    border: 1px solid rgba(148, 196, 255, 0.32);
    flex-shrink: 0;
}
.user-name {
    font-size: 0.8rem;
    color: var(--muted);
    font-weight: 500;
    white-space: nowrap;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.user-signout {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--muted);
    border-radius: 999px;
    padding: 5px 12px;
    font-size: 0.72rem;
    cursor: pointer;
    font-family: inherit;
    line-height: 1;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.user-signout:hover {
    color: var(--danger);
    border-color: rgba(255, 123, 156, 0.45);
    background: rgba(255, 123, 156, 0.06);
}
.user-collapse-btn {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--muted);
    border-radius: 6px;
    width: 26px;
    height: 26px;
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
    display: grid;
    place-items: center;
}
.user-collapse-btn:hover {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.4);
    background: rgba(148, 196, 255, 0.10);
}

/* Collapsed (desktop) = slim minimized bar. The pills + names hide, but the
   brand, active section, search, bell, avatar + toggle STAY — collapsing
   reclaims the link row without losing search / notifications / identity (the
   old behaviour vanished the whole header into an ugly strip). Mobile (≤720px)
   still fully hides the inner and shows the drawer strip instead. */
html[data-topnav="collapsed"] .top-nav.top-nav-v2 .top-nav-inner-v2 {
    padding-top: 0.22rem;
    padding-bottom: 0.22rem;
}
html[data-topnav="collapsed"] .top-nav-groups,
html[data-topnav="collapsed"] .user-name,
html[data-topnav="collapsed"] .brand-info .brand-title {
    display: none !important;
}
/* one-line brand (section only) + smaller round controls keep the bar slim */
html[data-topnav="collapsed"] .brand-info .brand-subtle { font-size: 0.72rem; margin-top: 0; }
html[data-topnav="collapsed"] .nav-cmdk,
html[data-topnav="collapsed"] .nav-bell { width: 30px; height: 30px; }
html[data-topnav="collapsed"] .user-collapse-btn { width: 24px; height: 24px; }
html[data-topnav="collapsed"] .user-collapse-caret {
    transform: rotate(180deg);
}
/* Shrink the mark + avatar when collapsed so the bar is genuinely slim while
   still keeping identity, search, bell + the expand toggle. */
html[data-topnav="collapsed"] .brand-mark { width: 26px; height: 26px; font-size: 0.6rem; border-radius: 7px; }
html[data-topnav="collapsed"] .user-avatar { width: 26px; height: 26px; font-size: 0.65rem; }
.top-nav-inner-v2 { transition: padding 0.2s ease; }
.brand-mark, .user-avatar { transition: width 0.2s ease, height 0.2s ease; }
.user-collapse-caret { width: 16px; height: 16px; transition: transform 0.2s ease; }

/* Mobile hamburger — desktop hides it, mobile shows it as a 44px tap
   target. The inline pager + sign-out also collapse on mobile (see
   below); operators get the drawer instead. */
.top-nav-mobile-toggle {
    display: none;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 10px;
    width: 44px;
    height: 44px;
    cursor: pointer;
    color: var(--text);
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    transition: background 120ms ease, border-color 120ms ease;
    -webkit-tap-highlight-color: transparent;
}
.top-nav-mobile-toggle svg { width: 22px; height: 22px; }
.top-nav-mobile-toggle:hover,
.top-nav-mobile-toggle[aria-expanded="true"] {
    background: rgba(148, 196, 255, 0.10);
    border-color: rgba(102, 214, 255, 0.40);
}

/* Mobile drawer — slides down below the strip when open. Each row is
   a 56px-tall link with icon + label + chevron for clear thumb tapping. */
.top-nav-mobile-drawer {
    display: none;
}
.top-nav-mobile-backdrop {
    display: none;
}
.top-nav-mobile-list {
    display: flex;
    flex-direction: column;
}
/* Grouped-nav section labels inside the mobile drawer (Operations / Sales /
   Admin / Account). Reorder/edit mode is desktop-only — the drawer just
   reflects the saved order. */
.top-nav-mobile-group-label {
    padding: 14px 18px 4px;
    font-size: var(--text-micro, 0.7rem);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    color: var(--muted);
}
.top-nav-mobile-link {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    min-height: 56px;
    color: var(--text);
    text-decoration: none;
    font-size: 1rem;
    font-weight: 500;
    border-bottom: 1px solid rgba(148, 196, 255, 0.08);
    -webkit-tap-highlight-color: rgba(102, 214, 255, 0.18);
}
.top-nav-mobile-link:hover { text-decoration: none; }
.top-nav-mobile-link:active {
    background: rgba(148, 196, 255, 0.08);
}
.top-nav-mobile-link.is-active {
    background: linear-gradient(90deg, rgba(102,214,255,0.16), rgba(140,125,255,0.10));
    color: var(--text);
    box-shadow: inset 3px 0 0 var(--accent);
}
.top-nav-mobile-link .top-nav-link-icon {
    width: 20px;
    height: 20px;
    color: var(--muted);
}
.top-nav-mobile-link.is-active .top-nav-link-icon { color: var(--accent); }
.top-nav-mobile-label { flex: 1; }
.top-nav-mobile-chevron { width: 16px; height: 16px; color: var(--muted); flex-shrink: 0; }
.top-nav-mobile-signout-form {
    padding: 16px 18px 22px;
    border-top: 1px solid var(--border);
    background: rgba(15, 22, 34, 0.6);
}
.top-nav-mobile-signout {
    width: 100%;
    min-height: 48px;
    background: transparent;
    border: 1px solid rgba(255, 123, 156, 0.4);
    color: var(--danger);
    border-radius: 12px;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    -webkit-tap-highlight-color: rgba(255, 123, 156, 0.2);
}
.top-nav-mobile-signout:active { background: rgba(255, 123, 156, 0.10); }

/* ── Mobile breakpoint (≤720px): swap inline nav for the drawer ──
 * Inline-link strip + pager arrows + user name + sign-out + collapse
 * button all hide on mobile. Brand block stays. Hamburger button
 * appears on the left, avatar stays on the right. Drawer slides down
 * below the strip when toggled. */
@media (max-width: 720px) {
    .top-nav-inner-v2 {
        padding: 0.55rem 0.75rem;
        gap: 0.7rem;
        min-height: 56px;
    }
    .top-nav-mobile-toggle {
        display: inline-flex;
    }
    /* Mobile keeps the full hide + drawer strip (no desktop minimized bar). */
    html[data-topnav="collapsed"] .top-nav-inner-v2 { display: none !important; }
    .top-nav-groups,
    .user-name,
    .user-menu-caret,
    .user-collapse-btn {
        display: none !important;
    }
    .brand-block-v2 {
        padding-right: 0;
        border-right: 0;
        flex: 1;
        min-width: 0;
    }
    .brand-mark { width: 36px; height: 36px; font-size: 0.78rem; }
    /* Collapse the wordmark to just the CW mark on mobile — the full
       "Columbia Windows / Database" lockup can't coexist with the hamburger +
       back/reload + ⌘K/bell/avatar cluster on a phone without overlapping
       them. The mark still links home; the page title carries the identity.
       brand-block stays flex:1 so the mark sits left and the freed space
       becomes the spacer that pushes the control cluster to the right edge. */
    .brand-info { display: none; }
    .user-block-v2 {
        padding-left: 0;
        border-left: 0;
        gap: 0;
    }
    .user-avatar { width: 38px; height: 38px; font-size: 0.85rem; }
    /* 44px tap targets on mobile (Apple HIG). The .user-block-v2 prefix beats
       the inline .nav-cmdk/.nav-bell sizing in top_nav.php's <style>. */
    .user-block-v2 .nav-cmdk,
    .user-block-v2 .nav-bell { width: 44px; height: 44px; }
    .user-avatar-btn { min-height: 44px; }

    /* Drawer + backdrop become visible on mobile. The drawer flips its
       `hidden` attr via the JS toggle; CSS just provides the layout
       and animation. */
    .top-nav-mobile-drawer {
        display: block;
        position: absolute;
        left: 0;
        right: 0;
        top: 100%;
        background: linear-gradient(180deg, rgba(15,22,34,0.98), rgba(9,14,22,0.96));
        border-bottom: 1px solid var(--border);
        backdrop-filter: blur(12px);
        max-height: calc(100vh - 60px);
        overflow-y: auto;
        z-index: 30;
        box-shadow: 0 12px 32px rgba(var(--shadow-rgb), 0.45);
        animation: topnavDrawerIn 180ms ease-out;
    }
    .top-nav-mobile-drawer[hidden] { display: none; }
    .top-nav-mobile-backdrop {
        display: block;
        position: fixed;
        left: 0; right: 0; bottom: 0;
        top: 60px; /* sits below the strip */
        background: rgba(7, 11, 18, 0.55);
        border: 0;
        padding: 0;
        cursor: pointer;
        z-index: 25;
        -webkit-tap-highlight-color: transparent;
    }
    .top-nav-mobile-backdrop[hidden] { display: none; }

    /* Lock body scroll while the drawer is open so the page underneath
       doesn't rubber-band while the user is scanning the menu. */
    html.topnav-mobile-open,
    html.topnav-mobile-open body {
        overflow: hidden;
    }
}

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

/* The top-nav header is the anchor for the absolutely-positioned drawer.
 * Make it the positioning context so `top: 100%` resolves correctly. */
.top-nav.top-nav-v2 {
    position: sticky;
    /* keep the existing sticky behavior so the strip pins on scroll */
}
/* End top nav v2 ======================================================== */

/* ── Top-nav polish (2026-05): pager → overflow "More" menu + avatar menu ──
   The prev/next pager is gone; pills that don't fit are moved into the More
   menu by the overflow script in top_nav.php. Settings/Admin + sign-out live
   in the avatar dropdown. Tokenised onto cwdb-tokens.css. */

/* Brand cluster is now a home link — strip the default anchor chrome. */
a.brand-block-v2 {
    text-decoration: none;
    color: inherit;
    border-radius: var(--radius-sm, 8px);
    transition: background var(--transition-base, 0.2s ease);
}
a.brand-block-v2:hover { background: rgba(148, 196, 255, 0.06); }
a.brand-block-v2:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Active pill: keep the gradient fill, add a crisp inset accent underline +
   semibold weight so "you are here" reads instantly. */
.top-nav-link-v2.is-active {
    font-weight: var(--weight-semibold, 600);
    box-shadow: 0 0 22px rgba(102, 214, 255, 0.12), inset 0 -2px 0 var(--accent);
}

/* "More ▾" overflow control + menu ------------------------------------- */
.top-nav-more { position: relative; display: inline-flex; flex-shrink: 0; align-items: center; }
.top-nav-more[hidden] { display: none; }
.top-nav-more-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 7px 12px;
    min-height: 36px;
    border-radius: var(--radius-pill, 999px);
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
    font-family: inherit;
    font-size: var(--text-sm, 0.8rem);
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transition-base, 0.2s ease), color var(--transition-base, 0.2s ease), border-color var(--transition-base, 0.2s ease);
}
.top-nav-more-btn:hover,
.top-nav-more-btn[aria-expanded="true"] {
    background: rgba(148, 196, 255, 0.08);
    color: var(--text);
    border-color: var(--border);
}
.top-nav-more-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.top-nav-more-caret { width: 14px; height: 14px; flex-shrink: 0; }
.top-nav-more-dot { width: 6px; height: 6px; border-radius: var(--radius-pill, 999px); background: var(--accent); flex-shrink: 0; }
.top-nav-more-dot[hidden] { display: none; }

/* Fixed so it escapes the nav's overflow:hidden clip; JS sets top/right. */
.top-nav-more-menu {
    position: fixed;
    min-width: 210px;
    max-height: 72vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 0.3rem;
    background: var(--surface, #11203a);
    border: 1px solid var(--border, #2b3a55);
    border-radius: var(--radius-card, 12px);
    box-shadow: var(--shadow-md, 0 14px 30px rgba(var(--shadow-rgb), 0.35));
    z-index: 9998;
}
.top-nav-more-menu[hidden] { display: none; }
/* Moved pills render as full-width rows inside the menu. */
.top-nav-more-menu .top-nav-link-v2 {
    width: 100%;
    justify-content: flex-start;
    border-radius: var(--radius-sm, 8px);
    padding: 0.5rem 0.6rem;
}

/* Avatar dropdown (absorbs Settings/Admin + Sign out) ------------------- */
.user-menu-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.user-avatar-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 3px 8px 3px 3px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-pill, 999px);
    cursor: pointer;
    font-family: inherit;
    transition: background var(--transition-base, 0.2s ease), border-color var(--transition-base, 0.2s ease);
}
.user-avatar-btn:hover,
.user-avatar-btn[aria-expanded="true"] {
    background: rgba(148, 196, 255, 0.08);
    border-color: var(--border);
}
.user-avatar-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.user-menu-caret { width: 14px; height: 14px; color: var(--muted); flex-shrink: 0; }
.user-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 220px;
    padding: 0.3rem;
    background: var(--surface, #11203a);
    border: 1px solid var(--border, #2b3a55);
    border-radius: var(--radius-card, 12px);
    box-shadow: var(--shadow-md, 0 14px 30px rgba(var(--shadow-rgb), 0.35));
    z-index: 9998;
}
.user-menu[hidden] { display: none; }
.user-menu-head { padding: 0.5rem 0.6rem 0.4rem; }
.user-menu-name { font-size: var(--text-sm, 0.8rem); font-weight: var(--weight-semibold, 600); color: var(--text); }
.user-menu-sub { font-size: var(--text-micro, 0.7rem); color: var(--muted); margin-top: 1px; }
.user-menu-sep { height: 1px; background: var(--border); margin: 0.25rem 0; }
.user-menu-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-sm, 8px);
    color: var(--text);
    text-decoration: none;
    font-size: var(--text-sm, 0.8rem);
}
.user-menu-item .top-nav-link-icon { width: 16px; height: 16px; color: var(--muted); }
.user-menu-item:hover { background: rgba(148, 196, 255, 0.08); }
.user-menu-item.is-active { background: rgba(102, 214, 255, 0.12); }
.user-menu-item.is-active .top-nav-link-icon { color: var(--accent); }
.user-menu-signout-form { margin: 0; }
.user-menu-signout {
    width: 100%;
    text-align: left;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-sm, 8px);
    background: transparent;
    border: 0;
    color: var(--muted);
    font-family: inherit;
    font-size: var(--text-sm, 0.8rem);
    cursor: pointer;
}
.user-menu-signout:hover { background: rgba(255, 123, 156, 0.10); color: var(--danger); }
/* End top-nav polish ==================================================== */

/* /database — Reschedule button + modal ================================== */
/* Lays out the Start-date label/input + the Reschedule button as a row.
 * The inner <label class="db-field"> keeps its existing label-above-input
 * stacking; the wrapper just puts the field and button side-by-side. */
.db-schedule-field-row {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    width: 100%;
}
.db-schedule-field-row > .db-field {
    flex: 1;
    min-width: 0;
    margin: 0; /* override .db-field bottom margin so button stays aligned */
}
.db-reschedule-btn {
    flex-shrink: 0;
    height: 38px;
    white-space: nowrap;
    margin-bottom: 0;
}

.db-reschedule-backdrop {
    /* Sits above the drawer's own modal backdrop. */
    z-index: 100;
}
.db-reschedule-modal {
    max-width: 480px;
    width: calc(100% - 32px);
    margin: 60px auto 0;
    padding: 0;
}
.db-reschedule-body {
    padding: 0 22px 22px;
}
.db-reschedule-body .db-field {
    margin-top: 14px;
    display: block;
}
.db-reschedule-body .db-field-hint {
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.4;
}
.db-reschedule-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 18px;
}
.db-reschedule-status {
    margin: 12px 0 0;
    min-height: 1.2em;
    color: var(--muted);
    font-size: 0.85rem;
}
/* End /database reschedule ============================================== */

/* =========================================================================
   /database POLISH — list view + drawer + mobile (2026-05-20)
   --------------------------------------------------------------------------
   Layered on top of the .db-* base styles above. Adds:
     - Click-to-sort affordance on column headers (arrow indicator)
     - Inline CFM/Demo/Sold dot chips in the Job cell
     - Tighter row density + refined hover state
     - 2-column drawer layout at ≥860px (Identity+Status+Schedule on left,
       Customer+Notes on right) so the 900px-wide modal uses horizontal
       space better and reduces vertical scroll
     - Sticky drawer header strip with History link
     - Mobile responsive @media at ≤480px: horizontal-scroll table with
       sticky Job column, drawer full-screen, filter bar stacks
   ========================================================================= */

/* ---- T1 list view polish ------------------------------------------------ */

/* Sortable header arrow indicator. The TH carries data-sort-state="asc"|"desc"|"none";
   the ::after pseudo on the arrow span paints the chevron in the active
   direction. Inactive columns show a faint static glyph that brightens on
   hover so the affordance is discoverable. */
.db-list-table thead th.db-th-sort {
    cursor: pointer;
    user-select: none;
    transition: background 0.12s ease, color 0.12s ease;
}
.db-list-table thead th.db-th-sort:hover {
    color: var(--text);
    background: rgba(102, 214, 255, 0.08);
}
.db-list-table thead th.db-th-sort:focus-visible {
    outline: 2px solid rgba(102, 214, 255, 0.55);
    outline-offset: -3px;
}
.db-th-sort-arrow {
    display: inline-block;
    margin-left: 0.35rem;
    width: 0.55rem;
    opacity: 0.35;
    transition: opacity 0.12s ease, transform 0.12s ease;
    font-variant: normal;
}
.db-list-table thead th.db-th-sort:hover .db-th-sort-arrow {
    opacity: 0.85;
}
.db-list-table thead th.db-th-sort[data-sort-state="none"] .db-th-sort-arrow::after {
    content: "↕";
}
.db-list-table thead th.db-th-sort[data-sort-state="asc"] {
    color: var(--text);
}
.db-list-table thead th.db-th-sort[data-sort-state="asc"] .db-th-sort-arrow {
    opacity: 1;
}
.db-list-table thead th.db-th-sort[data-sort-state="asc"] .db-th-sort-arrow::after {
    content: "↑";
    color: var(--accent);
}
.db-list-table thead th.db-th-sort[data-sort-state="desc"] {
    color: var(--text);
}
.db-list-table thead th.db-th-sort[data-sort-state="desc"] .db-th-sort-arrow {
    opacity: 1;
}
.db-list-table thead th.db-th-sort[data-sort-state="desc"] .db-th-sort-arrow::after {
    content: "↓";
    color: var(--accent);
}

/* Inline dot chips next to the job name. Compact pill (≈14×14px circle
   with a letter inside) keeps the row dense; full status name is in the
   `title` attribute for hover-disclosure. Three tones (ok / warning /
   danger / muted) cover the CFM/Demo/Sold enum mapping (see
   reference_demo_status_enum.md). */
.db-cell-job-head {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    line-height: 1.2;
}
.db-row-chips {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    flex-shrink: 0;
}
.db-row-chip {
    /* Letter-in-a-dot. 14×14px keeps it tight; 16px font-size + bold
       weight makes the letter readable at this scale. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 800;
    font-variant: small-caps;
    letter-spacing: 0;
    line-height: 1;
    text-transform: uppercase;
    cursor: help;  /* hint that the title attribute carries more info */
    border: 1px solid transparent;
}
.db-row-chip-ok {
    background: rgba(46, 204, 113, 0.18);
    border-color: rgba(46, 204, 113, 0.55);
    color: var(--success);
}
.db-row-chip-warning {
    background: rgba(255, 191, 0, 0.18);
    border-color: rgba(255, 191, 0, 0.55);
    color: var(--warning);
}
.db-row-chip-danger {
    background: rgba(255, 87, 87, 0.18);
    border-color: rgba(255, 87, 87, 0.55);
    color: #ffaaaa;
}
.db-row-chip-muted {
    background: rgba(148, 196, 255, 0.08);
    border-color: rgba(148, 196, 255, 0.25);
    color: var(--muted);
}

/* Tighter row density — drop padding so 50 rows fit a normal viewport
   without scroll. Hover stays vivid against the slightly tighter row. */
.db-list-table tbody td {
    padding: 0.5rem 0.65rem;
}
.db-row {
    /* Slight crossfade between hover/selected/idle so the row interaction
       feels responsive without animation noise. */
    transition: background 0.12s ease, box-shadow 0.12s ease;
}
.db-row:hover td {
    background: rgba(102, 214, 255, 0.09);
}
.db-row.is-selected td {
    background: rgba(102, 214, 255, 0.14);
}

/* ---- T2 drawer polish --------------------------------------------------- */

/* History link in the drawer header — quick jump to /database/history?job_id=N
   so the operator can audit the same job they're inspecting without leaving
   context. Hidden until a job is loaded. */
.db-drawer-head-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.db-drawer-head-link {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.5rem;
    border: 1px solid rgba(148, 196, 255, 0.3);
    border-radius: 6px;
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 600;
    text-decoration: none;
    background: rgba(18, 28, 43, 0.4);
    transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.db-drawer-head-link:hover {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.55);
    background: rgba(102, 214, 255, 0.08);
}
.db-drawer-head-link[hidden] {
    display: none;
}

/* Sticky drawer header — name + history link stay visible while the form
   below scrolls. The drawer itself is already overflow-y:auto, so we just
   sticky-anchor the head at top:0 with a solid background so form content
   scrolling past doesn't bleed through. */
.db-detail-drawer .db-drawer-head {
    position: sticky;
    top: 0;
    z-index: 5;
    background: linear-gradient(180deg, rgba(15, 22, 34, 0.99), rgba(13, 20, 31, 0.99));
    /* Already has border-bottom + padding — just need the sticky positioning. */
}

/* ---- T2 drawer interior spacing + visual rhythm ------------------------- */

/* Drawer outer padding — slightly tighter so more content shows on a
   typical 900px-wide modal without scrolling. */
.db-detail-drawer.is-modal {
    padding: 0;
}
.db-detail-drawer.is-modal .db-drawer-head {
    padding: 0.7rem 1.05rem 0.6rem;
}
.db-detail-drawer.is-modal .db-drawer-form {
    padding: 0.55rem 1.05rem 0.8rem;
}

/* Section card styling — give each section a subtle surface so its
   boundaries read clearly without a heavy divider line. Replaces the
   old `border-top` divider that worked in 1-col scroll but disappeared
   visually in the 2-col grid. */
.db-detail-drawer.is-modal .db-drawer-section {
    border: 1px solid rgba(148, 196, 255, 0.09);
    border-radius: 10px;
    padding: 0.45rem 0.8rem 0.5rem;
    margin: 0;
    background: rgba(12, 18, 28, 0.32);
    /* :first-of-type override from base CSS no longer needed — every
       section is a card now. */
}
.db-detail-drawer.is-modal .db-drawer-section:first-of-type {
    border-top: 1px solid rgba(148, 196, 255, 0.09);  /* override base */
    padding-top: 0.45rem;
}

/* Section heading — slightly larger + brighter for legibility, with the
   accent color flowing into the underline divider rather than a flat
   color block. */
.db-detail-drawer.is-modal .db-section-h {
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    color: var(--accent);
    opacity: 0.9;
    margin: 0 0 0.4rem;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid rgba(102, 214, 255, 0.18);
}

/* Field rhythm — tight, consistent margins so 5+ fields stack cleanly
   inside Customer without overrunning the row's vertical budget. */
.db-detail-drawer.is-modal .db-field {
    margin-bottom: 0.3rem;
    gap: 0.18rem;
}
.db-detail-drawer.is-modal .db-field:last-child {
    margin-bottom: 0;
}
.db-detail-drawer.is-modal .db-field-label {
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    color: var(--muted);
}
.db-detail-drawer.is-modal .db-field-row {
    gap: 0.5rem;
    margin-bottom: 0.3rem;
}
.db-detail-drawer.is-modal .db-field-row:last-child {
    margin-bottom: 0;
}
.db-detail-drawer.is-modal .db-field-hint {
    margin-top: 0.4rem;
    font-size: 0.72rem;
    color: var(--muted);
}

/* Identity section reference line — JNID + Job ID as a single inline
   muted text line under the Job name + Marketer field row. Was a
   full field-row of readonly fields pre-polish; collapsed to inline
   to reclaim vertical space. */
.db-detail-drawer.is-modal .db-identity-refline {
    margin: 0.35rem 0 0;
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
    flex-wrap: wrap;
    font-size: 0.72rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
.db-identity-refline-label {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    font-size: 0.62rem;
    opacity: 0.7;
}
.db-identity-refline-value {
    color: var(--text);
    font-weight: 600;
    user-select: all;  /* one-click select for easy copy */
}
.db-identity-refline-sep {
    opacity: 0.4;
}

/* Statuses section: chip row is short and shouldn't visually compete
   with the chunky Customer column. Tighter chip slot spacing. */
.db-detail-drawer.is-modal .db-drawer-chiprow {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.45rem;
}
.db-detail-drawer.is-modal .db-drawer-chipfield {
    display: flex;
    flex-direction: column;
    gap: 0.22rem;
}

/* Actions row — buttons aligned right with a small gap, hint stays
   left-aligned so it doesn't blob next to the buttons. */
.db-detail-drawer.is-modal .db-action-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.db-detail-drawer.is-modal .db-action-hint {
    font-size: 0.72rem;
    color: var(--muted);
    flex: 1 1 auto;
}

/* Notes textarea — comfortable typing space. */
.db-detail-drawer.is-modal .db-drawer-section-notes textarea {
    min-height: 6rem;
    line-height: 1.4;
}

/* Schedule's start_datetime + Reschedule button row — make the button
   align with the input baseline, not stretched. */
.db-detail-drawer.is-modal .db-schedule-field-row {
    display: flex;
    gap: 0.5rem;
    align-items: flex-end;
}
.db-detail-drawer.is-modal .db-schedule-field-row > .db-field {
    flex: 1 1 auto;
    margin-bottom: 0;
}
.db-detail-drawer.is-modal .db-reschedule-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Hidden-from-calendars toggle — sits in the Schedule section under the
   ATSB pair. Single-line layout with checkbox + label + small hint stack.
   Hover/focus brings up the muted hint into the regular text color so
   the operator gets visual feedback that the row is interactive. */
.db-detail-drawer.is-modal .db-hidden-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    margin: 0.5rem 0 0;
    padding: 0.45rem 0.6rem;
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 8px;
    background: rgba(8, 13, 21, 0.45);
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease;
}
.db-detail-drawer.is-modal .db-hidden-toggle:hover {
    border-color: rgba(102, 214, 255, 0.35);
    background: rgba(8, 13, 21, 0.65);
}
.db-detail-drawer.is-modal .db-hidden-toggle input[type="checkbox"] {
    /* Slight nudge so the checkbox aligns with the title baseline rather
       than the hint baseline. */
    margin-top: 0.15rem;
    width: 1rem;
    height: 1rem;
    accent-color: var(--accent);
    cursor: pointer;
    flex: 0 0 auto;
}
.db-hidden-toggle-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}
.db-hidden-toggle-title {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
}
.db-detail-drawer.is-modal .db-hidden-toggle:has(input:checked) .db-hidden-toggle-title {
    /* Active state — emphasise the title so it's visible at a glance
       that this job IS hidden. */
    color: var(--warning);
}
.db-detail-drawer.is-modal .db-hidden-toggle:has(input:checked) {
    border-color: rgba(255, 191, 0, 0.45);
    background: rgba(255, 191, 0, 0.06);
}
.db-hidden-toggle-hint {
    font-size: 0.7rem;
    color: var(--muted);
    line-height: 1.3;
}

/* ---- Reschedule modal polish (paired with drawer redesign) -------------- */

/* Tighter modal body padding so the new context block + input + actions
   fit without forcing the modal taller than necessary. */
.db-reschedule-body {
    padding: 0.85rem 1.05rem 1.05rem !important;
}
/* Drop the visible top border on the modal header so the title sits
   flush against the new "Currently scheduled" reference block below. */
.db-reschedule-modal .db-drawer-head {
    padding: 0.7rem 1.05rem 0.55rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.1);
}
/* Two-line meta in the modal header: "Reschedule" title + the job name
   as the subtitle (instead of the previous long instruction sentence). */
.db-reschedule-modal .db-drawer-meta {
    font-size: 0.92rem;
    color: var(--text);
    opacity: 0.95;
    line-height: 1.25;
    margin-top: 0.18rem;
}

/* "Currently scheduled" reference block: prominent so the operator
   reads the FROM time before picking the new TO time. */
.db-reschedule-from {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    background: rgba(8, 13, 21, 0.5);
    margin-bottom: 0.7rem;
    flex-wrap: wrap;
}
.db-reschedule-label {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--muted);
    flex: 0 0 auto;
}
.db-reschedule-current {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    flex: 1 1 auto;
    min-width: 0;
}
.db-reschedule-count {
    flex: 0 0 auto;
    padding: 0.18rem 0.5rem;
    border-radius: 999px;
    border: 1px solid rgba(255, 191, 0, 0.5);
    background: rgba(255, 191, 0, 0.12);
    color: var(--warning);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
}
.db-reschedule-count[hidden] {
    display: none;
}

/* "To" field — the new datetime input. Slight emphasis so it reads as
   the primary action target. */
.db-reschedule-to {
    margin-bottom: 0.6rem !important;
}
.db-reschedule-to input {
    font-weight: 600;
    font-size: 0.95rem;
}

/* Note paragraph (replaces the verbose duplicate hint) — single short
   sentence explaining the RESET behavior + sync side effect. */
.db-reschedule-note {
    margin: 0 0 0.85rem;
    padding: 0.45rem 0.6rem;
    border-radius: 6px;
    background: rgba(102, 214, 255, 0.05);
    border-left: 2px solid rgba(102, 214, 255, 0.4);
    font-size: 0.74rem;
    color: var(--muted);
    line-height: 1.4;
}
.db-reschedule-note strong {
    color: var(--text);
    font-weight: 700;
}

/* 2-column drawer at ≥860px viewport. Identity spans full width on row 1
   so its three controls breathe; below that, Statuses+Customer pair, then
   Schedule+Notes pair, then Actions spans full width again. Critical
   `align-items: start` keeps short sections (Statuses) from stretching to
   match tall ones (Customer) in the same row. */
@media (min-width: 860px) {
    .db-detail-drawer.is-modal .db-drawer-form {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
        gap: 0.5rem 0.75rem;
        align-items: start;  /* don't stretch sections to row max-height */
    }
    /* Identity: full width on row 1 so JNID+Job ID readonly pair and
       Marketer dropdown lay out comfortably in a horizontal field-row. */
    .db-detail-drawer.is-modal .db-drawer-form > section:nth-of-type(1) {
        grid-column: 1 / -1;
    }
    /* Statuses (col 1) pairs with Customer (col 2) on row 2.
       Statuses is short; align-items:start above keeps it from stretching. */
    .db-detail-drawer.is-modal .db-drawer-form > section:nth-of-type(2) { grid-column: 1; }
    .db-detail-drawer.is-modal .db-drawer-form > section:nth-of-type(3) {
        grid-column: 2;
        /* Customer is the tallest section; let it span 2 rows so Schedule
           can sit directly under Statuses in col 1 without leaving a
           gap below Customer. */
        grid-row: span 2;
    }
    /* Schedule on row 3 col 1, under Statuses. */
    .db-detail-drawer.is-modal .db-drawer-form > section:nth-of-type(4) { grid-column: 1; }
    /* Notes: full-width on its own row so the textarea has comfortable
       typing width. Sits BELOW Customer (which spans down via grid-row:
       span 2 above) and ABOVE Actions. Without this rule, Notes would
       land in col 2 row 4 with col 1 empty — visible gap. */
    .db-detail-drawer.is-modal .db-drawer-form > section:nth-of-type(5) {
        grid-column: 1 / -1;
    }
    /* Actions: full width on the last row so the Save button has proper
       horizontal space. */
    .db-detail-drawer.is-modal .db-drawer-form > section:nth-of-type(6) {
        grid-column: 1 / -1;
    }
    /* Hidden inputs (csrf, job_id, slot_week_key) — no footprint, span
       both columns so they don't push the grid layout. */
    .db-detail-drawer.is-modal .db-drawer-form > input[type="hidden"] {
        grid-column: 1 / -1;
    }
}

/* ---- T4 mobile responsive (≤480px) ------------------------------------- */
@media (max-width: 480px) {
    /* Filter bar stacks vertically so each control gets full width. */
    .db-filter-bar {
        display: flex;
        flex-direction: column;
        gap: 0.4rem;
        padding: 0.55rem 0.6rem;
    }
    .db-filter,
    .db-filter-search,
    .db-filter-narrow {
        width: 100%;
    }
    /* Table: horizontal scroll with sticky Job column so the operator can
       see which row they're looking at while scrolling sideways for
       Marketer/Contact/Address. Same pattern as the ATSB grid mobile fix. */
    .db-list-wrap {
        overflow-x: auto;
    }
    .db-list-table {
        width: auto;
        min-width: 100%;
    }
    .db-list-table .db-col-job,
    .db-list-table .db-cell-job {
        position: sticky;
        left: 0;
        z-index: 1;
        background: rgba(13, 20, 31, 0.98);
        min-width: 12rem;
        max-width: 14rem;
    }
    .db-list-table thead th.db-col-job {
        z-index: 3;  /* above sticky body cells AND sticky header */
    }
    /* Other columns get min-widths so each remains tappable / readable. */
    .db-list-table .db-col-start,
    .db-list-table .db-cell-start  { min-width: 7rem; }
    .db-list-table .db-col-marketer,
    .db-list-table .db-cell-marketer { min-width: 8rem; }
    .db-list-table .db-col-contact,
    .db-list-table .db-cell-contact { min-width: 12rem; }
    .db-list-table .db-col-address,
    .db-list-table .db-cell-address { min-width: 14rem; max-width: 20rem; }

    /* Drawer goes full-screen at this width — easier to fill out form
       fields on a phone than wrestling with a constrained modal. */
    .db-detail-modal-backdrop {
        padding: 0;
    }
    .db-detail-drawer.is-modal {
        width: 100% !important;
        max-width: 100% !important;
        height: 100vh !important;
        height: 100dvh !important;
        max-height: 100vh !important;
        max-height: 100dvh !important;
        border-radius: 0 !important;
        margin: 0 !important;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    /* Drawer head: tighter padding, ensure close button is reachable. */
    .db-detail-drawer .db-drawer-head {
        padding: 0.6rem 0.85rem 0.55rem;
    }
    .db-drawer-head-link {
        padding: 0.35rem 0.65rem;
        min-height: 2.2rem;
    }
    /* Pager: stack summary and nav vertically. */
    .db-pager {
        flex-direction: column;
        align-items: flex-start;
    }
    .db-pager-nav {
        margin-left: 0;
    }
    .db-pager-btn {
        min-height: 2.4rem;
        min-width: 2.4rem;
    }
}

/* =========================================================================
   END /database POLISH
   ========================================================================= */

/* =====================================================================
   /confirmation detail modal — B3 layout
   Side-by-side Details + Notes, 2-tab (Details / Call history), action
   bar pinned above the body, click-to-edit fields, autosave notes, and
   a collapsible metadata strip. Scoped via `.is-b3` on the drawer so
   it overrides the legacy `.detail-modal-head` / `.detail-grid` rules
   without affecting the rest of the app.
   ===================================================================== */

.confirmation.detail-drawer.is-modal.is-b3 {
    /* Wider than the legacy 900px so the side-by-side columns breathe. */
    width: min(960px, calc(100vw - 1.5rem));
    padding: 0 !important;
}

/* Header: customer name as a real heading (replaces the legacy "SELECTED
   ROW" uppercase tag), chip+time+relative inline below, close button
   positioned top-right. Override the legacy flex:row layout. */
.is-b3 .confirmation.detail-modal-head.b3-head {
    display: block;
    padding: 1.05rem 1.3rem 0.9rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}
.is-b3 .confirmation.detail-modal-head.b3-head::before {
    /* Keep the existing cyan accent line. */
    border-radius: 14px 14px 0 0;
}
.is-b3 .confirmation.detail-modal-close {
    position: absolute;
    top: 0.7rem;
    right: 0.85rem;
    z-index: 6;
}
/* Higher specificity to override the legacy `.detail-drawer h2` rule
   that styled the heading as a small uppercase accent tag. */
.confirmation.detail-drawer.is-b3 h2.b3-name,
.is-b3 h2.confirmation.b3-name {
    margin: 0 2.5rem 0.3rem 0;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--text);
    text-transform: none;
    line-height: 1.2;
    opacity: 1;
}
.confirmation.detail-drawer.is-b3 p.b3-meta-line,
.is-b3 p.confirmation.b3-meta-line {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    color: var(--muted);
    font-size: 0.9rem;
    font-weight: 500;
}
.is-b3 .confirmation.b3-appt {
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Action bar — sticky right under the header so Confirm wins. */
.confirmation.b3-action-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
    padding: 0.85rem 1.3rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    margin: 0;
}
.confirmation.b3-action-bar .confirmation.action-btn {
    padding: 0.55rem 0.95rem;
    font-size: 0.9rem;
    font-weight: 700;
    border-radius: 8px;
    margin: 0;
}
.confirmation.b3-action-bar .confirmation.action-btn.is-cfm {
    padding: 0.6rem 1.15rem;
    font-size: 0.95rem;
    flex-grow: 1;
    max-width: 280px;
}
.confirmation.b3-action-bar .confirmation.action-status {
    margin-left: auto;
    font-size: 0.78rem;
}

/* Tab strip. */
.confirmation.b3-tabs {
    display: flex;
    gap: 0;
    padding: 0 1.3rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}
.confirmation.b3-tab {
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    color: var(--muted);
    padding: 0.65rem 1rem;
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    margin-bottom: -1px;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    transition: color 0.12s ease, border-color 0.12s ease;
}
.confirmation.b3-tab:hover {
    color: var(--text);
}
.confirmation.b3-tab.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.confirmation.b3-tab-count {
    display: inline-block;
    background: var(--surface-3);
    color: var(--muted);
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.4;
}
.confirmation.b3-tab.is-active .confirmation.b3-tab-count {
    background: rgba(102, 214, 255, 0.18);
    color: var(--accent);
}

/* Panes. */
.confirmation.b3-pane {
    padding: 1rem 1.3rem 1.2rem;
}
.confirmation.b3-pane[hidden] {
    display: none;
}

/* Details grid — 2 columns equal width. */
.confirmation.b3-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem 1.2rem;
    align-items: stretch;
    margin-bottom: 0.9rem;
}
.confirmation.b3-col-lead,
.confirmation.b3-col-notes {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-width: 0;
}

.confirmation.b3-section-label {
    display: block;
    font-size: 0.7rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 800;
    margin: 0 0 0.25rem;
}

/* Phones — stacked tappable rows (M / H / W) with a small "edit" button. */
.is-b3 .confirmation.detail-phones.b3-phones {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 0.3rem;
    margin: 0;
}
.confirmation.b3-phones-edit {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    width: auto;
    padding: 0.25rem 0.65rem;
    font-size: 0.74rem;
    color: var(--muted);
    background: transparent;
    border: 1px dashed var(--border);
    border-radius: 6px;
    cursor: pointer;
    font-family: inherit;
    margin-bottom: 0.35rem;
    white-space: nowrap;
    line-height: 1.3;
}
.confirmation.b3-phones-edit:hover,
.confirmation.b3-phones-edit:focus-visible {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.55);
    background: rgba(102, 214, 255, 0.08);
    outline: none;
}
.confirmation.b3-phones-edit:hover {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.4);
    background: rgba(102, 214, 255, 0.05);
}

/* Click-to-edit fields. Hovering reveals affordance without an ✎ icon. */
.is-b3 .confirmation.detail-hit.b3-field {
    display: block;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 0.5rem 0.65rem;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease;
    width: 100%;
    color: var(--text);
    font-family: inherit;
}
.is-b3 .confirmation.detail-hit.b3-field:hover,
.is-b3 .confirmation.detail-hit.b3-field:focus-visible {
    background: var(--surface-2);
    border-color: var(--border);
    outline: none;
}
.confirmation.b3-field-label {
    display: block;
    font-size: 0.7rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    margin-bottom: 0.18rem;
}
.confirmation.b3-field-value {
    display: block;
    color: var(--text);
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.35;
}
.confirmation.b3-field-value small {
    display: block;
    color: var(--muted);
    font-size: 0.76rem;
    font-weight: 500;
    margin-top: 0.15rem;
}

/* Notes column — full-height textarea fills the col. */
.is-b3 .confirmation.notes-form.b3-notes {
    display: flex;
    flex-direction: column;
    flex: 1;
    margin: 0;
    background: transparent;
    padding: 0;
    border: 0;
    gap: 0.35rem;
}
.confirmation.b3-notes-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
}
.confirmation.b3-notes-saved {
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--muted);
    min-height: 1em;
}
.confirmation.b3-notes-saved:not(:empty) {
    color: var(--accent);
}
/* Higher specificity to beat `.confirmation.notes-form.notes-form-inline textarea`
   which fixes the legacy textarea to 92px. */
.is-b3 .confirmation.b3-col-notes textarea.b3-textarea,
.is-b3 .confirmation.notes-form.b3-notes textarea.b3-textarea {
    flex: 1 1 auto;
    width: 100%;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 8px;
    padding: 0.6rem 0.7rem;
    font-family: inherit;
    font-size: 0.9rem;
    line-height: 1.5;
    min-height: 240px;
    resize: vertical;
    box-sizing: border-box;
}
.is-b3 .confirmation.b3-col-notes textarea.b3-textarea:focus,
.is-b3 .confirmation.notes-form.b3-notes textarea.b3-textarea:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: 0 0 0 1px var(--accent);
}

/* Reminder preview block — keeps existing visual, just tighter margins. */
.is-b3 .confirmation.reminder-preview.b3-reminder {
    margin: 0 0 0.85rem;
    padding: 0.65rem 0.85rem;
    background: rgba(255, 214, 107, 0.06);
    border-left: 3px solid var(--tone-reminders, #ffd66b);
    border-radius: 0 8px 8px 0;
}

/* Metadata disclosure — quiet button + reveal strip. */
.confirmation.b3-meta-disclosure {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--muted);
    padding: 0.3rem 0.85rem;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    margin-bottom: 0.6rem;
}
.confirmation.b3-meta-disclosure:hover {
    color: var(--text);
    border-color: rgba(102, 214, 255, 0.4);
}
.confirmation.b3-meta-disclosure-icon {
    line-height: 1;
}
.confirmation.b3-meta-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem 1.1rem;
    background: var(--surface-2);
    border-radius: 8px;
    padding: 0.6rem 0.85rem;
    font-size: 0.78rem;
    color: var(--muted);
}
.confirmation.b3-meta-strip[hidden] {
    display: none;
}
.confirmation.b3-meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}
.confirmation.b3-meta-item .muted-line {
    margin: 0;
    color: var(--muted);
}
.confirmation.b3-meta-item span:not(.muted-line),
.confirmation.b3-meta-item code {
    color: var(--text);
    font-weight: 600;
}
.confirmation.b3-meta-jnid {
    font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
    font-size: 0.74rem;
    background: var(--surface-3);
    padding: 0.05rem 0.4rem;
    border-radius: 4px;
}
/* Compact job-name editor inside the metadata strip — no full row to itself. */
.is-b3 .confirmation.b3-meta-item .confirmation.detail-hit.detail-hit-inline {
    display: inline-block;
    background: transparent;
    border: 1px dashed transparent;
    border-radius: 4px;
    padding: 0.05rem 0.3rem;
    color: var(--text);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}
.is-b3 .confirmation.b3-meta-item .confirmation.detail-hit.detail-hit-inline:hover {
    border-color: var(--border);
    background: var(--surface);
}

/* Call history pane. */
.confirmation.b3-history-head {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-bottom: 0.7rem;
    flex-wrap: wrap;
}
.confirmation.b3-history-head .confirmation.b3-section-label {
    margin: 0;
}
.confirmation.b3-history-log-btn {
    margin-left: auto;
    padding: 0.35rem 0.8rem;
    font-size: 0.8rem;
}
.is-b3 .confirmation.call-history-list {
    margin: 0;
}

/* Hide legacy "Call logging" + "Call history" separate sections — they were
   absorbed into the Call history tab. The old `.call-log-block` no longer
   renders inside B3, but defensively keep the rule out of cascade trouble. */
.is-b3 .confirmation.call-log-block,
.is-b3 .confirmation.call-history-section {
    display: none;
}

/* Responsive — narrow viewports collapse to single column, notes below. */
@media (max-width: 720px) {
    .confirmation.b3-grid {
        grid-template-columns: 1fr;
    }
    .is-b3 .confirmation.b3-textarea {
        min-height: 140px;
    }
    .confirmation.b3-action-bar .confirmation.action-btn.is-cfm {
        max-width: none;
        width: 100%;
    }
}

/* =====================================================================
   /confirmation inbox — V2 layout
   ---------------------------------------------------------------------
   Adds three things to the legacy 7-column table without restructuring
   the data attributes JS depends on:
     1. Segment color bar on the row's first td + a subtle background tint
        for the most urgent segments (call-now / past-due / same-day).
        Rest of the row reads "I'm urgent" pre-attentively, no chip-text
        scanning required.
     2. Hover-reveal inline action pill (Confirm + ⋯ overflow → Remind /
        NoGo / Cancel job) in a new rightmost td. Pointer-events: none at
        rest so the action area doesn't accidentally interrupt row clicks.
        Touch devices keep actions always-visible via `@media (hover:none)`.
     3. Workload pills in the hero summarizing the visible queue by
        urgency. Updates live from JS after every sort/filter pass.
   ===================================================================== */

/* Segment color bar — applies a 4px left edge in the row's segment tone
   plus a soft horizontal gradient tint for the highest-urgency tiers. The
   tint is intentionally subtle (8-14% alpha) so the row still reads as a
   table row, not a tinted card. */
.confirmation.inbox-row.is-segment-call-now > td:first-child,
.confirmation.inbox-row.is-segment-past-due > td:first-child,
.confirmation.inbox-row.is-segment-same-day > td:first-child,
.confirmation.inbox-row.is-segment-next-day > td:first-child,
.confirmation.inbox-row.is-segment-three-day > td:first-child,
.confirmation.inbox-row.is-segment-future > td:first-child,
.confirmation.inbox-row.is-segment-reminders > td:first-child,
.confirmation.inbox-row.is-segment-no-start-date > td:first-child {
    /* Kill the legacy neon-magenta/cyan/violet `box-shadow: inset 4px` stripe
       (lines 6577-6610 + mobile fallback at ~7203) so it doesn't render as a
       second colored bar adjacent to our V2 border. Without this override,
       call-now rows show magenta+orange side-by-side, past-due shows red+red,
       etc. — looking like fragmented "rainbow stripes" on the left edge. */
    box-shadow: none !important;
    border-left: 4px solid rgba(157, 177, 204, 0.4);
}
.confirmation.inbox-row.is-segment-call-now > td:first-child {
    border-left-color: #ff9d4d;
}
.confirmation.inbox-row.is-segment-past-due > td:first-child {
    border-left-color: var(--danger-strong);
}
.confirmation.inbox-row.is-segment-same-day > td:first-child {
    border-left-color: var(--danger-strong);
}
.confirmation.inbox-row.is-segment-next-day > td:first-child {
    border-left-color: #ffb46b;
}
.confirmation.inbox-row.is-segment-three-day > td:first-child {
    border-left-color: var(--accent);
}
.confirmation.inbox-row.is-segment-future > td:first-child {
    border-left-color: rgba(157, 177, 204, 0.55);
}
.confirmation.inbox-row.is-segment-reminders > td:first-child {
    border-left-color: #ffd66b;
}
.confirmation.inbox-row.is-segment-no-start-date > td:first-child {
    border-left-color: rgba(157, 177, 204, 0.35);
}

/* Row tint — applied ONLY to the first cell so it stays subtle and we
   avoid the "vertical red line between cells" artifact that comes from
   running a gradient inside every td (each cell would reset the gradient
   start, creating visible column dividers in the segment tone). The
   colored 4px left bar carries the urgency signal; the gradient inside
   the first cell adds a soft glow without leaking into other columns. */
.confirmation.inbox-row.is-segment-call-now > td:first-child {
    background-image: linear-gradient(90deg, rgba(255, 157, 77, 0.14), rgba(255, 157, 77, 0));
}
.confirmation.inbox-row.is-segment-past-due > td:first-child {
    background-image: linear-gradient(90deg, rgba(255, 93, 119, 0.18), rgba(255, 93, 119, 0));
}
.confirmation.inbox-row.is-segment-same-day > td:first-child {
    background-image: linear-gradient(90deg, rgba(255, 93, 119, 0.10), rgba(255, 93, 119, 0));
}
.confirmation.inbox-row.is-segment-reminders > td:first-child {
    background-image: linear-gradient(90deg, rgba(255, 214, 107, 0.12), rgba(255, 214, 107, 0));
}

/* Inline row actions — Confirm + ⋯ overflow.
   Hover-reveal so the table reads clean at rest. Column needs to be wide
   enough to fit the wrap (Confirm + ⋯) WITHOUT overflowing — at 130px
   the wrap (148px) was getting clipped by the cell's overflow:hidden
   AND the trigger ended up against the viewport edge. */
.confirmation.inbox-col-actions { width: 200px; }
.confirmation.inbox-th-actions { width: 200px; }

.confirmation.inbox-cell.row-actions {
    /* Right-aligned pill with breathing room on both sides so the cursor
       has room to land on the wrap without falling off-screen. */
    text-align: right;
    padding: 0.45rem 1.1rem 0.45rem 0.7rem;
    white-space: nowrap;
    /* Don't clip the wrap; let it sit naturally inside the wider column. */
    overflow: visible;
}
.confirmation.inbox-cell.has-row-actions {
    position: relative;
    min-width: 130px;
}
.confirmation.inbox-cell.has-row-actions::before {
    content: "···";
    position: absolute;
    right: 1.2rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--muted);
    font-size: 0.95rem;
    letter-spacing: 0.18em;
    opacity: 0.35;
    transition: opacity 0.15s ease;
    pointer-events: none;
}
.confirmation.inbox-row:hover .confirmation.inbox-cell.has-row-actions::before,
.confirmation.inbox-row:focus-within .confirmation.inbox-cell.has-row-actions::before {
    opacity: 0;
}

.confirmation.inbox-actions-cell-wrap {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.22rem 0.4rem;
    background: rgba(15, 22, 34, 0.55);
    border: 1px solid rgba(148, 196, 255, 0.14);
    border-radius: 10px;
    opacity: 0;
    transform: translateX(4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    pointer-events: none;
    position: relative;
}
.confirmation.inbox-row:hover .confirmation.inbox-actions-cell-wrap,
.confirmation.inbox-row:focus-within .confirmation.inbox-actions-cell-wrap {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.confirmation.btn-confirm-row {
    background: rgba(102, 214, 255, 0.08);
    color: var(--accent);
    border: 1px solid rgba(102, 214, 255, 0.45);
    border-radius: 8px;
    padding: 0.32rem 0.85rem;
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    font-family: inherit;
    letter-spacing: 0.02em;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
    line-height: 1.2;
    white-space: nowrap;
}
.confirmation.btn-confirm-row::before {
    content: "✓";
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
}
.confirmation.btn-confirm-row:hover,
.confirmation.btn-confirm-row:focus-visible {
    background: var(--accent);
    color: #0b1a2e;
    border-color: var(--accent);
    outline: none;
}

.confirmation.btn-overflow-row {
    background: transparent;
    color: var(--muted);
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 0.32rem 0.55rem;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.confirmation.btn-overflow-row:hover,
.confirmation.btn-overflow-row:focus-visible {
    color: var(--text);
    border-color: var(--border);
    background: var(--surface-2);
    outline: none;
}

.confirmation.inbox-actions-more {
    position: relative;
}
.confirmation.inbox-actions-menu {
    position: absolute;
    /* Open DOWNWARD. The hover chain is held open by the invisible bridge
       below the trigger (see ::before pseudo-element) plus the fact that
       the menu is a DOM child of `.inbox-actions-more`, so hovering the
       menu items keeps `:hover` on the parent active. */
    top: calc(100% + 4px);
    right: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.3rem;
    display: none;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 150px;
    z-index: 6;
    box-shadow: 0 8px 30px rgba(var(--shadow-rgb), 0.45);
}
/* Invisible bridge — a 6px transparent strip ABOVE the menu that covers
   the gap between the trigger and the menu. Without this, the mouse
   crosses 4px of empty space when moving from the ⋯ button down to the
   menu, briefly leaving the hover zone and closing the menu. */
.confirmation.inbox-actions-menu::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 8px;
}
.confirmation.inbox-actions-more:hover .confirmation.inbox-actions-menu,
.confirmation.inbox-actions-more:focus-within .confirmation.inbox-actions-menu {
    display: flex;
}
/* When the menu is open, keep the parent row's hover-reveal alive even
   if the mouse drifts into the menu's bounds. The menu is rendered as a
   child of the row's action cell, so the row stays hovered for free —
   but the action wrap's pointer-events: none/auto needs to stay open. */
.confirmation.inbox-actions-menu .btn {
    width: 100%;
    text-align: left;
    justify-content: flex-start;
    padding: 0.4rem 0.65rem;
    font-size: 0.82rem;
}

/* Touch devices have no real hover — keep actions always visible so
   iPad / phone operators don't get stuck. */
@media (hover: none) {
    .confirmation.inbox-actions-cell-wrap {
        opacity: 1;
        transform: none;
        pointer-events: auto;
    }
    .confirmation.inbox-cell.has-row-actions::before {
        display: none;
    }
}

/* Workload pills in the hero. */
.confirmation.workload-pills {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0.4rem 0 0;
    flex: 0 1 auto;
}
.confirmation.workload-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.65rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--muted);
}
.confirmation.workload-pill strong {
    color: var(--text);
    font-weight: 800;
    font-size: 0.88rem;
}
.confirmation.workload-pill.is-call-now {
    border-color: rgba(255, 157, 77, 0.5);
    color: #ff9d4d;
}
.confirmation.workload-pill.is-call-now strong { color: #ffba7e; }
.confirmation.workload-pill.is-past-due {
    border-color: rgba(255, 93, 119, 0.55);
    color: var(--danger-strong);
}
.confirmation.workload-pill.is-past-due strong { color: #ff8aa0; }
.confirmation.workload-pill.is-same-day {
    border-color: rgba(255, 93, 119, 0.35);
    color: #ff8aa0;
}
.confirmation.workload-pill.is-same-day strong { color: #ffb2c0; }

/* ---- SMS templates page (/messages/templates) ---- */
.smstpl-page {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem 3rem;
    color: var(--text, #e6e9ef);
}
.smstpl-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    padding-bottom: 0.75rem;
}
.smstpl-title { font-size: 1.25rem; margin: 0; }
.smstpl-sub { color: rgba(255,255,255,0.55); font-size: 0.85rem; margin: 0.15rem 0 0; }
.smstpl-sub a { color: rgba(255,255,255,0.7); }
.smstpl-new {
    display: inline-block;
    background: var(--info);
    color: var(--white);
    padding: 0.45rem 0.85rem;
    border-radius: 6px;
    text-decoration: none;
    font-size: 0.85rem;
}
.smstpl-new:hover { background: #4c6cff; }

.smstpl-shell {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 1.5rem;
    align-items: start;
}

.smstpl-list { border-right: 1px solid rgba(255,255,255,0.06); padding-right: 1rem; }
.smstpl-cat { margin-bottom: 1rem; }
.smstpl-cat-name {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255,255,255,0.45);
    margin-bottom: 0.35rem;
}
.smstpl-list ul { list-style: none; padding: 0; margin: 0; }
.smstpl-list-item a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.4rem 0.5rem;
    border-radius: 5px;
    color: rgba(255,255,255,0.85);
    text-decoration: none;
    font-size: 0.9rem;
}
.smstpl-list-item a:hover { background: rgba(255,255,255,0.05); }
.smstpl-list-item.is-current a { background: rgba(44,78,240,0.18); color: #c8d3ff; }
.smstpl-list-item.is-inactive a { color: rgba(255,255,255,0.45); }
.smstpl-badge {
    background: rgba(255,255,255,0.1);
    color: rgba(255,255,255,0.6);
    padding: 0.05rem 0.4rem;
    border-radius: 3px;
    font-size: 0.65rem;
    text-transform: uppercase;
}

.smstpl-editor { padding-left: 0.25rem; }
.smstpl-field { margin-bottom: 0.9rem; }
.smstpl-field label {
    display: block;
    font-size: 0.78rem;
    color: rgba(255,255,255,0.6);
    margin-bottom: 0.25rem;
    letter-spacing: 0.02em;
}
.smstpl-field input[type="text"],
.smstpl-field select,
.smstpl-field textarea {
    width: 100%;
    background: rgba(255,255,255,0.04);
    color: var(--text, #e6e9ef);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 6px;
    padding: 0.55rem 0.65rem;
    font: inherit;
}
.smstpl-field textarea { resize: vertical; min-height: 120px; }
.smstpl-row { display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: end; }

.smstpl-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 0.45rem;
    font-size: 0.78rem;
    color: rgba(255,255,255,0.6);
    flex-wrap: wrap;
    gap: 0.5rem;
}
.smstpl-merge-hint { display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: center; }
.smstpl-merge-tag {
    background: rgba(255,255,255,0.08);
    color: rgba(255,255,255,0.85);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 4px;
    padding: 0.1rem 0.45rem;
    font-size: 0.7rem;
    cursor: pointer;
    font-family: inherit;
}
.smstpl-merge-tag:hover { background: rgba(44,78,240,0.2); border-color: rgba(44,78,240,0.6); }

.smstpl-preview-box {
    background: rgba(46, 213, 115, 0.05);
    border-left: 3px solid rgba(46, 213, 115, 0.5);
    padding: 0.7rem 0.85rem;
    border-radius: 4px;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    color: rgba(255,255,255,0.92);
    white-space: pre-wrap;
    word-wrap: break-word;
    min-height: 2.6rem;
}

.smstpl-actions { margin-top: 1.25rem; display: flex; align-items: center; gap: 0.75rem; }
.smstpl-save {
    background: var(--info);
    color: var(--white);
    border: 0;
    padding: 0.55rem 1.2rem;
    border-radius: 6px;
    font: inherit;
    cursor: pointer;
}
.smstpl-save:hover { background: #4c6cff; }
.smstpl-status { font-size: 0.85rem; color: rgba(255,255,255,0.6); }
.smstpl-status.is-ok { color: #6dcd86; }
.smstpl-status.is-error { color: #ff8aa0; }

/* ═════════════════════════════════════════════════════════════════════════
   /messages/templates POLISH v1 — visual refresh (2026-05-20)
   Mirrors the /messages/automations polish: card framing, legible labels,
   refined inputs, accent gradient save button, mobile responsive.
   Additive overrides win the cascade against the original rules above.
   ═════════════════════════════════════════════════════════════════════════ */

/* Page frame */
.smstpl-page {
    max-width: 1240px;
    padding: 1.5rem 1.75rem 3.5rem;
}
.smstpl-head {
    border-bottom: 1px solid var(--border);
    padding-bottom: 1rem;
    margin-bottom: 1.25rem;
    gap: 1rem;
}
.smstpl-title {
    font-size: 1.55rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
    margin: 0;
}
.smstpl-page > .smstpl-head > div:first-child > .smstpl-sub {
    color: var(--muted);
    font-size: 0.88rem;
    margin-top: 0.35rem;
    line-height: 1.55;
}
.smstpl-page > .smstpl-head > div:first-child > .smstpl-sub a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smstpl-page > .smstpl-head > div:first-child > .smstpl-sub a:hover { border-bottom-style: solid; }
.smstpl-sep { color: rgba(255, 255, 255, 0.25); margin: 0 0.35rem; }

/* "+ New template" promoted to accent fill */
.smstpl-new {
    background: linear-gradient(180deg, var(--accent), #4eb8e8);
    color: #04121a;
    border: 1px solid var(--accent);
    padding: 0.55rem 1rem;
    border-radius: 8px;
    font-size: 0.86rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    transition: transform 0.1s ease, box-shadow 0.15s ease;
}
.smstpl-new:hover {
    background: linear-gradient(180deg, #8de4ff, var(--accent));
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.18);
    transform: translateY(-1px);
}

/* Banner — only shown when no template is being edited (orientation hint) */
.smstpl-banner {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.07), rgba(102, 214, 255, 0.03));
    border: 1px solid rgba(102, 214, 255, 0.22);
    border-left: 3px solid var(--accent);
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.55;
    padding: 0.8rem 1rem;
    border-radius: 8px;
    margin-bottom: 1.5rem;
}
.smstpl-banner strong { color: var(--accent); font-weight: 600; }
.smstpl-banner a {
    color: var(--accent);
    text-decoration: underline;
    text-decoration-color: rgba(102, 214, 255, 0.45);
}
.smstpl-banner a:hover { text-decoration-color: var(--accent); }
.smstpl-banner code {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    padding: 0.08rem 0.4rem;
    border-radius: 4px;
    font-size: 0.78rem;
    color: var(--text);
}

/* Shell — slightly wider sidebar so category labels don't crowd names */
.smstpl-shell {
    grid-template-columns: 280px 1fr;
    gap: 1.5rem;
}

/* Sidebar list */
.smstpl-list {
    border-right: none;
    padding-right: 0;
}
.smstpl-cat { margin-bottom: 1.15rem; }
.smstpl-cat-name {
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.08em;
    margin-bottom: 0.5rem;
    padding-left: 0.35rem;
}
.smstpl-list-item { margin-bottom: 0.3rem; }
.smstpl-list-item a {
    padding: 0.55rem 0.75rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 0.88rem;
    color: var(--text);
    font-weight: 500;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smstpl-list-item a:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.35);
    transform: translateY(-1px);
}
.smstpl-list-item.is-current a {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.14), rgba(102, 214, 255, 0.06));
    border-color: var(--accent);
    color: var(--accent);
    box-shadow: 0 0 0 1px rgba(102, 214, 255, 0.2);
}
.smstpl-list-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
    min-width: 0;
}
.smstpl-list-item.is-inactive a { color: var(--muted); }
.smstpl-badge {
    background: rgba(255, 208, 102, 0.15);
    color: var(--warning);
    border: 1px solid rgba(255, 208, 102, 0.3);
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    flex: 0 0 auto;
    margin-left: 0.4rem;
}

/* Editor card frame */
.smstpl-editor {
    padding: 1.25rem 1.35rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-sm, 0 6px 14px rgba(var(--shadow-rgb), 0.34));
}

/* Bigger, bolder labels */
.smstpl-field { margin-bottom: 1.05rem; }
.smstpl-field > label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0.4rem;
    text-transform: none;
    letter-spacing: 0;
}
/* The "Live preview" label has a sub-note baked in — keep that muted */
.smstpl-field > label .smstpl-sub {
    color: var(--muted);
    font-weight: 400;
    font-size: 0.78rem;
}

/* Inputs */
.smstpl-field input[type="text"],
.smstpl-field select,
.smstpl-field textarea {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    padding: 0.6rem 0.75rem;
    font-size: 0.92rem;
    color: var(--text);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.smstpl-field input[type="text"]:hover,
.smstpl-field select:hover,
.smstpl-field textarea:hover {
    border-color: rgba(148, 196, 255, 0.32);
}
.smstpl-field input[type="text"]:focus,
.smstpl-field select:focus,
.smstpl-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.15);
    background: var(--surface);
}
.smstpl-field textarea {
    min-height: 140px;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
    line-height: 1.55;
}
.smstpl-field select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%2366d6ff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.65rem center;
    background-size: 14px;
    padding-right: 2rem;
}
/* Active checkbox row — match the inline label visual treatment */
.smstpl-field > label input[type="checkbox"] {
    margin-right: 0.45rem;
    transform: scale(1.05);
    vertical-align: middle;
    accent-color: var(--accent);
}
/* The row that holds Category + Active needs the active toggle to look balanced */
.smstpl-row { gap: 1.1rem; align-items: end; }
.smstpl-row .smstpl-field:last-child {
    display: flex;
    align-items: center;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    margin-bottom: 0;
    min-height: 42px;
}
.smstpl-row .smstpl-field:last-child > label {
    margin-bottom: 0;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
}

/* Meta row under textarea — counter + insert chips */
.smstpl-meta {
    margin-top: 0.6rem;
    padding: 0.65rem 0.75rem;
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.1);
    border-radius: 8px;
    font-size: 0.78rem;
    color: var(--muted);
    align-items: flex-start;
}
#smstpl-count {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    background: var(--surface);
    border: 1px solid var(--border);
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
}
.smstpl-merge-hint { gap: 0.3rem; }
.smstpl-merge-hint::before {
    content: "Click to insert:";
    color: var(--muted);
    margin-right: 0.4rem;
    font-weight: 500;
    font-size: 0.78rem;
    align-self: center;
}

/* Merge tag chips */
.smstpl-merge-tag {
    background: var(--surface);
    color: var(--accent);
    border: 1px solid rgba(102, 214, 255, 0.3);
    border-radius: 6px;
    padding: 0.2rem 0.55rem;
    font-size: 0.76rem;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, transform 0.1s ease;
}
.smstpl-merge-tag:hover {
    background: rgba(102, 214, 255, 0.14);
    border-color: var(--accent);
    transform: translateY(-1px);
}

/* Live preview — chat-bubble style */
.smstpl-preview-box {
    background: linear-gradient(135deg, rgba(44, 78, 240, 0.18), rgba(27, 92, 170, 0.12));
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-left: 3px solid var(--accent);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, "Plus Jakarta Sans", "Segoe UI", sans-serif;
    font-size: 0.92rem;
    line-height: 1.55;
    padding: 0.85rem 1rem;
    border-radius: 4px 14px 14px 14px;     /* asymmetric — feels like an inbound chat bubble */
    min-height: 3rem;
    max-width: 32rem;
    box-shadow: 0 1px 3px rgba(var(--shadow-rgb), 0.25);
    position: relative;
}
.smstpl-preview-box::before {
    content: "Preview SMS";
    position: absolute;
    top: -0.65rem;
    left: 0.85rem;
    background: var(--surface);
    color: var(--accent);
    padding: 0.05rem 0.5rem;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border: 1px solid var(--border);
    border-radius: 4px;
}

/* Actions row */
.smstpl-actions {
    margin-top: 1.5rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--border);
    gap: 0.75rem;
}
.smstpl-save {
    background: linear-gradient(180deg, var(--accent), #4eb8e8);
    border: 1px solid var(--accent);
    color: #04121a;
    padding: 0.6rem 1.4rem;
    border-radius: 8px;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
    transition: transform 0.1s ease, box-shadow 0.15s ease;
}
.smstpl-save:hover {
    background: linear-gradient(180deg, #8de4ff, var(--accent));
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.2);
    transform: translateY(-1px);
}
.smstpl-status { font-size: 0.85rem; color: var(--muted); font-weight: 500; }
.smstpl-status.is-ok    { color: #7be9a6; }
.smstpl-status.is-error { color: #ff8aa0; }

/* Mobile responsive */
@media (max-width: 900px) {
    .smstpl-page { padding: 1rem 1rem 2.5rem; }
    .smstpl-head { flex-direction: column; align-items: flex-start; }
    .smstpl-head h1 { font-size: 1.35rem; }
    .smstpl-new { align-self: stretch; text-align: center; }
    .smstpl-shell { grid-template-columns: 1fr; gap: 1.25rem; }
    .smstpl-editor { padding: 1rem 1.05rem; }
    .smstpl-row { grid-template-columns: 1fr; }
}
@media (max-width: 520px) {
    .smstpl-page { padding: 0.85rem 0.75rem 2.5rem; }
    .smstpl-actions { flex-direction: column; align-items: stretch; }
    .smstpl-save { width: 100%; }
    .smstpl-preview-box { max-width: 100%; }
}

/* ---- /messages: inline template picker (continuous-system feel) ---- */

/* Labeled toggle button (replaces the bare ⚡ icon).
   `width: auto` and `flex-shrink: 0` defeat the legacy 32px square
   sizing at line ~10232 so the icon + label + chevron all fit. */
.msg-templates-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    width: auto;
    flex-shrink: 0;
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.9);
    padding: 0.4rem 0.75rem;
    border-radius: 6px;
    cursor: pointer;
    font: inherit;
    font-size: 0.82rem;
    height: 36px;
    white-space: nowrap;
}
.msg-templates-toggle:hover {
    background: rgba(44,78,240,0.16);
    border-color: rgba(44,78,240,0.4);
}
.msg-templates-toggle.is-on {
    background: rgba(44,78,240,0.25);
    border-color: rgba(44,78,240,0.6);
    color: var(--white);
}
.msg-templates-toggle .msg-templates-chev {
    color: rgba(255,255,255,0.5);
    transition: transform 0.12s ease;
}
.msg-templates-toggle.is-on .msg-templates-chev {
    transform: rotate(90deg);
    color: rgba(255,255,255,0.85);
}

/* Dropdown */
.msg-templates {
    background: rgba(10,15,25,0.96);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    padding: 0.5rem;
    margin-bottom: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    max-height: 60vh;
    overflow-y: auto;
    box-shadow: 0 6px 20px rgba(0,0,0,0.35);
}
.msg-templates-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.1rem 0.35rem 0.4rem;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255,255,255,0.45);
    border-bottom: 1px solid rgba(255,255,255,0.06);
    margin-bottom: 0.15rem;
}
.msg-templates-head a {
    color: rgba(180,200,255,0.85);
    text-decoration: none;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.75rem;
}
.msg-templates-head a:hover { color: var(--white); }

/* Each chip */
.msg-template-row {
    position: relative;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 6px;
    display: flex;
    align-items: stretch;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.msg-template-row:hover {
    background: rgba(44,78,240,0.12);
    border-color: rgba(44,78,240,0.4);
}
.msg-template-row.is-editing {
    background: rgba(44,78,240,0.16);
    border-color: rgba(44,78,240,0.55);
    flex-direction: column;
}
.msg-template-row.is-just-saved {
    background: rgba(46,213,115,0.16);
    border-color: rgba(46,213,115,0.5);
}

.msg-template-pick {
    flex: 1 1 auto;
    background: transparent;
    border: 0;
    color: rgba(255,255,255,0.92);
    padding: 0.55rem 0.7rem;
    text-align: left;
    cursor: pointer;
    font: inherit;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}
.msg-template-row-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
}
.msg-template-name {
    font-weight: 600;
    font-size: 0.86rem;
    color: rgba(255,255,255,0.95);
}
.msg-template-cat {
    font-size: 0.65rem;
    color: rgba(255,255,255,0.5);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    background: rgba(255,255,255,0.06);
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    white-space: nowrap;
}
.msg-template-preview {
    font-size: 0.78rem;
    color: rgba(255,255,255,0.6);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.msg-template-row.is-editing .msg-template-preview {
    -webkit-line-clamp: unset;
    overflow: visible;
}

/* Edit pencil */
.msg-template-edit {
    flex: 0 0 auto;
    align-self: flex-start;
    background: transparent;
    border: 0;
    border-left: 1px solid rgba(255,255,255,0.06);
    color: rgba(255,255,255,0.45);
    width: 36px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: color 0.12s ease, background 0.12s ease;
}
.msg-template-edit:hover {
    color: rgba(180,200,255,0.95);
    background: rgba(44,78,240,0.1);
}
.msg-template-row.is-editing .msg-template-edit {
    display: none;
}

/* Inline editor */
.msg-template-editor {
    padding: 0.4rem 0.7rem 0.6rem;
    border-top: 1px solid rgba(255,255,255,0.08);
    margin-top: 0.2rem;
}
.msg-template-textarea {
    width: 100%;
    background: rgba(0,0,0,0.25);
    color: rgba(255,255,255,0.95);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 4px;
    padding: 0.45rem 0.55rem;
    font: inherit;
    font-size: 0.85rem;
    resize: vertical;
    min-height: 80px;
}
.msg-template-editor-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 0.45rem;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.msg-template-editor-hint {
    font-size: 0.7rem;
    color: rgba(255,255,255,0.45);
    flex: 1 1 200px;
}
.msg-template-editor-buttons {
    display: flex;
    gap: 0.35rem;
    flex: 0 0 auto;
}
.msg-template-cancel,
.msg-template-save {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.85);
    padding: 0.35rem 0.7rem;
    border-radius: 4px;
    cursor: pointer;
    font: inherit;
    font-size: 0.78rem;
}
.msg-template-save {
    background: var(--info);
    border-color: var(--info);
    color: var(--white);
}
.msg-template-save:hover { background: #4c6cff; }
.msg-template-save:disabled { opacity: 0.55; cursor: wait; }
.msg-template-cancel:hover { background: rgba(255,255,255,0.1); }

.msg-templates-empty {
    padding: 0.9rem 0.7rem;
    color: rgba(255,255,255,0.55);
    font-size: 0.85rem;
    text-align: center;
}
.msg-templates-empty a {
    color: rgba(180,200,255,0.9);
    margin-left: 0.25rem;
    text-decoration: none;
}
.msg-templates-empty a:hover { color: var(--white); }

/* ---- Composer char/segment counter ---- */
.msg-composer-meta {
    display: flex;
    justify-content: flex-end;
    padding: 0.2rem 0.1rem 0;
    min-height: 1.1rem;
}
.msg-composer-count {
    font-size: 0.72rem;
    color: rgba(255,255,255,0.45);
    font-variant-numeric: tabular-nums;
}
.msg-composer-count.is-multi { color: rgba(255, 184, 108, 0.85); }
.msg-composer-count.is-warning { color: rgba(255, 138, 160, 0.95); font-weight: 600; }

/* ---- Improved empty thread copy ---- */
.msg-empty-thread strong { display: block; margin-bottom: 0.35rem; color: rgba(255,255,255,0.85); }
.msg-empty-thread a {
    display: inline-block;
    margin-top: 0.6rem;
    color: rgba(180, 200, 255, 0.85);
    text-decoration: none;
}
.msg-empty-thread a:hover { color: var(--white); }

/* ---- Inbound bubble classification badges (YES/STOP/HELP) ---- */
.msg-bubble-meta {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0 4px;
}
.msg-bubble-badge {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    padding: 0.05rem 0.4rem;
    border-radius: 3px;
    text-transform: uppercase;
}
.msg-bubble-badge-opt_in {
    background: rgba(46, 213, 115, 0.18);
    border: 1px solid rgba(46, 213, 115, 0.45);
    color: #7be9a6;
}
.msg-bubble-badge-opt_out {
    background: rgba(255, 93, 119, 0.18);
    border: 1px solid rgba(255, 93, 119, 0.45);
    color: #ffb2c0;
}
.msg-bubble-badge-help {
    background: rgba(255, 184, 108, 0.18);
    border: 1px solid rgba(255, 184, 108, 0.45);
    color: #ffd5a8;
}

/* Subtle left-edge tint on the inbound bubble itself for the same cues. */
.msg-bubble-row.cls-opt_in .msg-bubble-body {
    border-left: 3px solid rgba(46, 213, 115, 0.55);
}
.msg-bubble-row.cls-opt_out .msg-bubble-body {
    border-left: 3px solid rgba(255, 93, 119, 0.55);
}
.msg-bubble-row.cls-help .msg-bubble-body {
    border-left: 3px solid rgba(255, 184, 108, 0.55);
}

/* ---- Needs-response sidebar pulse ---- */
.msg-convo.needs-response {
    position: relative;
}
.msg-convo.needs-response::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: calc(100% - 12px);
    background: linear-gradient(180deg, var(--danger-strong), #ff8aa0);
    border-radius: 2px;
    box-shadow: 0 0 6px rgba(255, 93, 119, 0.5);
    animation: msg-needs-pulse 1.6s ease-in-out infinite;
}
@keyframes msg-needs-pulse {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 1; }
}
.msg-convo.needs-response .msg-convo-last {
    color: rgba(255, 178, 192, 0.95);
    font-style: italic;
}

/* ---- Context-panel enrichment: status pill + appointment block ---- */
.msg-context-status {
    margin-top: 0.45rem;
}
.msg-status-pill {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 0.15rem 0.5rem;
    border-radius: 3px;
    border: 1px solid transparent;
}
.msg-status-lead {
    background: rgba(148, 196, 255, 0.12);
    border-color: rgba(148, 196, 255, 0.4);
    color: rgba(190, 215, 255, 0.95);
}
.msg-status-confirmed {
    background: rgba(46, 213, 115, 0.16);
    border-color: rgba(46, 213, 115, 0.5);
    color: #7be9a6;
}
.msg-status-demoed {
    background: rgba(102, 189, 255, 0.16);
    border-color: rgba(102, 189, 255, 0.5);
    color: #b8d8ff;
}
.msg-status-won {
    background: rgba(46, 213, 115, 0.28);
    border-color: rgba(46, 213, 115, 0.7);
    color: #9eedb6;
    font-weight: 800;
}
.msg-status-lost,
.msg-status-declined {
    background: rgba(255, 93, 119, 0.16);
    border-color: rgba(255, 93, 119, 0.5);
    color: #ffb2c0;
}

.msg-context-sub-warn {
    color: rgba(255, 184, 108, 0.85);
}

/* ---- Context-panel activity timeline ---- */
.msg-timeline {
    list-style: none;
    padding: 0;
    margin: 0.45rem 0 0;
    position: relative;
}
.msg-timeline::before {
    content: '';
    position: absolute;
    left: 6px;
    top: 0.4rem;
    bottom: 0.4rem;
    width: 1px;
    background: rgba(148, 196, 255, 0.18);
}
.msg-timeline-item {
    position: relative;
    padding: 0.35rem 0 0.35rem 1.2rem;
    font-size: 0.8rem;
}
.msg-timeline-dot {
    position: absolute;
    left: 0;
    top: 0.65rem;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: rgba(148, 196, 255, 0.5);
    border: 2px solid rgba(9, 14, 22, 0.95);
    box-shadow: 0 0 0 1px rgba(148, 196, 255, 0.45);
}
.msg-tl-good   .msg-timeline-dot { background: rgba(46, 213, 115, 0.85);  box-shadow: 0 0 0 1px rgba(46, 213, 115, 0.55); }
.msg-tl-bad    .msg-timeline-dot { background: rgba(255, 93, 119, 0.85);  box-shadow: 0 0 0 1px rgba(255, 93, 119, 0.55); }
.msg-tl-warn   .msg-timeline-dot { background: rgba(255, 184, 108, 0.85); box-shadow: 0 0 0 1px rgba(255, 184, 108, 0.55); }
.msg-tl-neutral .msg-timeline-dot { background: rgba(190, 215, 255, 0.7); }

.msg-timeline-body {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.msg-timeline-label {
    color: rgba(255,255,255,0.85);
    line-height: 1.3;
}
.msg-timeline-when {
    color: rgba(255,255,255,0.45);
    font-size: 0.7rem;
    cursor: help; /* hint that hover gives absolute timestamp */
}
.msg-tl-good .msg-timeline-label { color: #b6efce; }
.msg-tl-bad  .msg-timeline-label { color: #ffb2c0; }
.msg-tl-warn .msg-timeline-label { color: #ffd5a8; }

/* Sidebar footer compact links (Health / Templates) */
.msg-foot-link {
    font-size: 0.74rem;
    color: rgba(180, 200, 255, 0.85);
    text-decoration: none;
    padding: 0.15rem 0.5rem;
    border: 1px solid rgba(180, 200, 255, 0.25);
    border-radius: 4px;
    margin-left: 0.3rem;
}
.msg-foot-link:hover {
    background: rgba(180, 200, 255, 0.08);
    color: var(--white);
}

/* ---- /messages/health page ---- */
.smshealth-page {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem 3rem;
    color: var(--text, #e6e9ef);
}
.smshealth-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    padding-bottom: 0.75rem;
    margin-bottom: 1.25rem;
}
.smshealth-head h1 { font-size: 1.25rem; margin: 0; }
.smshealth-sub { color: rgba(255,255,255,0.55); font-size: 0.85rem; margin: 0.15rem 0 0; }
.smshealth-sub a { color: rgba(255,255,255,0.7); }
.smshealth-templates-link {
    color: rgba(180, 200, 255, 0.85);
    text-decoration: none;
    padding: 0.4rem 0.75rem;
    border: 1px solid rgba(180, 200, 255, 0.25);
    border-radius: 6px;
    font-size: 0.85rem;
}
.smshealth-templates-link:hover { background: rgba(180,200,255,0.08); color: var(--white); }

.smshealth-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.85rem;
    margin-bottom: 1.5rem;
}
.smshealth-card {
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 8px;
    padding: 0.85rem 1rem;
}
.smshealth-metric-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255,255,255,0.5);
    margin-bottom: 0.4rem;
}
.smshealth-metric-val {
    font-size: 1.55rem;
    font-weight: 700;
    color: #b6efce;
    line-height: 1.05;
}
.smshealth-metric-val.smshealth-tone-bad { color: #ffb2c0; }
.smshealth-metric-val.smshealth-tone-muted { color: rgba(255,255,255,0.4); font-weight: 500; }
.smshealth-metric-sub {
    margin-top: 0.4rem;
    font-size: 0.75rem;
    color: rgba(255,255,255,0.55);
}

.smshealth-section { margin-top: 1.75rem; }
.smshealth-section-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
    flex-wrap: wrap;
}
.smshealth-section-head h2 {
    font-size: 0.95rem;
    margin: 0;
    color: rgba(255,255,255,0.9);
}
.smshealth-section-sub {
    font-size: 0.75rem;
    color: rgba(255,255,255,0.5);
}
.smshealth-pill {
    background: rgba(148, 196, 255, 0.12);
    border: 1px solid rgba(148, 196, 255, 0.3);
    color: rgba(190, 215, 255, 0.95);
    border-radius: 9px;
    font-size: 0.7rem;
    padding: 0.05rem 0.45rem;
    margin-left: 0.35rem;
    vertical-align: middle;
}
.smshealth-cap {
    font-size: 0.78rem;
    color: rgba(255,255,255,0.6);
}
.smshealth-cap strong { color: var(--white); }

.smshealth-spark {
    display: flex;
    align-items: flex-end;
    gap: 0.75rem;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 8px;
    padding: 0.85rem 1rem 0.6rem;
    min-height: 110px;
}
.smshealth-spark-col {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
}
.smshealth-spark-stack {
    display: flex;
    flex-direction: column-reverse;
    width: 100%;
    height: 70px;
    justify-content: flex-end;
}
.smshealth-spark-bar {
    width: 100%;
    min-height: 1px;
    border-radius: 2px;
}
.smshealth-spark-out {
    background: linear-gradient(180deg, #4c6cff, var(--info));
}
.smshealth-spark-in {
    background: linear-gradient(180deg, rgba(46, 213, 115, 0.85), rgba(46, 213, 115, 0.55));
    margin-top: 2px;
}
.smshealth-spark-label {
    font-size: 0.7rem;
    color: rgba(255,255,255,0.55);
    text-transform: uppercase;
}
.smshealth-spark-total {
    font-size: 0.72rem;
    color: rgba(255,255,255,0.8);
    font-variant-numeric: tabular-nums;
}

.smshealth-list {
    list-style: none;
    padding: 0;
    margin: 0;
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 8px;
    overflow: hidden;
}
.smshealth-list-row {
    border-top: 1px solid rgba(255,255,255,0.05);
}
.smshealth-list-row:first-child { border-top: 0; }
.smshealth-list-link,
.smshealth-list-row-quiet {
    display: grid;
    grid-template-columns: 200px 1fr 80px;
    gap: 0.85rem;
    padding: 0.55rem 0.85rem;
    color: rgba(255,255,255,0.9);
    text-decoration: none;
    font-size: 0.85rem;
    align-items: baseline;
}
.smshealth-list-link:hover { background: rgba(44, 78, 240, 0.08); }
.smshealth-list-name { font-weight: 600; color: rgba(255,255,255,0.95); }
.smshealth-list-body {
    color: rgba(255,255,255,0.7);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.smshealth-list-body-quiet { color: rgba(255,255,255,0.5); }
.smshealth-list-when {
    color: rgba(255,255,255,0.45);
    text-align: right;
    font-size: 0.78rem;
}
.smshealth-empty {
    padding: 1rem;
    text-align: center;
    color: rgba(255,255,255,0.5);
    font-size: 0.88rem;
    border: 1px dashed rgba(255,255,255,0.1);
    border-radius: 8px;
}

/* ---- /messages "+ New" overlay ---- */
.msg-new-overlay {
    position: fixed;
    inset: 0;
    background: rgba(5, 9, 16, 0.65);
    backdrop-filter: blur(4px);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.msg-new-overlay[hidden] { display: none; }
.msg-new-panel {
    background: rgba(14, 21, 33, 0.98);
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 10px;
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 18px 48px rgba(0,0,0,0.55);
}
.msg-new-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.85rem 1rem;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.msg-new-head h2 { font-size: 1rem; margin: 0; }
.msg-new-close {
    background: transparent;
    border: 0;
    color: rgba(255,255,255,0.6);
    font-size: 1.4rem;
    cursor: pointer;
    line-height: 1;
    padding: 0 0.3rem;
}
.msg-new-close:hover { color: var(--white); }

.msg-new-body {
    padding: 0.85rem 1rem 1rem;
    overflow-y: auto;
}
.msg-new-label {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255,255,255,0.55);
    margin-bottom: 0.35rem;
}
.msg-new-search-input {
    width: 100%;
    background: rgba(0,0,0,0.25);
    color: rgba(255,255,255,0.95);
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    font: inherit;
}
.msg-new-results {
    margin-top: 0.7rem;
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 6px;
    max-height: 320px;
    overflow-y: auto;
}
.msg-new-hint {
    padding: 1rem;
    text-align: center;
    color: rgba(255,255,255,0.45);
    font-size: 0.85rem;
}
.msg-new-result {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 0.6rem;
    align-items: center;
    width: 100%;
    background: transparent;
    border: 0;
    border-bottom: 1px solid rgba(255,255,255,0.05);
    color: rgba(255,255,255,0.92);
    padding: 0.55rem 0.7rem;
    text-align: left;
    cursor: pointer;
    font: inherit;
    font-size: 0.85rem;
}
.msg-new-result:last-child { border-bottom: 0; }
.msg-new-result:hover { background: rgba(44, 78, 240, 0.12); }
.msg-new-result-name { font-weight: 600; }
.msg-new-result-phone {
    color: rgba(255,255,255,0.55);
    font-variant-numeric: tabular-nums;
    font-size: 0.78rem;
}
.msg-new-tag {
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.1rem 0.4rem;
    border-radius: 3px;
    border: 1px solid transparent;
    white-space: nowrap;
}
.msg-new-tag-good {
    background: rgba(46, 213, 115, 0.16);
    border-color: rgba(46, 213, 115, 0.45);
    color: #7be9a6;
}
.msg-new-tag-warn {
    background: rgba(255, 184, 108, 0.16);
    border-color: rgba(255, 184, 108, 0.45);
    color: #ffd5a8;
}
.msg-new-tag-bad {
    background: rgba(255, 93, 119, 0.16);
    border-color: rgba(255, 93, 119, 0.45);
    color: #ffb2c0;
}

.msg-new-compose { margin-top: 0.4rem; }
.msg-new-picked {
    background: rgba(44, 78, 240, 0.1);
    border: 1px solid rgba(44, 78, 240, 0.3);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    margin-bottom: 0.6rem;
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    column-gap: 0.6rem;
    align-items: center;
}
.msg-new-picked-name {
    grid-column: 1;
    font-weight: 600;
}
.msg-new-picked-phone {
    grid-column: 1;
    color: rgba(255,255,255,0.55);
    font-size: 0.78rem;
}
.msg-new-picked .msg-new-tag {
    grid-column: 2;
    grid-row: 1 / 3;
    justify-self: end;
}
#msg-new-textarea {
    width: 100%;
    background: rgba(0,0,0,0.25);
    color: rgba(255,255,255,0.95);
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    font: inherit;
    resize: vertical;
    min-height: 100px;
}
.msg-new-foot {
    margin-top: 0.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.msg-new-count {
    font-size: 0.72rem;
    color: rgba(255,255,255,0.5);
    font-variant-numeric: tabular-nums;
}
.msg-new-foot-actions { display: flex; gap: 0.35rem; }
.msg-new-back,
.msg-new-send {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.85);
    padding: 0.4rem 0.85rem;
    border-radius: 5px;
    font: inherit;
    font-size: 0.82rem;
    cursor: pointer;
}
.msg-new-send {
    background: var(--info);
    border-color: var(--info);
    color: var(--white);
}
.msg-new-send:hover { background: #4c6cff; }
.msg-new-send:disabled { opacity: 0.55; cursor: not-allowed; }
.msg-new-back:hover { background: rgba(255,255,255,0.1); }
.msg-new-error {
    margin-top: 0.5rem;
    color: #ffb2c0;
    font-size: 0.82rem;
}

/* Template picker inside the + New overlay */
.msg-new-tpl-bar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 0.45rem;
}
.msg-new-tpl-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.85);
    padding: 0.35rem 0.7rem;
    border-radius: 5px;
    cursor: pointer;
    font: inherit;
    font-size: 0.78rem;
}
.msg-new-tpl-toggle:hover {
    background: rgba(44, 78, 240, 0.16);
    border-color: rgba(44, 78, 240, 0.45);
}
.msg-new-tpl-toggle.is-on {
    background: rgba(44, 78, 240, 0.22);
    border-color: rgba(44, 78, 240, 0.55);
    color: var(--white);
}
.msg-new-tpl-chev {
    color: rgba(255,255,255,0.5);
    transition: transform 0.12s ease;
}
.msg-new-tpl-toggle.is-on .msg-new-tpl-chev {
    transform: rotate(90deg);
    color: rgba(255,255,255,0.85);
}
.msg-new-tpl-list {
    background: rgba(10, 15, 25, 0.96);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 6px;
    margin-bottom: 0.55rem;
    max-height: 240px;
    overflow-y: auto;
    padding: 0.3rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.msg-new-tpl-loading,
.msg-new-tpl-empty {
    padding: 0.7rem 0.6rem;
    text-align: center;
    color: rgba(255,255,255,0.5);
    font-size: 0.82rem;
}
.msg-new-tpl-empty a { color: rgba(180, 200, 255, 0.9); margin-left: 0.25rem; }
.msg-new-tpl-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 5px;
    color: rgba(255,255,255,0.92);
    padding: 0.45rem 0.6rem;
    text-align: left;
    cursor: pointer;
    font: inherit;
}
.msg-new-tpl-chip:hover {
    background: rgba(44, 78, 240, 0.16);
    border-color: rgba(44, 78, 240, 0.45);
}
.msg-new-tpl-row1 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    gap: 0.4rem;
}
.msg-new-tpl-name {
    font-weight: 600;
    font-size: 0.82rem;
    color: rgba(255,255,255,0.95);
}
.msg-new-tpl-cat {
    font-size: 0.6rem;
    color: rgba(255,255,255,0.5);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: rgba(255,255,255,0.06);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
}
.msg-new-tpl-preview {
    font-size: 0.75rem;
    color: rgba(255,255,255,0.6);
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Fill-in form for missing merge fields (appt_date, rep, etc.) */
.msg-new-fillin {
    background: rgba(255, 184, 108, 0.07);
    border: 1px solid rgba(255, 184, 108, 0.32);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    margin-bottom: 0.6rem;
}
.msg-new-fillin-head {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 213, 168, 0.95);
    margin-bottom: 0.45rem;
    font-weight: 700;
}
.msg-new-fillin-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 0.45rem;
}
.msg-new-fillin-field {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}
.msg-new-fillin-label {
    font-size: 0.7rem;
    color: rgba(255,255,255,0.7);
}
.msg-new-fillin-input {
    background: rgba(0,0,0,0.3);
    color: rgba(255,255,255,0.95);
    border: 1px solid rgba(255, 184, 108, 0.35);
    border-radius: 4px;
    padding: 0.35rem 0.5rem;
    font: inherit;
    font-size: 0.82rem;
}
.msg-new-fillin-input:focus {
    outline: 1px solid rgba(255, 184, 108, 0.65);
    outline-offset: 0;
    border-color: rgba(255, 184, 108, 0.65);
}

/* Now the + New button needs to actually be styleable (was disabled). */
.msg-new-btn {
    background: var(--info);
    border: 1px solid var(--info);
    color: var(--white);
    padding: 0.15rem 0.55rem;
    border-radius: 4px;
    font: inherit;
    font-size: 0.74rem;
    cursor: pointer;
    margin-left: 0.3rem;
}
.msg-new-btn:hover { background: #4c6cff; border-color: #4c6cff; }
.msg-new-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.msg-foot-links { display: flex; gap: 0.25rem; flex-wrap: wrap; }

/* ---- /messages/bulk page ---- */
.smsbulk-page {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem 3rem;
    color: var(--text, #e6e9ef);
}
.smsbulk-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    padding-bottom: 0.75rem;
    margin-bottom: 1.25rem;
}
.smsbulk-head h1 { font-size: 1.25rem; margin: 0; }
.smsbulk-sub { color: rgba(255,255,255,0.55); font-size: 0.85rem; margin: 0.15rem 0 0; }
.smsbulk-sub a { color: rgba(255,255,255,0.7); }
.smsbulk-templates-link {
    color: rgba(180, 200, 255, 0.85);
    text-decoration: none;
    padding: 0.4rem 0.75rem;
    border: 1px solid rgba(180, 200, 255, 0.25);
    border-radius: 6px;
    font-size: 0.85rem;
}
.smsbulk-templates-link:hover { background: rgba(180,200,255,0.08); color: var(--white); }

.smsbulk-explainer {
    background: rgba(255, 184, 108, 0.08);
    border-left: 3px solid rgba(255, 184, 108, 0.55);
    padding: 0.75rem 0.9rem;
    border-radius: 4px;
    color: rgba(255,255,255,0.78);
    font-size: 0.85rem;
    margin-bottom: 1.25rem;
}
.smsbulk-explainer p { margin: 0 0 0.5rem; }
.smsbulk-explainer code {
    background: rgba(255,255,255,0.08);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    font-size: 0.78rem;
}
.smsbulk-warning {
    color: #ffb2c0;
    font-size: 0.82rem;
    margin-top: 0.45rem;
}
.smsbulk-template-peek summary {
    cursor: pointer;
    color: rgba(180, 200, 255, 0.85);
    font-size: 0.78rem;
}
.smsbulk-template-body {
    background: rgba(0,0,0,0.25);
    padding: 0.55rem 0.7rem;
    border-radius: 4px;
    font-size: 0.82rem;
    margin-top: 0.35rem;
    white-space: pre-wrap;
}

.smsbulk-section { margin-top: 1.25rem; }
.smsbulk-section-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.65rem;
    flex-wrap: wrap;
    gap: 0.6rem;
}
.smsbulk-section-head h2 { font-size: 0.95rem; margin: 0; }
.smsbulk-pill {
    background: rgba(148, 196, 255, 0.12);
    border: 1px solid rgba(148, 196, 255, 0.3);
    color: rgba(190, 215, 255, 0.95);
    border-radius: 9px;
    font-size: 0.7rem;
    padding: 0.05rem 0.45rem;
    margin-left: 0.35rem;
}
.smsbulk-controls { display: flex; gap: 0.5rem; align-items: center; }
.smsbulk-batch-label {
    font-size: 0.82rem;
    color: rgba(255,255,255,0.7);
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.smsbulk-batch-label select {
    background: rgba(0,0,0,0.25);
    color: rgba(255,255,255,0.95);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 4px;
    padding: 0.3rem 0.4rem;
    font: inherit;
    font-size: 0.85rem;
}
.smsbulk-send {
    background: var(--info);
    border: 1px solid var(--info);
    color: var(--white);
    padding: 0.45rem 1.1rem;
    border-radius: 5px;
    cursor: pointer;
    font: inherit;
    font-size: 0.88rem;
}
.smsbulk-send:hover { background: #4c6cff; }
.smsbulk-send:disabled { opacity: 0.55; cursor: not-allowed; }
.smsbulk-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}
.smsbulk-table th,
.smsbulk-table td {
    text-align: left;
    padding: 0.45rem 0.7rem;
    border-bottom: 1px solid rgba(255,255,255,0.05);
}
.smsbulk-table th {
    color: rgba(255,255,255,0.5);
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    font-weight: 600;
}
.smsbulk-cell-id { color: rgba(255,255,255,0.45); font-variant-numeric: tabular-nums; width: 80px; }
.smsbulk-cell-phone { font-variant-numeric: tabular-nums; color: rgba(255,255,255,0.8); }
.smsbulk-empty {
    padding: 1.2rem;
    text-align: center;
    color: rgba(255,255,255,0.5);
    border: 1px dashed rgba(255,255,255,0.12);
    border-radius: 8px;
}
.smsbulk-result-body {
    background: rgba(0,0,0,0.35);
    color: rgba(255,255,255,0.92);
    padding: 0.7rem 0.85rem;
    border-radius: 6px;
    font-size: 0.78rem;
    overflow-x: auto;
}
.smsbulk-result-summary {
    padding: 0.75rem 1rem;
    border-radius: 6px;
    margin-bottom: 0.6rem;
    font-size: 0.92rem;
    border: 1px solid rgba(255,255,255,0.08);
}
.smsbulk-result-summary.smsbulk-tone-ok {
    background: rgba(46, 213, 115, 0.12);
    border-color: rgba(46, 213, 115, 0.4);
    color: #c8f0d6;
}
.smsbulk-result-summary.smsbulk-tone-warn {
    background: rgba(255, 184, 108, 0.12);
    border-color: rgba(255, 184, 108, 0.4);
    color: #ffe1c5;
}
.smsbulk-result-summary.smsbulk-tone-muted {
    background: rgba(148, 196, 255, 0.06);
    color: rgba(255,255,255,0.7);
}
.smsbulk-result-summary strong { font-weight: 700; color: var(--white); }
.smsbulk-result-details {
    font-size: 0.78rem;
}
.smsbulk-result-details summary {
    cursor: pointer;
    color: rgba(180, 200, 255, 0.85);
    padding: 0.2rem 0;
    user-select: none;
}
.smsbulk-result-details summary:hover { color: var(--white); }

/* Fill-in form inside the main composer (matches msg-new-fillin styling
   so both surfaces feel like one continuous workflow). */
.msg-fillin {
    background: rgba(255, 184, 108, 0.07);
    border: 1px solid rgba(255, 184, 108, 0.32);
    border-radius: 6px;
    padding: 0.5rem 0.65rem;
    margin-bottom: 0.45rem;
}
.msg-fillin-head {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 213, 168, 0.95);
    margin-bottom: 0.4rem;
    font-weight: 700;
}
.msg-fillin-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0.4rem;
}
.msg-fillin-field {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.msg-fillin-label {
    font-size: 0.66rem;
    color: rgba(255,255,255,0.7);
}
.msg-fillin-input {
    background: rgba(0,0,0,0.3);
    color: rgba(255,255,255,0.95);
    border: 1px solid rgba(255, 184, 108, 0.35);
    border-radius: 4px;
    padding: 0.3rem 0.45rem;
    font: inherit;
    font-size: 0.8rem;
}
.msg-fillin-input:focus {
    outline: 1px solid rgba(255, 184, 108, 0.65);
    border-color: rgba(255, 184, 108, 0.65);
}

/* ---- /messages/automations page ---- */
.smsauto-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem 3rem;
    color: var(--text, #e6e9ef);
}
.smsauto-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    padding-bottom: 0.75rem;
    margin-bottom: 1rem;
}
.smsauto-head h1 { font-size: 1.25rem; margin: 0; }
.smsauto-sub { color: rgba(255,255,255,0.55); font-size: 0.85rem; margin: 0.15rem 0 0; }
.smsauto-sub a { color: rgba(255,255,255,0.7); }
.smsauto-new {
    background: var(--info);
    color: var(--white);
    padding: 0.45rem 0.85rem;
    border-radius: 6px;
    text-decoration: none;
    font-size: 0.85rem;
}
.smsauto-new:hover { background: #4c6cff; }

.smsauto-banner {
    background: rgba(255, 184, 108, 0.08);
    border-left: 3px solid rgba(255, 184, 108, 0.55);
    padding: 0.65rem 0.9rem;
    border-radius: 4px;
    color: rgba(255,255,255,0.78);
    font-size: 0.85rem;
    margin-bottom: 1.25rem;
}
.smsauto-banner code {
    background: rgba(255,255,255,0.08);
    padding: 0.05rem 0.3rem;
    border-radius: 3px;
    font-size: 0.78rem;
}
.smsauto-banner a {
    color: rgba(180, 200, 255, 0.85);
}

.smsauto-shell {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 1.5rem;
    align-items: start;
}
.smsauto-list {
    border-right: 1px solid rgba(255,255,255,0.06);
    padding-right: 1rem;
}
.smsauto-list ul { list-style: none; padding: 0; margin: 0; }
.smsauto-list-item { margin-bottom: 0.4rem; }
.smsauto-list-link {
    display: block;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    color: rgba(255,255,255,0.9);
    text-decoration: none;
}
.smsauto-list-link:hover { background: rgba(44,78,240,0.12); }
.smsauto-list-item.is-current .smsauto-list-link {
    background: rgba(44,78,240,0.2);
    border-color: rgba(44,78,240,0.55);
}
.smsauto-list-row1 {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.smsauto-list-name { font-weight: 600; font-size: 0.88rem; }
.smsauto-list-state {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.05rem 0.4rem;
    border-radius: 3px;
    background: rgba(255,255,255,0.06);
    color: rgba(255,255,255,0.6);
}
.smsauto-list-state.is-on {
    background: rgba(46, 213, 115, 0.2);
    color: #7be9a6;
}
.smsauto-list-row2 {
    display: flex;
    justify-content: space-between;
    font-size: 0.74rem;
    color: rgba(255,255,255,0.55);
    margin-top: 0.15rem;
}
.smsauto-list-row3 {
    color: rgba(255,255,255,0.7);
    font-size: 0.76rem;
    margin-top: 0.18rem;
}

.smsauto-empty {
    padding: 1.5rem 1rem;
    text-align: center;
    color: rgba(255,255,255,0.55);
    border: 1px dashed rgba(255,255,255,0.1);
    border-radius: 6px;
    font-size: 0.86rem;
}
.smsauto-empty a { color: rgba(180, 200, 255, 0.85); margin-left: 0.2rem; }

.smsauto-editor { padding-left: 0.25rem; }
.smsauto-field { margin-bottom: 0.9rem; }
.smsauto-field label {
    display: block;
    font-size: 0.74rem;
    color: rgba(255,255,255,0.6);
    margin-bottom: 0.25rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
.smsauto-field input[type="text"],
.smsauto-field select,
.smsauto-field textarea {
    width: 100%;
    background: rgba(255,255,255,0.04);
    color: var(--text, #e6e9ef);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 6px;
    padding: 0.55rem 0.65rem;
    font: inherit;
}
.smsauto-field textarea { min-height: 60px; resize: vertical; }
.smsauto-hint {
    font-size: 0.74rem;
    color: rgba(255,255,255,0.5);
    margin-top: 0.3rem;
}
.smsauto-hint a { color: rgba(180, 200, 255, 0.85); }
.smsauto-row { display: grid; grid-template-columns: 1.5fr 1fr; gap: 1rem; }

.smsauto-actions {
    margin-top: 1.2rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.smsauto-save {
    background: var(--info);
    border: 1px solid var(--info);
    color: var(--white);
    padding: 0.5rem 1.1rem;
    border-radius: 5px;
    cursor: pointer;
    font: inherit;
}
.smsauto-save:hover { background: #4c6cff; }
.smsauto-toggle,
.smsauto-delete {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.85);
    padding: 0.45rem 0.85rem;
    border-radius: 5px;
    cursor: pointer;
    font: inherit;
    font-size: 0.85rem;
}
.smsauto-toggle:hover { background: rgba(46, 213, 115, 0.2); border-color: rgba(46, 213, 115, 0.45); }
.smsauto-delete:hover { background: rgba(255, 93, 119, 0.18); border-color: rgba(255, 93, 119, 0.45); color: #ffb2c0; }
.smsauto-status { font-size: 0.82rem; color: rgba(255,255,255,0.6); margin-left: 0.4rem; }
.smsauto-status.is-ok { color: #6dcd86; }
.smsauto-status.is-error { color: #ff8aa0; }

/* ═════════════════════════════════════════════════════════════════════════
   /messages POLISH v2 — visual refresh.
   Additive overrides at end-of-file so they win the cascade against the
   original rules above. Targets the surfaces operators stare at most:
   bubbles, conversation cards, right context panel, composer, empty states.
   No layout changes — only visual treatment.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Message bubbles ──────────────────────────────────────────────
   Softer corners, subtle depth shadow, refined inbound contrast,
   calmer outbound gradient. Inbound + outbound now also have a
   slightly larger tail radius for a more modern chat-bubble feel. */
.msg-bubble-body {
    max-width: 78%;
    padding: 0.62rem 0.9rem;
    font-size: 0.88rem;
    line-height: 1.5;
    box-shadow: 0 1px 2px rgba(var(--shadow-rgb), 0.25);
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.msg-bubble-in .msg-bubble-body {
    background: linear-gradient(180deg, rgba(28, 42, 62, 0.92), rgba(22, 34, 52, 0.92));
    border: 1px solid rgba(148, 196, 255, 0.16);
    border-radius: 18px 18px 18px 6px;
}
.msg-bubble-out .msg-bubble-body {
    background: linear-gradient(135deg, rgba(44, 78, 240, 0.85), rgba(27, 92, 170, 0.85));
    border: 1px solid rgba(102, 161, 255, 0.4);
    border-radius: 18px 18px 6px 18px;
    color: #f1f5fc;
    box-shadow: 0 2px 8px rgba(44, 78, 240, 0.18);
}
.msg-bubble-row:hover .msg-bubble-body {
    box-shadow: 0 2px 10px rgba(var(--shadow-rgb), 0.32);
}
.msg-bubble-meta {
    margin-top: 2px;
    opacity: 0.85;
}
/* Subtle fade-in for poll-injected new bubbles (live updates). */
@keyframes msgBubbleIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.msg-bubble-row { animation: msgBubbleIn 0.18s ease-out; }

/* Classification stripes: tighter, more visible. */
.msg-bubble-row.cls-opt_in  .msg-bubble-body { border-left-width: 4px; border-left-color: rgba(46, 213, 115, 0.7); }
.msg-bubble-row.cls-opt_out .msg-bubble-body { border-left-width: 4px; border-left-color: rgba(255, 93, 119, 0.7); }
.msg-bubble-row.cls-help    .msg-bubble-body { border-left-width: 4px; border-left-color: rgba(255, 184, 108, 0.7); }

/* ── Conversation cards in sidebar ─────────────────────────────── */
.msg-convo {
    padding: 0.78rem 0.85rem 0.82rem;
    border-bottom-color: rgba(148, 196, 255, 0.05);
    border-left-width: 3px;
}
.msg-convo:hover {
    background: rgba(148, 196, 255, 0.05);
}
.msg-convo.is-active {
    background: linear-gradient(90deg, rgba(44, 78, 240, 0.18), rgba(44, 78, 240, 0.02));
    border-left-color: #4c6cff;
}
.msg-convo.is-active .msg-convo-name { color: var(--white); }
.msg-convo.has-unread .msg-convo-time { color: var(--accent); font-weight: 700; }
.msg-convo-last {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.55);
    line-height: 1.35;
    margin-top: 0.15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
}
.msg-convo.has-unread .msg-convo-last { color: rgba(255, 255, 255, 0.85); }

/* Cleaner needs-response treatment — keep the pulse but soften it. */
.msg-convo.needs-response::before {
    width: 3px;
    top: 14%;
    bottom: 14%;
    height: auto;
    transform: none;
    background: linear-gradient(180deg, var(--danger-strong), #ff8aa0);
    box-shadow: 0 0 8px rgba(255, 93, 119, 0.45);
}

/* Avatar with cleaner gradient + larger letter */
.msg-avatar {
    width: 40px;
    height: 40px;
    background: linear-gradient(135deg, rgba(44, 78, 240, 0.4), rgba(102, 214, 255, 0.25));
    border-color: rgba(148, 196, 255, 0.3);
}
.msg-avatar-letter { font-size: 0.95rem; }
.msg-unread-dot {
    background: var(--danger-strong);
    color: var(--white);
    box-shadow: 0 0 0 2px #0a131e, 0 0 6px rgba(255, 93, 119, 0.7);
    font-size: 0.6rem;
}

/* ── Thread header ────────────────────────────────────────────── */
.msg-thread-head {
    padding: 0.8rem 1rem;
    border-bottom: 1px solid rgba(148, 196, 255, 0.1);
    background: linear-gradient(180deg, rgba(13, 19, 30, 0.9), rgba(9, 14, 22, 0.95));
}
.msg-thread-name { font-size: 0.96rem; font-weight: 700; color: var(--white); letter-spacing: -0.005em; }
.msg-thread-phone {
    font-size: 0.74rem;
    color: rgba(255, 255, 255, 0.55);
    font-variant-numeric: tabular-nums;
    margin-top: 0.1rem;
}
.msg-context-toggle {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.75);
    border-radius: 6px;
    width: 28px;
    height: 28px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease;
}
.msg-context-toggle:hover { background: rgba(255, 255, 255, 0.1); color: var(--white); }
.msg-context-toggle.is-on { background: rgba(44, 78, 240, 0.2); border-color: rgba(44, 78, 240, 0.5); color: var(--white); }
.msg-context-toggle-arrow { font-size: 1rem; line-height: 1; }

/* ── Composer ─────────────────────────────────────────────────── */
.msg-composer {
    border-top: 1px solid rgba(148, 196, 255, 0.1);
    background: linear-gradient(180deg, rgba(9, 14, 22, 0.85), rgba(7, 11, 18, 0.95));
    padding: 0.75rem 0.85rem;
}
.msg-input {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 8px;
    padding: 0.55rem 0.75rem;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.msg-input:focus {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(44, 78, 240, 0.6);
    box-shadow: 0 0 0 3px rgba(44, 78, 240, 0.12);
    outline: none;
}
.msg-send {
    background: linear-gradient(180deg, #4c6cff, var(--info));
    border: 1px solid var(--info);
    color: var(--white);
    padding: 0.45rem 1.1rem;
    border-radius: 8px;
    font-weight: 600;
    font-size: 0.86rem;
    height: 36px;
    cursor: pointer;
    transition: background 0.12s ease, transform 0.08s ease;
    box-shadow: 0 2px 6px rgba(44, 78, 240, 0.3);
}
.msg-send:hover { background: linear-gradient(180deg, #6580ff, #3a5cf5); transform: translateY(-1px); }
.msg-send:active { transform: translateY(0); }
.msg-send:disabled {
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.4);
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
}

/* ── Right context panel: section cards ─────────────────────── */
.msg-context {
    padding: 1rem;
    background: rgba(9, 14, 22, 0.95);
    border-left: 1px solid rgba(148, 196, 255, 0.1);
}
.msg-context-block {
    background: rgba(255, 255, 255, 0.025);
    border: 1px solid rgba(148, 196, 255, 0.08);
    border-radius: 8px;
    padding: 0.85rem 0.95rem;
    margin-bottom: 0.65rem;
}
.msg-context-block.msg-context-divided {
    border-top-width: 1px;
    margin-top: 0;
    padding-top: 0.85rem;
}
.msg-context-label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.45);
    font-weight: 700;
    margin-bottom: 0.45rem;
}
.msg-context-value-strong {
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--white);
    line-height: 1.35;
}
.msg-context-value {
    font-size: 0.86rem;
    color: rgba(255, 255, 255, 0.85);
}
.msg-context-sub {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.55);
    margin-top: 0.2rem;
    line-height: 1.4;
}

/* Status pill: more prominent, with subtle glow on confirmed/won. */
.msg-status-pill {
    font-size: 0.7rem;
    padding: 0.2rem 0.6rem;
    font-weight: 800;
}
.msg-status-confirmed { box-shadow: 0 0 0 1px rgba(46, 213, 115, 0.3); }
.msg-status-won       { box-shadow: 0 0 12px rgba(46, 213, 115, 0.25); }

/* Quick action links: more button-like */
.msg-action-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.45rem 0.7rem;
    margin-top: 0.3rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(148, 196, 255, 0.15);
    border-radius: 6px;
    color: rgba(190, 215, 255, 0.95);
    text-decoration: none;
    font-size: 0.82rem;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.msg-action-link:hover {
    background: rgba(44, 78, 240, 0.12);
    border-color: rgba(44, 78, 240, 0.4);
    color: var(--white);
}
.msg-action-arrow { opacity: 0.7; font-size: 0.85rem; }

/* ── Empty states ─────────────────────────────────────────────── */
.msg-empty-thread {
    padding: 2.5rem 1.5rem;
    text-align: center;
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.88rem;
    line-height: 1.5;
    border: 1px dashed rgba(148, 196, 255, 0.15);
    border-radius: 10px;
    margin: 2rem auto;
    max-width: 420px;
    background: rgba(255, 255, 255, 0.015);
}
.msg-empty-thread strong {
    display: block;
    margin-bottom: 0.6rem;
    color: rgba(255, 255, 255, 0.95);
    font-size: 1rem;
}

/* ── Sidebar footer: cleaner separation ─────────────────────── */
.msg-side-foot {
    padding: 0.65rem 0.85rem 0.75rem;
    border-top: 1px solid rgba(148, 196, 255, 0.1);
    background: rgba(7, 11, 18, 0.6);
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.msg-from-line {
    font-size: 0.7rem;
    color: rgba(255, 255, 255, 0.4);
    font-variant-numeric: tabular-nums;
}
.msg-new-btn {
    padding: 0.5rem 0.8rem;
    border-radius: 6px;
    font-size: 0.82rem;
    font-weight: 600;
    margin-left: 0;
    box-shadow: 0 2px 6px rgba(44, 78, 240, 0.3);
}
.msg-foot-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    border-top: 1px dashed rgba(148, 196, 255, 0.08);
    padding-top: 0.5rem;
}
.msg-foot-link {
    flex: 1 1 auto;
    text-align: center;
    font-size: 0.72rem;
    padding: 0.32rem 0.4rem;
    border-color: rgba(148, 196, 255, 0.15);
}

/* ── Health page: bigger metrics, prettier sparkline ──────── */
.smshealth-metric-val { font-size: 1.85rem; letter-spacing: -0.01em; }
.smshealth-card {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02));
    border-color: rgba(148, 196, 255, 0.12);
}
.smshealth-spark-stack { height: 78px; }
.smshealth-spark-bar { border-radius: 3px; }
.smshealth-spark-out {
    background: linear-gradient(180deg, #6580ff, var(--info));
    box-shadow: inset 0 -1px 0 rgba(0,0,0,0.2);
}
.smshealth-spark-in {
    background: linear-gradient(180deg, rgba(46, 213, 115, 0.95), rgba(46, 213, 115, 0.6));
    box-shadow: inset 0 -1px 0 rgba(0,0,0,0.2);
}
.smshealth-spark-total { font-weight: 700; }

/* ── Templates page: bring up to par ─────────────────────── */
.smstpl-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem 3rem;
}
.smstpl-list a { color: rgba(180, 200, 255, 0.85); text-decoration: none; }
.smstpl-list a:hover { color: var(--white); }

/* ── /messages templates dropdown chips refresh ───────────── */
.msg-template-row {
    border-radius: 8px;
    transition: background 0.12s ease, border-color 0.12s ease, transform 0.08s ease;
}
.msg-template-row:hover { transform: translateX(2px); }
.msg-template-name { font-size: 0.9rem; }
.msg-template-preview { font-size: 0.8rem; line-height: 1.4; }

/* ── Misc: smoother scrollbars + subtle text selection ──── */
.msg-shell *::-webkit-scrollbar { width: 8px; height: 8px; }
.msg-shell *::-webkit-scrollbar-thumb {
    background: rgba(148, 196, 255, 0.18);
    border-radius: 999px;
}
.msg-shell *::-webkit-scrollbar-thumb:hover {
    background: rgba(148, 196, 255, 0.3);
}
.msg-bubble-body::selection { background: rgba(44, 78, 240, 0.4); color: var(--white); }

/* =========================================================================
   /settings notification device control (2026-05-20)
   --------------------------------------------------------------------------
   Per-device, per-category notification preferences. List one card per
   push_subscriptions row owned by the current user. Each card has a label
   input (editable), a master is_enabled toggle, a per-category checkbox
   grid, and Test/Remove action buttons. Layered into the existing
   .panel#notifications section in workspace/settings.php.
   ========================================================================= */
.notif-devices {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
}
.notif-devices-h {
    margin: 0;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
    opacity: 0.85;
}
.notif-devices-intro {
    margin: 0;
    line-height: 1.4;
}

.notif-device {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.65rem 0.85rem;
    background: rgba(12, 18, 28, 0.5);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.notif-device-head {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex-wrap: wrap;
}
.notif-device-label-input {
    flex: 1 1 12rem;
    min-width: 8rem;
    padding: 0.35rem 0.55rem;
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 6px;
    background: rgba(8, 13, 21, 0.6);
    color: var(--text);
    font-size: 0.95rem;
    font-weight: 600;
}
.notif-device-label-input:focus {
    border-color: rgba(102, 214, 255, 0.55);
    outline: none;
}
.notif-device-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.55rem;
    border: 1px solid rgba(148, 196, 255, 0.2);
    border-radius: 6px;
    cursor: pointer;
    background: rgba(8, 13, 21, 0.45);
    font-size: 0.78rem;
    color: var(--muted);
    font-weight: 600;
}
.notif-device-toggle input {
    accent-color: var(--accent);
}
.notif-device-toggle:has(input:checked) {
    border-color: rgba(46, 204, 113, 0.5);
    background: rgba(46, 204, 113, 0.08);
    color: var(--success);
}
.notif-device-toggle:not(:has(input:checked)) {
    border-color: rgba(255, 87, 87, 0.4);
    color: #ffaaaa;
    background: rgba(255, 87, 87, 0.05);
}

.notif-device-actions {
    display: inline-flex;
    gap: 0.35rem;
    margin-left: auto;
}
.notif-device-actions .btn {
    padding: 0.3rem 0.7rem;
    font-size: 0.78rem;
}
.notif-device-remove {
    color: #ffaaaa;
}

.notif-device-meta {
    margin: 0;
    font-size: 0.72rem;
    line-height: 1.3;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.notif-device-err {
    color: #ffaaaa;
}

.notif-device-categories {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: 0.3rem 0.6rem;
    margin-top: 0.15rem;
    padding-top: 0.5rem;
    border-top: 1px dashed rgba(148, 196, 255, 0.08);
}
.notif-cat {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.4rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--text);
    transition: background 0.12s ease;
}
.notif-cat:hover {
    background: rgba(102, 214, 255, 0.06);
}
.notif-cat input {
    accent-color: var(--accent);
    cursor: pointer;
}
.notif-cat:not(:has(input:checked)) {
    color: var(--muted);
    opacity: 0.7;
}

.notif-device-status {
    min-height: 1.1em;
    margin: 0;
    font-size: 0.72rem;
}

@media (max-width: 600px) {
    .notif-device-head {
        gap: 0.4rem;
    }
    .notif-device-label-input {
        flex: 1 1 100%;
    }
    .notif-device-actions {
        margin-left: 0;
    }
    .notif-device-categories {
        grid-template-columns: 1fr;
    }
}

/* =========================================================================
   /settings polish (2026-05-20)
   --------------------------------------------------------------------------
   Hero with avatar + identity, sticky tabs with scroll-spy, section rhythm
   (card spacing + accent headings), card-style theme picker, mobile.
   ========================================================================= */

/* ---- Hero ------------------------------------------------------------- */
.settings-hero {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.2rem;
    padding: 1rem 1.2rem;
    margin-bottom: 0.85rem;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(18, 28, 43, 0.85), rgba(13, 20, 31, 0.7));
    box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.18);
}
.settings-hero-identity {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    min-width: 0;
}
.settings-hero-avatar {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 999px;
    background: linear-gradient(135deg, rgba(102, 214, 255, 0.35), rgba(140, 188, 255, 0.25));
    border: 1px solid rgba(102, 214, 255, 0.45);
    color: var(--text);
    font-weight: 800;
    font-size: 1.35rem;
    letter-spacing: 0.02em;
}
.settings-hero-name {
    min-width: 0;
}
.settings-hero-name h1 {
    margin: 0;
    font-size: 1.45rem;
    font-weight: 800;
    color: var(--text);
    letter-spacing: -0.01em;
    line-height: 1.15;
}
.settings-hero-sub {
    margin: 0.2rem 0 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.8rem;
    color: var(--muted);
}
.settings-hero-username {
    font-variant-numeric: tabular-nums;
}
.settings-hero-role {
    display: inline-flex;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    border: 1px solid rgba(148, 196, 255, 0.25);
    background: rgba(18, 28, 43, 0.6);
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}
.settings-hero-role-admin {
    border-color: rgba(255, 191, 0, 0.55);
    background: rgba(255, 191, 0, 0.12);
    color: var(--warning);
}
.settings-hero-tagline {
    margin: 0;
    font-size: 0.85rem;
    color: var(--muted);
    text-align: right;
    flex: 0 0 auto;
}

/* ---- Sticky tabs ------------------------------------------------------ */
.settings-tabs {
    position: sticky;
    top: 0;
    z-index: 6;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    padding: 0.5rem 0.6rem;
    margin: 0 0 0.85rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(15, 22, 34, 0.96), rgba(13, 20, 31, 0.95));
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 12px rgba(var(--shadow-rgb), 0.2);
}
.settings-tab {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.75rem;
    border-radius: 999px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--muted);
    text-decoration: none;
    font-size: 0.82rem;
    font-weight: 600;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.settings-tab:hover {
    color: var(--text);
    background: rgba(102, 214, 255, 0.08);
}
.settings-tab.is-active {
    color: var(--accent);
    background: rgba(102, 214, 255, 0.12);
    border-color: rgba(102, 214, 255, 0.4);
}

/* ---- Section cards ---------------------------------------------------- */
.settings-card {
    margin-bottom: 0.85rem;
    /* scroll-margin so smooth-scroll lands the heading below the sticky
       tab bar instead of hidden under it. Tabs are ~50px tall + 8px gap. */
    scroll-margin-top: 70px;
}
.settings-card-head {
    margin-bottom: 0.75rem;
    padding-bottom: 0.55rem;
    border-bottom: 1px solid rgba(102, 214, 255, 0.16);
}
.settings-card-head h2 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: -0.005em;
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
}
.settings-card-sub {
    margin: 0.25rem 0 0;
    font-size: 0.82rem;
    line-height: 1.4;
    color: var(--muted);
}
.settings-card-badge {
    display: inline-flex;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    border: 1px solid rgba(255, 191, 0, 0.55);
    background: rgba(255, 191, 0, 0.12);
    color: var(--warning);
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.settings-card-section {
    padding: 0.5rem 0;
    margin-top: 0.4rem;
}
.settings-card-section h3 {
    margin: 0 0 0.25rem;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.005em;
}
.settings-link {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.4);
}
.settings-link:hover {
    border-bottom-style: solid;
}

/* ---- PWA install: bottom-toast banner + /settings card states ----------- */
.pwa-install-banner {
    position: fixed;
    left: 50%;
    bottom: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    z-index: 9000;
    display: flex;
    align-items: center;
    gap: 14px;
    width: max-content;
    max-width: min(92vw, 460px);
    padding: 12px 14px;
    border: 1px solid rgba(102, 214, 255, 0.40);
    border-radius: 14px;
    background: linear-gradient(160deg, rgba(20, 31, 47, 0.97), rgba(13, 20, 31, 0.97));
    box-shadow: 0 20px 48px rgba(var(--shadow-rgb), 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.05);
    color: var(--text);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.pwa-install-banner[hidden] { display: none; }
/* When the Phase-2 "Update available" toast (#cwdb-update-toast, z 99999,
   bottom-center) is also showing, lift the install banner above it so the two
   bottom toasts stack instead of overlapping. Pure CSS (:has) — degrades to the
   prior overlap on engines without :has, and only the rare post-deploy +
   install-eligible + not-dismissed window ever triggers both at once. */
body:has(#cwdb-update-toast) .pwa-install-banner {
    bottom: calc(84px + env(safe-area-inset-bottom, 0px));
}
.pwa-install-banner-icon {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: rgba(102, 214, 255, 0.14);
    color: var(--accent);
    font-size: 18px;
}
.pwa-install-banner-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    line-height: 1.3;
}
.pwa-install-banner-text strong { font-size: 0.9rem; font-weight: 700; }
.pwa-install-banner-text span { font-size: 0.78rem; color: var(--muted); }
.pwa-install-banner-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}
.pwa-install-banner .btn { min-height: 44px; white-space: nowrap; }
@media (max-width: 520px) {
    .pwa-install-banner { flex-wrap: wrap; width: auto; }
    .pwa-install-banner-actions { width: 100%; }
    .pwa-install-banner-actions .btn { flex: 1; }
}

.pwa-install-states { display: flex; flex-direction: column; gap: 12px; }
.pwa-install-states > [hidden] { display: none; }
.pwa-install-state-ok {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid rgba(34, 197, 94, 0.40);
    background: rgba(34, 197, 94, 0.10);
}
.pwa-install-state-icon {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: rgba(34, 197, 94, 0.25);
    color: #7ee2a3;
    font-weight: 700;
    font-size: 13px;
}
.pwa-ios-steps {
    margin: 10px 0 0;
    padding-left: 1.2rem;
    color: var(--muted);
    font-size: 0.82rem;
    line-height: 1.6;
}
.pwa-ios-steps[hidden] { display: none; }
.pwa-ios-steps strong { color: var(--text); }

/* ---- Theme picker (card-style) --------------------------------------- */
.theme-picker {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.7rem;
    margin-bottom: 0.85rem;
}
.theme-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    padding: 0.55rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: rgba(8, 13, 21, 0.45);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.08s ease;
}
.theme-card:hover {
    border-color: rgba(102, 214, 255, 0.4);
    background: rgba(8, 13, 21, 0.6);
}
.theme-card.is-active {
    border-color: rgba(102, 214, 255, 0.7);
    background: rgba(102, 214, 255, 0.07);
    box-shadow: 0 0 0 1px rgba(102, 214, 255, 0.3);
}
.theme-card input[type="radio"] {
    /* Hide the actual radio; the whole card label is the click target. */
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
}
.theme-card-preview {
    height: 5rem;
    border-radius: 6px;
    border: 1px solid rgba(148, 196, 255, 0.12);
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.4rem;
}
.theme-card-preview-dark { background: linear-gradient(180deg, #0c121c, #060a12); }
.theme-card-preview-light { background: linear-gradient(180deg, #f5f7fb, #dde3eb); }
.theme-card-preview-auto {
    flex-direction: row;
    padding: 0;
    gap: 0;
}
.theme-card-preview-half {
    flex: 1;
    height: 100%;
}
.theme-card-preview-half-dark { background: linear-gradient(180deg, #0c121c, #060a12); }
.theme-card-preview-half-light { background: linear-gradient(180deg, #f5f7fb, #dde3eb); }
.theme-card-preview-bar {
    display: block;
    height: 0.5rem;
    width: 100%;
    border-radius: 2px;
}
.theme-card-preview-block {
    display: block;
    height: 1.2rem;
    width: 60%;
    border-radius: 3px;
}
.theme-card-preview-line {
    display: block;
    height: 0.35rem;
    width: 90%;
    border-radius: 999px;
}
.theme-card-preview-line.short { width: 50%; }

.theme-card-preview-dark .theme-card-preview-bar { background: rgba(102, 214, 255, 0.65); }
.theme-card-preview-dark .theme-card-preview-block { background: rgba(102, 214, 255, 0.18); }
.theme-card-preview-dark .theme-card-preview-line { background: rgba(255, 255, 255, 0.15); }

.theme-card-preview-light .theme-card-preview-bar { background: #4f7ff7; }
.theme-card-preview-light .theme-card-preview-block { background: rgba(79, 127, 247, 0.12); }
.theme-card-preview-light .theme-card-preview-line { background: rgba(20, 30, 50, 0.18); }

.theme-card-meta {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}
.theme-card-name {
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--text);
}
.theme-card-hint {
    font-size: 0.7rem;
    color: var(--muted);
}
.theme-card-check {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 999px;
    background: var(--accent);
    color: #0a0e14;
    font-weight: 800;
    font-size: 0.78rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transform: scale(0.7);
    transition: opacity 0.12s ease, transform 0.12s ease;
}
.theme-card.is-active .theme-card-check {
    opacity: 1;
    transform: scale(1);
}
.theme-picker-actions {
    display: flex;
    justify-content: flex-end;
}

/* ---- Mobile (≤ 600px) ------------------------------------------------- */
@media (max-width: 600px) {
    .settings-hero {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }
    .settings-hero-tagline {
        text-align: left;
    }
    .settings-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding: 0.45rem 0.5rem;
        gap: 0.3rem;
        -webkit-overflow-scrolling: touch;
    }
    .settings-tab {
        flex: 0 0 auto;
        white-space: nowrap;
    }
    .theme-picker {
        grid-template-columns: 1fr;
    }
}

/* JS theme-card click handler updates state via the underlying radio
   input + .is-active class. Inline below the script also re-syncs on
   form submit to be sure. */

/* =========================================================================
   SmsAutomation conditional builder (2026-05-20)
   --------------------------------------------------------------------------
   Renders inside /messages/automations editor. Tree of AND/OR groups +
   predicates. Pure DOM render-from-JSON via the IIFE in the template.
   ========================================================================= */
.smsauto-conditions {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.55rem 0.7rem;
    background: rgba(8, 13, 21, 0.45);
}
.cond-group {
    border: 1px dashed rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    padding: 0.45rem 0.55rem;
    margin: 0.4rem 0;
    background: rgba(12, 18, 28, 0.25);
}
.cond-group.is-root {
    border: none;
    padding: 0;
    margin: 0;
    background: transparent;
}
.cond-group-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.35rem;
}
.cond-op {
    flex: 0 0 auto;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.5);
    background: rgba(102, 214, 255, 0.12);
    color: var(--accent);
    font-weight: 800;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    cursor: pointer;
}
.cond-op:hover { background: rgba(102, 214, 255, 0.2); }
.cond-group-hint {
    font-size: 0.72rem;
    color: var(--muted);
    flex: 1 1 auto;
}
.cond-group-actions {
    display: inline-flex;
    gap: 0.3rem;
}
.cond-group-actions button {
    padding: 0.18rem 0.5rem;
    font-size: 0.72rem;
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 6px;
    background: rgba(18, 28, 43, 0.5);
    color: var(--text);
    cursor: pointer;
}
.cond-group-actions button:hover { border-color: rgba(102, 214, 255, 0.55); }
.cond-children {
    padding-left: 0.85rem;
    border-left: 2px solid rgba(102, 214, 255, 0.12);
    margin-left: 0.25rem;
}
.cond-group.is-root > .cond-children {
    padding-left: 0;
    border-left: none;
    margin-left: 0;
}
.cond-empty {
    margin: 0.2rem 0;
    font-size: 0.74rem;
    color: var(--muted);
    font-style: italic;
}
.cond-predicate {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin: 0.35rem 0;
    padding: 0.3rem 0.4rem;
    border: 1px solid rgba(148, 196, 255, 0.1);
    border-radius: 6px;
    background: rgba(18, 28, 43, 0.45);
}
.cond-predicate select,
.cond-predicate input {
    padding: 0.25rem 0.45rem;
    border: 1px solid rgba(148, 196, 255, 0.25);
    border-radius: 5px;
    background: rgba(8, 13, 21, 0.7);
    color: var(--text);
    font-size: 0.82rem;
}
.cond-predicate .cond-field { min-width: 12rem; flex: 1 1 12rem; }
.cond-predicate .cond-cmp   { min-width: 6rem;  flex: 0 0 auto; }
.cond-predicate .cond-val   { min-width: 6rem;  flex: 1 1 6rem; }
.cond-remove {
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    border: 1px solid rgba(248, 113, 113, 0.4);
    border-radius: 4px;
    background: transparent;
    color: #ffaaaa;
    cursor: pointer;
    font-size: 0.95rem;
    line-height: 1;
}
.cond-remove:hover { background: rgba(248, 113, 113, 0.15); }

/* Test-eval card */
.smsauto-testeval-row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.smsauto-testeval-row input {
    width: 8rem;
}
.smsauto-testeval-row button {
    padding: 0.4rem 0.85rem;
    border: 1px solid rgba(102, 214, 255, 0.55);
    border-radius: 6px;
    background: rgba(102, 214, 255, 0.1);
    color: var(--accent);
    cursor: pointer;
    font-weight: 600;
}
.smsauto-testeval-result {
    margin-top: 0.5rem;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    background: rgba(8, 13, 21, 0.6);
    border-left: 3px solid var(--muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    white-space: pre-wrap;
    color: var(--text);
}
.smsauto-testeval-result.is-ok    { border-left-color: var(--success); }
.smsauto-testeval-result.is-warn  { border-left-color: var(--warning); }
.smsauto-testeval-result.is-error { border-left-color: #ffaaaa; }

/* ═════════════════════════════════════════════════════════════════════════
   /messages/automations POLISH v1 — visual refresh (2026-05-20)
   Additive overrides win the cascade. The page was hard to scan: muted
   uppercase labels, no editor card framing, low-contrast inputs, weak empty
   state, hard-coded blue save button. This block tightens hierarchy, frames
   the editor like the rest of the app, and bumps every label to a legible
   sentence-case weight. No JS or markup changes required.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Page frame ──────────────────────────────────────────────── */
.smsauto-page {
    max-width: 1240px;
    padding: 1.5rem 1.75rem 3.5rem;
}
.smsauto-head {
    border-bottom: 1px solid var(--border);
    padding-bottom: 1rem;
    margin-bottom: 1.25rem;
    gap: 1rem;
}
.smsauto-head h1 {
    font-size: 1.55rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
}
.smsauto-sub {
    color: var(--muted);
    font-size: 0.86rem;
    margin-top: 0.35rem;
}
.smsauto-sub a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smsauto-sub a:hover { border-bottom-style: solid; }

/* Header actions row — Pending queue link + New automation button */
.smsauto-head-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.smsauto-activitylink {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 0.95rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    font-size: 0.86rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsauto-activitylink:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.45);
    transform: translateY(-1px);
}
.smsauto-activitylink::before {
    content: "📊";
    font-size: 0.95rem;
    line-height: 1;
}

.smsauto-queuelink {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.95rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    font-size: 0.86rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsauto-queuelink:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.45);
    transform: translateY(-1px);
}
.smsauto-queuelink.has-pending {
    border-color: rgba(255, 208, 102, 0.5);
    color: var(--warning);
    background: linear-gradient(180deg, rgba(255, 208, 102, 0.1), rgba(255, 208, 102, 0.03));
}
.smsauto-queuelink.has-pending:hover {
    background: linear-gradient(180deg, rgba(255, 208, 102, 0.18), rgba(255, 208, 102, 0.06));
    border-color: rgba(255, 208, 102, 0.75);
}
.smsauto-queue-badge {
    display: inline-block;
    min-width: 1.4rem;
    padding: 0.05rem 0.45rem;
    text-align: center;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.65);
    font-size: 0.74rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.smsauto-queuelink.has-pending .smsauto-queue-badge {
    background: rgba(255, 208, 102, 0.25);
    color: var(--warning);
}

/* "+ New automation" button — promote to accent fill */
.smsauto-new {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.18), rgba(102, 214, 255, 0.08));
    color: var(--accent);
    border: 1px solid rgba(102, 214, 255, 0.45);
    padding: 0.55rem 1rem;
    border-radius: 8px;
    font-size: 0.86rem;
    font-weight: 600;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsauto-new:hover {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.28), rgba(102, 214, 255, 0.14));
    border-color: rgba(102, 214, 255, 0.7);
    transform: translateY(-1px);
}

/* ── Banner ──────────────────────────────────────────────────── */
.smsauto-banner {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.07), rgba(102, 214, 255, 0.03));
    border: 1px solid rgba(102, 214, 255, 0.22);
    border-left: 3px solid var(--accent);
    color: var(--text);
    font-size: 0.88rem;
    line-height: 1.55;
    padding: 0.8rem 1rem;
    border-radius: 8px;
    margin-bottom: 1.5rem;
}
.smsauto-banner strong { color: var(--accent); }
.smsauto-banner code {
    background: rgba(8, 13, 21, 0.7);
    border: 1px solid rgba(148, 196, 255, 0.18);
    padding: 0.08rem 0.4rem;
    border-radius: 4px;
    font-size: 0.78rem;
    color: var(--text);
}
.smsauto-banner a { color: var(--accent); text-decoration: underline; text-decoration-color: rgba(102, 214, 255, 0.45); }
.smsauto-banner a:hover { text-decoration-color: var(--accent); }

/* ── Shell layout: list (left) + editor (right) ──────────────── */
.smsauto-shell {
    gap: 1.5rem;
    grid-template-columns: 300px 1fr;
}

/* ── Rules list ──────────────────────────────────────────────── */
.smsauto-list {
    border-right: none;
    padding-right: 0;
}
.smsauto-list-item { margin-bottom: 0.5rem; }
.smsauto-list-link {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.7rem 0.85rem;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsauto-list-link:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.35);
    transform: translateY(-1px);
}
.smsauto-list-item.is-current .smsauto-list-link {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.14), rgba(102, 214, 255, 0.06));
    border-color: var(--accent);
    box-shadow: 0 0 0 1px rgba(102, 214, 255, 0.2);
}
.smsauto-list-name {
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
}
.smsauto-list-state {
    font-size: 0.65rem;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
    background: rgba(255,255,255,0.07);
    color: var(--muted);
    font-weight: 700;
}
.smsauto-list-state.is-on {
    background: rgba(46, 213, 115, 0.18);
    color: #7be9a6;
    box-shadow: inset 0 0 0 1px rgba(46, 213, 115, 0.35);
}
.smsauto-list-row2 {
    font-size: 0.76rem;
    color: var(--muted);
    margin-top: 0.3rem;
    gap: 0.5rem;
}
.smsauto-list-trigger {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.smsauto-list-delay {
    flex: 0 0 auto;
    color: var(--accent);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.smsauto-list-row3 {
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.78rem;
    margin-top: 0.3rem;
    padding-top: 0.3rem;
    border-top: 1px dashed rgba(255, 255, 255, 0.07);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Empty state ─────────────────────────────────────────────── */
.smsauto-empty {
    padding: 2rem 1.25rem;
    background: var(--surface);
    border: 1px dashed rgba(148, 196, 255, 0.22);
    border-radius: 10px;
    color: var(--muted);
    font-size: 0.88rem;
    line-height: 1.6;
}
.smsauto-empty a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
    margin-left: 0.35rem;
}
.smsauto-empty a:hover { text-decoration: underline; }

/* ── Editor card ─────────────────────────────────────────────── */
.smsauto-editor {
    padding: 1.25rem 1.35rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-sm, 0 6px 14px rgba(var(--shadow-rgb), 0.34));
}

/* ── Field labels — sentence case, accent tint, weight 600 ──── */
.smsauto-field { margin-bottom: 1.05rem; }
.smsauto-field label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0.4rem;
    text-transform: none;
    letter-spacing: 0;
}

/* ── Inputs — refined contrast + accent focus ring ───────────── */
.smsauto-field input[type="text"],
.smsauto-field input[type="number"],
.smsauto-field select,
.smsauto-field textarea {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    padding: 0.6rem 0.75rem;
    font-size: 0.92rem;
    color: var(--text);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.smsauto-field input[type="text"]:hover,
.smsauto-field input[type="number"]:hover,
.smsauto-field select:hover,
.smsauto-field textarea:hover {
    border-color: rgba(148, 196, 255, 0.32);
}
.smsauto-field input[type="text"]:focus,
.smsauto-field input[type="number"]:focus,
.smsauto-field select:focus,
.smsauto-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.15);
    background: var(--surface);
}
.smsauto-field textarea { min-height: 72px; font-family: inherit; }
.smsauto-field select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%2366d6ff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.65rem center;
    background-size: 14px;
    padding-right: 2rem;
}

/* ── Hint text ───────────────────────────────────────────────── */
.smsauto-hint {
    font-size: 0.78rem;
    color: var(--muted);
    margin-top: 0.4rem;
    line-height: 1.5;
}
.smsauto-hint a { color: var(--accent); text-decoration: none; border-bottom: 1px dashed rgba(102, 214, 255, 0.35); }
.smsauto-hint a:hover { border-bottom-style: solid; }

/* ── Row layout for trigger + delay ──────────────────────────── */
.smsauto-row { grid-template-columns: 1.5fr 1fr; gap: 1.1rem; }

/* ── Conditions builder — clearer nesting ────────────────────── */
.smsauto-conditions {
    border: 1px solid rgba(148, 196, 255, 0.18);
    background: var(--bg);
    padding: 0.75rem 0.85rem;
    border-radius: 10px;
}
.cond-group {
    border: 1px solid rgba(148, 196, 255, 0.15);
    background: rgba(148, 196, 255, 0.03);
    border-radius: 9px;
    padding: 0.6rem 0.7rem;
    margin: 0.5rem 0;
}
/* Alternate nested-group background for depth perception */
.cond-group .cond-group {
    background: rgba(148, 196, 255, 0.05);
    border-color: rgba(148, 196, 255, 0.18);
}
.cond-group .cond-group .cond-group {
    background: rgba(148, 196, 255, 0.07);
}
.cond-group.is-root {
    border: none;
    background: transparent;
    padding: 0;
    margin: 0;
}
.cond-group-head {
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}
.cond-op {
    padding: 0.25rem 0.75rem;
    border-radius: 999px;
    border: 1px solid rgba(102, 214, 255, 0.55);
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.22), rgba(102, 214, 255, 0.12));
    color: var(--accent);
    font-weight: 800;
    font-size: 0.74rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transition: background 0.15s ease, transform 0.1s ease;
}
.cond-op:hover {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.3), rgba(102, 214, 255, 0.18));
    transform: translateY(-1px);
}
.cond-group-hint {
    font-size: 0.78rem;
    color: var(--muted);
    font-style: italic;
}
.cond-group-actions button {
    padding: 0.25rem 0.65rem;
    font-size: 0.76rem;
    font-weight: 600;
    border: 1px solid rgba(148, 196, 255, 0.28);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    transition: border-color 0.15s ease, background 0.15s ease;
}
.cond-group-actions button:hover {
    border-color: var(--accent);
    background: var(--surface-2);
    color: var(--accent);
}
.cond-children {
    padding-left: 1rem;
    border-left: 2px solid rgba(102, 214, 255, 0.25);
    margin-left: 0.4rem;
}
.cond-empty {
    font-size: 0.78rem;
    color: var(--muted);
    padding: 0.45rem 0.55rem;
    background: rgba(8, 13, 21, 0.4);
    border-radius: 6px;
    text-align: center;
}
.cond-predicate {
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid rgba(148, 196, 255, 0.14);
    border-radius: 7px;
    background: var(--surface);
    transition: border-color 0.15s ease;
}
.cond-predicate:hover { border-color: rgba(148, 196, 255, 0.3); }
.cond-predicate select,
.cond-predicate input {
    width: auto;            /* override .smsauto-field width:100% so flex can size */
    padding: 0.35rem 0.55rem;
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 6px;
    background: var(--bg);
    color: var(--text);
    font-size: 0.85rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.cond-predicate select:focus,
.cond-predicate input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.18);
}
.cond-predicate select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%23a4cfff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.4rem center;
    background-size: 12px;
    padding-right: 1.6rem;
}
.cond-remove {
    width: 1.75rem;
    height: 1.75rem;
    border: 1px solid rgba(248, 113, 113, 0.35);
    border-radius: 6px;
    color: #ffaaaa;
    font-size: 1rem;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.cond-remove:hover {
    background: rgba(248, 113, 113, 0.18);
    border-color: rgba(248, 113, 113, 0.6);
}

/* ── Test-eval card ─────────────────────────────────────────── */
.smsauto-testeval { margin-top: 0.5rem; }
.smsauto-testeval-row {
    gap: 0.6rem;
}
.smsauto-testeval-row input {
    width: 9rem;
    padding: 0.5rem 0.65rem;
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 7px;
    background: var(--bg);
    color: var(--text);
    font-size: 0.88rem;
}
.smsauto-testeval-row input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.18);
}
.smsauto-testeval-row button {
    padding: 0.5rem 1rem;
    border: 1px solid rgba(102, 214, 255, 0.5);
    border-radius: 7px;
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.18), rgba(102, 214, 255, 0.08));
    color: var(--accent);
    font-weight: 600;
    font-size: 0.86rem;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.smsauto-testeval-row button:hover {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.28), rgba(102, 214, 255, 0.14));
    border-color: rgba(102, 214, 255, 0.75);
}
.smsauto-testeval-result {
    margin-top: 0.7rem;
    padding: 0.7rem 0.85rem;
    border-radius: 9px;
    background: var(--bg);
    border-left-width: 4px;
    font-size: 0.82rem;
    line-height: 1.55;
}

/* ── Action buttons row — natural position at form bottom.
   Sticky was tried but it covered content underneath. The form is
   short enough most of the time that natural-bottom is fine, and
   when the conditions tree gets tall the operator scrolls down
   normally to reach Save. ────────────────────────────────────── */
.smsauto-actions {
    margin-top: 1.6rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--border);
    gap: 0.6rem;
}
.smsauto-save {
    background: linear-gradient(180deg, var(--accent), #4eb8e8);
    border: 1px solid var(--accent);
    color: #04121a;
    padding: 0.6rem 1.4rem;
    border-radius: 8px;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
    transition: transform 0.1s ease, box-shadow 0.15s ease;
}
.smsauto-save:hover {
    background: linear-gradient(180deg, #8de4ff, var(--accent));
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.2);
    transform: translateY(-1px);
}
.smsauto-toggle,
.smsauto-delete {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 0.55rem 0.95rem;
    border-radius: 8px;
    font-size: 0.86rem;
    font-weight: 600;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.smsauto-toggle:hover {
    background: rgba(46, 213, 115, 0.16);
    border-color: rgba(46, 213, 115, 0.5);
    color: #7be9a6;
}
.smsauto-clone {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 0.55rem 0.95rem;
    border-radius: 8px;
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.smsauto-clone:hover {
    background: rgba(102, 214, 255, 0.12);
    border-color: rgba(102, 214, 255, 0.5);
    color: var(--accent);
}
.smsauto-delete:hover {
    background: rgba(248, 113, 113, 0.16);
    border-color: rgba(248, 113, 113, 0.5);
    color: #ffaaaa;
}

/* Per-rule firing-history stats panel — renders above the actions row
   when editing an existing rule so the operator sees real-world behaviour
   before deciding whether to keep it on, tweak it, or clone it. */
.smsauto-stats {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.85rem 1rem;
    margin-bottom: 1.05rem;
}
.smsauto-stats > label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: 0.6rem;
    display: block;
}
.smsauto-stats-empty {
    color: var(--muted);
    font-style: italic;
    font-size: 0.86rem;
}
.smsauto-stats-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 0.5rem;
}
.smsauto-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0.55rem 0.5rem;
    border-radius: 8px;
    background: var(--surface);
    border: 1px solid rgba(148, 196, 255, 0.12);
}
.smsauto-stat-n {
    font-size: 1.4rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    color: var(--text);
}
.smsauto-stat-label {
    margin-top: 0.3rem;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 600;
}
.smsauto-stat-total    .smsauto-stat-n { color: var(--text); }
.smsauto-stat-pending  .smsauto-stat-n { color: var(--warning); }
.smsauto-stat-sent     .smsauto-stat-n { color: var(--success); }
.smsauto-stat-rejected .smsauto-stat-n { color: rgba(255, 170, 170, 0.85); }
.smsauto-stat-failed   .smsauto-stat-n { color: var(--danger); }
.smsauto-stats-meta {
    margin-top: 0.65rem;
    font-size: 0.78rem;
    color: var(--muted);
    line-height: 1.5;
}
.smsauto-stats-meta a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smsauto-stats-meta a:hover { border-bottom-style: solid; }

@media (max-width: 600px) {
    .smsauto-stats-grid { grid-template-columns: repeat(2, 1fr); }
}
.smsauto-status {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--muted);
}
.smsauto-status.is-ok    { color: #7be9a6; }
.smsauto-status.is-error { color: #ff8aa0; }

/* ── Mobile responsive (≤900px collapses sidebar) ────────────── */
@media (max-width: 900px) {
    .smsauto-page { padding: 1rem 1rem 2.5rem; }
    .smsauto-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.75rem;
    }
    .smsauto-head h1 { font-size: 1.35rem; }
    .smsauto-new {
        align-self: stretch;
        text-align: center;
    }
    .smsauto-shell {
        grid-template-columns: 1fr;
        gap: 1.25rem;
    }
    .smsauto-editor { padding: 1rem 1.05rem; }
    .smsauto-row { grid-template-columns: 1fr; gap: 0.9rem; }
}

@media (max-width: 520px) {
    .smsauto-page { padding: 0.85rem 0.75rem 2.5rem; }
    .smsauto-banner { font-size: 0.84rem; padding: 0.7rem 0.85rem; }
    .smsauto-actions { flex-direction: column; align-items: stretch; }
    .smsauto-save,
    .smsauto-toggle,
    .smsauto-delete { width: 100%; }
    .cond-predicate { gap: 0.4rem; }
    .cond-predicate .cond-field,
    .cond-predicate .cond-cmp,
    .cond-predicate .cond-val { flex: 1 1 100%; min-width: 0; }
}

/* ═════════════════════════════════════════════════════════════════════════
   /messages/automations starter library — visible when no rule is being
   edited. Card grid; each card has trigger/template/delay meta + Clone
   button that POSTs the slug to /messages/automations/clone-starter.
   ═════════════════════════════════════════════════════════════════════════ */
.smsauto-starters {
    margin-bottom: 1.5rem;
}
.smsauto-starters-head {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-bottom: 0.9rem;
}
.smsauto-starters-head h2 {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.005em;
    margin: 0;
}
.smsauto-starters-sub {
    color: var(--muted);
    font-size: 0.82rem;
    margin: 0;
}
.smsauto-starter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.85rem;
}
.smsauto-starter-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 0.95rem 1rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsauto-starter-card:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.35);
    transform: translateY(-1px);
}
.smsauto-starter-card.is-covered {
    opacity: 0.7;
}
.smsauto-starter-card-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
}
.smsauto-starter-tag {
    background: rgba(102, 214, 255, 0.12);
    color: var(--accent);
    border: 1px solid rgba(102, 214, 255, 0.3);
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.smsauto-starter-covered {
    color: #7be9a6;
    font-size: 0.72rem;
    font-weight: 600;
}
.smsauto-starter-name {
    font-size: 0.96rem;
    font-weight: 600;
    color: var(--text);
    margin: 0.2rem 0 0;
    letter-spacing: -0.01em;
}
.smsauto-starter-blurb {
    color: var(--muted);
    font-size: 0.84rem;
    line-height: 1.5;
    margin: 0;
    min-height: 2.5em;        /* keep cards equal-ish height for short blurbs */
}
.smsauto-starter-meta {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 0.6rem;
    row-gap: 0.2rem;
    margin: 0.2rem 0 0;
    padding: 0.55rem 0.65rem;
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.1);
    border-radius: 8px;
    font-size: 0.78rem;
}
.smsauto-starter-meta > div {
    display: contents;
}
.smsauto-starter-meta dt {
    color: var(--muted);
    font-weight: 600;
    margin: 0;
}
.smsauto-starter-meta dd {
    color: var(--text);
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.smsauto-starter-clone {
    margin-top: 0.4rem;
    padding: 0.5rem 0.85rem;
    background: linear-gradient(180deg, var(--accent), #4eb8e8);
    border: 1px solid var(--accent);
    color: #04121a;
    border-radius: 8px;
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.smsauto-starter-clone:hover {
    background: linear-gradient(180deg, #8de4ff, var(--accent));
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.18);
    transform: translateY(-1px);
}
.smsauto-starter-clone:disabled {
    opacity: 0.6;
    cursor: wait;
    transform: none;
}
.smsauto-starter-card.is-covered .smsauto-starter-clone {
    background: var(--surface);
    color: var(--text);
    border-color: var(--border);
}
.smsauto-starter-card.is-covered .smsauto-starter-clone:hover {
    background: var(--surface-2);
    border-color: var(--accent);
}

@media (max-width: 600px) {
    .smsauto-starter-grid { grid-template-columns: 1fr; }
}

/* ═════════════════════════════════════════════════════════════════════════
   Schedule-window editor + sidebar window chip (2026-05-21)
   ═════════════════════════════════════════════════════════════════════════ */
.smsauto-hint-inline {
    color: var(--muted);
    font-weight: 400;
    font-size: 0.78rem;
}

.smsauto-window {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 10px;
    padding: 0.65rem 0.8rem;
}
.smsauto-window-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-size: 0.86rem;
    font-weight: 500;
    color: var(--text);
    user-select: none;
}
.smsauto-window-toggle input[type="checkbox"] {
    width: auto;
    accent-color: var(--accent);
    transform: scale(1.05);
}
.smsauto-window-controls {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    margin-top: 0.7rem;
    padding-top: 0.65rem;
    border-top: 1px solid rgba(148, 196, 255, 0.1);
}
.smsauto-window-days {
    display: inline-flex;
    gap: 0.35rem;
    flex-wrap: wrap;
}
.smsauto-window-day {
    position: relative;
    cursor: pointer;
}
.smsauto-window-day input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
    width: 100%;
    height: 100%;
}
.smsauto-window-day span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.1rem;
    height: 2.1rem;
    padding: 0 0.5rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 7px;
    color: var(--muted);
    font-size: 0.82rem;
    font-weight: 600;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.smsauto-window-day input:checked + span {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.18), rgba(102, 214, 255, 0.08));
    border-color: var(--accent);
    color: var(--accent);
}
.smsauto-window-day:hover span {
    border-color: rgba(102, 214, 255, 0.45);
    color: var(--text);
}
.smsauto-window-times {
    display: flex;
    gap: 0.9rem;
    flex-wrap: wrap;
    align-items: center;
}
.smsauto-window-times label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.84rem;
    color: var(--muted);
    font-weight: 500;
}
.smsauto-window-times input[type="time"] {
    width: auto;
    padding: 0.4rem 0.55rem;
    background: var(--surface);
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 6px;
    color: var(--text);
    font: inherit;
    font-size: 0.86rem;
    font-variant-numeric: tabular-nums;
}
.smsauto-window-times input[type="time"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(102, 214, 255, 0.18);
}

.smsauto-list-window {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0.05rem 0.45rem;
    background: rgba(255, 208, 102, 0.14);
    color: var(--warning);
    border: 1px solid rgba(255, 208, 102, 0.28);
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ═════════════════════════════════════════════════════════════════════════
   /messages/automations/activity — dashboard (2026-05-21)
   ═════════════════════════════════════════════════════════════════════════ */
.smsact-page {
    max-width: 1320px;
    margin: 0 auto;
    padding: 1.5rem 1.75rem 3.5rem;
    color: var(--text);
}
.smsact-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    border-bottom: 1px solid var(--border);
    padding-bottom: 1rem;
    margin-bottom: 1.5rem;
    gap: 1rem;
    flex-wrap: wrap;
}
.smsact-head h1 {
    font-size: 1.55rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0;
}
.smsact-sub {
    color: var(--muted);
    font-size: 0.88rem;
    margin: 0.35rem 0 0;
    line-height: 1.55;
}
.smsact-sub a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smsact-sub a:hover { border-bottom-style: solid; }
.smsact-sep { color: rgba(255, 255, 255, 0.25); margin: 0 0.35rem; }
.smsact-worker-status {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.15rem;
    padding: 0.55rem 0.85rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.smsact-worker-label {
    color: var(--muted);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.smsact-worker-time {
    color: var(--text);
    font-size: 0.92rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.smsact-worker-time.is-stale { color: var(--muted); font-style: italic; }

/* Counter cards */
.smsact-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.85rem;
    margin-bottom: 1.75rem;
}
.smsact-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    transition: border-color 0.15s ease, transform 0.1s ease;
}
.smsact-card:hover {
    transform: translateY(-1px);
}
.smsact-card-num {
    font-size: 2.1rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}
.smsact-card-label {
    color: var(--muted);
    font-size: 0.86rem;
    font-weight: 600;
    margin-top: 0.15rem;
}
.smsact-card-meta {
    color: var(--muted);
    font-size: 0.75rem;
    margin-top: 0.45rem;
    padding-top: 0.4rem;
    border-top: 1px dashed rgba(255, 255, 255, 0.08);
}
.smsact-card-pending  { border-color: rgba(255, 208, 102, 0.35); }
.smsact-card-pending  .smsact-card-num { color: var(--warning); }
.smsact-card-sent     { border-color: rgba(110, 231, 168, 0.35); }
.smsact-card-sent     .smsact-card-num { color: var(--success); }
.smsact-card-rejected { border-color: rgba(255, 170, 170, 0.3); }
.smsact-card-rejected .smsact-card-num { color: #ffaaaa; }
.smsact-card-failed   { border-color: rgba(255, 123, 156, 0.4); }
.smsact-card-failed   .smsact-card-num { color: var(--danger); }

/* Sections */
.smsact-section {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.1rem 1.25rem;
    margin-bottom: 1.5rem;
}
.smsact-section-head {
    margin-bottom: 1rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.smsact-section-head h2 {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
    margin: 0 0 0.2rem;
    letter-spacing: -0.005em;
}
.smsact-section-head p {
    color: var(--muted);
    font-size: 0.82rem;
    margin: 0;
}

.smsact-empty {
    padding: 1.5rem 1rem;
    background: var(--bg);
    border: 1px dashed rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    color: var(--muted);
    font-size: 0.86rem;
    text-align: center;
    line-height: 1.55;
}

/* Bar chart */
.smsact-chart {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.6rem;
    height: 200px;
    align-items: end;
    padding: 0.5rem 0;
}
.smsact-chart-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    gap: 0.5rem;
}
.smsact-chart-bar {
    width: 100%;
    min-height: 4px;
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.14);
    border-radius: 6px 6px 0 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
    position: relative;
    flex: 1 1 auto;
}
.smsact-chart-num {
    position: absolute;
    top: -1.3rem;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.smsact-chart-seg {
    width: 100%;
    flex: 0 0 auto;
    min-height: 1px;
}
.smsact-chart-seg.is-sent     { background: linear-gradient(180deg, var(--success), #4ec48a); }
.smsact-chart-seg.is-pending  { background: linear-gradient(180deg, var(--warning), #e8b540); }
.smsact-chart-seg.is-rejected { background: rgba(255, 170, 170, 0.45); }
.smsact-chart-seg.is-failed   { background: linear-gradient(180deg, var(--danger), #d65a78); }
.smsact-chart-label {
    flex: 0 0 auto;
    font-size: 0.74rem;
    color: var(--muted);
    font-weight: 600;
    letter-spacing: 0.02em;
}
.smsact-chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 0.85rem;
    padding-top: 0.8rem;
    border-top: 1px dashed rgba(255, 255, 255, 0.06);
}
.smsact-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    color: var(--muted);
}
.smsact-dot {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 3px;
}
.smsact-dot.is-sent     { background: var(--success); }
.smsact-dot.is-pending  { background: var(--warning); }
.smsact-dot.is-rejected { background: rgba(255, 170, 170, 0.6); }
.smsact-dot.is-failed   { background: var(--danger); }

/* Top rules table */
.smsact-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}
.smsact-table thead th {
    text-align: left;
    padding: 0.55rem 0.7rem;
    border-bottom: 1px solid var(--border);
    color: var(--muted);
    font-weight: 600;
    font-size: 0.76rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.smsact-table tbody td {
    padding: 0.7rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    vertical-align: middle;
}
.smsact-table tbody tr:last-child td { border-bottom: none; }
.smsact-table tbody tr:hover { background: rgba(102, 214, 255, 0.03); }
.smsact-num { text-align: right; font-variant-numeric: tabular-nums; }
.smsact-rule a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smsact-rule a:hover { border-bottom-style: solid; }
.smsact-rule-tpl {
    color: var(--muted);
    font-size: 0.76rem;
    margin-top: 0.15rem;
}
.smsact-tag.is-off {
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    background: rgba(255, 255, 255, 0.07);
    color: var(--muted);
    border-radius: 999px;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.smsact-pending-cell  { color: var(--warning); font-weight: 600; }
.smsact-sent-cell     { color: var(--success); font-weight: 600; }
.smsact-rejected-cell { color: #ffaaaa; font-weight: 600; }
.smsact-failed-cell   { color: var(--danger); font-weight: 600; }
.smsact-rate {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 7rem;
}
.smsact-rate-bar {
    width: 5rem;
    height: 0.45rem;
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.12);
    border-radius: 999px;
    overflow: hidden;
}
.smsact-rate-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--success), #4ec48a);
}
.smsact-rate-num {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    font-size: 0.82rem;
}
.smsact-muted { color: var(--muted); font-style: italic; }

@media (max-width: 720px) {
    .smsact-head { flex-direction: column; align-items: flex-start; }
    .smsact-worker-status { align-self: stretch; align-items: flex-start; }
    .smsact-chart { height: 160px; gap: 0.35rem; }
    .smsact-table { font-size: 0.82rem; }
    .smsact-table thead th, .smsact-table tbody td { padding: 0.5rem 0.45rem; }
    .smsact-rate { min-width: 0; }
    .smsact-rate-bar { width: 3rem; }
}

/* ═════════════════════════════════════════════════════════════════════════
   Unified /messages/* sub-nav (2026-05-21)
   Renders across every messaging page so the operator can flip between
   Inbox / Rules / Queue / Activity / Templates / Health in one tap.
   ═════════════════════════════════════════════════════════════════════════ */
.msg-subnav {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 0 1.5rem;
    /* Sticky top so it stays visible while pages scroll. Inbox pages with
       their own viewport-locked layout get the subnav as a static flex
       child of layout-main, so this sticky is a no-op there. */
    position: sticky;
    top: 0;
    z-index: 18;
    /* Subtle inset gradient so the subnav reads as a distinct strip */
    background: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
}
.msg-subnav-inner {
    display: flex;
    gap: 0.15rem;
    /* Matches the admin-page max-width (.smsauto-page et al.) so the tabs
       visually align with the page content underneath them when tabbing
       between Inbox (full-bleed) and admin pages (capped at 1280). */
    max-width: 1280px;
    margin: 0 auto;
    overflow-x: auto;
    /* Hide scrollbar on horizontal overflow — small viewports show all tabs
       with a swipe instead of a visible bar. */
    scrollbar-width: thin;
    scrollbar-color: rgba(102, 214, 255, 0.2) transparent;
}
/* Subnav-inner stays at the same 1280px max-width on every page, including
   the inbox. The inbox's 3-pane shell is full-bleed below, but the subnav
   itself stays centered + capped so the tabs never shift horizontally when
   navigating between pages. (Reverted the :has() max-width:none override
   2026-05-21: it caused a ~370px first-tab x-jump that read as the page
   "jumping in size" when clicking between tabs.) */
.msg-subnav-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.75rem 0.95rem 0.7rem;
    color: var(--muted);
    font-size: 0.88rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
    position: relative;
}
.msg-subnav-tab:hover {
    color: var(--text);
    background: rgba(102, 214, 255, 0.04);
}
.msg-subnav-tab.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.msg-subnav-tab.is-active::before {
    /* Subtle inset glow for the active tab */
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.06), transparent 70%);
    pointer-events: none;
}
.msg-subnav-icon {
    font-size: 0.95rem;
    line-height: 1;
    opacity: 0.85;
}
.msg-subnav-tab.is-active .msg-subnav-icon { opacity: 1; }
.msg-subnav-label {
    /* Hide labels on very narrow viewports, keep icons */
}
.msg-subnav-badge {
    display: inline-block;
    min-width: 1.4rem;
    padding: 0.08rem 0.45rem;
    border-radius: 999px;
    background: rgba(255, 208, 102, 0.25);
    color: var(--warning);
    font-size: 0.7rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
    margin-left: 0.1rem;
}
.msg-subnav-tab.is-active .msg-subnav-badge {
    background: rgba(255, 208, 102, 0.35);
}
@media (max-width: 720px) {
    .msg-subnav { padding: 0 0.75rem; }
    .msg-subnav-tab { padding: 0.65rem 0.65rem 0.6rem; font-size: 0.82rem; gap: 0.3rem; }
    .msg-subnav-icon { font-size: 0.88rem; }
    .msg-subnav-badge { font-size: 0.65rem; padding: 0.05rem 0.35rem; min-width: 1.2rem; }
}
@media (max-width: 480px) {
    .msg-subnav-label { display: none; }   /* icon-only on phones */
    .msg-subnav-tab { padding: 0.7rem 0.85rem; }
}

/* ═════════════════════════════════════════════════════════════════════════
   /messages/* DEEP COHESION POLISH (2026-05-21)
   Standardizes the chrome — page chrome, header pattern, card frames,
   typography rhythm — across every messaging page below the subnav.
   Goal: when you tab between Inbox / Rules / Queue / Activity / Templates
   / Health they feel like the same tool, not 6 different apps.
   ═════════════════════════════════════════════════════════════════════════ */

/* Shared page-frame override across all admin-panel messaging pages.
   Inbox keeps its 3-pane layout via .msg-page (no chrome change).
   The five admin pages get matching max-width + padding + color. */
.smsauto-page,
.smsq-page,
.smsact-page,
.smstpl-page,
.smshealth-page,
.smsbulk-page {
    max-width: 1280px;
    margin: 0 auto;
    padding: 1.5rem 1.75rem 3.5rem;
    color: var(--text);
}

/* Health page — bring it up to the same level as Activity */
.smshealth-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
    border-bottom: 1px solid var(--border);
    padding-bottom: 1rem;
    margin-bottom: 1.5rem;
}
.smshealth-head h1 {
    font-size: 1.55rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
    margin: 0;
}
.smshealth-sub {
    color: var(--muted);
    font-size: 0.88rem;
    margin: 0.35rem 0 0;
    line-height: 1.55;
}
.smshealth-sub a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smshealth-sub a:hover { border-bottom-style: solid; }
.smshealth-templates-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.55rem 0.95rem;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 8px;
    font-size: 0.86rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smshealth-templates-link:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.45);
    color: var(--accent);
    transform: translateY(-1px);
}

.smshealth-grid {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.85rem;
    margin-bottom: 1.75rem;
}
.smshealth-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    transition: border-color 0.15s ease, transform 0.1s ease;
}
.smshealth-card:hover {
    transform: translateY(-1px);
    border-color: rgba(102, 214, 255, 0.35);
}
.smshealth-metric-label {
    font-size: 0.75rem;
    text-transform: none;
    letter-spacing: 0;
    color: var(--muted);
    margin-bottom: 0.35rem;
    font-weight: 600;
    order: 2;       /* label below value for hierarchy match with Activity */
}
.smshealth-metric-val {
    font-size: 2.1rem;
    font-weight: 700;
    color: var(--success);       /* good metric = green */
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    order: 1;
}
.smshealth-metric-val.smshealth-tone-bad   { color: var(--danger); }
.smshealth-metric-val.smshealth-tone-muted { color: var(--muted); font-weight: 500; }
.smshealth-metric-sub {
    margin-top: 0.45rem;
    padding-top: 0.4rem;
    border-top: 1px dashed rgba(255, 255, 255, 0.08);
    font-size: 0.76rem;
    color: var(--muted);
    order: 3;
}

.smshealth-section {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.1rem 1.25rem;
    margin-top: 0;
    margin-bottom: 1.5rem;
}
.smshealth-section-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    flex-wrap: wrap;
}
.smshealth-section-head h2 {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: -0.005em;
    margin: 0;
}
.smshealth-section-sub {
    font-size: 0.82rem;
    color: var(--muted);
}
.smshealth-pill {
    background: rgba(102, 214, 255, 0.14);
    border: 1px solid rgba(102, 214, 255, 0.3);
    color: var(--accent);
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.08rem 0.55rem;
    margin-left: 0.4rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    vertical-align: middle;
}
.smshealth-cap {
    font-size: 0.82rem;
    color: var(--muted);
}

/* Subnav-to-page seam — the page-frame top padding visually attaches to
   the subnav's bottom border. Reduce top padding on admin pages so the
   page header sits closer to the subnav without feeling disconnected. */
.smsauto-page,
.smsq-page,
.smsact-page,
.smstpl-page,
.smshealth-page,
.smsbulk-page {
    padding-top: 1.5rem;
}

/* Tighten subnav strip — slightly thinner so it doesn't compete with
   the page H1 for visual weight. Bottom border is darker so the
   separation reads as "tab strip + page" not "two stacked panels." */
.msg-subnav {
    padding: 0 1.5rem;
    background: linear-gradient(180deg, var(--surface) 0%, rgba(15, 22, 34, 0.6) 100%);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}
.msg-subnav-tab {
    padding: 0.65rem 0.95rem 0.6rem;
    font-size: 0.86rem;
}

/* Inbox-specific footer trim — the side panel's footer now only has the
   "From" line + "+ New" + Bulk link, since templates/automations/health
   are reachable via the subnav. Compact it. */
.msg-foot-bulk {
    display: inline-block;
    margin-top: 0.5rem;
    padding: 0.4rem 0.6rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 7px;
    color: var(--muted);
    font-size: 0.78rem;
    text-decoration: none;
    text-align: center;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.msg-foot-bulk:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.35);
    color: var(--accent);
}

/* "Fire automation" button in the /database drawer header — accent-toned
   so it visually pairs with the History link but reads as an action vs a
   navigation. The bolt icon is inline text since we don't have an icon font. */
.db-fire-automation-btn {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.18), rgba(102, 214, 255, 0.08));
    color: var(--accent);
    border: 1px solid rgba(102, 214, 255, 0.4);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.db-fire-automation-btn:hover {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.28), rgba(102, 214, 255, 0.12));
    border-color: var(--accent);
    transform: translateY(-1px);
}

/* ═════════════════════════════════════════════════════════════════════════
   /messages/automations/queue — firing-queue review board.
   The worker writes SmsAutomationFiring rows in 'pending'. Operator
   approves+sends or rejects each from this page. Per the no-auto-
   dispatch policy, every send is a deliberate human click.
   ═════════════════════════════════════════════════════════════════════════ */
.smsq-page {
    max-width: 1320px;
    margin: 0 auto;
    padding: 1.5rem 1.75rem 3.5rem;
    color: var(--text);
}
.smsq-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    border-bottom: 1px solid var(--border);
    padding-bottom: 1rem;
    margin-bottom: 1.25rem;
    gap: 1rem;
}
.smsq-head h1 {
    font-size: 1.55rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0;
    color: var(--text);
}
.smsq-sub {
    color: var(--muted);
    font-size: 0.88rem;
    margin: 0.35rem 0 0;
    line-height: 1.55;
}
.smsq-sub strong { color: var(--accent); font-weight: 600; }
.smsq-sub a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.35);
}
.smsq-sub a:hover { border-bottom-style: solid; }
.smsq-sep { margin: 0 0.4rem; color: rgba(255, 255, 255, 0.25); }

/* Filter bar — status pills on the left, rule dropdown on the right */
.smsq-filters {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
    flex-wrap: wrap;
}
.smsq-statuspills { display: inline-flex; gap: 0.5rem; flex-wrap: wrap; }
.smsq-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.85rem;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 0.86rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsq-pill:hover {
    background: var(--surface-2);
    border-color: rgba(102, 214, 255, 0.35);
    transform: translateY(-1px);
}
.smsq-pill.is-active {
    background: linear-gradient(180deg, rgba(102, 214, 255, 0.16), rgba(102, 214, 255, 0.06));
    border-color: var(--accent);
    color: var(--accent);
    box-shadow: 0 0 0 1px rgba(102, 214, 255, 0.18);
}
.smsq-pill-count {
    display: inline-block;
    min-width: 1.4rem;
    padding: 0.05rem 0.45rem;
    text-align: center;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.75);
    font-size: 0.74rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.smsq-pill.is-active .smsq-pill-count {
    background: rgba(102, 214, 255, 0.22);
    color: var(--accent);
}
.smsq-pill.smsq-pill-pending.is-active   { border-color: var(--warning); color: var(--warning); background: linear-gradient(180deg, rgba(255, 208, 102, 0.14), rgba(255, 208, 102, 0.05)); }
.smsq-pill.smsq-pill-pending.is-active .smsq-pill-count { background: rgba(255, 208, 102, 0.22); color: var(--warning); }
.smsq-pill.smsq-pill-sent.is-active      { border-color: var(--success); color: var(--success); background: linear-gradient(180deg, rgba(110, 231, 168, 0.12), rgba(110, 231, 168, 0.04)); }
.smsq-pill.smsq-pill-sent.is-active .smsq-pill-count { background: rgba(110, 231, 168, 0.2); color: var(--success); }
.smsq-pill.smsq-pill-rejected.is-active  { border-color: #ffaaaa; color: #ffaaaa; background: linear-gradient(180deg, rgba(255, 170, 170, 0.12), rgba(255, 170, 170, 0.04)); }
.smsq-pill.smsq-pill-failed.is-active    { border-color: var(--danger); color: var(--danger); background: linear-gradient(180deg, rgba(255, 123, 156, 0.14), rgba(255, 123, 156, 0.05)); }

.smsq-rulefilter {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.smsq-rulefilter label {
    font-size: 0.85rem;
    color: var(--muted);
    font-weight: 600;
}
.smsq-rulefilter select {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 8px;
    padding: 0.5rem 2rem 0.5rem 0.65rem;
    color: var(--text);
    font-size: 0.88rem;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%2366d6ff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
}
.smsq-rulefilter select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.15);
}

/* Empty state — when the current filter has 0 rows */
.smsq-empty {
    background: var(--surface);
    border: 1px dashed rgba(148, 196, 255, 0.22);
    border-radius: 12px;
    padding: 2rem;
    text-align: center;
    color: var(--muted);
    line-height: 1.6;
}
.smsq-empty p { margin: 0 0 0.5rem; }
.smsq-empty strong { color: var(--text); font-weight: 600; }
.smsq-empty a { color: var(--accent); }
.smsq-empty code {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    font-size: 0.82rem;
    color: var(--text);
}

/* Table */
.smsq-tablewrap {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: var(--shadow-sm, 0 6px 14px rgba(var(--shadow-rgb), 0.34));
}
.smsq-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}
.smsq-table thead th {
    text-align: left;
    padding: 0.7rem 0.85rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    color: var(--muted);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
.smsq-table tbody td {
    padding: 0.8rem 0.85rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    vertical-align: top;
}
.smsq-table tbody tr:last-child td { border-bottom: none; }
.smsq-table tbody tr:hover { background: rgba(102, 214, 255, 0.03); }

/* Per-row status tint */
.smsq-row.smsq-row-pending   { /* default */ }
.smsq-row.smsq-row-sent      td { opacity: 0.78; }
.smsq-row.smsq-row-rejected  td { opacity: 0.62; }
.smsq-row.smsq-row-failed    td { background: rgba(255, 123, 156, 0.04); }
.smsq-row.is-just-sent       td { background: rgba(110, 231, 168, 0.12); transition: background 0.4s ease; }
.smsq-row.is-just-rejected   td { background: rgba(255, 170, 170, 0.1); transition: background 0.4s ease; }

/* Columns */
.smsq-detected-rel { font-weight: 600; color: var(--text); font-size: 0.86rem; }
.smsq-detected-abs { color: var(--muted); font-size: 0.76rem; margin-top: 0.15rem; }

.smsq-rule-link {
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    border-bottom: 1px dashed rgba(102, 214, 255, 0.3);
}
.smsq-rule-link:hover { border-bottom-style: solid; }
.smsq-trigger {
    margin-top: 0.2rem;
    color: var(--muted);
    font-size: 0.76rem;
    font-style: italic;
}

.smsq-jobname a {
    color: var(--text);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px dashed rgba(148, 196, 255, 0.3);
}
.smsq-jobname a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.smsq-contact {
    margin-top: 0.25rem;
    color: var(--muted);
    font-size: 0.82rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: baseline;
}
.smsq-contact-name { color: rgba(255, 255, 255, 0.82); }
.smsq-contact-phone { font-variant-numeric: tabular-nums; color: var(--muted); }
.smsq-muted { color: var(--muted); font-style: italic; }

.smsq-flags { margin-top: 0.3rem; display: flex; gap: 0.3rem; flex-wrap: wrap; }
.smsq-flag {
    display: inline-block;
    padding: 0.08rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.smsq-flag.is-ok      { background: rgba(110, 231, 168, 0.15); color: var(--success); }
.smsq-flag.is-warn    { background: rgba(255, 208, 102, 0.18); color: var(--warning); }
.smsq-flag.is-danger  { background: rgba(255, 123, 156, 0.2); color: var(--danger); }

.smsq-tpl-name {
    font-weight: 600;
    color: var(--text);
    font-size: 0.86rem;
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}
.smsq-tpl-cat {
    font-weight: 500;
    font-size: 0.7rem;
    color: var(--accent);
    background: rgba(102, 214, 255, 0.12);
    padding: 0.05rem 0.45rem;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.smsq-tpl-body {
    margin-top: 0.4rem;
    color: rgba(236, 243, 255, 0.9);
    font-size: 0.84rem;
    line-height: 1.5;
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.18);
    padding: 0.55rem 0.7rem;
    border-radius: 6px;
    max-width: 32rem;
    word-break: break-word;
}
.smsq-tpl-missing {
    margin-top: 0.35rem;
    font-size: 0.74rem;
    color: var(--warning);
    background: rgba(255, 208, 102, 0.08);
    border: 1px solid rgba(255, 208, 102, 0.22);
    padding: 0.25rem 0.5rem;
    border-radius: 5px;
    display: inline-block;
}
.smsq-tpl-raw {
    margin-top: 0.4rem;
    font-size: 0.74rem;
}
.smsq-tpl-raw summary {
    color: var(--muted);
    cursor: pointer;
    user-select: none;
    padding: 0.1rem 0;
}
.smsq-tpl-raw summary:hover { color: var(--accent); }
.smsq-tpl-raw[open] summary { color: var(--accent); }
.smsq-tpl-raw code {
    display: block;
    margin-top: 0.3rem;
    color: rgba(255, 255, 255, 0.7);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
    font-size: 0.76rem;
    background: rgba(8, 13, 21, 0.5);
    border: 1px solid rgba(148, 196, 255, 0.08);
    padding: 0.4rem 0.55rem;
    border-radius: 5px;
    white-space: pre-wrap;
    word-break: break-word;
}

.smsq-statuspill {
    display: inline-block;
    padding: 0.15rem 0.65rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    background: rgba(255, 255, 255, 0.06);
    color: var(--muted);
}
.smsq-statuspill-pending  { background: rgba(255, 208, 102, 0.18); color: var(--warning); }
.smsq-statuspill-sent     { background: rgba(110, 231, 168, 0.18); color: var(--success); }
.smsq-statuspill-rejected { background: rgba(255, 170, 170, 0.15); color: #ffaaaa; }
.smsq-statuspill-failed   { background: rgba(255, 123, 156, 0.22); color: var(--danger); }
.smsq-meta {
    margin-top: 0.3rem;
    font-size: 0.72rem;
    color: var(--muted);
}
.smsq-meta code {
    background: var(--bg);
    border: 1px solid rgba(148, 196, 255, 0.12);
    padding: 0.02rem 0.3rem;
    border-radius: 4px;
    font-size: 0.7rem;
}
.smsq-err { color: #ffaaaa; cursor: help; }

/* Actions column */
.smsq-actions-th { width: 12rem; }
.smsq-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.35rem;
    min-width: 9rem;
}
.smsq-btn {
    padding: 0.4rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: var(--surface);
    color: var(--text);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.smsq-btn:hover { transform: translateY(-1px); }
.smsq-btn-send {
    background: linear-gradient(180deg, var(--accent), #4eb8e8);
    border-color: var(--accent);
    color: #04121a;
}
.smsq-btn-send:hover {
    background: linear-gradient(180deg, #8de4ff, var(--accent));
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.18);
}
.smsq-btn-reject {
    background: var(--surface-2);
    border-color: rgba(255, 170, 170, 0.3);
    color: rgba(255, 200, 200, 0.9);
}
.smsq-btn-reject:hover {
    background: rgba(255, 170, 170, 0.12);
    border-color: rgba(255, 170, 170, 0.55);
    color: #ffaaaa;
}
.smsq-btn-retry {
    border-color: rgba(255, 208, 102, 0.4);
    color: var(--warning);
}
.smsq-btn-retry:hover { background: rgba(255, 208, 102, 0.12); }
.smsq-btn:disabled { opacity: 0.5; cursor: wait; transform: none; }
.smsq-actions-done { color: var(--muted); font-size: 0.8rem; padding: 0.4rem 0; text-align: center; }

/* Inline confirm */
.smsq-confirm {
    display: inline-flex;
    flex-direction: column;
    gap: 0.3rem;
}
.smsq-confirm-label {
    font-size: 0.78rem;
    color: var(--muted);
    font-style: italic;
    text-align: center;
    padding: 0.1rem 0;
}
.smsq-btn-confirm {
    background: linear-gradient(180deg, var(--success), #4ec48a);
    border-color: var(--success);
    color: #04121a;
}
.smsq-btn-confirm:hover { background: linear-gradient(180deg, #8df0bb, var(--success)); }
.smsq-btn-cancel {
    background: var(--surface);
    border-color: var(--border);
    color: var(--muted);
}

/* Mobile responsive */
@media (max-width: 900px) {
    .smsq-page { padding: 1rem 1rem 2.5rem; }
    .smsq-head { flex-direction: column; align-items: flex-start; }
    .smsq-filters { flex-direction: column; align-items: flex-start; }
    .smsq-tablewrap { overflow-x: auto; }
    .smsq-table { min-width: 760px; }
}
@media (max-width: 520px) {
    .smsq-statuspills { gap: 0.35rem; }
    .smsq-pill { padding: 0.35rem 0.65rem; font-size: 0.8rem; }
    .smsq-tpl-body { max-width: 100%; }
}

/* ═════════════════════════════════════════════════════════════════════════
   Automation auto-send toggle — editor checkbox + queue card + row badge.
   Lets operators flip a rule between "queue for manual review" (default)
   and "worker auto-dispatches matches immediately." Lives at the end so
   tweaks don't fight cascade ordering against the smsauto-* / smsq-*
   blocks above.
   ═════════════════════════════════════════════════════════════════════════ */

/* Editor checkbox (templates/workspace/messages_automations.php). The
   per-field wrapper inherits .smsauto-field's margin, but we strip the
   uppercase label treatment because this control reads as a sentence. */
.smsauto-autosend-field { margin-bottom: 0.9rem; }
.smsauto-autosend-label {
    display: flex;
    gap: 0.65rem;
    align-items: flex-start;
    cursor: pointer;
    padding: 0.7rem 0.85rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 7px;
    transition: border-color 0.15s ease, background 0.15s ease;
    text-transform: none;
    letter-spacing: normal;
    color: var(--text, #e6e9ef);
    font-size: 0.88rem;
}
.smsauto-autosend-label:hover { border-color: rgba(102, 214, 255, 0.35); background: rgba(102, 214, 255, 0.04); }
.smsauto-autosend-label input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 2px 0 0 0;
    accent-color: #4c9aff;
    flex: 0 0 auto;
    cursor: pointer;
}
.smsauto-autosend-text { display: block; line-height: 1.45; }
.smsauto-autosend-text strong {
    display: block;
    color: var(--text, #e6e9ef);
    font-weight: 600;
    margin-bottom: 0.15rem;
}
.smsauto-autosend-text .smsauto-hint {
    display: block;
    margin-top: 0;
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.78rem;
    line-height: 1.5;
}

/* Queue page focused-rule card (visible when filtered to one rule).
   Color shifts amber when the rule is "manual" (queue for review) and
   green when "auto" so the state is unambiguous at a glance. */
.smsq-rulecard {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin: 0 0 1.1rem;
    padding: 0.85rem 1.1rem;
    border-radius: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    transition: border-color 0.15s ease, background 0.15s ease;
}
.smsq-rulecard.is-manual {
    border-color: rgba(255, 184, 76, 0.42);
    background: linear-gradient(180deg, rgba(255, 184, 76, 0.07), rgba(255, 184, 76, 0.02));
}
.smsq-rulecard.is-auto {
    border-color: rgba(64, 196, 124, 0.5);
    background: linear-gradient(180deg, rgba(64, 196, 124, 0.08), rgba(64, 196, 124, 0.02));
}
.smsq-rulecard-name { font-size: 1rem; color: var(--text); display: flex; gap: 0.6rem; align-items: center; }
.smsq-rulecard-name strong { font-weight: 600; }
.smsq-rulecard-paused {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 184, 76, 0.85);
    background: rgba(255, 184, 76, 0.12);
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
}
.smsq-rulecard-toggle { flex: 0 0 auto; }

/* iOS-style switch (the actual checkbox is sr-only-ish; the slider is the
   visible track + knob). Adjacent text gives the current state + hint. */
.smsq-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    cursor: pointer;
    user-select: none;
}
.smsq-switch input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}
.smsq-switch-slider {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
    background: rgba(255, 184, 76, 0.35);
    border-radius: 999px;
    transition: background 0.18s ease;
    flex: 0 0 auto;
}
.smsq-switch-slider::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    background: var(--white);
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(var(--shadow-rgb), 0.45);
    transition: transform 0.18s ease;
}
.smsq-switch input:checked + .smsq-switch-slider {
    background: rgba(64, 196, 124, 0.65);
}
.smsq-switch input:checked + .smsq-switch-slider::after {
    transform: translateX(18px);
}
.smsq-switch input:focus-visible + .smsq-switch-slider {
    box-shadow: 0 0 0 3px rgba(102, 214, 255, 0.25);
}
.smsq-switch input:disabled + .smsq-switch-slider {
    opacity: 0.55;
    cursor: progress;
}
.smsq-switch-labels { display: flex; flex-direction: column; line-height: 1.35; }
.smsq-switch-state {
    font-weight: 600;
    color: var(--text);
    font-size: 0.86rem;
}
.smsq-switch-hint {
    color: var(--muted);
    font-size: 0.74rem;
}

/* Per-row AUTO badge in the Rule column. Tucks beside the rule link so
   operators can see at a glance which rules currently auto-dispatch. */
.smsq-rule-autobadge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.08rem 0.42rem;
    background: rgba(64, 196, 124, 0.18);
    color: rgba(110, 226, 158, 0.95);
    border: 1px solid rgba(64, 196, 124, 0.45);
    border-radius: 4px;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    vertical-align: 1px;
}

@media (max-width: 720px) {
    .smsq-rulecard { flex-direction: column; align-items: flex-start; gap: 0.7rem; }
    .smsq-rulecard-toggle { width: 100%; }
    .smsq-switch-labels { display: none; }
    .smsq-switch::after {
        content: attr(data-mobile-label);
        color: var(--muted);
        font-size: 0.78rem;
    }
}

/* ──────────────────────────────────────────────────────────────────
   Confirmation preview modal — opens after slot pick to verify data
   before commit. Reuses .confirmation.modal-card width + chrome.
   ────────────────────────────────────────────────────────────────── */
.confirmation.preview-grid {
    margin: 0.75rem 0 0.6rem;
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: 0.85rem;
    row-gap: 0.4rem;
    align-items: baseline;
    font-size: 0.92rem;
}

.confirmation.preview-grid dt {
    color: rgba(148, 196, 255, 0.78);
    font-weight: 500;
    margin: 0;
}

.confirmation.preview-grid dd {
    margin: 0;
    color: rgba(232, 240, 252, 0.95);
    word-break: break-word;
}

.confirmation.preview-grid .confirmation.phone-link {
    margin-right: 0.5rem;
}

.confirmation.preview-send-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.75rem 0 0.25rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 8px;
    background: rgba(21, 33, 50, 0.7);
    font-size: 0.9rem;
    cursor: pointer;
}

.confirmation.preview-send-toggle input[type="checkbox"] {
    margin: 0;
    cursor: pointer;
}

.confirmation.preview-sms-section {
    margin-top: 0.85rem;
    padding-top: 0.85rem;
    border-top: 1px solid rgba(148, 196, 255, 0.18);
}

.confirmation.preview-sms-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}

.confirmation.preview-sms-templates {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.confirmation.preview-sms-card {
    border: 1px solid rgba(148, 196, 255, 0.22);
    border-radius: 8px;
    padding: 0.55rem 0.7rem;
    background: rgba(21, 33, 50, 0.55);
}

.confirmation.preview-sms-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 0.35rem;
}

.confirmation.preview-sms-rule-name {
    font-weight: 600;
    color: rgba(232, 240, 252, 0.95);
    font-size: 0.85rem;
}

.confirmation.preview-sms-template-name {
    font-size: 0.7rem;
}

.confirmation.preview-sms-body {
    width: 100%;
    min-height: 5.5em;
    background: rgba(0, 0, 0, 0.32);
    color: rgba(232, 240, 252, 0.95);
    border: 1px solid rgba(148, 196, 255, 0.18);
    border-radius: 6px;
    padding: 0.5rem 0.6rem;
    font: inherit;
    font-size: 0.85rem;
    resize: vertical;
    box-sizing: border-box;
    margin-bottom: 0.45rem;
}

.confirmation.preview-sms-body:focus {
    outline: 1px solid rgba(148, 196, 255, 0.35);
}

.confirmation.preview-sms-note {
    font-size: 0.74rem;
    margin: 0.5rem 0 0;
    color: rgba(255, 255, 255, 0.55);
}

/* ============================================================
   LIGHT THEME  (added 2026-05-30)
   Applied when <html data-theme="light"> (set in html_head.php from the
   user's users.theme_mode). This block lives at the END of app.css — the
   last stylesheet in the cascade — so it overrides BOTH cwdb-tokens.css's
   :root and the unprefixed :root alias block at the top of this file.
   Flips the ~16 base tokens (which app.css consumes via var() ~869x) plus
   the most visible hardcoded-dark surfaces (page bg, top nav, shadows).
   ============================================================ */
:root[data-theme="light"] {
    /* unprefixed aliases (top of app.css) */
    --bg: #eef2f8;
    --surface: #ffffff;
    --surface-2: #f5f8fc;
    --surface-3: #e9eff7;
    --text: #16202e;
    --muted: #56657c;
    --accent: #0a6193;
    --accent-2: #6a4ee8;
    --danger: #d3315a;
    --danger-ink: #b91c1c; /* danger emphasis text — dark red on pale red tints (light mode) */
    --shadow-rgb: 30, 50, 80; /* soft blue-grey shadow for light surfaces */
    --border: rgba(30, 60, 100, 0.18);
    --glow: 0 0 0 1px rgba(14, 127, 184, 0.22), 0 0 24px rgba(14, 127, 184, 0.12);

    /* cwdb-prefixed tokens (cwdb-tokens.css) */
    --cwdb-bg: #eef2f8;
    --cwdb-surface: #ffffff;
    --cwdb-surface-2: #f5f8fc;
    --cwdb-surface-3: #e9eff7;
    --cwdb-text: #16202e;
    --cwdb-muted: #56657c;
    --cwdb-accent: #0a6193;
    --cwdb-accent-2: #6a4ee8;
    --cwdb-danger: #d3315a;
    --cwdb-border: rgba(30, 60, 100, 0.18);
    --cwdb-glow: 0 0 0 1px rgba(14, 127, 184, 0.22), 0 0 24px rgba(14, 127, 184, 0.12);

    /* shadows — lighter neutral ink, lower alpha on white */
    --shadow-sm: 0 4px 12px rgba(30, 50, 80, 0.10);
    --shadow-md: 0 12px 26px rgba(30, 50, 80, 0.12);
    --shadow-lg: 0 18px 42px rgba(30, 50, 80, 0.18);
    --shadow-hover: 0 8px 18px rgba(30, 50, 80, 0.14);
    --shadow-inset-top: inset 0 1px 0 rgba(255, 255, 255, 0.7);

    /* gradients — light surfaces */
    --gradient-panel: linear-gradient(160deg, var(--white), #f5f8fc);
    --gradient-hero: linear-gradient(135deg, var(--white), #eef3fb);
    --gradient-header: linear-gradient(180deg, #f7faff, #eef3fb);
    --gradient-btn: linear-gradient(180deg, var(--white), #eef2f8);
    --gradient-btn-primary: linear-gradient(180deg, #1391c9, #0e6fa6);
    --gradient-page-bg: radial-gradient(1200px 700px at 20% -10%, rgba(14, 127, 184, 0.10), transparent 60%);
}

/* Hardcoded-color hotspots that don't read a token — override under light. */
:root[data-theme="light"],
:root[data-theme="light"] body {
    background: radial-gradient(1200px 700px at 20% -10%, rgba(14, 127, 184, 0.08), transparent 60%), var(--bg);
}
html[data-theme="light"] .top-nav {
    background: rgba(255, 255, 255, 0.9);
}

/* Light theme — shared surface classes that hardcode the dark gradient
   literals (rgba(20,31,47,*) / rgba(13,20,31,*)) instead of reading
   --gradient-panel. Re-point the dominant shared surfaces at the (now light)
   gradient tokens. Per-component panels that use bespoke classes are the
   remaining tokenizing pass. */
:root[data-theme="light"] .panel {
    background: var(--gradient-panel);
}
:root[data-theme="light"] .ws-page-header,
:root[data-theme="light"] .page-header {
    background: var(--gradient-hero);
}
:root[data-theme="light"] .db-filter-bar {
    background: linear-gradient(rgba(255, 255, 255, 0.66), rgba(244, 247, 252, 0.55));
}
/* Form controls that hardcode a dark fill. */
:root[data-theme="light"] input,
:root[data-theme="light"] select,
:root[data-theme="light"] textarea {
    background-color: var(--white);
    color: var(--text);
}


/* ============================================================
   LIGHT THEME — per-component overrides (light-mode-polish workflow,
   2026-05-30). Re-points hardcoded-dark surfaces across database /
   confirmation / routing / messages / atsb / employee-stats / shared
   chrome to the light palette. Every rule is :root[data-theme="light"]
   scoped, so dark mode is untouched.
   ============================================================ */
/* --- light overrides: Shared Chrome Light Mode Overrides (Modals, Drawers, Popovers, Buttons, Tabs, Badges, Pills, Tooltips) (31 selectors) --- */
:root[data-theme="light"] .confirmation.modal-backdrop {
    background: rgba(20, 40, 70, 0.35);
}

:root[data-theme="light"] .confirmation.modal-card {
    background: var(--gradient-panel);
    box-shadow: 0 20px 48px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .atsb-test-jobs-popover {
    background: var(--gradient-panel);
    box-shadow: 0 12px 32px rgba(30, 50, 80, 0.12), 0 0 0 1px rgba(30, 50, 80, 0.08);
}

:root[data-theme="light"] .atsb-test-jobs-popover-head {
    background: rgba(14, 127, 184, 0.06);
}

:root[data-theme="light"] .atsb-test-jobs-popover-item {
    background: #f5f8fc;
}

:root[data-theme="light"] .atsb-test-jobs-popover-item.is-clickable:hover {
    background: rgba(14, 127, 184, 0.08);
}

:root[data-theme="light"] .atsb-test-modal-backdrop {
    background: rgba(20, 40, 70, 0.35);
}

:root[data-theme="light"] .atsb-test-modal-card {
    background: var(--gradient-panel);
    box-shadow: 0 16px 36px rgba(30, 50, 80, 0.12), 0 0 0 1px rgba(30, 50, 80, 0.08);
}

:root[data-theme="light"] .atsb-test-modal-head {
    background: rgba(14, 127, 184, 0.06);
}

:root[data-theme="light"] .atsb-test-modal-actions {
    background: rgba(14, 127, 184, 0.03);
}

:root[data-theme="light"] .routing-modal-backdrop {
    background: rgba(20, 40, 70, 0.35);
}

:root[data-theme="light"] .routing-modal {
    background: var(--gradient-panel);
    box-shadow: 0 20px 50px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .routing-modal-head {
    background: rgba(14, 127, 184, 0.06);
}

:root[data-theme="light"] .routing-modal-head-link {
    background: #f5f8fc;
}

:root[data-theme="light"] .routing-modal-head-link:hover {
    background: rgba(14, 127, 184, 0.08);
}

:root[data-theme="light"] .routing-modal-summary {
    background: #f5f8fc;
}

:root[data-theme="light"] .btn-primary {
    background: linear-gradient(180deg, #1391c9, #0e6fa6);
}

:root[data-theme="light"] .btn-primary:hover {
    background: linear-gradient(180deg, #1ba0d8, #0f7eb5);
}

:root[data-theme="light"] .top-nav.top-nav-v2 {
    background: rgba(255, 255, 255, 0.9);
}

:root[data-theme="light"] .confirmation.detail-drawer {
    background: var(--gradient-panel);
}

:root[data-theme="light"] .confirmation.save-toast {
    background: var(--gradient-panel);
    box-shadow: 0 12px 26px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .confirmation.preview-send-toggle {
    background: #f5f8fc;
}

:root[data-theme="light"] .confirmation.preview-sms-card {
    background: #f5f8fc;
}

:root[data-theme="light"] .confirmation.preview-sms-body {
    background: var(--white);
}


/* --- light overrides: Database Light Mode Overrides (15 selectors) --- */
:root[data-theme="light"] .db-filter-bar {
    background: linear-gradient(180deg, rgba(245, 248, 252, 0.8), rgba(233, 239, 247, 0.7));
}

:root[data-theme="light"] .db-list-wrap {
    background: rgba(255, 255, 255, 0.6);
}

:root[data-theme="light"] .db-list-table thead th {
    background: rgba(255, 255, 255, 0.95);
}

:root[data-theme="light"] .db-pager-btn {
    background: rgba(200, 210, 230, 0.4);
}

:root[data-theme="light"] .db-pager-btn:hover:not(.is-disabled) {
    background: rgba(200, 210, 230, 0.6);
}

:root[data-theme="light"] .db-edit-input {
    background: rgba(230, 240, 250, 0.5);
}

:root[data-theme="light"] .db-edit-input:hover:not(:focus):not(:disabled) {
    background: rgba(210, 225, 245, 0.6);
}

:root[data-theme="light"] .db-edit-input:focus {
    background: rgba(245, 250, 255, 0.8);
}

:root[data-theme="light"] .db-detail-modal-backdrop {
    background: rgba(80, 100, 150, 0.35);
}

:root[data-theme="light"] .db-detail-drawer.is-modal .db-drawer-head {
    background: var(--surface-2);
}

:root[data-theme="light"] .db-detail-drawer.is-modal .db-drawer-section {
    background: rgba(240, 245, 252, 0.5);
}

:root[data-theme="light"] .db-detail-drawer .db-drawer-head {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(245, 248, 252, 0.98));
}

:root[data-theme="light"] .db-row {
    background: transparent;
}

@media (max-width: 720px) {
    :root[data-theme="light"] .db-row {
        background: rgba(240, 245, 252, 0.5);
    }
}

/* --- light overrides: Confirmation Inbox Light Mode CSS Overrides (18 selectors) --- */
:root[data-theme="light"] .confirmation.modal-backdrop {
    background: rgba(20, 40, 70, 0.35);
}

:root[data-theme="light"] .confirmation.modal-card {
    background: linear-gradient(180deg, var(--surface), var(--surface));
    box-shadow: 0 20px 48px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .confirmation.detail-modal-backdrop {
    background: rgba(20, 40, 70, 0.35);
}

:root[data-theme="light"] .confirmation.detail-drawer.is-modal {
    box-shadow: 0 24px 60px rgba(30, 50, 80, 0.12), 0 0 0 1px rgba(100, 100, 120, 0.15);
}

:root[data-theme="light"] .confirmation.detail-modal-head {
    background: var(--surface-2);
}

:root[data-theme="light"] .confirmation.inbox-toolbar {
    background: linear-gradient(180deg, var(--surface-2), var(--surface-2));
}

:root[data-theme="light"] .confirmation.reminder-preview {
    background: var(--surface-3);
}

:root[data-theme="light"] .confirmation.job-card {
    background: linear-gradient(170deg, var(--surface), var(--surface));
    box-shadow: 0 10px 20px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .confirmation.job-card:hover {
    box-shadow: 0 14px 26px rgba(30, 50, 80, 0.15);
}

:root[data-theme="light"] .confirmation.lane {
    background: linear-gradient(180deg, var(--surface-2), var(--surface));
    box-shadow: 0 12px 28px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .confirmation.lane-header {
    background: linear-gradient(180deg, var(--surface-2), var(--surface-2));
}

:root[data-theme="light"] .confirmation.lane-count {
    background: var(--surface-3);
}

:root[data-theme="light"] .confirmation.save-toast {
    background: linear-gradient(170deg, var(--surface-2), var(--surface));
    box-shadow: 0 12px 24px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .confirmation.save-toast.is-error {
    background: linear-gradient(170deg, var(--surface), var(--surface));
}

:root[data-theme="light"] .confirmation.time-bubble {
    background: linear-gradient(135deg, var(--surface-2), var(--surface-2));
}

/* --- light overrides: routing (52 selectors) --- */
:root[data-theme="light"] .routing.corner {
    background: var(--surface-2);
}

:root[data-theme="light"] .routing.day-head {
    background: var(--surface-2);
}

:root[data-theme="light"] .routing.period-head {
    background: var(--surface-3);
}

:root[data-theme="light"] .routing.grid-cell {
    background: var(--surface);
}

:root[data-theme="light"] .routing.grid-cell:hover {
    background: var(--surface-2);
}

:root[data-theme="light"] .routing.grid-cell.is-selected {
    background: rgba(14, 127, 184, 0.08);
}

:root[data-theme="light"] .routing-v2-header {
    background: rgba(255, 255, 255, 0.8);
}

:root[data-theme="light"] .routing-v2-btn {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-v2-btn:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: rgba(14, 127, 184, 0.35);
}

:root[data-theme="light"] .routing-v2-picker {
    background: var(--surface);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-v2-list {
    background: var(--surface);
}

:root[data-theme="light"] .routing-v2-mapwrap,
:root[data-theme="light"] .routing-v2-map {
    background: #f0f4fa;
}

:root[data-theme="light"] .routing-v2-period-head {
    background: rgba(255, 255, 255, 0.7);
}

:root[data-theme="light"] .routing-v2-card {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-v2-card:hover,
:root[data-theme="light"] .routing-v2-card:focus-visible,
:root[data-theme="light"] .routing-v2-card.is-hover {
    background: var(--surface-3);
    border-color: rgba(14, 127, 184, 0.35);
}

:root[data-theme="light"] .routing-v2-legend {
    background: rgba(255, 255, 255, 0.75);
}

:root[data-theme="light"] .routing-v2-day-total {
    background: rgba(255, 255, 255, 0.75);
}

:root[data-theme="light"] .routing-modal-backdrop {
    background: rgba(20, 40, 70, 0.35);
}

:root[data-theme="light"] .routing-modal {
    background: var(--gradient-panel);
}

:root[data-theme="light"] .routing-modal-head {
    background: var(--surface-3);
}

:root[data-theme="light"] .routing-modal-head-link {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-modal-head-link:hover {
    background: var(--surface-3);
    border-color: rgba(14, 127, 184, 0.35);
}

:root[data-theme="light"] .routing-modal-summary {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-modal-select {
    background-color: var(--surface);
    border-color: rgba(30, 60, 100, 0.18);
    color-scheme: light;
    /* Darker caret for the light surface. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%231e3c64' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

:root[data-theme="light"] .routing-modal-foot {
    background: var(--surface-2);
}

:root[data-theme="light"] .routing-modal-drive-preview {
    background: var(--surface-3);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-jnrow {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-jnrow.is-pending {
    border-color: rgba(14, 127, 184, 0.35);
    background: rgba(14, 127, 184, 0.04);
}

:root[data-theme="light"] .routing-jnrow.is-ok {
    border-color: rgba(34, 197, 94, 0.35);
    background: rgba(34, 197, 94, 0.04);
}

:root[data-theme="light"] .routing-jnrow.is-error {
    border-color: rgba(211, 49, 90, 0.35);
    background: rgba(211, 49, 90, 0.04);
}

:root[data-theme="light"] .routing-settings-row {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-settings-reset {
    border-color: rgba(30, 60, 100, 0.18);
}

:root[data-theme="light"] .routing-settings-reset:hover:not(:disabled) {
    border-color: rgba(14, 127, 184, 0.35);
    background: var(--surface-3);
}

:root[data-theme="light"] .cwdb-leg-label-inner {
    background: rgba(255, 255, 255, 0.85);
    border-color: rgba(14, 127, 184, 0.35);
    box-shadow: 0 4px 12px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .leaflet-container .leaflet-tooltip {
    background: rgba(255, 255, 255, 0.85);
    border-color: rgba(14, 127, 184, 0.35);
    box-shadow: 0 4px 12px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .leaflet-container .leaflet-tooltip-top::before {
    border-top-color: rgba(14, 127, 184, 0.35);
}

:root[data-theme="light"] .leaflet-container .leaflet-control-attribution {
    background: rgba(255, 255, 255, 0.7);
}

:root[data-theme="light"] .cwdb-route-tip-wrap.leaflet-tooltip {
    background: rgba(255, 255, 255, 0.9);
    border-color: rgba(14, 127, 184, 0.35);
    box-shadow: 0 6px 16px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .routing-v2-viewtoggle-btn {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}

@media (max-width: 880px) {
    :root[data-theme="light"] .routing-v2-list {
        border-bottom-color: rgba(30, 60, 100, 0.18);
    }
}

:root[data-theme="light"] .atsb-ws .atsb-test-grid thead .atsb-planner-corner {
    background: linear-gradient(180deg, var(--surface-2), var(--surface-3));
}

:root[data-theme="light"] .atsb-ws .atsb-test-grid tbody th.atsb-planner-period {
    background: var(--surface);
}

/* --- light overrides: Messages/SMS Console - Light Mode Overrides (46 selectors) --- */
:root[data-theme="light"] .msg-sidebar {
  background: var(--surface);
  border-right: 1px solid var(--border);
}

:root[data-theme="light"] .msg-side-head {
  border-bottom: 1px solid var(--border);
}

:root[data-theme="light"] .msg-search {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
}

:root[data-theme="light"] .msg-search:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(14, 127, 184, 0.08);
}

:root[data-theme="light"] .msg-convo-list::-webkit-scrollbar-thumb {
  background: rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .msg-convo {
  border-bottom: 1px solid var(--border);
}

:root[data-theme="light"] .msg-convo:hover {
  background: rgba(102, 214, 255, 0.04);
}

:root[data-theme="light"] .msg-convo-time {
  color: var(--muted);
}

:root[data-theme="light"] .msg-convo.has-unread .msg-convo-last {
  color: var(--text);
}

:root[data-theme="light"] .msg-unread-dot {
  border: 2px solid var(--surface);
}

:root[data-theme="light"] .msg-side-foot {
  border-top: 1px solid var(--border);
}

:root[data-theme="light"] .msg-new-btn {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--white);
}

:root[data-theme="light"] .msg-thread-head {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

:root[data-theme="light"] .msg-bubbles {
  background: var(--bg);
}

:root[data-theme="light"] .msg-bubbles::-webkit-scrollbar-thumb {
  background: rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .msg-bubble-in .msg-bubble-body {
  background: var(--surface-2);
  border: 1px solid var(--border);
}

:root[data-theme="light"] .msg-bubble-out .msg-bubble-body {
  background: var(--accent);
  color: var(--white);
  border: none;
}

:root[data-theme="light"] .msg-composer {
  background: var(--surface);
  border-top: 1px solid var(--border);
}

:root[data-theme="light"] .msg-templates {
  background: var(--surface-2);
  border: 1px solid var(--border);
}

:root[data-theme="light"] .msg-input {
  background: var(--surface-3);
  border: 1px solid var(--border);
  color: var(--text);
}

:root[data-theme="light"] .msg-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(14, 127, 184, 0.08);
}

:root[data-theme="light"] .msg-send {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--white);
}

:root[data-theme="light"] .msg-send:disabled {
  background: var(--surface-3);
  border-color: var(--border);
  color: var(--muted);
}

:root[data-theme="light"] .msg-context {
  background: var(--surface);
  border-left: 1px solid var(--border);
}

:root[data-theme="light"] .msg-context-divided {
  border-top: 1px solid var(--border);
}

:root[data-theme="light"] .msg-context-sub {
  color: var(--muted);
}

:root[data-theme="light"] .msg-action-link {
  background: var(--surface-2);
  border: 1px solid var(--border);
}

:root[data-theme="light"] .msg-action-link:hover {
  background: var(--surface-3);
  border-color: var(--accent);
}

:root[data-theme="light"] .msg-back-btn {
  background: transparent;
  border: 1px solid var(--border);
}

:root[data-theme="light"] .msg-back-btn:hover {
  background: var(--surface-2);
  border-color: var(--accent);
}

@media (max-width: 720px) {
  :root[data-theme="light"] .top-nav-mobile-drawer {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
  }

  :root[data-theme="light"] .top-nav-mobile-backdrop {
    background: rgba(20, 40, 70, 0.35);
  }

  :root[data-theme="light"] .top-nav-mobile-link {
    border-bottom: 1px solid var(--border);
  }

  :root[data-theme="light"] .top-nav-mobile-link.is-active {
    background: var(--surface-2);
  }

  :root[data-theme="light"] .top-nav-mobile-signout-form {
    background: var(--surface-2);
    border-top: 1px solid var(--border);
  }
}

/* --- light overrides: atsb_stats (21 selectors) --- */
:root[data-theme="light"] .employee.stats-tabs {
    background: linear-gradient(180deg, var(--gradient-panel), var(--gradient-panel));
    box-shadow: inset 0 1px 0 rgba(var(--shadow-rgb), 0.04), 0 10px 24px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .employee.stats-tab {
    background: linear-gradient(180deg, var(--surface-2), var(--surface-2));
}

:root[data-theme="light"] .employee.stats-tab:hover {
    background: linear-gradient(180deg, var(--surface-3), var(--surface-3));
    box-shadow: 0 6px 14px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .employee.stats-section .stats.card {
    background: linear-gradient(180deg, var(--surface), var(--surface-2));
}

:root[data-theme="light"] .employee.week-picker-menu {
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 14px 30px rgba(30, 50, 80, 0.12);
}

:root[data-theme="light"] .employee.week-picker-nav {
    background: var(--surface-2);
}

:root[data-theme="light"] .employee.week-picker-nav:hover {
    background: var(--surface-3);
}

:root[data-theme="light"] .employee.week-picker-row {
    background: var(--surface-2);
}

:root[data-theme="light"] .employee.week-picker-row:hover {
    background: var(--surface-3);
}

:root[data-theme="light"] .atsb-slots-table-wrap {
    background: var(--surface-2);
}

:root[data-theme="light"] .atsb-slots-table thead th {
    background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
}

:root[data-theme="light"] .atsb-planner-settings {
    background: linear-gradient(180deg, var(--surface), var(--surface-2));
}

:root[data-theme="light"] .atsb-planner-gridwrap {
    background: var(--surface-2);
    background-image: linear-gradient(to right, transparent calc(100% - 36px), rgba(233, 239, 247, 0.55) 100%);
}

:root[data-theme="light"] .atsb-planner-grid thead th {
    background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
}

:root[data-theme="light"] .atsb-planner-send {
    background: var(--surface-2);
}

:root[data-theme="light"] .atsb-planner-send input {
    background: var(--surface-3);
}

:root[data-theme="light"] .atsb-planner-cell {
    background: var(--surface-2);
}

:root[data-theme="light"] .atsb-planner-cell.is-pad {
    background: var(--surface-3);
}

:root[data-theme="light"] .atsb-planner-slot {
    background: var(--surface-2);
}

:root[data-theme="light"] .atsb-planner-summary {
    background: var(--surface-2);
}

:root[data-theme="light"] .atsb-ws .atsb-test-toolbar {
    background: linear-gradient(180deg, var(--surface), var(--surface-2));
}

/* Light theme — remaining list-table header strips (the most visible
   cross-page dark remnant). */
:root[data-theme="light"] .confirmation.inbox-table thead th,
:root[data-theme="light"] .disp-table thead th,
:root[data-theme="light"] .smsact-table thead th,
:root[data-theme="light"] .smsq-table thead th {
    background: var(--surface-3);
    color: var(--muted);
}

/* Light theme — employee-stats data-table header strip. */
:root[data-theme="light"] .empstats-table thead th,
:root[data-theme="light"] .empstats-table thead {
    background: var(--surface-3);
    color: var(--muted);
}

/* Light theme — routing header/toolbar + card text were tuned light-on-dark;
   set the inherited base color to dark so titles/labels read on light. */
:root[data-theme="light"] .routing-v2-header,
:root[data-theme="light"] .routing-v2-header .routing-v2-title,
:root[data-theme="light"] .routing-v2-list,
:root[data-theme="light"] .routing-v2-card,
:root[data-theme="light"] .routing-v2-period-head {
    color: var(--text);
}
:root[data-theme="light"] .routing-v2-btn,
:root[data-theme="light"] .routing-v2-day-total {
    color: var(--text);
}

/* Light theme — confirmation inbox dark wrappers (the row-action cell + the
   list backdrop made the action column look dark even though the Confirm
   button itself is light) + the modal slot-picker option. */
:root[data-theme="light"] .confirmation.inbox-list-wrap {
    background: rgba(255, 255, 255, 0.55);
}
:root[data-theme="light"] .confirmation.inbox-actions-cell-wrap {
    background: transparent;
}
:root[data-theme="light"] .confirmation.slot-option {
    background: var(--surface-2);
}

/* Light theme — table text contrast: hardcoded light cell/chip text that
   fails on light surfaces. Scoped to light so dark mode is untouched. */
:root[data-theme="light"] .db-cell-marketer,
:root[data-theme="light"] .db-cell-status {
    color: var(--text);
}
:root[data-theme="light"] .db-row-chip-ok { color: var(--success-ink); }
:root[data-theme="light"] .db-row-chip-warning { color: var(--warning-ink); }
:root[data-theme="light"] .db-row-chip-danger { color: #c01f44; }
:root[data-theme="light"] .db-row-chip-muted { color: var(--muted); }

/* Light theme — generic .table header cells (thead + tfoot/totals rows).
   The base `.table th` hardcodes #bad0e8 text on a dark gradient, which is
   invisible (1.4:1) on a light surface. The more-specific
   `.empstats-table thead th` rule above still wins for the column header
   strip; this catches the tfoot totals row and every other `.table`-classed
   header (database / confirmation / disposition / admin) in light mode. */
:root[data-theme="light"] .table th {
    color: var(--text);
    background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
}

/* Light theme — hero/page tag pills (the small uppercase cyan badges next to
   page titles). Base text is near-white (var(--accent-pale)) on a faint cyan tint —
   invisible (≈1:1) on a light surface. Repaint as accent text on a defined
   accent pill. Covers every bespoke variant so they stay one design token. */
:root[data-theme="light"] .db-hero-tag,
:root[data-theme="light"] .confirm-hero-tag,
:root[data-theme="light"] .disp-hero-tag,
:root[data-theme="light"] .atsb-ws-hero-tag,
:root[data-theme="light"] .page-tag {
    background: rgba(10, 97, 147, 0.12);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--accent);
}

/* ===== Light theme — chip / badge / pill text families ===== */
/* The .db-chip tone system + confirmation hero/scope/refresh pills hardcode
   LIGHT text (near-white / light-tinted per hue) designed for dark tinted-pill
   backgrounds. In light mode the tint turns pale and that light text drops to
   ~1.1–1.5:1 (invisible). Repaint each to a dark, saturated same-hue color
   that clears WCAG-AA on the pale tint. The color on .db-chip-<tone> cascades
   to the inner .db-chip-label (which carries no own color). All rules are
   [data-theme="light"]-scoped, so dark mode is mathematically unaffected. */
:root[data-theme="light"] .db-chip-green  { color: var(--success-ink); }
:root[data-theme="light"] .db-chip-red    { color: var(--danger-deep); }
:root[data-theme="light"] .db-chip-amber  { color: var(--warning-ink); }
:root[data-theme="light"] .db-chip-cyan   { color: var(--accent-deep); }
:root[data-theme="light"] .db-chip-violet { color: #6b21a8; }
:root[data-theme="light"] .db-chip-orange { color: #9a3412; }

:root[data-theme="light"] .confirmation.inbox-lead-received { color: var(--accent-deep); }
:root[data-theme="light"] .confirmation.inbox-refresh-btn { color: var(--accent-deep); }
:root[data-theme="light"] .confirm-hero-clock-time { color: var(--text); }

:root[data-theme="light"] .confirm-scope-chip.is-active[data-tone="cyan"]  { color: var(--accent-deep); }
:root[data-theme="light"] .confirm-scope-chip.is-active[data-tone="green"] { color: var(--success-ink); }
:root[data-theme="light"] .confirm-scope-chip.is-active[data-tone="amber"] { color: #9a3412; }
:root[data-theme="light"] .confirm-scope-chip.is-active[data-tone="red"]   { color: var(--danger-deep); }

/* ===== Light theme — /messages SMS console ===== */
/* The messages "refresh" block (~14820–15011) re-hardcodes white / light-tinted
   text for what was a dark console panel; in light mode the panels turn pale so
   that text collapses to ~1:1. Repaint each to tokens / dark same-hue colors.
   All [data-theme="light"]-scoped → dark console is unaffected. */
:root[data-theme="light"] .msg-convo-last { color: var(--muted); }
:root[data-theme="light"] .msg-convo.is-active .msg-convo-name { color: var(--text); }
:root[data-theme="light"] .msg-convo-address { color: var(--muted); }
:root[data-theme="light"] .msg-thread-name { color: var(--text); }
:root[data-theme="light"] .msg-thread-phone { color: var(--muted); }
:root[data-theme="light"] .msg-context-value-strong { color: var(--text); }
:root[data-theme="light"] .msg-action-arrow { color: var(--accent); }
:root[data-theme="light"] .msg-avatar,
:root[data-theme="light"] .msg-avatar-letter { color: var(--accent-deep); }
:root[data-theme="light"] .msg-subnav-badge { color: var(--warning-ink); }
:root[data-theme="light"] .msg-unread-dot { background: #d61f44; color: var(--white); }
/* product chips — darken the tone vars so the uppercase label reads on white */
:root[data-theme="light"] .msg-product-chip { --msg-product-color: #3a5573; }
:root[data-theme="light"] .msg-product-chip[data-product="windows"] { --msg-product-color: var(--accent-deep); }
:root[data-theme="light"] .msg-product-chip[data-product="siding"]  { --msg-product-color: var(--warning-ink); }
:root[data-theme="light"] .msg-product-chip[data-product="roofing"] { --msg-product-color: #6b21a8; }

/* Light theme — /messages stragglers: context panel, templates toggle,
   timeline labels, status pills, action links (all hardcoded light/white in
   the dark-console refresh block). Tone classes darkened per hue. */
:root[data-theme="light"] .msg-context-value { color: var(--text); }
:root[data-theme="light"] .msg-templates-toggle,
:root[data-theme="light"] .msg-templates-toggle.is-on,
:root[data-theme="light"] .msg-templates-chev,
:root[data-theme="light"] .msg-templates-toggle.is-on .msg-templates-chev,
:root[data-theme="light"] .msg-context-toggle-arrow { color: var(--text); }
:root[data-theme="light"] .msg-templates-head a { color: var(--accent); }
:root[data-theme="light"] .msg-templates-head a:hover { color: #08364f; }
:root[data-theme="light"] .msg-timeline-label { color: var(--text); }
:root[data-theme="light"] .msg-tl-good .msg-timeline-label { color: var(--success-ink); }
:root[data-theme="light"] .msg-tl-bad  .msg-timeline-label { color: var(--danger-deep); }
:root[data-theme="light"] .msg-tl-warn .msg-timeline-label { color: var(--warning-ink); }
:root[data-theme="light"] .msg-action-link { color: var(--accent-deep); }
:root[data-theme="light"] .msg-status-lead { color: #3a5573; }
:root[data-theme="light"] .msg-status-confirmed,
:root[data-theme="light"] .msg-status-won { color: var(--success-ink); }
:root[data-theme="light"] .msg-status-declined,
:root[data-theme="light"] .msg-status-lost { color: var(--danger-deep); }
:root[data-theme="light"] .msg-status-demoed { color: var(--accent-deep); }

/* Light theme — /admin avatars + badges (light text on dark tint pills). */
:root[data-theme="light"] .admin-avatar,
:root[data-theme="light"] .admin-avatar-lg { color: var(--accent-deep); }
:root[data-theme="light"] .admin-badge-violet { background: rgba(140, 125, 255, 0.14); color: #5b21b6; }
:root[data-theme="light"] .admin-badge-green  { background: rgba(34, 197, 94, 0.14); color: var(--success-ink); }

/* Light theme — ATSB planner same-day / setting chips (light text on tint). */
:root[data-theme="light"] .atsb-ws .atsb-test-sameday-chip { color: var(--warning-ink); }
:root[data-theme="light"] .atsb-ws .atsb-test-setting-chip { color: var(--success-ink); }

/* Light theme — routing board card rep names, error states, today badge
   (light cyan / light red hardcoded for the dark board). */
:root[data-theme="light"] .routing-v2-card-rep { color: var(--text); }
:root[data-theme="light"] .routing-v2-card-rep.is-empty,
:root[data-theme="light"] .routing-v2-status.is-error,
:root[data-theme="light"] .routing-v2-day-total-error { color: var(--danger-deep); }
:root[data-theme="light"] .routing-v2-todaybadge { color: var(--accent-deep); }

/* Light theme — /settings: amber role badges, danger alert, device toggle
   enabled/disabled states, remove button, and the theme-swatch check glyph
   (which sits on the now-darker accent circle, so flip it to white). */
:root[data-theme="light"] .settings-hero-role-admin,
:root[data-theme="light"] .settings-card-badge { color: var(--warning-ink); }
:root[data-theme="light"] .alert-error {
    background: #fdeaea;
    border-color: rgba(185, 28, 28, 0.3);
    color: var(--danger-deep);
}
:root[data-theme="light"] .notif-device-toggle:has(input:checked) { color: var(--success-ink); }
:root[data-theme="light"] .notif-device-toggle:not(:has(input:checked)),
:root[data-theme="light"] .notif-device-remove { color: var(--danger-deep); }
:root[data-theme="light"] .theme-card-check { color: var(--white); }

/* Light theme — DB drawer "hide from calendar" toggle title (amber when on). */
:root[data-theme="light"] .db-detail-drawer.is-modal .db-hidden-toggle:has(input:checked) .db-hidden-toggle-title { color: var(--warning-ink); }

/* ============================================================
   Light theme — interactive controls (dark hover/resting sweep)
   The dark theme hardcoded DARK backgrounds in :hover (a "darken on
   hover" lift) and dark resting fills on secondary controls/cards.
   In light mode those stayed dark, so buttons "turned dark" on hover
   and cards/toggles read as leftover dark patches. Found via the
   lightmode-hover-history-sweep workflow. All [data-theme="light"]-
   scoped → dark mode (the default) is byte-for-byte unaffected.
   ============================================================ */

/* Global secondary button — base was a dark gradient + dark hover.
   (.btn-primary already has its own light override and still wins.) */
:root[data-theme="light"] .btn {
    background: var(--surface-2);
    border-color: var(--border);
    color: var(--text);
    box-shadow: 0 4px 12px rgba(30, 50, 80, 0.08);
}
:root[data-theme="light"] .btn:hover {
    background: var(--surface-3);
    border-color: rgba(14, 127, 184, 0.35);
    color: var(--text);
}

:root[data-theme="light"] .top-nav-collapsed-toggle:hover {
    background: rgba(10, 97, 147, 0.08);
    color: var(--text);
}

/* Confirmation quick-action buttons */
:root[data-theme="light"] .confirmation.action-btn.is-nogo:hover:not(:disabled) {
    background: rgba(185, 28, 28, 0.10);
    border-color: rgba(185, 28, 28, 0.55);
    color: var(--danger-deep);
}
:root[data-theme="light"] .confirmation.action-btn.is-cancel:hover:not(:disabled) {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--text);
}
:root[data-theme="light"] .confirmation.action-btn.is-cancel-disposition,
:root[data-theme="light"] .confirmation.action-btn.is-cancel-disposition:hover:not(:disabled) {
    background: rgba(185, 28, 28, 0.10);
    border-color: rgba(185, 28, 28, 0.55);
    color: var(--danger-deep);
}

/* Confirmation detail edit btn / phone link / slot option hovers */
:root[data-theme="light"] .confirmation.detail-edit-btn:hover,
:root[data-theme="light"] .confirmation.detail-edit-btn:focus-visible {
    background: rgba(10, 97, 147, 0.10);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--accent-deep);
}
:root[data-theme="light"] .confirmation.phone-link:hover,
:root[data-theme="light"] .confirmation.phone-link:focus-visible {
    background: rgba(10, 97, 147, 0.10);
    border-color: rgba(10, 97, 147, 0.55);
    color: var(--accent-deep);
}
:root[data-theme="light"] .confirmation.slot-option:hover:not(.is-disabled) {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--text);
}

/* Confirmation scope-filter chips — dark resting + dark hover */
:root[data-theme="light"] .confirm-scope-chip {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
    color: var(--muted);
}
:root[data-theme="light"] .confirm-scope-chip:hover:not(.is-active) {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--text);
}

:root[data-theme="light"] .disp-undo-btn:hover {
    background: rgba(138, 90, 12, 0.10);
    color: var(--warning-ink);
}

:root[data-theme="light"] .routing-v2-btn.is-danger:hover:not(:disabled) {
    background: rgba(185, 28, 28, 0.10);
    border-color: rgba(185, 28, 28, 0.55);
    color: var(--danger-deep);
}

/* ATSB job-popover buttons (reassign / open-in-db ghost / remove) */
:root[data-theme="light"] .atsb-test-jobs-popover-actions .atsb-test-jobs-reassign-btn,
:root[data-theme="light"] .atsb-test-jobs-popover-actions .atsb-test-jobs-reassign-btn:hover:not(:disabled) {
    background: rgba(10, 97, 147, 0.10);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--accent-deep);
}
:root[data-theme="light"] .atsb-test-jobs-popover-actions .btn.btn-ghost {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
    color: var(--text);
}
:root[data-theme="light"] .atsb-test-jobs-popover-actions .btn.btn-ghost:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: rgba(14, 127, 184, 0.35);
    color: var(--text);
}
:root[data-theme="light"] .atsb-test-jobs-remove-btn,
:root[data-theme="light"] .atsb-test-jobs-remove-btn:hover:not(:disabled) {
    background: rgba(185, 28, 28, 0.10);
    border-color: rgba(185, 28, 28, 0.5);
    color: var(--danger-deep);
}

/* Admin user cards / pick-user rows — dark resting + dark hover */
:root[data-theme="light"] .admin-user-card,
:root[data-theme="light"] .admin-pick-user {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
    color: var(--text);
}
:root[data-theme="light"] .admin-user-card:hover,
:root[data-theme="light"] .admin-pick-user:hover {
    background: var(--surface-3);
    border-color: rgba(14, 127, 184, 0.35);
}

/* SMS automation toggle/delete + queue reject */
:root[data-theme="light"] .smsauto-toggle:hover {
    background: rgba(22, 101, 52, 0.10);
    border-color: rgba(22, 101, 52, 0.45);
    color: var(--success-ink);
}
:root[data-theme="light"] .smsauto-delete:hover {
    background: rgba(185, 28, 28, 0.10);
    border-color: rgba(185, 28, 28, 0.5);
    color: var(--danger-deep);
}
:root[data-theme="light"] .smsq-btn-reject {
    color: var(--danger-deep);
    border-color: rgba(185, 28, 28, 0.3);
}
:root[data-theme="light"] .smsq-btn-reject:hover {
    background: rgba(185, 28, 28, 0.10);
    border-color: rgba(185, 28, 28, 0.55);
    color: var(--danger-deep);
}

/* Settings theme-card swatch container (preview child is separate, untouched) */
:root[data-theme="light"] .theme-card {
    background: var(--surface-2);
    border-color: rgba(30, 60, 100, 0.18);
}
:root[data-theme="light"] .theme-card:hover {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(14, 127, 184, 0.4);
}

/* DB drawer "Hide from calendar" toggle — dark resting + hover-to-black */
:root[data-theme="light"] .db-detail-drawer.is-modal .db-hidden-toggle {
    background: var(--surface-2);
    border-color: var(--border);
}
:root[data-theme="light"] .db-detail-drawer.is-modal .db-hidden-toggle:hover {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(14, 127, 184, 0.35);
}
:root[data-theme="light"] .db-detail-drawer.is-modal .db-hidden-toggle:has(input:checked) {
    background: rgba(138, 90, 12, 0.10);
    border-color: rgba(138, 90, 12, 0.45);
}

/* DB drawer head links — "History" (#dbDetailHistoryLink) + "Fire automation":
   dark chip with muted text on the pale sticky header -> light chip, accent text */
:root[data-theme="light"] .db-drawer-head-link {
    background: var(--surface);
    color: var(--accent);
    border-color: var(--border);
}
:root[data-theme="light"] .db-drawer-head-link:hover {
    background: rgba(10, 97, 147, 0.08);
    color: #08364f;
    border-color: rgba(10, 97, 147, 0.45);
}

/* Light theme — admin tab bar (dark gradient container; inactive tab text is
   var(--muted) which only read on the dark bar). Active tab keeps its bright
   cyan→violet gradient + dark text (theme-independent, reads fine). */
:root[data-theme="light"] .admin-tabs {
    background: var(--surface-2);
    border-color: var(--border);
}

/* Light theme — disposition stat cards + savebar (dark gradient containers;
   their values/labels use var(--text)/var(--muted) so once the card is light
   the text reads). is-warn / has-pending keep their red/amber signal as a
   pale tint instead of a dark slab. */
:root[data-theme="light"] .disp-stat {
    background: var(--surface-2);
    border-color: var(--border);
}
:root[data-theme="light"] .disp-stat.is-warn {
    background: rgba(185, 28, 28, 0.08);
    border-color: rgba(185, 28, 28, 0.30);
}
:root[data-theme="light"] .disp-savebar {
    background: var(--surface);
    border-color: var(--border);
}
:root[data-theme="light"] .disp-form.has-pending .disp-savebar {
    background: rgba(138, 90, 12, 0.10);
    border-color: rgba(138, 90, 12, 0.35);
}

/* Light theme — settings hero banner + tab bar (dark gradient containers).
   The hero avatar / H1 / username / role / tagline and the tab labels all use
   var(--text)/var(--muted)/var(--accent), so lightening the containers makes
   them read. The avatar keeps its cyan-tint gradient (pale over the light hero). */
:root[data-theme="light"] .settings-hero {
    background: linear-gradient(180deg, var(--surface), var(--surface-2));
    border-color: var(--border);
}
:root[data-theme="light"] .settings-tabs {
    background: var(--surface-2);
    border-color: var(--border);
}

/* Light theme — brand "CW" logo chip. Its bg is linear-gradient(var(--accent),
   var(--accent-2)); in dark mode that's a BRIGHT cyan gradient (dark text reads),
   but the light --accent is dark (var(--accent-deep)→#6a4ee8), so the dark var(--text) on it
   drops to ~2.8:1. White text on the dark-accent chip restores AA. */
:root[data-theme="light"] .brand-mark { color: var(--white); }

/* Light theme — /messages "compose new" footer + its template picker popover.
   The footer (.msg-side-foot) kept a dark rgba(7,11,18,0.6) fill (its existing
   light override only set border-top), and the .msg-new-tpl-* family was a
   white-on-dark popover. Both are dark slabs on the light console. */
:root[data-theme="light"] .msg-side-foot { background: var(--surface-2); }
:root[data-theme="light"] .msg-new-tpl-toggle {
    background: var(--surface-2);
    border-color: var(--border);
    color: var(--muted);
}
:root[data-theme="light"] .msg-new-tpl-toggle:hover {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(10, 97, 147, 0.45);
    color: var(--text);
}
:root[data-theme="light"] .msg-new-tpl-toggle.is-on {
    background: rgba(10, 97, 147, 0.12);
    border-color: rgba(10, 97, 147, 0.55);
    color: var(--accent);
}
:root[data-theme="light"] .msg-new-tpl-chev { color: var(--muted); }
:root[data-theme="light"] .msg-new-tpl-list {
    background: var(--surface);
    border-color: var(--border);
}
:root[data-theme="light"] .msg-new-tpl-loading,
:root[data-theme="light"] .msg-new-tpl-empty { color: var(--muted); }
:root[data-theme="light"] .msg-new-tpl-empty a { color: var(--accent); }
:root[data-theme="light"] .msg-new-tpl-chip {
    background: var(--surface-2);
    border-color: var(--border);
}
:root[data-theme="light"] .msg-new-tpl-chip:hover {
    background: rgba(10, 97, 147, 0.08);
    border-color: rgba(10, 97, 147, 0.45);
}
:root[data-theme="light"] .msg-new-tpl-name { color: var(--text); }
:root[data-theme="light"] .msg-new-tpl-cat { color: var(--muted); background: rgba(30, 60, 100, 0.08); }
:root[data-theme="light"] .msg-new-tpl-preview { color: var(--muted); }

/* Light theme — /messages borderline-contrast polish (elements on medium tints):
   - avatar initials sit on a medium-lavender circle (var(--accent-deep) letter only hit
     3.5:1) -> dark var(--text) letter reads ~7:1;
   - the "49" count badge on a pale-teal pill -> darker teal text;
   - the active conversation row's indigo tint was strong enough to pull the
     muted preview text to 4.48 -> retint to a paler accent wash so it clears AA. */
:root[data-theme="light"] .msg-avatar,
:root[data-theme="light"] .msg-avatar-letter { color: var(--text); }
:root[data-theme="light"] .msg-count { color: #08486b; }
:root[data-theme="light"] .msg-convo.is-active {
    background: linear-gradient(90deg, rgba(10, 97, 147, 0.08), rgba(10, 97, 147, 0.02) 70%, transparent);
}

/* ============================================================
   Employee Stats — print-button row + on-screen numeric polish
   (2026-06-01). Two surfaces:
     (C) .employee.table-actions — the previously-unstyled print-
         button wrapper, now a tidy right-anchored actions strip.
     (D) .empstats-table numeric alignment — right-aligned tabular
         figures + a Totals row that echoes the printed report.
   Uses existing tokens so the light-theme overrides flip cleanly.
   ============================================================ */

/* (C) Print-button row. The wrapper had no rule before — buttons just
   fell in a line. Right-anchor them with a faint top hairline so the
   strip reads as attached to the table beneath it. */
.employee.table-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    margin: 0.5rem 0 0.6rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border);
}
/* Jobs sub-table rows sit directly under an <h4> subheading — tuck them
   up so the strip hugs its heading + table (no second divider). */
.employee.stats-subheading + .employee.table-actions {
    margin-top: 0.25rem;
    padding-top: 0;
    border-top: 0;
}
.employee.table-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    letter-spacing: 0.01em;
}
.employee.table-actions .ta-ico {
    flex: 0 0 auto;
    opacity: 0.85;
}
.employee.table-actions .btn-secondary:hover {
    border-color: var(--accent);
    color: var(--text);
}

/* (D) On-screen numeric alignment — scoped to .empstats-table so the
   jobs sub-tables (.stats-jobs-table, which carry TEXT columns) are
   untouched. Column 1 is the Marketer/Rep name (a <td>) or the tfoot
   "Totals" label (a <th>) and stays LEFT; every other cell is a
   count / % / $ figure and is right-aligned with tabular figures.
   Targeting :not(:first-child) positionally is robust to the heavily
   conditional columns (Leads+CXL, Weekly/Monthly Goal, Leads Ran,
   Close %, Lead/Sold all come and go) — no per-cell class to keep in
   sync with the PHP. */
.empstats-table thead th:not(:first-child),
.empstats-table tbody td:not(:first-child),
.empstats-table tfoot th:not(:first-child),
.empstats-table tfoot td:not(:first-child) {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    white-space: nowrap;
}
.empstats-table thead th:first-child,
.empstats-table tbody td:first-child,
.empstats-table tfoot th:first-child {
    text-align: left;
    white-space: nowrap;
}
/* The empty-state "No employees found" cell spans all columns via colspan
   and is :first-child, so it stays left — reassert defensively + let it
   wrap (it can be long). Scoped to `tbody td` so it outranks the
   first-child nowrap rule above (same specificity, later in source wins).
   NB: the jobs sub-tables' Job ID cells also carry a `num` class — that is
   the print-popup right-align hook (td.num/th.num in the popup CSS); there
   is intentionally NO on-screen `.num` rule, so don't add one here. */
.empstats-table tbody td.muted-line {
    text-align: left;
    white-space: normal;
    font-variant-numeric: normal;
}
/* Mirror the printed report's emphasized Totals row on screen: brighter
   top rule + fill + heavier text, using accent/surface tokens. */
.empstats-table tfoot th {
    border-top: 2px solid var(--accent);
    background: var(--surface-3);
    color: var(--text);
    font-weight: 700;
}

/* ============================================================
   Employee Management (/employees) — roster + drawer editor.
   Scoped under .emp- so it can't leak into other pages. Uses the
   shared color/radius tokens so it themes (dark + light) for free.
   ============================================================ */
.emp-toolbar { margin-bottom: var(--space-4); }
.emp-toolbar-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
}
.emp-search,
.emp-filter-select {
    padding: 0.5rem 0.65rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    color: var(--text);
    font: inherit;
}
.emp-search { flex: 1 1 16rem; min-width: 12rem; }
.emp-filter-select { flex: 0 0 auto; }
.emp-search::placeholder { color: var(--muted); }
.emp-search:focus,
.emp-filter-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: var(--cwdb-glow);
}
.emp-toolbar-spacer { flex: 1 1 auto; }
.emp-toolbar-meta { margin: var(--space-3) 0 0; }

.emp-roster {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
    gap: var(--space-3);
}
.emp-card {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    text-align: left;
    width: 100%;
    padding: var(--space-3) var(--space-4);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    cursor: pointer;
    color: var(--text);
    transition: border-color 0.12s ease, transform 0.12s ease, box-shadow 0.12s ease;
}
.emp-card:hover {
    border-color: var(--accent);
    transform: translateY(-1px);
    box-shadow: var(--shadow-sm);
}
.emp-card:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.emp-card.is-inactive { opacity: 0.62; }
.emp-card-avatar {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    color: var(--accent);
    font-weight: 700;
    font-size: var(--text-lg);
}
.emp-card-avatar-lg { width: 3rem; height: 3rem; font-size: var(--text-xl); }
.emp-card-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.emp-card-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.emp-card-sub {
    font-size: var(--text-xs);
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.emp-card-badges {
    flex: 0 0 auto;
    display: flex;
    gap: 0.3rem;
    align-items: center;
}

.emp-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.12rem 0.5rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-micro);
    font-weight: 700;
    letter-spacing: 0.02em;
    background: var(--surface-3);
    color: var(--muted);
    border: 1px solid var(--border);
    white-space: nowrap;
}
.emp-badge-green { background: rgba(var(--cwdb-setting-rgb), 0.16); color: var(--cwdb-success); border-color: rgba(var(--cwdb-setting-rgb), 0.4); }
.emp-badge-blue { background: rgba(var(--cwdb-afternoon-rgb), 0.16); color: var(--accent); border-color: rgba(var(--cwdb-afternoon-rgb), 0.4); }
.emp-badge-violet { background: rgba(var(--cwdb-evening-rgb), 0.18); color: var(--accent-2); border-color: rgba(var(--cwdb-evening-rgb), 0.42); }
.emp-badge-muted { opacity: 0.85; }

/* ---- Modal backdrop + drawer ---- */
.emp-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: clamp(0.5rem, 4vh, 3rem) var(--space-3);
    background: rgba(4, 10, 16, 0.62);
    backdrop-filter: blur(2px);
    overflow-y: auto;
}
.emp-modal-backdrop[hidden] { display: none; }
body.emp-modal-open { overflow: hidden; }
.emp-drawer {
    width: min(46rem, 100%);
    max-height: calc(100vh - 2rem);
    display: flex;
    flex-direction: column;
    padding: 0;
    box-shadow: var(--shadow-lg);
}
.emp-add-drawer { width: min(38rem, 100%); }
.emp-drawer-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    border-radius: var(--radius-panel) var(--radius-panel) 0 0;
}
.emp-drawer-head-main {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}
.emp-drawer-head h2 { margin: 0; font-size: var(--text-xl); }
.emp-drawer-head-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}
.emp-drawer-close {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border);
    background: var(--surface-3);
    color: var(--text);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
}
.emp-drawer-close:hover { border-color: var(--accent); }
.emp-active-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: var(--text-xs);
    color: var(--muted);
    cursor: pointer;
    white-space: nowrap;
}
.emp-drawer-body {
    padding: var(--space-4);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}
.emp-drawer-status {
    margin: var(--space-3) var(--space-4) 0;
    padding: 0.45rem 0.7rem;
    border-radius: var(--radius-btn);
    font-size: var(--text-xs);
    font-weight: 600;
}
.emp-drawer-status.is-ok { background: rgba(var(--cwdb-setting-rgb), 0.16); color: var(--cwdb-success); }
.emp-drawer-status.is-error { background: rgba(var(--cwdb-blocked-rgb), 0.16); color: var(--danger); }

.emp-section { display: flex; flex-direction: column; gap: var(--space-3); }
.emp-section-title {
    margin: 0;
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
}
.emp-section-hint { text-transform: none; letter-spacing: 0; font-weight: 400; opacity: 0.85; }
.emp-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
}
.emp-field { display: flex; flex-direction: column; gap: 0.25rem; }
.emp-field-label { font-size: var(--text-xs); color: var(--muted); font-weight: 600; }
.emp-req { color: var(--danger); }
.emp-field input,
.emp-field select,
.emp-login-reset input {
    width: 100%;
    padding: 0.45rem 0.55rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    color: var(--text);
    font: inherit;
}
.emp-field input:focus,
.emp-field select:focus { outline: none; border-color: var(--accent); box-shadow: var(--cwdb-glow); }

/* ---- Login & access ---- */
.emp-login-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
}
.emp-login-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.emp-login-badges { display: flex; gap: 0.3rem; }
.emp-login-toggle { font-size: var(--text-sm); color: var(--text); }
.emp-login-create, .emp-login-link { display: flex; flex-direction: column; gap: var(--space-3); }
.emp-login-link { border-top: 1px dashed var(--border); padding-top: var(--space-3); }
.emp-login-actions { display: flex; flex-direction: column; gap: var(--space-2); }
.emp-login-reset { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.emp-login-reset input { flex: 1 1 8rem; }
.emp-unlink-btn { align-self: flex-start; color: var(--danger); }

/* ---- History + meta ---- */
.emp-history-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.emp-history-row {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.4rem 0.55rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.emp-history-detail { font-size: var(--text-xs); color: var(--text); }
.emp-history-meta { font-size: var(--text-micro); color: var(--muted); }
.emp-meta { font-size: var(--text-micro); color: var(--muted); border-top: 1px solid var(--border); padding-top: var(--space-3); }
.emp-add-actions { display: flex; justify-content: flex-end; gap: var(--space-3); margin-top: var(--space-3); }

@media (max-width: 600px) {
    .emp-grid { grid-template-columns: 1fr; }
    .emp-modal-backdrop { padding: 0; }
    .emp-drawer { max-height: 100vh; max-height: 100dvh; border-radius: 0; }
    .emp-drawer-body { padding-bottom: calc(var(--space-4, 1rem) + env(safe-area-inset-bottom, 0px)); }
}

/* ==========================================================================
   MOBILE / TOUCH POLISH LAYER  (added 2026-06-04)

   Shared, additive rules closing the systemic findings from the 2026-06-04
   mobile/tablet audit. Touch-only rules are gated to coarse-pointer / no-hover
   devices, so desktop density is unchanged. NOTE: the rep app (rep.css) does
   NOT load app.css — none of this affects the already-mobile-first /rep app.
   ========================================================================== */

/* ---- iOS focus-zoom floor -------------------------------------------------
   Mobile Safari auto-zooms the page whenever a focused form control has a
   computed font-size < 16px. Nearly every CWDB control inherits a 12.8-15.2px
   token, so it zoom-fires on every field tap. One coarse-pointer floor neutralizes
   it app-wide. !important is required to win over the many single-class
   font-size rules; scoped to text-entry controls + coarse pointers so it can
   only ever raise a sub-16px control to the no-zoom threshold. */
@media (hover: none), (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
    select,
    textarea {
        font-size: 16px !important;
    }
}

/* ---- 44px touch targets ---------------------------------------------------
   Apple HIG / Material both call for a ~44px minimum hit target. The only
   compliant surface today is the rep app. This lifts the shared operator
   controls to 44px on touch without changing their desktop footprint. */
@media (hover: none), (pointer: coarse) {
    .btn,
    .btn-sm,
    .btn-ghost,
    .btn-primary,
    .btn-secondary {
        min-height: 44px;
    }
    /* Button-ish controls that already live in flex toolbars (so min-height
       applies to the flex item directly). */
    .routing-v2-btn,
    .routing-v2-viewtoggle-btn,
    .confirm-scope-chip,
    .confirmation.btn-confirm-row,
    .confirmation.btn-overflow-row,
    .db-jump-btn,
    .msg-subnav-tab,
    .msg-new-btn,
    .admin-tab,
    .settings-tab,
    .stats-tab,
    .commission-tabs .ws-tab,
    .nav-cmdk,
    .nav-bell,
    .top-nav-chip,
    .top-nav-edit-toggle,
    .user-avatar-btn,
    .rb-seg button,
    .rb-back {
        min-height: 44px;
    }
    .db-pager-btn { min-width: 44px; min-height: 44px; }
    /* Reorder grip + pencil get the full 44px HIG target on touch devices that
       still show the desktop grouped nav (iPad/2-in-1 ≥721px, coarse pointer);
       the chips/edit-toggle already get min-height:44px in the list above. */
    .top-nav-grip { min-width: 44px; min-height: 44px; }
    .top-nav-edit-toggle { min-width: 44px; }
    .confirmation.btn-overflow-row { min-width: 44px; }
    /* Filter/search selects are discrete tap targets and sit at ~32px — bump
       to 44 on touch. (Selects keep their right-anchored chevron centered.) */
    select { min-height: 44px; }
    /* Popover / menu rows — comfortable thumb rows. */
    .user-menu-item,
    .user-menu-signout,
    .nav-bell-menu-item,
    .top-nav-group-item {
        min-height: 44px;
        display: flex;
        align-items: center;
    }
    /* Modal / drawer close-X: a uniform 2rem/32px everywhere → 44×44 hit box
       with the glyph centered (visual glyph size unchanged). */
    .confirmation.detail-modal-close,
    .db-drawer-close,
    .emp-drawer-close,
    .routing-modal-close,
    .atsb-test-modal-close,
    .cmn-modal-close,
    .rb-x {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

/* ---- Safe-area insets (viewport-fit=cover is global) ----------------------
   The notch / home-indicator can occlude the sticky header and bottom-anchored
   bars in PWA standalone. env() resolves to 0 off-notch, so these are no-ops
   on non-inset devices. (Restate full padding so the shorthand top is kept.) */
.top-nav-inner-v2 {
    padding-top: calc(0.5rem + env(safe-area-inset-top, 0px));
}
.msg-composer {
    padding-bottom: calc(0.65rem + env(safe-area-inset-bottom, 0px));
}

/* ---- Wide data tables: horizontal scroll on phone --------------------------
   Most CWDB .table elements are width:100%, so on a phone they squish to
   nothing rather than overflow. Give the holding panel/section a horizontal
   scroll and a min-width so columns stay readable. The min-width is scoped to
   tables INSIDE a scrolling panel (`.panel:has(.table) .table`) so it can never
   force a clip on a table without a scroll context. :has() is Chrome 105+ /
   Safari 15.4+; older engines simply keep today's behavior. */
@media (max-width: 640px) {
    .panel:has(.table) {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .panel:has(.table) .table { min-width: 560px; }

    .smsbulk-tablewrap,
    .smsact-tablewrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .smsbulk-table { min-width: 520px; }
    .smsact-table { min-width: 680px; }
}
