
/* ============================================================
   Base / typography
   ============================================================ */

/* Brand UI typeface — Hanken Grotesk (self-hosted, variable 400–700). */
@font-face {
    font-family: 'Hanken Grotesk';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url(/fonts-lms/ui/hanken-grotesk.woff2) format('woff2');
}

:root {
    --lms-font: 'Hanken Grotesk', system-ui, -apple-system, BlinkMacSystemFont,
                'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
}

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

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    font-family: var(--lms-font);
    font-size: 13px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Form controls don't inherit the font by default. */
input, button, select, textarea { font-family: var(--lms-font); }

#main {
    width: 100%;
    height: 100vh;
    /* Phones: browser chrome eats into 100vh and pushes the bottom of
       the layout (chat composer) under the toolbar; dvh tracks the
       actually-visible viewport. Older browsers keep the vh fallback. */
    height: 100dvh;
    overflow: hidden;
}

/* ============================================================
   Custom two-panel layout (LmsLayout)
   ============================================================ */

.lms-layout {
    display: flex;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: var(--lms-bg);
}

.lms-panel-left {
    flex-shrink: 0;
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--lms-bg-panel);
}

.lms-resize-handle {
    width: 4px;
    flex-shrink: 0;
    cursor: col-resize;
    /* Blend with the sidebar so there's no dead transparent strip; the single
       divider line lives on the handle's right edge (the true sidebar/main
       boundary). Highlights on hover so the drag affordance is still findable. */
    background: var(--lms-bg-panel);
    border-right: 1px solid var(--lms-border-light);
    transition: background-color 0.15s;
}

.lms-resize-handle:hover,
.lms-resize-handle:active {
    background: var(--lms-border);
}

.lms-panel-main {
    flex: 1;
    min-width: 0;
    height: 100%;
    overflow: hidden;
    background: var(--lms-bg);
}

/* Hamburger toggle for the mobile sidebar drawer — hidden by default;
   unhidden by css-lms/mobile.css below the responsive breakpoint. */
.lms-mobile-toggle {
    display: none;
}

/* Back button for the channels/DM mobile master-detail view — hidden by
   default; unhidden by css-lms/mobile.css below the responsive breakpoint. */
.lms-mobile-back {
    display: none;
}

/* ============================================================
   Custom sidebar (LmsSidebar)
   ============================================================ */

.lms-sidebar {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--lms-bg-panel);
    color: var(--lms-text);
    overflow: hidden;
}

/* --- workspace header --- */
.lms-ws {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--lms-border-light);
}
.lms-ws-mark {
    width: 105px; height: 24px; flex-shrink: 0;
    /* Full Vantage logo (icon + wordmark) — dark on light, white on dark. */
    background: url(/img-lms/vantage-full.png) left center / contain no-repeat;
}
html.dark-mode .lms-ws-mark {
    background-image: url(/img-lms/vantage-full-white.png);
}
/* The wordmark is part of the logo image now, so the text label is hidden. */
.lms-ws-name { display: none; }

/* --- scrollable nav body --- */
.lms-nav {
    flex: 1; min-height: 0; overflow-y: auto;
    padding: 8px 8px 14px;
}
.lms-nav::-webkit-scrollbar { width: 9px; }
.lms-nav::-webkit-scrollbar-thumb {
    background: var(--lms-border); border-radius: 6px;
    border: 2px solid var(--lms-bg-panel);
}

/* optional category separator label */
.lms-grouplabel {
    font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
    color: var(--lms-text-faint);
    padding: 18px 8px 6px; user-select: none;
}
.lms-nav > .lms-grouplabel:first-child { padding-top: 6px; }

/* --- a row: leaf or section header --- */
.lms-node {
    display: flex; align-items: center; gap: 10px;
    height: 33px; padding: 0 8px; margin: 1px 0;
    border-radius: 6px; cursor: pointer;
    color: var(--lms-text-muted);
    position: relative;
    transition: background-color 0.1s ease, color 0.1s ease;
    user-select: none;
}
.lms-node:hover { background-color: rgba(0, 0, 0, 0.05); color: var(--lms-text); }
html.dark-mode .lms-node:hover { background-color: rgba(255, 255, 255, 0.06); }

.lms-section-header { user-select: none; }

.lms-ico {
    width: 17px; height: 17px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; color: var(--lms-text-faint);
}
.lms-node:hover .lms-ico { color: var(--lms-text-muted); }

.lms-node-label {
    /* Not flex:1: a label that grows into a widened sidebar's spare width
       drags everything after it (the count badge, the pin) along with it,
       so the badge drifts away from the text instead of sitting right after
       it. flex-shrink stays on (the default) so a long label still truncates
       with an ellipsis when the row is too narrow to fit everything; any
       spare width from a wide sidebar is left at the end of the row instead,
       after the badge and pin, where it is simply blank. */
    flex: 0 1 auto; min-width: 0;
    font-size: 13px; font-weight: 450; text-transform: none; letter-spacing: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.lms-chev {
    flex-shrink: 0; font-size: 13px; color: var(--lms-text-faint);
    transition: transform 0.15s ease;
}
.lms-section.lms-open > .lms-section-header .lms-chev { transform: rotate(90deg); }

/* section body collapse */
.lms-section-body { display: none; }
.lms-section.lms-open > .lms-section-body { display: block; }

/* Whisper-faint separation between top-level sidebar sections — enough to
   parse the groups while scanning a long nav, without heavy divider lines.
   Only between the major sections (direct children of .lms-nav), never between
   individual items. */
.lms-nav > .lms-section {
    margin-top: 6px;
    padding-top: 7px;
    border-top: 1px solid var(--lms-border-light);
}
.lms-nav > .lms-section:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

/* nested leaf: indented text, no icon — hierarchy via indent + active rail */
.lms-node.lms-sub { height: 31px; padding-left: 35px; }
.lms-node.lms-sub .lms-node-label { font-size: 12.5px; }

/* active / selected */
.lms-node.lms-selected {
    background-color: var(--lms-active-tint);
    color: var(--lms-text);
    font-weight: 600;
}
.lms-node.lms-selected .lms-ico { color: var(--lms-text); }

/* count badges */
.lms-node-count {
    flex-shrink: 0;
    font-size: 10.5px; font-weight: 600; line-height: 17px;
    min-width: 19px; text-align: center; padding: 0 6px;
    border-radius: 9px;
    background-color: #e6e8ec; color: var(--lms-text-muted);
}
html.dark-mode .lms-node-count { background-color: #2a2f37; color: var(--lms-text-muted); }

[data-badge="notifications_view"] {
    background-color: #e74c3c;
    color: #fff;
}
html.dark-mode [data-badge="notifications_view"] {
    background-color: #c0392b;
    color: #fff;
}

/* --- account footer: a single trigger that opens a menu (de-cramped) --- */
.lms-acct {
    flex-shrink: 0;
    position: relative;
    padding: 8px 10px;
    border-top: 1px solid var(--lms-border-light);
}
.lms-acct-trigger {
    display: flex; align-items: center; gap: 10px; width: 100%;
    background: none; border: none; cursor: pointer; text-align: left;
    padding: 6px 8px; border-radius: 8px; color: var(--lms-text);
    transition: background-color 0.1s ease;
}
.lms-acct-trigger:hover { background-color: var(--lms-active-tint); }
.lms-avatar {
    width: 30px; height: 30px; flex-shrink: 0; border-radius: 50%;
    background: var(--lms-bg-alt); color: var(--lms-text);
    border: 1px solid var(--lms-border);
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 600;
}
.lms-acct-meta { min-width: 0; flex: 1; line-height: 1.25; }
.lms-acct-name { font-size: 13px; font-weight: 550; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lms-acct-sub { font-size: 11.5px; color: var(--lms-text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lms-acct-chev { flex-shrink: 0; color: var(--lms-text-faint); }

.lms-acct-menu {
    position: absolute; bottom: calc(100% - 2px); left: 10px; right: 10px;
    background: var(--lms-bg); border: 1px solid var(--lms-border);
    border-radius: 9px; box-shadow: 0 8px 24px rgba(16, 24, 40, 0.14);
    padding: 5px; z-index: 60;
}
html.dark-mode .lms-acct-menu { box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55); }
.lms-acct-menu[hidden] { display: none; }
.lms-acct-item {
    display: flex; align-items: center; gap: 10px; width: 100%;
    background: none; border: none; cursor: pointer; text-align: left;
    padding: 7px 10px; border-radius: 6px; font: inherit; font-size: 13px;
    color: var(--lms-text); transition: background-color 0.1s ease;
}
.lms-acct-item:hover { background-color: var(--lms-active-tint); }
.lms-acct-item svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--lms-text-faint); }

.top-level {
    font-weight: 600;
    letter-spacing: 0.01em;
    font-size: 11px;
}

.leaf-level {
    font-size: 12.5px;
}

/* ============================================================
   Grid — headers
   ============================================================ */

/* Column headers: cleaner, more distinct from data rows */
.w2ui-grid-columns .w2ui-head,
.w2ui-head {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--lms-text-label, #555);
    padding: 0 8px;
}

/* ============================================================
   Grid — rows & cells
   ============================================================ */

.w2ui-grid-data {
    padding: 0 8px;
    font-size: 13px;
}

/* Slightly taller rows — default w2ui rows are very compressed */
.w2ui-grid td, .w2ui-grid-data {
    height: 30px;
    line-height: 30px;
}

/* Money/number columns: tabular figures so values align */
.w2ui-grid .w2ui-grid-data[col] {
    font-variant-numeric: tabular-nums;
}

/* Subtle hover on non-selected rows */
.w2ui-grid-records tr:not(.w2ui-selected):hover td {
    background-color: rgba(0, 0, 0, 0.03) !important;
}
html.dark-mode .w2ui-grid-records tr:not(.w2ui-selected):hover td {
    background-color: rgba(255, 255, 255, 0.04) !important;
}

/* Per-row "⋮" hamburger action button — the row-level equivalent of the
   grid's right-click context menu, same item list either way. Always
   visible (not hover-revealed) so it reads as a real menu affordance
   rather than a blank column. */
.lms-row-act-btn {
    opacity: 1;
    cursor: pointer;
    padding: 0 6px;
}

.lms-row-act-menu {
    position: fixed;
    background: var(--lms-bg-panel);
    color: var(--lms-text);
    border: 1px solid var(--lms-border);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(16, 24, 40, 0.14);
    z-index: 10000;
    min-width: 236px;
    max-width: 90vw;
    /* Capped well short of the viewport: the Loan Tape's menu is 21 items,
       and at full height it covered the grid it was acting on. It scrolls
       instead, and the group headings below make that scroll navigable. */
    max-height: min(72vh, calc(100vh - 16px));
    overflow-y: auto;
    padding: 5px;
    opacity: 0;
    transform: scale(0.97);
}

/* The record the menu will act on, named at the top - the menu usually
   covers the row itself, so "which one is this?" has to be answerable
   without closing it. Sticky so it survives the scroll on a long menu. */
.lms-row-act-head {
    position: sticky;
    top: -5px;
    z-index: 1;
    margin: -5px -5px 4px;
    padding: 10px 12px 8px;
    background: var(--lms-bg-panel);
    border-bottom: 1px solid var(--lms-border-light);
    border-radius: 10px 10px 0 0;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Named groups in place of anonymous rules: the same clusters the dividers
   already marked, said out loud, so a long list can be scanned rather than
   read from the top every time. */
.lms-row-act-group {
    padding: 10px 12px 4px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--lms-text-faint);
}
.lms-row-act-head + .lms-row-act-group { padding-top: 4px; }
.lms-row-act-menu.open {
    opacity: 1;
    transform: scale(1);
    transition: opacity 0.1s ease, transform 0.1s ease;
}
@media (prefers-reduced-motion: reduce) {
    .lms-row-act-menu.open { transition: none; }
}
html.dark-mode .lms-row-act-menu { box-shadow: 0 12px 34px rgba(0, 0, 0, 0.6); }

.lms-row-act-menu-item {
    /* Written for divs originally. The navigation's own menu uses real
       buttons, so the user agent's chrome has to be turned off here or they
       arrive as grey 2px outset boxes with near-white text on them: unreadable
       in dark mode, and not the width of the menu. */
    appearance: none;
    width: 100%;
    border: 0;
    background: transparent;
    font: inherit;
    text-align: left;
    display: flex;
    align-items: center;
    padding: 7px 12px;
    border-radius: 6px;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
    color: var(--lms-text);
    transition: background-color 0.1s ease;
}

/* Muted, evenly-spaced leading icons. */
.lms-row-act-menu-item i {
    color: var(--lms-text-faint);
    width: 16px;
    margin-right: 8px;
    text-align: center;
    font-size: 13px;
}

/* Hover and keyboard focus share one state (mouseenter syncs them). */
.lms-row-act-menu-item:hover,
.lms-row-act-menu-item.active {
    background: var(--lms-active-tint);
}
.lms-row-act-menu-item:hover i,
.lms-row-act-menu-item.active i {
    color: var(--lms-text-muted);
}

/* Hairline divider between clusters of related actions. */
.lms-row-act-sep {
    height: 1px;
    margin: 5px 8px;
    background: var(--lms-border-light);
}

/* Destructive actions (archive, leave) read as such. */
.lms-row-act-menu-item.danger,
.lms-row-act-menu-item.danger i { color: var(--lms-danger-text); }

/* The row a context menu is open for stays visibly anchored. */
.tabulator .tabulator-row.lms-ctx-row {
    background-color: var(--lms-active-tint) !important;
}

/* Column show/hide menu (the "Columns" toolbar button). */
.lms-col-menu {
    position: fixed;
    background: var(--lms-bg-panel);
    color: var(--lms-text);
    border: 1px solid var(--lms-border);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(16, 24, 40, 0.14);
    z-index: 10000;
    min-width: 190px;
    max-height: 60vh;
    overflow-y: auto;
    padding: 5px;
}
html.dark-mode .lms-col-menu { box-shadow: 0 12px 34px rgba(0, 0, 0, 0.6); }

.lms-col-menu-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 11px;
    border-radius: 6px;
    font-size: 13px;
    color: var(--lms-text);
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
}
.lms-col-menu-item:hover { background: var(--lms-active-tint); }
.lms-col-menu-item input {
    margin: 0;
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    cursor: pointer;
    accent-color: var(--lms-accent);
}

/* ============================================================
   Grid — footer (record count)
   ============================================================ */

.w2ui-grid-footer {
    font-size: 11px;
    color: var(--lms-text-muted, #888);
    padding: 0 12px;
    border-top: 1px solid var(--lms-border-light, #e0e0e0);
}

/* ============================================================
   Toolbar
   ============================================================ */

/* Slightly taller, better padding */
.w2ui-toolbar {
    padding: 3px 4px;
    border-bottom: 1px solid var(--lms-border-light, #e0e0e0);
}

/* Rounder, more button-like toolbar buttons */
.w2ui-toolbar .w2ui-tb-button {
    border-radius: 4px;
    padding: 3px 8px;
    font-size: 12.5px;
    transition: background-color 0.1s ease;
}

.w2ui-toolbar .w2ui-tb-button:hover:not(.disabled) {
    background-color: rgba(0, 0, 0, 0.06);
}

html.dark-mode .w2ui-toolbar .w2ui-tb-button:hover:not(.disabled) {
    background-color: rgba(255, 255, 255, 0.08) !important;
}

/* Toolbar separator — slightly more visible */
.w2ui-toolbar .w2ui-tb-line {
    border-left: 1px solid var(--lms-border, #ccc);
    margin: 4px 3px;
    height: 20px;
    flex-shrink: 0;
}

/* Disabled toolbar buttons — clearly muted */
.w2ui-toolbar .w2ui-tb-button.disabled {
    opacity: 0.45;
    cursor: default;
}

/* ============================================================
   Sidebar
   ============================================================ */

/* ============================================================
   Popup / modal
   ============================================================ */

.w2ui-popup .w2ui-popup-title {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.01em;
    padding: 12px 16px;
    border-bottom: 1px solid var(--lms-border-light, #e0e0e0);
}

.w2ui-popup-body {
    font-size: 13px;
    line-height: 1.55;
}

/* Popup action buttons */
.w2ui-popup-buttons button,
.w2ui-popup .w2ui-popup-btn {
    border-radius: 4px;
    font-size: 12.5px;
    padding: 5px 14px;
    font-weight: 500;
}

/* ============================================================
   Form inputs (used in custom popup markup)
   ============================================================ */

input, select, textarea {
    font-family: inherit;
    font-size: 13px;
    border-radius: 4px;
    border: 1px solid var(--lms-border, #ccc);
    padding: 5px 8px;
    background-color: var(--lms-bg, #fff);
    color: var(--lms-text, #000);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--lms-accent);
    box-shadow: 0 0 0 3px var(--lms-active-tint);
}

html.dark-mode input:focus,
html.dark-mode select:focus,
html.dark-mode textarea:focus {
    border-color: #5a9fd4;
    box-shadow: 0 0 0 2px rgba(90, 159, 212, 0.25);
}

/* ============================================================
   Scrollbars — light mode (WebKit/Blink)
   ============================================================ */

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background-color: var(--lms-bg-alt, #f5f5f5);
}

::-webkit-scrollbar-thumb {
    background-color: #c0c0c0;
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background-color: #999;
}

/* Firefox */
* {
    scrollbar-width: thin;
    scrollbar-color: #c0c0c0 var(--lms-bg-alt, #f5f5f5);
}

/* ============================================================
   Misc helpers
   ============================================================ */

.blur {
    filter: blur(2px);
}

body.test-mode {
    padding-top: 20px;
}

.test-mode-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    background: #c0392b;
    color: #fff;
    text-align: center;
    font-size: 12px;
    font-weight: bold;
    padding: 3px 0;
    letter-spacing: 0.05em;
}

/* ============================================================
   Dashboard & Settings panels — consistent typography
   ============================================================ */

#main a {
    color: var(--lms-accent-warm);
    text-decoration: none;
}

#main a:hover {
    text-decoration: underline;
}

html.dark-mode #main a {
    color: var(--lms-text);
}

/* ============================================================
   Tabulator grid integration (Phase 2)
   Override Tabulator's default theme to match the LMS design tokens.
   ============================================================ */

/* Container — full-bleed; no outer border (the toolbar's bottom border and the
   footer's top border provide the horizontal dividers). */
.tabulator {
    font-family: inherit;
    font-size: 13px;
    background-color: var(--lms-bg, #fff);
    border: none;
}

/* Sort arrows only on hover or the actively-sorted column (was always-on). */
.tabulator .tabulator-col .tabulator-col-sorter { opacity: 0; transition: opacity 0.12s ease; }
.tabulator .tabulator-col:hover .tabulator-col-sorter,
.tabulator .tabulator-col[aria-sort="asc"] .tabulator-col-sorter,
.tabulator .tabulator-col[aria-sort="desc"] .tabulator-col-sorter,
.tabulator .tabulator-col[aria-sort="ascending"] .tabulator-col-sorter,
.tabulator .tabulator-col[aria-sort="descending"] .tabulator-col-sorter { opacity: 1; }

/* Column headers */
.tabulator .tabulator-header {
    background-color: var(--lms-bg-alt, #f5f5f5);
    border-color: var(--lms-border, #ccc);
}

.tabulator .tabulator-header .tabulator-col {
    background-color: var(--lms-bg-alt, #f5f5f5);
    border-color: var(--lms-border, #ccc);
}

.tabulator .tabulator-header .tabulator-col .tabulator-col-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--lms-text-label, #555);
    padding: 0 8px;
    line-height: 38px;
}

/* Trailing spacer column (see tabulator_grid.js _buildTabConfig) — always
   empty, so it shouldn't show a leading divider line as if it were a real
   boundary between two data columns. */
.tabulator .tabulator-header .tabulator-col.lms-spacer-col,
.tabulator .tabulator-cell.lms-spacer-col {
    border-left: none;
}

/* Header filter inputs sit inside the (tinted) header row, so they need
   their own background/border rather than inheriting the generic
   input/select styling — otherwise a themed input can end up matching
   the header's own background color and disappear (this is what happened
   in dark mode: the generic dark-mode input rule and the header both used
   --lms-bg-alt). The extra descendant classes here give this rule enough
   specificity to win over that generic rule without needing !important. */
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input,
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter select {
    background-color: var(--lms-bg, #fff);
    border: 1px solid var(--lms-border, #ccc);
    border-radius: 3px;
    color: var(--lms-text, #000);
    font-size: 11px;
    padding: 3px 5px;
}

.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input:focus,
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter select:focus {
    outline: none;
    border-color: var(--lms-accent);
    box-shadow: 0 0 0 2px var(--lms-active-tint);
}

.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::placeholder {
    color: var(--lms-text-faint, #999);
}

/* Rows */
.tabulator .tabulator-row {
    min-height: 36px;
    color: var(--lms-text, #000);
    border-bottom: 1px solid var(--lms-border-light, #e0e0e0);
}

/* no zebra striping — clean rows on the container background (matches the redesign) */
.tabulator .tabulator-row.tabulator-row-even {
    background-color: transparent;
}

/* Grids that open something on a plain row click (see TabulatorGrid's
   config.onRowClick) show a pointer cursor over the whole row, not just
   whatever link-styled cell used to be the only clickable target. */
.lms-row-clickable-grid .tabulator-row {
    cursor: pointer;
}

.tabulator .tabulator-row:not(.tabulator-selected):hover {
    background-color: rgba(0, 0, 0, 0.035);
}
/* Dark-mode override lives in dark-mode.css (loaded after this file, so it
   would win regardless) alongside every other html.dark-mode rule - this
   file previously carried its own separate, slightly different-valued copy
   (0.05 vs dark-mode.css's 0.04 alpha) that was always fully shadowed by
   the one that actually loads last; removed as dead, redundant CSS with no
   visible effect either way. */

/* Selected row — a distinct light blue (not the same low-contrast tint used
   for hover/menu-active states, which made a selected row hard to tell apart
   from one merely under the cursor) so selection is unambiguous in both themes. */
.tabulator .tabulator-row.tabulator-selected,
.tabulator .tabulator-row.tabulator-selected:hover {
    background-color: var(--lms-row-selected-bg) !important;
    color: var(--lms-text) !important;
}

/* Frozen ⋮ actions column, and the frozen select checkbox column: give both
   an opaque background so horizontally scrolled row content doesn't bleed
   through the sticky column (Tabulator's own default is background-color:
   inherit, which inherits the row's transparent base and lets whatever
   scrolls underneath show through rather than matching the row). Hover/
   selected tints are composited over the opaque base (via background-image)
   so both columns still follow the row state without letting anything show
   through. */
.tabulator .tabulator-cell.lms-row-act-col,
.tabulator .tabulator-cell.lms-row-sel-col {
    background-color: var(--lms-bg) !important;
}
.tabulator .tabulator-row:hover .tabulator-cell.lms-row-act-col,
.tabulator .tabulator-row:hover .tabulator-cell.lms-row-sel-col {
    background-image: linear-gradient(rgba(0, 0, 0, 0.035), rgba(0, 0, 0, 0.035));
}
html.dark-mode .tabulator .tabulator-row:hover .tabulator-cell.lms-row-act-col,
html.dark-mode .tabulator .tabulator-row:hover .tabulator-cell.lms-row-sel-col {
    background-image: linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05));
}
/* !important: the dark-mode hover rule above (html.dark-mode ...:hover ...)
   has higher specificity than this selector (an extra html type selector
   tips the tie once class-selector counts are equal), so without it,
   hovering a selected row's action column in dark mode silently dropped the
   blue selected tint back to the plain hover tint - the exact opposite of
   what hovering a selected row should ever do. !important sidesteps the
   specificity comparison entirely rather than chasing it with an even more
   specific selector. */
.tabulator .tabulator-row.tabulator-selected .tabulator-cell.lms-row-act-col,
.tabulator .tabulator-row.tabulator-selected:hover .tabulator-cell.lms-row-act-col,
.tabulator .tabulator-row.tabulator-selected .tabulator-cell.lms-row-sel-col,
.tabulator .tabulator-row.tabulator-selected:hover .tabulator-cell.lms-row-sel-col {
    background-image: linear-gradient(var(--lms-row-selected-bg), var(--lms-row-selected-bg)) !important;
}

/* ============================================================
   Channels / DMs — Discord-style chat surface
   Shell: #cd-root = rail (channel + DM lists) beside #cd-main
   (one conversation panel at a time). Built by lms.js's
   render_channels_and_dms(); rows/messages by channels.js / dm.js.
   ============================================================ */

#cd-root { display: flex; height: 100%; overflow: hidden; }

/* --- Rail ------------------------------------------------------------ */
#cd-rail {
    width: 240px; flex-shrink: 0;
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--lms-bg-panel);
    border-right: 1px solid var(--lms-border-light);
}
#cd-rail-top {
    flex-shrink: 0; padding: 10px 12px;
    border-bottom: 1px solid var(--lms-border-light);
}
#cd-rail-search {
    width: 100%; height: 30px;
    display: flex; align-items: center; gap: 8px;
    padding: 0 10px; border: none; border-radius: 7px;
    background: var(--lms-bg);
    color: var(--lms-text-faint);
    font-family: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
    transition: color 0.12s ease;
}
#cd-rail-search:hover { color: var(--lms-text-muted); }
#cd-rail-search i { font-size: 11px; }
#cd-rail-scroll { flex: 1; overflow-y: auto; padding: 6px 0 14px; }
#cd-rail-foot {
    flex-shrink: 0; padding: 8px 12px;
    display: flex; gap: 4px;
    border-top: 1px solid var(--lms-border-light);
}
#cd-archived-btn, #cd-markallread-btn {
    flex: 1; min-width: 0; height: 28px;
    display: flex; align-items: center; justify-content: center; gap: 7px;
    padding: 0 8px; border: none; border-radius: 6px;
    background: none; cursor: pointer;
    color: var(--lms-text-faint);
    font-family: inherit; font-size: 12px;
    white-space: nowrap;
    transition: color 0.12s ease, background-color 0.12s ease;
}
#cd-archived-btn:hover, #cd-markallread-btn:hover {
    background: var(--lms-active-tint); color: var(--lms-text-muted);
}
#cd-archived-btn i, #cd-markallread-btn i { font-size: 11px; width: 14px; text-align: center; }

/* Online-presence dot (DM avatars, participant roster). */
.ch-presence-dot {
    position: absolute; right: -1px; bottom: -1px;
    width: 9px; height: 9px; border-radius: 50%;
    background: #2ea86b;
    border: 2px solid var(--lms-bg-panel);
}

/* "Show all N…" expander at the foot of a capped Deal threads list. */
.cd-row-showall {
    color: var(--lms-text-faint);
    font-size: 12.5px;
    justify-content: center;
}
.cd-row-showall:hover { color: var(--lms-text-muted); }

.cd-section { margin-top: 12px; }
.cd-section:first-child { margin-top: 4px; }
.cd-section-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 2px 10px 3px 16px;
    font-size: 11.5px; font-weight: 600; color: var(--lms-text-muted);
}
.cd-section-add {
    width: 20px; height: 20px;
    display: flex; align-items: center; justify-content: center;
    border: none; background: none; border-radius: 5px; cursor: pointer;
    color: var(--lms-text-muted); font-size: 10px; opacity: 0;
    transition: opacity 0.12s ease, background-color 0.12s ease, color 0.12s ease;
}
.cd-section:hover .cd-section-add,
.cd-section-add:focus-visible { opacity: 1; }
.cd-section-add:hover { background: var(--lms-active-tint); color: var(--lms-text); }

/* Rail rows — channels and DMs share one language. */
.cd-row {
    display: flex; align-items: center; gap: 8px;
    height: 32px; margin: 1px 8px; padding: 0 8px;
    border-radius: 6px; cursor: pointer;
    color: var(--lms-text-muted);
    transition: background-color 0.1s ease, color 0.1s ease;
}
.cd-row:not(.active):hover {
    background: color-mix(in srgb, var(--lms-active-tint) 55%, transparent);
    color: var(--lms-text-dim);
}
.cd-row.active { background: var(--lms-active-tint); color: var(--lms-text); }
.cd-row.unread:not(.active) { color: var(--lms-text); font-weight: 600; }
.cd-row-lead {
    width: 20px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; color: var(--lms-text-faint);
}
.cd-row.active .cd-row-lead, .cd-row.unread .cd-row-lead { color: var(--lms-text-muted); }
.cd-row-name {
    flex: 1; min-width: 0; font-size: 13.5px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cd-row-badge {
    flex-shrink: 0; min-width: 18px; height: 16px; padding: 0 5px;
    border-radius: 8px; background: var(--lms-accent-warm); color: #fff;
    font-size: 10.5px; font-weight: 700; line-height: 16px; text-align: center;
}
.cd-row-avatar {
    width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 9px; font-weight: 700; color: #fff;
}
/* Muted conversations sit back: faint text, a small bell-slash marker, no
   unread emphasis (the badge is suppressed by the renderer). */
.cd-row.muted { color: var(--lms-text-faint); }
.cd-row.muted .cd-row-lead { color: var(--lms-text-faint); }
.cd-row-mute {
    flex-shrink: 0; width: 16px;
    display: flex; align-items: center; justify-content: center;
    font-size: 10px; color: var(--lms-text-faint);
}
.cd-row:hover .cd-row-mute { display: none; }

/* Hover "⋯" options affordance — swaps in for the unread badge on hover
   (right-click opens the same menu). */
.cd-row-more {
    width: 20px; height: 20px; flex-shrink: 0;
    display: none; align-items: center; justify-content: center;
    border-radius: 5px; cursor: pointer;
    color: var(--lms-text-muted); font-size: 12px;
}
.cd-row:hover .cd-row-more { display: flex; }
.cd-row:hover .cd-row-badge { display: none; }
.cd-row-more:hover { background: var(--lms-active-tint); color: var(--lms-text); }
.cd-list-empty { padding: 4px 24px; font-size: 12.5px; color: var(--lms-text-faint); }

/* --- Main area -------------------------------------------------------- */
#cd-main { flex: 1; min-width: 0; display: flex; overflow: hidden; }
#cd-main-ch, #cd-main-dm { flex: 1; min-width: 0; display: flex; overflow: hidden; }
#ch-main, #dm-convo-panel {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; overflow: hidden;
}

/* Chat header — 48px toolbar: glyph, title, divider, topic, actions. */
.cd-chat-header {
    flex-shrink: 0; height: 48px; box-sizing: border-box;
    display: flex; align-items: center; gap: 8px;
    padding: 0 16px;
    border-bottom: 1px solid var(--lms-border-light);
}
.cd-chat-glyph {
    width: 18px; flex-shrink: 0;
    display: flex; justify-content: center;
    color: var(--lms-text-faint); font-size: 15px;
}
.cd-chat-title {
    font-size: 14.5px; font-weight: 600; color: var(--lms-text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cd-chat-sep { width: 1px; height: 20px; flex-shrink: 0; margin: 0 6px; background: var(--lms-border); }
.cd-chat-topic {
    flex: 1; min-width: 0;
    font-size: 12.5px; color: var(--lms-text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cd-chat-actions { margin-left: auto; display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.cd-chat-peer { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cd-chat-peer-avatar {
    width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 10px; font-weight: 700; color: #fff;
}
.cd-chat-peer-group { background: var(--lms-bg-alt); color: var(--lms-text-muted); font-size: 11px; }

/* Header / hover icon buttons. */
.ch-icon-btn {
    width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 7px; cursor: pointer; color: var(--lms-text-muted);
    font-size: 14px; transition: background-color 0.1s ease, color 0.1s ease;
}
.ch-icon-btn:hover { background: var(--lms-active-tint); color: var(--lms-text); }

/* --- Messages ---------------------------------------------------------- */
#ch-messages, #dm-messages {
    flex: 1; overflow-y: auto;
    display: flex; flex-direction: column;
    padding: 16px 0 10px;
}
/* A thread that does not fill the window starts at the top.
   This used to push the first child down with margin-top:auto, which
   bottom-anchors sparse content: on a quiet channel the opening block and the
   first messages sat 621px down a 1000px viewport with nothing above them.
   A full thread is unaffected, because there is no free space to absorb;
   scrolling to the newest message is done by scrollTop on load either way. */

.ch-msg {
    display: flex; gap: 12px;
    padding: 2px 16px; position: relative;
}
.ch-msg:hover { background-color: color-mix(in srgb, var(--lms-active-tint) 35%, transparent); }
.ch-msg:not(.ch-msg-cont) { margin-top: 12px; }
.ch-avatar {
    width: 36px; height: 36px; flex-shrink: 0; margin-top: 2px;
    border-radius: 50%;
    background: var(--lms-bg-alt);
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 600; color: #fff;
}
.ch-msg-content { flex: 1; min-width: 0; }
.ch-msg-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 1px; }
.ch-msg-author { font-weight: 600; font-size: 14px; color: var(--lms-text); }
.ch-msg-time { font-size: 11px; color: var(--lms-text-faint); }
.ch-msg-body { font-size: 14px; line-height: 1.45; color: var(--lms-text-dim); word-break: break-word; white-space: pre-wrap; }

/* Grouped continuation — slim hover-time gutter instead of a repeated avatar. */
.ch-msg-cont { padding-top: 1px; padding-bottom: 1px; }
.ch-gutter { width: 36px; flex-shrink: 0; display: flex; justify-content: center; }
.ch-gutter-time { font-size: 10px; color: var(--lms-text-faint); opacity: 0; line-height: 20px; white-space: nowrap; }
.ch-msg-cont:hover .ch-gutter-time { opacity: 1; }

/* Floating hover-action bar, top-right of the row. */
.ch-msg-actions {
    position: absolute; top: -14px; right: 16px;
    display: flex; gap: 1px; padding: 3px;
    background: var(--lms-bg-panel);
    border: 1px solid var(--lms-border);
    border-radius: 8px;
    box-shadow: 0 4px 14px rgba(16, 24, 40, 0.14);
    opacity: 0; pointer-events: none;
    transition: opacity 0.1s ease;
    z-index: 2;
}
html.dark-mode .ch-msg-actions { box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5); }
.ch-msg:hover .ch-msg-actions { opacity: 1; pointer-events: auto; }
.ch-act {
    width: 27px; height: 27px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 6px; cursor: pointer;
    color: var(--lms-text-muted); font-size: 13px;
    transition: background-color 0.1s ease, color 0.1s ease;
}
.ch-act:hover { background: var(--lms-active-tint); color: var(--lms-text); }
.ch-act.ch-act-danger:hover { color: var(--lms-danger-text); }

/* Day separator — a hairline with an inline date label. */
.ch-date-sep {
    display: flex; align-items: center; gap: 10px;
    margin: 18px 16px 4px; color: var(--lms-text-faint);
    font-size: 11px; font-weight: 600;
}
.ch-date-sep::before, .ch-date-sep::after {
    content: ''; flex: 1; height: 1px; background: var(--lms-border-light);
}

/* Unread marker — coral hairline with a centred "New" label (anchored to the
   oldest unread message when the conversation opens). Lines flank both sides
   so the label sits in the middle, matching the date separator. */
.ch-new-sep {
    display: flex; align-items: center; gap: 10px;
    margin: 10px 16px 2px;
    color: var(--lms-accent-warm);
    font-size: 10.5px; font-weight: 700;
}
.ch-new-sep::before, .ch-new-sep::after {
    content: ''; flex: 1; height: 1px;
    background: color-mix(in srgb, var(--lms-accent-warm) 55%, transparent);
}

/* Links in message bodies. */
.ch-link { color: var(--lms-accent-warm); text-decoration: none; word-break: break-all; }
.ch-link:hover { text-decoration: underline; }

/* Inline-reply reference — compact clickable line above a reply pointing at
   the message it answers. */
.ch-replyref {
    display: flex; align-items: center; gap: 6px;
    margin-bottom: 2px; max-width: 560px;
    font-size: 12px; color: var(--lms-text-muted);
    cursor: pointer;
}
.ch-replyref:hover .ch-replyref-text { color: var(--lms-text-dim); }
.ch-replyref i { font-size: 10px; color: var(--lms-text-faint); flex-shrink: 0; }
.ch-replyref-dot {
    width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0;
}
.ch-replyref-name { font-weight: 600; flex-shrink: 0; color: var(--lms-text-dim); }
.ch-replyref-text {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ch-replyref-gone { cursor: default; font-style: italic; color: var(--lms-text-faint); }

/* Composer "Replying to …" bar. */
.cd-replybar {
    display: flex; align-items: center; gap: 8px;
    margin-bottom: 4px; padding: 6px 12px;
    background: var(--lms-bg-alt);
    border-radius: 8px;
    font-size: 12px; color: var(--lms-text-muted);
}
.cd-replybar i { font-size: 10px; color: var(--lms-text-faint); flex-shrink: 0; }
.cd-replybar-text {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cd-replybar-text strong { color: var(--lms-text-dim); }
.cd-replybar-close {
    flex-shrink: 0; cursor: pointer; padding: 2px 6px; border-radius: 5px;
    color: var(--lms-text-faint);
}
.cd-replybar-close:hover { background: var(--lms-active-tint); color: var(--lms-text); }

/* Forwarded-message quote. */
.ch-fwd {
    border-left: 2px solid var(--lms-border);
    padding-left: 10px; margin: 1px 0 2px;
}
.ch-fwd-label {
    font-size: 11px; color: var(--lms-text-faint);
    margin-bottom: 1px;
}
.ch-fwd-label i { font-size: 10px; margin-right: 2px; }

/* Link-preview card (Open Graph embed). */
.ch-embed {
    max-width: 440px; margin-top: 6px; padding: 10px 12px;
    background: var(--lms-bg-alt);
    border-left: 3px solid var(--lms-border);
    border-radius: 6px;
}
.ch-embed-site { font-size: 11px; color: var(--lms-text-faint); margin-bottom: 2px; }
.ch-embed-title {
    display: block; font-size: 13.5px; font-weight: 600;
    color: var(--lms-accent-warm); text-decoration: none;
}
.ch-embed-title:hover { text-decoration: underline; }
.ch-embed-desc {
    margin-top: 2px; font-size: 12.5px; line-height: 1.4;
    color: var(--lms-text-muted);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
.ch-embed-img {
    display: block; margin-top: 8px;
    max-width: 100%; max-height: 180px;
    border-radius: 4px;
}

/* Channel / conversation intro (Discord's "Welcome to #x" block). */
.ch-welcome { padding: 8px 16px 14px; }
.ch-welcome-glyph {
    width: 56px; height: 56px; border-radius: 50%;
    background: var(--lms-bg-alt);
    display: flex; align-items: center; justify-content: center;
    font-size: 24px; font-weight: 600; color: var(--lms-text);
    margin-bottom: 10px;
}
.ch-welcome-title {
    font-size: 21px; font-weight: 700; letter-spacing: -0.01em;
    color: var(--lms-text); margin-bottom: 3px;
}
.ch-welcome-sub { font-size: 13px; color: var(--lms-text-muted); }
.ch-welcome-sub strong { color: var(--lms-text-dim); font-weight: 600; }

/* "Load earlier" affordance. */
.ch-load-older {
    align-self: center; margin: 0 auto 6px;
    font-size: 12px; color: var(--lms-text-muted);
    background: var(--lms-bg-alt);
    border: 1px solid var(--lms-border-light);
    border-radius: 999px; padding: 4px 12px; cursor: pointer;
}
.ch-load-older:hover { background: var(--lms-active-tint); color: var(--lms-text); }

/* System / audit messages — a centred, quiet pill. */
.ch-sysmsg {
    align-self: center;
    display: inline-flex; align-items: center; gap: 8px;
    margin: 6px auto; padding: 4px 14px; max-width: 92%;
    background: color-mix(in srgb, var(--lms-bg-alt) 65%, transparent);
    border-radius: 999px;
    font-size: 12px; color: var(--lms-text-muted);
}
.ch-sysmsg i { color: var(--lms-text-faint); }
.ch-sysmsg-time { color: var(--lms-text-faint); font-size: 10.5px; }

/* Thread replies / reply-count link. */
.ch-open-thread { font-size: 12px; color: var(--lms-accent-warm); cursor: pointer; }
.ch-open-thread:hover { text-decoration: underline; }

/* Reactions. */
.ch-reactions { margin-top: 4px; display: flex; gap: 4px; flex-wrap: wrap; }
.ch-reaction-pill {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 8px; border-radius: 9px; cursor: pointer;
    background: var(--lms-bg-alt); border: 1px solid transparent;
    font-size: 12.5px; line-height: 1.4; color: var(--lms-text-dim);
    transition: border-color 0.1s ease, background-color 0.1s ease;
}
.ch-reaction-pill span { font-size: 11.5px; font-weight: 600; }
.ch-reaction-pill:hover { border-color: var(--lms-border); }
.ch-reaction-pill.mine {
    background: color-mix(in srgb, var(--lms-accent-warm) 14%, transparent);
    border-color: color-mix(in srgb, var(--lms-accent-warm) 45%, transparent);
    color: var(--lms-text);
}

/* Message markdown — chat-scale, not a document renderer. */
.ch-md-code {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 12.5px;
    background: var(--lms-bg-alt);
    border: 1px solid var(--lms-border-light);
    border-radius: 4px;
    padding: 1px 5px;
}
.ch-md-pre {
    display: block; margin: 4px 0;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 12.5px; line-height: 1.5;
    background: var(--lms-bg-alt);
    border: 1px solid var(--lms-border-light);
    border-radius: 6px;
    padding: 8px 10px;
    white-space: pre-wrap; word-break: break-word;
    max-width: 640px; overflow-x: auto;
}
.ch-md-quote {
    display: block;
    border-left: 3px solid var(--lms-border);
    padding-left: 10px;
    color: var(--lms-text-muted);
}

/* @mention token. */
.ch-mention {
    background: color-mix(in srgb, var(--lms-accent-warm) 16%, transparent);
    color: var(--lms-accent-warm);
    border-radius: 4px; padding: 0 3px; font-weight: 500;
}

/* Attachments. */
.ch-attachment-img { margin-top: 6px; }
.ch-attachment-img img {
    max-width: 320px; max-height: 240px;
    border-radius: 8px; display: block;
}
.ch-attachment-file {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 6px; padding: 8px 12px;
    background: var(--lms-bg-alt);
    border: 1px solid var(--lms-border-light);
    border-radius: 8px; text-decoration: none;
    font-size: 13px; color: var(--lms-text);
}
.ch-attachment-file i { color: var(--lms-text-muted); }
.ch-attachment-file em { font-style: normal; font-size: 11.5px; color: var(--lms-text-faint); }
.ch-attachment-file:hover { border-color: var(--lms-border); }
.cd-attach-preview { padding: 4px 20px; font-size: 12px; color: var(--lms-text-muted); }

/* --- Composer ----------------------------------------------------------- */
.cd-composer-wrap { flex-shrink: 0; padding: 6px 16px 0; }
/* The channel composer is followed by a reserved typing-indicator line that
   supplies its bottom breathing room. The DM composer has no typing bar, so
   as the last child it must supply its own or it sits flush against the
   panel edge (and, on a phone, against the bottom navigation). */
.cd-composer-wrap:last-child:not(.cd-composer-wrap-thread) { padding-bottom: 8px; }
.cd-composer-wrap-thread { padding: 8px 12px 12px; }
.cd-composer {
    position: relative;
    display: flex; align-items: flex-end; gap: 2px;
    padding: 5px 6px;
    background: var(--lms-bg-alt);
    border-radius: 10px;
}
/* Beat the global dark-mode textarea skin (html.dark-mode textarea) on
   specificity — the composer field must be chromeless inside its pill. */
.cd-composer textarea.cd-input {
    flex: 1; min-width: 0;
    resize: none; border: none !important; outline: none !important;
    box-shadow: none !important;
    background: transparent !important; color: var(--lms-text) !important;
    font-family: inherit; font-size: 14px; line-height: 1.45;
    padding: 8px 6px !important; max-height: 140px;
    height: auto; overflow-y: auto;
}
.cd-composer textarea.cd-input::placeholder { color: var(--lms-text-faint); }
.cd-icon-btn {
    flex-shrink: 0; width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center;
    border: none; background: none; cursor: pointer; border-radius: 8px;
    color: var(--lms-text-muted); font-size: 17px;
    transition: color 0.12s ease;
}
.cd-icon-btn:hover { color: var(--lms-text); }
.cd-send-btn {
    flex-shrink: 0; width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center;
    border: none; background: none; cursor: pointer; border-radius: 8px;
    color: var(--lms-text-faint); font-size: 15px;
    transition: color 0.12s ease;
}
.cd-send-btn:hover, .cd-composer.has-text .cd-send-btn { color: var(--lms-accent-warm); }
.cd-mention-menu {
    position: absolute; bottom: calc(100% + 6px); left: 0;
    background: var(--lms-bg-panel);
    border: 1px solid var(--lms-border);
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
    max-height: 180px; overflow-y: auto; z-index: 10; min-width: 180px;
}

/* Drag-a-file-over-the-conversation state — the composer lights up as the
   drop target. */
.cd-dropping .cd-composer {
    outline: 2px dashed var(--lms-accent-warm);
    outline-offset: 2px;
}

/* Rail banner offering desktop notifications (one-time, dismissible). */
#cd-notif-offer {
    flex-shrink: 0;
    display: flex; align-items: center; gap: 8px;
    margin: 0 12px 8px; padding: 8px 10px;
    background: var(--lms-bg-alt);
    border: 1px solid var(--lms-border-light);
    border-radius: 8px;
    font-size: 11.5px; color: var(--lms-text-muted);
}
#cd-notif-offer i { color: var(--lms-text-faint); flex-shrink: 0; }
#cd-notif-offer span { flex: 1; min-width: 0; line-height: 1.35; }
#cd-notif-offer button {
    flex-shrink: 0; border: none; cursor: pointer; font-family: inherit;
    background: none; padding: 3px 6px; border-radius: 5px;
    font-size: 11.5px; color: var(--lms-text-muted);
}
#cd-notif-offer #cd-notif-enable {
    color: var(--lms-accent-warm); font-weight: 600;
}
#cd-notif-offer button:hover { background: var(--lms-active-tint); }

/* Typing indicator — reserved line under the composer (no layout shift). */
.cd-typing {
    flex-shrink: 0; height: 20px; box-sizing: border-box;
    padding: 3px 24px 0;
    font-size: 11.5px; color: var(--lms-text-muted);
}

/* --- Thread side panel --------------------------------------------------- */
#ch-thread {
    width: 0; flex-shrink: 0; overflow: hidden;
    display: flex; flex-direction: column;
    border-left: 1px solid var(--lms-border-light);
    transition: width 0.2s ease;
}
.cd-thread-header .cd-chat-title { flex: 1; }
#ch-thread-messages {
    flex: 1; overflow-y: auto;
    display: flex; flex-direction: column;
    padding: 12px 0;
}
.ch-thread-divider {
    display: flex; align-items: center; gap: 10px;
    margin: 12px 16px 2px;
    font-size: 11px; font-weight: 600; color: var(--lms-text-faint);
}
.ch-thread-divider::after {
    content: ''; flex: 1; height: 1px; background: var(--lms-border-light);
}

/* Thin themed scrollbars on chat surfaces. */
#cd-rail-scroll::-webkit-scrollbar,
#ch-messages::-webkit-scrollbar,
#dm-messages::-webkit-scrollbar,
#ch-thread-messages::-webkit-scrollbar { width: 8px; }
#cd-rail-scroll::-webkit-scrollbar-track,
#ch-messages::-webkit-scrollbar-track,
#dm-messages::-webkit-scrollbar-track,
#ch-thread-messages::-webkit-scrollbar-track { background: transparent; }
#cd-rail-scroll::-webkit-scrollbar-thumb,
#ch-messages::-webkit-scrollbar-thumb,
#dm-messages::-webkit-scrollbar-thumb,
#ch-thread-messages::-webkit-scrollbar-thumb {
    background: var(--lms-border); border-radius: 4px;
}

/* Mobile back affordance inside chat headers. */
.cd-chat-header .lms-mobile-back { cursor: pointer; font-size: 16px; }

/* Cells */
.tabulator .tabulator-cell {
    height: 36px;
    line-height: 36px;
    padding: 0 8px;
    border-color: var(--lms-border-light, #e0e0e0);
    color: var(--lms-text, #000);
    font-variant-numeric: tabular-nums;
}

/* Audit Log grid: each row's Old/New Data cells render a variable number of
   "Field: value" lines (1 for a single-field UPDATE, up to AUDIT_MAX_ROWS for
   a wide INSERT/DELETE — see js-lms/action_handlers.js::audit_value_row_html()
   and js-lms/utils.js::AUDIT_MAX_ROWS). The global .tabulator-cell rule above
   fixes every cell at a single 36px height with overflow:hidden, which is
   correct for ordinary single-line grid columns but forces every audit_log
   row to whatever height the tallest record on the grid needs, leaving a
   large dead gap below shorter records' content. Overriding to an auto
   height (with visible overflow, since content is already truncated/wrapped
   at the line level, not the cell level) lets Tabulator size each row from
   its own tallest cell's real rendered content height instead of one
   grid-wide constant.
*/
.lms-tabgrid-audit_log .tabulator-cell {
    height: auto;
    min-height: 36px;
    overflow: visible;
}

/* Hide Tabulator's own footer — we provide our own .lms-tabgrid-footer */
.tabulator .tabulator-footer {
    display: none;
}

/* Scrollbar */
.tabulator .tabulator-tableholder::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.tabulator .tabulator-tableholder::-webkit-scrollbar-track {
    background-color: var(--lms-bg-alt, #f5f5f5);
}

.tabulator .tabulator-tableholder::-webkit-scrollbar-thumb {
    background-color: #c0c0c0;
    border-radius: 4px;
}

/* ============================================================
   TabulatorGrid toolbar (hand-built button row)
   Reuses .w2ui-toolbar base styles from above.
   ============================================================ */

/* toolbar row: a touch more breathing room */
/* Full-width page toolbar pinned at the top of the content area. Wraps onto
   a second line once a grid's button count outgrows one row (e.g. Analyzed
   Deals, which carries Quick Add Deal on top of the shared origination
   button set) rather than letting the flex row shrink every button/
   separator down to fit, which read as the whole toolbar looking "squashed". */
.lms-tabgrid-toolbar {
    padding: 10px 16px;
    border-bottom: 1px solid var(--lms-border-light);
    background: var(--lms-bg);
    flex-wrap: wrap;
    row-gap: 8px;
}

/* modern bordered toolbar buttons (match the redesign) */
.lms-tabgrid-toolbar button.w2ui-tb-button {
    background: var(--lms-bg);
    border: 1px solid var(--lms-border);
    cursor: pointer;
    color: var(--lms-text, #000);
    border-radius: 6px;
    height: 30px;
    padding: 0 11px;
    margin: 0 5px 0 0;
    vertical-align: middle;
    font-size: 12.5px;
    font-weight: 500;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    transition: background-color 0.1s ease, border-color 0.1s ease;
}

.lms-tabgrid-toolbar button.w2ui-tb-button:hover:not(.disabled):not([disabled]) {
    background-color: var(--lms-bg-alt);
}

.lms-tabgrid-toolbar button.w2ui-tb-button.disabled,
.lms-tabgrid-toolbar button.w2ui-tb-button[disabled] {
    opacity: 0.45;
    cursor: default;
}

/* quick-filter search box */
.lms-tabgrid-search {
    height: 30px;
    vertical-align: middle;
    border: 1px solid var(--lms-border);
    border-radius: 6px;
    padding: 0 8px;
    font-size: 12.5px;
    font-family: inherit;
    background: var(--lms-bg);
    color: var(--lms-text);
    outline: none;
    transition: border-color 0.1s ease, box-shadow 0.1s ease;
}
.lms-tabgrid-search:focus {
    border-color: var(--lms-accent);
    box-shadow: 0 0 0 3px var(--lms-active-tint);
}

.lms-tabgrid-toolbar button.w2ui-tb-button.lms-tb-active {
    background-color: rgba(192, 57, 43, 0.10);
    color: #c0392b;
    outline: 1px solid rgba(192, 57, 43, 0.30);
}
.lms-tabgrid-toolbar button.w2ui-tb-button.lms-tb-active:hover:not(.disabled):not([disabled]) {
    background-color: rgba(192, 57, 43, 0.18);
}
html.dark-mode .lms-tabgrid-toolbar button.w2ui-tb-button.lms-tb-active {
    background-color: rgba(231, 76, 60, 0.16);
    color: #e74c3c;
    outline: 1px solid rgba(231, 76, 60, 0.35);
}

.lms-tb-html {
    display: inline-flex;
    align-items: center;
    padding: 0;
    flex-shrink: 0;
}

/* ============================================================
   lmsPopup — vanilla modal overlay (Phase 4, replaces w2popup)
   ============================================================ */

.lms-popup-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.lms-popup-box {
    background: var(--lms-bg);
    color: var(--lms-text);
    border: 1px solid var(--lms-border);
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    max-width: 96vw;
    max-height: 92vh;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
    overflow: hidden;
}

.lms-popup-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 11px 16px;
    border-bottom: 1px solid var(--lms-border-light);
    font-size: 14px;
    font-weight: 600;
    flex-shrink: 0;
    background: var(--lms-bg-alt);
    border-radius: 6px 6px 0 0;
    color: var(--lms-text);
}

.lms-popup-close-x {
    background: none;
    border: none;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    color: var(--lms-text-muted);
    padding: 0 2px;
    flex-shrink: 0;
}

.lms-popup-close-x:hover {
    color: var(--lms-text);
}

.lms-popup-body {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
    background: var(--lms-bg);
    color: var(--lms-text);
}

.lms-popup-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 10px 16px;
    border-top: 1px solid var(--lms-border-light);
    background: var(--lms-bg-alt);
    border-radius: 0 0 6px 6px;
    flex-shrink: 0;
}

.lms-popup-btn {
    padding: 5px 14px;
    border-radius: 4px;
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    border: 1px solid var(--lms-border);
    background: var(--lms-bg);
    color: var(--lms-text);
    font-family: inherit;
    transition: background-color 0.1s ease;
}

.lms-popup-btn:hover {
    background-color: rgba(0, 0, 0, 0.06);
}

.lms-popup-btn:disabled {
    cursor: not-allowed;
    opacity: 0.65;
}

/* Spinner shown while a button's (possibly async) handler is running -
   see js-lms/lms_popup.js. currentColor picks up whichever variant's
   own text colour (plain/primary/danger) automatically. */
.lms-popup-btn-busy::after {
    content: '';
    display: inline-block;
    width: 11px;
    height: 11px;
    margin-left: 7px;
    vertical-align: -1px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: lms-popup-btn-spin 0.6s linear infinite;
}

@keyframes lms-popup-btn-spin {
    to { transform: rotate(360deg); }
}

.lms-popup-btn-primary {
    background: var(--lms-accent);
    color: var(--lms-accent-text);
    border-color: var(--lms-accent);
}

.lms-popup-btn-primary:hover {
    background: var(--lms-accent);
    filter: brightness(1.1);
}

.lms-popup-btn-danger {
    background: var(--lms-danger-btn);
    color: var(--lms-danger-btn-text);
    border-color: var(--lms-danger-btn);
}

.lms-popup-btn-danger:hover {
    background: var(--lms-danger-btn);
    filter: brightness(1.1);
}

/* Themed alert()/confirm()/prompt() replacements — see js-lms/ui_dialogs.js */
.lms-dialog-msg {
    padding: 16px;
    font-family: Arial, sans-serif;
    font-size: 13px;
    line-height: 1.5;
    color: var(--lms-text);
    background: var(--lms-bg);
    white-space: pre-line;
}

.lms-dialog-input {
    display: block;
    width: calc(100% - 32px);
    box-sizing: border-box;
    margin: 0 16px 16px;
    padding: 6px 8px;
    font-size: 13px;
    font-family: inherit;
    border: 1px solid var(--lms-border);
    border-radius: 3px;
    background: var(--lms-bg);
    color: var(--lms-text);
}

/* ============================================================
   Book Loan form — two-column field layout
   ============================================================ */

.lms-bd-col2 {
    display: inline-block;
    width: 48%;
    vertical-align: top;
    margin-right: 2%;
}

.lms-bd-col2last {
    display: inline-block;
    width: 48%;
    vertical-align: top;
}

/* ============================================================
   Tabulator polish (Phase 5)
   ============================================================ */

/* Footer height — matches the record-count strip under w2ui grids */
.lms-tabgrid-footer {
    height: 24px;
    line-height: 24px;
    flex-shrink: 0;
}
/* The filter bar carries the count; the footer only appears where there is no bar. */
.lms-tabgrid-footer[hidden] { display: none; }

/* Sort arrow — use design tokens instead of hardcoded grey */
.tabulator .tabulator-col-sorter .tabulator-arrow {
    border-bottom-color: var(--lms-text-muted, #888) !important;
    border-top-color:    var(--lms-text-muted, #888) !important;
}

/* Context-menu popup (rowContextMenu) */
.tabulator-menu {
    background:   var(--lms-bg-panel, #fff);
    border:       1px solid var(--lms-border, #ccc);
    border-radius: 10px;
    box-shadow:   0 10px 30px rgba(16, 24, 40, 0.14);
    font-size:    13px;
    font-family:  inherit;
    padding:      5px;
    min-width:    210px;
}

.tabulator-menu .tabulator-menu-item {
    color:        var(--lms-text, #000);
    padding:      7px 11px;
    border-radius: 6px;
    transition:   background-color 0.1s ease;
}

/* Muted, evenly-spaced icons within menu items. */
.tabulator-menu .tabulator-menu-item i {
    color: var(--lms-text-faint);
    width: 16px;
    margin-right: 8px;
    text-align: center;
}

.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover {
    background: var(--lms-active-tint) !important;
    color:      var(--lms-text, #000) !important;
}
.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover i {
    color: var(--lms-text-muted);
}

.tabulator-menu .tabulator-menu-separator {
    border-color: var(--lms-border-light, #e0e0e0) !important;
    margin: 5px 6px;
}

/* List-editor dropdown (editable list columns) */
.tabulator-edit-list {
    background:    var(--lms-bg, #fff);
    border:        1px solid var(--lms-border, #ccc);
    border-radius: 4px;
    box-shadow:    0 4px 12px rgba(0, 0, 0, 0.12);
    font-size:     13px;
    font-family:   inherit;
}

.tabulator-edit-list .tabulator-edit-list-item {
    color:   var(--lms-text, #000);
    padding: 5px 8px;
}

.tabulator-edit-list .tabulator-edit-list-item.active,
.tabulator-edit-list .tabulator-edit-list-item:hover {
    background: var(--lms-active-tint) !important;
    color:      var(--lms-text) !important;
    cursor:     pointer;
}

.tabulator-edit-list .tabulator-edit-list-placeholder {
    color: var(--lms-text-muted, #888);
    padding: 5px 8px;
}

/* Transient toast ("Link copied") — bottom-centred pill, non-blocking. */
#lms-toast {
    position: fixed; left: 50%; bottom: 34px;
    transform: translateX(-50%) translateY(6px);
    z-index: 10001;
    padding: 8px 16px; border-radius: 999px;
    background: var(--lms-accent);
    color: var(--lms-accent-text);
    font-size: 12.5px; font-weight: 600;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
    opacity: 0; pointer-events: none;
    transition: opacity 0.18s ease, transform 0.18s ease;
}
#lms-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
@media (prefers-reduced-motion: reduce) {
    #lms-toast { transition: none; }
}

/* Notification deep-link highlight — fades out over 2.5s */
@keyframes msg-flash {
    0%   { background: color-mix(in srgb, var(--lms-accent-warm) 28%, transparent); }
    100% { background: transparent; }
}
.msg-highlight {
    animation: msg-flash 2.5s ease-out forwards;
    border-radius: 4px;
}

/* Larger tree expand/collapse toggle in the Documents grid */
.tabulator-row .tabulator-cell .tabulator-data-tree-control {
    width:  16px;
    height: 16px;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand,
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse {
    height: 10px;
}
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after,
.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after {
    width:  10px;
    left:   -4px;
    top:    4px;
}

/* Vendor hardcodes the tree toggle's box/border/bars to #333 for a light
   background — use design tokens instead, same as the sort arrow above, so
   the "+" stays visible against a dark background in dark mode. Only the
   "expand" (+) state's own background is a bar (the "collapse"/− state's
   own background is deliberately transparent, so it must be left alone —
   both states' :after pseudo-elements draw the shared horizontal bar). */
.tabulator-data-tree-control {
    background: var(--lms-bg-alt, rgba(0, 0, 0, .1)) !important;
    border-color: var(--lms-text-muted, #888) !important;
}
.tabulator-data-tree-control-expand {
    background: var(--lms-text-muted, #888) !important;
}
.tabulator-data-tree-control-expand:after,
.tabulator-data-tree-control-collapse:after {
    background: var(--lms-text-muted, #888) !important;
}

/* ============================================================
   Login page — not used in the main app but lives in same CSS
   (lms.css is not loaded by login.html; this section is here
    for reference only and has no effect on login.html)
   ============================================================ */

/* Risk Score postcode input uppercases typed text via an inline
   text-transform; the placeholder must not inherit it (it rendered as
   "E.G. SW1A 1AA"). */
#rs-postcode::placeholder { text-transform: none; }

/* ── Deal and loan thread rows ───────────────────────────────────────────
   A two-line row: the reference, and who it is about with what is at stake
   (database/166_deal_thread_context.sql). Only rows that have those facts
   take the second line, so an un-analysed deal stays a single line rather
   than reserving space for nothing. */
/* A two-line row cannot keep the one-line row's fixed 32px height: the second
   line spilled out of the box and came to rest beside the next row's name, so
   every client read as belonging to the thread underneath it. Height comes
   from the content, with the padding doing the spacing. */
.cd-row-two {
    align-items: flex-start;
    height: auto;
    min-height: 44px;
    padding-top: 5px;
    padding-bottom: 5px;
}
.cd-row-two .cd-row-lead { margin-top: 1px; }
.cd-row-two .cd-row-name { line-height: 1.35; }
.cd-row-main { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.cd-row-sub {
    font-size: 11.5px;
    /* text-2, not text-3: the client's name is the reason this line is here,
       and on the selected row's lifted ground the quiet ink measures 3.5. */
    color: var(--vantage-text-2);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    margin-top: 1px;
}

/* ── A screen's own list living in the navigation panel ──────────────────
   Channels lends the panel its conversation list (LmsSidebar.setPanelSlot),
   so the screen keeps the area rail and the panel instead of adding a third
   navigation column beside them. The slot fills what is left of the panel
   under the pins, and the lent list drops the border and fixed width it
   needed when it was its own column. */
/* The panel body becomes a column so the lent list can take the height that
   is left under the pins. Without this the list sized to its content and its
   own footer (Mark all read, Archived) sat wherever that ended, halfway up
   the panel with empty space beneath it. */
.lms-apanel-body:has(.lms-apanel-slot) { display: flex; flex-direction: column; min-height: 0; }
.lms-apanel-slot { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.lms-apanel-slot > #cd-rail {
    width: auto;
    border-right: 0;
    background: transparent;
    flex: 1;
    min-height: 0;
}
/* Its search box duplicated the panel it now sits in, and its own section
   headings sit under the panel's, so the spacing tightens. */
.lms-apanel-slot #cd-rail-top { padding-top: 2px; }
.lms-apanel-slot #cd-rail-scroll { padding-inline: 0; }
.lms-apanel-slot .cd-row { margin-inline: 0; }
