/* ============================================================
   SalesPulse — site.css (Phase 6a — v3 visual overhaul)
   Tokens, sidebar, header, tables, modals, pills, forms, activity feed.
   ============================================================ */

/* ── Tokens (lifted from v3) ──────────────────────────────── */
:root {
    --navy: #080f1e;
    --navy2: #0d1829;
    --navy3: #111f38;
    /* --teal vars are the accent colour family. They get overridden per
       user via body[data-theme="…"] selectors near the bottom of the file. */
    --teal: #0d9488;
    --teal2: #14b8a6;
    --teal3: rgba(13, 148, 136, 0.12);
    --green: #10b981;
    --green3: rgba(16, 185, 129, 0.10);
    --red: #f43f5e;
    --red3: rgba(244, 63, 94, 0.10);
    --amber: #f59e0b;
    --amber3: rgba(245, 158, 11, 0.12);
    --blue: #3b82f6;
    --blue3: rgba(59, 130, 246, 0.10);

    --bg: #f4f6fa;
    --card: #ffffff;
    --border: #e8edf2;
    --border2: #d1d9e0;
    --tx: #0f172a;
    --tx2: #475569;
    --tx3: #94a3b8;

    --r: 14px;
    --rs: 10px;

    --sidebar-w: 232px;
    --header-h: 56px;
}

/* ── Reset / typography ───────────────────────────────────── */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
    font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, Arial, sans-serif;
    background: var(--bg);
    color: var(--tx);
    font-size: 14px;
    line-height: 1.45;
}

body.app-shell {
    display: flex;
    overflow: hidden;
    /* Render the whole app at ~90% so filters + wide tables (Quotes, Proposals,
       Invoices) fit with breathing room instead of hugging the right edge. */
    zoom: 0.9;
    /* zoom scales the element, so a plain 100vh shell would only cover 90% of
       the screen. Divide by the zoom factor so it fills the viewport exactly. */
    height: calc(100vh / 0.9);
}

h1, h2, h3 { font-family: 'Inter', 'Segoe UI', sans-serif; letter-spacing: -0.2px; }
h1 { font-size: 22px; font-weight: 800; margin: 0 0 8px; color: var(--tx); }
h2 { font-size: 16px; font-weight: 800; margin: 0 0 8px; color: var(--tx); }
h3 { font-size: 14px; font-weight: 700; margin: 0 0 6px; color: var(--tx); }

a { color: var(--teal); text-decoration: none; }
a:hover { text-decoration: underline; }

code {
    background: #f1f5f9; padding: 2px 7px; border-radius: 5px;
    font-family: ui-monospace, Consolas, monospace; font-size: 12px;
    color: var(--tx2); border: 1px solid #e2e8f0;
}

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

/* ── Sidebar ──────────────────────────────────────────────── */
.sidebar {
    width: var(--sidebar-w);
    min-width: var(--sidebar-w);
    background: linear-gradient(180deg, #080f1e 0%, #0a1628 100%);
    display: flex; flex-direction: column;
    /* 100% (of the zoomed app-shell) rather than 100vh, so it fills the shell
       exactly under body.app-shell { zoom }. A raw 100vh would only cover 90%. */
    height: 100%;
    border-right: 1px solid rgba(255,255,255,0.06);
    box-shadow: 4px 0 24px rgba(0,0,0,0.3);
    /* Smooth collapse — slightly longer with a soft ease-in-out so the
       width change feels intentional rather than snappy. */
    transition: width 0.35s cubic-bezier(0.65, 0, 0.35, 1),
                min-width 0.35s cubic-bezier(0.65, 0, 0.35, 1);
}
.sidebar .logo {
    padding: 22px 18px 16px;
    border-bottom: 1px solid rgba(255,255,255,0.07);
    text-align: center;
    position: relative;
    /* Clip the inner logo/wordmark while the rail is narrower than them,
       so nothing "escapes" the sidebar during the collapse/expand animation. */
    overflow: hidden;
    max-height: 240px;
}

/* When expanding back from collapsed, wait for the rail to finish widening
   before the logo image and "SalesPulse" wordmark fade in — otherwise they
   appear at full size while the rail is still narrow and visually overflow. */
.sidebar .logo .logo-img,
.sidebar .logo h1,
.sidebar .logo p {
    transition: opacity 0.18s ease 0.22s;
}

/* Burger toggle — small button in the top-right of the sidebar header */
.sb-toggle {
    position: absolute;
    top: 8px; right: 8px;
    width: 28px; height: 28px;
    border-radius: 8px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.10);
    color: rgba(255,255,255,0.65);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    z-index: 2;
    padding: 0;
}
.sb-toggle svg {
    width: 16px; height: 16px;
    stroke: currentColor;
    display: block;
}
.sb-toggle:hover {
    background: rgba(255,255,255,0.08);
    color: #fff;
    border-color: rgba(255,255,255,0.18);
}
.sb-toggle:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.30); }
.sidebar .logo .logo-img {
    display: block;
    width: 72px; height: 72px;
    border-radius: 14px;
    /* Stretch to fill the 72x72 tile edge-to-edge — no whitespace bars
       regardless of the source aspect or baked-in padding. We let the
       browser use its default scaling filter (bilinear); CSS rendering
       hints like image-rendering or transform-promotion were tried and
       made the result LOOK worse on real uploads, so we don't use them. */
    object-fit: fill;
    margin: 0 auto 12px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.25);
}
.sidebar .logo h1 {
    font-size: 18px; font-weight: 900; letter-spacing: -0.5px;
    margin: 0;
    display: inline-flex; align-items: baseline;
    justify-content: center;
}
.sidebar .logo h1 .logo-w1 { color: #fff; }
.sidebar .logo h1 .logo-w2 {
    /* Follow the active theme — both stops pulled from the --teal family so
       the wordmark recolours when the user switches theme. */
    background: linear-gradient(135deg, var(--teal2) 0%, var(--teal) 100%);
    -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
    color: transparent;
}
.sidebar .logo p {
    font-size: 9.5px; color: rgba(255,255,255,0.3); margin-top: 3px;
    letter-spacing: 0.6px; text-transform: uppercase;
}

.sb-user {
    padding: 12px 16px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
    display: flex; align-items: center; gap: 10px;
}
.av {
    width: 34px; height: 34px; border-radius: 50%;
    background: linear-gradient(135deg, #0d9488, #3b82f6);
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 800; color: #fff; flex-shrink: 0;
    box-shadow: 0 0 0 2px rgba(13,148,136,0.4), 0 4px 12px rgba(13,148,136,0.3);
}
.sb-user-name { font-size: 12px; font-weight: 600; color: #fff; }
.sb-user-role { font-size: 10px; color: rgba(255,255,255,0.4); text-transform: uppercase; letter-spacing: 0.4px; }

.sidebar nav { flex: 1; overflow-y: auto; padding: 8px 6px; }

.ns {
    font-size: 9px; font-weight: 800; color: rgba(255,255,255,0.2);
    letter-spacing: 1.2px; text-transform: uppercase;
    padding: 14px 10px 5px;
}
.ni {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 11px; border-radius: 10px;
    cursor: pointer;
    color: rgba(255,255,255,0.55);
    font-size: 12.5px; font-weight: 500;
    margin-bottom: 2px;
    /* Quick hover feedback, but matched easing with the sidebar collapse
       so padding/gap shrink smoothly when the rail toggles. */
    transition: background 0.18s, color 0.18s, transform 0.18s,
                padding 0.35s cubic-bezier(0.65, 0, 0.35, 1),
                gap 0.35s cubic-bezier(0.65, 0, 0.35, 1);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
}
.ni:hover {
    background: rgba(255,255,255,0.08);
    color: rgba(255,255,255,0.95);
    transform: translateX(2px);
    text-decoration: none;
}
.ni.on {
    /* Stronger fade left → right: solid-feeling colour on the left,
       fading to a much more translucent right edge for a soft tail. */
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--teal)  55%, transparent),
        color-mix(in srgb, var(--teal2) 10%, transparent));
    color: #fff; font-weight: 700;
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--teal) 42%, transparent),
        0 4px 12px color-mix(in srgb, var(--teal) 18%, transparent);
}
.ni .ico {
    flex-shrink: 0;
    width: 20px; height: 20px;
    display: inline-flex; align-items: center; justify-content: center;
    color: inherit;
}
.ni .ico svg {
    width: 17px; height: 17px;
    display: block;
    stroke: currentColor;
    transition: width 0.25s ease, height 0.25s ease;
}
/* Slightly less bold by default, brighten on hover/active via colour inherit */
.ni:not(.on) .ico svg { opacity: 0.85; }
.ni:hover .ico svg, .ni.on .ico svg { opacity: 1; }

/* Button variant of .ni inside the sidebar — match the anchor variant exactly */
button.ni {
    width: 100%;
    background: none; border: none;
    font-family: inherit; text-align: left;
}

.sb-footer {
    padding: 10px 12px; border-top: 1px solid rgba(255,255,255,0.06);
    display: flex; flex-direction: column; gap: 4px;
}
.sb-footer .ni { font-size: 11.5px; }

/* Sidebar count badges */
.nbadge {
    margin-left: auto;
    background: rgba(255,255,255,0.10);
    color: rgba(255,255,255,0.75);
    font-size: 10px; font-weight: 800;
    padding: 2px 7px; border-radius: 10px;
    min-width: 22px; text-align: center;
    line-height: 1.4;
}
.nbadge-gold  { background: rgba(245,158,11,0.20); color: #f59e0b; }
.nbadge-red   { background: rgba(244,63,94,0.20);  color: #fda4af; }
.nbadge-blue  { background: rgba(59,130,246,0.20); color: #93c5fd; }
.nbadge-green { background: rgba(16,185,129,0.20); color: #6ee7b7; }

/* ── Main column / header ─────────────────────────────────── */
.main {
    flex: 1; display: flex; flex-direction: column; overflow: hidden;
    min-width: 0;
}
.topbar {
    background: var(--card);
    border-bottom: 1px solid var(--border);
    padding: 0 24px;
    height: var(--header-h);
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    flex-shrink: 0;
    box-shadow: 0 1px 8px rgba(0,0,0,0.04);
}
.topbar .page-title { font-weight: 700; font-size: 15px; color: var(--tx); }
.topbar .topbar-right { display: flex; align-items: center; gap: 14px; color: var(--tx2); font-size: 12.5px; }
.topbar .topbar-right .user { font-weight: 600; color: var(--tx); }
.topbar .inline-form { display: inline; margin: 0; }
.topbar a { color: var(--tx2); }
.topbar a:hover { color: var(--teal); text-decoration: none; }

/* Topbar search trigger */
.topbar-search-btn {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 6px 12px;
    background: var(--bg); border: 1px solid var(--border); border-radius: 999px;
    color: var(--tx3); font: inherit; font-size: 12px; font-weight: 500;
    cursor: pointer; transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.topbar-search-btn:hover {
    border-color: var(--teal);
    color: var(--tx2);
    background: #fff;
}
.topbar-search-btn .ico { font-size: 13px; line-height: 1; color: var(--tx3); }
.topbar-search-btn .kbd {
    background: #fff; border: 1px solid var(--border); border-radius: 4px;
    padding: 1px 6px; font-size: 10px; font-family: ui-monospace, monospace;
    color: var(--tx3); margin-left: 2px;
}

/* Topbar profile dropdown */
.tb-profile { position: relative; }

.tb-profile-trigger {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 5px 12px 5px 5px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    cursor: pointer;
    font: inherit;
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.tb-profile-trigger:hover,
.tb-profile.open .tb-profile-trigger {
    border-color: var(--teal);
    background: #fff;
    box-shadow: 0 2px 8px rgba(13, 148, 136, 0.10);
}

.tb-av {
    position: relative;
    width: 32px; height: 32px; border-radius: 50%;
    background: linear-gradient(135deg, #0d9488, #3b82f6);
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 11px; font-weight: 800;
    flex-shrink: 0; overflow: hidden;
    box-shadow: 0 0 0 2px rgba(13,148,136,0.4), 0 4px 12px rgba(13,148,136,0.3);
}
.tb-av img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover;
    border-radius: 50%;
    z-index: 1;
}
.tb-av-initials { position: relative; z-index: 0; }
/* If the photo loaded successfully, hide the initials behind it.
   When the photo 404s, onerror removes the <img>, the :has() no longer matches,
   and initials become visible again. */
.tb-av:has(img) .tb-av-initials { display: none; }

.tb-profile-text {
    display: flex; flex-direction: column; align-items: flex-start; line-height: 1.1;
    text-align: left;
}
.tb-profile-name { font-size: 12.5px; font-weight: 600; color: var(--tx); }
.tb-profile-role {
    font-size: 9.5px; font-weight: 700;
    color: var(--tx3); text-transform: uppercase; letter-spacing: 0.5px;
    margin-top: 2px;
}
.tb-profile-caret { color: var(--tx3); font-size: 10px; margin-left: 2px; }

.tb-profile-menu {
    position: absolute; top: calc(100% + 8px); right: 0;
    min-width: 220px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow:
        0 6px 16px rgba(15, 23, 42, 0.08),
        0 12px 32px rgba(15, 23, 42, 0.10);
    padding: 6px;
    z-index: 50;
}
.tb-profile-menu .inline-form { display: block; }
.tb-profile-item {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border-radius: 8px;
    color: var(--tx);
    font: inherit; font-size: 12.5px; font-weight: 500;
    background: none; border: none; text-align: left;
    cursor: pointer; text-decoration: none;
}
.tb-profile-item:hover {
    background: var(--bg);
    color: var(--teal);
    text-decoration: none;
}
.tb-profile-item .ico { font-size: 14px; line-height: 1; width: 18px; text-align: center; }
.tb-profile-sep { height: 1px; background: var(--border); margin: 4px 6px; }
.tb-profile-danger { color: #be123c; }
.tb-profile-danger:hover { background: #fef2f2; color: #be123c; }

.content { --content-pad-top: 22px; flex: 1; overflow-y: auto; padding: var(--content-pad-top) 24px 32px; }

/* legacy auth shell — login page renders without sidebar */
body.auth-shell {
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(180deg, #f4f6fa 0%, #e8edf2 100%);
    min-height: 100vh;
}
body.auth-shell .auth-status {
    position: absolute; top: 24px; left: 50%; transform: translateX(-50%);
    z-index: 10; max-width: 420px;
}

/* ── Page header (in-content h1 + actions) ────────────────── */
.page-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 16px; gap: 12px;
}
.page-header-actions { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.page-header-title   { display: inline-flex; align-items: center; gap: 12px; min-width: 0; }
.page-header-title h1 { margin: 0; }

/* Rep-edit form: dashboard widgets grouped checkbox grid */
.widget-grp { margin-top: 10px; }
.widget-grp-hd {
    font-size: 11px; font-weight: 700; color: var(--tx3);
    text-transform: uppercase; letter-spacing: 0.6px;
    margin-bottom: 6px;
}
.widget-grp-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 6px 14px;
    margin-bottom: 4px;
}

/* Rep Group member chips (Team page) */
.rg-chip {
    display: inline-block;
    margin: 1px 2px;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--teal3);
    color: var(--teal);
    font-size: 11.5px;
    font-weight: 600;
    box-shadow: inset 0 0 0 1px rgba(13,148,136,0.22);
}
.page-header h1 { margin: 0; }

/* ── Filter bar ──────────────────────────────────────────── */
.filter-bar {
    display: flex; flex-wrap: wrap; gap: 14px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--rs);
    padding: 12px 16px;
    margin-bottom: 14px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03);
}
.filter-bar label {
    display: flex; flex-direction: column; gap: 4px;
    font-size: 11px; font-weight: 700; color: var(--tx2);
    letter-spacing: 0.3px; text-transform: uppercase;
}
.filter-bar select, .filter-bar input {
    padding: 7px 10px;
    border: 1.5px solid var(--border);
    border-radius: var(--rs);
    background: #fff;
    font-size: 13px; color: var(--tx);
    min-width: 140px;
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.filter-bar select:focus, .filter-bar input:focus {
    border-color: var(--teal);
    box-shadow: 0 0 0 3px var(--teal3);
}

/* ── Module date-range filter (shared _ModuleDateFilter partial) ── */
.filter-dr {
    display: flex; flex-direction: column; gap: 4px;
    font-size: 11px; font-weight: 700; color: var(--tx2);
    letter-spacing: 0.3px; text-transform: uppercase;
    order: 100;          /* render at the end of the filter bar */
    margin-left: auto;   /* push it all the way to the right */
}
.filter-dr-inputs { display: flex; align-items: center; gap: 6px; }
.filter-dr-inputs input[type="date"] {
    min-width: 130px;
    /* Match the app's date inputs (e.g. the KPI dashboard custom range) instead
       of the browser-default date font, and reset the bold/uppercase/letter-
       spacing inherited from the .filter-dr caption wrapper. */
    font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, Arial, sans-serif;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
    color: var(--tx);
}
.filter-dr-sep { color: var(--tx3); font-weight: 600; }
.filter-dr-clear {
    border: 1.5px solid var(--border); background: #fff; color: var(--tx2);
    border-radius: var(--rs); cursor: pointer;
    font-size: 12px; line-height: 1; padding: 6px 8px;
    transition: border-color 0.15s, color 0.15s;
}
.filter-dr-clear:hover { border-color: var(--teal); color: var(--teal); }
/* Dim the Month/Year filters while a date range is active. They stay clickable
   so picking a value clears the range (handled in _module-daterange.js).
   IMPORTANT: do NOT put opacity on the <label> itself — opacity creates a
   stacking context that traps the slim-select dropdown panel (position:fixed)
   behind neighbouring cards. Instead grey the caption via colour and fade only
   the control button (a sibling of the panel), so the open dropdown still
   paints on top. */
.filter-bar label.dr-dimmed { color: var(--tx3); }
.filter-bar label.dr-dimmed .ss-btn,
.filter-bar label.dr-dimmed > select { opacity: 0.5; }

/* ── Buttons ─────────────────────────────────────────────── */
.btn-primary, .btn-secondary {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 9px 18px; border-radius: var(--rs);
    font-size: 13px; font-weight: 600; cursor: pointer;
    border: 1px solid transparent; font-family: inherit;
    /* Only animate the things that actually change on hover — no `all` so
       the gradient never tweens, which avoids the abrupt colour shift. */
    transition: box-shadow 0.22s cubic-bezier(0.4, 0, 0.2, 1),
                transform  0.18s cubic-bezier(0.4, 0, 0.2, 1),
                border-color 0.18s ease;
    letter-spacing: 0.1px; text-decoration: none;
}
.btn-primary {
    background: linear-gradient(135deg, var(--teal), var(--teal2));
    color: #fff;
    box-shadow:
        0 2px 8px color-mix(in srgb, var(--teal) 38%, transparent),
        0 1px 2px rgba(0,0,0,0.10);
}
.btn-primary:hover {
    /* Identical gradient → no colour transition. Hover is communicated
       purely through a softer, larger shadow and a 1 px lift. */
    box-shadow: 0 6px 18px color-mix(in srgb, var(--teal) 45%, transparent),
                0 1px 2px rgba(0,0,0,0.10);
    transform: translateY(-1px);
    color: #fff; text-decoration: none;
}
.btn-primary:active { transform: translateY(0); box-shadow: 0 2px 8px color-mix(in srgb, var(--teal) 35%, transparent); }
.btn-secondary {
    background: #fff; color: var(--tx2);
    border-color: var(--border2);
    box-shadow: 0 1px 3px rgba(0,0,0,0.07);
}
.btn-secondary:hover {
    background: #f8fafc; border-color: #cbd5e1; color: var(--tx);
    text-decoration: none;
}

/* Disabled state for both primary and secondary buttons. Grey, no hover
   transform, no shadow lift — makes the "can't click this right now" state
   obvious without removing the button from the layout. */
.btn-primary:disabled, .btn-primary[disabled],
.btn-secondary:disabled, .btn-secondary[disabled] {
    background: #e2e8f0;
    color: #94a3b8;
    border-color: #cbd5e1;
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
    pointer-events: none;       /* defensive — disabled buttons shouldn't get hover/click anyway */
}
.btn-primary:disabled:hover, .btn-primary[disabled]:hover,
.btn-secondary:disabled:hover, .btn-secondary[disabled]:hover {
    background: #e2e8f0; color: #94a3b8; transform: none;
}

.link-button {
    background: none; border: none;
    color: var(--teal); cursor: pointer;
    padding: 0; font: inherit; font-size: 12.5px; font-weight: 600;
    text-decoration: none;
}
.link-button:hover { text-decoration: underline; }
.link-button.danger { color: var(--red); }

/* ── Alerts ──────────────────────────────────────────────── */
.alert {
    padding: 11px 14px;
    border-radius: 10px;
    margin-bottom: 14px;
    font-size: 13px;
    line-height: 1.45;
}
.alert:empty { display: none; }
/* asp-validation-summary renders <ul><li>…</li></ul>; flatten the list so
   the message reads as plain text with no bullet markers. */
.alert ul { margin: 0; padding: 0; list-style: none; }
.alert ul li { list-style: none; }
.alert ul li + li { margin-top: 4px; }
/* When asp-validation-summary is valid the wrapper gets this class
   AND its inner <ul> is empty — hide the whole alert in that state. */
.alert.validation-summary-valid,
div.validation-summary-valid { display: none; }
.alert-success {
    background: var(--green3); color: #047857;
    border: 1px solid rgba(16,185,129,0.25);
}
.alert-error {
    background: var(--red3); color: #be123c;
    border: 1px solid rgba(244,63,94,0.22);
}
.field-error { color: var(--red); font-size: 12px; }

/* ── Forms ───────────────────────────────────────────────── */
.form-stack { max-width: 640px; }
/* Targets edit form needs more room — it's a 3-column grid (Sales /
   Proposals / Cold Calls etc.), and 640px makes each block ~200px wide
   which feels cramped. Bump just this form to fit the wider layout. */
.form-stack:has(.targets-grid) { max-width: 1200px; }
.form-row { margin-bottom: 12px; display: flex; flex-direction: column; gap: 5px; }
.form-row label {
    font-size: 12px; font-weight: 600; color: var(--tx2); letter-spacing: 0.1px;
}
.form-row input[type=text],
.form-row input[type=email],
.form-row input[type=password],
.form-row input[type=number],
.form-row input[type=date],
.form-row input[type=tel],
.form-row input[type=search],
.form-row input[type=url],
.form-row select,
.form-row textarea {
    padding: 9px 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--rs);
    font-size: 13px; font-family: inherit; color: var(--tx);
    background: #fff; width: 100%; outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.form-row textarea { resize: vertical; min-height: 76px; }

input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; appearance: textfield; }

.files-pop { cursor: default; }
.files-popover {
    position: absolute; z-index: 1000;
    background: #fff; border: 1px solid var(--border);
    border-radius: var(--rs); box-shadow: 0 6px 18px rgba(0,0,0,0.12);
    padding: 6px 0; min-width: 220px; max-width: 360px;
    font-size: 12px; color: var(--tx);
}
.files-popover-list { list-style: none; padding: 0; margin: 0; }
.files-popover-list li {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 5px 12px; border-bottom: 1px solid #f1f5f9;
}
.files-popover-list li:last-child { border-bottom: 0; }
.files-popover-list .fp-name { word-break: break-word; }
.files-popover-list .fp-size { white-space: nowrap; }
.files-popover-empty { padding: 6px 12px; }
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
    border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal3);
}
.form-row input:hover, .form-row select:hover { border-color: var(--border2); }
.form-row input[readonly] { background: #f8fafc; color: var(--tx2); }

.form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; }
@media (max-width: 600px) { .form-grid-2 { grid-template-columns: 1fr; } }

/* Targets edit page — fieldsets fill the row side-by-side. auto-fit collapses
   gracefully: 4 columns on a wide screen, 2 on a tablet, 1 on mobile. */
.targets-grid {
    display: grid;
    /* Fixed 3 equal columns. Sales+Meetings stack in col 1; Proposals+
       Activity Rings stack in col 2; Cold Calls occupies col 3 spanning
       both rows. Equal widths keep the row 1 / row 2 fieldsets matching
       in size, as requested. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    /* `stretch` makes paired fieldsets in the same row (Sales+Proposals,
       Meetings+Activity Rings) match each other's height so their bottom
       borders line up. */
    align-items: stretch;
}
/* Force legends + labels to stay on a single line inside the narrow grid
   columns. Wrapping legends (e.g. "Activity rings ...") used to push the
   following input row down by one line, breaking horizontal alignment with
   the neighbouring fieldset. */
.targets-grid legend,
.targets-grid .form-row label {
    white-space: nowrap;
}
/* Cold Calls is pinned to column 3 spanning rows 1-2 so it fills the
   right-hand side of the layout, alongside Proposals (row 1) and Activity
   Rings (row 2). The other four fieldsets auto-flow into the remaining
   cells in HTML order. */
.targets-grid .targets-grid-cell-right {
    grid-column: 3;
    grid-row: 1 / span 2;
}

/* Drop back to 1 column on narrow viewports so labels + inputs aren't
   squashed; ~720px is roughly where 3 cols starts to feel cramped. */
@media (max-width: 720px) {
    .targets-grid { grid-template-columns: 1fr; }
    .targets-grid .targets-grid-cell-right { grid-column: 1; grid-row: auto; }
}

.form-stack fieldset {
    border: 1px solid var(--border); border-radius: var(--rs);
    padding: 12px 16px; margin: 14px 0;
}
/* Targets-grid fieldsets must NOT carry the form-stack 14px top/bottom
   margin — combined with the grid's own `gap: 14px` it would otherwise
   add ~42px of dead space between row 1 and row 2. Placed AFTER the
   .form-stack rule so it wins on cascade order (same specificity). */
.targets-grid fieldset { margin: 0; }
.form-stack legend { font-weight: 700; padding: 0 6px; font-size: 12px; color: var(--tx2); text-transform: uppercase; letter-spacing: 0.3px; }
.checkbox-row { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.modules-fieldset .checkbox-row { display: flex; margin: 4px 0; font-weight: 400; }
.form-actions { margin-top: 18px; display: flex; gap: 10px; }
.actions { margin-bottom: 12px; display: flex; gap: 10px; align-items: center; }

/* ── Tables ──────────────────────────────────────────────── */
.data-table {
    /* separate (not collapse) so the hover highlight's end cells can be
       rounded — collapsed borders ignore border-radius on cells. spacing:0
       keeps cells flush, so it looks identical to the old collapsed borders. */
    width: 100%; border-collapse: separate; border-spacing: 0;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r);
    /* `clip` (not `hidden`) still clips the rounded corners but does NOT create
       a scroll container, so the sticky header below pins to the page's scroll
       area (.content) instead of being trapped inside the table box. */
    overflow: clip;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03), 0 4px 16px rgba(0,0,0,0.025);
}
.data-table th {
    text-align: left; padding: 8px 10px;
    font-size: 10.5px; font-weight: 800; color: var(--tx2);
    text-transform: uppercase; letter-spacing: 0.5px;
    /* Faded grey so the (often sticky) header reads as distinct from the
       white table body it sits above. */
    background: #f1f4f8;
    border-bottom: 2px solid var(--border);
}
/* Sticky header — keeps column labels visible while a long list scrolls.
   Pins to the top of the nearest scroll container (.content on module pages,
   or a bounded wrapper like .registry-scroll). */
.data-table thead th {
    position: sticky;
    /* .content (the scroll container) has 22px top padding. A plain top:0 would
       pin the header at the content-box top — i.e. 22px BELOW the scrollport —
       leaving a gap where rows show above it. top:-22px pins it flush with the
       bottom of the topbar. (.registry-scroll has no padding, so its own rule
       below overrides this back to top: 0.) */
    top: -22.5px;
    z-index: 2;
}
/* Keep the header bar's top corners rounded even when pinned. The table's
   overflow:clip only rounds the header while it sits at the table's top; once
   scrolled, round the end cells directly so the sticky bar stays rounded. */
.data-table thead th:first-child { border-top-left-radius: var(--r); }
.data-table thead th:last-child  { border-top-right-radius: var(--r); }
.data-table td {
    /* Slightly tighter than before (was 10px 14px / 13px) so the wider
       Quotes + Proposals tables fit the extra "Last modified" column. */
    padding: 8px 10px; font-size: 12px; color: var(--tx);
    font-family: 'Nunito', 'Inter', system-ui, -apple-system, sans-serif;
    border-bottom: 1px solid #f1f5f9; vertical-align: middle;
}
.data-table tr:last-child td { border-bottom: none; }
/* Row hover = a light tint of the user's active theme colour (--teal is
   overridden per theme). Mixed with transparent so it reads as a faint wash
   over the white row, with rounded ends on the first/last cells. */
.data-table tbody tr:hover td { background: color-mix(in srgb, var(--teal) 9%, transparent); transition: background 0.12s; }
.data-table tbody tr:hover td:first-child { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
.data-table tbody tr:hover td:last-child  { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }

/* Scrollable table wrapper — caps height to ~7 rows and keeps the header
   pinned while the body scrolls. Used by the Customers registry. */
.registry-scroll {
    max-height: 320px;
    overflow-y: auto;
    border-radius: var(--r);
    border: 1px solid var(--border);
}
.registry-scroll .data-table { border: none; border-radius: 0; box-shadow: none; }
.registry-scroll .data-table thead th {
    position: sticky; top: 0; z-index: 1;
}
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table .mono {
    font-family: 'Nunito', 'Inter', system-ui, -apple-system, sans-serif;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}
.data-table .strong { font-weight: 600; color: var(--tx); }
/* ── Resizable columns (col-resize.js) ───────────────────────
   Handle sits on the right edge of each header cell. thead th is
   position:sticky (a positioned ancestor), so the absolute handle anchors to
   it without needing position:relative (which would break the sticky header). */
.col-resizer {
    position: absolute; top: 0; right: -4px; width: 9px; height: 100%;
    cursor: col-resize; z-index: 3; touch-action: none; user-select: none;
}
.col-resizer::after {
    content: ''; position: absolute; top: 25%; bottom: 25%; right: 4px;
    border-right: 2px solid transparent;
}
.col-resizer:hover::after { border-right-color: var(--teal); }
body.col-resizing, body.col-resizing .data-table { cursor: col-resize; user-select: none; }
/* Click-to-sort headers (col-sort.js) */
.data-table thead th.th-sortable { cursor: pointer; user-select: none; }
.data-table thead th.th-sortable:hover { color: var(--teal); }
.data-table thead th.th-sorted { color: var(--teal); }
.th-sort-arrow { font-size: 9px; }
/* Default truncate cap — tightened so text-heavy columns don't push the
   whole table past the viewport. Individual cells can still override via
   an inline style="max-width:..." if a specific column needs more room. */
.data-table .truncate { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Row-actions column — applies to every data-table's last cell. Flush against
   the table's right edge: width:1% + nowrap shrinks the column to its content
   width, so other columns soak up the slack; text-align:right + inline-block
   children push every button (and the visibility-hidden placeholders) to the
   right edge. We override the historical flex layout because flex containers
   ignore text-align and made the buttons drift to the left when the column
   was wider than its content. */
.data-table .row-actions {
    display: table-cell;
    text-align: right;
    white-space: nowrap;
    width: 1%;
    padding-right: 14px;
}
.data-table .row-actions > * {
    display: inline-block;
    vertical-align: middle;
    margin-left: 14px;
}
.data-table .row-actions > *:first-child {
    margin-left: 0;
}
/* Form wrappers (e.g. Deactivate's POST form) are direct children of
   .row-actions, so they pick up the universal 14px left-margin from the
   `> *` rule above. We DON'T reset margin here — doing so used to win on
   specificity and made the Deactivate button hug its left neighbour. */
.data-table .row-actions form { display: inline-block; }
/* Invisible same-width slot for a missing row-action button so columns
   stay vertically aligned across rows (e.g. Quotes' "→ Proposal" on
   Won/Lost rows). The label text still gets reserved width. */
.data-table .row-actions .row-action-placeholder {
    visibility: hidden;
    pointer-events: none;
    cursor: default;
}
/* Header for the actions column. Right-align to match the right-aligned
   action buttons in the data cells below; `.num` headers inherit the
   right-align from `.data-table .num` so they sit above their right-aligned
   numeric values. */
.data-table thead th:last-child {
    text-align: right;
    padding-right: 14px;
    white-space: nowrap;
}

/* Rep Groups table — the Count column (.num, right-aligned) sat too close
   to Actions because both ended at the right edge of their cells. Extra
   right-padding on Count pushes the "2" value leftward, creating a visual
   gap between Count and Actions that matches the spacing of the other
   columns. Padding-% on a table cell is calculated against the table width,
   so this scales naturally as the viewport (and table) widens / narrows. */
#rg-table thead th.num,
#rg-table tbody td.num {
    padding-right: 14%;
}

/* `.cell-truncate` is an alias for the existing `.truncate` so older code
   referencing either name behaves identically. Override max-width per cell
   with an inline style if a column needs more/less space. */
.data-table .cell-truncate {
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.data-table tr.task-done td { opacity: 0.55; text-decoration: line-through; }
.data-table tr.task-done td:first-child, .data-table tr.task-done .row-actions { text-decoration: none; opacity: 1; }
/* Tasks page: a row ticked for the Complete / Task-incomplete batch action. */
.data-table tr.row-selected td { background: var(--teal3); }
.data-table tr.row-selected td:first-child { box-shadow: inset 3px 0 0 var(--teal); }

/* Customers registry keeps its own boxed scroll (capped height + horizontal
   scroll inside the box). */
.registry-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Module grids (#grid-container) intentionally do NOT establish a scroll
   container — their table scrolls with the whole page, so the sticky header
   (.data-table thead th { top: -22.5px }) pins under the topbar exactly like
   the Pipeline tables. Trade-off: a very wide grid overflows into the page's
   own horizontal scroll instead of scrolling inside the container. */

/* Search-result row flash. Applied to a <tr data-row-id="..."> when the
   user clicks a search result and lands on the destination page. The row
   stays solid teal for 2 seconds, then fades over 0.5s. Total: 2.5s. */
@keyframes row-flash-anim {
    0%, 80%  { background-color: var(--teal3); }
    100%     { background-color: transparent; }
}
@keyframes row-flash-accent-anim {
    0%, 80%  { box-shadow: inset 3px 0 0 var(--teal); }
    100%     { box-shadow: inset 3px 0 0 transparent; }
}
.data-table tr.row-flash td { animation: row-flash-anim 2.5s ease-out; }
.data-table tr.row-flash td:first-child { animation: row-flash-anim 2.5s ease-out, row-flash-accent-anim 2.5s ease-out; }

/* settings table */
.settings-table input[type=text],
.settings-table input[type=number],
.settings-table select { width: 320px; padding: 7px 10px; border: 1.5px solid var(--border); border-radius: var(--rs); font-size: 13px; }

/* Dedicated settings card (used for single-purpose option groups that
   need richer UI than the generic key/value table — e.g. radio groups). */
.settings-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: 16px 20px;
    margin-bottom: 22px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03);
}
.settings-card h2 { margin: 0 0 4px; font-size: 14px; font-weight: 700; color: var(--tx); }
.settings-card > p { margin: 0 0 14px; font-size: 12.5px; }
.settings-radio-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.settings-radio {
    display: grid; grid-template-columns: 18px auto 1fr; align-items: baseline; gap: 6px 10px;
    padding: 8px 10px;
    border: 1px solid var(--border); border-radius: 8px;
    cursor: pointer; transition: border-color 0.12s, background 0.12s;
}
.settings-radio:hover { border-color: var(--teal); background: #f8fafc; }
.settings-radio input[type=radio] { margin: 0; accent-color: var(--teal); }
.settings-radio-label { font-weight: 600; color: var(--tx); font-size: 13px; }
.settings-radio-help { font-size: 12px; }
.settings-radio:has(input:checked) {
    border-color: var(--teal);
    background: var(--teal3);
}
.settings-table code { font-size: 11.5px; }

/* Logo upload card — preview tile on the left, file picker + reset on right */
.logo-upload-grid {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 20px;
    align-items: start;
}
.logo-upload-preview {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 14px;
    background: linear-gradient(180deg, #080f1e 0%, #0a1628 100%);
    border: 1px solid var(--border); border-radius: 12px;
}
.logo-upload-preview img {
    width: 96px; height: 96px;
    object-fit: contain; border-radius: 12px;
    background: #fff;
    box-shadow: 0 2px 8px rgba(0,0,0,0.25);
}
.logo-upload-preview .muted { color: rgba(255,255,255,0.55); text-align: center; }
.logo-upload-actions { display: flex; flex-direction: column; align-items: flex-start; }
.logo-upload-form {
    display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.logo-upload-form input[type=file] {
    font-size: 13px;
    padding: 6px 8px;
    border: 1.5px dashed var(--border); border-radius: 8px;
    background: #fff;
}

/* ── Pills ───────────────────────────────────────────────── */
.pill {
    display: inline-flex; align-items: center;
    padding: 3px 10px; border-radius: 20px;
    font-size: 11px; font-weight: 700; white-space: nowrap; letter-spacing: 0.2px;
    background: #e5e7eb; color: var(--tx2);
    box-shadow: inset 0 0 0 1px rgba(148,163,184,0.20);
}
.pill-green   { background: var(--green3);  color: #047857; box-shadow: inset 0 0 0 1px rgba(16,185,129,0.22); }
.pill-red     { background: var(--red3);    color: #be123c; box-shadow: inset 0 0 0 1px rgba(244,63,94,0.20); }
.pill-amber   { background: var(--amber3);  color: #b45309; box-shadow: inset 0 0 0 1px rgba(245,158,11,0.22); }
.pill-blue    { background: var(--blue3);   color: #1d4ed8; box-shadow: inset 0 0 0 1px rgba(59,130,246,0.20); }
.pill-neutral { background: #f1f5f9;        color: var(--tx2); box-shadow: inset 0 0 0 1px var(--border); }
.pill-purple  { background: rgba(124, 58, 237, 0.10); color: #6d28d9; box-shadow: inset 0 0 0 1px rgba(124,58,237,0.22); }

/* ── Modal ───────────────────────────────────────────────── */
.modal-overlay {
    position: fixed; inset: 0;
    background: rgba(6,13,26,0.65);
    backdrop-filter: blur(4px);
    z-index: 900;
    display: flex; align-items: flex-start; justify-content: center;
    padding: 60px 20px 20px;
    /* No overflow-y here — the .modal-card has its own scroll and a
       max-height that keeps it inside the viewport. The overlay itself
       never needs to scroll. */
}
.modal-overlay[hidden] { display: none; }

/* Lock every potential scroll container behind a modal so no scrollbar
   shows past the right edge of the card. We don't know up-front whether
   the page is scrolling on .content (authenticated layout), .main, html
   or body, so we shut them all. The body class is toggled by openModal /
   closeModal in common.js. */
html.modal-open, body.modal-open,
body.modal-open .main, body.modal-open .content {
    overflow: hidden !important;
}

/* Hide scrollbars everywhere while a modal is open — scrolling still
   works via mouse wheel / keyboard / touch. Belt-and-braces fallback for
   when overflow:hidden doesn't fully suppress a scrollbar (rare browser
   quirks, sub-pixel rounding, fixed-height ancestors that bypass the
   overflow lock). */
body.modal-open ::-webkit-scrollbar,
body.modal-open::-webkit-scrollbar { width: 0; height: 0; display: none; }
body.modal-open *,
body.modal-open { scrollbar-width: none; -ms-overflow-style: none; }

/* Hide the modal card's own scrollbar too — the card scrolls internally
   when its content exceeds max-height, but a visible bar inside the white
   card looks ugly. Scroll wheel still works. */
.modal-card { scrollbar-width: none; -ms-overflow-style: none; }
.modal-card::-webkit-scrollbar { width: 0; height: 0; display: none; }
.modal-card {
    background: var(--card);
    border-radius: 20px;
    width: 100%; max-width: 720px;
    max-height: calc(100vh - 80px);
    overflow-y: auto;
    border: 1px solid rgba(0,0,0,0.08);
    box-shadow: 0 32px 80px rgba(0,0,0,0.4), 0 8px 24px rgba(0,0,0,0.15);
    display: flex; flex-direction: column;
}
.modal-header {
    padding: 18px 22px 14px;
    border-bottom: 1px solid #f1f5f9;
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.modal-header h2 {
    margin: 0; font-size: 15px; font-weight: 800; color: var(--tx);
    flex: 1;
}
.modal-header .link-button {
    width: 28px; height: 28px;
    border-radius: 8px; background: #f1f5f9; color: var(--tx3);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 700;
}
.modal-header .link-button:hover { background: #e2e8f0; color: var(--tx2); text-decoration: none; }
.modal-card form, .modal-card .activity-feed { padding: 16px 22px; }
.modal-card form { max-width: none; }

/* ── File drop zone + list ───────────────────────────────── */
.file-drop {
    border: 2px dashed var(--border2);
    border-radius: var(--rs);
    padding: 16px; text-align: center;
    color: var(--tx2);
    transition: border-color .15s, background .15s;
}
.file-drop.drag-over {
    border-color: var(--teal);
    background: var(--teal3);
    color: var(--teal);
}
.file-drop p { margin: 0; }

.file-list { list-style: none; padding: 0; margin: 12px 0 0; display: flex; flex-direction: column; gap: 6px; }
.file-row {
    display: grid; grid-template-columns: 1fr auto auto;
    align-items: center; gap: 12px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--rs);
    background: #fafbfc;
    font-size: 12.5px;
}
.file-row.file-pending { border-style: dashed; }
.file-row .file-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-row .file-size { color: var(--tx3); font-size: 11.5px; }

/* ── Activity feed (inside the modal-card) ───────────────── */
.activity-feed {
    list-style: none;
    margin: 0;
    display: flex; flex-direction: column;
    gap: 0;
}
.activity-row {
    display: grid; grid-template-columns: 9px 1fr;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid #f1f5f9;
}
.activity-row:last-child { border-bottom: none; }
.activity-row::before {
    content: '';
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--teal);
    margin-top: 5px;
}
.activity-row > * { grid-column: 2; }
.activity-action {
    /* justify-self: start prevents the pill from stretching to fill the
       grid column. width: max-content sizes it to its text content even
       when the parent .activity-row is display: grid. */
    display: inline-block;
    justify-self: start;
    width: max-content;
    font-size: 10.5px; font-weight: 800;
    text-transform: uppercase; letter-spacing: 0.4px;
    color: var(--teal);
    margin-bottom: 3px;
    padding: 1px 7px;
    border-radius: 4px;
    background: var(--teal3);
}
.activity-detail { font-size: 13px; color: var(--tx); }
.activity-meta {
    font-size: 11px; color: var(--tx3); margin-top: 4px;
    display: flex; gap: 8px;
}

/* Action-kind colours — applied to the entire .activity-row so both the
   leading dot (::before) and the action pill stay in sync. Inferred from
   the action name in JS via actionKind(). */
.activity-row.kind-created::before { background: #059669; }
.activity-row.kind-created .activity-action {
    color: #047857; background: rgba(5,150,105,0.12);
}
.activity-row.kind-updated::before { background: #f59e0b; }
.activity-row.kind-updated .activity-action {
    color: #b45309; background: rgba(245,158,11,0.14);
}
.activity-row.kind-deleted::before { background: #dc2626; }
.activity-row.kind-deleted .activity-action {
    color: #b91c1c; background: rgba(220,38,38,0.12);
}
.activity-row.kind-other::before   { background: var(--teal); }

/* Activity Feed loading state — spinner + label centred in the empty list. */
.activity-feed .af-loading {
    display: flex; align-items: center; justify-content: center;
    gap: 10px;
    padding: 28px 16px;
    border-bottom: none;
}
.activity-feed .af-loading::before { display: none; } /* hide the leading dot during load */

/* ── Login card (auth-shell) ─────────────────────────────── */
.login-card {
    background: var(--card);
    padding: 32px;
    border: none;
    border-radius: 16px;
    width: 100%; max-width: 420px;
    /* Subtle teal halo — matches the Sign In button (#0d9488) */
    box-shadow:
        0 6px 16px rgba(15, 23, 42, 0.05),
        0 0 40px   rgba(13, 148, 136, 0.10),
        0 0 100px  rgba(20, 184, 166, 0.07);
    transition: box-shadow 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}
.login-card:hover {
    box-shadow:
        0 8px 20px rgba(15, 23, 42, 0.07),
        0 0 50px   rgba(13, 148, 136, 0.14),
        0 0 120px  rgba(20, 184, 166, 0.10);
}
.login-card h1 { margin: 0 0 16px; font-size: 22px; }

/* Modern circular teal checkbox — global */
.checkbox-row { gap: 10px; cursor: pointer; user-select: none; align-items: center; }
/* .form-row forces flex-direction:column; a checkbox row must stay horizontal
   and left-aligned (otherwise align-items:center centres the label). */
.form-row.checkbox-row { flex-direction: row; justify-content: flex-start; }
input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px; height: 18px;
    margin: 0 6px 0 0;
    border-radius: 50%;
    border: 1.5px solid #cbd5e1;
    background: #fff;
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    vertical-align: middle;
    transition: border-color 0.18s, background 0.18s, box-shadow 0.18s;
}
input[type="checkbox"]:hover:not(:disabled) { border-color: var(--teal); }
input[type="checkbox"]:checked {
    background: var(--teal);
    border-color: var(--teal);
    box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.18);
}
input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 5px; height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: translate(-50%, -62%) rotate(45deg);
}
input[type="checkbox"]:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.28);
}
input[type="checkbox"]:disabled {
    background: var(--bg);
    border-color: var(--border);
    cursor: not-allowed;
    opacity: 0.6;
}

/* ── Misc utility classes ────────────────────────────────── */
.muted { color: var(--tx3); }
.mono  { font-family: ui-monospace, 'DM Mono', Consolas, monospace; }
.module-list { padding-left: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.module-list li {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--rs);
    padding: 10px 14px;
    font-size: 13px;
}
.module-list li a { font-weight: 600; color: var(--tx); }
.module-list li a:hover { color: var(--teal); }

.footer { display: none; }  /* sidebar handles auth-bar; legacy footer hidden */

/* ── Dashboard (Phase 6c — v3 port) ──────────────────────────────────── */

/* Top toolbar: period tabs + rep filter + last-updated + refresh.
   flex-wrap: nowrap keeps every control on a single row. position: relative
   anchors the custom-range popover, which positions itself just below the
   toolbar. overflow stays visible so the popover isn't clipped. */
.d-topbar {
    position: relative;
    display: flex; align-items: center; gap: 12px; flex-wrap: nowrap;
    background: var(--card); border: 1px solid var(--border);
    border-radius: var(--rs); padding: 10px 14px; margin-bottom: 14px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03);
}
/* Don't let individual rows wrap their own contents either (e.g. REP: label
   stays beside its select). flex-shrink:0 stops the items from collapsing
   below their content width when the topbar is tight. */
.d-topbar > * { flex-shrink: 0; }
.d-topbar .d-spacer { flex: 1 1 auto; min-width: 0; }
.d-period-tabs {
    display: flex; background: var(--bg); border: 1px solid var(--border);
    border-radius: var(--rs); overflow: hidden;
}
.dash-period-btn {
    border: none; background: transparent; cursor: pointer;
    padding: 6px 14px; font: inherit; font-size: 12.5px; font-weight: 600;
    color: var(--tx2); transition: background 0.15s, color 0.15s;
}
.dash-period-btn:hover { color: var(--tx); }
.dash-period-btn.on {
    background: linear-gradient(135deg, var(--teal), #0891b2);
    color: #fff;
}
.d-rep-filter { display: flex; align-items: center; gap: 8px; font-size: 11.5px; }
.d-rep-filter select {
    padding: 6px 10px; border: 1.5px solid var(--border); border-radius: var(--rs);
    font-size: 12.5px; background: #fff;
}
.d-period-label, .d-updated { font-size: 11px; }
.d-spacer { flex: 1; }
.btn-sm { padding: 5px 12px; font-size: 12px; border-radius: 8px; }

/* 4-column KPI grid (8 cards = 2 rows on desktop, wraps on small screens) */
.d-kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 16px;
}
@media (max-width: 1100px) { .d-kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px)  { .d-kpi-grid { grid-template-columns: 1fr; } }
.d-kpi-skeleton {
    grid-column: 1 / -1;
    padding: 24px; text-align: center; color: var(--tx3);
    background: var(--card); border: 1px solid var(--border); border-radius: var(--r);
}
.d-kpi {
    position: relative;
    background: var(--card); border: 1px solid var(--border); border-radius: var(--r);
    padding: 14px 16px 12px;
    box-shadow:
        0 1px 2px  rgba(15, 23, 42, 0.03),
        0 1px 3px  rgba(15, 23, 42, 0.03);
    overflow: hidden;
    transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1), transform 0.18s ease;
    /* Reset button defaults so <button.d-kpi> looks identical to the original <div> */
    font: inherit; text-align: left; cursor: pointer; width: 100%; display: block;
    color: inherit;
}
.d-kpi:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--teal3), 0 1px 2px rgba(15,23,42,0.04); }
.d-kpi:active { transform: translateY(1px); }
.d-kpi:hover {
    box-shadow:
        0 1px 2px   rgba(15, 23, 42, 0.04),
        0 4px 10px  rgba(15, 23, 42, 0.06),
        0 16px 32px rgba(15, 23, 42, 0.05);
}
.d-kpi-top-bar {
    position: absolute; top: 0; left: 0; right: 0; height: 3px;
}
.d-kpi-label {
    font-size: 11px; font-weight: 700; color: var(--tx2);
    letter-spacing: 0.4px;
    margin-top: 6px;
}
.d-kpi-val {
    font-size: 28px; font-weight: 800; line-height: 1.1;
    margin: 4px 0 6px;
    font-family: 'Inter', sans-serif;
    letter-spacing: -0.5px;
}
.d-kpi-sub { font-size: 11.5px; color: var(--tx2); }
.d-kpi-footer {
    display: flex; align-items: flex-end; justify-content: space-between;
    margin-top: 10px; gap: 8px;
}
.d-kpi-delta {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 10px; border-radius: 999px;
    font-size: 10.5px; font-weight: 700; line-height: 1.4;
    letter-spacing: 0.2px; white-space: nowrap;
    background: #f1f5f9; color: var(--tx2);
    box-shadow: inset 0 0 0 1px var(--border);
    transition: background 0.18s, color 0.18s, box-shadow 0.18s;
}
.d-kpi-delta.up {
    background: var(--green3); color: #047857;
    box-shadow: inset 0 0 0 1px rgba(16,185,129,0.22);
}
.d-kpi-delta.down {
    background: var(--red3); color: #be123c;
    box-shadow: inset 0 0 0 1px rgba(244,63,94,0.20);
}
.d-kpi-delta.nt {
    background: #f1f5f9; color: var(--tx3);
    box-shadow: inset 0 0 0 1px var(--border);
}
.d-kpi-spark { flex-shrink: 0; }

/* Bottom row: funnel + activity rings (was funnel + gauge + activity rings —
   the gauge "Month-End Forecast" widget was removed at the user's request). */
.d-bottom-row {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 14px;
    margin-bottom: 18px;
}
@media (max-width: 1100px) { .d-bottom-row { grid-template-columns: 1fr; } }

/* 3-column variant used by the Pipeline page so Active pipeline by software,
   Lost reasons and Win rate by rep all sit on one line. */
.d-bottom-row--3col { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1100px) { .d-bottom-row--3col { grid-template-columns: 1fr; } }

/* The ⋮ "more" button sits to the right of the Custom period button and
   toggles the date-range popover. No outline/border in any state — just a
   subtle tinted background derived from the active theme's `--teal` variable
   via color-mix so the highlight follows the user's chosen colour theme
   (teal, purple, etc.). */
.d-period-more {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 6px 10px;
    font: inherit;
    font-size: 18px;
    line-height: 1;
    color: var(--tx2);
    border-left: 1px solid var(--border);
    outline: none;
    transition: background 0.15s, color 0.15s;
}
.d-period-more:hover { color: var(--teal); background: color-mix(in srgb, var(--teal) 10%, transparent); }
.d-period-more:focus,
.d-period-more:focus-visible {
    outline: none;
    color: var(--teal);
    background: color-mix(in srgb, var(--teal) 15%, transparent);
}
.d-period-more.on {
    color: var(--teal);
    background: color-mix(in srgb, var(--teal) 18%, transparent);
}

/* Custom date-range popover — anchored to the dashboard topbar (which has
   position: relative). Appears just below the topbar, aligned with the
   period-tabs on the left. Floats above the dashboard cards, no backdrop. */
.d-period-custom-popover {
    position: absolute;
    top: calc(100% + 4px);
    left: 14px;
    z-index: 30;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--rs);
    box-shadow: 0 6px 20px rgba(0,0,0,0.12);
    font-size: 12px;
    white-space: nowrap;
}
/* Explicit override — `display: inline-flex` above wins over the browser's
   default `[hidden] { display: none }` rule on specificity, so we need to
   restate it here for the hidden attribute to actually hide the popover. */
.d-period-custom-popover[hidden] { display: none; }
.d-period-custom-popover label {
    font-weight: 600;
    color: var(--tx2);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.d-period-custom-popover label + input[type="date"] { margin-right: 6px; }
/* Match the form-row input styling used by the proposals "Expected close date"
   field so the look is consistent across the app. */
.d-period-custom-popover input[type="date"] {
    padding: 9px 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--rs);
    font-size: 13px;
    font-family: inherit;
    color: var(--tx);
    background: #fff;
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.d-period-custom-popover input[type="date"]:focus { border-color: var(--teal); box-shadow: 0 0 0 2px rgba(13,148,136,0.18); }
.d-card {
    background: var(--card); border: 1px solid var(--border); border-radius: var(--r);
    padding: 14px 16px;
    box-shadow:
        0 1px 2px rgba(15, 23, 42, 0.03),
        0 1px 3px rgba(15, 23, 42, 0.03);
    transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.d-card:hover {
    box-shadow:
        0 1px 2px   rgba(15, 23, 42, 0.04),
        0 6px 16px  rgba(15, 23, 42, 0.06),
        0 24px 48px rgba(15, 23, 42, 0.06);
}
.d-card-hd {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 12px;
}
.d-card-hd h2 { margin: 0; font-size: 14px; }
.d-card-hd-badge { font-size: 10.5px; }
.d-card-center { display: flex; flex-direction: column; align-items: stretch; }

/* Bottom-row cards: stretch their content to fill the card height */
.d-bottom-row .d-card { display: flex; flex-direction: column; }
.d-bottom-row .d-card-hd { flex-shrink: 0; }

/* Funnel */
.d-funnel-wrap {
    display: flex; flex-direction: column; gap: 12px;
    flex: 1; justify-content: space-around;
}
.d-funnel-row {
    display: grid; grid-template-columns: 130px 1fr 60px;
    gap: 12px; align-items: center;
}
.d-funnel-label-col { line-height: 1.2; }
.d-funnel-stage-name { font-size: 12.5px; font-weight: 600; color: var(--tx); }
.d-funnel-stage-count { font-size: 10.5px; color: var(--tx3); }
.d-funnel-bar-wrap {
    background: #f1f5f9; border-radius: 8px; height: 36px;
    overflow: hidden; position: relative;
}
.d-funnel-bar {
    height: 100%; min-width: 0;
    display: flex; align-items: center; justify-content: flex-start;
    padding: 0 10px;
    color: #fff; font-size: 11px; font-weight: 700;
    transition: width 0.4s cubic-bezier(.4,0,.2,1);
    border-radius: 8px;
    /* Clip the value text so it never bleeds out of the coloured bar onto
       the light-grey track behind it (white-on-light is unreadable). */
    overflow: hidden; white-space: nowrap;
}
.d-funnel-bar-val { font-weight: 800; }
.d-funnel-conv {
    font-size: 11px; font-weight: 700; color: var(--tx2); text-align: right;
}
.d-funnel-total {
    margin-top: 14px; padding-top: 10px;
    border-top: 1px solid var(--border);
    font-size: 11.5px; color: var(--tx2);
}
.pill-pt { background: var(--teal3); color: var(--teal); box-shadow: inset 0 0 0 1px rgba(13,148,136,0.22); }

/* Gauge */
.d-gauge-wrap {
    display: flex; align-items: center; justify-content: center;
    padding: 12px 0;
    flex: 1;
}
/* Render at native size — scaling up made it blurry */
.d-gauge-wrap canvas { width: 200px; height: 120px; }
.d-gauge-stat-row {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: 8px; margin-top: auto;
}
.d-gauge-stat {
    background: var(--bg); border-radius: var(--rs);
    padding: 14px 10px; text-align: center;
}
.d-gauge-stat-val { font-size: 18px; font-weight: 800; line-height: 1.1; }
.d-gauge-stat-lbl {
    font-size: 11px; font-weight: 700; color: var(--tx3);
    text-transform: uppercase; letter-spacing: 0.5px; margin-top: 4px;
}

/* Activity rings */
.d-ring-grid { display: flex; flex-direction: column; gap: 8px; flex: 1; justify-content: space-between; }
.d-ring-card {
    display: flex; align-items: center; gap: 10px;
    background: var(--bg); border: 1px solid transparent; border-radius: var(--rs);
    padding: 8px 10px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.d-ring-card:hover { background: #fff; border-color: var(--border); }
.d-ring-card:active { transform: translateY(1px); }
.d-ring-card:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.d-ring-label { font-size: 12.5px; font-weight: 600; color: var(--tx); }
.d-ring-tgt { font-size: 9.5px; color: var(--tx3); }
.d-ring-right { text-align: right; }
.d-ring-num { font-size: 18px; font-weight: 800; line-height: 1; }
.d-ring-sub { font-size: 9.5px; color: var(--tx3); margin-top: 2px; }

/* ── 2-column row variant (charts, leaderboard + NCA) ───────────────── */
.d-bottom-row-2col { grid-template-columns: 1.4fr 1fr; }
@media (max-width: 1100px) { .d-bottom-row-2col { grid-template-columns: 1fr; } }

/* Empty-state — no widgets permitted */
.d-empty-state {
    background: var(--card); border: 1px solid var(--border); border-radius: var(--r);
    padding: 48px 24px;
    text-align: center;
    margin-top: 24px;
    box-shadow: 0 1px 3px rgba(15,23,42,0.04);
}
.d-empty-icon { font-size: 42px; opacity: 0.6; margin-bottom: 12px; }
.d-empty-state h2 { font-size: 18px; font-weight: 800; color: var(--tx); margin: 0 0 6px; }
.d-empty-state p  { font-size: 13px; line-height: 1.55; max-width: 480px; margin: 0 auto; }

/* Module-by-type widgets (Scheduling / Cold Calling) */
.d-mbt-tiles {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 8px;
    margin-bottom: 12px;
}
.d-mbt-tile {
    background: var(--bg); border-radius: var(--rs);
    padding: 10px 12px;
    transition: background 0.18s;
}
.d-mbt-tile:hover { background: #f1f5f9; }
.d-mbt-tile-val { font-size: 22px; font-weight: 800; line-height: 1.1; }
.d-mbt-tile-lbl {
    font-size: 10.5px; font-weight: 700; color: var(--tx3);
    text-transform: uppercase; letter-spacing: 0.4px;
    margin-top: 4px;
}
.d-mbt-bars { display: flex; flex-direction: column; gap: 6px; }
.d-mbt-bar-row {
    display: grid; grid-template-columns: 110px 1fr 40px; gap: 10px;
    align-items: center;
    font-size: 12px;
}
.d-mbt-bar-label { color: var(--tx2); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.d-mbt-bar-track {
    height: 16px;
    background: #f1f5f9;
    border-radius: 8px;
    overflow: hidden;
}
.d-mbt-bar-fill {
    height: 100%;
    border-radius: 8px;
    transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.d-mbt-bar-num { text-align: right; font-weight: 700; color: var(--tx); font-variant-numeric: tabular-nums; }

/* Chart legends (top-right of card header) */
.d-legend { display: flex; align-items: center; gap: 12px; font-size: 11px; color: var(--tx2); }
.d-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.d-legend-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.d-svg-wrap { width: 100%; }
.d-empty { padding: 32px 12px; text-align: center; color: var(--tx3); font-size: 12.5px; }

/* ── Leaderboard ─────────────────────────────────────────────────────── */
.d-leaderboard { display: flex; flex-direction: column; gap: 8px; }
.lb-row {
    display: grid;
    grid-template-columns: 36px 1fr 200px 50px;
    gap: 12px;
    align-items: center;
    padding: 8px 10px;
    border-radius: var(--rs);
    transition: background 0.15s;
}
.lb-row:hover { background: var(--bg); }
.lb-medal {
    font-size: 22px; line-height: 1;
    width: 36px; height: 36px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--bg); border-radius: 50%;
}
.lb-rank {
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--bg); color: var(--tx2);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 800;
}
.lb-name { font-size: 13.5px; font-weight: 700; color: var(--tx); }
.lb-sub  { font-size: 11px; color: var(--tx3); margin-top: 2px; }
.lb-sub-tag {
    display: inline-block; padding: 1px 6px; margin-right: 6px;
    background: var(--teal3); color: var(--teal); border-radius: 6px;
    font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px;
}
.lb-bar-col { min-width: 0; }
.lb-bar { height: 6px; background: #f1f5f9; border-radius: 999px; overflow: hidden; }
.lb-bar-fill { height: 100%; border-radius: 999px; transition: width 0.4s cubic-bezier(.4,0,.2,1); }
.lb-bar-meta { font-size: 10px; color: var(--tx3); margin-top: 4px; white-space: nowrap; }
.lb-pct { font-size: 13px; font-weight: 800; text-align: right; }
@media (max-width: 700px) {
    .lb-row { grid-template-columns: 36px 1fr 50px; gap: 8px; }
    .lb-bar-col { display: none; }
}

/* ── NCA vs Existing card ────────────────────────────────────────────── */
.d-nca-wrap {
    display: grid; grid-template-columns: 140px 1fr;
    gap: 18px; align-items: center;
    padding: 4px 0 8px;
}
.d-nca-donut svg { display: block; }
.d-nca-legend { display: flex; flex-direction: column; gap: 14px; }
.d-nca-legend-row { display: flex; gap: 10px; align-items: flex-start; }
.d-nca-dot {
    width: 10px; height: 10px; border-radius: 50%;
    margin-top: 6px; flex-shrink: 0;
}
.d-nca-legend-label { font-size: 12px; font-weight: 600; color: var(--tx2); }
.d-nca-legend-val   { font-size: 18px; font-weight: 800; line-height: 1.1; margin-top: 2px; }
.d-nca-legend-acc   { font-size: 10.5px; color: var(--tx3); margin-top: 2px; }

.d-nca-divider { height: 1px; background: var(--border); margin: 6px 0 12px; }
.d-nca-contrib-label {
    font-size: 10.5px; font-weight: 800; color: var(--tx3);
    text-transform: uppercase; letter-spacing: 0.6px;
    margin-bottom: 8px;
}
.d-nca-contrib { display: flex; flex-direction: column; gap: 6px; }
.d-nca-contrib-row {
    display: grid; grid-template-columns: 80px 1fr 60px;
    gap: 10px; align-items: center;
    font-size: 12px;
}
.d-nca-contrib-name { color: var(--tx2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.d-nca-contrib-bar  { height: 6px; background: #f1f5f9; border-radius: 999px; overflow: hidden; }
.d-nca-contrib-fill { height: 100%; border-radius: 999px; }
.d-nca-contrib-val  {
    text-align: right; font-family: ui-monospace, 'DM Mono', Consolas, monospace;
    font-size: 11px; color: var(--tx2);
}

/* ── Lookups admin grid ─────────────────────────────────── */
.lookup-cat {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r);
    margin-bottom: 14px;
    overflow: hidden;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03);
}
.lookup-cat-header {
    padding: 12px 16px;
    background: #f8fafc;
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between;
}
.lookup-cat-header h3 { margin: 0; font-size: 13px; }
.lookup-cat .data-table { border: none; border-radius: 0; box-shadow: none; }
.lookup-cat .data-table th { background: transparent; }

/* Lock column widths so every category's table has identical geometry —
   without this, each table auto-sizes from its widest cell so the SORT /
   ACTIVE columns drift left/right depending on the longest Display Name in
   that group. Edit and Delete each get their own column so they line up
   vertically across all categories. */
.lookup-cat .data-table { table-layout: fixed; }
.lookup-cat .data-table th:nth-child(1),
.lookup-cat .data-table td:nth-child(1) { width: 22%; }
.lookup-cat .data-table th:nth-child(2),
.lookup-cat .data-table td:nth-child(2) { width: 40%; }
.lookup-cat .data-table th:nth-child(3),
.lookup-cat .data-table td:nth-child(3) { width: 10%; }
.lookup-cat .data-table th:nth-child(4),
.lookup-cat .data-table td:nth-child(4) { width: 10%; }
.lookup-cat .data-table th:nth-child(5),
.lookup-cat .data-table td:nth-child(5) { width: 9%; }
.lookup-cat .data-table th:nth-child(6),
.lookup-cat .data-table td:nth-child(6) { width: 9%; }
/* Slightly tighter than the default 10px row padding, but with enough
   breathing room to read comfortably. Ellipsis on overflowing display names. */
.lookup-cat .data-table th { padding: 8px 14px; }
.lookup-cat .data-table td { padding: 8px 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lookup-cat .data-table td.lookup-action { overflow: visible; }

/* ── Global search modal ─────────────────────────────────── */
.search-overlay {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(3px);
    z-index: 1000;
    display: flex; justify-content: center; align-items: flex-start;
    padding: 100px 20px 20px;
    overflow-y: auto;
}
.search-overlay[hidden] { display: none; }
.search-card {
    background: var(--card);
    border-radius: 16px;
    width: 100%; max-width: 720px;
    box-shadow: 0 32px 80px rgba(0,0,0,0.30), 0 8px 24px rgba(0,0,0,0.12);
    border: 1px solid var(--border);
    overflow: hidden;
    display: flex; flex-direction: column;
    max-height: calc(100vh - 140px);
}

.search-input-row {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 18px;
    border-bottom: 1px solid #f1f5f9;
}
.search-icon { font-size: 16px; color: var(--tx3); }
#search-input {
    flex: 1; border: none; outline: none; background: transparent;
    font: inherit; font-size: 15px; color: var(--tx);
    min-width: 0;
    /* contenteditable styling */
    line-height: 1.4;
    white-space: pre;
    overflow-x: auto;
    overflow-y: hidden;
}
#search-input:empty::before {
    content: attr(data-placeholder);
    color: var(--tx3);
    pointer-events: none;
}
#search-input::-webkit-scrollbar { display: none; }

/* Hidden honeypots that absorb Chrome's password-manager autofill */
.ss-honeypot {
    position: absolute !important;
    left: -9999px !important;
    top: -9999px !important;
    width: 1px !important; height: 1px !important;
    opacity: 0 !important; pointer-events: none !important;
}
.search-esc {
    font-size: 11px; font-weight: 600; color: var(--teal);
    letter-spacing: 0.3px;
}

.search-results { overflow-y: auto; padding: 6px 0; }
.search-hint {
    text-align: center; padding: 28px 16px;
    color: var(--teal); font-size: 13px; font-weight: 500;
}
.search-hint-loading {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    color: var(--tx2);
}

.search-group-label {
    font-size: 10.5px; font-weight: 800;
    color: var(--tx3); text-transform: uppercase; letter-spacing: 0.6px;
    padding: 12px 18px 4px;
}
.search-result {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 18px;
    text-decoration: none; color: inherit;
    border-left: 3px solid transparent;
    transition: background 0.10s, border-color 0.10s;
}
.search-result:hover, .search-result.on {
    background: var(--teal3);
    border-left-color: var(--teal);
    text-decoration: none;
}
.search-result-icon {
    flex-shrink: 0;
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--tx2);
}
.search-result-icon svg { display: block; }

/* Customer/company type-ahead dropdown (customer-autocomplete.js). Fixed-
   positioned + high z-index so it floats above the record modal. */
.sp-ac-menu {
    position: fixed;
    z-index: 10010;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18);
    max-height: 240px;
    overflow-y: auto;
    padding: 4px;
}
.sp-ac-menu[hidden] { display: none; }
.sp-ac-option {
    padding: 8px 10px;
    border-radius: 6px;
    font-size: 13px;
    color: var(--tx);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sp-ac-option:hover,
.sp-ac-option.on {
    background: color-mix(in srgb, var(--teal) 12%, transparent);
    color: var(--teal);
}
.search-result-body { flex: 1; min-width: 0; }
.search-result-title {
    font-weight: 600; font-size: 13.5px; color: var(--tx);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-result-sub {
    font-size: 11.5px; color: var(--tx3);
    margin-top: 2px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-family: ui-monospace, 'DM Mono', Consolas, monospace;
}
.search-result-go {
    font-size: 11px; color: var(--teal); font-weight: 600;
    flex-shrink: 0;
    white-space: nowrap;
}

/* ── Anthropic API Key modal ───────────────────────────────────────── */
.ak-overlay {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(2px);
    display: flex; align-items: center; justify-content: center;
    z-index: 1000;
    padding: 20px;
}
.ak-overlay[hidden] { display: none; }
.ak-card {
    background: #fff;
    border-radius: 18px;
    box-shadow: 0 30px 80px rgba(15, 23, 42, 0.30), 0 8px 24px rgba(15, 23, 42, 0.10);
    width: 100%; max-width: 600px;
    display: flex; flex-direction: column;
    overflow: hidden;
}
.ak-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 22px 24px 16px;
}
.ak-head h2 {
    margin: 0;
    font-size: 17px; font-weight: 800; color: var(--tx);
}
.ak-close {
    width: 32px; height: 32px; border-radius: 8px;
    background: var(--bg); border: 1px solid var(--border);
    color: var(--tx2); font-size: 18px; line-height: 1;
    cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.ak-close:hover { background: #fff; color: var(--tx); border-color: var(--teal); }

.ak-body { padding: 0 24px 4px; }

.ak-info {
    background: #eef2ff;
    border: 1px solid #e0e7ff;
    border-radius: 12px;
    padding: 14px 16px;
    color: #334155;
    font-size: 13px; line-height: 1.55;
}
.ak-info p { margin: 0; }
.ak-info p + p { margin-top: 10px; }
.ak-info a { color: #2563eb; font-weight: 600; }
.ak-info a:hover { text-decoration: underline; }
.ak-info strong { font-weight: 700; color: var(--tx); }

.ak-label {
    display: block;
    margin: 18px 0 6px;
    font-size: 12.5px; font-weight: 700; color: var(--tx);
}
.ak-input {
    width: 100%;
    padding: 11px 14px;
    border: 1.5px solid var(--teal);
    border-radius: 10px;
    font: inherit; font-size: 13px;
    color: var(--tx);
    background: #fff;
    box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.10);
    outline: none;
}
.ak-input::placeholder { color: var(--tx3); font-family: ui-monospace, 'DM Mono', Consolas, monospace; }

.ak-hint {
    margin: 10px 0 4px;
    font-size: 12px; color: var(--tx3);
    line-height: 1.55;
}
.ak-hint-ico { font-size: 11px; margin-right: 4px; }
.ak-hint code {
    background: var(--bg);
    border: 1px solid var(--border); border-radius: 4px;
    padding: 1px 6px; font-size: 11px;
    color: var(--tx2);
}

.ak-msg {
    margin-top: 10px;
    padding: 8px 12px; border-radius: 8px;
    font-size: 12.5px; font-weight: 500;
}
.ak-msg.ok  { background: var(--green3); color: #047857; border: 1px solid rgba(16,185,129,0.25); }
.ak-msg.err { background: var(--red3);   color: #be123c; border: 1px solid rgba(244,63,94,0.22); }

.ak-foot {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 16px 24px 22px;
}

/* ── Import Excel page ────────────────────────────────────────────── */
.imp-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 18px 20px;
    margin-bottom: 16px;
    box-shadow: 0 1px 3px rgba(15,23,42,0.04);
}
.imp-section-title {
    font-size: 15px; font-weight: 700; color: var(--tx);
    margin: 0 0 8px;
}

/* Drop zone */
.imp-dropzone {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 6px;
    padding: 36px 24px;
    border: 2px dashed #cbd5e1;
    border-radius: 14px;
    background: #f8fafc;
    cursor: pointer;
    transition: border-color 0.18s, background 0.18s, transform 0.05s;
    text-align: center;
}
.imp-dropzone:hover, .imp-dropzone:focus-visible {
    border-color: var(--teal);
    background: #f0fdfa;
    outline: none;
}
.imp-dropzone.dragging {
    border-color: var(--teal);
    background: #ecfdf5;
    box-shadow: inset 0 0 0 4px rgba(13,148,136,0.10);
}
.imp-dropzone-ico { font-size: 32px; line-height: 1; }
.imp-dropzone-title { font-weight: 600; color: var(--tx); font-size: 14px; }
.imp-dropzone-title u { text-decoration: underline; color: var(--teal); }
.imp-dropzone-sub { color: var(--tx3); font-size: 12px; }

/* Pending file list */
.imp-pending-files { margin-top: 14px; }
.imp-pending-hd { font-size: 12px; font-weight: 700; color: var(--tx2); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; }
.imp-pending-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.imp-pending-list li {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 13px;
}
.imp-pending-ico { font-size: 14px; flex-shrink: 0; }
.imp-pending-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--tx); font-weight: 500; }
.imp-pending-size { color: var(--tx3); font-size: 11.5px; flex-shrink: 0; }
.imp-pending-remove {
    width: 22px; height: 22px; border-radius: 50%;
    background: #fff; border: 1px solid var(--border);
    color: var(--tx2); font-size: 14px; line-height: 1;
    cursor: pointer; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
}
.imp-pending-remove:hover { background: #fef2f2; color: #be123c; border-color: rgba(244,63,94,0.3); }

.imp-actions {
    display: flex; justify-content: flex-end; gap: 8px;
    margin-top: 14px;
}

/* Module reference grid — always 6 columns sharing the row equally.
   minmax(0, 1fr) prevents content (long module names) from forcing a column
   wider than its share, so the row never wraps regardless of screen width. */
.imp-module-grid {
    display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 10px; margin-top: 10px;
}
.imp-module {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 12px;
    display: flex; flex-direction: column; gap: 6px;
    min-width: 0;          /* allow children to shrink below their intrinsic width */
}
.imp-module-hd { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-width: 0; }
.imp-module-name { font-weight: 700; color: var(--tx); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.imp-module-meta { color: var(--tx3); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.imp-template-link {
    color: var(--teal); font-size: 12px; font-weight: 600;
    margin-top: 4px;
}
.imp-template-link:hover { text-decoration: underline; }

/* Info icon + tooltip */
.imp-info-ico {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px;
    border-radius: 50%;
    background: var(--teal3);
    color: var(--teal);
    font-size: 12px; font-weight: 700;
    cursor: help;
}
.imp-info-ico:hover, .imp-info-ico:focus-visible { background: var(--teal); color: #fff; outline: none; }

.imp-tip {
    /* Fixed-positioned via JS on hover (escapes .main { overflow: hidden }). */
    position: fixed;
    top: 0; left: 0;
    width: 620px; max-width: calc(100vw - 32px);
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 10px 32px rgba(15,23,42,0.18), 0 4px 10px rgba(15,23,42,0.08);
    padding: 14px 16px;
    z-index: 9999;
    visibility: hidden; opacity: 0; transform: translateY(-4px);
    transition: opacity 0.14s, transform 0.14s, visibility 0.14s;
    pointer-events: none;
    text-align: left;
    font-weight: 400;
}
/* Visibility is now controlled by JS in Views/Import/Index.cshtml so the
   tooltip can use position:fixed and escape .main { overflow:hidden }. */

.imp-tip-title { font-weight: 700; font-size: 13px; color: var(--tx); margin-bottom: 6px; }
.imp-tip-note { color: var(--tx2); font-size: 11.5px; line-height: 1.5; margin-bottom: 10px; }
.imp-tip-table-wrap {
    overflow-x: auto;
    margin-bottom: 10px;
    border-radius: 6px;
}
.imp-tip-table {
    border-collapse: collapse;
    font-size: 11px;
    width: max-content;
    min-width: 100%;
}
.imp-tip-table th {
    background: var(--teal); color: #fff;
    padding: 5px 8px;
    text-align: left;
    font-weight: 700;
    border: 1px solid var(--teal);
    white-space: nowrap;
}
.imp-tip-table td {
    padding: 5px 8px;
    background: var(--bg);
    border: 1px solid var(--border);
    white-space: nowrap;
    color: var(--tx2);
}
.imp-tip-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px; }
.imp-tip-field {
    border-top: 1px dashed var(--border);
    padding-top: 6px;
    font-size: 11.5px;
}
.imp-tip-field-name { font-weight: 600; color: var(--tx); }
.imp-tip-field-type {
    color: var(--tx3); font-size: 10.5px;
    margin-left: 5px; font-family: ui-monospace, monospace;
}
.imp-tip-field-syn { color: var(--tx3); font-size: 10.5px; margin-top: 2px; }
.imp-tip-field-syn-lbl { color: var(--tx2); font-weight: 600; }

/* Caps Lock tooltip — floats above the focused password input */
.caps-lock-tip {
    position: absolute;
    background: #1f2937;
    color: #fff;
    font-size: 11.5px;
    font-weight: 600;
    padding: 5px 9px;
    border-radius: 6px;
    box-shadow: 0 4px 10px rgba(15,23,42,0.25);
    pointer-events: none;
    opacity: 0;
    transform: translateY(2px);
    transition: opacity 0.12s, transform 0.12s;
    z-index: 10000;
    white-space: nowrap;
}
.caps-lock-tip.is-visible { opacity: 1; transform: translateY(0); }
.caps-lock-tip::after {
    content: ''; position: absolute; right: 12px; bottom: -5px;
    width: 0; height: 0;
    border-left: 5px solid transparent; border-right: 5px solid transparent;
    border-top: 5px solid #1f2937;
}

/* File preview cards */
.imp-file-card { border-left: 4px solid var(--teal); }
.imp-file-hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }

.imp-sheet-card {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 16px;
    margin-top: 12px;
}
.imp-sheet-hd {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}
.imp-sheet-name { font-weight: 700; color: var(--tx); font-size: 14px; }

.imp-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 10px; border-radius: 999px;
    font-size: 11px; font-weight: 700;
    background: var(--bg); color: var(--tx2);
    box-shadow: inset 0 0 0 1px var(--border);
}
.imp-pill-strong { background: var(--green3); color: #047857; box-shadow: inset 0 0 0 1px rgba(16,185,129,0.3); }
.imp-pill-mid    { background: var(--amber3); color: #b45309; box-shadow: inset 0 0 0 1px rgba(245,158,11,0.3); }
.imp-pill-weak   { background: var(--red3);   color: #be123c; box-shadow: inset 0 0 0 1px rgba(244,63,94,0.25); }

.imp-sheet-row {
    display: flex; align-items: center; gap: 10px;
    margin-top: 8px;
    flex-wrap: wrap;
}
.imp-sheet-lbl { font-size: 12px; font-weight: 600; color: var(--tx2); min-width: 80px; }
.imp-sheet-row select {
    padding: 6px 10px;
    border: 1px solid var(--border); border-radius: 8px;
    background: #fff; color: var(--tx);
    font: inherit; font-size: 12.5px;
    min-width: 200px;
}
.imp-sheet-row select:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal3); }
.imp-sheet-dup-help { font-size: 11.5px; }

.imp-sheet-stats {
    display: flex; gap: 18px; flex-wrap: wrap;
    margin-top: 10px;
    font-size: 12px; color: var(--tx2);
}
.imp-stat-ok   { color: #047857; }
.imp-stat-err  { color: #be123c; }
.imp-stat-warn { color: #b45309; }
.imp-stat-dup  { color: #d97706; font-weight: 600; }

/* Sample preview table */
.imp-sample-wrap {
    margin-top: 12px;
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
}
.imp-sample-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}
.imp-sample-table th {
    background: var(--bg);
    padding: 8px 10px;
    text-align: left;
    font-weight: 700;
    color: var(--tx);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.imp-sample-table td {
    padding: 6px 10px;
    border-bottom: 1px solid #f1f5f9;
    color: var(--tx);
    vertical-align: top;
}
.imp-sample-table tr:last-child td { border-bottom: none; }
.imp-mapped-to {
    font-size: 10px; font-weight: 500; color: var(--teal);
    font-family: ui-monospace, monospace;
    margin-top: 2px;
}
.imp-req { color: #be123c; font-weight: 700; }
.imp-sample-rownum { color: var(--tx3); font-family: ui-monospace, monospace; font-size: 11px; }
.imp-row-ok { background: #fff; }
.imp-row-err { background: #fef2f2; }
/* Duplicate rows — softer amber tint so they're distinguishable from
   validation-error rows (red) but still draw the eye. */
.imp-row-dup { background: #fff7ed; }
.imp-dup-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: 0.4px;
    border-radius: 4px;
    background: #f59e0b;
    color: #fff;
}
.imp-issue-dup { color: #b45309; font-style: italic; }
.imp-cell-err {
    background: rgba(244,63,94,0.12);
    color: #be123c;
    font-weight: 600;
    cursor: help;
}
.imp-issue {
    font-size: 11px; line-height: 1.4;
    padding: 2px 0;
}
.imp-issue-error   { color: #be123c; }
.imp-issue-warning { color: #b45309; }
.imp-sample-issues { max-width: 280px; }

.imp-unmapped {
    margin-top: 10px;
    padding: 8px 12px;
    background: var(--amber3);
    border: 1px solid rgba(245,158,11,0.22);
    border-radius: 8px;
    color: #92400e;
    font-size: 11.5px;
}

/* Commit bar */
.imp-commit-bar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    position: sticky; bottom: 12px;
    border: 1px solid var(--teal);
    background: linear-gradient(180deg, #ffffff, #f0fdfa);
    box-shadow: 0 8px 20px rgba(13,148,136,0.12);
}
.imp-commit-msg { color: var(--tx2); font-size: 13px; flex: 1; min-width: 240px; }

/* Right-hand group of the commit bar — holds the skip-invalid toggle (when
   shown) next to the Commit button. flex keeps them on one line; gap gives
   the toggle some breathing room from the button. */
.imp-commit-actions {
    display: flex; align-items: center; gap: 14px;
    flex-wrap: nowrap;
}
.imp-skip-toggle {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--tx2);
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
    transition: border-color 0.12s, background 0.12s;
}
.imp-skip-toggle:hover { border-color: var(--teal); background: #f8fafc; }
.imp-skip-toggle input[type=checkbox] { margin: 0; accent-color: var(--teal); }
.imp-skip-toggle:has(input:checked) {
    border-color: var(--teal);
    background: var(--teal3);
    color: var(--tx);
}

/* Result table */
.imp-result-file { margin-top: 12px; }
.imp-result-fname { font-weight: 700; color: var(--tx); margin-bottom: 6px; }
.imp-result-table { font-size: 12.5px; }
.imp-result-table th, .imp-result-table td { padding: 6px 10px; }

/* Recent imports */
.imp-recent-wrap { overflow-x: auto; }
.imp-recent-table { font-size: 12.5px; min-width: 880px; }
.imp-recent-table th { background: var(--bg); }
.imp-recent-table td, .imp-recent-table th { padding: 8px 10px; vertical-align: top; }
.imp-num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--tx); }
.imp-recent-sheets { display: flex; flex-direction: column; gap: 2px; }
.imp-recent-sheet { font-size: 12px; color: var(--tx); }
.imp-recent-sheet .muted { font-size: 11px; margin-left: 4px; }

.imp-status {
    display: inline-block;
    padding: 2px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.4px;
}
.imp-status-committed { background: var(--green3); color: #047857; box-shadow: inset 0 0 0 1px rgba(16,185,129,0.25); }
.imp-status-pending   { background: var(--amber3); color: #b45309; box-shadow: inset 0 0 0 1px rgba(245,158,11,0.25); }
.imp-status-cancelled { background: #f1f5f9;       color: var(--tx3); box-shadow: inset 0 0 0 1px var(--border); }
.imp-status-failed    { background: var(--red3);   color: #be123c; box-shadow: inset 0 0 0 1px rgba(244,63,94,0.22); }

/* ── Slim Select (custom <select> replacement) ─────────────────────── */
.ss-wrap {
    position: relative;
    /* min-width chosen to match the existing select metric in most forms */
    min-width: 140px;
    vertical-align: middle;
}
/* The native select stays in the DOM (hidden) so forms still submit & change events fire. */
.ss-native {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    border: 0 !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

/* Visible button */
.ss-btn {
    display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
    width: 100%;
    padding: 7px 12px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 8px;
    font: inherit; font-size: 13px;
    color: var(--tx);
    cursor: pointer;
    text-align: left;
    line-height: 1.3;
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.ss-btn:hover:not(:disabled) { border-color: var(--teal); }
.ss-btn:focus-visible       { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal3); }
.ss-btn:disabled            { background: var(--bg); color: var(--tx3); cursor: not-allowed; }
.ss-wrap.ss-open .ss-btn    { border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal3); }

.ss-btn-label {
    flex: 1;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ss-btn-label.ss-placeholder { color: var(--tx3); }
.ss-caret {
    color: var(--tx2); font-size: 14px; line-height: 1; flex-shrink: 0;
    font-weight: 700;
    margin-left: 4px;
    transition: transform 0.18s, color 0.15s;
}
.ss-btn:hover .ss-caret { color: var(--teal); }
.ss-wrap.ss-open .ss-caret { color: var(--teal); transform: rotate(180deg); }

/* Dropdown panel — position:fixed so it escapes any overflow:hidden ancestor
   (e.g. inside modals). JS positions top/left from the button's bounding rect. */
.ss-panel {
    position: fixed;
    top: 0; left: 0;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow:
        0 6px 16px rgba(15, 23, 42, 0.08),
        0 12px 32px rgba(15, 23, 42, 0.10);
    padding: 4px;
    z-index: 1100;
    max-height: 280px;
    overflow-y: auto;
    white-space: nowrap;
}

/* Items */
.ss-item {
    padding: 7px 12px;
    border-radius: 8px;
    font-size: 13px;
    color: var(--tx);
    cursor: pointer;
    user-select: none;
    transition: background 0.12s, color 0.12s;
    line-height: 1.3;
}
.ss-item + .ss-item { margin-top: 1px; }

/* Hover OR keyboard-active — light teal tint with teal text */
.ss-item:hover,
.ss-item.ss-item-active {
    background: var(--teal3);
    color: var(--teal);
}

/* Currently-selected option — full teal with white text + bold */
.ss-item.ss-item-selected {
    background: var(--teal);
    color: #fff;
    font-weight: 600;
}
.ss-item.ss-item-selected:hover,
.ss-item.ss-item-selected.ss-item-active {
    background: var(--teal);
    color: #fff;
}

.ss-item.ss-item-disabled {
    color: var(--tx3); cursor: not-allowed; opacity: 0.7;
}
.ss-item.ss-item-disabled:hover {
    background: transparent; color: var(--tx3);
}

/* Multi-select variant: each item has a circular teal checkbox indicator. */
.ss-wrap.ss-multi .ss-item {
    display: flex; align-items: center; gap: 10px;
}
.ss-checkbox {
    width: 18px; height: 18px;
    border: 1.5px solid #cbd5e1;
    border-radius: 50%;
    background: #fff;
    flex-shrink: 0;
    position: relative;
    transition: border-color 0.18s, background 0.18s, box-shadow 0.18s;
}
.ss-wrap.ss-multi .ss-item:hover .ss-checkbox { border-color: var(--teal); }
.ss-wrap.ss-multi .ss-item.ss-item-checked .ss-checkbox {
    background: var(--teal);
    border-color: var(--teal);
    box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.18);
}
.ss-wrap.ss-multi .ss-item.ss-item-checked .ss-checkbox::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 5px; height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: translate(-50%, -62%) rotate(45deg);
}
/* In multi mode the row itself stays transparent — only the checkbox shows state */
.ss-wrap.ss-multi .ss-item.ss-item-checked { background: transparent; color: var(--tx); font-weight: 500; }
.ss-wrap.ss-multi .ss-item.ss-item-checked:hover,
.ss-wrap.ss-multi .ss-item.ss-item-checked.ss-item-active { background: var(--teal3); color: var(--teal); }
.ss-item-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Custom thin scrollbar inside the panel */
.ss-panel::-webkit-scrollbar { width: 8px; }
.ss-panel::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.ss-panel::-webkit-scrollbar-thumb:hover { background: #cbd5e1; }

/* ── Custom dialog (alert/confirm replacement) ─────────────────────── */
.sp-dlg-overlay {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(2px);
    display: flex; align-items: center; justify-content: center;
    z-index: 10000;
    padding: 20px;
    opacity: 0;
    transition: opacity 0.16s ease;
}
.sp-dlg-overlay.sp-dlg-shown { opacity: 1; }

.sp-dlg-card {
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 30px 80px rgba(15, 23, 42, 0.30), 0 8px 24px rgba(15, 23, 42, 0.10);
    width: 100%; max-width: 460px;
    transform: translateY(8px) scale(0.98);
    transition: transform 0.16s ease;
    overflow: hidden;
    /* subtle teal accent at top */
    border-top: 3px solid var(--teal);
}
.sp-dlg-overlay.sp-dlg-shown .sp-dlg-card { transform: translateY(0) scale(1); }

.sp-dlg-title {
    padding: 18px 22px 8px;
    font-size: 16px; font-weight: 700; color: var(--tx);
}
.sp-dlg-body {
    padding: 0 22px 18px;
    font-size: 13.5px; color: var(--tx2); line-height: 1.55;
    max-height: 60vh; overflow-y: auto;
}
.sp-dlg-foot {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 14px 22px 18px;
    border-top: 1px solid var(--border);
    background: var(--bg);
}
.sp-dlg-btn { min-width: 90px; }
.sp-dlg-btn.sp-dlg-danger {
    background: linear-gradient(180deg, #f43f5e, #be123c);
    box-shadow: 0 2px 8px rgba(244,63,94,0.35), 0 1px 2px rgba(0,0,0,0.10);
}
.sp-dlg-btn.sp-dlg-danger:hover { box-shadow: 0 4px 16px rgba(244,63,94,0.45); }

/* ── Button busy state (spinner overlay, button keeps original size) ─── */
.is-busy {
    position: relative;
    color: transparent !important;
    pointer-events: none;
    cursor: wait;
}
.is-busy > * { visibility: hidden; }
.is-busy::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 16px; height: 16px;
    margin: -8px 0 0 -8px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    color: #fff;             /* spinner colour for filled buttons */
    opacity: 0.95;
    visibility: visible;
    animation: sp-spin 0.7s linear infinite;
}
.btn-secondary.is-busy::after,
.link-button.is-busy::after { color: var(--teal); }

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

/* ── Toast notifications (Common.showToast) ───────────────────────────────
   Stacked top-right. Click to dismiss, auto-dismisses after a few seconds.
   Sits above modal overlays (z-index > .modal-overlay's 900) so form
   submit errors are still visible while a modal is open. */
.sp-toast-container {
    position: fixed; top: 16px; right: 16px;
    z-index: 1100;
    display: flex; flex-direction: column; gap: 8px;
    max-width: calc(100vw - 32px);
    pointer-events: none;
}
.sp-toast {
    pointer-events: auto;
    min-width: 280px; max-width: 460px;
    padding: 11px 14px;
    border-radius: 10px;
    font-size: 13px; line-height: 1.4; font-weight: 500;
    box-shadow: 0 8px 24px rgba(0,0,0,0.16), 0 2px 6px rgba(0,0,0,0.08);
    background: #fff; color: var(--tx);
    border-left: 4px solid var(--teal);
    cursor: pointer;
    opacity: 0; transform: translateX(8px);
    transition: opacity 0.18s ease-out, transform 0.18s ease-out;
}
.sp-toast.sp-toast-in  { opacity: 1; transform: translateX(0); }
.sp-toast.sp-toast-out { opacity: 0; transform: translateX(8px); }
.sp-toast-error   { border-left-color: #dc2626; background: #fef2f2; color: #7f1d1d; }
.sp-toast-success { border-left-color: #059669; background: #f0fdf4; color: #14532d; }
.sp-toast-info    { border-left-color: #2563eb; background: #eff6ff; color: #1e3a8a; }

/* Generic spinner element (used inline, e.g. search loading) */
.sp-spinner {
    display: inline-block;
    width: 14px; height: 14px;
    border-radius: 50%;
    border: 2px solid var(--teal);
    border-top-color: transparent;
    animation: sp-spin 0.7s linear infinite;
    vertical-align: middle;
}

/* ── Dashboard KPI drill-down modal ──────────────────────────────────── */
.dkd-overlay {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(2px);
    display: flex; align-items: center; justify-content: center;
    z-index: 9000;
    padding: 24px;
}
.dkd-overlay[hidden] { display: none; }

.dkd-card {
    background: #fff;
    border-radius: 16px;
    /* Top strip is recoloured per-card via inline style set in JS — falls
       back to teal for any caller that doesn't pass a colour. */
    border-top: 3px solid var(--teal);
    box-shadow: 0 30px 80px rgba(15, 23, 42, 0.30), 0 8px 24px rgba(15, 23, 42, 0.10);
    width: 100%; max-width: 1100px; max-height: 86vh;
    display: flex; flex-direction: column;
    overflow: hidden;
}
.dkd-head {
    padding: 18px 22px 14px;
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.dkd-title   { font-size: 16px; font-weight: 800; color: var(--tx); }
.dkd-summary { font-size: 12.5px; color: var(--tx2); margin-top: 4px; line-height: 1.5; }
.dkd-close {
    width: 32px; height: 32px; border-radius: 8px;
    background: var(--bg); border: 1px solid var(--border);
    color: var(--tx2); font-size: 18px; line-height: 1;
    cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.dkd-close:hover { background: #fff; color: var(--tx); border-color: var(--teal); }

/* Sparkline hover tooltip — fixed-positioned, follows the cursor over any
   .d-spark SVG on the page. The marker dot + dashed guide line are drawn
   inside the SVG by dashboard.js. */
.d-spark-tip {
    position: fixed;
    z-index: 10000;
    background: #0f172a;
    color: #fff;
    padding: 4px 9px;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
    letter-spacing: 0.2px;
}
.d-spark-tip[hidden] { display: none; }
.d-spark { cursor: crosshair; }
/* Big dashboard charts share the same hover-tooltip system. */
#d-revenue-chart svg,
#d-winrate-chart svg { cursor: crosshair; }

/* ── Page-loading overlay ────────────────────────────────────────────
   Shown on sidebar navigation clicks to smooth over the white flash
   browsers sometimes show between server-rendered pages. The sidebar
   stays visible at all times — the overlay covers only the main content
   area to its right. Visibility is driven by the .page-loading class on
   <html>; the preload script in _Layout.cshtml's <head> adds it as soon
   as a stored timestamp is detected, and a DOMContentLoaded handler
   removes it after a 1500ms minimum so even fast pages get the polished
   loading state. */
.page-loader-overlay {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    left: 0; /* default — covers the whole viewport (auth pages w/o sidebar) */
    background: rgba(248, 250, 252, 0.94);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    z-index: 99999;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 14px;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    /* Delay the visibility transition so the overlay stays interactive
       while opacity fades out, then disappears completely. */
    transition: opacity 0.25s ease, visibility 0s linear 0.25s,
                left 0.35s cubic-bezier(0.65, 0, 0.35, 1);
}
/* On the authenticated app shell, the overlay covers only the main content
   area — sidebar and topbar stay fully visible and interactive. left skips
   past the sidebar (var(--sidebar-w) or 64px when collapsed); top skips
   past the topbar (var(--header-h)). */
body.app-shell .page-loader-overlay {
    left: var(--sidebar-w);
    top:  var(--header-h);
}
html.sb-collapsed body.app-shell .page-loader-overlay {
    left: 64px;
}
html.page-loading .page-loader-overlay {
    opacity: 1;
    visibility: visible;
    pointer-events: all;
    transition: opacity 0.12s ease;
}
.page-loader-spinner {
    width: 48px; height: 48px;
    border: 3px solid color-mix(in srgb, var(--teal) 18%, transparent);
    border-top-color: var(--teal);
    border-radius: 50%;
    animation: page-loader-spin 0.8s linear infinite;
}
.page-loader-label {
    font-size: 12.5px; font-weight: 700;
    color: var(--tx2);
    letter-spacing: 0.6px;
    text-transform: uppercase;
}
@keyframes page-loader-spin {
    to { transform: rotate(360deg); }
}

/* Per-module KPI strip — sits above the filter bar on every module's
   Index page. Reuses the .d-kpi card style from the dashboard so the
   visual hover lift carries over too. The CARDS: picker is now inline
   in the page header next to Export Excel. */
.mod-kpi-row {
    margin-bottom: 16px;
}
.mod-kpi-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}
/* Module KPI cards: same hover lift as the dashboard's clickable cards.
   These aren't drill-downs (yet) so the cursor stays default, but the
   visual hover feedback matches. */
.mod-kpi { cursor: default; }
.mod-kpi-picker {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 11.5px;
    color: var(--tx2);
    margin-left: 8px;
}
.mod-kpi-picker .muted {
    font-weight: 700; letter-spacing: 0.8px;
    text-transform: uppercase; font-size: 10.5px;
}
.mod-kpi-picker select { min-width: 180px; }

/* When the picker hits its max (4 selected), slim-select adds .ss-disabled
   to every unselected option-row so the user can see they need to
   deselect one before picking another. */
.ss-option.ss-disabled {
    opacity: 0.4;
    pointer-events: none;
    cursor: not-allowed;
}

/* Flex column so the table's separate header div stays pinned while only the
   inner .dkd-table-scroll scrolls (single-table AND split layouts alike). The
   card's max-height bounds it; short tables still size to content. */
.dkd-body {
    padding: 14px 22px 22px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.dkd-loading {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 40px 16px; color: var(--tx2);
}
/* Drill-down detail table.
   The header is rendered as a separate <div> stack ABOVE the scroll
   container so it stays perfectly fixed while the body scrolls (sticky
   <thead> inside a scrolling tbody jitters on some browsers and loses its
   bottom border with border-collapse:collapse). Header column widths and
   the table's <colgroup> are both percentages so the two stay aligned;
   table-layout: fixed enforces those widths instead of letting cell content
   stretch a column. */
.dkd-table-wrap {
    display: flex;
    flex-direction: column;
    min-height: 0;
    flex: 1 1 auto; /* fill the body so the inner scroll (not the body) scrolls */
    border: 1px solid var(--border);
    border-radius: var(--rs);
    background: var(--card);
    overflow: hidden; /* clip the rounded corners of the inner table */
}
.dkd-table-head {
    display: flex;
    align-items: stretch;
    /* Faded grey — matches .data-table th so the fixed drill-down header
       contrasts with the scrolling table body. */
    background: #f1f4f8;
    border-bottom: 2px solid var(--border);
    flex-shrink: 0;
}
.dkd-th {
    padding: 8px 10px;
    box-sizing: border-box;
    font-size: 10.5px;
    font-weight: 800;
    color: var(--tx2);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dkd-th.num,
.dkd-th:last-child { text-align: right; }
.dkd-table-scroll {
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
}
.dkd-table {
    width: 100%;
    table-layout: fixed;
    /* separate + spacing:0 so the hover highlight's end cells round (collapsed
       borders ignore cell border-radius). */
    border-collapse: separate;
    border-spacing: 0;
    font-size: 12px;
    background: var(--card);
}
.dkd-table td {
    padding: 8px 10px;
    color: var(--tx);
    font-family: 'Nunito', 'Inter', system-ui, -apple-system, sans-serif;
    border-bottom: 1px solid #f1f5f9;
    vertical-align: middle;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dkd-table tr:last-child td { border-bottom: none; }
.dkd-table tr:hover td { background: color-mix(in srgb, var(--teal) 9%, transparent); transition: background 0.12s; }
.dkd-table tr:hover td:first-child { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
.dkd-table tr:hover td:last-child  { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }
.dkd-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
/* .mono in module tables is sans-serif with tabular-nums (despite the name) —
   keep parity so drill-down numbers match the module list look. */
.dkd-table td.mono {
    font-family: 'Nunito', 'Inter', system-ui, -apple-system, sans-serif;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}
/* Always right-align the last column of any drill-down table — looks
   tidier when the table's rightmost data sits flush with the right edge,
   regardless of whether the controller marked the column Align="right". */
.dkd-table td:last-child { text-align: right; }

/* Stacked comparison view inside the drill-down modal — used by the NCA
   chart to show NCA on top and Existing customers below. Each table scrolls
   independently inside a fixed max-height so the modal itself doesn't scroll. */
.dkd-split {
    display: flex;
    flex-direction: column;
    gap: 14px;
    flex: 1 1 auto;
    min-height: 0;
}
.dkd-split-col {
    display: flex;
    flex-direction: column;
    min-height: 0;
    flex: 1 1 0;
}
/* Split-col uses the standard .dkd-table-wrap layout (border + own scroll);
   we just give it a min-height so an empty side still shows a visible card. */
.dkd-split-col .dkd-table-wrap {
    flex: 1 1 0;
    min-height: 120px;
}
.dkd-split-caption {
    font-size: 12px;
    font-weight: 700;
    color: var(--tx);
    padding: 6px 8px;
    margin-bottom: 6px;
    background: var(--bg);
    border-radius: var(--rs);
    flex-shrink: 0;
}
/* Split layout (NCA vs Existing) — claim the remaining card height and stop
   the modal itself from scrolling so each split-col table-wrap handles its
   own scroll. The `.dkd-body--split` class is a JS-toggled fallback for
   browsers without :has() support. Single-table modals deliberately don't
   match this rule — they size to content with a max-height cap so a 5-row
   detail doesn't render as a giant half-empty box. */
.dkd-body:has(.dkd-split),
.dkd-body--split {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
    flex: 1 1 auto;
}
/* Force the card itself to take the full available height when a split
   layout is rendered. Without this the card sizes to head + collapsed body
   (since the body's flex:1 has no parent height to grow into) and the user
   ends up with a sliver of a modal. */
.dkd-card:has(.dkd-split),
.dkd-card--split {
    height: 86vh;
}

/* Clickable dashboard card — gives a subtle pointer cursor + lift on hover
   so the user knows the whole card opens a drill-down (e.g. the NCA card). */
.d-card-clickable { cursor: pointer; transition: box-shadow 0.15s, transform 0.1s; }
.d-card-clickable:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
.d-card-clickable:active { transform: translateY(1px); }
.d-card-clickable:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

/* ── Custom date picker (replaces native browser calendar) ─────────────── */

/* Hide the native calendar indicator on enhanced inputs */
input.dp-input::-webkit-calendar-picker-indicator { display: none; opacity: 0; pointer-events: none; }
input.dp-input { cursor: text; }

/* Wrapper around the input + calendar icon */
.dp-input-wrap {
    position: relative;
    display: inline-block;
    width: 100%;
}
.dp-input-wrap > input.dp-input {
    width: 100%;
    padding-right: 38px; /* room for the icon button */
}
.dp-icon-btn {
    position: absolute;
    top: 50%; right: 6px;
    transform: translateY(-50%);
    width: 30px; height: 30px;
    border: none; background: transparent;
    border-radius: 8px;
    color: var(--tx2);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background 0.15s, color 0.15s;
}
.dp-icon-btn:hover { background: var(--teal3); color: var(--teal); }
.dp-icon-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--teal3); color: var(--teal); }

.dp-popup {
    position: absolute;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow:
        0 6px 16px rgba(15, 23, 42, 0.08),
        0 12px 32px rgba(15, 23, 42, 0.12);
    padding: 14px;
    z-index: 9999;
    width: 296px;
    user-select: none;
    /* Subtle teal accent bar at top */
    border-top: 3px solid var(--teal);
}
.dp-popup[hidden] { display: none; }

.dp-header {
    display: flex; align-items: center; justify-content: space-between;
    padding-bottom: 10px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--border);
    color: var(--tx);
}
.dp-month-picker {
    padding: 5px 12px;
    border-radius: 8px;
    cursor: pointer;
    font-weight: 700; font-size: 14px; color: var(--tx);
    transition: background 0.15s, color 0.15s;
}
.dp-month-picker:hover { background: var(--teal3); color: var(--teal); }
/* Month nav group — mirrors .dp-year-picker so the month can be stepped with
   ‹ › arrows just like the year. */
.dp-month-picker-group { display: flex; align-items: center; gap: 4px; }

.dp-year-picker {
    display: flex; align-items: center; gap: 4px;
    font-weight: 700; font-size: 14px; color: var(--tx);
}
.dp-nav {
    width: 28px; height: 28px; border-radius: 50%;
    background: transparent; border: none;
    color: var(--tx2); font-size: 16px; line-height: 1; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background 0.15s, color 0.15s;
}
.dp-nav:hover { background: var(--teal3); color: var(--teal); }
.dp-year-label { min-width: 48px; text-align: center; }

/* Sliding views — day grid ↔ month list animate horizontally */
.dp-views {
    position: relative;
    overflow: hidden;
    height: 268px;
}
.dp-view {
    position: absolute; inset: 0;
    transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.22s ease;
    will-change: transform, opacity;
}
.dp-view-days   { transform: translateX(0);     opacity: 1; }
.dp-view-months { transform: translateX(100%);  opacity: 0; pointer-events: none; }
.dp-popup.dp-show-months .dp-view-days   { transform: translateX(-100%); opacity: 0; pointer-events: none; }
.dp-popup.dp-show-months .dp-view-months { transform: translateX(0);     opacity: 1; pointer-events: auto; }

.dp-week-day {
    display: grid; grid-template-columns: repeat(7, 1fr);
    margin-bottom: 4px;
}
.dp-week-day > div {
    text-align: center;
    font-size: 10px; font-weight: 700;
    color: var(--tx3); text-transform: uppercase; letter-spacing: 0.5px;
    padding: 6px 0;
}

.dp-day {
    display: grid; grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}
.dp-day-cell {
    height: 34px;
    display: flex; align-items: center; justify-content: center;
    font-size: 12.5px; color: var(--tx);
    cursor: pointer;
    border-radius: 8px;
    transition: background 0.12s, color 0.12s;
}
.dp-day-cell:hover { background: var(--teal3); color: var(--teal); }
.dp-day-cell.dp-out { color: var(--tx3); opacity: 0.5; cursor: default; }
.dp-day-cell.dp-out:hover { background: transparent; color: var(--tx3); }

.dp-day-cell.dp-today {
    box-shadow: inset 0 0 0 1.5px var(--teal);
    color: var(--teal); font-weight: 700;
}
.dp-day-cell.dp-selected {
    background: var(--teal); color: #fff; font-weight: 700;
    box-shadow: 0 2px 6px rgba(13,148,136,0.3);
}
.dp-day-cell.dp-selected:hover { background: var(--teal); color: #fff; }

.dp-footer {
    display: flex; gap: 6px; justify-content: flex-end;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}
.dp-action {
    background: transparent; border: 1px solid var(--border);
    padding: 5px 12px; border-radius: 8px;
    font: inherit; font-size: 12px; font-weight: 600;
    color: var(--tx2);
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.dp-action:hover { border-color: var(--teal); color: var(--teal); background: var(--teal3); }

.dp-month-list {
    height: 100%;
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    align-content: center;
    padding: 6px 2px;
}
.dp-month-cell {
    padding: 14px 6px;
    border-radius: 10px;
    text-align: center;
    font-size: 13px; font-weight: 600;
    color: var(--tx);
    cursor: pointer;
    transition: background 0.12s, color 0.12s, transform 0.12s;
}
.dp-month-cell:hover { background: var(--teal3); color: var(--teal); }
.dp-month-cell.dp-month-selected {
    background: var(--teal); color: #fff;
    box-shadow: 0 2px 8px rgba(13,148,136,0.30);
}
.dp-month-cell.dp-month-selected:hover { background: var(--teal); color: #fff; }

/* ── Per-user accent themes ──────────────────────────────────────────────
   Every accent component reads var(--teal), --teal2 and --teal3, so a
   single override per theme recolours: buttons, slim-select, checkboxes,
   sidebar active item, KPI top borders (set via JS to var(--theme)),
   period-tab pill, hover states, etc.
   The "teal" theme is the default — listed first for parity even though
   the :root values already match.
*/
body[data-theme="teal"]   { --teal: #0d9488; --teal2: #14b8a6; --teal3: rgba(13, 148, 136, 0.14); }
body[data-theme="green"]  { --teal: #059669; --teal2: #10b981; --teal3: rgba(5, 150, 105, 0.14); }
body[data-theme="blue"]   { --teal: #2563eb; --teal2: #3b82f6; --teal3: rgba(37, 99, 235, 0.14); }
body[data-theme="indigo"] { --teal: #4f46e5; --teal2: #6366f1; --teal3: rgba(79, 70, 229, 0.14); }
body[data-theme="purple"] { --teal: #7c3aed; --teal2: #8b5cf6; --teal3: rgba(124, 58, 237, 0.14); }
body[data-theme="pink"]   { --teal: #db2777; --teal2: #ec4899; --teal3: rgba(219, 39, 119, 0.14); }
body[data-theme="rose"]   { --teal: #e11d48; --teal2: #f43f5e; --teal3: rgba(225, 29, 72, 0.14); }
body[data-theme="red"]    { --teal: #dc2626; --teal2: #ef4444; --teal3: rgba(220, 38, 38, 0.14); }
body[data-theme="orange"] { --teal: #ea580c; --teal2: #f97316; --teal3: rgba(234, 88, 12, 0.14); }
body[data-theme="amber"]  { --teal: #d97706; --teal2: #f59e0b; --teal3: rgba(217, 119, 6, 0.14); }

/* Theme picker page */
.theme-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 14px;
    margin-top: 14px;
}
.theme-swatch {
    background: var(--card);
    border: 2px solid var(--border);
    border-radius: 14px;
    padding: 16px 12px 12px;
    cursor: pointer;
    text-align: center;
    font: inherit;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
    position: relative;
    color: var(--tx);
}
.theme-swatch:hover { border-color: #cbd5e1; box-shadow: 0 4px 12px rgba(15,23,42,0.06); }
.theme-swatch:active { transform: translateY(1px); }
.theme-swatch.is-current {
    border-color: var(--swatch-color, var(--teal));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--swatch-color, var(--teal)) 22%, transparent);
}
.theme-swatch-dot {
    display: block;
    width: 56px; height: 56px; border-radius: 50%;
    margin: 0 auto 10px;
    background: var(--swatch-color);
    box-shadow:
        0 0 0 3px color-mix(in srgb, var(--swatch-color) 18%, transparent),
        0 8px 18px color-mix(in srgb, var(--swatch-color) 35%, transparent);
}
.theme-swatch-name { font-size: 12.5px; font-weight: 700; color: var(--tx); }
.theme-swatch.is-current::after {
    content: '✓';
    position: absolute; top: 8px; right: 10px;
    width: 22px; height: 22px;
    border-radius: 50%;
    background: var(--swatch-color);
    color: #fff;
    font-weight: 900; font-size: 13px;
    display: inline-flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 6px color-mix(in srgb, var(--swatch-color) 35%, transparent);
}

/* ── Sidebar collapsed state ─────────────────────────────────────────────
   Triggered by `.collapsed` on `.sidebar` (set by JS) or the preload class
   `.sb-collapsed` on <html> (set synchronously to avoid first-paint flash). */
.sidebar.collapsed { width: 64px; min-width: 64px; }
html.sb-collapsed .sidebar { width: 64px; min-width: 64px; }

/* Logo header — hide the image, wordmark and tagline; leave just the burger */
.sidebar.collapsed .logo,
html.sb-collapsed .sidebar .logo {
    padding: 8px 6px;
    border-bottom: 1px solid rgba(255,255,255,0.07);
    min-height: 44px;
    max-height: 44px;
    /* Hold the container at full height for ~120ms while the contents fade out,
       then snap to the small burger-only height. Avoids a visible jump where
       the contents disappear before the rail starts collapsing. */
    transition: max-height 0s 0.12s, padding 0s 0.12s;
}
.sidebar.collapsed .logo .logo-img,
.sidebar.collapsed .logo h1,
.sidebar.collapsed .logo p,
html.sb-collapsed .sidebar .logo .logo-img,
html.sb-collapsed .sidebar .logo h1,
html.sb-collapsed .sidebar .logo p {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s ease;  /* fast fade-out on collapse */
}

/* Burger sits centred when collapsed (no longer top-right) */
.sidebar.collapsed .sb-toggle,
html.sb-collapsed .sidebar .sb-toggle {
    position: relative; top: auto; right: auto;
    margin: 0 auto; display: flex;
}

/* Section headings → a more visible horizontal divider when collapsed so
   the groupings of icons (Overview / Activity Log / Tools) read clearly.
   We render a wider rule with side fades and a touch more breathing room
   above and below than the equivalent rule in the expanded sidebar. */
.sidebar.collapsed .ns,
html.sb-collapsed .sidebar .ns {
    font-size: 0;
    padding: 12px 12px 10px;
    text-align: center;
}
.sidebar.collapsed .ns::before,
html.sb-collapsed .sidebar .ns::before {
    content: '';
    display: block;
    height: 1px;
    background: linear-gradient(90deg,
        rgba(255,255,255,0) 0%,
        rgba(255,255,255,0.18) 30%,
        rgba(255,255,255,0.18) 70%,
        rgba(255,255,255,0) 100%);
}
/* The very first .ns (right after the burger row) doesn't need a divider
   on top — the logo header's bottom border already separates it. */
.sidebar.collapsed nav > .ns:first-child::before,
html.sb-collapsed .sidebar nav > .ns:first-child::before {
    background: none;
}

/* Nav items — icon only, centred, label + badge hidden */
.sidebar.collapsed .ni,
html.sb-collapsed .sidebar .ni {
    justify-content: center;
    padding: 10px 0;
    gap: 0;
    /* Hide the text node by zeroing its rendered size, but transition it
       smoothly so it fades out as the rail collapses. */
    color: transparent;
    font-size: 0;
}
/* The icon span itself keeps its colour even when the label fades */
.sidebar.collapsed .ni .ico,
html.sb-collapsed .sidebar .ni .ico {
    color: rgba(255,255,255,0.65);
}
.sidebar.collapsed .ni:hover .ico,
.sidebar.collapsed .ni.on .ico,
html.sb-collapsed .sidebar .ni:hover .ico,
html.sb-collapsed .sidebar .ni.on .ico {
    color: #fff;
}
.sidebar.collapsed .ni .ico svg,
html.sb-collapsed .sidebar .ni .ico svg {
    width: 19px; height: 19px;
}
.sidebar.collapsed .ni .nbadge,
html.sb-collapsed .sidebar .ni .nbadge { display: none; }

/* Active item highlight shrinks to a centred pill */
.sidebar.collapsed .ni.on,
html.sb-collapsed .sidebar .ni.on {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--teal) 38%, transparent),
        color-mix(in srgb, var(--teal2) 22%, transparent));
}

/* Tighter vertical rhythm so the icon-only nav doesn't feel airy */
.sidebar.collapsed nav,
html.sb-collapsed .sidebar nav { padding: 6px 6px; }
