/* Davidson HR CRM — holding page: logo, background colour, one line. */
:root { --navy:#16233f; }

.crm-holding {
    position: fixed;
    inset: 0;
    background: var(--navy);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2rem;
    font-family: 'Open Sans', 'Segoe UI', Arial, sans-serif;
}

.crm-holding-inner { max-width: 560px; }

.crm-logo { width: min(340px, 80vw); height: auto; margin: 0 auto 2rem; display: block; }

.crm-holding h1 {
    font-size: clamp(1.4rem, 3.5vw, 2rem);
    font-weight: 600;
    line-height: 1.2;
    margin: 0;
}

/* The heading is auto-focused on load (FocusOnNavigate) — hide the focus outline
   so it doesn't show a ring around the text, matching the default template behaviour. */
.crm-holding h1:focus,
.crm-holding h1:focus-visible {
    outline: none;
}

/* Standard page title inside the CRM shell (matches the old dashboard heading size). */
.crm-page-title {
    color: #191F45;
    font-size: 22px;
    font-weight: 600;
    margin: 0 0 4px;
}
.crm-page-title:focus, .crm-page-title:focus-visible { outline: none; }

/* ===========================================================================
   List / search pages (DevExpress grid) — frozen-frame layout.
   Adapted from the Performance-Finance CMS.Web list-view styling to keep the
   two CRMs consistent. The grid fills the body and scrolls internally, so the
   toolbar + search stay pinned while rows scroll. */

/* When a list-view is on the page, stop the pane's own scroll — the grid scrolls instead.
   ANCHORED AT THE PANE, never higher: with the tab workspace every open screen is mounted
   at once, so a body-level :has() would match when ANY tab holds a list-view and leak the
   frozen layout into every other tab (the CMS.Web bug this comment exists to prevent). */
.ws-pane-inner:has(.list-view) { overflow: hidden; display: flex; flex-direction: column; }

.list-view { flex: 1; display: flex; flex-direction: column; gap: 12px; min-height: 0; }

.list-toolbar {
    display: flex;
    align-items: flex-start;   /* title + actions align with the top of the search box */
    gap: 18px;
}

/* Page title, in the command row (moved out of the navy top bar). Min-width leaves room for
   longer screen names without shoving the buttons around. */
.list-title {
    font-size: 27px;
    font-weight: 600;
    color: #191F45;
    margin: 0;
    min-width: 150px;
    flex: 0 0 auto;
    line-height: 34px;   /* match the search box height so title sits level with it */
}

.list-commandbar { display: flex; gap: 4px; align-items: center; min-height: 34px; }
.cmd-btn-danger:hover:not(:disabled) { background: #fbe9e9; color: #b32121; }
.cmd-btn {
    background: transparent;
    border: 0;
    padding: 6px 12px;
    font-size: 14px;
    color: #222;
    cursor: pointer;
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /* A link dressed as a button (View, Open in Xero, Get directions…) must not keep the link
       underline Bootstrap gives every <a> (Steven, 2026-09-15). */
    text-decoration: none;
}
.cmd-btn:hover:not(:disabled) { background: #f0f0f0; text-decoration: none; }
.cmd-btn:disabled { color: #999; cursor: default; }

.list-search-wrap { margin-left: auto; display: flex; flex-direction: column; gap: 4px; }
.list-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    background: #fff;
    border: 1px solid #c8c8c8;
    border-radius: 6px;
    padding: 5px 10px;
    width: 280px;
}
.list-search i { color: #888; }
.list-search input { border: 0; outline: none; flex: 1; font-size: 14px; background: transparent; }
.search-clear {
    background: transparent; border: 0; color: #999; cursor: pointer;
    padding: 0; margin: 0; font-size: 20px; line-height: 1; width: 20px; height: 20px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; flex-shrink: 0;
}
.search-clear:hover { color: #222; background: #eee; }
.list-search-status { font-size: 12px; color: #666; min-height: 0; padding-left: 2px; }

/* "Include contact detail" toggle under the search box. */
.search-option {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; color: #555; cursor: pointer; padding-left: 2px;
}
.search-option input { cursor: pointer; margin: 0; }

/* The grid fills remaining height and scrolls internally. */
.list-grid { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.list-grid .dxbl-grid,
.list-grid [class*="dxbl-grid-root"] { flex: 1; min-height: 0; }

/* Shade the main grid's column headers the same blue-grey as the Contact detail headers. */
.list-grid .dxbl-grid-header-row > th,
.list-grid .dxbl-grid-header { background-color: #eceff4 !important; }

/* THE APP-STANDARD filter funnel (promoted from the retired T&E DxGrid — Steven,
   2026-09-07): half-size, pinned to the header's top-right, and shown on header hover
   only — except an ACTIVE filter's funnel, which stays visible (a hidden active filter
   would be silently narrowing the grid), and keyboard focus always reveals it. */
.list-grid .dxbl-grid-header-row > th { position: relative; }
.list-grid .dxbl-grid-header-row > th button[class*="filter"],
.list-grid .dxbl-grid-header-row > th [class*="filter-menu"] {
    /* top 5px measures out to the SAME visual 1px gap as right (the button's
       containing block sits 4px above the header edge — measured 2026-09-07). */
    position: absolute; top: 5px; right: 1px;
    width: 15px; height: 15px; min-width: 15px; padding: 0;
    opacity: 0; transition: opacity .12s;
}
.list-grid .dxbl-grid-header-row > th button[class*="filter"] svg,
.list-grid .dxbl-grid-header-row > th [class*="filter-menu"] svg { width: 10px; height: 10px; }
.list-grid .dxbl-grid-header-row > th:hover button[class*="filter"],
.list-grid .dxbl-grid-header-row > th:hover [class*="filter-menu"],
.list-grid .dxbl-grid-header-row > th button[class*="filter"]:focus-visible,
.list-grid .dxbl-grid-header-row > th [class*="filter-menu"][class*="active"],
.list-grid .dxbl-grid-header-row > th button[class*="filter"][class*="active"],
.list-grid .dxbl-grid-header-row > th button[class*="filter"][aria-expanded="true"] { opacity: 1; }

.grid-link { color: #16233f; text-decoration: none; font-weight: 600; }
/* "Opens in a new tab" — the external-link icon after a link's label (NewTabMark, 2026-09-15). */
.new-tab-icon { font-size: .9em; margin-left: 3px; vertical-align: -1px; opacity: .8; }
.grid-link:hover { text-decoration: underline; }
/* A link into a screen the person can't View (GatedLink, permissions Model B, 2026-10-07): the same words as plain,
   greyed text with a lock - the lock and the hover say it, not the grey alone. */
.gated-off { color: #8a8f9a; font-weight: inherit; text-decoration: none; cursor: not-allowed; }
.gated-off:hover { text-decoration: none; }
.gated-off .gated-lock { font-size: 0.85em; margin-left: 4px; }
/* A View-only form (Model B, 2026-10-07): a disabled fieldset round the inputs, no frame of its own. */
.ro-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.grid-name { color: #222; font-weight: 500; }
.sub-item { font-size: 12px; color: #666; margin-top: 2px; }
.muted { color: #6b6b6b; font-size: 0.9rem; }

/* Search-match highlight inside grid cells. */
.dxbl-grid mark, mark { background-color: #fff066; color: inherit; padding: 0; border-radius: 0; }

/* "Internal" tag beside the Davidson HR client name in the list. */
.co-tag {
    display: inline-block; margin-left: 6px; vertical-align: middle;
    font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
    color: #16233f; background: #e7edf6; border-radius: 3px; padding: 1px 5px;
}
.contact-cell { display: flex; flex-direction: column; }

/* Status pill (Client / Lead / Inactive). */
.status-pill {
    display: inline-block; font-size: 12px; font-weight: 600;
    padding: 2px 10px; border-radius: 11px; line-height: 1.4;
}
.status-client   { background: #e2f4e8; color: #1c7a44; }
.status-lead     { background: #fdf1dc; color: #9a6a12; }
.status-inactive { background: #f0f0f0; color: #777; }

/* Yes/No flag cells (Virtual HRM). */
.yesno { display: inline-block; font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 11px; }
.yesno-yes { background: #e2f4e8; color: #1c7a44; }
.yesno-no  { background: #f2f2f2; color: #999; }

/* Toolbar separator + toggle + filter controls. */
.cmd-sep { width: 1px; align-self: stretch; background: #e0e0e0; margin: 2px 6px; }
.cmd-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: #222; cursor: pointer; padding: 6px 8px; }
.cmd-toggle input { cursor: pointer; }
.cmd-filter { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; padding: 0 6px; }
.cmd-filter-label { color: #666; }
.cmd-filter select {
    border: 1px solid #c8c8c8; border-radius: 6px; padding: 4px 8px;
    font-size: 14px; background: #fff; color: #222; cursor: pointer;
}

/* Master-detail child: the "other contacts" table. */
/* DevExpress puts 1.75rem (28px) of vertical padding on the detail-row cell — override it
   right down so the "Contact detail" panel hugs its parent row. Our own inner padding below
   provides the small breathing room. */
.list-grid .dxbl-grid-detail-cell { --dxbl-grid-detail-cell-padding-y: 0; padding-top: 0; padding-bottom: 0; }
/* The detail-row expand/collapse control shows the T&E board's triangle (▸ / ▾, same size
   and colour as .te-co-tog) instead of DevExpress's chevron (Steven, 2026-09-08). The
   theme swaps the SVG for state rather than a class, so the expanded state is read from
   the detail row that follows the master row (:has(+ …)), with aria-expanded as a backup. */
.list-grid .dxbl-grid-expand-button-cell .dxbl-grid-expand-button > svg.dxbl-image { display: none; }
.list-grid .dxbl-grid-expand-button-cell .dxbl-grid-expand-button::before {
    content: '▸'; color: #52586e; font-size: 24px; line-height: 1; display: inline-block; width: 28px; text-align: center;
}
.list-grid tr:has(+ tr > td.dxbl-grid-detail-cell) .dxbl-grid-expand-button::before,
.list-grid .dxbl-grid-expand-button[aria-expanded="true"]::before { content: '▾'; }
/* DevExpress paints its hover shade through the SAME ::before (content:"", absolutely
   positioned, 4% black) with a longer selector than ours, so the glyph vanished on hover
   (review, 2026-09-08). Mirror their selector, anchored on our .list-grid root, to outrank
   it: the glyph stays and darkens a touch; the shade goes. */
.dxbl-grid.list-grid .dxbl-grid-table .dxbl-grid-expand-button-cell .dxbl-grid-expand-button:not(.dxbl-disabled):not(:disabled):hover::before {
    content: '▸'; position: static; inset: auto; z-index: auto; background: none; opacity: 1; color: #16233f;
}
.dxbl-grid.list-grid .dxbl-grid-table tr:has(+ tr > td.dxbl-grid-detail-cell) .dxbl-grid-expand-button-cell .dxbl-grid-expand-button:not(.dxbl-disabled):not(:disabled):hover::before { content: '▾'; }

.detail-contacts { padding: 6px 14px 8px 58px; background: #fafbfc; }
.detail-contacts-head { font-size: 13px; font-weight: 600; color: #191F45; margin-bottom: 6px; }
.detail-contacts-empty { color: #999; font-style: italic; padding-left: 58px; }
/* Gridlines match the main DevExpress grid: full cell borders, 1px #ced4da, header + body. */
.detail-contacts-table { width: 100%; max-width: 900px; border-collapse: collapse; font-size: 13px; border: 1px solid #ced4da; }
.detail-contacts-table th {
    text-align: left; font-weight: 600; color: #555; font-size: 12px;
    padding: 6px 12px; background: #eceff4 !important; border: 1px solid #ced4da;
}
.detail-contacts-table td { padding: 5px 12px; border: 1px solid #ced4da; color: #222; }

/* "Primary" marker beside the primary contact in the detail table. */
.primary-tag {
    display: inline-block; margin-left: 6px;
    font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em;
    color: #16233f; background: #e7edf6; border-radius: 3px; padding: 1px 5px; vertical-align: middle;
}
/* An inactive contact (has left, 2026-10-08): the word, on a dashed grey tag, and the name muted. */
.inactive-tag { color: #5b6275; background: #f1f2f5; border: 1px dashed #b9bfcc; }
.crm-tag { color: #5a3e00; background: #fdf3dc; }   /* a CRM user (2026-10-08) - the key and the words */
.contact-inactive { color: #7a8090; }
.panel-actions .contacts-inactive { margin-left: auto; align-self: center; }

/* ===========================================================================
   Working tabs (the CMS.Web workspace pattern). Every open screen stays mounted;
   visibility is CSS-only. .ws-pane controls VISIBILITY, .ws-pane-inner controls
   LAYOUT — they must stay separate elements or layout rules override the hiding. */

/* The workspace fills the shell body; each pane scrolls internally. */
.crm-body:has(> .ws-workspace) { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.ws-workspace { flex: 1; min-height: 0; position: relative; }

/* Inactive panes stay LAID OUT at full size, merely invisible — NOT display:none. A
   DevExpress grid that re-renders while display:none measures a 0-wide host and bakes
   junk column widths: the "come back to a squashed grid" bug that the resize kick in
   TabWorkspace only sometimes cured. Stacked absolutely, every pane always sees the real
   width (and Chrome keeps scroll positions, which display:none threw away). visibility
   takes the pane out of focus order and the accessibility tree; opacity guarantees nothing
   inside can override visibility; pointer-events lets clicks fall through to the active
   pane whatever the DOM order. The ACTIVE pane gets no z-index/opacity of its own so its
   fixed dialogs still stack in the root context, above the sidebar and top band. */
.ws-pane { position: absolute; inset: 0; display: flex; flex-direction: column; visibility: hidden; opacity: 0; pointer-events: none; }
.ws-pane.ws-pane-active { visibility: visible; opacity: 1; pointer-events: auto; }
/* Top padding halved (24 → 12) when the breadcrumb row was retired — this is THE standard
   space above every page title (Clients, Retainers, Cases, Settings, details…). */
.ws-pane-inner { flex: 1; min-height: 0; overflow-y: auto; padding: 12px 26px 24px; }

/* --- The strip in the navy top band --- */
.ws-strip-wrap {
    flex: 1; min-width: 0; height: 100%;
    display: flex; align-items: flex-end; gap: 2px; padding-top: 12px;
}
.ws-strip {
    flex: 1; min-width: 0; display: flex; gap: 3px; align-items: flex-end;
    overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
.ws-strip::-webkit-scrollbar { display: none; }

/* EVERY TAB AT ITS NATURAL WIDTH (Steven, 2026-10-08): never shrinks, never cuts its title - the strip scrolls
   instead (was flex: 0 1 auto with max-width 210px and an ellipsis, so many open tabs were squashed). */
.ws-tab {
    flex: 0 0 auto; height: 36px;
    display: flex; align-items: center;
    background: rgba(255, 255, 255, .07); color: #c3cbe4;
    border-radius: 7px 7px 0 0;
}
.ws-tab:hover { background: rgba(255, 255, 255, .14); color: #fff; }
.ws-tab.active { background: #f4f5f7; color: #191F45; }
.ws-tab-main {
    display: flex; align-items: center; gap: 7px; height: 100%;
    padding: 0 8px 0 12px; background: none; border: 0; color: inherit;
    font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.ws-tab-title { white-space: nowrap; }

/* The drop zone past the last tab (only rendered while dragging). */
.ws-drop-end { flex: 0 0 0; width: 0; height: 36px; border-radius: 7px 7px 0 0; border: 1px dashed transparent; transition: flex-basis .12s; }
.ws-drop-end.active { flex-basis: 56px; border-color: rgba(255,255,255,.35); }
.ws-drop-end.drag-over { background: rgba(255,255,255,.18); border-style: solid; }
/* Home has no close button — give it symmetric padding so icon + label sit central. */
.ws-tab.home .ws-tab-main { padding: 0 14px; justify-content: center; }

/* Drag-reorder affordances: grab cursor on movable tabs, an insert marker on the hover
   target's left edge while a drag is in flight. */
.ws-tab[draggable="true"] { cursor: grab; }
.ws-tab.drag-over { box-shadow: inset 3px 0 0 #6f8fd6; }
/* The edit dot (2026-10-08): amber = in edit mode, red = unsaved changes. Darker shades in the white
   All open tabs list. */
.ws-dirty { color: #e8b34b; font-size: 9px; flex: 0 0 auto; }
.ws-dirty.changed { color: #ff6b6b; }
.ws-overflow-menu .ws-dirty { color: #b7791f; margin-left: auto; padding-left: 8px; }
.ws-overflow-menu .ws-dirty.changed { color: #c62828; }
.ws-tab-close {
    height: 100%; padding: 0 9px 0 2px; background: none; border: 0;
    color: inherit; opacity: .55; font-size: 15px; cursor: pointer; flex: 0 0 auto;
}
.ws-tab-close:hover { opacity: 1; }

.ws-scroll {
    align-self: flex-end; height: 36px; padding: 0 5px;
    background: none; border: 0; color: #8892ad; cursor: pointer; list-style: none;
}
.ws-scroll:hover { color: #fff; }
.ws-scroll:focus-visible { outline: 2px solid #6f8fd6; outline-offset: -2px; border-radius: 4px; }
/* The arrows (js/hscroll.js): only while the tabs don't all fit; at an end, disabled - dimmed, no hover, and
   announced as unavailable. */
.ws-strip-wrap:not([data-overflow]) .ws-arrow { display: none; }
.ws-arrow:disabled { opacity: .3; cursor: default; }
.ws-arrow:disabled:hover { color: #8892ad; }
.ws-overflow { position: relative; align-self: flex-end; }
.ws-overflow summary { display: flex; align-items: center; height: 36px; }
.ws-overflow summary::marker, .ws-overflow summary::-webkit-details-marker { display: none; }
.ws-overflow-menu {
    position: absolute; right: 0; top: 40px; z-index: 60; min-width: 200px;
    background: #fff; border: 1px solid #e3e6ee; border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .14); padding: 4px; max-height: 60vh; overflow-y: auto;
}
.ws-overflow-menu button {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 7px 10px; background: none; border: 0; border-radius: 5px;
    font-size: 13px; color: #2b3142; cursor: pointer; text-align: left;
}
.ws-overflow-menu button:hover { background: #f4f5f7; }
.ws-overflow-menu button.on { font-weight: 600; color: #191F45; }

/* ===========================================================================
   Record locking + edit panel (CMS.Web pattern: read-only until Edit acquires the
   lock; the lock bar shows who holds a record and for how long). */

/* Edit/Save/Unlock commands, right-aligned in the detail title row. */
.detail-actions { margin-left: auto; display: flex; gap: 6px; }
.cmd-btn-outline { border: 1px solid #c8c8c8; }
.cmd-btn-primary { background: #191F45; color: #fff; font-weight: 600; }
.cmd-btn-primary:hover:not(:disabled) { background: #232b5c; color: #fff; }

/* Lock status bar — amber when this session holds the lock, red when blocked by another
   holder (mirrors the desktop-CMS Gold/Crimson convention). */
.lock-bar {
    display: flex; align-items: center; gap: 9px;
    padding: 8px 14px; border-radius: 6px;
    font-size: 13.5px; font-weight: 600;
}
.lock-bar.mine    { background: #fdf1dc; color: #9a6a12; }
.lock-bar.blocked { background: #fbe9e9; color: #b32121; }
.lock-bar .lock-elapsed { margin-left: auto; font-weight: 400; font-variant-numeric: tabular-nums; }

/* Inputs inside the info-grid when a section is in edit mode. */
.edit-input {
    width: 100%; box-sizing: border-box;
    border: 1px solid #c8c8c8; border-radius: 5px;
    padding: 5px 9px; font-size: 13.5px; font-family: inherit; color: #222;
}
.edit-input:focus { outline: none; border-color: #6f8fd6; }

/* Per-section save errors listed under the lock bar. */
/* A settled, good-news counterpart to .section-error — an icon, a line of text and one
   action on the right. Never colour alone: the words carry it (2026-09-09). */
.section-note {
    display: flex; align-items: center; gap: 10px; margin: 10px 0 14px; padding: 10px 14px;
    border: 1px solid #cfe3d4; border-left: 4px solid #1c7a44; border-radius: 6px;
    background: #f3faf5; font-size: 13.5px;
}
.section-note i { color: #1c7a44; font-size: 18px; flex: 0 0 auto; }
.section-note form { margin-left: auto; }
/* The same shape when the news is neither good nor bad — "here is why this dialog opened".
   Green would read as a result; this is an instruction, so it takes the app's info blue. As
   ever the words carry it and the icon is the second signal, never the colour alone. */
.section-note.info { border-color: #cdd8ef; border-left-color: #4a6fb5; background: #f4f7fd; }
.section-note.info i { color: #4a6fb5; }

/* ---------- Settings: Users & Permissions (2026-09-09) ---------- */
.u-cell { display: flex; align-items: center; gap: 10px; }
.u-actions { text-align: right; white-space: nowrap; }
/* A row's Permissions ▾ (2026-10-10): View permissions · View CRM as <name>, a panel like the filter dropdowns' opening
   under it, right-aligned (it's the grid's last column); then a gap before Manage (Steven: "a spacer"). A greyed entry
   says why in words beneath it. */
.u-menu { position: relative; display: inline-block; margin-right: 12px; }
.u-menu .cmd-btn .ti-chevron-down { font-size: 13px; margin-left: 2px; }
.u-menu-panel { position: absolute; top: calc(100% + 4px); right: 0; z-index: 61; min-width: 260px; max-width: 340px;
    background: #fff; border: 1px solid #ced4da; border-radius: 6px; box-shadow: 0 6px 18px rgba(25, 31, 69, .14);
    padding: 4px; text-align: left; white-space: normal; }
.u-menu-panel .mpd-row { align-items: flex-start; }
.u-menu-panel .mpd-row i { margin-top: 2px; }
.u-menu-panel .mpd-row .cell-sub { display: block; margin-top: 2px; }
.u-menu-panel .mpd-row:disabled { color: #8a93a3; cursor: not-allowed; background: transparent; }
/* "Online now" is a WORD with a mark beside it, never a bare dot: a coloured dot alone
   tells a colourblind reader nothing at all. */
.u-online { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: #1c7a44; }
.u-online i { font-size: 13px; }
.u-roles { display: flex; flex-direction: column; gap: 7px; }
.u-role { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.u-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.u-reset {
    margin-top: 14px; padding: 12px 14px; border: 1px solid #e3c7c7; border-left: 4px solid #b32121;
    border-radius: 6px; background: #fdf6f6; font-size: 13.5px;
}
.u-reset .edit-input { width: 100%; }
/* CHANGE EMAIL, one look in both places (2026-10-09) - Users & Permissions and Virtual HRM access: a blue box below the
   action buttons (neutral - nothing is lost), New email (typed once) with Cancel and Send link on its row. */
.email-change { margin-top: 14px; padding: 12px 14px; border: 1px solid #dfe6f5; border-radius: 6px; background: #f4f7fd; font-size: 13.5px; }
.email-change-row { display: flex; align-items: flex-end; gap: 12px; }
.email-change-row .form-field { flex: 1; margin-bottom: 0; }
.email-change .edit-input { width: 100%; }
.email-change-acts { display: flex; justify-content: flex-end; gap: 8px; }
/* The Manage dialog. It was borrowing .cd-grid, a 12-column FORM grid, which put every
   label and value in a column of its own and ran the lot together (2026-09-09). */
.u-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.u-head-name { font-weight: 600; font-size: 15px; }
.u-head .pill { margin-left: auto; }
.u-head-av { width: 40px; height: 40px; font-size: 15px; }
.u-facts { display: grid; grid-template-columns: max-content 1fr; gap: 7px 18px; margin: 0 0 4px; font-size: 13.5px; }
.u-facts dt { color: #6b7280; }
.u-pending { display: block; margin-top: 2px; }   /* a sign-in email change waiting to be confirmed (2026-10-09) */
.u-facts dd { margin: 0; }
/* The invite form: labels above fields, one column, nothing clever. */
.inv-form { display: grid; gap: 4px 0; }
.inv-form .form-label { margin: 10px 0 0; }
.inv-form .form-label:first-child { margin-top: 0; }
.inv-form .edit-input { width: 100%; }
/* ---------- Users & Permissions: shared pieces (permissions phase 1, 2026-10-07; Model B the same day) ----------
   Every state is a glyph AND a word - ✓ Yes, — No, ⊘ Disabled, lock + Locked - so colour carries nothing. The
   Permissions tab's own rules are the .pt- block further down. */
.pm-link { background: none; border: 0; padding: 0; font: inherit; color: #191F45; text-decoration: underline;
    text-underline-offset: 2px; cursor: pointer; text-align: left; }
.pm-link:hover { color: #2b5cad; }
.pm-no { display: inline-flex; align-items: center; gap: 4px; color: #5f6673; white-space: nowrap; }
.pm-perm { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pm-kv { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 7px 14px; margin: 0 0 4px; font-size: 13.5px; align-items: baseline; }
.pm-kv dt { color: #6b7280; font-weight: 400; }
.pm-kv dd { margin: 0; min-width: 0; }
.pm-sa { display: flex; gap: 6px; align-items: center; font-weight: 700; color: #191F45; padding: 10px 0 4px; }
/* Hint's own marker swapped for an icon or an avatar (Hint Marker): no circle of its own. */
.hint-mark.hint-mark-custom { border: 0; background: none; width: auto; height: auto; border-radius: 0; padding: 0;
    font-style: normal; font-weight: 400; font-size: 14px; color: #191F45; line-height: 1; }
/* ---------- Editing permissions (permissions phase 2, 2026-10-07; plan §7.4-7.5, mockup b) ----------
   A pending change is a WORD in a box - New solid, Removed dashed - never a colour; a removed Extra is struck
   through as well as tagged. "Required" is a word under its field, not a red border. */
.pm-lock .lock-bar { margin-bottom: 12px; }
.pm-chg { display: inline-block; font-size: 11px; font-weight: 700; border: 1px solid #191F45; color: #191F45;
    border-radius: 3px; padding: 0 5px; letter-spacing: .02em; white-space: nowrap; }
.pm-chg.pm-rm { border-style: dashed; }
.pm-ex { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 1px 0 3px; }
.pm-ex.pm-gone .pm-ex-text { color: #5f6673; text-decoration: line-through; text-decoration-thickness: 1px; }
.pm-foot-note { margin-right: auto; font-size: 12.5px; color: #5f6673; }
/* Review changes (plan §7.7-7.8, mockup c; its own dialog since the edit standard, 2026-10-07 - the dialog's title says
   what is reviewed). A checkbox always has its label beside it; a change is + or − in a box AND "Gains" / "Loses" in
   words. */
.pm-ck { display: inline-flex; gap: 6px; align-items: center; margin: 0; cursor: pointer; font-weight: 400; }
.pm-ck input { margin: 0; }
.pm-rv { border: 1px solid #e4e7ee; border-radius: 6px; padding: 9px 11px; margin: 0 0 8px; font-size: 13.5px; }
.pm-rv-k { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-weight: 600; }
.pm-rv-sign { display: inline-block; min-width: 18px; text-align: center; font-size: 12px; font-weight: 700; line-height: 16px;
    border: 1px solid #191F45; border-radius: 3px; padding: 0 4px; color: #191F45; }
.pm-rv-v { margin-top: 4px; }
.pm-rv-keep { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; }
/* ---------- Settings → Users & Permissions → Permissions (Model B, part 3, 2026-10-07; permissions-mockup-b) ----------
   View by Role · Individual · All roles: a list down the left, the catalogue as a tree - areas, screens that open and
   close, an action per row - with the "i" in a column of its own. ✓ and — are shapes with a hidden word; Adding /
   Removing are words in a box (.pm-chg); a lock says System Admin only. Colour carries nothing. */
.pt-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.pt-bar .pm-foot-note { margin-right: 0; }
.pt-bar .grow, .pt-tools .grow { flex: 1; }
.pt-lbl { color: #6b7280; font-size: 12.5px; }
.pt-locked { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 600; color: #3d4b63;
    border: 1px solid #c3cad8; border-radius: 999px; padding: 2px 10px; background: #f6f7fa; }
.pt-split { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 16px; }
@media (max-width: 760px) { .pt-split { grid-template-columns: 1fr; } }
.pt-side { border: 1px solid #e5e5e5; border-radius: 6px; padding: 5px; align-self: start; }
.pt-gh { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #6b7280; padding: 6px 8px 4px; }
.pt-side > button { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; border: 0; background: none;
    padding: 7px 8px; border-radius: 4px; font: inherit; font-size: 13px; cursor: pointer; color: #333; }
.pt-side > button:hover { background: #f4f5f7; }
.pt-side > button.on { background: #eceff4; color: #191F45; font-weight: 600; box-shadow: inset 3px 0 0 #191F45; }
.pt-side small { display: block; font-weight: 400; color: #6b7280; font-size: 11.5px; }
.pt-main { min-width: 0; }
.pt-head { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.pt-head b { color: #191F45; font-size: 15px; }
.pt-sub { color: #6b7280; }
.pt-mem { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; font-size: 12.5px; }
.pt-chip { display: inline-flex; align-items: center; background: #eceff4; border-radius: 12px; padding: 1px 9px; font-size: 12px; }
.pt-state { display: flex; align-items: center; gap: 5px; color: #5f6673; font-size: 13px; margin-bottom: 8px; }
.pt-ind { border: 1px solid #e4e7ee; border-radius: 6px; padding: 8px 11px; margin: 4px 0 12px; font-size: 13.5px; }
.pt-ind-h { font-weight: 700; color: #191F45; margin-bottom: 4px; }
.pt-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 0 10px; }
.pt-scroll { overflow-x: auto; }
table.pt-table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
table.pt-table.pt-wide { min-width: 760px; }
table.pt-table col.pt-icol { width: 40px; }
table.pt-table col.pt-acol { width: 220px; }
table.pt-table col.pt-fcol { width: 230px; }
table.pt-table col.pt-rcol { width: 170px; }
table.pt-table th { background: #eceff4; text-align: left; padding: 7px 8px; font-weight: 600; color: #333;
    border-bottom: 1px solid #d5dae3; white-space: nowrap; vertical-align: middle; }
table.pt-table td { padding: 6px 8px; border-bottom: 1px solid #eef0f4; vertical-align: middle; }
table.pt-table td.pt-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
table.pt-table td.pt-i { text-align: center; }
table.pt-table tr.pt-area td { background: #e9edf3; font-weight: 700; color: #191F45; font-size: 12px; letter-spacing: .04em;
    text-transform: uppercase; padding: 6px 8px; }
table.pt-table tr.pt-scr td { background: #f7f8fb; font-weight: 600; color: #1f2937; }
table.pt-table tr.pt-scr td.pt-sum { font-weight: 400; color: #444; font-size: 12.5px; }
table.pt-table tr.pt-act td.pt-name { padding-left: 34px; color: #333; }
/* A screen under another (AI assistant's tabs): its chevron in line with the parent's actions, its own actions one step
   further in - the indent says it, not a colour. */
table.pt-table tr.pt-scr.pt-child td.pt-name { padding-left: 34px; }
table.pt-table tr.pt-act.pt-child td.pt-name { padding-left: 60px; }
table.pt-table td.pt-from { font-size: 12px; color: #444; }
.pt-fold { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; text-align: left;
    width: 100%; display: inline-flex; align-items: center; gap: 4px; }
.pt-fold i { color: #6b7a90; font-size: 14px; }
.pt-fold:focus-visible { outline: 2px solid #191F45; outline-offset: 2px; }
.pt-yes { font-weight: 700; color: #1f2937; }
.pt-no { color: #8a8f9a; }
.pt-cell { display: inline-flex; align-items: center; gap: 6px; }
/* Template groups in Settings → Emails. */
.tpl-group { margin-top: 20px; }
.tpl-group:first-of-type { margin-top: 0; }
.tpl-app-filter { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; font-size: 13px; }
.tpl-app-filter label { font-weight: 600; color: #555; }
/* ---------- Column headings that explain themselves (2026-09-09) ---------- */
/* One layout for every hoverable title: bold heading with a rule under it, then either a
   vocabulary (one term per line) or a single sentence. CSS only for the showing and hiding,
   so it works inside a Blazor circuit with no library and opens on keyboard focus too;
   hint.js does nothing but flip it when it would run off the screen. */
.hint { position: relative; display: inline-flex; align-items: center; gap: 4px; }
.hint-mark {
    border: 1px solid #b9bfcb; background: #fff; color: #5a6273; cursor: help;
    width: 14px; height: 14px; border-radius: 50%; padding: 0; line-height: 1;
    font-size: 10px; font-weight: 700; font-style: italic; display: inline-flex;
    align-items: center; justify-content: center; flex: 0 0 auto;
}
.hint-mark:hover, .hint-mark:focus-visible { border-color: #191F45; color: #191F45; }
.hint-pop {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; width: 300px;
    background: #fff; border: 1px solid #ced4da; border-radius: 6px; padding: 9px 11px;
    box-shadow: 0 6px 22px rgba(20,26,50,.16); display: none;
    font-size: 11.5px; font-weight: 400; line-height: 1.5; color: #333;
    text-transform: none; letter-spacing: normal; white-space: normal; text-align: left;
}
.hint:hover .hint-pop, .hint:focus-within .hint-pop { display: block; }
/* hint.js pins it with position:fixed once it has worked out a spot inside the viewport.
   Fixed is what gets it OUT of a scrolling grid header, which clips an absolutely positioned
   child and is why the Billing grid's hint appeared to do nothing at all. Without the script
   the rule below never applies and the pop-up keeps its default absolute position: right
   everywhere except inside a scrolling grid. */
.hint.hint-fixed .hint-pop { position: fixed; }
/* The rule runs the full width of the pop-up, so the negative margins undo the padding. */
.hint-h {
    display: block; font-weight: 700; color: #191F45; font-size: 12px;
    margin: -9px -11px 7px; padding: 7px 11px 6px; border-bottom: 1px solid #e3e6ec;
}
.hint-row { display: block; margin-top: 4px; }
.hint-row b { color: #191F45; }
/* A number with its explanation marker, on one line and right-aligned like the number. */
.num-hint { display: inline-flex; align-items: center; justify-content: flex-end; gap: 3px; white-space: nowrap; }
/* Inside a row the marker has no label beside it, so it needs no gap of its own. */
.hint-inline { gap: 0; }

/* ---------- Billing details panel (2026-09-09) ---------- */
/* ONE fixed size, because it appears on the Retainer tab and again on the Summary tab and
   has to be the same object in both. The height is fixed too, so the panel does not jump
   as recipients come and go - three names fit, the rest fold into the hover. */
.bd-panel { width: 460px; max-width: 100%; }
.bd-body { min-height: 152px; }
.bd-row { display: grid; grid-template-columns: 140px 1fr; gap: 0 14px; padding: 12px 0; align-items: start; }
/* The rule between the two halves: they are separate facts sharing a box, and must never
   read as one. */
.bd-row + .bd-row { border-top: 1px solid #e9ecef; }
.bd-row:first-child { padding-top: 2px; }
.bd-label { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: #191F45; font-size: 13.5px; }
.bd-value { min-width: 0; }
.bd-name { font-weight: 600; font-size: 13.5px; line-height: 1.45; }
.bd-none { color: #8a8f9a; font-size: 13.5px; }


.tpl-group-h {
    font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: #8a8f9a; margin: 0 0 6px;
}

/* Template editor: fields and smart phrases as buttons that insert, and the live preview
   (2026-09-15). A phrase chip carries an icon as well as its tint — never colour alone. */
.tpl-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.tpl-chip {
    font: 12.5px/1.2 Consolas, 'Cascadia Mono', monospace; color: #222; cursor: pointer;
    background: #eceff4; border: 1px solid #dde2ea; border-radius: 5px; padding: 3px 8px;
    display: inline-flex; align-items: center; gap: 4px;
}
.tpl-chip:hover { background: #e1e6ef; border-color: #c6cdda; }
.tpl-chip:focus-visible { outline: 2px solid #3b5bdb; outline-offset: 1px; }
.tpl-chip.phrase { background: #eef1fb; border-color: #cfd7f3; color: #1f3a8a; }
/* A button chip (2026-09-16): an icon as well as the tint, and the line it inserts as its text. */
.tpl-chip.button { background: #fff; border-color: #c6cdda; color: #191F45; }
/* The preview draws a button line as the button the email will show — navy, white words. */
.tpl-preview-btn { display: inline-block; background: #191F45; color: #fff; font-weight: 700; font-size: 14px;
                   padding: 9px 20px; border-radius: 6px; cursor: help; }
.tpl-phrases { display: flex; flex-direction: column; gap: 4px; }
.tpl-phrase { display: flex; align-items: center; gap: 10px; }
.tpl-phrase .grow { flex: 1; min-width: 0; }
.tpl-scenarios { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.tpl-scenario {
    font-size: 13px; padding: 4px 11px; border-radius: 14px; cursor: pointer;
    background: #fff; border: 1px solid #ced4da; color: #333;
}
.tpl-scenario.on { background: #191F45; border-color: #191F45; color: #fff; font-weight: 600; }
.tpl-preview { background: #fff; border: 1px solid #ced4da; border-radius: 8px; padding: 12px 16px; font-size: 14px; color: #222; }
.tpl-preview-subj { padding-bottom: 8px; margin-bottom: 10px; border-bottom: 1px solid #eef0f4; }
.tpl-preview p { margin: 0 0 10px; }
.tpl-preview p:last-child { margin-bottom: 0; }
/* Send test to me, under the preview (2026-09-16). */
.tpl-test { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; margin-top: 10px; }
.tpl-test .cell-sub .ti { color: #1c7a44; }

/* The client's Accounting tab (2026-09-15): Billing details and the Xero customer side by side. */
.acc-panels { display: grid; grid-template-columns: 460px 460px; gap: 20px; align-items: stretch; margin-top: 6px; }
@media (max-width: 1000px) { .acc-panels { grid-template-columns: 1fr; } }
.acc-xero-acts { margin-top: 12px; flex-wrap: wrap; }   /* the Xero panel's buttons, together (2026-10-09) */
.acc-facts { grid-template-columns: 170px 1fr; gap: 9px 14px; font-size: 13.5px; }
.acc-facts dt { white-space: nowrap; }

/* Invoices — the client's Invoices tab and Billing → Invoicing (2026-09-15). */
.inv-actions { align-items: center; flex-wrap: wrap; gap: 8px 14px; }
.inv-actions .grow { flex: 1; min-width: 0; }
.inv-table td { vertical-align: top; }
.inv-table th.num, .inv-table td.num { text-align: right; }
.inv-src { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; border-radius: 4px; padding: 1px 7px; white-space: nowrap; }
.inv-src.run { background: #e7edf6; color: #16233f; }
.inv-src.xero { background: #e6f4f8; color: #0b5b73; }
.inv-summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 22px; margin: 0 0 10px; font-size: 14px; }
/* Totals only since 2026-09-16 — not buttons, so no pointer, hover or selected state. */
.inv-tiles { display: grid; grid-template-columns: repeat(3, minmax(190px, 1fr)); gap: 10px; margin: 4px 0 14px; max-width: 830px; }
@media (max-width: 700px) { .inv-tiles { grid-template-columns: 1fr; } }
.inv-tile {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left;
    background: #fff; border: 1px solid #ced4da; border-radius: 8px; padding: 10px 14px;
}
.inv-tile-lab { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 600; color: #59607a; }
.inv-tile-num { font-size: 20px; font-weight: 700; color: #191F45; font-variant-numeric: tabular-nums; }
.inv-filters { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 10px; }
.inv-filters .grow { flex: 1; min-width: 200px; }
/* The list's own count, at the end of the filters line. */
.inv-filters .inv-count { margin-left: auto; }

/* Settings → Scheduled tasks (2026-09-15). */
.sched-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.sched-table { background: #fff; }   /* white, like every other grid (Steven, 2026-09-15) */
.sched-table td { vertical-align: top; background: #fff; }
.sched-group-row th { background: #eef1f6; color: #191F45; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; text-align: left; padding: 6px 10px; }
.sched-on { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.sched-outcome { display: inline-flex; align-items: center; gap: 5px; }
.sched-msg { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
.sched-name { display: inline-flex; align-items: center; gap: 6px; }
.sched-failed-icon { color: #b32121; font-size: 16px; }
.sched-paused td { color: #6b7280; }
.sched-actions { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px; width: 200px; }
.sched-actions .cmd-btn { width: 100%; justify-content: center; box-sizing: border-box; }
.sched-days-mode { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.sched-days-mode label, .sched-inline { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 14px; }
.sched-days { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.sched-row { display: flex; flex-wrap: wrap; column-gap: 18px; }
.sched-row .grow { flex: 1; min-width: 260px; }
.sched-preview { background: #f4f6fa; border: 1px solid #dde2ea; border-radius: 8px; padding: 10px 12px; margin-top: 4px; }

/* One smart phrase rule: "When [field] [check] [value]" over its wording. */
.phrase-rule { border: 1px solid #dde2ea; border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; background: #fafbfd; }
.phrase-rule.otherwise { margin-top: 10px; }
.phrase-rule textarea { width: 100%; box-sizing: border-box; }
.phrase-when { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.phrase-when .grow { flex: 1; }
.phrase-lab { font-size: 13px; font-weight: 600; color: #191F45; min-width: 62px; }
.section-error {
    display: flex; align-items: center; gap: 7px;
    color: #b32121; font-size: 13.5px; font-weight: 600;
    background: #fbe9e9; border-radius: 6px; padding: 7px 12px;
}

/* ===========================================================================
   Client detail view — breadcrumb + read-only info panels (CMS.Web pattern). */
.detail-view { display: flex; flex-direction: column; gap: 12px; }
.detail-breadcrumb { font-size: 13px; color: #555; display: flex; align-items: center; gap: 8px; }
.detail-breadcrumb a { color: #191F45; text-decoration: none; display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }
.detail-breadcrumb a:hover { text-decoration: underline; }
.detail-breadcrumb .sep { color: #b3b8c4; }

.detail-titlerow { display: flex; align-items: center; gap: 12px; }
.detail-title { font-size: 26px; font-weight: 600; color: #191F45; margin: 0; }
/* A section's screen in the detail frame wears the two-line title (Virtual HRM / AI assistant). */
.detail-titlerow > .ts-title { margin: 0; }

.info-panels { max-width: 900px; display: flex; flex-direction: column; gap: 16px; margin-top: 6px; }
.info-panel { background: #fff; border: 1px solid #e5e5e5; border-radius: 6px; overflow: hidden; }
.info-panel-header {
    background: #eceff4;
    padding: 9px 16px;
    font-size: 13px;
    font-weight: 600;
    color: #191F45;
    border-bottom: 1px solid #e5e5e5;
    display: flex;
    align-items: center;
    gap: 10px;
}
.info-panel-header .right { margin-left: auto; display: flex; gap: 6px; align-items: center; }
/* Header buttons must not fatten the bar — negative vertical margin keeps the header the
   same height as a plain-text one (Summary tab's panels are the reference). */
.info-panel-header .right .cmd-btn { padding: 2px 10px; font-size: 12.5px; margin: -3px 0; }
/* Free-form panel body (Retainer tab panels) — same breathing room as .info-grid gives
   the Summary panels. */
.info-panel-body { padding: 16px; }
.info-grid {
    display: grid;
    grid-template-columns: 150px 1fr 150px 1fr;
    gap: 10px 16px;
    padding: 16px;
    margin: 0;
    background: #fff;
}
.info-grid dt { color: #666; font-weight: 400; font-size: 13.5px; align-self: center; }
.info-grid dd { margin: 0; color: #222; font-size: 13.5px; font-weight: 600; align-self: center; }
.info-grid dd a { color: #191F45; }
/* Summary tab (2026-09-15): Client information + Address stacked on the left, and on the right
   the Setup panel - Steven: "a group box quite thin running down right hand side, just as long
   as top to client info to bottom of address". Stretch makes it exactly the pair's height; the
   wrapper takes the top margin so the two columns start level. */
.summary-layout { display: grid; grid-template-columns: minmax(0, 900px) 250px; gap: 16px; align-items: stretch; margin-top: 6px; }
.summary-layout > .info-panels { margin-top: 0; }
/* Address: the lines stacked on the left, the map on the right (2026-09-15); stacked when narrow. */
.addr-layout { display: grid; grid-template-columns: minmax(260px, 1fr) minmax(0, 1.25fr); align-items: start; }
.info-grid.addr-list { grid-template-columns: 100px 1fr; }
.client-map { padding: 16px 16px 16px 0; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.client-map-frame { width: 100%; height: 230px; border: 1px solid #dde2ea; border-radius: 6px; display: block; }
.client-map-empty { height: 230px; box-sizing: border-box; border: 1px dashed #ced4da; border-radius: 6px; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 16px; text-align: center; color: #6b7280; font-size: 13px; }
.client-map-empty .ti { font-size: 20px; }
.client-map-links { display: flex; flex-wrap: wrap; gap: 6px; }
@media (max-width: 900px) {
    .addr-layout { grid-template-columns: 1fr; }
    .client-map { padding: 0 16px 16px; }
}
.intg-maps-mark { color: #1a73e8; font-size: 20px; }
.intg-openai-mark { color: #111827; font-size: 20px; }
.intg-anthropic-mark { color: #d97757; font-size: 20px; }
/* The presenter services' own logos (Steven, 2026-10-06): ElevenLabs' wordmark, D-ID's mark. */
.intg-logo.elevenlabs { height: 18px; }
.intg-logo.did { height: 28px; }
/* The D-ID card's presenter: the chosen face, and the chooser's grid of them. */
.did-current { display: flex; gap: 12px; align-items: flex-start; }
.did-thumb { width: 72px; height: 72px; object-fit: cover; border-radius: 8px; border: 1px solid #e4e7ee; background: #f4f6f9; }
.did-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; max-height: 52vh; overflow-y: auto; padding: 2px; }
.did-pick { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px; border: 1px solid #e4e7ee; border-radius: 10px; background: #fff; font: inherit; cursor: pointer; text-align: center; }
.did-pick img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 6px; background: #f4f6f9; }
.did-pick:hover { border-color: #8a94a6; }
/* Chosen: a thick border AND the word "Chosen" - never colour alone. */
.did-pick.on { border: 2px solid #08203d; }
.did-pick-name { font-weight: 600; font-size: 13px; }

/* Virtual HRM: a FROZEN FRAME (2026-09-17). The workspace pane stops scrolling; the title, the screen's
   tabs and the AI sub-tabs stay where they are; the innermost pane (.ai-scroll) is what scrolls. The
   same :has() device as .list-view and .rd-view. The more specific selectors are needed to beat
   .detail-view:has(> .detail-cols) and .detail-cols .tab-pane, which let a detail screen grow. */
.ws-pane-inner:has(.vhrm-view) { overflow: hidden; display: flex; flex-direction: column; }
.detail-view.vhrm-view { flex: 1 1 0; min-height: 0; }
.vhrm-view > .detail-cols { flex: 1 1 0; min-height: 0; }
.vhrm-view > .detail-cols > .tab-pane { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; }
.vhrm-view > .detail-cols > .tab-pane:has(> .ai-scroll) { overflow: hidden; }
.vhrm-view .tab-pane.ai-scroll { flex: 1 1 0; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
/* Settings and Knowledge are as tall as their content, and the pane scrolls them. */
.vhrm-view .ai-scroll > div { flex: 0 0 auto; }
/* TEST CHAT IS DIFFERENT (Steven, 2026-09-17: "there should be no scrollbar on Test chat, maybe
   within the control for the chat"). It takes exactly the height that is left — the controls, then
   the chat card filling the rest — so the pane never scrolls and the Send box is never cut off; the
   conversation scrolls inside the card, as it does in the portal. The floor keeps the card usable on
   a very short window, where the pane scrolls after all. [hidden] must be restated: a display rule
   on a class beats the attribute's own display:none. */
.vhrm-view .ai-scroll > .ai-pane-fill { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
.vhrm-view .ai-scroll > .ai-pane-fill[hidden] { display: none; }
/* The chat on the LEFT, filling the height; "Testing options" in a column to its RIGHT (Steven,
   2026-09-17: above the chat they "distract and look complicated to average admin"). On a narrow
   window the options drop beneath the chat. */
.ai-pane-fill > .ai-chat { flex: 1 1 0; min-height: 0; display: flex; flex-direction: row; align-items: stretch; gap: 28px; }
.ai-pane-fill .ai-chat-panel { flex: 1 1 0; min-width: 0; min-height: 300px; display: flex; flex-direction: column; }
.ai-options { flex: 0 0 270px; display: flex; flex-direction: column; gap: 10px; align-self: flex-start;
              padding: 12px 14px; border: 1px solid #e4e7ee; border-radius: 8px; background: #fbfcfe; }
.ai-options-title { margin: 0 0 2px; font-size: 13px; font-weight: 700; color: #191F45; text-transform: uppercase; letter-spacing: .04em; }
.ai-options .form-field { margin: 0; }
.ai-options .cmd-btn { justify-content: center; }
@media (max-width: 1000px) {
    .ai-pane-fill > .ai-chat { flex-direction: column; }
    .ai-options { flex: 0 0 auto; align-self: stretch; }
}
.ai-tabrow { display: flex; align-items: flex-end; gap: 12px; flex: 0 0 auto; }
.ai-readonly { margin-bottom: 6px; }
.ai-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }

/* Virtual HRM → AI (2026-09-17). The chat itself is the shared AssistantChat
   (_content/DavidsonHR.Shared.Ui/assistant-chat.css); this is only the frame round it. */
.ai-chat { max-width: 980px; }
/* The panel is the portal's card, at about the width it has there, so what is tested is what is seen. */
.ai-chat-panel { max-width: 640px; }
.ai-check { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: #191F45; cursor: pointer; margin: 0; }

/* Virtual HRM → AI → Document check: a folder heads its documents; each finding is a block with the
   document's own words quoted. */
.dc-folder td { background: #f4f6f9; }
.dc-finding { border: 1px solid #e3e6ea; border-radius: 8px; padding: 10px 12px; margin-bottom: 10px; display: flex; flex-direction: column; gap: 6px; }
.dc-finding-head { display: flex; align-items: center; gap: 8px; }
.dc-passage { margin: 0; padding: 6px 10px; border-left: 3px solid #c5ccd6; background: #f8f9fb; font-style: italic; white-space: pre-wrap; }
.ai-know { max-width: 1280px; }
.ai-source { padding-bottom: 10px; margin-bottom: 12px; border-bottom: 1px solid #e4e7ee; }
.ai-find { display: flex; gap: 8px; margin-bottom: 10px; max-width: 760px; }
.ai-find input, .ai-filter { flex: 1; min-width: 0; border: 1px solid #c8c8c8; border-radius: 6px; padding: 7px 10px; font-size: 13.5px; font-family: inherit; }
.ai-filter { max-width: 320px; }
.ai-found { margin-bottom: 4px; }
.ai-entries td { vertical-align: top; }
.ai-q { font-weight: 600; color: #191F45; }
.ai-a { margin: 3px 0 4px; white-space: pre-wrap; }
.ai-quote { margin: 2px 0 5px; padding-left: 10px; border-left: 3px solid #005883; font-style: italic; color: #374151; font-size: 12.5px; }
.ai-quote::before { content: "Shown to clients: \201C"; font-style: normal; font-weight: 600; color: #191F45; }
.ai-quote::after { content: "\201D"; }
.ai-preview { margin: 10px 0 0; padding: 10px 12px; border: 1px dashed #c8c8c8; border-radius: 6px; background: #fbfcfe; font: 12.5px/1.45 Consolas, "Courier New", monospace; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 420px; overflow-y: auto; }
.ai-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; font-size: 13px; }
.ai-bar label { font-weight: 600; color: #191F45; }
.ai-bar select { border: 1px solid #c8c8c8; border-radius: 6px; padding: 6px 10px; font-size: 13.5px; font-family: inherit; background: #fff; }
.ai-bar .ai-bar-end { margin-left: auto; }
.ai-set { max-width: 1180px; }
.ai-prompts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
@media (max-width: 1100px) { .ai-prompts { grid-template-columns: minmax(0, 1fr); } }
.ai-prompt textarea { width: 100%; border: 1px solid #c8c8c8; border-radius: 6px; padding: 10px 12px; font-size: 13px; line-height: 1.45; font-family: Consolas, "Courier New", monospace; resize: vertical; }
/* ONE line, always: heading and (i) keep their width, the version takes what is left and its text is
   cut short with an ellipsis (the full text is its hover) — a wrapped version line pushed the two
   prompt boxes out of step with each other. */
.ai-prompt-head { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; margin-bottom: 6px; min-height: 28px; }
.ai-prompt-head h4, .ai-prompt-head .ai-hint, .ai-prompt-head .pill { flex: 0 0 auto; white-space: nowrap; }
.ai-prompt-head .ai-version { flex: 0 1 auto; }
.ai-prompt-head .ai-version span, .ai-prompt-head .ai-version select { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-prompt-head h4 { margin: 0; font-size: 14px; font-weight: 700; color: #191F45; }
.ai-prompt-head .ai-version { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: #555; min-width: 0; max-width: 65%; }
.ai-prompt-head .ai-version label { font-weight: 600; color: #191F45; margin: 0; }
.ai-prompt-head select { border: 1px solid #c8c8c8; border-radius: 6px; padding: 4px 8px; font-size: 12.5px; font-family: inherit; background: #fff; min-width: 0; }
.ai-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.ai-row input[type=text] { flex: 1; min-width: 160px; border: 1px solid #c8c8c8; border-radius: 6px; padding: 7px 10px; font-size: 13px; font-family: inherit; }
/* AiHint: the (i) beside a heading or a field label — hover or focus for what it does. */
.ai-hint { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin-left: 4px; vertical-align: 1px;
           border: 1px solid #005883; border-radius: 50%; background: #fff; color: #005883; font: italic 700 9.5px/1 Georgia, "Times New Roman", serif;
           text-transform: none; letter-spacing: 0; cursor: help; user-select: none; }
.ai-hint:hover, .ai-hint:focus-visible { background: #005883; color: #fff; outline: none; }
/* The knowledge date needs a look (the chat model changed): icon + bold words + a border, not colour alone. */
.ai-date-warn { margin: 0 0 10px; padding: 8px 10px; border: 1px solid #b7791f; border-left-width: 4px; border-radius: 6px; background: #fffaf0; color: #5a3d0a; font-size: 12.5px; line-height: 1.4; }
.ai-dials { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 16px; }
/* Inputs sit on one line across a row even when one label wraps onto two. */
.ai-dials .form-field { display: flex; flex-direction: column; justify-content: flex-end; }
.ai-dials .wide { grid-column: span 2; }
.ai-dials .full { grid-column: 1 / -1; }
@media (max-width: 1100px) { .ai-dials { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ai-group { display: flex; align-items: baseline; gap: 8px; margin: 18px 0 8px; font-size: 13px; font-weight: 700; color: #191F45; text-transform: uppercase; letter-spacing: .04em; }
.ai-group .pill { text-transform: none; letter-spacing: 0; font-weight: 600; }
/* Narrow: underneath, at the Billing details width rather than stretched thin across 900px. */
@media (max-width: 1000px) {
    .summary-layout { grid-template-columns: minmax(0, 900px); }
    .setup-panel { max-width: 460px; }
}
.setup-list { margin: 0; }
.setup-row { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 10px; padding: 8px 0; }
.setup-row + .setup-row { border-top: 1px solid #e9ecef; }
.setup-row dt { color: #666; font-weight: 400; font-size: 13.5px; }
.setup-row dd { margin: 0 0 0 auto; display: inline-flex; align-items: center; gap: 5px; font-size: 13.5px; font-weight: 600; color: #222; white-space: nowrap; }
/* Steven is colourblind: the tick/cross shape and the word carry the meaning, the tint only helps. */
.setup-row dd .ti { font-size: 17px; }
.setup-row dd.is-yes .ti { color: #1c7a44; }
.setup-row dd.is-no .ti { color: #b32121; }
.detail-grid { max-width: 100%; margin-top: 6px; }

/* RECENT CLIENTS AND CASES (RecentLists — Home and the Recent screen, 2026-09-14). Two panels side
   by side; a row is the record on the left and when it was last opened on the right. */
.recent-lists { max-width: 1100px; }
.recent-list { list-style: none; margin: 0; padding: 4px 0; background: #fff; }
.recent-list li { display: flex; align-items: center; gap: 12px; padding: 8px 16px; border-bottom: 1px solid #f0f2f6; }
.recent-list li:last-child { border-bottom: 0; }
.recent-what { flex: 1 1 auto; min-width: 0; }
.recent-what .grid-link { overflow-wrap: anywhere; }
.recent-when { flex: 0 0 auto; font-size: 12px; color: #666; white-space: nowrap; font-variant-numeric: tabular-nums; }
.info-panel-header a.cmd-btn { text-decoration: none; color: #191F45; }

/* HOME (2026-09-14): a heading per section, then its panels — Shortcuts, then Recent. Both use
   the two-column .panel-row at the same width, so the Shortcuts panel is exactly as wide as
   Recent's Clients panel and the space to its right is free for later. */
.home-section { display: flex; flex-direction: column; gap: 8px; }
/* HOME FITS THE WINDOW (Steven, 2026-09-16): Recent takes the height left under Shortcuts and each
   panel scrolls its own list, rather than the whole page scrolling. Anchored at the pane, like
   .list-view, so it never leaks into another open tab. The panels keep a usable minimum; in a
   window too short for that, the pane scrolls as before. One column when narrow, the two panels
   sharing the height. */
.ws-pane-inner:has(.home-view) { display: flex; flex-direction: column; }
.home-view { flex: 1 0 auto; }
/* 2026-09-17: two halves under the top row — Recent (Clients over Cases) and What's new — sharing
   the height that is left; every list scrolls inside its own panel. One column when narrow. */
.home-grid { flex: 1 1 0; min-height: 460px; max-width: 1100px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
.home-grid > .home-section { min-height: 0; }
@media (max-width: 980px) { .home-grid { grid-template-columns: minmax(0, 1fr); min-height: 0; } .home-grid > .home-section { min-height: 300px; } }
.home-recent .recent-lists { flex: 1 1 0; min-height: 0; grid-template-columns: minmax(0, 1fr); grid-auto-rows: minmax(0, 1fr); }
.home-news .news-panel { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
.news-list { list-style: none; margin: 0; padding: 0; background: #fff; flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-width: thin; scrollbar-color: #b9c0cf transparent; }
.news-list li { border-bottom: 1px solid #f0f2f6; }
.news-list li:last-child { border-bottom: 0; }
.news-item { display: flex; flex-direction: column; gap: 4px; width: 100%; padding: 12px 16px; border: 0; background: none; text-align: left; font-family: inherit; color: #191F45; cursor: pointer; }
.news-item:hover { background: #f6f8fb; }
.news-item:focus-visible { outline: 2px solid #31527a; outline-offset: -2px; }
.news-top { display: flex; align-items: baseline; gap: 12px; }
.news-title { flex: 1 1 auto; min-width: 0; font-size: 14.5px; font-weight: 700; }
.news-date { flex: 0 0 auto; font-size: 12px; color: #666; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Three lines, then … — the rest is behind the click. */
.news-summary { font-size: 13px; line-height: 1.45; color: #444; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.news-more { font-size: 12.5px; font-weight: 600; color: #005883; text-decoration: underline; }
.news-more .ti { font-size: 12px; vertical-align: -1px; }
.news-detail { font-size: 14px; line-height: 1.5; color: #1f2937; }
.news-detail-date { font-size: 12.5px; color: #666; margin-bottom: 10px; }
.news-detail h4 { margin: 16px 0 6px; font-size: 14.5px; font-weight: 700; color: #191F45; }
.news-detail p { margin: 0 0 10px; }
.news-detail ul { margin: 0 0 10px; padding-left: 20px; }
.news-detail li { margin-bottom: 6px; }
/* The shortcuts, in the top row beside the welcome: icon left, two short lines right, about the
   height of the two-line title. */
.home-top { align-items: center; flex-wrap: wrap; }
.home-shortcuts { display: flex; flex-wrap: wrap; gap: 8px; margin-left: 12px; }
.home-shortcuts .shortcut { flex-direction: row; align-items: center; gap: 10px; padding: 7px 14px 7px 12px; }
.home-shortcuts .shortcut > .ti { font-size: 22px; margin: 0; }
.shortcut-text { display: flex; flex-direction: column; gap: 1px; }
.home-shortcuts .shortcut-name { font-size: 13.5px; }
.home-shortcuts .shortcut-hint { font-size: 11.5px; white-space: nowrap; }
.home-recent .recent-lists > .info-panel { display: flex; flex-direction: column; min-height: 0; }
.home-recent .recent-lists .recent-list,
.home-recent .recent-lists .panel-stub { flex: 1 1 auto; min-height: 0; overflow-y: auto;
    scrollbar-width: thin; scrollbar-color: #b9c0cf transparent; }
/* An empty panel on Home is tall, so its message is a proper empty state (Steven, 2026-09-16: "looks
   weird and not centred"): a faint icon over the words, in the middle both ways. */
.home-recent .recent-lists .panel-stub { flex-direction: column; justify-content: center; text-align: center; gap: 8px; }
.home-recent .recent-lists .panel-stub .ti { font-size: 30px; color: #b9c1cf; }
.home-recent .recent-list::-webkit-scrollbar { width: 10px; }
.home-recent .recent-list::-webkit-scrollbar-track { background: transparent; }
.home-recent .recent-list::-webkit-scrollbar-thumb { background: #b9c0cf; border-radius: 5px;
    border: 2px solid #fff; background-clip: padding-box; }
.home-h { margin: 6px 0 0; font-size: 17px; font-weight: 700; color: #191F45; display: flex; align-items: center; gap: 6px; }
.shortcut {
    display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
    padding: 12px 12px 11px; border: 1px solid #e4e7ee; border-radius: 8px; background: #fbfcfe;
    color: #191F45; text-decoration: none; text-align: left; font-family: inherit; cursor: pointer;
}
.shortcut:hover { background: #f1f4f9; border-color: #c9d1de; }
.shortcut:focus-visible { outline: 2px solid #31527a; outline-offset: 2px; }
.shortcut > .ti { font-size: 22px; margin-bottom: 4px; }
.shortcut-name { font-size: 14px; font-weight: 600; }
.shortcut-hint { font-size: 12px; color: #666; line-height: 1.35; }

/* Placeholder for not-yet-built sub-sections (Virtual HRM log-ons, activity, Cases). */
.panel-stub { padding: 18px 16px; color: #8a8f9a; font-size: 13.5px; display: flex; align-items: center; gap: 8px; background: #fff; }

/* Logo editor (Virtual HRM tab). */
.logo-editor { display: flex; gap: 20px; padding: 16px; background: #fff; align-items: flex-start; }
.logo-preview {
    width: 120px; height: 120px; flex: 0 0 auto;
    border: 1px solid #e5e5e5; border-radius: 8px; background: #fff;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.logo-placeholder { display: flex; flex-direction: column; align-items: center; gap: 6px; color: #b3b8c4; font-size: 12px; }
.logo-placeholder i { font-size: 26px; }
.logo-actions { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.logo-upload-btn { cursor: pointer; border: 1px solid #c8c8c8; }
/* A label can't be disabled, so it looks it: the client not in Edit (2026-10-08). */
.logo-upload-btn.is-disabled { color: #999; cursor: default; pointer-events: none; }
.logo-hint { font-size: 12px; color: #888; }
/* The logo's surround in the portal header + its preview (2026-10-05). */
.logo-surround { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 13px; }
.logo-surround select { font: inherit; padding: 3px 6px; }
/* THE PREVIEW mirrors the portal's header (DavidsonHR.VirtualHrm wwwroot/app.css: .portal-hero,
   .client-logo-*, .portal-welcome) - keep the two in step. */
.pv-band { background: #08203d; border-radius: 8px; padding: 24px 24px 20px; display: flex; align-items: flex-end; gap: 24px; }
.pv-main { display: block; flex: 0 0 auto; width: 151px; height: 90px; }
.pv-client { display: flex; align-items: center; justify-content: center; flex: 0 1 auto; min-width: 0;
             height: 64px; max-width: 220px; border-radius: 12px; }
.pv-client img { display: block; max-height: 100%; max-width: 100%; object-fit: contain; }
.pv-client-light { background: #fff; padding: 8px 14px; }
.pv-client-dark { background: #12305a; padding: 8px 14px; border: 1px solid rgba(255,255,255,.25); }
.pv-client-none { padding: 0; }
.pv-right { margin-left: auto; display: flex; align-items: flex-end; gap: 22px; min-width: 0; }
.pv-welcome { text-align: right; color: #fff; line-height: 1.2; min-width: 0; max-width: 300px; margin-bottom: -3px; font-family: 'Open Sans', system-ui, sans-serif; }
.pv-welcome-hi { font-size: 1.15rem; font-weight: 600; }
.pv-welcome-client { font-size: .9rem; color: #b9c9dc; margin-top: 2px; }
.pv-switch { display: flex; align-items: center; gap: 8px; margin-top: 14px; font-size: 13px; color: #55607a; }
.logo-msg { font-size: 13px; padding: 4px 0; }
.logo-msg.ok { color: #1c7a44; }
.logo-msg.err { color: #b32121; }

/* ===========================================================================
   Error surfaces (CMS.Web pattern). #blazor-error-ui is a fatal-circuit banner
   revealed by blazor.web.js; .page-error is the in-page ErrorBoundary content. */
#blazor-error-ui {
    display: none;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 2000;
    background: #b32121;
    color: #fff;
    padding: 12px 40px 12px 16px;
    font-size: 14px;
    box-shadow: 0 -1px 4px rgba(0,0,0,0.3);
}
#blazor-error-ui .reload { color: #fff; text-decoration: underline; }
#blazor-error-ui .dismiss { position: absolute; right: 14px; top: 10px; cursor: pointer; }

.page-error { max-width: 640px; padding: 40px 4px; }
.page-error h1 { font-size: 22px; margin-bottom: 12px; color: #191F45; display: flex; align-items: center; gap: 8px; }
.page-error h1 i { color: #b32121; }
.page-error .muted { color: #6b6b6b; font-size: .9rem; }
.page-error .cmd-btn { display: inline-block; margin-top: 10px; border: 1px solid #c8c8c8; text-decoration: none; }

/* =============================================================================
   Cases (transcribed from the v2 mockup — the build spec). Board, list, pills,
   category tags, the shared progress track, case-detail tabs, dialogs, notes,
   documents, activity, audit, and the Settings->Cases screens.
   ============================================================================= */
select { border: 1px solid #c8c8c8; border-radius: 6px; padding: 4px 8px; font-size: 13.5px; background: #fff; color: #222; cursor: pointer; font-family: inherit; }
.seg { display: inline-flex; border: 1px solid #c8c8c8; border-radius: 6px; overflow: hidden; background: #fff; }
.seg button { border: 0; background: transparent; padding: 5px 13px; font-size: 13.5px; cursor: pointer; color: #666; font-family: inherit; }
.seg button.on { background: #191F45; color: #fff; font-weight: 600; }

table.cases { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.cases th { position: sticky; top: 0; text-align: left; font-weight: 600; color: #555; font-size: 12px; padding: 8px 14px; background: #eceff4; border-bottom: 1px solid #ced4da; white-space: nowrap; z-index: 2; }
/* WHITE column headers (Steven, 2026-09-09: "try making the column header white, I want to
   eyeball that"). Sits after the rule it overrides so the intent is obvious; the band of
   colour is replaced by a single firmer rule under the header. Delete this line to bring the
   tint back. */
table.cases > thead > tr > th { background: #fff; border-bottom: 2px solid #d7dbe4; }
table.cases td { padding: 9px 14px; border-bottom: 1px solid #eef0f4; vertical-align: middle; }
table.cases tr.rowlink { cursor: pointer; }
table.cases tr.rowlink:hover td { background: #f7f9fc; }
.cell-sub { font-size: 12px; color: #666; margin-top: 1px; }
.num { font-variant-numeric: tabular-nums; }

/* % bar — the one progress representation outside the detail (list AND board cards). */
.pct-wrap { display: flex; align-items: center; gap: 8px; min-width: 110px; }
.pct-bar { flex: 1; height: 6px; border-radius: 3px; background: #e4e7ee; overflow: hidden; }
.pct-bar i { display: block; height: 100%; background: #6f8fd6; border-radius: 3px; }
.pct-wrap .num { font-size: 12px; color: #666; width: 34px; text-align: right; }

/* ---------- Board ---------- */
.board { flex: 1; min-height: 0; overflow: auto; display: grid; grid-template-columns: repeat(4, minmax(230px, 1fr)); gap: 14px; align-items: start; }
.board-col { background: #ebedf2; border-radius: 8px; padding: 10px; min-height: 120px; }
.board-col-head { display: flex; align-items: center; gap: 8px; padding: 2px 4px 10px; }
.board-col-head .t { font-size: 13px; font-weight: 700; color: #191F45; }
.board-col-head .n { font-size: 11.5px; font-weight: 700; background: #fff; color: #666; border-radius: 9px; min-width: 20px; text-align: center; padding: 1px 6px; }
/* A plain note, not hover help (Steven, 2026-09-11: "last 7 days" changed the cursor "as if
   its going to give some info but doesnt"). It was class "hint", which the hover-help standard
   below dresses with a help cursor and a dotted underline for the shared Hint component. */
.board-col-head .board-col-note { margin-left: auto; font-size: 11px; color: #8a8f9a; }
.case-card { background: #fff; border: 1px solid #e5e5e5; border-radius: 7px; padding: 10px 12px 11px; margin-bottom: 10px; cursor: pointer; display: block; width: 100%; text-align: left; font-family: inherit; font-size: inherit; box-shadow: 0 1px 2px rgba(20,26,58,.05); }
.case-card:hover { border-color: #6f8fd6; box-shadow: 0 2px 8px rgba(20,26,58,.13); }
.case-card.done { opacity: .78; }
.case-card .row1 { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.case-card .ref { margin-left: auto; font-size: 11px; color: #8a8f9a; font-weight: 600; }
.case-card .t { font-size: 13.5px; font-weight: 600; color: #222; line-height: 1.35; display: block; margin-bottom: 3px; }
.case-card .co { font-size: 12px; color: #666; display: block; margin-bottom: 9px; }
.case-card .row3 { display: flex; align-items: center; gap: 8px; }
.case-card .days { margin-left: auto; font-size: 11.5px; color: #8a8f9a; }
.case-card .pct-wrap { margin-top: 9px; }

/* ---------- Pills / tags ---------- */
.pill { display: inline-block; font-size: 12px; font-weight: 600; padding: 2px 10px; border-radius: 11px; line-height: 1.4; white-space: nowrap; }
.st-new { background: #e3ecfa; color: #2b5cad; }
.st-step { background: #e2f4e8; color: #1c7a44; }
.st-completed { background: #e7edf6; color: #16233f; }
.st-onhold { background: #ede9f7; color: #5b4a9e; }
.st-cancelled { background: #fbe9e9; color: #b32121; }
.st-archived { background: #f0f0f0; color: #777; }
.pr-critical { background: #fbe9e9; color: #b32121; }
.pr-high { background: #fdeadd; color: #b25a12; }
.pr-medium { background: #fdf1dc; color: #9a6a12; }
.pr-low { background: #f0f0f0; color: #777; }
.cat-tag { display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; border-radius: 3px; padding: 2px 6px; }
.cat-tag.lg { font-size: 12px; padding: 4px 10px; border-radius: 4px; }
.cat-disciplinary { background: #fbe4ec; color: #a92559; }
.cat-grievance { background: #e4ecfb; color: #2b5cad; }
.cat-redundancy { background: #fdeadd; color: #b25a12; }
.cat-contract { background: #e2f4e8; color: #1c7a44; }
.cat-flexible { background: #ede9f7; color: #5b4a9e; }
.cat-sickness { background: #e0f2f4; color: #16717c; }
.cat-general { background: #e7edf6; color: #16233f; }
.origin-tag { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: #16233f; background: #e7edf6; border-radius: 3px; padding: 1px 6px; }
/* THE avatar circle, and the only place one is drawn (Steven, 2026-09-09). Everything comes
   through Avatar.razor, so these rules cover the header, the grids, the Who filters and the
   pickers alike. box-sizing and font-family are pinned rather than inherited: the control
   renders as a <button> in some places and a <span> in others, and a button does not inherit
   the page font, which is how the same initials ended up in two different faces. */
.who { width: 26px; height: 26px; box-sizing: border-box; border-radius: 50%; background: #6f8fd6;
       color: #fff; font-family: inherit; font-size: 11px; font-weight: 700; line-height: 1;
       letter-spacing: 0; padding: 0; border: 0; text-transform: none;
       display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.who.w2 { background: #4d9e83; }
.who.w3 { background: #b0781f; }
.who.client { background: #8892ad; }
.who.unassigned { background: #fff; color: #9aa1b3; border: 2px dashed #c3c9d6; }
/* Header size. The one place an avatar is bigger than the grid circles. */
.who.av-lg { width: 38px; height: 38px; font-size: 14px; }
/* Three characters need a smaller size to sit inside the circle (chosen initials, 2026-09-16). */
.who.who-tight { font-size: 9px; letter-spacing: -.02em; }
.who.who-tight.av-lg { font-size: 12px; }
.crm-avatar { cursor: pointer; }
.crm-avatar:hover { filter: brightness(1.12); }

/* ---------- Case detail ---------- */

/* Lock bar (the real CRM's ClientDetail pattern: amber = this session holds the lock,
   red = blocked by another holder; elapsed clock ticks). */

/* Inputs when the Summary section is in edit mode (matches the CRM's .edit-input). */
.detail-eyebrow { font-size: 12px; font-weight: 600; color: #8a8f9a; letter-spacing: .04em; }
.detail-meta { display: flex; align-items: center; gap: 8px 22px; flex-wrap: wrap; font-size: 13.5px; color: #666; }
.detail-meta .m { display: inline-flex; align-items: center; gap: 7px; }
.detail-meta a { color: #191F45; font-weight: 600; text-decoration: none; }
.detail-meta a:hover { text-decoration: underline; }
.detail-meta .m b { color: #222; font-weight: 600; }

/* Progress panel. Topline: label + status phrase + % (left) · dropdown + pencil (right). */
.stage-panel { background: #fff; border: 1px solid #e5e5e5; border-radius: 6px; padding: 12px 26px 16px; }
/* Collapsed: the topline is the whole panel — drop the space the track used to need. */
.stage-panel.collapsed { padding-bottom: 12px; }
.stage-panel.collapsed .stage-topline { margin-bottom: 0; }
.stage-topline { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.stage-topline .h { font-size: 15px; font-weight: 600; color: #191F45; }
.stage-status { font-size: 13.5px; color: #666; font-weight: 600; }
.stage-status b { color: #191F45; }
.stage-note { display: inline-flex; align-items: center; gap: 7px; border-radius: 5px; padding: 4px 12px; font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.stage-note.onhold { background: #ede9f7; color: #5b4a9e; }
.stage-note.cancelled { background: #fbe9e9; color: #b32121; }
.stage-note.archived { background: #f0f0f0; color: #777; }
.stage-right { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.stage-edit { width: 30px; height: 30px; border: 1px solid #c8c8c8; border-radius: 6px; background: #fff; color: #666; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; }
.stage-edit:hover { border-color: #6f8fd6; color: #191F45; }
.stage-edit svg { width: 14px; height: 14px; }

/* THE SHARED PROGRESS CONTROL (case detail + Settings category editor).
   Equal spacing: dot centres sit at even intervals from flush-left to flush-right on an
   absolute rail; a fill bar runs to the current dot. Every stage reserves the date line. */
/* overflow-y HIDDEN, explicitly (Steven, 2026-09-10). "overflow-x: auto" on its own computes
   overflow-y to auto as well, and the stages are absolutely positioned so a two-line label
   ("Consideration meeting") overflows the track's fixed height and raises a vertical
   scrollbar on a diagram nobody ever wants to scroll vertically. Sideways is the only
   direction that means anything here. The track is taller to match: 34px dot + 9px gap +
   two lines of label + the date line the stages all reserve. */
.stage-scroll { overflow-x: auto; overflow-y: hidden; scrollbar-gutter: stable; }
.stage-track { position: relative; height: 104px; min-width: 560px; }
.stage-track .rail, .stage-track .rail-fill { position: absolute; top: 16px; height: 3px; border-radius: 2px; }
.stage-track .rail { left: 17px; right: 17px; background: #dfe2ea; }
.stage-track .rail-fill { left: 17px; background: #6f8fd6; }
.dimmed .stage-track { opacity: .45; }
.stage { position: absolute; top: 0; display: flex; flex-direction: column; align-items: center; width: 120px; transform: translateX(-50%); }
.stage.edge-l { transform: none; align-items: flex-start; text-align: left; }
.stage.edge-r { transform: translateX(-100%); align-items: flex-end; text-align: right; }
.stage .dot { width: 34px; height: 34px; border-radius: 50%; position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; background: #fff; border: 3px solid #dfe2ea; color: #b3b8c4; font-size: 12.5px; font-weight: 700; }
.stage.done .dot { background: #6f8fd6; border-color: #6f8fd6; color: #fff; }
.stage.current .dot { border-color: #191F45; color: #191F45; box-shadow: 0 0 0 4px #e3e8f6; }
.stage .lbl { margin-top: 9px; font-size: 12px; font-weight: 600; color: #666; line-height: 1.3; }
.stage.done .lbl, .stage.current .lbl { color: #191F45; }
.stage .date { font-size: 11px; color: #8a8f9a; margin-top: 2px; min-height: 14px; }

/* Detail tabs — OUTLINED like the main workspace tabs: each tab is a bordered box, the
   active one joins the pane below, so the icons/markers inside clearly belong to their tab. */
/* Case page: the tab pane fills whatever height remains in the scroll container, so
   its bottom border sits a constant small distance from the screen edge on EVERY tab —
   and space freed above it (collapsing Progress, bigger screens) flows straight into
   the pane. Every link in the chain must grow: pane-inner → .detail-view wrapper →
   .detail-cols → .tab-pane. Same :has() trick as the list pages; taller content still
   scrolls normally. */
.ws-pane-inner:has(.detail-cols) { display: flex; flex-direction: column; }
.detail-view:has(> .detail-cols) { flex: 1 0 auto; }
.detail-cols { display: flex; flex-direction: column; flex: 1 0 auto; }
.detail-cols .tab-pane { flex: 1 0 auto; }
.tabs { display: flex; gap: 3px; align-items: flex-end; flex-wrap: wrap; }
.tab {
    border: 1px solid #ced4da; border-bottom: 0; background: #eceff4; color: #555;
    border-radius: 7px 7px 0 0; padding: 8px 12px; margin-bottom: 0;
    font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
    display: inline-flex; align-items: center; gap: 7px; position: relative;
    /* A floor, so a two-letter label ("AI") is not a sliver beside its neighbours (Steven,
       2026-09-17). Centred, which only shows on a tab the floor has widened. */
    min-width: 76px; justify-content: center;
}
.tab:hover { background: #f4f6f9; color: #191F45; }
/* A tab onto a screen the person can't View (permissions Model B, 2026-10-07): greyed, a lock, "No access · needs …"
   on hover, and it can't be pressed. */
.tab.off, .tab.off:hover { background: #f3f4f7; color: #9aa0ad; cursor: not-allowed; }
.tab.on {
    background: #fff; color: #191F45;
    margin-bottom: -1px; padding-bottom: 9px;   /* drops over the pane's top border */
    z-index: 1;
}
/* Colour semantics (Steven, 2026-08-28): the DANGER signal sits where the risk lives —
   CLIENT notes are red (whatever goes here, the client sees); INTERNAL notes are green
   (safe, internal eyes only). */
.tab.client.on { color: #b32121; }
.tab.internal.on { color: #1c7a44; }
.tab .cnt { font-size: 11px; background: #e4e7ee; color: #666; border-radius: 8px; padding: 0 6px; line-height: 16px; }
/* Directional counters: ↑ sent to the client, ↓ received from the client. */
.tab .cnt.up { background: #e3ecfa; color: #2b5cad; }
.tab .cnt.down { background: #e2f4e8; color: #1c7a44; }
.dir-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 11px; white-space: nowrap; }
.dir-chip.out { background: #e3ecfa; color: #2b5cad; }
.dir-chip.in { background: #e2f4e8; color: #1c7a44; }
.file-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; background: #eceff4; color: #191F45; border-radius: 5px; padding: 2px 9px; margin: 4px 6px 0 0; }
.file-chip .x { border: 0; background: none; color: inherit; opacity: .55; cursor: pointer; padding: 0; font-size: 13px; }
.file-chip .x:hover { opacity: 1; }
.tab-pane { background: #fff; border: 1px solid #ced4da; border-radius: 0 6px 6px 6px; padding: 18px 20px; }
/* A pane with no tab above it (Virtual HRM → Document Templates, 2026-10-09): all four corners round. */
.tab-pane.doc-pane-solo { border-radius: 6px; }

/* Summary tab: label/value pairs kept CLOSE (no full-width sprawl). */
.summary-grid { display: grid; grid-template-columns: 130px minmax(160px, max-content) 60px 130px minmax(160px, max-content); gap: 10px 16px; padding: 6px 2px; margin: 0; }
.summary-grid dt { color: #666; font-weight: 400; font-size: 13.5px; align-self: center; }
.summary-grid dd { margin: 0; color: #222; font-size: 13.5px; font-weight: 600; align-self: center; display: flex; align-items: center; gap: 7px; }
.summary-grid dd a { color: #191F45; text-decoration: none; }
.summary-grid .gap { grid-column: 3; }
/* Title and Description above the grid, and Policy documents below it (2026-09-16) — the same 130px
   label column, so the labels line up with the grid's; the value takes the width it needs, to a limit. */
.case-headline { display: grid; grid-template-columns: 130px minmax(0, 760px); gap: 10px 16px; padding: 6px 2px; margin: 0 0 8px; }
.case-headline dt { color: #666; font-weight: 400; font-size: 13.5px; padding-top: 2px; }
.case-headline dd { margin: 0; color: #222; font-size: 13.5px; min-width: 0; }
.case-headline dd b { font-weight: 600; }
.case-headline .edit-input { width: 100%; box-sizing: border-box; }
.case-headline textarea.edit-input { resize: vertical; min-height: 64px; font: inherit; line-height: 1.45; }
.case-desc { white-space: pre-line; line-height: 1.5; }
.case-policy { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid #eef0f4; }
.case-policy dd { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.policy-docs { display: flex; flex-wrap: wrap; gap: 8px; }
.policy-doc { display: inline-flex; align-items: center; gap: 6px; border: 1px solid #dde2ea; border-radius: 8px; background: #fff; padding: 5px 6px 5px 10px; }
.policy-doc-link { display: inline-flex; align-items: center; gap: 7px; color: #191F45; text-decoration: none; font-weight: 600; max-width: 340px; }
.policy-doc-link:hover .policy-doc-name { text-decoration: underline; }
.policy-doc-link .doc-icon { font-size: 22px; }
.policy-doc-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.policy-doc .doc-pill { margin: 0; }
.policy-doc-remove { border: 0; background: transparent; color: #8a90a6; cursor: pointer; padding: 2px 4px; border-radius: 4px; line-height: 1; }
.policy-doc-remove:hover { color: #b32121; background: #fbe9e9; }

.note-strip { display: flex; align-items: center; gap: 8px; font-size: 12.5px; border-radius: 5px; padding: 7px 12px; margin-bottom: 14px; font-weight: 600; }
.note-strip.client { background: #fbe9e9; color: #b32121; }
.note-strip.internal { background: #e2f4e8; color: #1c7a44; }
.note { display: flex; gap: 11px; padding: 12px 2px; border-bottom: 1px solid #eef0f4; }
.note:last-of-type { border-bottom: 0; }
.note .body { flex: 1; }
.note .meta { font-size: 12px; color: #8a8f9a; margin-bottom: 3px; }
.note .meta b { color: #222; font-size: 12.5px; }
.note p { margin: 0; font-size: 13.5px; line-height: 1.5; color: #222; }
.note-compose { display: flex; gap: 10px; margin-top: 14px; }
.note-compose input { flex: 1; border: 1px solid #c8c8c8; border-radius: 6px; padding: 8px 12px; font-size: 13.5px; font-family: inherit; }
.empty-hint { color: #8a8f9a; font-size: 13px; font-style: italic; padding: 8px 2px; }
.doc-vis { font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 11px; display: inline-block; }
.doc-vis.yes { background: #e2f4e8; color: #1c7a44; }
.doc-vis.no { background: #f0f0f0; color: #777; }
.role-chip { display: inline-block; font-size: 12px; font-weight: 600; padding: 2px 10px; border-radius: 11px; background: #e7edf6; color: #191F45; }
.act { display: flex; gap: 12px; padding: 10px 2px; border-bottom: 1px solid #eef0f4; align-items: flex-start; }
.act:last-child { border-bottom: 0; }
.act .ic { width: 28px; height: 28px; border-radius: 50%; background: #eceff4; color: #191F45; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; margin-top: 1px; }
.act .ic svg { width: 14px; height: 14px; }
.act .t { font-size: 13.5px; color: #222; }
.act .when { font-size: 12px; color: #8a8f9a; margin-top: 2px; }
.act-log { display: flex; gap: 8px; margin-top: 14px; align-items: center; flex-wrap: wrap; }
.act-log input { flex: 1; min-width: 160px; border: 1px solid #c8c8c8; border-radius: 6px; padding: 7px 10px; font-size: 13px; font-family: inherit; }

/* ---------- Settings ---------- */
.settings-layout { display: grid; grid-template-columns: 210px 1fr; gap: 20px; align-items: start; }
.settings-nav { background: #fff; border: 1px solid #e5e5e5; border-radius: 6px; overflow: hidden; }
.settings-nav .grp { padding: 10px 14px 4px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #8a8f9a; }
.settings-nav button { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 8px 14px 8px 22px; font-size: 13.5px; color: #444; cursor: pointer; font-family: inherit; }
.settings-nav button:hover { background: #f4f5f7; }
.settings-nav button.on { background: #eceff4; color: #191F45; font-weight: 600; }
.settings-nav .dis { color: #b3b8c4; cursor: default; }
.settings-nav .dis:hover { background: none; }
.chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.step-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; background: #eceff4; color: #191F45; border-radius: 14px; padding: 4px 12px; }
.step-chip.sys { background: #e3ecfa; color: #2b5cad; }
.step-chip .x { border: 0; background: none; color: inherit; opacity: .55; cursor: pointer; font-size: 13px; padding: 0; }
.step-chip .x:hover { opacity: 1; }

/* Config step rows (category editor + edit-steps dialog share the look) */
.step-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid #e4e7ee; border-radius: 6px; margin-bottom: 6px; background: #fbfcfe; }
.step-row .n { width: 22px; height: 22px; border-radius: 50%; font-size: 11px; font-weight: 700; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; background: #e4e7ee; color: #666; }
.step-row.done .n { background: #6f8fd6; color: #fff; }
.step-row .nm { flex: 1; font-size: 13.5px; font-weight: 600; color: #222; padding: 4px 6px; }
.step-row input[type=text] { flex: 1; border: 1px solid transparent; background: transparent; font-family: inherit; font-size: 13.5px; padding: 4px 6px; border-radius: 4px; color: #222; font-weight: 600; }
.step-row input[type=text]:hover:not(:disabled), .step-row input[type=text]:focus { border-color: #c8c8c8; background: #fff; outline: none; }
.step-row .done-lbl { font-size: 11px; color: #1c7a44; font-weight: 700; }
.step-lock { font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #8a8f9a; background: #eef0f5; border-radius: 3px; padding: 2px 7px; flex: 0 0 auto; }
.step-custom { font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #9a6a12; background: #fdf1dc; border-radius: 3px; padding: 2px 7px; flex: 0 0 auto; }
.step-btn { width: 26px; height: 26px; border: 1px solid #d5d9e2; background: #fff; border-radius: 5px; color: #666; cursor: pointer; font-size: 13px; line-height: 1; flex: 0 0 auto; }
.step-btn:hover:not(:disabled) { border-color: #6f8fd6; color: #191F45; }
.step-btn:disabled { opacity: .35; cursor: default; }
.step-btn.del:hover:not(:disabled) { border-color: #b32121; color: #b32121; }
.step-add { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; align-items: center; }
.step-add input, .step-add select { border: 1px solid #c8c8c8; border-radius: 6px; padding: 8px 12px; font-size: 13.5px; font-family: inherit; }
.step-add .or { font-size: 12px; color: #8a8f9a; font-weight: 600; }

/* Add-step panel (edit-steps dialog): radio choice between library and custom. */
.add-panel { border: 1px solid #e4e7ee; border-radius: 8px; background: #fbfcfe; padding: 12px 14px; margin-top: 14px; }
.add-panel-head { font-size: 13px; font-weight: 600; color: #191F45; margin-bottom: 8px; }
.add-panel-modes { display: flex; gap: 18px; margin-bottom: 10px; }
.add-panel-modes label { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; color: #444; cursor: pointer; }
.add-panel-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.add-panel-row select, .add-panel-row input { border: 1px solid #c8c8c8; border-radius: 6px; padding: 8px 12px; font-size: 13.5px; font-family: inherit; min-width: 240px; }
.add-panel-info { font-size: 12px; color: #8a8f9a; }

/* ---------- Modals ---------- */
.dlg-overlay { position: fixed; inset: 0; background: rgba(16,20,42,.45); z-index: 100; display: none; align-items: center; justify-content: center; padding: 20px; }
.dlg-overlay.open { display: flex; }
.dlg { background: #fff; border-radius: 10px; width: 620px; max-width: 100%; box-shadow: 0 18px 50px rgba(10,14,35,.35); max-height: 88vh; display: flex; flex-direction: column; }
.dlg-head { padding: 14px 20px; border-bottom: 1px solid #e5e5e5; display: flex; align-items: center; font-size: 15px; font-weight: 600; color: #191F45; }
.dlg-head .x { margin-left: auto; border: 0; background: transparent; font-size: 20px; color: #8a8f9a; cursor: pointer; line-height: 1; }
.dlg-head .x:hover { color: #222; }
.dlg-head .x:disabled { color: #c5c8d0; cursor: default; }
.dlg-body { padding: 16px 20px; overflow-y: auto; }
/* align-items: center — a multi-line note in the footer must not stretch the buttons tall
   (flex default is stretch); buttons never wrap their captions. */
.dlg-foot { padding: 12px 20px; border-top: 1px solid #e5e5e5; display: flex; gap: 8px; justify-content: flex-end; align-items: center; }
.dlg-foot .cmd-btn { white-space: nowrap; flex: 0 0 auto; }
.dlg-hint { font-size: 12.5px; color: #8a8f9a; margin: 0 0 12px; }
.form-field { margin-bottom: 14px; }
.form-field label { display: block; font-size: 13px; font-weight: 600; color: #191F45; margin-bottom: 5px; }
.form-field input, .form-field select, .form-field textarea { width: 100%; border: 1px solid #c8c8c8; border-radius: 6px; padding: 8px 12px; font-size: 13.5px; font-family: inherit; }
/* Checkboxes/radios in a form field size themselves — the width:100% above would stretch
   them across the row and shove their label text to the far edge. */
.form-field input[type=checkbox], .form-field input[type=radio] { width: auto; }
/* A box that can't be changed must LOOK it (2026-10-08: a portal user's email in the contact dialog read as
   editable) - grey ground, muted text, no text cursor. Shape and the note beside it, not colour alone.
   Never DevExpress's own editors: a DxComboBox you pick from (no typing) marks its inner box readonly, and
   greyed it out though it works (the T&E entry's Action, the same day). */
.form-field input:is([readonly], :disabled):not([type=checkbox], [type=radio]):not([class*="dxbl"]):not([class*="dxbl"] *),
.form-field select:disabled,
.form-field textarea:is([readonly], :disabled) {
    background: #f1f2f5; color: #5b6275; border-color: #dcdfe6; cursor: default;
}

/* Cases command row: the view/filter cluster sits clearly apart from New/Refresh. */
.cmd-filters { display: flex; align-items: center; gap: 10px; margin-left: 56px; }
/* Both list screens' toolbars reserve the same height (Clients' three-row search stack
   sets the tallest case), so the content below always starts at the same position. */
.list-toolbar { min-height: 80px; }
/* Secondary line under a grid's main link (e.g. the case reference) — clickable, quiet. */
.grid-sublink { display: block; font-size: 12px; color: #666; text-decoration: none; margin-top: 1px; }
.grid-sublink:hover { text-decoration: underline; color: #16233f; }
/* Tile client line is a real link into the client record. */
a.co { text-decoration: none; }
a.co:hover { text-decoration: underline; color: #16233f; }
/* An EMPTY tile column collapses to just its header, shaped as a rounded pill — the title
   sits exactly where a populated column's header sits. */
.board-col.empty { min-height: 0; padding: 10px; }   /* identical box to a populated column up to the card-top line */
.board-col.empty .board-col-head { padding-bottom: 0; }   /* head's 10px hand-off to the first card becomes the pill's own bottom padding — bottom edge = card top */
/* The tile's client link is clickable only over the TEXT, not the whole row — the rest of
   that line stays part of the card's open-the-case click. */
.case-card a.co { display: inline-block; }
/* Mutating controls read as OFF outside edit mode, like every cmd-btn already does. */
.edit-input:disabled { background: #f2f3f6; color: #a2a6b3; border-color: #e2e4ea; cursor: default; }
.stage-edit:disabled { color: #c9cdd7; border-color: #e2e4ea; background: #f7f8fa; cursor: default; }
.stage-edit:disabled:hover { border-color: #e2e4ea; color: #c9cdd7; }
/* Bordered danger button (dialog Delete/Remove, settings deletes): outline at rest, the
   red treatment on hover — border included. Clients' borderless commandbar Delete is
   plain .cmd-btn-danger and stays as it was. */
.cmd-btn-outline.cmd-btn-danger:hover:not(:disabled) { background: #fbe9e9; color: #b32121; border-color: #e0b4b4; }
/* The lock bar's self-session Take over button sits tight against the message. */
.lock-bar .lock-takeover { padding: 2px 10px; font-size: 12.5px; margin-left: 6px; background: #fff; }

/* ============================ Settings (restructured) ============================
   Clean second-level menu (no sub-menus; tabs inside each section). */
.set-page { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.set-title { font-size: 27px; font-weight: 600; color: #191F45; margin: 0; }
.set-sub { font-size: 13.5px; color: #8a8f9a; margin: 2px 0 18px; }
.set-layout { display: flex; gap: 26px; min-height: 0; flex: 1; align-items: flex-start; }
.set-nav { flex: 0 0 210px; display: flex; flex-direction: column; gap: 2px; }
.set-nav button {
    display: flex; align-items: center; gap: 10px; text-align: left;
    border: 0; background: transparent; cursor: pointer; font: inherit;
    font-size: 14.5px; color: #333a4d; padding: 9px 14px; border-radius: 8px;
}
.set-nav button i { font-size: 18px; color: #6a7186; }
.set-nav button:hover { background: #f1f2f6; }
.set-nav button.on { background: #e9edf9; color: #191F45; font-weight: 600; }
.set-nav button.on i { color: #3d5296; }
/* A section the person can't View (Model B): greyed, a lock, the reason on hover, not pressable. */
.set-nav button.off, .set-nav button.off:hover { background: transparent; color: #9aa0ad; cursor: not-allowed; }
.set-nav button.off i { color: #b9c1cf; }
/* Its lock at the right, every one in the same column (Steven, 2026-10-10: "align the locks, always"). */
.set-nav button .set-label { flex: 1 1 auto; min-width: 0; }
.set-nav button .set-lock { margin-left: auto; flex: 0 0 auto; width: 18px; text-align: center; font-size: 16px; }
.set-body { flex: 1; min-width: 0; }
.set-body .tab-pane { padding-top: 16px; }

/* The standard inner-tab accent: the DevExpress Office-White orange Clients' tabs use,
   as a top edge on the ACTIVE tab (internal-notes red still wins for its label). */
.tab.on { border-top: 3px solid #fe7109; padding-top: 6px; }
/* A disabled primary keeps its navy-on-white look, just dimmed — the base .cmd-btn:disabled
   grey text would otherwise out-specify .cmd-btn-primary and leave navy-with-grey-text. */
.cmd-btn-primary:disabled { background: #191F45; color: #fff; opacity: .45; }

/* =============================================================================
   Client Retainer tab (transcribed from the billing-crm-v1 mockup). */
.panel-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: stretch; }
@media (max-width: 980px) { .panel-row { grid-template-columns: 1fr; } }
/* The fee block is exactly the width of the label column below (130px + 16px gap), so the
   offering name + comment line up with the values underneath. */
.agr-top { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.agr-fee { font-size: 30px; font-weight: 700; color: #191F45; line-height: 1.05; flex: 0 0 130px; }
.agr-fee small { font-size: 13px; font-weight: 400; color: #666; display: block; margin-top: 2px; }
.agr-off { flex: 1; min-width: 240px; }
.agr-off .nm { font-size: 15px; font-weight: 600; color: #191F45; }
.agr-off .lineage { font-size: 12.5px; color: #666; margin-top: 2px; }
.badge { display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; border-radius: 3px; padding: 2px 7px; vertical-align: 2px; margin-left: 8px; }
.badge.bespoke { background: #fdeadd; color: #b25a12; }
.badge.standard { background: #e7edf6; color: #16233f; }
.badge.onfile { background: #e2f4e8; color: #1c7a44; margin-left: 2px; }
.badge.missing { background: #fbe9e9; color: #b32121; margin-left: 2px; }
.agr-grid { display: grid; grid-template-columns: 130px 1fr; gap: 9px 16px; margin: 16px 0 0; font-size: 13.5px; }
.agr-grid dt { color: #666; }
.agr-grid dd { margin: 0; color: #222; font-weight: 600; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.kv { display: grid; grid-template-columns: 150px 1fr; gap: 9px 14px; font-size: 13.5px; margin: 0; }
.kv dt { color: #666; align-self: center; }
.kv dd { margin: 0; color: #222; font-weight: 600; align-self: center; }
.dev-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: #fe7109; flex: 0 0 auto; }
.empty-retainer { text-align: center; padding: 34px 20px 38px; color: #666; }
.empty-retainer .big { font-size: 16px; font-weight: 600; color: #191F45; margin-bottom: 6px; }
.empty-retainer p { margin: 0 auto 16px; font-size: 13.5px; max-width: 52ch; }
.badge.legacy { background: #f0f0f0; color: #777; }

/* Online sign-up preview (Settings > Retainers) — how the public sign-up cards will look.
   This preview IS the spec for the future public page. */
.signup-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.signup-card { border: 1px solid #dfe2ea; border-radius: 10px; padding: 18px 18px 16px; display: flex; flex-direction: column; gap: 8px; background: #fff; }
.signup-card:hover { border-color: #6f8fd6; box-shadow: 0 2px 10px rgba(20,26,58,.10); }
.su-name { font-size: 14px; font-weight: 700; color: #191F45; line-height: 1.3; }
.su-price { font-size: 28px; font-weight: 700; color: #191F45; }
.su-price span { font-size: 13px; font-weight: 400; color: #666; margin-left: 3px; }
.su-desc { font-size: 12.5px; color: #555; line-height: 1.45; }
.su-includes { list-style: none; margin: 2px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.su-includes li { font-size: 12.5px; color: #333; display: flex; align-items: center; gap: 7px; }
.su-includes li i { color: #1c7a44; font-size: 13px; }
.su-small { font-size: 11.5px; color: #8a8f9a; margin-top: auto; padding-top: 8px; }
.su-cta { justify-content: center; }

/* Retainers grid anomaly tint — on the CELL carrying the problem (Agreement cell with no
   retainer, Contract cell with nothing on file). !important beats DevExpress's own cell
   background. */
.list-grid td.cell-alert { background-color: #fbe9e9 !important; }

/* Deviation pills — which aspects of a deal stray from its source offering
   (Price / Includes / Allowance / Rate). Panel lineage line + retainer dialog. */
.dev-pill { display: inline-block; font-size: 10.5px; font-weight: 700; background: #fdeadd; color: #b25a12; border-radius: 9px; padding: 1px 8px; margin-left: 4px; vertical-align: 1px; }
.dev-line { font-size: 12.5px; color: #444; font-weight: 600; margin: 2px 0 10px; }
.dev-line.matches { color: #1c7a44; }
.dev-details { display: flex; flex-direction: column; gap: 4px; margin: 0 0 12px; }
.dev-row { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; color: #444; }
.dev-row .dev-pill { margin-left: 0; flex: 0 0 auto; min-width: 68px; text-align: center; }
/* Inline link-styled button (view the standard offering, etc.). */
.link-btn { background: none; border: 0; padding: 0; margin-left: 6px; font-family: inherit; font-size: 12px; font-weight: 600; color: #16233f; text-decoration: underline; cursor: pointer; }
.link-btn:hover { color: #2b5cad; }

/* Retainer summary strip atop the case Time & Expenses tab — the capture context at a
   glance: package, allowance, includes, overage. */
.retainer-strip { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: #fbfcfe; border: 1px solid #e4e7ee; border-radius: 7px; padding: 8px 14px; margin-bottom: 14px; font-size: 13px; }
.retainer-strip .rs-name { font-weight: 700; color: #191F45; }
.retainer-strip .rs-item { color: #444; }
.retainer-strip .step-chip { padding: 2px 10px; font-size: 12px; }
.retainer-strip .rs-sep { color: #b3b8c4; }
/* Action combo dropdown rows: name left, coverage pill right — pills align in a column. */
.combo-row { display: flex; align-items: center; gap: 12px; width: 100%; }
.combo-row .badge { margin-left: auto; }

/* Time & Expenses grid: consultant circle stacks (hover names, help cursor), the
   Billable/Billed tick-cross glyphs, and the dialog's avatar toggle picker. */
.who-stack { display: inline-flex; }
.who-stack .who { border: 2px solid #fff; margin-left: -7px; cursor: help; }
.who-stack .who:first-child { margin-left: 0; }
.bill-yes { color: #1c7a44; font-weight: 700; font-size: 15px; }
.bill-no { color: #b32121; font-weight: 700; font-size: 15px; }
.who-pick { display: flex; gap: 8px; flex-wrap: wrap; padding: 2px 0; }
.who-pick .who { border: 0; padding: 0; cursor: pointer; font-family: inherit; }
.who-pick .who.off { opacity: .3; filter: grayscale(1); }
.who-pick .who:hover:not(:disabled) { box-shadow: 0 0 0 3px #e3e8f6; }
.who-pick .who:disabled { cursor: default; }

/* DxComboBox dropdown items follow the app's quiet selection highlight, not the
   office-white theme's orange primary (native selects don't glow orange either).
   The theme HARD-CODES #fe7109 on tr.dxbl-list-box-item-selected (td + a ::before
   overlay) with huge selector specificity — hence !important on the real selectors. */
tr.dxbl-list-box-item-selected > td,
tr.dxbl-list-box-item-selected > td::before {
    background-color: #e9edf9 !important;
    color: #191F45 !important;
}
tr.dxbl-list-box-item-selected:hover > td,
tr.dxbl-list-box-item-selected:hover > td::before {
    background-color: #e2e7f5 !important;
    color: #191F45 !important;
}
.dxbl-list-box { --dxbl-list-box-focus-frame-color: #6f8fd6; --dxbl-list-box-focus-color: #191F45; }
/* MultiPickDropdown — the CRM multiselect filter (who / client pickers). The button
   mirrors .cmd-filter select; rows are circle+name with a ✓ on picked rows (state is
   never colour-only). */
.mpd { position: relative; display: inline-flex; }
.mpd-btn {
    display: inline-flex; align-items: center; gap: 8px; min-width: 150px;
    border: 1px solid #c8c8c8; border-radius: 6px; padding: 4px 8px;
    font-size: 14px; background: #fff; color: #222; cursor: pointer;
}
.mpd-btn .ti-chevron-down { margin-left: auto; color: #888; font-size: 13px; }
.mpd-btn .who { flex: 0 0 auto; }
.mpd-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mpd-overlay { position: fixed; inset: 0; z-index: 60; }
.mpd-panel {
    position: absolute; top: calc(100% + 4px); left: 0; z-index: 61; min-width: 230px;
    max-height: 340px; overflow-y: auto; background: #fff; border: 1px solid #ced4da;
    border-radius: 6px; box-shadow: 0 6px 18px rgba(25, 31, 69, .14); padding: 4px;
}
.mpd-search { display: flex; align-items: center; gap: 6px; padding: 4px 8px 6px; border-bottom: 1px solid #eceff4; margin-bottom: 4px; }
.mpd-search i { color: #888; font-size: 13px; }
.mpd-search input { border: 0; outline: none; flex: 1; font-size: 13.5px; background: transparent; }
.mpd-row {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    border: 0; background: transparent; border-radius: 5px; padding: 6px 8px;
    font-size: 13.5px; color: #222; cursor: pointer;
}
.mpd-row:hover { background: #eceff7; }
.mpd-row.on .mpd-name { font-weight: 600; }
.mpd-row .ti-check { margin-left: auto; color: #191F45; font-size: 14px; }
.mpd-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Settings → My Account: the avatar swatch picker (30 fixed colours, one per person). */
.acct-h { font-size: 15px; font-weight: 600; color: #191F45; margin: 0 0 6px; }
.acct-preview { display: flex; align-items: center; gap: 10px; margin: 8px 0 14px; }
.swatch-grid { display: grid; grid-template-columns: repeat(7, 36px); gap: 9px; }
.swatch {
    width: 36px; height: 36px; border-radius: 50%; border: 2px solid #fff;
    box-shadow: 0 0 0 1px #ced4da; cursor: pointer; color: #fff; padding: 0;
    display: inline-flex; align-items: center; justify-content: center; font-size: 14px;
}
.swatch:hover:not(:disabled) { box-shadow: 0 0 0 2px #191F45; }
.swatch:disabled { cursor: default; opacity: .55; }
.swatch-owner { font-size: 10px; font-weight: 700; }
/* My Account → the initials box, and everybody else's circles underneath it. */
.acct-sub-h { font-size: 13.5px; font-weight: 600; color: #191F45; margin: 20px 0 4px; }
.acct-initials { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin: 4px 0 8px; }
.acct-initials .form-field { margin: 0; }
.acct-initials-box { width: 96px; text-transform: uppercase; letter-spacing: .08em; font-weight: 600; }
.acct-initials .cell-sub { padding-bottom: 6px; }
.acct-others { display: flex; align-items: center; gap: 6px 16px; flex-wrap: wrap; margin: 6px 0 4px; }
.acct-other { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: #444; }
/* Avatars that explain themselves on hover (grid provenance dots etc.). */
.av-help { cursor: help; }
/* Neutral avatar circle — Anyone ("A"), the several-selected count, provenance dots:
   not a person, so never a person's colour. */
.who-neutral { background: #8a90a6 !important; }
/* Fixed-width MultiPickDropdown variants (the button never grows with content). */
.mpd-w200 .mpd-btn { width: 200px; }
/* The status filters (StatusPicker): wide enough for TWO status pills side by side — both work
   statuses at once (Steven, 2026-09-11). Three or more picked show a count instead, so the
   width stays fixed like every other toolbar control. */
.mpd-status .mpd-btn { width: 232px; }
.mpd-pills { display: inline-flex; gap: 4px; align-items: center; min-width: 0; flex: 1 1 auto;
             overflow: hidden; white-space: nowrap; }
/* T&E global filter grid: Who · Dates on row one, Client · Status aligned beneath. */
/* Compressed so the two rows fit the STANDARD toolbar height — the grid must start
   level with Clients/Cases. Buttons pin to the toolbar top (te-commandbar), and the
   display options share one right-aligned line under the search box. */
/* Buttons pin to the TOP of the two-row filter grid, but keep the standard bar's own
   34px band so their text sits exactly where it does on Clients and Cases (Steven,
   2026-09-09: "the location of the new and refresh buttons have gone out of whack"). */
.te-commandbar { align-items: flex-start; }
.te-commandbar > .cmd-btn { align-self: flex-start; min-height: 34px; }
.te-filter-grid { display: grid; grid-template-columns: auto auto; gap: 4px 26px; align-items: center; margin-left: 70px; }
.te-filter-grid .mpd-btn, .te-filter-grid select { padding: 4px 8px; height: 31px; box-sizing: border-box; }
/* THE date field (shared DateField component). Two contexts, two pinned heights:
   default matches the dialog form controls (.form-field metrics), .compact matches the
   toolbar controls — and the toolbar selects are pinned to the SAME height below, so
   the pair can never drift apart again. */
.date-field {
    border: 1px solid #c8c8c8; border-radius: 6px; padding: 8px 12px;
    font-size: 13.5px; background: #fff; color: #222;
    height: 37px; box-sizing: border-box; font-family: inherit;
}
.date-field.compact { padding: 4px 8px; font-size: 14px; height: 31px; }
.date-field:disabled { background: #f5f5f5; color: #888; }
/* Avatar stacks in grid Who cells (multi-person lines). */
.av-stack { display: inline-flex; cursor: help; }
.av-stack .who { box-shadow: 0 0 0 2px #fff; }
.av-stack .who + .who { margin-left: -3px; }
/* Group bands: a stronger shade + a colour strip down the left edge. */
.list-grid .dxbl-grid-group-row > td,
.list-grid tr[class*="group-row"] > td { background: #dfe6f3 !important; }
.list-grid .dxbl-grid-group-row > td:first-child,
.list-grid tr[class*="group-row"] > td:first-child { border-left: 4px solid #6f8fd6 !important; }
/* Who dropdown closed state: picked avatars lined up, slight overlap, ringed. */
.mpd-avrow { display: inline-flex; }
.mpd-avrow .who { box-shadow: 0 0 0 2px #fff; }
.mpd-avrow .who + .who { margin-left: -3px; }   /* both initials stay readable */
/* The dialog's live outcome line + the provisional tag on allowance meters. */
.outcome-line { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: #f7f8fb; border: 1px solid #e2e6ef; border-radius: 6px; margin-bottom: 12px; font-size: 13.5px; }
.outcome-line .cell-sub { flex: 1; }
.prov-tag { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #9a6a12; background: #fdf1dc; border-radius: 3px; padding: 1px 5px; margin-left: 4px; }
/* The T&E client board (v2 layout, Steven 2026-09-07): band with the retainer facts,
   position-style standings table per client, totals at each group's foot. */
/* The board scrolls itself — the pane's own scroll is off whenever a list-view is
   mounted (the frozen-frame rule above), so without this nothing below the fold is
   reachable. */
.te-board { flex: 1 1 0; min-height: 0; overflow-y: auto; padding-right: 2px; }
.te-co-block { margin-bottom: 18px; }
.te-co-band { background: #e7ebf2; border: 1px solid #ced4da; border-bottom: 0; border-radius: 7px 7px 0 0; padding: 8px 14px; display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.te-co-name { font-size: 15px; font-weight: 700; flex: 0 0 460px; min-width: 0; overflow-wrap: break-word; }
/* No underline on hover here (Steven, 2026-09-09). .grid-link underlines on hover, which is
   right in a grid cell and wrong on a 460px-wide heading: the pointer is over it whenever
   somebody reaches for the band, so it flickered constantly. */
.te-co-name:hover { text-decoration: none; }
.te-co-facts { font-size: 12.5px; color: #444; display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; flex: 1 1 0; min-width: 0; }
.te-co-facts b { color: #191F45; }
.te-fact-sep { color: #a5abb8; font-size: 17px; font-weight: 700; line-height: 1; }
.te-co-band-tog { cursor: pointer; }
.te-co-band-tog:hover { background: #dfe6f3; }
.te-co-tog { color: #52586e; font-size: 24px; width: 28px; flex: 0 0 auto; line-height: 1; align-self: center; }
/* Collapsed band: the totals stay in place (same figures as the table's foot). */
.te-co-collapsed { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; background: #fbfcfe; border: 1px solid #ced4da; border-top: 0; padding: 8px 14px 8px 42px; font-size: 13px; color: #555; }
.te-co-collapsed b { color: #191F45; }

/* The run screen (/billing/runs/{id}) + the statement document (agreed 2026-09-07). */
/* NO CARD (Steven, 2026-09-09): a white box on a white page was drawing a border around
   three facts and calling it a panel. The head is ONE row - title and facts on the left,
   provenance and actions stacked right - and it matches .list-toolbar's 80px, so the table
   below starts level with the grid on Clients and every other list screen. Margins are the
   parent's business (.detail-view has its own 12px gap); a margin here would push the table
   past that line again. */
.rd-head { display: flex; align-items: flex-start; gap: 24px; flex-wrap: wrap; min-height: 80px; }
/* Title, then the facts beneath it (Steven, 2026-09-09). */
.rd-headline { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* A tight heading line-height, because the 80px budget is shared with three rows of facts. */
.rd-head .detail-title { line-height: 1.15; }
/* The run's status is the second most important thing in the head, and at pill size it read
   as a footnote to the name (Steven, 2026-09-10). Bigger, and given room to breathe. */
.rd-head .detail-title .pill { font-size: 14px; padding: 4px 14px; border-radius: 13px;
                               margin-left: 12px; vertical-align: 4px; }
/* Label column, value column, both left-aligned - the same treatment as the provenance block
   opposite, so the two halves of the head read as one thing.

   The size is arithmetic, not taste: the head is held to 80px so the table starts level with
   the Clients grid, the heading takes 29.9px and the gap 2px, which leaves ~48px. At TWO
   facts (Billable moved to the pinned totals row) that is 24px a row, so 18px/1.3 fits with
   a little to spare. Three facts is what forced it down to 12.5px before. */
.rd-facts { display: grid; grid-template-columns: max-content max-content; justify-items: start;
            gap: 0 12px; font-size: 18px; line-height: 1.3; font-weight: 400; color: #444; }
.rd-facts b { color: #191F45; font-weight: 600; }
/* THE RECEIPT on a billed row's (i): label and fact in two columns, so invoice, statement and
   recipients line up as three answers to three questions rather than a paragraph to read. */
.rd-receipt { display: grid; grid-template-columns: max-content 1fr; gap: 8px 14px;
              font-size: 13.5px; line-height: 1.45; align-items: start; }
.rd-receipt b { color: #191F45; font-weight: 600; }
/* A label that carries a hint is still a label: the shared control renders its text plain, so
   the weight it would have had as <b> is put back here rather than inside the control, which
   has no business knowing it is being used in a two-column card. */
.rd-receipt > div > .hint { color: #191F45; font-weight: 600; }
/* THE MARKERS LINE UP (Steven, 2026-09-11). Each (i) used to sit straight after its own label,
   so "Included" and "Allowance" — different widths — put their markers at different x. The hint
   fills the label column now and the marker goes to its right edge, which is the same edge for
   every label in the card. */
.rd-receipt > div > .hint { display: flex; justify-content: space-between; width: 100%; }
/* The label half of "Period: 1 Aug – 31 Aug" - present, but never competing with the value. */
.rd-lab { color: #7a8093; font-weight: 400; }
.rd-side { flex: 1 1 0; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
/* The provenance and the buttons stay LEFT-aligned to each other inside that right-hand
   block - labels under labels, values under values (Steven, 2026-09-09). */
.rd-side > * { align-self: flex-end; }
.rd-prov, .rd-actions { text-align: left; }
/* Labels under labels, values under values (Steven, 2026-09-09). max-content on both tracks
   so the columns are as wide as their longest line and no wider. */
.rd-prov { display: grid; grid-template-columns: max-content max-content; justify-items: start;
           gap: 2px 10px; font-size: 12px; color: #6b7180; line-height: 1.5; }
/* THE COUNTS, in the middle of the head (Steven, 2026-09-10). Its own flex track so it sits
   centred rather than shoved against whichever neighbour is wider. */
/* Centred BETWEEN the title and the provenance (Steven, 2026-09-10), which needs all three
   tracks to be equal — centring the middle one of three unequal tracks puts the table at the
   midpoint of its own share, not the midpoint of the head. .rd-side gives up its auto width
   and aligns its content right instead. */
.rd-countwrap { flex: 1 1 0; display: flex; justify-content: center; }
.rd-counts { border-collapse: collapse; align-self: flex-start; background: #fff; border: 1px solid #ced4da; }
.rd-counts th { background: #eceff4; font-size: 10.5px; font-weight: 700; color: #6b7180; text-transform: uppercase;
                letter-spacing: .05em; padding: 3px 12px; border-bottom: 1px solid #ced4da; text-align: center; white-space: nowrap; }
.rd-counts th.top { background: #191F45; color: #fff; letter-spacing: .09em; padding: 3px 0; }
.rd-counts td { padding: 4px 12px; text-align: center; font-size: 17px; font-weight: 600; color: #191F45;
                font-variant-numeric: tabular-nums; }
/* A zero stays VISIBLE, just quiet — a count that disappears at nought makes the row jump
   and hides the fact that it is nought. */
.rd-counts td.zero { color: #b9bec9; font-weight: 400; }
.rd-counts td.cb { color: #1c7a44; }
.rd-counts td.cf { color: #b32121; }
/* Total is the whole rather than one of the parts, so it is shaded and ruled off. */
.rd-counts .tot { background: #eef2f9; border-left: 2px solid #ced4da; }
.rd-counts th.tot { background: #e3e9f4; }

/* THE ACTION RAIL: fixed tracks, so every control keeps its x down the whole column and
   Discard is always last on the right. Nothing appears or disappears with status — it is
   disabled instead, which is the only way a row's controls stay where the hand expects. */
/* THREE tracks, matching the three children. It kept four after the two document icons
   became one (Steven, 2026-09-10), so Remove was laid into a 30px icon track and spilled out
   of it. A fixed grid and its markup have to be changed together — that is the cost of the
   alignment it buys. */
/* Narrower still (Steven, 2026-09-10: "seems to be a lot of room for the message/text now").
   A fixed message track was sized for the longest message anything could ever say, and every
   other row paid for it in a right-hand scrollbar. It takes what is left now: the two controls
   keep their pixels, so they stay put down the whole column, and the message absorbs the
   column's own width, whatever the pane makes that. Long ones ellipsis and keep their full
   text on hover, which is what a title is for. */
/* THE BUTTONS: entries, retainer, documents, Remove (the entries button 2026-09-11). The
   message moved to a column of its own the same day, so it can share the row's slack with the
   client name; the buttons keep a fixed column, padded in from the right-hand edge ("so that
   the Remove button isnt so close to the right edge"). */
.rn-acts { display: grid; grid-template-columns: 30px 30px 30px 76px; gap: 6px; align-items: center; justify-content: end; }
.rd-cos td.rn-btns { padding-right: 18px; }
.rd-cos td.rn-msg-cell { overflow: hidden; }
/* RIGHT UP AGAINST THE BUTTONS (Steven, 2026-09-10: "move the text comment closer to the
   buttons, huge gap right now"). The track has to be wide enough for the longest message, so a
   short one like "Ready to bill" left a hand's width of nothing between itself and the controls
   it belongs to. Aligned to the end of its track, the sentence and the buttons read as one group
   and the slack falls where slack should — in the empty middle of the row. */
.rn-msg { font-size: 11.5px; color: #8a90a6; display: flex; align-items: center; justify-content: flex-end;
          gap: 6px; min-width: 0; padding-right: 6px; }
.rn-msg-t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The invoice's Xero status on a billed row (2026-09-16): a pill that never shrinks or wraps, so the
   number beside it is what ellipsises when the column is tight. */
.rn-msg .pill { flex: none; white-space: nowrap; font-weight: 600; }
.rn-msg.bad { color: #b32121; font-weight: 600; }
.rn-msg.ok { color: #1c7a44; font-weight: 600; }
/* Ready, but tried before and pushed back. Not an error — the words carry it, as ever. */
.rn-msg.warn { color: #b25a12; font-weight: 600; }
.rn-acts .cmd-btn { justify-content: center; }
/* The lock beside a status pill: this line cannot change, and its title says why. Muted on
   purpose — it is an explanation, not a warning. */
.te-locked { font-size: 13px; color: #8a90a6; margin-left: 5px; vertical-align: 1px; cursor: help; }
/* The status and its lock are ONE fact (Steven, 2026-09-11), so they are one line that cannot
   wrap — the glyph used to drop under the pill whenever the column was a few pixels short. */
.te-status { display: inline-flex; align-items: center; white-space: nowrap; }
.te-status .te-locked { vertical-align: 0; }
.rn-edit-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px;
                  padding-bottom: 10px; border-bottom: 1px solid #e4e7ee; }
/* WHICH ONE AM I LOOKING AT. The same dialog serves the preview and the record of what went
   out, so it states which at the top — a draft that looks like a sent document is the worst of
   both, and the two carry different obligations. */
.doc-banner { display: flex; align-items: flex-start; gap: 9px; border-radius: 6px; padding: 8px 12px;
              font-size: 12.5px; line-height: 1.45; margin-bottom: 12px; }
.doc-banner i { font-size: 16px; flex: none; margin-top: 1px; }
.doc-banner.draft { background: #fdf1dc; border: 1px solid #e8cf9a; color: #7a5410; }
.doc-banner.sent { background: #e2f4e8; border: 1px solid #b7ddc6; color: #1c5f38; }
/* Billing's own progress, sitting just above the table it is working through. It exists only
   while something is running — a bar parked at 0% for the rest of a run's life is furniture. */
.rn-progress { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; }
.rn-progress-bar { flex: 0 0 220px; height: 6px; border-radius: 3px; background: #e4e7ee; overflow: hidden; }
.rn-progress-bar > div { height: 100%; background: #c2410c; transition: width .25s; }
.rn-progress-t { font-size: 12.5px; color: #59607a; font-variant-numeric: tabular-nums; }
/* THE TICK COLUMN, and it never centred anything (Steven, 2026-09-10: "the select all check
   isnt aligned with the others"). Every cell carrying this class holds a checkbox or a padlock
   and nothing else, and the name has been promising centring since it was written — but no rule
   ever defined it, so the contents sat hard left on whatever padding the cell happened to have.
   A header cell and a body cell do not have the same padding, so the header's tick sat 6px left
   of the column beneath it, and narrowing the header padding for the two-line headings pushed
   them further apart. Centred, the paddings cancel and the column lines up whatever they are.

   vertical-align:middle for the same reason: the heading beside it now wraps to two lines, and
   a tick pinned to the bottom of a tall cell floats away from the word it belongs to. */
.rd-cos th.ctr, .rd-cos td.ctr, .pk-table th.ctr, .pk-table td.ctr,
.cr-table th.ctr, .cr-table td.ctr {
    text-align: center; vertical-align: middle; padding-left: 4px; padding-right: 4px;
}
.rn-chk { width: 15px; height: 15px; cursor: pointer; accent-color: #191F45; }
/* The flag headers wrap to two lines, so the header row is tall and its text sits at the
   BOTTOM. A checkbox centred in that cell floated above the word "Client" beside it; this
   drops it onto the same line (Steven, 2026-09-10). */
.rn-chk:disabled { cursor: default; }
.rd-prov b { color: #444; font-weight: 600; }
.rd-prov .rd-lab { font-size: 12px; }
/* Natural-width buttons in a row (Steven, 2026-09-08: no more 214px stack). */
.rd-actions { display: flex; flex-direction: row; gap: 8px; align-items: flex-start; flex-wrap: wrap; justify-content: flex-end; }
/* THE RUN SCREEN SCROLLS LIKE A LIST SCREEN (Steven, 2026-09-09). The pane stops scrolling
   and the TABLE scrolls instead, so the head stays put and the table ends at its own totals
   row rather than running on under a floating one. Same shape as
   ".ws-pane-inner:has(.list-view)" above - a detail page that is really a grid deserves the
   grid's behaviour. */
.ws-pane-inner:has(.rd-view) { overflow: hidden; display: flex; flex-direction: column; }
.rd-view { flex: 1; min-height: 0; }
/* The scrollbar matches the list grids (Steven, 2026-09-10). DevExpress asks for the slim
   one; this table had the browser's default chunky bar with its arrow buttons, which is what
   made the two screens look like different applications. Firefox takes the standard
   properties, WebKit needs its own, so both are stated. */
.rd-cos-wrap { flex: 1; min-height: 0; overflow: auto; border: 1px solid #ced4da; background: #fff;
               scrollbar-width: thin; scrollbar-color: #b9c0cf transparent; }
.rd-cos-wrap::-webkit-scrollbar { width: 10px; height: 10px; }
.rd-cos-wrap::-webkit-scrollbar-track { background: transparent; }
.rd-cos-wrap::-webkit-scrollbar-thumb { background: #b9c0cf; border-radius: 5px;
                                        border: 2px solid #fff; background-clip: padding-box; }
.rd-cos-wrap::-webkit-scrollbar-thumb:hover { background: #9aa3b6; background-clip: padding-box; }
.rd-cos-wrap::-webkit-scrollbar-corner { background: transparent; }
/* FIXED LAYOUT (Steven, 2026-09-09): expanding a row must not move the columns above it.
   Under auto layout the nested entries grid joined the width negotiation and squeezed the
   client names onto two lines; fixed reads the widths from the colgroup alone. */
/* THE FLOOR, and the only width at which this table scrolls sideways. Its columns are
   percentages (see the colgroup in BillingRunDetail.razor), so it fits any pane; below this
   they would be fitting by becoming unusable, and an honest scrollbar beats a 40px name. */
/* 1170px of fixed columns plus a name worth reading. Below this it genuinely has to scroll:
   the other columns hold a tick, a pill, a figure or a short message and do not improve by
   shrinking. (2026-09-11: the chevron column went, Total hrs came, and the message left the
   button lane for a 190px column of its own.) */
.rd-cos { background: #fff; table-layout: fixed; min-width: 1320px; }
/* THE HEADERS WRAP (Steven, 2026-09-10). "table.cases th" is white-space:nowrap for the list
   grids, and under FIXED layout a nowrap header does not widen its column - it spills across
   the next one. So trimming these columns quietly pushed "Statement contact" over its
   neighbour instead of making the table narrower. Two short lines is what these want anyway. */
.rd-cos thead th { white-space: normal; line-height: 1.25; padding-left: 8px; padding-right: 8px; }
.rd-cos td { vertical-align: middle; }
/* Fixed layout clips rather than wraps by default — a long client name must still wrap. It is
   the SECOND column, after the tick (2026-09-11: the run's chevron column went). */
.rd-cos td:nth-child(2) { overflow-wrap: anywhere; }
/* PINNED TOTALS. Sticky - the mirror of the sticky header this table already has, bottom:0
   instead of top:0. Now that the wrapper is the scrollport, "bottom" is the bottom of the
   TABLE's box rather than the window's, which is what roots the row to the end of the grid.

   Applied to the CELLS, not the row: position:sticky on a <tr> or <tfoot> is ignored in
   several browsers, because a table row is not a box that can be offset. The opaque
   background is load-bearing too, or rows scroll straight through the text; z-index 2 matches
   the header so neither can be painted over by a cell. */
.rd-cos tfoot td { position: sticky; bottom: 0; z-index: 2;
                   background: #f2f5fa; border-top: 1px solid #ced4da;
                   font-weight: 700; color: #191F45; }
.rd-xero { width: 110px; border: 1px solid #c8c8c8; border-radius: 5px; padding: 3px 8px; font-family: inherit; font-size: 12.5px; }
.ico-btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 28px; background: #fff; border: 1px solid #c8c8c8; border-radius: 5px; cursor: pointer; color: #191F45; vertical-align: middle; font-size: 16px; }
.ico-btn:hover { background: #eef1f7; }
.ico-btn:disabled { opacity: .4; cursor: not-allowed; }
.cmd-btn-sm { padding: 3px 10px; font-size: 12.5px; }
.chips { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.chip { display: inline-flex; align-items: center; gap: 7px; background: #e7edf6; color: #16233f; border-radius: 14px; padding: 4px 6px 4px 12px; font-size: 13px; font-weight: 600; }
.chip .x { border: 0; background: transparent; cursor: pointer; color: #52586e; font-size: 14px; line-height: 1; padding: 0 4px; }
.chip .tag { font-size: 11px; font-weight: 600; color: #1c7a44; background: #e2f4e8; border-radius: 9px; padding: 1px 8px; }
.attach { border: 1px solid #d5d9e2; border-radius: 8px; }
.attach-head { background: #eceff4; border-bottom: 1px solid #d5d9e2; border-radius: 8px 8px 0 0; padding: 8px 14px; font-size: 12.5px; font-weight: 600; color: #52586e; display: flex; gap: 8px; align-items: center; }
.attach-body { padding: 20px 24px; }
.email-preview { border: 1px solid #d5d9e2; border-radius: 8px; padding: 16px 18px; background: #fbfcfe; font-size: 13.5px; }
.email-sig { margin-top: 14px; border-top: 1px solid #e5e5e5; padding-top: 12px; color: #444; }
/* the statement document (mirrors statement-pdf mock v2 — the print renderer copies this) */
/* The statement itself is now a PDF (StatementPdf.cs) — the run screen shows that file
   rather than a second HTML rendering, so the old .stmt-hd/.stmt-lines/.t-case rules are
   gone. These .stmt-facts rules stay because the INVOICE preview still uses them. */
.stmt-facts { display: flex; gap: 30px; flex-wrap: wrap; margin-bottom: 16px; }
.stmt-facts .f { font-size: 13px; color: #222; }
.stmt-facts .f .lab { display: block; font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: #7a7f8d; margin-bottom: 2px; }
.stmt-facts .f b { color: #16233f; }
.stmt-facts .hold { font-style: italic; color: #8a8f9a; }
/* the invoice preview doc */
.inv-doc { border: 1px solid #d5d9e2; border-radius: 8px; padding: 20px 24px; }
.inv-doc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; margin-bottom: 14px; }
.inv-doc-head img { width: 150px; height: auto; }
.inv-line { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid #eef0f4; font-size: 14px; }
.inv-total { display: flex; justify-content: space-between; gap: 16px; padding: 12px 0 0; font-size: 16px; font-weight: 700; color: #191F45; }

/* Settings — Integrations: connect cards (Renzo-style, 2026-09-07). */
.intg-group { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #666; margin: 18px 0 10px; }
.intg-cards { display: flex; flex-wrap: wrap; gap: 14px; }
/* Settings → Integrations: every card in one grid, two to a row, one when narrow (2026-09-15). */
.intg-grid { display: grid; grid-template-columns: repeat(2, 380px); gap: 14px; align-items: stretch; margin-top: 10px; }
.intg-grid > .intg-card { width: auto; }
@media (max-width: 1100px) { .intg-grid { grid-template-columns: minmax(0, 380px); } }
/* The heading with the usual Refresh button beside it (2026-10-08). */
.intg-title { display: flex; align-items: center; gap: 12px; margin: 0 0 6px; }
.intg-title .acct-h { margin: 0; }
/* A column so the button sits on the card's floor: cards in a row are the same height, so
   their buttons line up however many lines the description runs to (Steven, 2026-09-16 —
   Google Maps' one-line description left its button above SharePoint's). */
.intg-card { border: 1px solid #e4e7ee; border-radius: 8px; background: #fbfcfe; padding: 14px 16px; width: 380px;
             display: flex; flex-direction: column; }
.intg-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.intg-name { font-size: 15px; font-weight: 700; color: #191F45; display: inline-flex; align-items: center; gap: 8px; }
/* Xero's official Blue wordmark (103×29 viewBox, brand assets 2026-09-08) — height-led so
   the aspect holds; it IS the card's name, so no text beside it. */
.intg-logo { height: 22px; width: auto; display: block; }
/* The state icon at the card's top-right (Renzo's shape): a grey plug means not
   connected — it always carries a title/aria-label, never colour alone. */
.intg-plug { font-size: 18px; color: #9aa3b2; }
.intg-plug.on { color: #1c7a44; }
.intg-plug.warn { color: #b25a12; }
.btn-xero.warn { background: #fdeadd; color: #b25a12; }
/* Resend: black wordmark on the light card, black button (Resend's own style). */
.intg-logo.resend { height: 18px; }
.xero-dlg-mark.resend { height: 18px; }
.btn-resend { background: #000; color: #fff; font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.btn-resend:hover:not(:disabled) { background: #222; color: #fff; }
.btn-resend:disabled { background: #000; color: #fff; opacity: .55; }
.btn-resend.warn { background: #fdeadd; color: #b25a12; }
.xsteps.resend li.on { color: #000; background: #eee; }
.xsteps.resend li.on span { background: #000; color: #fff; }
/* SharePoint: Microsoft's SharePoint teal on the card. Steven is colourblind, so the state
   is ALWAYS carried by the plug icon + a worded label as well as the button colour. */
.intg-name.sp { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: 15px; color: #036c70; }
.intg-name.sp i { font-size: 20px; }
.btn-sharepoint { background: #036c70; color: #fff; font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.btn-sharepoint:hover:not(:disabled) { background: #025256; color: #fff; }
.btn-sharepoint:disabled { background: #036c70; color: #fff; opacity: .55; }
.btn-sharepoint.warn { background: #fdeadd; color: #b25a12; }
.xsteps.sp li.on { color: #036c70; background: #e3f1f1; }
.xsteps.sp li.on span { background: #036c70; color: #fff; }
/* The Master Templates folder picker — a lazy-loading tree of the library. Folders only are
   selectable as the templates root; files show greyed so the person sees what a folder holds. */
.sp-tree { border: 1px solid #d7dbe3; border-radius: 8px; max-height: 320px; overflow: auto; padding: 6px; background: #fbfcfe; }
.sp-node { display: flex; align-items: center; gap: 6px; padding: 3px 6px; border-radius: 5px; font-size: 13.5px; white-space: nowrap; }
.sp-node .sp-twist { width: 16px; text-align: center; cursor: pointer; color: #6b7280; flex: none; }
.sp-node .sp-twist.leaf { visibility: hidden; }
.sp-node .sp-label { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.sp-node .sp-label i { color: #036c70; }
.sp-node.file .sp-label { color: #9aa3b2; cursor: default; }
.sp-node.file .sp-label i { color: #b6bcc8; }
.sp-node.sel { background: #e3f1f1; font-weight: 600; }
.sp-node:hover:not(.file) { background: #eef4f4; }
.sp-children { margin-left: 16px; border-left: 1px solid #eceef3; padding-left: 2px; }
.sp-picked { font-size: 13px; color: #036c70; margin-top: 8px; display: inline-flex; align-items: center; gap: 6px; }
/* THE CLIENT PICKER (RunClientPicker) - one dialog for New Billing Run and Add T&E.
   The expandable row carries a whole entries grid, so the open row is tinted and the pair
   share a heavier bottom border: without it a nested table reads as part of the list. */
.pk-table td, .pk-table th { vertical-align: middle; }
/* A blocked client keeps its place and says why in WORDS, never by shade alone: the padlock
   is the second signal and the sentence under the name is the third. */
.pk-blocked { color: #b32121; }
.pk-blocked-i { font-size: 14px; color: #8a90a6; cursor: help; }

/* The Complete run dialog: plan table, progress bar, step list, summary. */
.cr-table { border: 1px solid #ced4da; }
.cr-table tfoot td { background: #f6f8fb; font-size: 13px; }
.cr-will { background: #f6f8fb; border: 1px solid #e4e7ee; border-radius: 8px; padding: 10px 14px; font-size: 13.5px; line-height: 1.6; }
.cr-progress { height: 10px; background: #e7ebf2; border-radius: 5px; overflow: hidden; }
.cr-bar { height: 100%; background: #191F45; transition: width .3s ease; }
.cr-steps { list-style: none; margin: 0; padding: 0; max-height: 300px; overflow-y: auto; font-size: 13px; }
.cr-steps li { display: flex; align-items: flex-start; gap: 8px; padding: 4px 0; border-bottom: 1px solid #eef0f4; }
.cr-steps li i { font-size: 15px; margin-top: 1px; color: #6b7280; }
.cr-steps li.done i { color: #1c7a44; }
.cr-steps li.fail { color: #b32121; }
.cr-steps li.fail i { color: #b32121; }
/* The Complete dialog's per-run Xero choice (Steven's point 6, 2026-09-08). */
/* The contact dialog (Steven's point 2, 2026-09-08): a 12-column grid so name parts and
   contact details sit on sensible rows at any dialog width. */
/* Required-field marker. Never colour alone — it is a glyph with a tooltip. */
/* Two-factor panel in Settings, My Account (2026-09-08). State and actions, no lecture. */
/* The CRM account screens (AuthCard): navy page, one card, centred. Was an inline <style>
   repeated on every account page before the shell existed (2026-09-08). */
.crm-auth-page { min-height: 100vh; background-color: #16243d; display: flex; align-items: center; justify-content: center; padding: 20px; }
.crm-auth-page .login-card { max-width: 420px; width: 100%; }
/* A button mid-submit (js/busyForms.js). It swallows further presses, so it must LOOK
   unavailable too — otherwise people keep pressing something that has quietly stopped responding
   and conclude the site is broken. The words change as well as the shade ("Signing in…"), so
   this never leans on the dimming alone. */
.crm-auth-page .is-busy,
.crm-auth-page .is-busy:hover { opacity: .65; cursor: progress; }
/* The two in-place disclosures under the QR on the authenticator screen. Deliberately NOT a
   modal: the reader is mid-scan and the code must stay visible (2026-09-08 research). */
/* The Troubleshooting pop-up on the authenticator screen. A modal is right HERE, unlike the
   setup steps: everything needed while it is open is inside it, the manual key included, so
   nothing behind it has to stay visible. */
.auth-signout { min-width: 130px; }
/* The password rules under a new-password box (PasswordRules, 2026-09-14). Tucked up to the box
   they describe; two columns so six short rules do not push the card off a laptop screen. */
.pw-rules { margin: -8px 0 16px; font-size: 13px; line-height: 1.45; color: #4b5563; }
.pw-rules ul { margin: 2px 0 0; padding-left: 18px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 16px; list-style: none; }
/* The marker is drawn, not the list's own: a bullet until the rule is met, then a green tick in the
   SAME fixed box to the left of the text (js/passwordRules.js) — so nothing shifts as it changes.
   Tick and bullet are different shapes; the green is never the only difference. */
.pw-rules li { position: relative; }
.pw-rules li::before { content: "\2022"; position: absolute; left: -16px; top: 0; width: 14px; text-align: center; color: #4b5563; }
.pw-rules li.met::before { content: "\2713"; color: #15803d; font-weight: 700; }
.pw-rules-note { margin-top: 4px; font-size: 13px; line-height: 1.45; color: #4b5563; }
.auth-help { text-align: center; margin: 4px 0 0; }
.linkish { border: 0; background: none; padding: 0; font-size: 13px; color: #31527a;
    text-decoration: underline; cursor: pointer; font-family: inherit; }
.howto { border: 0; border-radius: 8px; padding: 0; width: 420px; max-width: 92vw;
    max-height: 86vh; box-shadow: 0 18px 50px rgba(0,0,0,.4); color: #374151; }
.howto::backdrop { background: rgba(10,18,32,.55); }
.howto-head { padding: 14px 18px; border-bottom: 1px solid #e9ecef; font-weight: 700;
    color: #191F45; display: flex; align-items: center; }
.howto-head button { margin-left: auto; border: 0; background: none; font-size: 18px;
    color: #8a8f9a; cursor: pointer; line-height: 1; }
.howto-body { padding: 14px 18px 20px; font-size: 13.5px; line-height: 1.6; overflow-y: auto; }
.howto-body ul { margin: 4px 0 8px; padding-left: 18px; }
.howto-body li { margin-bottom: 3px; }
/* Per-app steps inside the Help pop-up (2026-09-09). Tighter than the page's own
   numbered steps, since there are four sets of them stacked up. */
.howto-body .howto-steps { margin: 4px 0 10px; padding-left: 20px; }
.howto-body .howto-steps li { margin-bottom: 4px; }
/* A .linkish used INSIDE running text (the "your authenticator app" link on the setup
   and verify screens) must not shrink mid-sentence, and needs an underline so it does
   not depend on colour alone to read as a link. */
.auth-steps .linkish, .form-label .linkish { font-size: inherit; text-decoration: underline; }
.auth-more-body { padding: 0 2px 12px; line-height: 1.6; }
.auth-more-h { font-weight: 700; color: #191F45; margin: 10px 0 2px; }
.auth-more-body > .auth-more-h:first-child { margin-top: 0; }
.auth-more-body p { margin: 0 0 6px; }
.auth-key { margin: 6px 0 8px; }
.auth-key code { font-size: 14px; letter-spacing: .09em; color: #16233f; }

.auth-h { font-size: 18px; font-weight: 700; color: #16233f; margin: 0 0 12px; }
.auth-lead { font-size: 14px; color: #444; }
/* The steps carry the QR and the code box inside them (Steven, 2026-09-08), so they need room
   to breathe and the numbers must stay aligned with the first line of each step. */
.auth-steps { margin: 0 0 14px 0; padding-left: 20px; font-size: 14px; color: #444; }
.auth-steps > li { margin-bottom: 9px; }
.auth-steps > li::marker { font-weight: 600; color: #16233f; }
.auth-verify { display: flex; gap: 8px; margin-top: 7px; }
.auth-verify .form-control { flex: 1; min-width: 0; }
.auth-verify .btn { flex: none; padding-left: 20px; padding-right: 20px; }
.auth-qr { display: flex; justify-content: flex-start; margin: 8px 0 2px; }
.rc-ack { display: flex; align-items: center; gap: 8px; font-size: 13.5px; margin-bottom: 10px; cursor: pointer; }
.btn.disabled, .btn.disabled:hover { pointer-events: none; opacity: .45; }

.rc-list { list-style: none; margin: 0 0 14px; padding: 12px; display: grid; grid-template-columns: 1fr 1fr;
    gap: 4px 16px; background: #f7f8fa; border: 1px solid #e5e5e5; border-radius: 6px;
    font-family: Consolas, monospace; font-size: 14px; color: #16233f; letter-spacing: .04em; }

.acct-2fa { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap;
    border: 1px solid #e5e5e5; border-radius: 7px; padding: 14px 16px; max-width: 720px; margin-bottom: 12px; }
.acct-2fa-state { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; }
.acct-2fa-state i { font-size: 22px; line-height: 1.1; }
.acct-2fa-state i.ok { color: #1c7a44; }
.acct-2fa-state i.off { color: #8a8f9a; }
.acct-2fa-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.acct-2fa-actions form { margin: 0; }

.req { color: #b32121; font-weight: 700; margin-left: 1px; }

/* New client (2026-10-08): similar names under Name, and Type beside Status. */
.nc-similar { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-top: 6px; font-size: 13px; }
.nc-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
/* Who signs in as this contact (2026-10-08): the key and the words, never colour alone. */
.cd-signin { display: flex; gap: 7px; align-items: baseline; margin: -2px 0 12px; padding: 7px 10px; font-size: 12.5px;
    background: #f4f7fd; border: 1px solid #dfe6f5; border-radius: 6px; color: #2b3142; }
.cd-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }   /* only there to disable the lot when read only */
.cd-fieldset:disabled .cd-check { cursor: default; }
.cd-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 0 12px; }
.cd-grid .form-field { margin-bottom: 12px; }
.cd-grid input, .cd-grid textarea { width: 100%; }
.cd-check { display: block; margin-top: 4px; font-size: 13.5px; cursor: pointer; }
.cd-check input { margin-right: 7px; }
.cd-check .cell-sub { display: block; margin-left: 24px; font-weight: 400; }
/* The Virtual HRM panel (2026-09-28; its own dialog since 2026-10-08, no longer a contact dialog tab).
   Every status pill carries its WORD - colour is never the only signal (ui-standards.md). Disabled and
   Locked out also differ in shape. */
.cd-mandatory { margin-top: 14px; }
.pu-pending { display: flex; align-items: center; gap: 10px; margin-top: 12px; padding: 8px 11px; font-size: 12.5px;
    background: #f4f7fd; border: 1px solid #dfe6f5; border-radius: 6px; }
.pu-pending .btn-link-plain { margin-left: auto; background: none; border: 0; padding: 0; color: #191F45; font-weight: 600; text-decoration: underline; cursor: pointer; }
/* Virtual HRM → Marketing (2026-10-05): the carousel slides list, the slide dialog and its preview. The
   preview mirrors the portal's carousel (VirtualHrm Dashboard.razor) - keep in step. */
/* Virtual HRM → Presenter → Events, the CALENDAR (2026-10-06, after the original portal's): Monday first; each
   week a grid of seven days with the event bars laid over it, a row (lane) each. */
.pc-nav { display: flex; align-items: center; gap: 8px; margin: 2px 0 10px; }
.pc-month { font: inherit; font-size: 13px; padding: 3px 6px; border: 1px solid #ced4da; border-radius: 6px; }
.pc-month-name { font-weight: 700; color: #16233f; margin-right: auto; }
.pc-cal { border: 1px solid #e4e7ee; border-radius: 8px; overflow: hidden; background: #fff; }
.pc-cal-head { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); background: #f6f7f9; border-bottom: 1px solid #e4e7ee; }
.pc-cal-head span { padding: 6px 8px; font-size: 12.5px; font-weight: 600; color: #55607a; }
.pc-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-template-rows: 26px repeat(var(--lanes), 26px) 14px;
           position: relative; border-top: 1px solid #eef0f4; min-height: 76px; }
.pc-week:first-of-type { border-top: 0; }
.pc-day { grid-row: 1 / -1; border-left: 1px solid #eef0f4; padding: 4px 6px; }
.pc-day:first-child { border-left: 0; }
.pc-other { background: #fafbfc; color: #9aa3b2; }
.pc-addable { cursor: pointer; }
.pc-addable:hover { background: #f1f5fa; }
.pc-num { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; font-size: 12.5px; }
/* Today: a filled circle - shape as well as colour. */
.pc-today .pc-num { background: #1f5fae; color: #fff; border-radius: 999px; font-weight: 700; padding: 0 6px; }
.pc-bar { position: relative; z-index: 1; display: flex; align-items: center; gap: 6px; margin: 2px 3px; padding: 0 8px; border: 0; border-radius: 4px;
          background: #08203d; color: #fff; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; min-width: 0; text-align: center; }
.pc-bar:hover { background: #16335b; }
.pc-bar-title { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pc-more { flex: 0 0 auto; }
/* Audio and video on the bar: a microphone and a camera, crossed through (and dimmer) when missing. */
.pc-av { flex: 0 0 auto; display: inline-flex; gap: 4px; font-size: 14px; }
.pc-av-no { opacity: .55; }
/* Presenter → Audio & Video (2026-10-06): today's message beside its words, then the list. */
.av-today { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 16px; align-items: start; margin-bottom: 14px; }
.av-today-player { height: 180px; border: 1px solid #e4e7ee; border-radius: 8px; overflow: hidden; background: #fff; }
.av-today-none { height: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; color: #8a94a6; }
.av-table { border: 1px solid #ced4da; }
.av-table td { vertical-align: top; font-size: 13.5px; }
.av-default td { background: #f6f8fb; }
/* A tick or a cross, and the words beside it - never colour alone. */
.av-mark { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; }
.av-mark.yes { color: #1d6b3a; }
.av-mark.no { color: #8a3a1a; }
.av-mark.busy { color: #005883; }
.av-audio { display: block; margin-top: 6px; height: 32px; width: 260px; }
.ps-default-box { margin-top: 16px; padding: 12px 14px; border: 1px solid #c9d6e6; border-radius: 8px; background: #f8fafd; }
/* An event that is off: an outline, not a fill, and "(off)" in its words. */
.pc-bar-off { background: #fff; color: #55607a; border: 1px dashed #8a94a6; font-weight: 400; }
.pc-bar-off:hover { background: #f4f6f9; }

/* Virtual HRM → Presenter → Events, the LIST (2026-10-06): a month heading over each month's rows. */
.pe-month { font-size: 14px; font-weight: 700; color: #16233f; margin: 14px 0 6px; }
.pe-list { background: #fff; border: 1px solid #e4e7ee; border-radius: 10px; overflow: hidden; }
.pe-row { display: grid; grid-template-columns: 150px minmax(0,1fr) minmax(0,2fr) 140px 100px 120px 90px; gap: 12px; align-items: center; padding: 8px 14px; border-top: 1px solid #eef0f4; font-size: 13.5px; }
/* The Voice and video panel (2026-10-06): two numbered steps, each with its state in words. */
.pm-panel { margin-top: 16px; padding-top: 12px; border-top: 1px solid #e4e7ee; }
.pm-head { font-size: 14px; font-weight: 700; color: #16233f; margin: 0 0 8px; }
.pm-note { background: #fff8e1; border: 1px solid #f0d58a; border-radius: 6px; padding: 6px 10px; font-size: 13px; margin-bottom: 8px; }
.pm-step { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; padding: 8px 0; }
.pm-step + .pm-step { border-top: 1px dashed #e4e7ee; }
.pm-step-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pm-num { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 999px; background: #08203d; color: #fff; font-size: 12px; font-weight: 700; }
.pm-audio { width: 100%; max-width: 420px; }
/* The player as on the portal's card: a wide white box, the presenter centred in it. */
.pm-player { width: 100%; max-width: 480px; height: 270px; background: #fff; border: 1px solid #e4e7ee; border-radius: 8px; overflow: hidden; }
.pe-list .pe-row:first-child { border-top: 0; }
.pe-title { font-weight: 600; }
.pe-script { color: #55607a; font-size: 13px; }
.pe-off { opacity: .65; }
.pe-form { border: 0; padding: 0; margin: 0; }
.pe-form textarea { width: 100%; font: inherit; }
.pe-dates { display: flex; gap: 16px; flex-wrap: wrap; }
.pe-who { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.mk-list { background: #fff; border: 1px solid #e4e7ee; border-radius: 10px; overflow: hidden; }
.mk-row { display: grid; grid-template-columns: 60px 96px minmax(0,1.2fr) minmax(0,1.4fr) 110px 70px 150px; gap: 12px; align-items: center; padding: 8px 14px; border-top: 1px solid #eef0f4; font-size: 13.5px; }
.mk-row.mk-head { border-top: 0; background: #f6f7f9; color: #55607a; font-size: 12.5px; font-weight: 600; }
.mk-order { display: flex; gap: 4px; }
.mk-move { width: 26px; height: 26px; border: 1px solid #d7dbe3; background: #fff; border-radius: 6px; cursor: pointer; color: #374055; display: inline-flex; align-items: center; justify-content: center; }
.mk-move:disabled { opacity: .35; cursor: default; }
.mk-thumb { width: 96px; height: 54px; border-radius: 6px; overflow: hidden; background: #19223b; display: flex; align-items: center; justify-content: center; color: #8a94a6; }
.mk-thumb img { width: 100%; height: 100%; object-fit: cover; }
.mk-thumb-contain img { object-fit: contain; }
.mk-form { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 4px 14px; }
.mk-form .mk-wide { grid-column: 1 / -1; }
.mk-form input:not([type=checkbox]), .mk-form select { width: 100%; }
.mk-upload { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; width: fit-content; }
.mk-check { display: flex; align-items: center; gap: 6px; font-weight: 400; }
/* The carousel previews (2026-10-06): the portal's own component (Shared.Ui PartnersCarousel) in a box the
   width of the portal's card; the height is the dialog's Height choice. */
.mk-carousel-box { width: 100%; max-width: 480px; height: 340px; margin: 6px auto 0; }
/* The settings dialog: three settings across, then a little table of positions. */
.mk-settings { border: 0; padding: 0; margin: 0; }
.mk-set-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.mk-set-head { font-weight: 600; margin: 14px 0 6px; display: flex; align-items: center; gap: 6px; }
.mk-set-pos { display: grid; grid-template-columns: 100px 70px 80px 80px 110px minmax(0, 1fr); gap: 8px 10px; align-items: center; }
.mk-set-pos input[type=checkbox] { justify-self: start; }
.mk-set-pos input[type=number] { width: 80px; }
.mk-set-extra { display: flex; gap: 8px; }
.mk-set-extra input { flex: 1 1 auto; min-width: 0; }
/* The click count when above 0: a link that looks like one - blue, underlined (Steven, 2026-10-05). */
.mk-count { color: #1f5fae; text-decoration: underline; font-weight: 600; }
.mk-count:hover { color: #16233f; }
.mk-clicks { max-height: 420px; overflow-y: auto; }
.mk-click { display: grid; grid-template-columns: 140px minmax(0,1fr) minmax(0,1fr); gap: 10px; padding: 6px 4px; border-top: 1px solid #eef0f4; font-size: 13px; }
.mk-click.mk-head { border-top: 0; color: #55607a; font-weight: 600; font-size: 12.5px; }

/* Virtual HRM → News ticker (2026-10-07): the Sources and Davidson HR news lists (the Marketing list's look), the
   settings, and the Preview - the headlines with where each came from. The ticker itself, above the tabs and in the
   item dialog, is the portal's own (Shared.Ui news-ticker.css, 2026-10-08). */
.nt-list { background: #fff; border: 1px solid #e4e7ee; border-radius: 10px; overflow: hidden; }
.nt-row { display: grid; gap: 12px; align-items: center; padding: 8px 14px; border-top: 1px solid #eef0f4; font-size: 13.5px; }
.nt-row.nt-head { border-top: 0; background: #f6f7f9; color: #55607a; font-size: 12.5px; font-weight: 600; }
.nt-src { grid-template-columns: 60px minmax(0,1fr) minmax(0,1.6fr) 90px 150px; }
.nt-own { grid-template-columns: 60px minmax(0,1.6fr) minmax(0,1fr) 190px 110px 150px; }
.nt-pre { grid-template-columns: 36px minmax(0,1fr) 190px; }
.nt-pre a { color: #1f5fae; }
.nt-url { color: #55607a; font-size: 12.5px; overflow-wrap: anywhere; }
.nt-url-row { display: flex; gap: 8px; align-items: center; }
.nt-url-row input { flex: 1 1 auto; min-width: 0; }
.nt-url-row .cmd-btn { flex: 0 0 auto; white-space: nowrap; }
.nt-test { margin-top: 6px; font-size: 13px; overflow-wrap: anywhere; }
.nt-dates { display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap; }
.nt-dates-note { margin-bottom: 22px; }
.nt-settings { border: 0; padding: 0; margin: 0; max-width: 360px; }
.nt-feeds { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13.5px; }
.nt-feeds li { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
/* The live preview (2026-10-08): the portal's ticker, full width, then Read feeds now, when, and "Unsaved settings". */
.nt-live { min-width: 0; }   /* .detail-view's column gap spaces it */
.nt-live-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 8px; min-height: 30px; }
.nt-unsaved { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 600; color: #8a4b00; }
/* What a Davidson HR item's pop-up has: Story, Picture - a glyph and a word each. */
.nt-has { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 2px; font-size: 12px; color: #55607a; }
.nt-has span { display: inline-flex; align-items: center; gap: 3px; }
.nt-has .ti { font-size: 13px; }
/* The item dialog's picture: a thumbnail, then Choose / Replace and Remove. */
.nt-pic-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.nt-thumb { width: 96px; height: 54px; border-radius: 6px; overflow: hidden; background: #eef0f4; display: flex; align-items: center; justify-content: center; }
.nt-thumb img { width: 100%; height: 100%; object-fit: cover; }

/* Virtual HRM → Footer and → Help & contact (2026-10-09): a preview of what the portal shows (its own components, so
   portal-text.css styles what's inside), then the form. */
.pf-preview { border: 1px dashed #c9d0dc; border-radius: 8px; background: #fbfcfe; padding: 8px 14px 4px; margin: 0 0 16px; }
.pf-preview-h { display: flex; align-items: center; gap: 10px; font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #6b7487; }
.pf-preview .pt-footer { margin-top: 6px; padding-bottom: 6px; }
.pf-preview-line { font-size: 14px; color: #2b2f38; padding: 6px 0 8px; }
.pf-preview-line a { color: #1f4e9c; text-decoration: underline; }
.pf-form { border: 0; padding: 0; margin: 0; max-width: 520px; }
.pf-with-buttons { display: flex; gap: 6px; align-items: center; }
.pf-with-buttons input { flex: 1 1 auto; min-width: 0; }
.pf-with-buttons .cmd-btn { flex: 0 0 auto; min-width: 40px; justify-content: center; }
.pf-pair { display: flex; gap: 10px; }
.pf-pair .form-field { flex: 1 1 auto; min-width: 0; }
.pf-pair .pf-label { flex: 0 0 90px; }
.pf-copy { display: flex; gap: 8px; flex-wrap: wrap; }
.pf-page-preview { border: 1px solid #e3e7ee; border-radius: 8px; background: #fff; padding: 20px 24px; }
.detail-view > .info-panel { margin: 0; }

/* A client's portal Activity history (2026-10-05), Virtual HRM tab. */
.pa-wrap { padding: 10px 14px 14px; }
.pa-empty { margin: 12px 0 0; }
/* A question's earlier conversation, folded away under its own line (2026-10-06). */
.pa-earlier { margin-bottom: 12px; border: 1px solid #e3e6ea; border-radius: 8px; padding: 6px 10px; }
.pa-earlier summary { cursor: pointer; font-weight: 600; font-size: 13px; }
.pa-turn { margin-top: 8px; font-size: 13px; }
/* Portal Activity (Shared/PortalActivity, 2026-10-06): tabs and filters on one line that wraps, then the list. */
.pa-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.pa-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.pa-who { width: 150px; padding: 5px 8px; border: 1px solid #ced4da; border-radius: 6px; font: inherit; font-size: 13px; }
.pa-table { border: 1px solid #ced4da; }
.pa-table td { font-size: 13px; vertical-align: top; }
/* A question opens its answer: a real link - blue and underlined, never colour alone (Steven, 2026-10-06). */
.pa-link { background: none; border: 0; padding: 0; font: inherit; text-align: left; color: #1f5fae; text-decoration: underline; cursor: pointer; }
.pa-link:hover { color: #16233f; }

/* Portal users' row buttons (2026-10-05): one row, left-aligned, Edit first, a gap, every button the same
   height whether or not it carries an icon. */
.pu-row-acts { display: flex; align-items: center; gap: 8px; }
.pu-row-acts .cmd-btn { display: inline-flex; align-items: center; gap: 5px; height: 28px; line-height: 1; white-space: nowrap; }
.pu-row-acts .cmd-btn .ti { font-size: 14px; }
.yesno + .pu-pill, .pu-pill + .pu-pill { margin-left: 6px; }
.pu-rows { display: grid; grid-template-columns: 140px 1fr; gap: 9px 14px; font-size: 13.5px; align-items: baseline; }
.pu-l { color: #555; font-size: 12.5px; font-weight: 600; }
.pu-when { margin-left: 6px; }
.pu-mono { font-variant-numeric: tabular-nums; }
.pu-note { margin-top: 8px; }
.pu-crm { margin: 10px 0 0; flex-wrap: wrap; }   /* the CRM-user line in Virtual HRM access, with Unlink */
.pu-acts-set { border: 0; margin: 0; padding: 0; min-width: 0; }   /* greys the actions when read only (2026-10-09) */
.pu-ro-hint { margin-top: 6px; }
.pu-acts { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 16px; padding-top: 12px; border-top: 1px solid #eef0f4; }
.pu-why { font-size: 12px; color: #8a8f9a; }
.pu-sub { display: block; margin-top: 2px; }   /* "Contact email: x" under a sign-in email that differs */
.pu-done { margin-top: 10px; }
.pill.pu-pill { font-size: 12px; }
.pill.pu-notinvited, .pill.pu-invitationexpired, .pill.pu-invitationwithdrawn { background: #eef0f4; color: #555; }
.pill.pu-invited { background: #e7eefc; color: #1d3f91; }
.pill.pu-registrationincomplete { background: #fff2dc; color: #8a5300; }
.pill.pu-active { background: #e3f3e8; color: #17663a; }
.pill.pu-disabled { background: #f1f1f1; color: #444; box-shadow: inset 0 0 0 1.5px #888; }
.pill.pu-locked { background: #fde8e8; color: #9b1c1c; box-shadow: inset 0 0 0 1.5px #9b1c1c; margin-left: 4px; }
.pu-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 12px; }
.pu-filter { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: #555; }
.pu-filter select { font-weight: 400; }

/* A panel's own action row (New contact, and anything similar that follows). */
.panel-actions { display: flex; gap: 8px; margin-bottom: 10px; }

.cr-choice { display: flex; align-items: flex-start; gap: 8px; margin-top: 6px; font-size: 13.5px; cursor: pointer; }
.cr-choice input { margin-top: 2px; flex: none; }

/* The statement tab shows the real PDF, so the frame just needs room and a border. */
.stmt-frame { border: 1px solid #ced4da; border-radius: 4px; background: #f4f5f7; overflow: hidden; }
.stmt-frame iframe { display: block; width: 100%; height: 62vh; min-height: 380px; border: 0; }
/* WHILE THE PDF IS ON ITS WAY (Steven, 2026-09-14: "doesnt show a loading message (sits blank for
   ages first)"). The message sits BEHIND the frame: a frame with nothing in it yet is transparent,
   so the message shows through, and the PDF viewer paints over it the moment the document arrives.
   No script, so nothing the Content Security Policy has to allow. */
.stmt-frame { position: relative; }
.stmt-frame-wait { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
                   gap: 8px; color: #7a8195; font-size: 14px; }
.stmt-frame iframe { position: relative; background: transparent; }
.stmt-frame-note { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 8px; font-size: 12.5px; color: #666; }
.stmt-frame-note i { margin-right: 4px; }

/* A Xero contact already linked to another client (Steven's point 3): named, never colour
   alone, and set apart from the row's own name. */
.xero-taken { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600;
    color: #8a5a00; background: #fdf3e3; border: 1px solid #f0d9b5; border-radius: 3px; padding: 1px 6px; }

.cr-summary { margin-top: 12px; padding: 10px 14px; border-radius: 8px; font-size: 13.5px; }
.cr-summary.ok { background: #e2f4e8; color: #1c7a44; }
.cr-summary.warn { background: #fdeadd; color: #b25a12; }
/* Statement dialog: the mock PDF attachment chip (opens the Statement tab). */
.attach-chip { display: inline-flex; align-items: center; gap: 6px; border: 1px solid #c8c8c8; border-radius: 6px; background: #fff; padding: 5px 10px; font: inherit; font-size: 13px; color: #191F45; cursor: pointer; }
.attach-chip:hover { background: #f0f0f0; }
.attach-chip i { color: #b32121; font-size: 16px; }
/* Invoice preview: the Xero customer + due date row above the document (points 7–8). */
.inv-top { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid #e4e7ee; }
/* Email preview frame (statement dialog, Settings → Emails): the real shell, sandboxed. */
.email-frame { width: 100%; height: 560px; border: 1px solid #e4e7ee; border-radius: 8px; background: #f3f5f9; }
/* Footer builder image slots. */
.slot-grid { display: flex; gap: 14px; flex-wrap: wrap; margin: 6px 0 12px; }
.slot { border: 1px dashed #c8c8c8; border-radius: 8px; padding: 10px; width: 170px; text-align: center; background: #fbfcfe; }
.slot img { max-height: 56px; max-width: 150px; display: block; margin: 0 auto 8px; }
.slot .slot-name { font-size: 12px; font-weight: 700; color: #191F45; margin-bottom: 6px; }
.slot.wide { width: 100%; max-width: 620px; text-align: left; }
.slot.wide img { max-height: none; max-width: 600px; width: 100%; margin: 0 0 8px; }
.footer-editor { background: #fff; }
.slot .slot-empty { height: 56px; display: flex; align-items: center; justify-content: center; color: #9aa3b2; font-size: 12px; margin-bottom: 8px; }
.btn-xero.warn:hover:not(:disabled) { background: #fbdcc4; color: #b25a12; }
.intg-desc { font-size: 13px; color: #444; margin: 0 0 12px; flex: 1 1 auto; }
/* Xero-branded Connect button: brand Blue #3ECCFF with brand Midnight #000856 text (white
   on this light blue fails contrast); disabled until the connection lands. */
.btn-xero { background: #3ECCFF; color: #000856; font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.btn-xero:hover:not(:disabled) { background: #22C0FA; color: #000856; }
.btn-xero:disabled { background: #3ECCFF; color: #000856; opacity: .55; }
/* The card's one button fills the card's width in every state, so Xero and Resend match
   and nothing resizes between Connect and Connected (Steven, 2026-09-08). */
.intg-card > .cmd-btn { width: 100%; justify-content: center; margin-top: auto; }
/* THE CARD'S BUTTON, ONE LOOK FOR EVERY PROVIDER (Steven, 2026-09-29): black to Connect, green once
   Connected, amber when it needs attention - its words say which, so colour is never the only signal.
   The brand colours stay on each card's logo and in its own setup dialog. */
.btn-intg-connect, .btn-intg-on, .btn-intg-warn { font-weight: 700; display: inline-flex; align-items: center; gap: 6px; }
.btn-intg-connect { background: #000; color: #fff; }
.btn-intg-connect:hover:not(:disabled) { background: #222; color: #fff; }
.btn-intg-connect:disabled { background: #000; color: #fff; opacity: .55; }
.btn-intg-on { background: #1c7a44; color: #fff; }
.btn-intg-on:hover:not(:disabled) { background: #166337; color: #fff; }
.btn-intg-warn { background: #fdeadd; color: #b25a12; }
.btn-intg-warn:hover:not(:disabled) { background: #fbdcc4; color: #b25a12; }
/* Twilio's mark and wordmark in its brand red (2026-09-29). */
.intg-twilio { color: #F22F46; font-weight: 700; font-size: 17px; letter-spacing: -.01em; display: inline-flex; align-items: center; gap: 6px; }
.intg-twilio img { height: 20px; width: 20px; display: block; }
/* Audit list scrolls within the page instead of being clipped by the settings column. */
.audit-scroll { overflow: auto; max-height: calc(100vh - 250px); border: 1px solid #ced4da; background: #fff; }
.audit-scroll table.cases { border: 0; margin: 0; }
/* Card state (labelled, never colour-only) + the settings cog beside it. */
.intg-right { display: inline-flex; align-items: center; gap: 8px; }
.intg-state { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 700; padding: 2px 10px; border-radius: 11px; }
.intg-state.on { background: #e2f4e8; color: #1c7a44; }
.intg-state.warn { background: #fdeadd; color: #b25a12; }
.intg-gear { border: 0; background: transparent; color: #6b7280; font-size: 18px; cursor: pointer; padding: 2px; line-height: 1; }
.intg-gear:hover { color: #191F45; }
/* The Xero-look dialogs: wordmark header, the three-step rail, the copyable redirect URI. */
.xero-dlg-mark { height: 22px; display: block; margin: 0 0 12px; }
.xsteps { list-style: none; display: flex; gap: 6px; padding: 0; margin: 0 0 14px; }
.xsteps li { flex: 1; display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: #8a8f9a; padding: 6px 8px; border-radius: 6px; background: #f3f5f9; }
.xsteps li span { width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; background: #d9dde6; color: #fff; }
.xsteps li.on { color: #000856; background: #e6f8ff; }
.xsteps li.on span { background: #3ECCFF; color: #000856; }
.xsteps li.done { color: #1c7a44; }
.xsteps li.done span { background: #1c7a44; }
.xero-p { font-size: 13.5px; color: #333; margin: 0 0 10px; line-height: 1.5; }
.xero-howto { font-size: 13px; color: #333; padding-left: 20px; margin: 0 0 8px; line-height: 1.6; }
.xero-howto li { margin-bottom: 4px; }
.xero-uri { display: flex; align-items: center; gap: 8px; margin: 4px 0 2px; }
.xero-uri code { background: #f3f5f9; border: 1px solid #e4e7ee; border-radius: 6px; padding: 5px 8px; font-size: 12.5px; word-break: break-all; }
.xero-go { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.xero-facts { display: grid; grid-template-columns: 130px 1fr; gap: 4px 12px; font-size: 13px; margin: 0 0 6px; }
.xero-facts dt { color: #666; }
.xero-facts dd { margin: 0; color: #191F45; }
.xero-toggle { display: flex; align-items: center; gap: 8px; font-size: 13.5px; }
/* Billing run grid: the readiness columns (tick / cross + title, never colour alone; crosses
   on light red), the (i) button and its reason row, and the shrink-to-content sent columns. */
th.ready, td.ready { text-align: center; white-space: nowrap; }
/* CENTRED AS A GROUP (Steven, 2026-09-10: "align tick/cross + icon ... centred within their
   cols"). text-align alone did not do it: .hint is an inline-flex box, so a heading and its
   information marker shrink-wrap together and the pair lands wherever that box happens to sit —
   which is not where the tick and its button land underneath. Both are laid out as flex rows
   filling the cell now, so the heading centres with its marker counted in. The tick and its
   button were already centred as a pair by text-align — it was only ever the heading that sat
   off to one side, and both being centred as a GROUP is what makes the column read straight. */
.rd-cos th.ready > .hint { display: flex; justify-content: center; width: 100%; }
td.ready.no { background: #fdeeee; }
/* A flag cell that opens what settles it, anywhere in the cell (Steven, 2026-09-11). Hover is an
   outline, not a fill, so it never hides the pale red that marks a flag not yet settled. */
.rd-cos td.ready.clickable { cursor: pointer; }
.rd-cos td.ready.clickable:hover { box-shadow: inset 0 0 0 2px #c8cfe0; }
td.ready i { font-size: 17px; vertical-align: middle; }
td.ready i.ok { color: #1c7a44; }
td.ready i.missing { color: #b32121; }
.info-btn { border: 0; background: transparent; color: #6b7280; font-size: 15px; cursor: pointer; padding: 0 2px; margin-left: 4px; vertical-align: middle; line-height: 1; }
.info-btn:hover, .info-btn.on { color: #191F45; }
.rd-cos th.nw, .rd-cos td.nw { white-space: nowrap; }
/* EXPAND A CLIENT IN PLACE (Steven, 2026-09-09). The chevron is a real button in its own
   narrow column - the client name beside it is a link to the client record, and one target
   per click. */
.rd-cos th.rn-x, .rd-cos td.rn-x { width: 34px; padding-left: 8px; padding-right: 0; text-align: center; }
.rn-tog { border: 0; background: none; cursor: pointer; padding: 0; width: 22px; line-height: 1;
          font-size: 17px; color: #52586e; font-family: inherit; }
.rn-tog:hover { color: #191F45; }
/* The open row and its detail read as one block, so the eye does not lose which client the
   entries belong to once the parent row has scrolled up under the header. */
.rd-cos tr.rn-open > td { background: #f4f7fc; }
.rd-cos tr.rn-detail > td { background: #f4f7fc; padding: 4px 14px 14px 40px; border-bottom: 2px solid #ced4da; }
.rn-detail-inner { overflow-x: auto; }
/* A nested table sets its own rhythm: smaller, and it must never inherit the parent's sticky
   header or footer, which would pin a child's rows over the run's own.
   Both selectors are qualified with `table` on purpose: "table.cases th" and ".rd-cos tfoot
   td" both out-specify a bare ".rn-entries th", so an unqualified rule here would lose and
   the child's header would stick to the parent's scrollport. */
.rn-entries { font-size: 12.5px; border: 1px solid #ced4da; background: #fff; }
table.rn-entries th { position: static; }
table.rn-entries tfoot td { position: static; background: #fbfcfe; font-weight: 700; color: #191F45; }
/* Client → Billing details dialog: the recipients checklist and the Xero customer lookup. */
.recip-list { display: flex; flex-direction: column; gap: 4px; max-height: 200px; overflow-y: auto; border: 1px solid #e4e7ee; border-radius: 6px; padding: 8px 10px; }
.recip-row { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.xero-picked { display: flex; align-items: center; gap: 10px; font-size: 13.5px; }
/* The Xero mark (2026-10-09): before the "Customer" label (the Xero panel, the Xero link dialog), and before the Xero details dialog's title. */
.xero-head { display: inline-flex; align-items: center; gap: 7px; }
.xero-head img { height: 14px; }
.dlg-head-img { height: 16px; margin-right: 8px; vertical-align: -3px; }
.xero-hits { margin-top: 8px; border: 1px solid #e4e7ee; }
@keyframes intg-spin { to { transform: rotate(360deg); } }
.spin { display: inline-block; animation: intg-spin 1s linear infinite; }

/* The Billing-run dialog (design §8 / mock v3). */
.st-review { background: #fff3d6; color: #8a6a12; }
.te-run-error { margin-top: 6px; max-width: 214px; text-align: left; color: #b02a37; font-size: 12.5px; font-weight: 600; }
/* In-button progress ring (Create run etc.) — the text still says what's happening,
   so reduced-motion users lose nothing when the spin is stilled. */
.btn-spin { display: inline-block; width: 12px; height: 12px; border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; border-radius: 50%; animation: btnspin .7s linear infinite; vertical-align: -1px; margin-right: 7px; }
@keyframes btnspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn-spin { animation: none; } }
/* .te-run-done went with the create-run result panel (Steven, 2026-09-09): creating a run
   drops back to Billing now, so there is no summary screen left to style. */
.te-run-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; background: #fbfcfe; border: 1px solid #e4e7ee; border-radius: 7px; padding: 10px 14px; margin-bottom: 14px; font-size: 13.5px; }
.te-run-desc { border: 1px solid #c8c8c8; border-radius: 5px; padding: 5px 10px; font-family: inherit; font-size: 13.5px; min-width: 260px; height: 31px; }
/* A two-row GRID rather than a wrapping flex row (2026-09-09), so Client lands directly
   under Name instead of wherever the wrap happened to leave it. Four columns, each sized to
   its control; the second row starts a new line at column one. */
.te-run-fields { display: grid; grid-template-columns: repeat(4, max-content); gap: 10px 14px; align-items: end; width: 100%; }
.te-run-field-row2 { grid-column: 1; }
/* Same WIDTH as the Name box above it, not merely the same left edge — two controls in a
   column that end at different places do not read as aligned (Steven, 2026-09-09). */
.te-run-field-row2 .mpd-btn { width: 260px; }
/* The client band's actions sit at the RIGHT, Add rightmost (Steven, 2026-09-09). */
.te-co-acts { display: inline-flex; gap: 6px; flex: 0 0 auto; margin-left: auto; }
.te-co-acts .cmd-btn { padding: 3px 12px; font-size: 13px; }
/* The state pill rides along just before them rather than claiming the auto margin itself. */
.te-co-state { flex: 0 0 auto; margin-left: auto; }
.te-co-state + .te-co-acts { margin-left: 0; }
.te-run-period { height: 31px; padding: 4px 8px; border: 1px solid #c8c8c8; border-radius: 6px; font-family: inherit; font-size: 13px; background: #fff; }
.te-run-field label { display: block; font-size: 11.5px; font-weight: 600; color: #555; margin-bottom: 3px; }
.te-run-foot { display: flex; padding: 8px 14px; background: #fbfcfe; border: 1px solid #ced4da; border-top: 0; }
/* THE ACTION BLOCK (Steven, 2026-09-09): three buttons of one width. It sits at the right
   of the header band, so it needs a fixed width - the buttons take 100% of it and therefore
   match each other exactly, without hand-tuning three numbers. */
.rn-actions { flex: 0 0 200px; display: flex; flex-direction: column; gap: 8px; align-self: flex-start; }
.rn-buttons { display: flex; flex-direction: column; gap: 6px; }
.rn-buttons .cmd-btn { width: 100%; justify-content: center; }
/* Create stands out by being half again as tall as the two above it, and by wearing the
   house accent - it is the one button here that writes anything. It stacks its own count
   underneath rather than carrying it in brackets, so the number has room to be a phrase. */
.rn-create { height: 47px; flex-direction: column; gap: 1px; line-height: 1.15; }
.rn-create-main { font-size: 14.5px; font-weight: 600; }
.rn-create-busy { display: inline-flex; align-items: center; gap: 6px; }
.rn-create-sub { font-size: 11px; font-weight: 500; opacity: .85; font-variant-numeric: tabular-nums; }
/* THE FACTS COLUMNS (Steven, 2026-09-09: "align x entries, people avatars and total hrs
   between each company by allowing enough space"). Fixed tracks, so the three facts sit at
   the same x down every card however many entries or people a company has. The who track
   holds five stacked circles (26px, overlapping 3px) before it scrolls its overflow. */
.rn-facts { display: grid; grid-template-columns: 74px 122px auto; align-items: center; gap: 0 14px; }
.rn-f-entries { white-space: nowrap; }
.rn-f-who { overflow: hidden; }
.rn-f-hrs { white-space: nowrap; }
.te-pos { border: 1px solid #ced4da; background: #fff; table-layout: fixed; }
.te-pos td { overflow: hidden; }   /* protect the fixed template; never paint an ellipsis beside pills/buttons */
.te-pos th, .te-pos td { padding: 7px 10px; }
.te-pos th { white-space: nowrap; position: static; }   /* table.cases th is sticky - not here (17 small tables, no shared scroll) */
/* The entries grid is drawn in three containers of three different widths - an expanded run
   row, the Entries dialog and the picker's own dialog - so its columns are shares, and its
   headers wrap for the same reason .rd-cos's do. */
.rn-entries { min-width: 900px; }
.rn-entries thead th { white-space: normal; line-height: 1.25; }
.te-pos th.num, .te-pos td.num { text-align: right; }
.te-pos tfoot td { border-top: 1px solid #ced4da; border-bottom: 0; font-weight: 600; background: #fbfcfe; }
/* Zero footprint: its own height + one list-view gap are clawed back by negative
   margins, so it tucks into the toolbar's empty corner without moving the board. */
.te-grand { display: flex; width: fit-content; gap: 20px; font-size: 13px; color: #555; margin: -2px 0 12px; padding: 7px 14px; background: #fff; border: 1px solid #ced4da; border-radius: 7px; }
.te-grand b { color: #191F45; }
/* The big-deal action (Process): the house accent, darkened for contrast. */
.cmd-btn-accent { background: #c2410c; border-color: #c2410c; color: #fff; font-weight: 600; }
.cmd-btn-accent:hover:not(:disabled) { background: #a33509; }
/* Disabled coloured buttons DIM, never grey-text (ui-standards): same colour, cloudy. */
.cmd-btn-primary:disabled { background: #191F45; color: #fff; opacity: .45; }
.cmd-btn-accent:disabled { background: #c2410c; color: #fff; opacity: .45; }

/* The Billable cell: tick + the Billing-detail button beside it (Steven, 2026-09-05 —
   an obvious button, not a corner glyph). Letter-in-a-circle, never colour alone. */
.bill-cell { display: inline-flex; align-items: center; gap: 6px; }
.why-btn {
    width: 18px; height: 18px; padding: 0; flex: 0 0 auto;
    border: 1px solid #8a90a6; border-radius: 50%;
    background: #fff; color: #16233f;
    font: italic 700 11px/16px Georgia, serif;
    cursor: pointer;
}
.why-btn:hover { border-color: #1b2a4a; color: #1b2a4a; background: #eef1f7; }

.st-warn { background: #fdeadd; color: #b25a12; }
.nw { white-space: nowrap; }
/* Time / Expense kind pills (labels carry the words; colour is secondary). */
.pill.kind-time { background: #e0f2ef; color: #00695c; }
.pill.kind-expense { background: #efe6f7; color: #6a1b9a; }
.te-f { display: flex; align-items: center; gap: 8px; }
.te-f > .cmd-filter-label { min-width: 62px; }
.te-f select { border: 1px solid #c8c8c8; border-radius: 6px; padding: 4px 8px; font-size: 14px; background: #fff; color: #222; width: auto; height: 31px; box-sizing: border-box; }

/* T&E options bar at the top of a case's Time & Expenses tab. Its filters are the SAME
   label-and-control groups as the T&E screen's toolbar (.te-f + .cmd-filter-label), so the two
   read alike. Only the fixed label width is dropped: that width lines the toolbar's two rows up,
   and this is a single row. (The uppercase .te-lab it used to have went on 2026-09-11.) */
.te-options { display: flex; gap: 14px; align-items: center; margin-bottom: 10px; flex-wrap: wrap; }
.te-options select { width: auto; }
.te-options .te-f > .cmd-filter-label { min-width: 0; }

/* The shared view switch's icons (SegSwitch — T&E's List / Calendar). */
.seg button i { margin-right: 5px; font-size: 14px; vertical-align: -1px; }

/* ===== GROUPS IN THE ENTRIES GRID (EntriesGrid, Steven 2026-09-11) =====
   A client or a week is a HEADING ROW of the grid itself — its label across the leading columns,
   its figures in the grid's own figure columns — so a group's totals line up with its lines ("I
   dont think it makes sense having totals that arent aligned with the child values underneath").
   It replaced a separate summary table whose rows opened onto a second, nested grid. */
table.rn-entries tr.eg-group > td { background: #f4f7fc; font-weight: 600; color: #16233f;
                                    border-top: 1px solid #ced4da; }
/* The heading's label: chevron · name (a fixed slot) · "N entries" · [This week / Last week].
   The name's slot is the same width on every heading of a grid, so the counts line up down it;
   a longer name ellipsises (the whole of it is on hover). A week's range is already a
   fixed-width grid of its own, so its slot is simply that. */
.eg-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.eg-name { flex: 0 0 min(340px, 50%); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eg-name.wk { flex: 0 0 auto; overflow: visible; }
.eg-count { flex: none; font-weight: 400; font-size: 12px; color: #6b7180; }
.eg-head .pill.te-wk-tag { margin-left: 4px; }
/* The week row's dates (Steven, 2026-09-11): day · month · year – day · month · year, each in
   a fixed slot so every range lines up down the list whatever its digits and month names. */
.te-wk-range { display: inline-grid; grid-template-columns: 2ch 2.7em 2ch 1.5em 2ch 2.7em 2ch; column-gap: 5px;
               align-items: baseline; font-weight: 600; color: #16233f; font-variant-numeric: tabular-nums;
               vertical-align: middle; }
.te-wk-range .d { text-align: right; }
.te-wk-range .sep { text-align: center; color: #8a90a6; font-weight: 400; }
/* This week / Last week: larger and clearer, a filled pill and an outlined one. */
.pill.te-wk-tag { margin-left: 16px; font-size: 12.5px; font-weight: 700; padding: 3px 12px; vertical-align: middle; }
.pill.te-wk-tag.now { background: #191F45; color: #fff; }
.pill.te-wk-tag.last { background: #fff; color: #191F45; box-shadow: inset 0 0 0 1.5px #191F45; }
/* THE T&E TOOLBARS — Enquiry and My Timesheet (Steven, 2026-09-11; reshaped 2026-09-14). Title ·
   New/Refresh · filters. THE TITLE IS TWO LINES on both (.ts-title below), so New and Refresh, and
   the filters after them, stand in the same place on the two screens.
   THE FILTERS ARE A GRID OF EQUAL CELLS (Steven, 2026-09-14: "find a default width for all of these
   controls on Enquiry filter and My Timesheet filter and make all the same. In general, fit 3 cols
   on wider screen, stack [to 2] when smaller"). Every cell is a 62px label and a 232px control —
   232 being the widest any of them needs: Status showing two pills, Grouping's None / Client /
   Consultant. THREE COLUMNS from 1720px of window, TWO below it: 1720 is the widest title (206) +
   the buttons (~165) + their spacing + three cells, plus the side menu and the page's margins, and
   a 15.6" laptop at 125% (1536) falls under it. Enquiry places its five by hand (.enq) so Status
   joins Who and Client's row when there are three columns and goes under Who when there are two;
   My Timesheet's three simply flow.
   As a backstop on anything narrower still, the toolbar wraps and the filter block keeps its own
   width, so it moves under the title WHOLE rather than breaking up. */
.list-toolbar.te-toolbar,
.list-toolbar.ts-toolbar { flex-wrap: wrap; column-gap: 18px; row-gap: 12px; align-items: flex-start; }
.te-toolbar > .list-commandbar,
.ts-toolbar > .list-commandbar { margin-right: 24px; }   /* the filters have always stood that much further out */
.te-filters { flex: 0 0 auto; display: grid; grid-template-columns: repeat(2, 302px);
              column-gap: 16px; row-gap: 8px; align-items: start; }
.te-filters .te-f > .cmd-filter-label { flex: 0 0 62px; width: 62px; min-width: 0; }
.te-filters .seg { width: 232px; box-sizing: border-box; }
.te-filters .seg > button { flex: 1 1 auto; height: 34px; padding-top: 0; padding-bottom: 0; }
.te-filters .mpd-btn { width: 232px; }
.te-filters select { width: 232px; height: 36px; }
.te-filters .date-field { height: 36px; box-sizing: border-box; border-radius: 6px; }
.te-filters.enq .f-grouping { grid-area: 1 / 1; }
/* A custom range's two date boxes go UNDER the Dates list in two columns, and beside it in three,
   where the cell spans the empty place to its right (Status sits a row lower). */
.te-filters.enq .f-dates { grid-area: 1 / 2; flex-wrap: wrap; row-gap: 6px; }
.te-filters.enq .f-who { grid-area: 2 / 1; }
.te-filters.enq .f-client { grid-area: 2 / 2; }
.te-filters.enq .f-status { grid-area: 3 / 1; }
.te-range { display: inline-flex; align-items: center; gap: 8px; }
@media (min-width: 1720px) {
    .te-filters { grid-template-columns: repeat(3, 302px); }
    .te-filters.enq .f-dates { grid-column: 2 / span 2; flex-wrap: nowrap; }
    .te-filters.enq .f-status { grid-area: 2 / 3; }
}
/* SHOW FINANCIALS, JUST ABOVE THE GRID ON THE RIGHT (Steven, 2026-09-14) — on Enquiry a line of its
   own, tucked up under the toolbar; on My Timesheet the end of the calendar's bar (.tec-bar-end). */
.te-grid-bar { display: flex; justify-content: flex-end; margin-top: -6px; }
.te-fin { margin: 0; }
/* The Grouping switch at the filters' width, where it is used outside them (the day dialog). */
.seg.seg-grp { width: 232px; box-sizing: border-box; }
.seg.seg-grp > button { flex: 1 1 auto; }
.seg.seg-w200 { width: 200px; box-sizing: border-box; }
.seg.seg-w200 > button { flex: 1 1 0; }
/* ONE HEIGHT for the row (Steven: "Client and Status drop downs need to be same height as Who"):
   the Who button's avatar makes it 36px, so every dropdown beside a label takes that height, on
   the case tab as well — and the switches on the toolbar match it. */
.te-f .mpd-btn { height: 36px; box-sizing: border-box; }

/* MY TIMESHEET'S TOOLBAR (Steven, 2026-09-12). It lines up with the screens either side of it:
     Time & Expenses   New Refresh                    Grouping […]  Who […]  Status […]
     My Timesheet                                                   Show financials
   THE TITLE IS TWO LINES. Line one is the screen title every other screen wears — .list-title's
   27px/600 (Steven, 2026-09-12: "Time & Expenses text to be same font/size etc as the Clients or
   Cases text on those screens"). That makes the block 206px wide rather than the 150px "Clients"
   takes, so New and Refresh sit that much further right than on Clients: SIZE WON OVER THAT
   ALIGNMENT, deliberately, after a round with it the other way. Line two is smaller and NOT bold
   ("Dont mind My Timesheet being a little smaller if necessary but not bold").
   THE FILTERS stood in one row ending where the grid ends until 2026-09-14; they now stand where
   Enquiry's do, two wide (see the T&E toolbar above). Show financials ends the calendar's bar, and
   the key is under the title. */
/* (The layout itself — a wrapping flex row, the filters one block — is with the T&E toolbar's above.)
   The two-line title takes .list-title's column on every toolbar that wears it, Billing's included,
   so the buttons stand where they do on Clients. */
.list-toolbar > .ts-title { margin: 0; min-width: 150px; flex: 0 0 auto; }
/* My Timesheet's title column: the two-line title with the calendar's key under it (Steven,
   2026-09-14: "Move Time Expense Approved key under My Timesheet text"). */
.list-toolbar > .ts-head { min-width: 150px; flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; }
.ts-head > .ts-title { margin: 0; }
/* The key never widens the column — the TITLE sets it, as on Enquiry, so the buttons and filters
   stand in the same place on both screens. It sits below the buttons, so it is free to run on. */
.ts-head > .tec-key { width: 0; }
.ts-title-top { display: block; font-size: 27px; font-weight: 600; color: #191F45; line-height: 34px; white-space: nowrap; }
.ts-title-name { display: block; font-size: 19px; font-weight: 400; color: #191F45; line-height: 24px; white-space: nowrap; }
/* The flat list: the entries grid IS the page's grid here, so its header and totals pin to the
   scroller like every list screen's — the nested copies deliberately never do. */
.te-flat-wrap > .rn-entries { border: 0; }
table.rn-entries.rn-flat th { position: sticky; top: 0; z-index: 2; background: #eceff4; }
table.rn-entries.rn-flat tfoot td { position: sticky; bottom: 0; z-index: 2; background: #f2f5fa; }
/* The T&E variants of the entries grid carry a status column with a pill AND a padlock, an
   open button, and (by week and flat) a Client column — so they need a higher floor. */
/* The entries dialog's body scrolls sideways when the grid is wider than the box. */
/* THE DAY DIALOG'S BAR (Steven, 2026-09-12): the day stepper, then the SAME Grouping and Show
   financials the screen behind carries, so a day can be re-cut without leaving it. */
.dayd-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.dayd-sum { font-size: 13px; color: #555; }
.dayd-sum b { color: #191F45; }
.dayd-bar .dayd-grp { margin-left: 10px; }
.dayd-bar .dayd-fin { margin: 0 0 0 auto; }
/* ONE HEIGHT WHATEVER THE DAY HOLDS (Steven, 2026-09-12: "Give it standard fixed size (the
   dialog) so that it doesnt shift sizes when left/right buttons are clicked within the dialog") —
   a busy day scrolls inside the box, an empty one leaves it empty, and stepping never resizes
   the dialog under the buttons you are clicking. */
.dayd-body { height: clamp(240px, 50vh, 480px); overflow: auto; }

.entries-dlg-body { overflow-x: auto; }
/* The floors: the fixed pixel columns (EntriesGrid's ColsOpen / ColsClientOpen, 890px)
   plus a readable Details — and, by week and flat, a Client beside it. Kept where they were
   (review, 2026-09-11): at 1150 / 1210 a 1440px window scrolled sideways; at 1100 Client and
   Details still get about 105px each at the very floor, and all the width above it. */
.rn-entries.rn-te { min-width: 1000px; }
.rn-entries.rn-te-wide { min-width: 1100px; }
/* The billing run's layouts are pixels too now (Steven, 2026-09-11: the entries dialog was "a
   bit cramped, Details in particular but case number, pills are cropped, approve button too
   close to edge"), so they get floors of their own: the fixed columns plus a readable Details. */
.rn-entries.rn-run { min-width: 1000px; }
.rn-entries.rn-run-edit { min-width: 1160px; }
/* 8px sides rather than .te-pos's 10, in every layout: twelve or thirteen columns each give
   back 4px, and every one of them goes to Details (and Client). */
.rn-entries th, .rn-entries td { padding-left: 8px; padding-right: 8px; }
/* The run's Approve / Un-approve / Edit cell sits IN from the grid's right edge. */
.rn-entries th.rn-act-cell, .rn-entries td.rn-act-cell { padding: 4px 12px 4px 6px; text-align: right; white-space: nowrap; }
/* The edit/view button sits IN from the grid's right edge (Steven, 2026-09-11), not against it. */
.rn-entries th.rn-open-cell, .rn-entries td.rn-open-cell { padding: 4px 12px 4px 4px; text-align: right; }

/* ===== THE T&E CALENDAR (TeCalendar, Steven 2026-09-11) =====
   A month, Monday first, with a week-total column. Kind is a SHAPE on every chip — a clock or a
   receipt, and a solid or dashed edge — so the edge colour is never the only signal; a padlock
   marks an approved line, and the key above the grid says so in words. */
.tec { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; overflow: auto; }
.tec-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tec-title { font-size: 17px; font-weight: 700; color: #191F45; margin: 0 4px; min-width: 150px; text-align: center; }
.tec-sum { margin-left: 12px; font-size: 13px; color: #555; }
.tec-sum b { color: #191F45; }
.tec-key { display: inline-flex; gap: 14px; font-size: 12px; color: #666; white-space: nowrap; }
.tec-bar-end { margin-left: auto; display: inline-flex; align-items: center; }
.tec-key i { font-size: 13px; vertical-align: -1px; }
.tec-grid { border: 1px solid #ced4da; background: #fff; min-width: 900px; }
/* The columns come from the component (--tec-cols): five or seven days, then the week total. */
.tec-row { display: grid; grid-template-columns: var(--tec-cols, repeat(7, minmax(0, 1fr)) 124px); }
/* A week is two grid rows, the date strip and the days' contents; its total spans both. */
.tec-week > .tec-wk { grid-row: span 2; }
.tec-row + .tec-row { border-top: 1px solid #e4e7ee; }
.tec-head { background: #eceff4; border-bottom: 1px solid #ced4da; position: sticky; top: 0; z-index: 2; }
.tec-head > div { padding: 7px 10px; font-size: 12px; font-weight: 600; color: #555; }
.tec-head > .tec-wkh { text-align: right; }
/* EACH WEEK IS ONE GRID: its date strip first, then its lanes — one lane ungrouped, one per
   client or consultant when grouped — so a day's column reads as one cell top to bottom. */
.tec-dh-cell, .tec-cell { min-width: 0; padding: 4px 6px; border-right: 1px solid #e4e7ee; display: flex; }
.tec-dh-cell { align-items: center; gap: 6px; min-height: 30px; }
.tec-cell { flex-direction: column; gap: 3px; padding-bottom: 7px; position: relative; }
/* THE MONTH FILLS THE SCREEN AND NO MORE (Steven, 2026-09-11: "getting [vertical scroll] by
   default" ... "there's definitely room for the +1 more to squeeze in"). The grid takes the
   calendar's remaining height; each week is as tall as it needs, and the slack is shared between
   them, in their contents rows (not their date strips). How many items a day shows is MEASURED
   (dhrFitCalendar): the most that let every week fit, so the month opens without a scrollbar; a
   week opened out with "+N more" grows past that, and then the calendar scrolls. */
.tec-grid.month { flex: 1 0 auto; display: flex; flex-direction: column; }
.tec-grid.month > .tec-week { flex: 1 0 auto; grid-template-rows: auto 1fr; }
.tec-grid.month .tec-cell { min-height: 40px; }
/* What a day holds back behind "+N more": laid out at the day's own width, so it can be measured,
   but not shown, not clickable and taking no room — anchored to the day's foot, so one taller than
   the day overflows upward, where it can never make the calendar scroll. */
.tec-over { position: absolute; left: 6px; right: 6px; bottom: 0; visibility: hidden; pointer-events: none; }
.tec-grid.week .tec-cell { min-height: 170px; }
.tec-dh-cell.we, .tec-cell.we { background: #fafbfd; }
.tec-dh-cell.out, .tec-cell.out { background: #f4f5f8; }
.tec-dh-cell.out .tec-dn { color: #a3a8b5; }
.tec-dn { font-size: 13px; font-weight: 600; color: #3a4056; min-width: 22px; height: 22px; line-height: 22px;
          text-align: center; border-radius: 11px; font-variant-numeric: tabular-nums; }
.tec-dn.wide { min-width: 0; padding: 0 7px; }   /* "Mon 7" in the week views */
/* Today: the number filled AND the word "Today" beside it... */
.tec-dh-cell.today .tec-dn { background: #191F45; color: #fff; }
/* ...AND A BORDER ROUND THE WHOLE DAY (Steven, 2026-09-11: "as per outlook") — the strip and
   every lane beneath it together. Inset shadows, so it takes no room and nothing shifts. */
.tec-grid .today-t { box-shadow: inset 2px 0 0 #191F45, inset -2px 0 0 #191F45, inset 0 2px 0 #191F45; }
.tec-grid .today-m { box-shadow: inset 2px 0 0 #191F45, inset -2px 0 0 #191F45; }
.tec-grid .today-b { box-shadow: inset 2px 0 0 #191F45, inset -2px 0 0 #191F45, inset 0 -2px 0 #191F45; }
.tec-grid .today-tb { box-shadow: inset 0 0 0 2px #191F45; }
/* GROUPED BY CLIENT OR CONSULTANT (Steven, 2026-09-11): one total per client, or per person,
   in each day — the name or the avatar, then its figures. It OPENS its entries in the shared
   dialog, so it has the chip's pointer and hover; its tooltip still lists them. Its edge is
   neutral grey, being a mix of time and expenses. */
.tec-chip.tec-agg { border-left: 3px solid #8a90a6; }
/* A total: its figures — by client, under the client's name. */
.tec-tot { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; font-weight: 600;
           font-variant-numeric: tabular-nums; }
.tec-tot-name { font-weight: 700; color: #16233f; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The figures along ONE line, "2.75 hrs, 1 expense" (Steven, 2026-09-11: "why not have the
   expense beside the hrs, would allow for a thinner rectangle"). A figure is never split: when
   the day is too narrow for them all, the next whole figure takes the next line. */
.tec-figs { display: flex; flex-wrap: wrap; column-gap: 4px; min-width: 0; }
.tec-figs > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.tec-figs > span:not(:last-child)::after { content: ","; }
.tec-chip.tec-agg .who.tec-av { width: 22px; height: 22px; font-size: 9.5px; }
/* The Month / Week / Work week choice — a plain toolbar select, as Outlook offers it. */
.tec-view { height: 31px; padding: 4px 8px; border: 1px solid #c8c8c8; border-radius: 6px; font: inherit;
            font-size: 13.5px; background: #fff; color: #222; }
.tec-today { font-size: 10.5px; font-weight: 700; color: #191F45; text-transform: uppercase; letter-spacing: .05em; }
.tec-dt { margin-left: auto; font-size: 11.5px; color: #59607a; font-variant-numeric: tabular-nums; }
/* A day's own buttons, at the right of its date strip: open the day in full, and add to it. */
.tec-dh-acts { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.tec-dt ~ .tec-dh-acts { margin-left: 4px; }
/* OPEN THE DAY — the same circle as the + so it reads as a button too (Steven, 2026-09-12: "Put
   the button in a circle as well, not blue but with same icon inside"), in the app's neutral
   grey: the blue one is the action, this one only looks. */
.tec-day { border: 0; background: #8a90a6; color: #fff; cursor: pointer; padding: 0;
           width: 20px; height: 20px; border-radius: 50%; line-height: 1; font-size: 12px; opacity: .85;
           display: inline-flex; align-items: center; justify-content: center; }
.tec-dh-cell:hover .tec-day, .tec-day:focus-visible { opacity: 1; }
.tec-day:hover { background: #59607a; }
/* ADD — a filled blue circle (Steven, 2026-09-12: "the + button to add on the day could be a blue
   icon, circle, with plus in, just makes it more obviously a button"). */
.tec-add { border: 0; background: #3d5296; color: #fff; cursor: pointer; padding: 0;
           width: 20px; height: 20px; border-radius: 50%; line-height: 1; font-size: 13px; opacity: .9;
           display: inline-flex; align-items: center; justify-content: center; }
.tec-dh-cell:hover .tec-add, .tec-add:focus-visible { opacity: 1; }
.tec-add:hover { background: #191F45; }
.tec-chip { display: flex; align-items: center; gap: 5px; width: 100%; min-width: 0; box-sizing: border-box;
            border: 1px solid #d9dde6; border-left: 3px solid #00695c; border-radius: 5px; background: #fff;
            padding: 2px 6px; font: inherit; font-size: 12px; color: #262b40; cursor: pointer; text-align: left; }
.tec-chip.k-exp { border-left: 3px dashed #6a1b9a; }
.tec-chip:hover { background: #eef1f7; }
.tec-chip:focus-visible { outline: 2px solid #191F45; outline-offset: 1px; }
.tec-chip > i { font-size: 13px; color: #59607a; flex: none; }
.tec-q { font-weight: 600; font-variant-numeric: tabular-nums; flex: none; }
.tec-cn { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tec-chip .who.tec-av { width: 18px; height: 18px; font-size: 8.5px; flex: none; }
.tec-lk { font-size: 12px; color: #8a90a6; flex: none; }
.tec-more { border: 0; background: none; padding: 1px 4px; font: inherit; font-size: 11.5px; font-weight: 600;
            color: #3b4a7a; cursor: pointer; text-align: left; }
.tec-more:hover { text-decoration: underline; }
.tec-wk { padding: 7px 10px; display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
          background: #fbfcfe; font-size: 12.5px; }
.tec-wk b { color: #191F45; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The week's other figure — the count of expenses, or £ expenses — on a line of its own (Steven,
   2026-09-11: "The label for expenses doesnt fit here"). */
.tec-wk .tec-wk-f { font-size: 11.5px; color: #3a4056; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tec-wk { padding-left: 8px; padding-right: 8px; }

/* ===========================================================================
   Hover-help standard (see docs/ui-standards.md): anything explained by a tooltip
   shows the help cursor, and text hints get a dotted underline as the discovery cue.
   Detail-table headers with a title attribute pick this up automatically. */
.hint { cursor: help; text-decoration: underline dotted #b3b8c4; text-underline-offset: 3px; }
table.cases th[title] { cursor: help; text-decoration: underline dotted #b3b8c4; text-underline-offset: 3px; }

/* VIEW AS (2026-10-09): the band while this tab views the CRM as somebody, read only. Its words say so - the amber
   is only a second cue (never colour alone). */
.viewas-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 14px 0; padding: 8px 14px;
              background: #fff4d6; border: 1px solid #e0b84a; border-radius: 6px; color: #5c4400; font-size: 14px; }
.viewas-bar > .ti { font-size: 18px; }
.viewas-bar .viewas-stop { margin-left: auto; background: #fff; border: 1px solid #5c4400; color: #5c4400; }

/* Virtual HRM → Client portal settings (2026-10-10): each client's logo in the row, framed as the portal frames it
   (the .pv-client surrounds above), small. The surround's name is in its own column too. */
.cps-search { max-width: 280px; }
.cps-logo { display: inline-flex; height: 34px; max-width: 170px; min-width: 34px; border-radius: 6px; position: relative; }
.cps-logo.pv-client-light, .cps-logo.pv-client-dark { padding: 4px 10px; }
.cps-logo.pv-client-light { border: 1px solid #e3e6ee; }
/* Until the logo arrives (imgWait.js marks it): the picture held back, a spinner in its place. Still laid out as before,
   so lazy loading still sees it. */
.cps-logo img[data-wait]:not([data-loaded]) { opacity: 0; }
.cps-wait { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #6b7a90; font-size: 18px; }
.cps-logo.pv-client-dark .cps-wait { color: #c8d3e6; }
.cps-logo img[data-loaded] + .cps-wait { display: none; }
