/* ==========================================================================
   Circles Co Studio Dashboard - Main Stylesheet
   ========================================================================== */

/* --------------------------------------------------------------------------
   CSS Custom Properties
   -------------------------------------------------------------------------- */
:root {
    /* Colors */
    --color-bg: #f2f6fb;
    --color-surface: #ffffff;
    --color-surface-secondary: #f9fafb;
    --color-surface-hover: #f2f6fb;
    /* Views across the app paint hovers and inset panels with
       --color-bg-subtle. It was never declared, so each use silently fell back
       to whatever light literal sat in its var() fallback and stayed white in
       dark mode. Declaring it in both themes fixes every one of them at once. */
    --color-bg-subtle: #f2f6fb;
    /* Two more names the app writes but nobody ever declared: --color-surface-2
       (a tint panel — tab strips, glyph tiles, inset rows) and
       --color-text-primary (a second spelling of --color-text). Same failure as
       above: undeclared, so a var() fallback painted a light literal, and a
       bare color: fell back to whatever it inherited. Aliasing them onto the
       real tokens here resolves them per theme, so they follow dark mode
       everywhere they are used instead of file by file. */
    --color-surface-2: var(--color-bg-subtle);
    --color-text-primary: var(--color-text);
    --color-border: #e5e7eb;
    --color-border-light: #dde5f1;

    --color-text: #111827;
    --color-text-secondary: #6b7280;
    --color-text-tertiary: #9ca3af;
    --color-text-inverse: #ffffff;

    --color-primary: #145fff;
    --color-primary-hover: #0e4fd6;
    --color-primary-light: #e8f0ff;
    --color-primary-bg: rgba(20, 95, 255, 0.08);

    --color-success: #1cc66d;
    --color-success-light: #d4f5e2;
    --color-success-bg: rgba(28, 198, 109, 0.08);
    /* Text-safe green, the counterpart to --color-warning-strong and
       --color-danger-strong. --color-success is a bright mint: right as a fill,
       about 2.2:1 as copy on white, and every "paid" figure in the app was set
       in a one-off #059669 with no dark-mode value. Reads ~4.8:1 on white and
       ~6.5:1 on --color-success-light; the bright end goes to dark mode. */
    --color-success-strong: #047857;

    --color-warning: #ffb600;
    --color-warning-light: #fff3d0;
    --color-warning-bg: rgba(255, 182, 0, 0.08);
    /* Text-safe amber. --color-warning is a golden yellow: gorgeous as a fill,
       about 1.7:1 as 12px copy on its own tint — and that is what every warning
       badge in the app was set in. Same family, dark enough to read (~6.2:1 on
       --color-warning-light). In dark mode the relationship inverts, so the
       bright value goes there. */
    --color-warning-strong: #854d0e;

    --color-danger: #ef4444;
    --color-danger-light: #fee2e2;
    --color-danger-bg: rgba(239, 68, 68, 0.08);
    /* Text-safe red, same deal as --color-warning-strong: --color-danger is
       about 3.3:1 on its own tint, which is under AA for anything small. This
       reads ~6.9:1 on --color-danger-light. Dark mode inverts it. */
    --color-danger-strong: #991b1b;

    --color-info: #1264FF;
    --color-info-light: #eff6ff;

    /* Sidebar */
    --sidebar-width: 260px;
    --sidebar-bg: #0f172a;
    --sidebar-text: #94a3b8;
    --sidebar-text-hover: #e2e8f0;
    --sidebar-active-bg: var(--color-primary);
    --sidebar-active-text: #ffffff;

    /* Sizing */
    --header-height: 64px;
    --radius-sm: 6px;
    --radius-md: 6px;
    --radius-lg: 12px;
    --radius-xl: 16px;

    /* Shadows */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05);

    /* Transitions */
    --transition-fast: 150ms ease;
    --transition-base: 200ms ease;
}

/* --------------------------------------------------------------------------
   Dark Mode
   -------------------------------------------------------------------------- */
[data-theme="dark"] {
    --color-bg: #0f1117;
    --color-surface: #1a1d27;
    --color-surface-secondary: #1f222d;
    --color-surface-hover: #252836;
    --color-bg-subtle: #252836;
    --color-border: #2e3140;
    --color-border-light: #262938;

    --color-text: #e8eaed;
    --color-text-secondary: #9ca3af;
    --color-text-tertiary: #6b7280;
    --color-text-inverse: #111827;

    --color-primary: #145fff;
    --color-primary-hover: #3b7fff;
    --color-primary-light: rgba(20, 95, 255, 0.15);
    --color-primary-bg: rgba(20, 95, 255, 0.12);

    --color-success-light: rgba(28, 198, 109, 0.15);
    --color-success-bg: rgba(28, 198, 109, 0.12);
    --color-success-strong: #6ee7b7; /* on a dark surface the bright end is the readable one */
    --color-warning-light: rgba(255, 182, 0, 0.15);
    --color-warning-bg: rgba(255, 182, 0, 0.12);
    --color-warning-strong: #ffc247; /* on a dark surface the bright end is the readable one */
    --color-danger-light: rgba(239, 68, 68, 0.15);
    --color-danger-bg: rgba(239, 68, 68, 0.12);
    --color-danger-strong: #fca5a5; /* on a dark surface the bright end is the readable one */
    --color-info-light: rgba(18, 100, 255, 0.12);

    --sidebar-bg: #151e37;
    --sidebar-text: #94a3b8;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.25);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.3);

    color-scheme: dark;
}

/* Dark mode overrides for inline styles */
[data-theme="dark"] [style*="color: #111827"],
[data-theme="dark"] [style*="color:#111827"] { color: var(--color-text) !important; }
[data-theme="dark"] [style*="color: #1e293b"],
[data-theme="dark"] [style*="color:#1e293b"] { color: var(--color-text) !important; }
[data-theme="dark"] [style*="color: #374151"],
[data-theme="dark"] [style*="color:#374151"] { color: #b0b5be !important; }
[data-theme="dark"] [style*="color: #6b7280"],
[data-theme="dark"] [style*="color:#6b7280"] { color: var(--color-text-secondary) !important; }
[data-theme="dark"] [style*="color: #9ca3af"],
[data-theme="dark"] [style*="color:#9ca3af"] { color: var(--color-text-tertiary) !important; }
[data-theme="dark"] [style*="color: #d1d5db"],
[data-theme="dark"] [style*="color:#d1d5db"] { color: #4b5060 !important; }

/* Background overrides */
[data-theme="dark"] [style*="background: #fff"],
[data-theme="dark"] [style*="background:#fff"],
[data-theme="dark"] [style*="background: #ffffff"],
[data-theme="dark"] [style*="background:#ffffff"] { background: var(--color-surface) !important; }
[data-theme="dark"] [style*="background-color: #fff"],
[data-theme="dark"] [style*="background-color:#fff"],
[data-theme="dark"] [style*="background-color: #ffffff"],
[data-theme="dark"] [style*="background-color:#ffffff"] { background-color: var(--color-surface) !important; }
[data-theme="dark"] [style*="background: #f2f6fb"],
[data-theme="dark"] [style*="background:#f2f6fb"] { background: var(--color-bg) !important; }
[data-theme="dark"] [style*="background: #f2f6fb"],
[data-theme="dark"] [style*="background:#f2f6fb"] { background: var(--color-surface-hover) !important; }
[data-theme="dark"] [style*="background: #f9fafb"],
[data-theme="dark"] [style*="background:#f9fafb"] { background: var(--color-surface-hover) !important; }
[data-theme="dark"] [style*="background: #eff6ff"],
[data-theme="dark"] [style*="background:#eff6ff"] { background: rgba(20, 95, 255, 0.15) !important; }
[data-theme="dark"] [style*="background: #f3f6fa"],
[data-theme="dark"] [style*="background:#f3f6fa"] { background: var(--color-surface-hover) !important; }
[data-theme="dark"] [style*="background: #e5e7eb"],
[data-theme="dark"] [style*="background:#e5e7eb"] { background: var(--color-border) !important; }
[data-theme="dark"] [style*="background: #dde5f1"],
[data-theme="dark"] [style*="background:#dde5f1"] { background: var(--color-border-light) !important; }

/* Attention card overrides — match both spaced + unspaced inline forms
   (`background: #x` and `background:#x`). Inline badges like the OWNER pill
   omit the space and were missing the dark treatment. */
[data-theme="dark"] [style*="background: #fef2f2"],
[data-theme="dark"] [style*="background:#fef2f2"] { background: rgba(239, 68, 68, 0.12) !important; }
[data-theme="dark"] [style*="background: #d4f5e2"],
[data-theme="dark"] [style*="background:#d4f5e2"] { background: rgba(28, 198, 109, 0.15) !important; }
[data-theme="dark"] [style*="background: #fffbeb"],
[data-theme="dark"] [style*="background:#fffbeb"] { background: rgba(255, 182, 0, 0.12) !important; }
[data-theme="dark"] [style*="background: #e0e7ff"],
[data-theme="dark"] [style*="background:#e0e7ff"] { background: rgba(20, 95, 255, 0.15) !important; }
[data-theme="dark"] [style*="background: #ecfdf5"],
[data-theme="dark"] [style*="background:#ecfdf5"] { background: rgba(28, 198, 109, 0.12) !important; }
[data-theme="dark"] [style*="background: #fef3c7"],
[data-theme="dark"] [style*="background:#fef3c7"] { background: rgba(255, 182, 0, 0.12) !important; }
[data-theme="dark"] [style*="background: #fee2e2"],
[data-theme="dark"] [style*="background:#fee2e2"] { background: rgba(239, 68, 68, 0.12) !important; }

/* Border overrides */
[data-theme="dark"] [style*="border: 1px solid #e5e7eb"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border: 1px solid #d1d5db"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border: 1px solid #dde5f1"] { border-color: var(--color-border-light) !important; }
[data-theme="dark"] [style*="border-bottom: 1px solid #e5e7eb"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border-top: 1px solid #e5e7eb"] { border-color: var(--color-border) !important; }
/* #dde5f1 is the HAIRLINE literal — the light-mode value of --color-border-light,
   used to separate rows inside a card. It mapped to --color-border here while the
   `border:` form above mapped it to --color-border-light, so the same hairline came
   back a shade heavier on a bottom edge than on a box, and row separators in dark
   read as ruled lines rather than as the faint divisions they are in light. */
[data-theme="dark"] [style*="border-bottom: 1px solid #dde5f1"] { border-color: var(--color-border-light) !important; }
[data-theme="dark"] [style*="border-top: 1px solid #dde5f1"] { border-color: var(--color-border-light) !important; }
[data-theme="dark"] [style*="border-color: #e5e7eb"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border-color: #fecaca"] { border-color: rgba(239, 68, 68, 0.3) !important; }
[data-theme="dark"] [style*="border-color: #bfdbfe"] { border-color: rgba(20, 95, 255, 0.3) !important; }
[data-theme="dark"] [style*="border-color: #fde68a"] { border-color: rgba(255, 182, 0, 0.3) !important; }
[data-theme="dark"] [style*="border: 2px dashed #e5e7eb"] { border-color: var(--color-border) !important; }
/* Stripe connect box uses a 1.5px border */
[data-theme="dark"] [style*="border: 1.5px solid #e5e7eb"] { border-color: var(--color-border) !important; }
/* Upload-preview drop targets (org logo, brand logo/wordmark/cover/welcome,
   detail letter) use a 1.5px dashed border — without this rule the dashes
   glow bright white on the auto-darkened background. */
[data-theme="dark"] [style*="border: 1.5px dashed #e5e7eb"],
[data-theme="dark"] [style*="border:1.5px dashed #e5e7eb"] { border-color: var(--color-border) !important; }
/* Owner / role badge text — colored green (#059669) on a green-tint background
   (#ecfdf5, auto-darkened above). The dark text becomes unreadable on the
   darkened tint; bump it to the bright green token. */
[data-theme="dark"] [style*="color: #059669"],
[data-theme="dark"] [style*="color:#059669"] { color: #34d399 !important; }
/* Blue-tinted highlight panels (current plan, storage add-ons) */
[data-theme="dark"] [style*="background: #f8faff"],
[data-theme="dark"] [style*="background:#f8faff"] { background: var(--color-primary-bg) !important; }
[data-theme="dark"] [style*="border: 1px solid #bfdbfe"] { border-color: rgba(20, 95, 255, 0.3) !important; }
[data-theme="dark"] [style*="border-bottom: 1px solid #bfdbfe"] { border-color: rgba(20, 95, 255, 0.3) !important; }
[data-theme="dark"] [style*="border: 1px solid #dbeafe"] { border-color: rgba(20, 95, 255, 0.22) !important; }
[data-theme="dark"] [style*="border-bottom: 1px solid #dbeafe"] { border-color: rgba(20, 95, 255, 0.22) !important; }

/* Purple-tinted highlight panels — same metric-card concept as the
   blue auto-darken rules above. Used by AI Concierge active state,
   add-on badges, and any other purple inline-styled callouts. */
[data-theme="dark"] [style*="background: #f5f3ff"],
[data-theme="dark"] [style*="background:#f5f3ff"] { background: rgba(124, 58, 237, 0.15) !important; }
[data-theme="dark"] [style*="background: #ede9fe"],
[data-theme="dark"] [style*="background:#ede9fe"] { background: rgba(124, 58, 237, 0.18) !important; }
[data-theme="dark"] [style*="border: 1px solid #ddd6fe"] { border-color: rgba(124, 58, 237, 0.3) !important; }
[data-theme="dark"] [style*="border-bottom: 1px solid #ddd6fe"] { border-color: rgba(124, 58, 237, 0.3) !important; }
[data-theme="dark"] [style*="border: 1px solid #ede9fe"] { border-color: rgba(124, 58, 237, 0.22) !important; }
/* Bump too-dark inline purple text so it reads on the new dark tints */
[data-theme="dark"] [style*="color: #5b21b6"],
[data-theme="dark"] [style*="color:#5b21b6"] { color: #a78bfa !important; }
[data-theme="dark"] [style*="color: #6d28d9"],
[data-theme="dark"] [style*="color:#6d28d9"] { color: #a78bfa !important; }

/* Modules-page paid-feature callout text — colored blue/purple in
   light mode for emphasis, plain white in dark mode for max contrast
   on the auto-darkened tinted backgrounds. */
[data-theme="dark"] .ms-paid-text,
[data-theme="dark"] .ms-paid-text strong { color: #fff !important; }

/* Input overrides — force on ALL inputs */
[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"]),
[data-theme="dark"] textarea,
[data-theme="dark"] .portal-input:not(select),
[data-theme="dark"] .form-input:not(select) {
    background: #1f222d !important;
    color: var(--color-text) !important;
    border-color: var(--color-border) !important;
}
[data-theme="dark"] select,
[data-theme="dark"] select.portal-input,
[data-theme="dark"] select.form-input,
[data-theme="dark"] select.form-select,
[data-theme="dark"] .portal-select,
[data-theme="dark"] .portal-select-sm,
[data-theme="dark"] select[style],
[data-theme="dark"] select[style*="background"] {
    background: #1f222d url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") no-repeat right 14px center !important;
    color: var(--color-text) !important;
    border-color: var(--color-border) !important;
}
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder { color: var(--color-text-tertiary) !important; }
[data-theme="dark"] select option { background: #1a1d27; color: #e8eaed; }

/* Contenteditable (editors, assignee field) */
[data-theme="dark"] [contenteditable="true"] {
    background: #1f222d !important;
    color: var(--color-text) !important;
    border-color: var(--color-border) !important;
}

/* Modal/overlay overrides */
[data-theme="dark"] [style*="background:rgba(0,0,0,0.5)"],
[data-theme="dark"] [style*="background: rgba(0,0,0,0.5)"] { background: rgba(0,0,0,0.7) !important; }

/* Toast */
[data-theme="dark"] #ccs-toast { background: #e8eaed !important; color: #111827 !important; }

/* Editor */
[data-theme="dark"] .se { border-color: var(--color-border) !important; }
[data-theme="dark"] .se__bar { background: var(--color-surface-hover) !important; border-color: var(--color-border-light) !important; }
[data-theme="dark"] .se__body { color: var(--color-text) !important; }
[data-theme="dark"] .se__files { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .se__mention-dropdown { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .se__mention-item-name { color: var(--color-text) !important; }
[data-theme="dark"] .se__mention-tag { background: rgba(20, 95, 255, 0.2) !important; color: #6db0ff !important; }

/* Cards and tables */
[data-theme="dark"] .card { background: var(--color-surface); border-color: var(--color-border); }
[data-theme="dark"] .pgroup { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .ptable th { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .ptable-row td { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .ptable-row:hover td { background: var(--color-surface-hover) !important; }
[data-theme="dark"] .ptable-title { color: var(--color-text) !important; }
[data-theme="dark"] .kanban-col { background: var(--color-bg) !important; }
[data-theme="dark"] .kanban-card { background: var(--color-surface) !important; border-color: var(--color-border) !important; }

/* Dropdown/multi-select */
[data-theme="dark"] .cc-multi-select__dropdown { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .fm-assignee-dropdown { background: var(--color-surface) !important; border-color: var(--color-border) !important; }

/* Dark scrollbar — tell the browser to use dark-themed native scrollbars */
[data-theme="dark"] { color-scheme: dark; }

/* Charts */
[data-theme="dark"] .chart-placeholder { background: linear-gradient(180deg, #2e3445 0%, var(--color-surface) 100%) !important; }
[data-theme="dark"] .chart-placeholder__bar { opacity: 0.8; }

/* Shortcuts modal */
[data-theme="dark"] .sc-modal { background: var(--color-surface) !important; box-shadow: 0 20px 60px rgba(0,0,0,0.5) !important; }
[data-theme="dark"] .sc-modal__header { color: var(--color-text) !important; border-color: var(--color-border-light) !important; }
[data-theme="dark"] .sc-modal__close:hover { color: var(--color-text) !important; background: var(--color-surface-hover) !important; }
[data-theme="dark"] .sc-modal-overlay { background: rgba(0,0,0,0.6) !important; }
[data-theme="dark"] .sc-row { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .sc-desc { color: var(--color-text) !important; }
[data-theme="dark"] .sc-key { background: var(--color-surface-hover) !important; border-color: var(--color-border) !important; color: var(--color-text-secondary) !important; }

/* To-do side panel */
[data-theme="dark"] #td-side-panel { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] #td-panel-overlay { background: rgba(0,0,0,0.5) !important; }

/* Generic modal overrides — catch all admin modals */
[data-theme="dark"] .modal-overlay { background: rgba(0,0,0,0.6) !important; }
[data-theme="dark"] .modal { background: var(--color-surface) !important; }
[data-theme="dark"] .modal__header { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .modal__footer { border-color: var(--color-border-light) !important; }

/* Data tables */
[data-theme="dark"] .data-table th { border-color: var(--color-border-light) !important; color: var(--color-text-tertiary) !important; }
[data-theme="dark"] .data-table td { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .data-table tbody tr:hover td { background: var(--color-surface-hover) !important; }

/* Detail rows */
[data-theme="dark"] .detail-row { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .detail-row__label { color: var(--color-text-secondary) !important; }
[data-theme="dark"] .detail-row__value { color: var(--color-text) !important; }

/* Tabs */
[data-theme="dark"] .tabs { background: #1a1d27; }
[data-theme="dark"] .tab { background: #252836; color: #9ca3af; }
[data-theme="dark"] .tab:hover { background: #2e3140; color: #e8eaed; }
[data-theme="dark"] .tab--active { background: rgba(18,100,255,0.15) !important; color: #5b9aff !important; }

/* Buttons */
[data-theme="dark"] .btn--ghost { color: var(--color-text-secondary) !important; }
[data-theme="dark"] .btn--ghost:hover { background: var(--color-surface-hover) !important; color: var(--color-text) !important; }
[data-theme="dark"] .btn--secondary { background: var(--color-surface) !important; color: var(--color-text) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .btn--secondary:hover { background: var(--color-surface-hover) !important; }

/* Form controls */
[data-theme="dark"] .form-input { background: #1f222d !important; color: var(--color-text) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .form-select { appearance: none; -webkit-appearance: none; background: #1f222d url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") no-repeat right 14px center !important; padding-right: 38px; color: var(--color-text) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .form-select { background-color: var(--color-surface) !important; color: var(--color-text) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .form-label { color: var(--color-text) !important; }

/* Header bar */
[data-theme="dark"] .ccs-header { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .ccs-header__search input,
[data-theme="dark"] .ccs-header__search-input { background: var(--color-surface-hover) !important; color: var(--color-text) !important; border-color: var(--color-border) !important; }
/* Toolbar search on list pages hardcodes the light #f2f6fb fill — it needs the
   same dark treatment as the header search or it burns a white box into every
   dark list page. */
[data-theme="dark"] .toolbar__search-input { background: var(--color-surface-hover) !important; color: var(--color-text) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .ccs-header__notification { color: #9ca3af !important; }
[data-theme="dark"] .ccs-header__notification:hover { color: #e8eaed !important; }
[data-theme="dark"] .ccs-header__push-ccc:hover { background: var(--color-primary) !important; color: #fff !important; }

/* Avatar overlap borders — match surface background in dark mode */
[data-theme="dark"] [style*="border: 2px solid #fff"],
[data-theme="dark"] [style*="border:2px solid #fff"] { border-color: var(--color-surface) !important; }

/* Dark save/action buttons that use --color-text as background */
[data-theme="dark"] [style*="background: var(--color-text"] { background: #e8eaed !important; color: #111827 !important; }
[data-theme="dark"] button[style*="background: var(--color-text"] { background: #e8eaed !important; color: #111827 !important; }

/* Sidebar */
[data-theme="dark"] .ccs-sidebar { background: var(--sidebar-bg) !important; }

/* Stat cards / info cards with inline bg */
[data-theme="dark"] [style*="background: #f9fafb"],
[data-theme="dark"] [style*="background:#f9fafb"] { background: var(--color-surface-hover) !important; }
[data-theme="dark"] [style*="background: #f2f6fb"],
[data-theme="dark"] [style*="background:#f2f6fb"] { background: var(--color-surface-hover) !important; }

/* Code blocks / pre */
[data-theme="dark"] pre, [data-theme="dark"] code { background: #1f222d !important; color: #e8eaed !important; }

/* Toggle switch tracks */
[data-theme="dark"] [style*="background: #d1d5db"] { background: #3b3f4e !important; }
[data-theme="dark"] [style*="background:#d1d5db"] { background: #3b3f4e !important; }

/* Ghost/outline buttons */
[data-theme="dark"] [style*="background: #f2f6fb"][style*="color: #374151"],
[data-theme="dark"] [style*="background:#f2f6fb"][style*="color:#374151"] { background: #252836 !important; color: #e8eaed !important; }

/* Settings page */
[data-theme="dark"] .settings-nav { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .settings-nav__item { color: var(--color-text-secondary) !important; }
[data-theme="dark"] .settings-nav__item:hover { background: var(--color-surface-hover) !important; color: var(--color-text) !important; }
[data-theme="dark"] .settings-nav__item--active { background: var(--color-primary-light) !important; color: var(--color-primary) !important; }

/* Admin cards — catch remaining inline white backgrounds */
[data-theme="dark"] .card__body { background: var(--color-surface) !important; }
[data-theme="dark"] .card__footer { border-color: var(--color-border-light) !important; }

/* Admin labels */
[data-theme="dark"] label { color: var(--color-text) !important; }

/* Light mode input background */
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"]),
textarea { background: #f2f6fb; }
select, .form-select { background: #f2f6fb; appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; padding-right: 38px; }

/* Lightbox — keep download button white */
[data-theme="dark"] #lightbox-download { background: #fff !important; color: #1264FF !important; }
[data-theme="dark"] #lightbox-bar { background: rgba(18,100,255,0.9) !important; }

/* Portal dashboard components */
[data-theme="dark"] .dash-metric { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .dash-metric__label { color: var(--color-text-secondary) !important; }
[data-theme="dark"] .dash-metric__value { color: var(--color-text) !important; }
[data-theme="dark"] .dash-metric__sub { color: var(--color-text-tertiary) !important; }
[data-theme="dark"] .dash-section { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .dash-section__header { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .dash-section__title { color: var(--color-text) !important; }
[data-theme="dark"] .dash-sidebar-card { background: var(--color-surface) !important; border-color: var(--color-border) !important; }
[data-theme="dark"] .dash-sidebar-card__header { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .dash-message { background: var(--color-surface) !important; }
[data-theme="dark"] .dash-message:hover { background: var(--color-surface-hover) !important; }
[data-theme="dark"] .dash-message__title { color: var(--color-text) !important; }
[data-theme="dark"] .dash-message__meta { color: var(--color-text-tertiary) !important; }
[data-theme="dark"] .dash-quick-btn { background: var(--color-surface) !important; border-color: var(--color-border) !important; color: var(--color-text) !important; }
[data-theme="dark"] .dash-quick-btn:hover { background: var(--color-surface-hover) !important; }
[data-theme="dark"] .dash-attention-card--tasks { background: rgba(255, 182, 0, 0.12) !important; border-color: rgba(255, 182, 0, 0.3) !important; }
[data-theme="dark"] .dash-attention-card--due { background: rgba(28, 198, 109, 0.12) !important; border-color: rgba(28, 198, 109, 0.3) !important; }
[data-theme="dark"] .dash-task { color: var(--color-text) !important; }
[data-theme="dark"] .dash-task:hover { background: var(--color-surface-hover) !important; }

/* Form modals */
[data-theme="dark"] .form-modal-overlay [style*="background:#fff"],
[data-theme="dark"] .form-modal-overlay [style*="background: #fff"] { background: var(--color-surface) !important; }
[data-theme="dark"] .form-modal-success { background: var(--color-surface) !important; }

/* Portal project tables */
[data-theme="dark"] .pgroup__header { border-color: var(--color-border-light) !important; }
[data-theme="dark"] .pgroup__name { color: var(--color-text) !important; }
[data-theme="dark"] .pgroup__count { background: var(--color-border-light) !important; }
[data-theme="dark"] .pgroup__empty { color: var(--color-text-tertiary) !important; }
[data-theme="dark"] .ptable-code { color: var(--color-text) !important; }
[data-theme="dark"] .ptable-status { color: var(--color-text) !important; }
[data-theme="dark"] .ptable-priority { color: var(--color-text) !important; }
[data-theme="dark"] .ptable-due { color: var(--color-text) !important; }
[data-theme="dark"] .kanban-card__title { color: var(--color-text) !important; }

/* Calendar sidebar */
[data-theme="dark"] .dash-cal-day { color: var(--color-text) !important; }
[data-theme="dark"] .dash-cal-day--today { background: #145fff !important; color: #fff !important; }

/* General dark bg for all white backgrounds not caught by attribute selectors */
[data-theme="dark"] [style*="background: #fff;"],
[data-theme="dark"] [style*="background:#fff;"],
[data-theme="dark"] [style*="background: #ffffff;"],
[data-theme="dark"] [style*="background:#ffffff;"] { background: var(--color-surface) !important; }

/* Dropdown menus */
[data-theme="dark"] [id*="dropdown"][style*="background:#fff"],
[data-theme="dark"] [id*="dropdown"][style*="background: #fff"] { background: var(--color-surface) !important; }

/* All borders with inline styles */
[data-theme="dark"] [style*="border: 1px solid #e5e7eb"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border:1px solid #e5e7eb"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border: 1px solid #d1d5db"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border:1px solid #d1d5db"] { border-color: var(--color-border) !important; }
[data-theme="dark"] [style*="border: 2px solid #e5e7eb"] { border-color: var(--color-border) !important; }

/* HR / dividers */
[data-theme="dark"] hr { border-color: var(--color-border-light) !important; }

/* New request dropdown */
[data-theme="dark"] #new-request-dropdown { background: var(--color-surface) !important; border-color: var(--color-border) !important; }

/* --------------------------------------------------------------------------
   Reset & Base
   -------------------------------------------------------------------------- */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* Prevent WP admin bar from pushing layout */
html,
html[lang] {
    font-size: 16px;
    margin-top: 0 !important;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

#wpadminbar {
    display: none !important;
}

body.ccs-dashboard {
    font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
    --font-display: 'Poppins', -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.5;
    overflow-x: hidden;
    margin: 0 !important;
    padding: 0 !important;
    min-height: 100vh;
}

/* Display font for page-level headings only */
h1,
.page-header__title,
.dash-hero__greeting,
.metric-card__value {
    font-family: var(--font-display);
}

/* Reset WP block styles that may leak in */
body.ccs-dashboard .wp-block-group,
body.ccs-dashboard .wp-site-blocks,
body.ccs-dashboard .entry-content {
    all: unset;
    display: block;
}

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

a:hover {
    color: var(--color-primary-hover);
}

img {
    max-width: 100%;
    display: block;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
.ccs-layout {
    display: flex;
    min-height: 100vh;
}

.ccs-main {
    flex: 1;
    margin-left: var(--sidebar-width);
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.ccs-content {
    flex: 1;
    padding: 24px 32px 40px;
    width: 100%;
}

/* --------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */
.ccs-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--sidebar-width);
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    display: flex;
    flex-direction: column;
    z-index: 100;
    transition: transform var(--transition-base);
}

.ccs-sidebar__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--header-height);
    padding: 0 20px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.ccs-sidebar__logo {
    display: flex;
    align-items: center;
    gap: 12px;
}

.ccs-sidebar__logo-icon {
    color: var(--color-primary);
    color: #5b9aff;
    display: flex;
}

.ccs-sidebar__brand {
    font-weight: 600;
    font-size: 15px;
    color: #f1f5f9;
    display: block;
    line-height: 1.2;
}

.ccs-sidebar__product {
    font-size: 11px;
    font-weight: 500;
    color: var(--sidebar-text);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.ccs-sidebar__toggle {
    display: none;
    background: none;
    border: none;
    color: var(--sidebar-text);
    cursor: pointer;
    padding: 4px;
}

/* Desktop collapse-to-icons toggle. Hidden on mobile so the X (drawer close)
   owns that breakpoint. */
.ccs-sidebar__collapse {
    background: none;
    border: none;
    color: var(--sidebar-text);
    cursor: pointer;
    padding: 6px;
    margin: 0 -6px 0 0;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 120ms, color 120ms;
}
.ccs-sidebar__collapse:hover {
    background: rgba(255, 255, 255, 0.06);
    color: #f1f5f9;
}

/* Compact (icons-only) sidebar. The custom property shrinks too so
   .ccs-main { margin-left: var(--sidebar-width); } auto-reflows. */
.ccs-sidebar__logo-mark { display: none; }

html.sidebar-collapsed { --sidebar-width: 64px; }
/* Header collapses to just the toggle button so users can re-open from here.
   Hiding the logo entirely keeps the 64px column from feeling crowded. */
html.sidebar-collapsed .ccs-sidebar__header { padding: 0; justify-content: center; }
html.sidebar-collapsed .ccs-sidebar__logo { display: none; }
html.sidebar-collapsed .ccs-sidebar__collapse { margin: 0; }
html.sidebar-collapsed .ccs-sidebar__collapse svg { transform: rotate(180deg); }
html.sidebar-collapsed .ccs-sidebar__nav { padding: 12px 8px; }
html.sidebar-collapsed .ccs-sidebar__item {
    justify-content: center;
    gap: 0;
    padding: 10px 0;
    position: relative;
}
html.sidebar-collapsed .ccs-sidebar__label,
html.sidebar-collapsed .ccs-sidebar__chevron,
html.sidebar-collapsed .ccs-sidebar__user-name,
html.sidebar-collapsed .ccs-sidebar__user-role { display: none !important; }
html.sidebar-collapsed .ccs-sidebar__menu ul[id$="-submenu"] { display: none !important; }
/* Badge becomes a small red corner dot, matching the notification bell.
   Inline-styled badges in the sidebar markup still win specificity, so we
   override with !important to force the bell-style look. */
html.sidebar-collapsed .ccs-sidebar__badge {
    position: absolute !important;
    top: -2px !important;
    right: -7px !important;
    min-width: 24px !important;
    height: 24px !important;
    padding: 0 5px !important;
    color: #fff !important;
    font-size: 10px !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    border-radius: 999px !important;
    border: 2px solid var(--sidebar-bg) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    margin: 0 !important;
}
/* When the parent item is active, the icon sits on a blue tile — invert the
   badge to white with navy text so it reads cleanly against the active fill. */
html.sidebar-collapsed .ccs-sidebar__item--active .ccs-sidebar__badge {
    background: #ffffff !important;
    color: var(--sidebar-bg) !important;
    border-color: var(--sidebar-active-bg) !important;
}
html.sidebar-collapsed .ccs-sidebar__footer {
    padding: 12px 8px;
}
html.sidebar-collapsed .ccs-sidebar__quicklinks { padding: 12px 8px; }
html.sidebar-collapsed .ccs-sidebar__quicklinks-label { display: none !important; }

/* Skye AI badge, above Quick Links. The AI look (purple into navy) as a
   tinted card with a gradient edge, so it reads as AI without shouting
   louder than the nav above it. Collapsed, it is just the spark. */
.ccs-sidebar__ai-wrap { padding: 10px 16px 14px; }
.ccs-sidebar__ai { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; text-decoration: none;
    width: 100%; text-align: left; font: inherit; cursor: pointer;
    border: 1px solid transparent; color: #fff;
    background: linear-gradient(135deg, rgba(124, 58, 237, .28), rgba(30, 58, 138, .32)) padding-box,
                linear-gradient(135deg, #7C3AED, #1E3A8A) border-box; }
/* dashboard.css rounds every <button> to 6px with !important; an ID clears it. */
#ccs-ai-badge { border-radius: 10px !important; }
#ccs-ai-badge:focus-visible { outline: 2px solid #A78BFA; outline-offset: 2px; }
.ccs-sidebar__ai:hover, a.ccs-sidebar__ai:hover { background: linear-gradient(135deg, rgba(124, 58, 237, .4), rgba(30, 58, 138, .45)) padding-box,
                linear-gradient(135deg, #8B5CF6, #2747A8) border-box; color: #fff; }
.ccs-sidebar__ai-spark { width: 28px; height: 28px; border-radius: 8px; flex: none; display: grid; place-items: center; font-size: 14px;
    background: linear-gradient(135deg, #7C3AED, #1E3A8A); color: #fff; box-shadow: 0 4px 12px rgba(67, 56, 202, .4); }
.ccs-sidebar__ai-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ccs-sidebar__ai-title { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.ccs-sidebar__ai-pill { font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: 2px 6px; border-radius: 999px;
    background: rgba(196, 181, 253, .18); color: #DDD6FE; }
.ccs-sidebar__ai-sub { font-size: 11.5px; color: rgba(221, 214, 254, .75); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.sidebar-collapsed .ccs-sidebar__ai-wrap { padding: 10px 8px 12px; }
html.sidebar-collapsed .ccs-sidebar__ai { justify-content: center; padding: 8px; }
html.sidebar-collapsed .ccs-sidebar__ai-body { display: none; }

/* The credits popup the badge opens. Fixed and placed beside the badge by
   JS, because the sidebar scrolls and would clip it. App surface tokens, so
   it follows light and dark like every other panel. */
.ccs-ai-pop { position: fixed; z-index: 1200; width: 320px; max-width: calc(100vw - 24px); display: flex; flex-direction: column; gap: 14px;
    padding: 16px; border-radius: 14px; background: var(--color-surface); color: var(--color-text);
    border: 1px solid var(--color-border); box-shadow: 0 24px 60px -18px rgba(30, 27, 75, .45); }
.ccs-ai-pop[hidden] { display: none; }
.ccs-ai-pop__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ccs-ai-pop__title { font-family: var(--font-display); font-size: 15px; font-weight: 600; }
.ccs-ai-pop__pill { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: 3px 8px; border-radius: 999px;
    background: rgba(124, 58, 237, .12); color: #6D28D9; }
[data-theme="dark"] .ccs-ai-pop__pill { color: #C4B5FD; background: rgba(139, 92, 246, .2); }
.ccs-ai-pop__balance, .ccs-ai-pop__used, .ccs-ai-pop__packs { display: flex; flex-direction: column; gap: 6px; }
.ccs-ai-pop__used, .ccs-ai-pop__packs { border-top: 1px solid var(--color-border); padding-top: 12px; }
.ccs-ai-pop__n { font-family: var(--font-display); font-size: 28px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.ccs-ai-pop__n small { font-family: inherit; font-size: 13px; font-weight: 500; color: var(--color-text-secondary); }
.ccs-ai-pop__meter { height: 8px; border-radius: 4px; background: var(--color-border); overflow: hidden; }
.ccs-ai-pop__meter i { display: block; height: 100%; border-radius: 4px; background: linear-gradient(90deg, #7C3AED, #1E3A8A); }
.ccs-ai-pop__note { font-size: 12px; line-height: 1.45; color: var(--color-text-secondary); }
.ccs-ai-pop__label { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-tertiary, #9ca3af); }
.ccs-ai-pop__row { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; font-variant-numeric: tabular-nums; }
.ccs-ai-pop__row span:last-child { color: var(--color-text-secondary); }
.ccs-ai-pop__row em { font-style: normal; font-size: 10.5px; font-weight: 700; color: #6D28D9; margin-left: 4px; }
[data-theme="dark"] .ccs-ai-pop__row em { color: #C4B5FD; }
.ccs-ai-pop__row--empty, .ccs-ai-pop__row--free { color: var(--color-text-secondary); }
.ccs-ai-pop__cta { justify-content: center; }
html.sidebar-collapsed .ccs-sidebar__group { display: none !important; }
/* Icon rail: there are no headers to expand, so section-collapse must not hide
   any item — every module shows as an icon regardless of its group state. */
html.sidebar-collapsed .ccs-sidebar__menu > li.ccs-nav-hidden { display: block !important; }
html.sidebar-collapsed .ccs-sidebar__user {
    justify-content: center;
    gap: 0;
}

/* Hover tooltips for icon-only items are rendered by JS (position:fixed
   chip appended to <body>) because .ccs-sidebar__nav has overflow-y:auto
   which clips any CSS-only absolute tooltip at the rail's right edge. */
html.sidebar-collapsed .ccs-sidebar__item { overflow: visible; }

/* Submenu flyout when collapsed.
   For top-level items that have a child <ul id="…-submenu">, hovering the row
   reveals the children as an absolutely-positioned panel next to the icon.
   This is the only way to reach child pages without un-collapsing the rail.
   :has() lets us suppress the parent's plain label-tooltip on the same row so
   the flyout doesn't fight a redundant tooltip beside it. */
html.sidebar-collapsed .ccs-sidebar__menu > li { position: relative; }
html.sidebar-collapsed .ccs-sidebar__menu > li:has(> ul[id$="-submenu"]) > a .ccs-sidebar__label {
    display: none !important;
}
/* Flyout open state. We can't use a pure CSS hover here because the parent
   .ccs-sidebar__nav has overflow-y: auto (which also clips horizontally),
   so the panel would be cut off at the sidebar's right edge. The companion
   JS in dashboard.js positions the panel with position:fixed using inline
   top/left set per-row on mouseenter, and toggles this class. */
html.sidebar-collapsed .ccs-sidebar__menu ul[id$="-submenu"].is-flyout-open {
    display: block !important;
    position: fixed !important;
    margin: 0 !important;
    padding: 6px !important;
    min-width: 200px;
    max-height: none !important;
    overflow: visible !important;
    background: #0f172a;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
    z-index: 1000;
}
/* Children inside the flyout: undo the inline padding-left:48px/font-size:13px
   that makes sense for nested rows in expanded mode but looks broken in a
   floating panel. */
html.sidebar-collapsed .ccs-sidebar__menu > li > ul[id$="-submenu"] > li > a.ccs-sidebar__item {
    padding: 8px 10px !important;
    justify-content: flex-start !important;
    gap: 10px !important;
    border-radius: 6px;
}
/* Override the label-as-tooltip styling for child labels — inside the flyout
   they should render as plain inline text, not floating popovers. */
html.sidebar-collapsed .ccs-sidebar__menu > li > ul[id$="-submenu"] .ccs-sidebar__label {
    display: inline !important;
    position: static !important;
    transform: none !important;
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    font-size: 13px;
    font-weight: 500;
    color: inherit;
}

.ccs-sidebar__nav {
    flex: 1;
    overflow-y: auto;
    padding: 12px 12px;
}

.ccs-sidebar__menu {
    list-style: none;
}

.ccs-sidebar__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: var(--radius-md);
    color: var(--sidebar-text);
    font-size: 14px;
    font-weight: 500;
    transition: all var(--transition-fast);
    margin-bottom: 2px;
}

.ccs-sidebar__item:hover {
    color: var(--sidebar-text-hover);
    background: #192031;
}

.ccs-sidebar__item--active {
    color: var(--sidebar-active-text);
    background: var(--sidebar-active-bg);
    opacity: 1;
}

.ccs-sidebar__item--active:hover {
    color: var(--sidebar-active-text);
    background: var(--sidebar-active-bg);
}

.ccs-sidebar__icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

/* Collapsible section headers. Deliberately styled UNLIKE a nav link — small
   uppercase muted label, dimmed icon, rotating chevron — so the eye reads them
   as section dividers, not destinations. Each owns the run of items beneath it
   (tagged by JS); the run hides when the header is closed. Only render when a
   section has 2+ enabled modules. See partials/admin/sidebar.blade.php. */
.ccs-sidebar__group {
    list-style: none;
    margin: 14px 0 2px;
    /* Carry the open block's 4px top/side padding even when collapsed, so a
       header's button doesn't jump 4px right/down the moment its group opens —
       opening only swaps in the recess background. .is-open adds the matching
       4px bottom for the header→first-item gap. */
    padding: 4px 4px 0;
}
.ccs-sidebar__menu > .ccs-sidebar__group:first-child {
    margin-top: 4px;
}
.ccs-sidebar__group-break { display: none; }
/* When a section's header is suppressed (a single-item section promoted to just
   its item), that item follows a group-break instead of a header. Give it the
   same top gap a group header carries (margin:14px…), so section spacing stays
   consistent whether the section shows a header or a lone promoted item. Only a
   real item qualifies — a following header or another break is excluded. */
.ccs-sidebar__group-break + li:not(.ccs-sidebar__group):not(.ccs-sidebar__group-break) { margin-top: 14px; }

/* ── Sidebar link tiers ──────────────────────────────────────────────────────
   Tier 1  top-level rows: Dashboard, group headers, and any single-item section
           promoted to just its item — 12px inset (the .ccs-sidebar__item base).
   Tier 2  rows inside a group (li[data-group], set by the grouping script) — 24px
           (see the li[data-group] > .ccs-sidebar__item rule below).
   Tier 3  submenu children under a Tier-2 row — 48px (inline on the child link).
   PROMOTION: when a section holds one item its header is dropped, so the item
   rises to Tier 1 (no data-group → base 12px, already handled) and its submenu
   children must shift up from Tier 3 to Tier 2. That single cascade rule: */
.ccs-sidebar__menu > li:not([data-group]) > ul[id$="-submenu"] .ccs-sidebar__item {
    padding-left: 24px !important; /* Tier 3 → Tier 2 when the parent is promoted */
}
.ccs-sidebar__group-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    /* Match the nav-item box exactly so a selected section tab is the same size
       as the Dashboard active pill (same padding all around + radius). */
    padding: 10px 12px;
    border-radius: var(--radius-md);
    background: none;
    border: 0;
    cursor: pointer;
    color: var(--sidebar-text);
    font-family: inherit;
    text-align: left;
    transition: color var(--transition-fast), background var(--transition-fast);
}
/* Drop the blue click-ring so the open tab reads as a clean filled tab, not an
   outlined box — keep a focus ring for keyboard users only. */
.ccs-sidebar__group-btn:focus { outline: none; }
.ccs-sidebar__group-btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}
.ccs-sidebar__group-btn:hover {
    color: var(--sidebar-text-hover);
    background: #192031;
    border-radius: var(--radius-md);
}
.ccs-sidebar__group-btn:hover .ccs-sidebar__group-icon { opacity: 1; }
/* Icon + label match a nav row exactly (20px icon, 14px/500 text, same start
   x), so a section header reads like a Dashboard-style row — the chevron is what
   marks it as an expandable group, not a different text treatment. */
.ccs-sidebar__group-icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}
.ccs-sidebar__group-icon svg {
    width: 20px;
    height: 20px;
}
.ccs-sidebar__group-label {
    flex: 1;
    font-size: 14px;
    font-weight: 500;
    user-select: none;
}
.ccs-sidebar__group-chev {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    opacity: 0.55;
    transform: rotate(-90deg);
    transition: transform 0.2s;
}
.ccs-sidebar__group.is-open .ccs-sidebar__group-chev { transform: rotate(0deg); }

/* OPEN but not the active section = merely expanded. Give it the same subtle
   neutral highlight as hover — opening a group shows you it's expanded, it does
   NOT claim "you are here". Blue is earned only by containing the active page. */
.ccs-sidebar__group.is-open {
    margin-bottom: 3px;
}
.ccs-sidebar__group.is-open .ccs-sidebar__group-btn {
    color: var(--sidebar-text-hover);
    background: #192031;
    border-radius: var(--radius-md);
}
.ccs-sidebar__group.is-open .ccs-sidebar__group-icon {
    opacity: 1;
}
.ccs-sidebar__group.is-open .ccs-sidebar__group-chev {
    opacity: 0.9;
}

/* TIER 1 — the section that CONTAINS the active page gets the full solid blue,
   identical to the Dashboard active pill. (It's always open too.) Defined after
   .is-open so it overrides the neutral look. Same blue = "this is where you
   are", whether that's the Dashboard row or the active group's header. */
.ccs-sidebar__group.is-active .ccs-sidebar__group-btn {
    color: var(--sidebar-active-text);
    background: var(--sidebar-active-bg);
    border-radius: var(--radius-md);
}
.ccs-sidebar__group.is-active .ccs-sidebar__group-icon {
    opacity: 1;
}
.ccs-sidebar__group.is-active .ccs-sidebar__group-label {
    color: var(--sidebar-active-text);
}
.ccs-sidebar__group.is-active .ccs-sidebar__group-chev {
    opacity: 1;
}

/* Items hidden because their section is collapsed. */
.ccs-nav-hidden { display: none !important; }

/* ── Open group = one recessed block ─────────────────────────────────────────
   When a section is expanded, the header AND its run of items share one fill a
   touch DARKER than the sidebar (a navy-black recess), with a few px of inner
   padding and rounded ends — so the whole open group reads as a single sunken
   container, and the lighter active pill inside pops against it instead of
   blending in. JS tags the visible run (.ccs-group-item-open) and the final
   row (.ccs-group-item-last). Skipped in icon-collapsed mode, where groups are
   hidden and items render as centered icons. */
html:not(.sidebar-collapsed) .ccs-sidebar__group.is-open,
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-group-item-open {
    background: #05080e;
}
html:not(.sidebar-collapsed) .ccs-sidebar__group.is-open {
    margin-bottom: 0;
    padding: 4px;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-group-item-open {
    display: flow-root;
    padding-left: 4px;
    padding-right: 4px;
}
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-group-item-open.ccs-group-item-last {
    padding-bottom: 4px;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}
/* 4px gaps between every row inside the open group — matching the block's 4px
   perimeter padding — coloured with the #05080e recess. flow-root on the
   open-group <li> contains each row's margin instead of letting a plain row's
   collapse out to a lighter sidebar-coloured seam (while a dropdown row's
   stayed in). Covers the row anchor and its submenu children; the last row is
   zeroed so the block's 4px bottom padding isn't doubled. */
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-group-item-open .ccs-sidebar__item {
    margin-bottom: 4px;
}
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-group-item-open.ccs-group-item-last > .ccs-sidebar__item {
    margin-bottom: 0;
}
/* …and when that last group row is an EXPANDED dropdown, its last submenu child
   is the real final row — zero its margin too, so the block keeps a single 4px
   bottom padding instead of 4px child margin + 4px block padding. */
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-group-item-open.ccs-group-item-last ul > li:last-child > .ccs-sidebar__item {
    margin-bottom: 0;
}

/* Promoted single-item section that's expandable (e.g. events-standalone People,
   now Tier 1) gets a recessed block like a Tier-2 open group — one #05080e
   container wrapping the parent row + its submenu. Top padding is 0 on purpose:
   the parent row is ALSO an ungrouped top-level row when collapsed (e.g. People
   on the Dashboard), so any top padding here would nudge the row down ~4px the
   moment it expands, making it "jump" when you navigate to it. Keeping top at 0
   pins the parent row at the exact same Y in both states; the recess still reads
   via the fill + bottom padding under the submenu. Side padding comes from the
   ungrouped-row rule below (4px). */
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li.ccs-sidebar__solo-open {
    background: #05080e;
    padding-top: 0;
    padding-bottom: 4px;
    border-radius: var(--radius-md);
    display: flow-root;
    margin-bottom: 3px;
}
html:not(.sidebar-collapsed) .ccs-sidebar__solo-open > .ccs-sidebar__item,
html:not(.sidebar-collapsed) .ccs-sidebar__solo-open ul > li > .ccs-sidebar__item {
    margin-bottom: 4px;
}
html:not(.sidebar-collapsed) .ccs-sidebar__solo-open ul > li:last-child > .ccs-sidebar__item {
    margin-bottom: 0;
}

/* Ungrouped top-level rows (Dashboard, plus the connector view's flat list)
   get the same 4px side padding the group headers carry, so every top-level
   icon — and active pill — lines up at one inset instead of Dashboard sitting
   4px left of the headers. data-group is JS-set on grouped rows, so :not()
   here matches only the ungrouped ones. */
html:not(.sidebar-collapsed) .ccs-sidebar__menu > li:not([data-group]):not(.ccs-sidebar__group):not(.ccs-sidebar__group-break) {
    padding-left: 4px;
    padding-right: 4px;
}

/* Top-level nav rows that start a new cluster (e.g. Workspace Access, Invites)
   get breathing room above them — as a class, not an inline margin. */
.ccs-sidebar__menu > li.ccs-sidebar__item-gap { margin-top: 14px; }

/* Section headers and ungrouped rows share the 4px inset above. The module
   links inside a section indent ~20px more so they read as nested beneath
   their header. Only the row's own <a> is padded (not the <li>), so submenu
   children keep their deeper inline indent relative to it. */
.ccs-sidebar__menu > li[data-group] > .ccs-sidebar__item {
    padding-left: 24px;
}
/* Icon rail: strip the indent so icons stay centered. */
html.sidebar-collapsed .ccs-sidebar__menu > li[data-group] > .ccs-sidebar__item {
    padding-left: 0;
}

/* TIER 2 — an active module link inside a section sits at the MIDPOINT between
   the tier-1 solid blue (alpha 1.0) and the tier-3 submenu pill (alpha 0.16):
   ~0.55 of the same blue, white text. So the active path reads as one blue in
   three descending strengths: solid header → mid link → soft submenu pill.
   Higher specificity than .ccs-sidebar__item--active, so it wins (incl. hover);
   ungrouped active items (Dashboard, lone links) keep the tier-1 solid blue. */
.ccs-sidebar__menu > li[data-group] > .ccs-sidebar__item--active {
    background: rgba(18, 100, 255, 0.45);
    color: var(--sidebar-active-text);
}

/* TIER 3 — active submenu child = a soft brand-tinted pill (set inline in the
   markup so it survives AJAX row swaps). Together the three tiers read as one
   blue at descending strength: solid (Dashboard / open group) → mid (active
   link) → soft pill (active submenu child). */

.ccs-sidebar__badge {
    margin-left: auto;
    background: var(--color-danger);
    color: white;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 10px;
    line-height: 1.4;
}

.ccs-sidebar__footer {
    padding: 16px 16px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.ccs-sidebar__user {
    display: flex;
    align-items: center;
    gap: 12px;
}

.ccs-sidebar__avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: rgba(20, 95, 255, 0.2);
    color: #5b9aff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 14px;
    flex-shrink: 0;
}

.ccs-sidebar__user-name {
    display: block;
    color: #e2e8f0;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.3;
}

.ccs-sidebar__user-role {
    display: block;
    color: var(--sidebar-text);
    font-size: 12px;
}

/* --------------------------------------------------------------------------
   Header Bar
   -------------------------------------------------------------------------- */
.ccs-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--header-height);
    padding: 0 32px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: 50;
}

.ccs-header__left {
    display: flex;
    align-items: center;
    gap: 12px;
    /* flex:1 on both edge clusters lets the fixed-width search bar
       in the middle stay viewport-centered no matter how wide the
       workspace name (left) or the pill + icon bar (right) grow. */
    flex: 1;
}

.ccs-header__menu-btn {
    display: none;
    background: none;
    border: none;
    color: var(--color-text-secondary);
    cursor: pointer;
    padding: 4px;
}

.ccs-header__breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
}

.ccs-header__breadcrumb-link {
    color: var(--color-text-secondary);
}

.ccs-header__breadcrumb-link:hover {
    color: var(--color-text);
}

.ccs-header__breadcrumb-sep {
    color: var(--color-text-tertiary);
    font-size: 12px;
}

.ccs-header__breadcrumb-current {
    color: var(--color-text);
    font-weight: 500;
}

.ccs-header__right {
    display: flex;
    align-items: center;
    gap: 2px;
}
.ccs-header__right > .ccs-header__search { margin-right: 10px; }
.ccs-header__right > .ccs-header__user-menu { margin-left: 10px; }

.ccs-header__search {
    position: relative;
    width: 320px;
}

.ccs-header__search-icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-text-tertiary);
    display: flex;
}

.ccs-header__search-input {
    width: 100%;
    padding: 8px 12px 8px 38px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg);
    font-size: 13px;
    font-family: inherit;
    color: var(--color-text);
    transition: all var(--transition-fast);
}

.ccs-header__search-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-bg);
    background: var(--color-surface);
}

.ccs-header__search-input::placeholder {
    color: var(--color-text-tertiary);
}


.ccs-header__notification {
    position: relative;
    color: var(--color-text-secondary, #6b7280);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    background: transparent;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    transition: color 0.12s;
    text-decoration: none;
    overflow: hidden;
}

.ccs-header__notification:hover {
    color: var(--color-text, #111827);
}

.ccs-header__push-ccc:hover {
    background: var(--color-primary) !important;
    color: #fff !important;
}

.ccs-header__notification-badge {
    position: absolute;
    top: 4px;
    right: 4px;
    background: var(--color-danger);
    color: white;
    font-size: 10px;
    font-weight: 700;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--color-surface);
}

.ccs-header__user-menu {
    position: relative;
    display: flex;
    align-items: center;
}

.ccs-header__user-btn {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
}

.ccs-header__user-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--color-primary-light);
    color: var(--color-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 14px;
}

.ccs-header__dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    min-width: 180px;
    z-index: 60;
    overflow: hidden;
}

.ccs-header__dropdown.is-open {
    display: block;
}

.ccs-header__dropdown-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    font-size: 14px;
    color: var(--color-text);
    transition: background var(--transition-fast);
}

.ccs-header__dropdown-item:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Unified Header Icon Bar (HIB) — shared right-side icons across all portals
   -------------------------------------------------------------------------- */
.ccs-hib {
    display: flex;
    align-items: center;
    gap: 2px;
}

.ccs-hib__btn {
    position: relative;
    color: var(--color-text-secondary, #6b7280);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    background: transparent;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    transition: color 0.12s;
    text-decoration: none;
}

.ccs-hib__btn:hover {
    color: var(--color-text, #111827);
}

/* A pill, not a fixed circle: "9+" and "12" were cramped inside an 18px
   round at 10px type. It grows with its number and sits on the bell's
   corner rather than on top of the glyph. */
.ccs-hib__badge {
    position: absolute;
    top: -3px;
    right: -4px;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    background: var(--color-danger, #ef4444);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    border: 2px solid var(--color-surface, #fff);
    box-shadow: var(--shadow-sm);
}

.ccs-hib__user {
    position: relative;
    margin-left: 6px;
}

.ccs-hib__user-btn {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
}

.ccs-hib__dropdown {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    margin-top: 8px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border-light, #e5e7eb);
    border-radius: 12px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    min-width: 220px;
    z-index: 200;
    overflow: hidden;
}

.ccs-hib__dropdown.is-open {
    display: block;
}

.ccs-hib__dropdown-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border-light, #f2f6fb);
}

.ccs-hib__dropdown-header__name {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text, #111827);
}

.ccs-hib__dropdown-header__email {
    font-size: 12px;
    color: var(--color-text-tertiary, #9ca3af);
}

.ccs-hib__dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    text-decoration: none;
    color: var(--color-text, #111827);
    font-size: 13px;
    font-weight: 500;
    transition: background 0.1s;
    border: none;
    background: none;
    width: 100%;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
}

.ccs-hib__dropdown-item:hover {
    background: var(--color-bg, #f9fafb);
}

.ccs-hib__dropdown-item--danger {
    color: var(--color-text-tertiary, #9ca3af);
}

.ccs-hib__dropdown-item--danger:hover {
    color: #ef4444;
}

.ccs-hib__dropdown-sep {
    border-top: 1px solid var(--color-border-light, #f2f6fb);
}

/* Notification dropdown */
.ccs-hib__notif-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 380px;
    max-height: 480px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border-light, #e5e7eb);
    border-radius: 12px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
    z-index: 200;
    overflow: hidden;
}

.ccs-hib__notif-head {
    padding: 14px 18px;
    border-bottom: 1px solid var(--color-border-light, #e5e7eb);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.ccs-hib__notif-head__title {
    font-size: 15px;
    font-weight: 700;
    color: var(--color-text, #111827);
}

.ccs-hib__notif-mark-all {
    font-size: 12px;
    font-weight: 500;
    color: var(--color-primary, #1264FF);
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
}

.ccs-hib__notif-list {
    max-height: 360px;
    overflow-y: auto;
}

.ccs-hib__notif-item {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 13px 18px;
    text-decoration: none;
    color: inherit;
    border-bottom: 1px solid var(--color-border-light, #f2f6fb);
    transition: background 0.12s ease;
}

.ccs-hib__notif-item:last-of-type {
    border-bottom: 0;
}

.ccs-hib__notif-item:hover {
    background: var(--color-surface-hover, #f2f6fb);
}

/* Unread is a wash, not a highlight — see the same note on .nfeed-item. */
.ccs-hib__notif-item--unread {
    background: var(--color-primary-bg, rgba(20, 95, 255, 0.08));
    box-shadow: inset 3px 0 0 var(--color-primary, #145fff);
}

/* Same category icon the inbox pages show, so the bell and the full list
   read as one thing rather than two designs of the same row. */
.ccs-hib__notif-icon {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-lg, 12px);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: var(--color-surface-secondary, #f9fafb);
    color: var(--color-text-tertiary, #9ca3af);
}

.ccs-hib__notif-item--unread .ccs-hib__notif-icon {
    background: var(--color-surface, #fff);
    color: var(--color-primary, #145fff);
}

/* The dot is always drawn — only its color changes. Hiding it on read rows
   left an empty 8px gutter, so read items looked mis-indented next to unread
   ones instead of simply calmer. */
.ccs-hib__notif-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    align-self: center;
    background: var(--color-border, #e5e7eb);
}

.ccs-hib__notif-dot--unread {
    background: var(--color-primary, #145fff);
}

.ccs-hib__notif-body {
    flex: 1;
    min-width: 0;
}

.ccs-hib__notif-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text, #111827);
    line-height: 1.4;
}

.ccs-hib__notif-title--unread {
    font-weight: 600;
}

.ccs-hib__notif-text {
    font-size: 12px;
    color: var(--color-text-secondary, #6b7280);
    line-height: 1.45;
    margin-top: 2px;
}

.ccs-hib__notif-time {
    font-size: 11px;
    color: var(--color-text-tertiary, #9ca3af);
    margin-top: 4px;
}

/* Which workspace a row came from — only rendered when that isn't the one
   you're currently in. See partials/header-notifications.blade.php. */
.ccs-hib__notif-ws {
    font-weight: 600;
}

.ccs-hib__notif-empty {
    padding: 40px 20px;
    text-align: center;
    color: var(--color-text-tertiary, #9ca3af);
}

.ccs-hib__notif-empty__icon {
    margin-bottom: 6px;
}

.ccs-hib__notif-empty__text {
    font-size: 13px;
}

.ccs-hib__notif-footer {
    display: flex;
    border-top: 1px solid var(--color-border-light, #e5e7eb);
}

.ccs-hib__notif-footer a {
    flex: 1;
    padding: 12px 18px;
    text-align: center;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-primary, #1264FF);
    text-decoration: none;
    transition: background 0.1s;
}

.ccs-hib__notif-footer a:hover {
    background: var(--color-bg, #f9fafb);
}

.ccs-hib__notif-footer a + a {
    color: var(--color-text-secondary, #6b7280);
    border-left: 1px solid var(--color-border-light, #e5e7eb);
}

/* --------------------------------------------------------------------------
   Page Header
   -------------------------------------------------------------------------- */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 24px;
}

.page-header__left {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.page-header__title {
    font-size: 28px;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.3;
}

.page-header__subtitle {
    font-size: 14px;
    color: var(--color-text-secondary);
}

.page-header__actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-border-light);
}

/* Use when a header contains a form control (select, input). The taller
   control would otherwise make the default 16px padding look top-heavy. */
.card__header--with-control {
    padding-top: 12px;
    padding-bottom: 12px;
}

.card__title {
    font-size: 15px;
    font-weight: 600;
    color: var(--color-text);
    margin: 0;
}

.card__body {
    padding: 20px;
}

/* A sentence a card genuinely needs (a warning, a privacy note, how it
   behaves). It lives at the top of the BODY — a card header is its title and
   nothing under it. Inside .card__body it is a lead paragraph; placed straight
   in .card (above a table) it carries the body's own padding. */
.card__lead {
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-text-secondary);
    margin: 0 0 16px;
}
.card > .card__lead {
    margin: 0;
    padding: 14px 20px 0;
}
.card > .card__lead + .card__body { padding-top: 12px; }
.card > .card__lead + .data-table-wrapper,
.card > .card__lead + table,
.card > .card__lead + div > table { margin-top: 12px; }
.card__lead--warn { color: var(--color-warning, #b45309); display: flex; align-items: flex-start; gap: 6px; }
.card__lead--warn svg { flex-shrink: 0; margin-top: 2px; }
.card__lead strong { color: var(--color-text); font-weight: 600; }

.card__footer {
    padding: 12px 20px;
    border-top: 1px solid var(--color-border-light);
}

/* --------------------------------------------------------------------------
   Side nav — global vertical tab list for detail/settings pages.
   Works on <a> (page tabs) and <button> (in-page tabs). Promoted from the
   events shell so every module shares one definition. `.event-side-nav` is
   aliased here so the events shell renders from this same source.
   -------------------------------------------------------------------------- */
.side-nav,
.event-side-nav { position: sticky; top: 80px; display: flex; flex-direction: column; gap: 2px; }
.side-nav__item,
.event-side-nav__item {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 10px 14px; border-radius: 8px;
    font-family: inherit; font-size: 14px; font-weight: 500; text-align: left;
    text-decoration: none; cursor: pointer; transition: all 0.12s;
    background: none; border: none; border-left: 3px solid transparent;
    color: var(--color-text-secondary, #6b7280);
}
.side-nav__item:hover,
.event-side-nav__item:hover { background: var(--color-surface-secondary, #f9fafb); color: var(--color-text, #111827); }
.side-nav__item.is-active,
.event-side-nav__item.is-active { color: var(--color-primary, #145fff); background: var(--color-primary-light, #eff6ff); border-left-color: var(--color-primary, #145fff); font-weight: 600; }
.side-nav__item svg,
.event-side-nav__item svg { flex: none; }
@media (max-width: 820px) {
    .side-nav,
    .event-side-nav { position: static; flex-direction: row; flex-wrap: wrap; }
    .side-nav__item,
    .event-side-nav__item { padding: 8px 12px; }
}

/* --- Stacked / connected cards -------------------------------------------
   Apply when a card needs to read as a continuation of the card before or
   after it — same outer outline, divider line in between, no doubled border
   or rounded gap. Used by Settings > Modules and Settings > Roles where the
   header card + list cards should look like one long card. */
.card--connect-down {
    /* This card has another card stacked DIRECTLY below it. */
    margin-bottom: 0 !important;
    border-bottom-left-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}
.card--connect-up {
    /* This card has another card stacked DIRECTLY above it. */
    margin-top: 0 !important;
    border-top: 0 !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}

/* --- Plain tables ----------------------------------------------------------
   `.table` / `.table-wrap` were being written in eight views with nothing
   behind them, so Booking and Meals rendered browser-default tables next to
   the rest of Studio. Same geometry as `.data-table` — the cells supply the
   card's horizontal gutter, so it sits flush in a `.card` with no
   `.card__body` around it. Use `.data-table` for a sortable, selectable list;
   this is the quiet one. */
.table-wrap { overflow-x: auto; }

.table {
    width: 100%;
    border-collapse: collapse;
}

.table thead {
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.table th {
    padding: 10px 0 10px 20px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary);
    text-align: left;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.table td {
    padding: 12px 0 12px 20px;
    font-size: 14px;
    border-bottom: 1px solid var(--color-border-light);
    vertical-align: middle;
}

.table th:last-child,
.table td:last-child { padding-right: 20px; }

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

.table--compact th { padding-top: 8px; padding-bottom: 8px; }
.table--compact td { padding-top: 8px; padding-bottom: 8px; }

/* Inside an already-padded container (a card body, a subcard section) the
   cells must not add the card gutter a second time. */
.table--flush th:first-child,
.table--flush td:first-child { padding-left: 0; }
.table--flush th:last-child,
.table--flush td:last-child { padding-right: 0; }

/* --- Card stack ------------------------------------------------------------
   Vertical rhythm for cards stacked down a page. `.card` deliberately carries
   no margin of its own (grids and toolbars place it), so every page that
   stacked cards was inlining `style="margin-bottom:20px"` on each one and
   whichever card got missed collapsed against its neighbour. Wrap the run
   instead. */
.card-stack { display: flex; flex-direction: column; gap: 20px; }

/* --- Subcards --------------------------------------------------------------
   A panel nested INSIDE a card body — one host, one member, one connected
   account: a repeated record that owns several sections of its own. It is
   deliberately quieter than `.card` (no shadow, lighter corner) so the
   nesting reads as one level down rather than as a second page.
   -------------------------------------------------------------------------- */
.subcard {
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    overflow: hidden;
}

.subcard + .subcard { margin-top: 16px; }

.subcard__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 16px;
    background: var(--color-surface-secondary);
    border-bottom: 1px solid var(--color-border-light);
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text);
}

.subcard__body { padding: 16px; }

/* Each run of fields inside a subcard, ruled off from the one above it. The
   first section sits flush against the header, which already has its own rule. */
.subcard__section { padding: 16px; }
.subcard__section + .subcard__section,
.subcard__body + .subcard__section,
.subcard__section + .subcard__body { border-top: 1px solid var(--color-border-light); }

/* A subcard section that is itself a form — the trailing .form-actions rule
   would otherwise double up with the section divider below it. */
.subcard__section > form:last-child > .form-actions:last-child { border-top: 0; padding-top: 12px; }
.subcard__section > .form-group:last-child,
.subcard__section > form > .form-group:last-child { margin-bottom: 0; }

/* --- Form sections ---------------------------------------------------------
   Groups of fields inside one card body, ruled off from each other. Reach for
   this before a second card: a settings form split across four cards reads as
   four things to save when there is only one Save button. */
.form-section + .form-section {
    margin-top: 24px;
    padding-top: 24px;
    border-top: 1px solid var(--color-border-light);
}
.form-section > .form-group:last-child,
.form-section > .form-row:last-child > .form-group { margin-bottom: 0; }
/* A row whose only successor is a conditionally-hidden field is the last row
   the reader sees, so it must not leave that field's gap behind it. The
   selector stops matching the moment the field is revealed. */
.form-section > .form-row:has(+ .form-group[style*="display:none"]) > .form-group { margin-bottom: 0; }

.form-section__title,
.subcard__subtitle {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-tertiary);
    margin: 0 0 14px;
}

/* --- Inline checkbox row ---------------------------------------------------
   A checkbox that sits on one line with its label. `.form-switch` is the
   toggle for a setting that takes effect on save; this is the plain box for
   a list of choices (weekdays, filters) where a row of sliders would read as
   six separate settings. */
.checkbox {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 14px;
    color: var(--color-text);
    cursor: pointer;
    line-height: 1.4;
}

.checkbox input[type="checkbox"] {
    flex: none;
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.checkbox + .checkbox { margin-top: 10px; }

/* --- Plain list ------------------------------------------------------------
   An unbulleted list of records with a rule between them — days off, linked
   accounts, anything short of a table. */
.plain-list { list-style: none; margin: 0 0 14px; padding: 0; }

.plain-list > li {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 0;
    border-bottom: 1px solid var(--color-border-light);
    font-size: 14px;
}

.plain-list > li:first-child { padding-top: 0; }
.plain-list > li:last-child { border-bottom: 0; padding-bottom: 0; }

/* --- Copy field ------------------------------------------------------------
   A read-only URL beside its Copy button. Every surface that hands over a
   link was rebuilding this out of inline flex. */
.copy-field { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.copy-field > .form-input {
    flex: 1;
    min-width: 240px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px;
}

/* --------------------------------------------------------------------------
   Metric Cards
   -------------------------------------------------------------------------- */
.metrics-grid {
    display: grid;
    gap: 16px;
    margin-bottom: 24px;
    /* Auto-stretch — every direct child becomes an equal column, however many
       there are: 3 cards → 33% each, 4 → 25%, 5 → 20%, 6 → 16.6%. No caller
       has to declare a count for the common case.

       grid-template-columns MUST stay `none` here. tokens.css sets
       `repeat(auto-fit, minmax(150px, 1fr))` on this same class, and because
       that's a different property than the two below, it survived the cascade
       and quietly fought them — explicit auto-fit tracks laid out alongside
       implicit auto-flow ones, so the track count followed container width
       rather than card count and a fifth card could land on its own row.
       Resetting it here is what makes the count dynamic.

       minmax(0, 1fr) rather than 1fr so a long value ("Choose type", a big
       currency figure) can't push its own column wider than its siblings —
       a bare 1fr floors at min-content and the row stops being even.

       Callers that want a fixed shape still win on the cascade: inline
       grid-template-columns (the `columns` prop) beats this, and the
       .metrics-grid--N helpers below re-declare both properties. */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    grid-template-columns: none;
}
.metrics-grid--3 { grid-auto-flow: row; grid-template-columns: repeat(3, 1fr); }
.metrics-grid--2 { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr); }
.metrics-grid--5 { grid-auto-flow: row; grid-template-columns: repeat(5, 1fr); }

.metric-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    padding: 16px 20px;
    box-shadow: var(--shadow-sm);
    transition: border-color 150ms;
}

.metric-card__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}

.metric-card__label {
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-secondary);
    display: block;
    margin-bottom: 4px;
}

.metric-card__icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Name values keep the full 28px figure size so they read level with the stat
   beside them, but truncate instead of wrapping — a name has no natural break
   point, and two lines makes the card taller than every other one in the row. */
.metric-card--name .metric-card__value {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Values that are phrases rather than figures — "Apr 6, 2026", "18 days",
   "Overdue 4d". The 28px figure size is built for numbers you scan; a date at
   that size wraps to two lines and makes its card taller than the numeric ones
   beside it. Smaller value, same card. */
.metric-card--compact .metric-card__value {
    font-size: 19px;
    line-height: 1.45;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Checkbox rows in the person profile's company modal. Each has a hint line
   under the label, so the box aligns to the first line rather than centring
   against the whole two-line block. */
.pp-c-toggles {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0 0 var(--space-3);
    padding: 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-secondary);
}
.pp-c-toggle {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    cursor: pointer;
    font-size: 13px;
    color: var(--color-text);
    line-height: 1.45;
}
.pp-c-toggle input[type="checkbox"] {
    width: 15px;
    height: 15px;
    margin: 2px 0 0;
    accent-color: #1264FF;
    cursor: pointer;
    flex-shrink: 0;
}
.pp-c-toggle em {
    display: block;
    font-style: normal;
    font-size: 12px;
    color: var(--color-text-tertiary);
    margin-top: 1px;
}

.metric-card__icon--primary {
    background: #eff6ff;
    color: #1264FF;
}

.metric-card__icon--success {
    background: #ecfdf5;
    color: #059669;
}

.metric-card__icon--warning {
    background: #fffbeb;
    color: #d97706;
}

.metric-card__icon--danger {
    background: #fef2f2;
    color: #ef4444;
}

.metric-card__value {
    font-size: 28px;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
}

.metric-card__footer {
    margin-top: 4px;
    font-size: 13px;
    color: var(--color-text-secondary);
}

.metric-card__trend {
    font-weight: 600;
}

.metric-card__trend--up {
    color: var(--color-success);
}

.metric-card__trend--down {
    color: var(--color-danger);
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-fast);
    line-height: 1.4;
    white-space: nowrap;
}

.btn--primary {
    background: var(--color-primary);
    color: white;
    border-color: var(--color-primary);
}

.btn--primary:hover {
    background: var(--color-primary-hover);
    border-color: var(--color-primary-hover);
    color: white;
}

.btn--secondary {
    background: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border);
}

.btn--secondary:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

/* AI actions — anything that asks Skye to write or build. One look across the
   app, purple into navy, so an AI button is never mistaken for an ordinary
   one. Use it on every AI button rather than a one-off gradient. */
.btn--ai {
    background: linear-gradient(135deg, #7C3AED 0%, #1E3A8A 100%);
    background-size: 160% 160%;
    background-position: 0% 50%;
    color: #fff;
    border-color: transparent;
    box-shadow: 0 2px 10px rgba(67, 56, 202, .28);
    transition: background-position .35s ease, box-shadow var(--transition-fast), transform var(--transition-fast);
}

.btn--ai:hover {
    background-position: 100% 50%;
    color: #fff;
    box-shadow: 0 4px 16px rgba(67, 56, 202, .38);
}

.btn--ai:focus-visible {
    outline: 2px solid #818CF8;
    outline-offset: 2px;
}

.btn--ai:disabled,
.btn--ai[aria-disabled="true"] {
    opacity: .6;
    cursor: default;
    box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
    .btn--ai { transition: none; }
}

.btn--danger {
    background: var(--color-danger);
    color: white;
    border-color: var(--color-danger);
}

.btn--danger:hover {
    background: #b91c1c;
    border-color: #b91c1c;
    color: white;
}

.btn--success {
    background: var(--color-success);
    color: white;
    border-color: var(--color-success);
}

.btn--success:hover {
    background: #047857;
    border-color: #047857;
    color: white;
}

.btn--ghost {
    background: transparent;
    color: var(--color-text-secondary);
    border-color: transparent;
}

.btn--ghost:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

.btn--sm {
    padding: 6px 12px;
    font-size: 13px;
}

.btn--lg {
    padding: 12px 24px;
    font-size: 15px;
}

.btn--icon {
    padding: 8px;
}

/* Icon-only buttons (e.g. a "⋯" more-actions toggle in a button row) must
   match the height of their text-labeled siblings instead of collapsing to
   the icon. The min-height equals a single text line-box plus vertical
   padding + border, so text buttons are unaffected and icon-only buttons
   rise to the same height at every size. Global — every .btn-based dots
   button on every page lines up. The compact .btn--icon table variant is
   intentionally excluded so it stays square. */
.btn:not(.btn--icon)     { min-height: calc(1.4em + 20px); }
.btn--sm:not(.btn--icon) { min-height: calc(1.4em + 14px); }
.btn--lg:not(.btn--icon) { min-height: calc(1.4em + 26px); }

.btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Badges
   -------------------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    /* A pill is one shape, so it breaks as one or not at all. Inside a frozen
       table cell the surrounding overflow-wrap:anywhere would otherwise split
       it down the middle — a "Published" badge rendering as "Publishe / d"
       with the pill drawn around both halves. .ev-type-badge already did this;
       every other badge needs it for the same reason. */
    white-space: nowrap;
}

.badge--success {
    background: var(--color-success-bg);
    color: var(--color-success);
}

/* The only badge that takes the solid -light tint rather than the 8%-alpha -bg
   the others use. At 8% over the page's own grey the pill had no edge at all —
   it read as loose text, which is the opposite of what a warning chip is for.
   Deliberately heavier than its siblings: this is the one meant to catch you. */
.badge--warning {
    background: var(--color-warning-light);
    color: var(--color-warning-strong);
}

.badge--danger {
    background: var(--color-danger-bg);
    color: var(--color-danger);
}

.badge--default {
    background: var(--color-surface-hover);
    color: var(--color-text-secondary);
}

.badge--primary {
    background: var(--color-primary-bg);
    color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   Data Tables
   -------------------------------------------------------------------------- */
.data-table-wrapper {
    overflow-x: auto;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table thead {
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.data-table th {
    padding: 10px 0 10px 20px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary);
    text-align: left;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

/* Sortable column headers — <x-th-sort>. The anchor carries the click target
   rather than the whole <th> so the existing th padding/alignment rules (.money,
   .tc, :last-child) keep working untouched. */
.data-table th.th-sort { cursor: pointer; }
.data-table th.th-sort .th-sort__link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    text-decoration: none;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    transition: color var(--transition-fast);
}
.data-table th.th-sort .th-sort__link:hover { color: var(--color-text); }
.data-table th.th-sort .th-sort__link:focus-visible {
    outline: 2px solid var(--color-primary, #1264FF);
    outline-offset: 2px;
    border-radius: 3px;
}
/* Idle columns hint at the affordance on hover only — 8 permanently visible
   arrows across a header row reads as noise. */
.data-table th.th-sort .th-sort__arrow {
    opacity: 0;
    flex: none;
    transition: opacity var(--transition-fast);
}
.data-table th.th-sort:hover .th-sort__arrow { opacity: 0.45; }
.data-table th.th-sort--active { color: var(--color-text); }
.data-table th.th-sort--active .th-sort__arrow,
.data-table th.th-sort--active:hover .th-sort__arrow { opacity: 1; }
[data-theme="dark"] .data-table th.th-sort--active { color: var(--color-text) !important; }

.data-table td {
    padding: 12px 0 12px 20px;
    font-size: 14px;
    border-bottom: 1px solid var(--color-border-light);
    vertical-align: middle;
}

.data-table th.cb, .data-table td.cb { width: 15px; padding-right: 0; }
.data-table th.cb + th, .data-table td.cb + td { padding-left: 16px; }

.data-table th:last-child { padding-right: 20px; }
.data-table td:last-child { padding-right: 20px; }

.data-table tr:last-child td {
    border-bottom: none;
}

.data-table tbody tr {
    transition: background var(--transition-fast);
}

.data-table tbody tr:hover {
    background: var(--color-surface-hover);
}

.data-table__name {
    font-weight: 500;
    color: var(--color-text);
    line-height: 1.3;
}

.data-table__name a {
    color: var(--color-text);
}

.data-table__name a:hover {
    color: var(--color-primary);
}

/* A link to another record from inside a table cell — the name column's own
   anchor styling, available to the other columns. Four views already asked for
   this class (time entries, promo codes) and nothing had ever defined it, so
   they were rendering browser-default blue underlines inside the table. */
.data-table__link {
    color: var(--color-text);
    text-decoration: none;
    transition: color 0.12s;
}

.data-table__link:hover {
    color: var(--color-primary);
}

.data-table__sub {
    font-size: 13px;
    color: var(--color-text-secondary);
    margin-top: 1px;
    line-height: 1.35;
}

/* A sub-line holding a URL. One line, clipped with an ellipsis, rather than a
   long address wrapping over three and making every row a different height.
   Pair it with a title attribute: the ellipsis eats the end of the string, and
   for a URL the end is the part that says which one it is.

   The max-width is what makes text-overflow work at all. A table cell sizes to
   its content, so with nothing capping it the cell simply grows to fit the
   whole address and there is never any overflow to clip. */
.data-table__sub--url {
    display: block;
    max-width: 320px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A whole cell that reads as secondary — a tier name, a buyer, a timestamp.
   These kept borrowing .data-table__sub, which is the line UNDER a name and
   is 13px for that reason, so entire columns came out a size smaller than the
   ones beside them. Grey says "secondary"; it doesn't have to be small too.
   Inherits the table's 14px and only takes the colour. */
.data-table__muted {
    color: var(--color-text-secondary);
}

/* A value that reads as a single token — a date, a time, an amount. "Oct 6,
   2026" broken after the comma is never what you want, and inside a frozen
   cell the surrounding overflow-wrap:anywhere will break it mid-word instead.
   Keeping it whole also raises the column's min-content, which auto layout
   treats as a hard floor — so the width first measured for the column is one
   the value actually fits in. */
.data-table__nowrap {
    white-space: nowrap;
}

.data-table__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
}

/* The All / Archived row a module gets from partials._archive-tabs. Matches the
   padding People's hand-rolled tab row uses so the two read identically. */
.archive-tabs {
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-border-light);
}

/* The line above an Archived list explaining what the screen is. Same slot in
   every module that opts into the archive tab, so it reads as one feature
   rather than eight similar ones. */
.archive-note {
    margin: 0;
    padding: 12px 20px 0;
    font-size: 13px;
    color: var(--color-text-muted);
}

/* Row action icons. The set of icons in a row never changes — an action that
   doesn't apply to that row still renders, greyed to 15%, so every row's icon
   column lines up and nothing shifts sideways between rows. Pair with
   .data-table__actions-cell on the <td> so the column is right-aligned. */
.row-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-1);
    background: none;
    border: none;
    color: var(--color-text-tertiary);
    text-decoration: none;
    cursor: pointer;
    transition: color 0.15s;
    vertical-align: middle;
}
.row-action:hover { color: var(--color-primary); }
.row-action--danger:hover { color: var(--color-danger); }

/* The "shown but inapplicable" state. Its own class rather than a .row-action
   modifier so ghost-button action rows (pages, media) can wear it too. */
.action-off {
    opacity: 0.15;
    pointer-events: none;
    cursor: default;
}

/* The cell those icons live in. Right-aligned and non-wrapping so the action
   column reads as one straight edge down the table. (.row-actions stays a
   pure JS click-guard hook — it also sits on checkbox cells, so it can't
   carry layout.) */
.data-table th.data-table__actions-cell,
.data-table td.data-table__actions-cell {
    text-align: right;
    white-space: nowrap;
}

.data-table__checkbox {
    width: 18px;
    height: 18px;
    border-radius: 4px;
    accent-color: var(--color-primary);
    cursor: pointer;
    vertical-align: middle;
}

/* Center-aligned cells for status, counts, yes/no, versions */
.data-table th.tc,
.data-table td.tc {
    text-align: center;
}

.data-table td.tc .badge,
.data-table td.tc .status-dot {
    margin-left: auto;
    margin-right: auto;
}

.data-table td.tc span {
    justify-content: center;
}

/* --------------------------------------------------------------------------
   Bulk selection bar

   The strip that appears above a data table once a row is checked: "N
   selected", the actions, and Clear.

   It lives here because the markup lived in thirty views and the CSS lived in
   thirty <style> blocks, which is thirty chances to add the classes and forget
   the rules. Email campaigns did exactly that and rendered a raw browser
   button jammed against the table header.

   The thirty local copies are left where they are on purpose: they sit in
   @push('styles'), which loads AFTER this file, so every page that already has
   one keeps rendering byte-identically and nothing needed re-checking. Delete
   them as those views are next touched, not in a sweep.
   -------------------------------------------------------------------------- */
.cc-bulk-col { padding: 0 8px; }
.cc-bulk-col input[type="checkbox"] { cursor: pointer; width: 16px; height: 16px; accent-color: #1264FF; }

.cc-bulk-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 20px;
    background: rgba(18, 100, 255, 0.08);
    border-top: 1px solid var(--color-border, #dbeafe);
    border-bottom: 1px solid var(--color-border, #dbeafe);
}
[data-theme="dark"] .cc-bulk-bar {
    background: rgba(18, 100, 255, 0.12);
    border-top-color: rgba(18, 100, 255, 0.25);
    border-bottom-color: rgba(18, 100, 255, 0.25);
}

.cc-bulk-count { font-size: 13px; font-weight: 600; color: #1264FF; }
[data-theme="dark"] .cc-bulk-count { color: #60a5fa; }

.cc-bulk-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 6px 14px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #bfdbfe);
    border-radius: 6px;
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary, #6b7280);
    cursor: pointer;
}
.cc-bulk-btn--publish { color: #059669; }
.cc-bulk-btn--delete { color: #ef4444; border-color: #fecaca; }
[data-theme="dark"] .cc-bulk-btn--delete { border-color: rgba(239, 68, 68, 0.4); }

.cc-bulk-clear {
    margin-left: auto;
    padding: 6px 10px;
    background: transparent;
    border: none;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text-secondary, #6b7280);
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   Toolbar / Filters
   -------------------------------------------------------------------------- */
.toolbar {
    display: flex;
    align-items: center;
    /* Inputs/selects/search always hug the LEFT. Only .toolbar__right (buttons,
       view-switches) is allowed to push to the right via margin-left:auto. */
    justify-content: flex-start;
    padding: 16px 20px !important;
    margin-bottom: 16px;
    gap: 12px;
    flex-wrap: wrap;
}
.toolbar:has(+ .data-table-wrapper),
.card > .toolbar,
.card__body > .toolbar { margin-bottom: 0; }

.toolbar__left {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    /* Allowed to shrink below its max-content width. Without this the group is
       sized by the widest thing in it, so .toolbar__right (margin-left:auto)
       gets pushed onto a line of its own and reads as a layout mistake — a lone
       right-aligned button under a row of filters. */
    flex: 1 1 auto;
    min-width: 0;
}

.toolbar__right {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
}

/* --------------------------------------------------------------------------
   Collapsible toolbar filters
   The filters fold into a single button + modal exactly when they would wrap
   onto a second row. Not at a fixed breakpoint — the number of filters differs
   per page, so the width where the row breaks does too. toolbar-filters.js
   measures it. See .toolbar__filters-btn; the modal itself is the canonical
   .ccs-modal, with .ccs-modal--filters for width.
   -------------------------------------------------------------------------- */
.toolbar__filters-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: 13px;
    font-weight: var(--weight-medium);
    cursor: pointer;
    white-space: nowrap;
    transition: border-color var(--transition-fast), background var(--transition-fast);
}
/* A class that sets `display` outranks the user-agent's [hidden] rule, so
   `el.hidden = true` leaves the element on screen. Without this the Filters
   button sat next to the very filters it replaces, reading "Filters 0". */
.toolbar__filters-btn[hidden] { display: none !important; }
.toolbar__filters-btn:hover { background: var(--color-surface-hover); border-color: var(--color-border-light); }
.toolbar__filters-btn--active { border-color: var(--color-primary); color: var(--color-primary); }
.toolbar__filters-count[hidden] { display: none !important; }
.toolbar__filters-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--color-primary);
    color: #fff;
    font-size: 11px;
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
}

/* The filters modal is the canonical .ccs-modal — overlay, panel, header, body,
   footer — and adds only what a filter list needs on top of it. It was briefly
   a parallel modal system with its own paddings and radius, which is how a
   codebase ends up with two of everything. */
.ccs-modal--filters { max-width: 440px; }

/* Inside the modal a filter is a full-width field, not a chip: the inline cap
   that stops a long client name blowing up the toolbar is wrong here. */
.cc-modal-body .filter-select {
    width: 100%;
    max-width: none;
    min-width: 0;
}

.toolbar__search {
    position: relative;
    /* Gives ground before the row wraps, and only as far as it has to: 320px
       wherever there is room, never below 170px. */
    flex: 1 1 200px;
    min-width: 170px;
    max-width: 320px;
}

.toolbar__search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-text-tertiary);
    display: flex;
}

.toolbar__search-input {
    padding: 8px 32px 8px 34px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: 13px;
    font-family: inherit;
    color: var(--color-text);
    background: #f2f6fb;
    /* The 320px lives on .toolbar__search now, as a max — this fills it. */
    width: 100%;
    transition: all var(--transition-fast);
}
.toolbar__search-clear {
    position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
    background: none; border: none; cursor: pointer; color: var(--color-text-tertiary);
    padding: 2px; display: none; align-items: center; line-height: 0;
}
.toolbar__search-clear:hover { color: var(--color-text-secondary); }

.toolbar__search-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-bg);
}

.filter-select {
    padding: 8px 32px 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: 13px;
    font-family: inherit;
    color: var(--color-text);
    background: var(--color-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") no-repeat right 10px center;
    appearance: none;
    cursor: pointer;
    min-width: 140px;
    /* A select is sized by its widest OPTION, and these get filled with user
       data — a client list, a campus list. One long name made the control
       hundreds of pixels wide and wrapped the whole toolbar. A filter shows the
       current selection; the dropdown is where the full text lives. */
    max-width: 220px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-select:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-bg);
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.form-group {
    margin-bottom: 20px;
}

.form-label {
    display: block;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text);
    margin-bottom: 6px;
}

.form-label__required {
    color: var(--color-danger);
}

.form-hint {
    font-size: 13px;
    color: var(--color-text-secondary);
    margin-top: 4px;
}

.form-input,
.form-select,
.form-textarea {
    width: 100%;
    padding: 10px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: 14px;
    font-family: inherit;
    color: var(--color-text);
    background: #f2f6fb;
    transition: all var(--transition-fast);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-bg);
}

/* Form inputs inside a tinted section (e.g. Schedule / Location panels using
   --color-surface-secondary as their background) need a white fill so they
   stand out from the surrounding tint instead of blending in. !important
   because the global input[type="text"] etc. rule sets background later in
   the cascade for native inputs. */
[style*="surface-secondary"] .form-input,
[style*="surface-secondary"] .form-select,
[style*="surface-secondary"] .form-textarea,
[style*="surface-secondary"] input,
[style*="surface-secondary"] select,
[style*="surface-secondary"] textarea,
.tinted-section .form-input,
.tinted-section .form-select,
.tinted-section .form-textarea,
.tinted-section input,
.tinted-section select,
.tinted-section textarea {
    background-color: #fff !important;
}

.form-textarea {
    resize: vertical;
    min-height: 100px;
}

/* A tighter input for dense rows (a time grid, an inline severity picker).
   Deliberately does not touch width — the two other views that already
   write this class expect their select to stay full width. */
.form-input--sm {
    padding: 7px 10px;
    font-size: 13px;
}

.form-select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 36px;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

/* --- Form row variants -----------------------------------------------------
   `.form-row` is a hard two-column grid. Four children silently became a
   2x2 block and a six-field "add" form became three stacked pairs, which is
   how an inline form ends up looking like a settings panel. */
.form-row--3 { grid-template-columns: repeat(3, 1fr); }
.form-row--4 { grid-template-columns: repeat(4, 1fr); }

/* An inline form: fields sized to their content, all on one line, wrapping
   only when they run out of room. */
.form-row--inline {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
}
.form-row--inline > .form-input,
.form-row--inline > .form-select,
.form-row--inline > select.form-input { width: auto; min-width: 150px; }
.form-row--inline > .form-group { margin-bottom: 0; }


.form-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 0;
    padding-top: 20px;
    border-top: 1px solid var(--color-border-light);
}

.form-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
}

.form-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.form-switch__slider {
    width: 40px;
    height: 22px;
    background: var(--color-border);
    border-radius: 50px !important;
    position: relative;
    transition: background var(--transition-fast);
}

.form-switch__slider::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    background: white;
    border-radius: 50% !important;
    top: 3px;
    left: 3px;
    transition: transform var(--transition-fast);
    box-shadow: var(--shadow-sm);
}

.form-switch input:checked + .form-switch__slider {
    background: var(--color-primary);
}

.form-switch input:checked + .form-switch__slider::after {
    transform: translateX(18px);
}

.form-switch--internal .form-switch__slider { background: #fed7aa; }
.form-switch--internal input:checked + .form-switch__slider { background: #f59e0b; }
.form-switch--success .form-switch__slider { background: #d1d5db; }
.form-switch--success input:checked + .form-switch__slider { background: #1cc66d; }

.form-switch__label {
    font-size: 14px;
    color: var(--color-text);
}

/* Switch + title + description, as one row. The pattern for a setting that
   needs a sentence of explanation next to the toggle.
   Global because it was previously copy-pasted into individual pages' inline
   <style> blocks — any page that used the markup without pasting the CSS (the
   membership plan editor) rendered a bare checkbox and unstyled text. */
.cc-switch-row { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
.cc-switch { position: relative; display: inline-flex; flex: 0 0 auto; margin-top: 1px; }
.cc-switch input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; margin: 0; cursor: pointer; }
.cc-switch__track { width: 38px; height: 22px; border-radius: 999px; background: var(--color-border, #cbd5e1); transition: background .15s ease; display: inline-block; position: relative; }
.cc-switch__thumb { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25); transition: transform .15s ease; }
.cc-switch input:checked + .cc-switch__track { background: var(--color-primary, #145fff); }
.cc-switch input:checked + .cc-switch__track .cc-switch__thumb { transform: translateX(16px); }
.cc-switch input:focus-visible + .cc-switch__track { box-shadow: 0 0 0 3px rgba(59,130,246,.35); }
.cc-switch-row__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cc-switch-row__title { font-size: 14px; font-weight: 600; color: var(--color-text, #111827); line-height: 1.2; }
.cc-switch-row__desc { font-size: 12px; color: var(--color-text-tertiary, #9ca3af); line-height: 1.4; }
/* A set of switches, laid out in columns instead of one long stack — two
   short settings side by side read faster than two stacked paragraphs.
   Opt-in wrapper, so the pages that already had their own copy of the base
   styles keep their spacing exactly as it was. */
.cc-switch-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px 28px; }

.form-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 14px;
    color: var(--color-text);
}

.form-checkbox input {
    width: 18px;
    height: 18px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   Grid Layouts
   -------------------------------------------------------------------------- */
.grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 20px;
}

.grid-sidebar {
    display: grid;
    grid-template-columns: 1fr 360px;
    gap: 24px;
}

/* Dashboard "needs attention" chips (reusable across all org-type dashboards) */
.dash-attn-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.dash-attn { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 8px; text-decoration: none; font-size: 12px; font-weight: 500; border: 1px solid; transition: transform 0.12s, box-shadow 0.12s; }
.dash-attn:hover { transform: translateY(-1px); }
.dash-attn--static { cursor: default; }
.dash-attn--static:hover { transform: none; }
.dash-attn__count { font-weight: 700; }
.dash-attn--blue  { background: #eff6ff; border-color: #bfdbfe; color: #1e40af; }
.dash-attn--green { background: #f0fdf4; border-color: #bbf7d0; color: #065f46; }
.dash-attn--amber { background: #fffbeb; border-color: #fde68a; color: #92400e; }
.dash-attn--red   { background: #fef2f2; border-color: #fecaca; color: #991b1b; }
/* Fresh activity — new registrations, new sign-ups. Good news, so it reads
   as live rather than as a warning. Built only from Studio's primary tokens,
   which carry their own dark values, so it matches the buttons and icon chips
   in both themes without a second palette. */
.dash-attn--fresh { background: linear-gradient(135deg, var(--color-primary-light) 0%, var(--color-primary-bg) 100%); border-color: rgba(20, 95, 255, 0.3); color: var(--color-primary-hover); font-weight: 600; }
.dash-attn--fresh:hover { box-shadow: 0 4px 12px rgba(20, 95, 255, 0.18); }
.dash-attn--fresh .dash-attn__count { color: var(--color-primary); font-weight: 700; }
.dash-attn__pulse { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--color-primary); flex-shrink: 0; }
.dash-attn__pulse::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--color-primary); animation: dash-attn-pulse 1.8s ease-out infinite; }
@keyframes dash-attn-pulse { from { transform: scale(1); opacity: 0.6; } to { transform: scale(2.6); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .dash-attn__pulse::after { animation: none; } }
[data-theme="dark"] .dash-attn--blue  { background: rgba(18,100,255,0.14); border-color: rgba(18,100,255,0.32); color: #93c5fd; }
[data-theme="dark"] .dash-attn--green { background: rgba(5,150,105,0.14); border-color: rgba(5,150,105,0.32); color: #6ee7b7; }
[data-theme="dark"] .dash-attn--amber { background: rgba(217,119,6,0.14); border-color: rgba(217,119,6,0.32); color: #fcd34d; }
[data-theme="dark"] .dash-attn--red   { background: rgba(239,68,68,0.14); border-color: rgba(239,68,68,0.3); color: #fca5a5; }

/* --------------------------------------------------------------------------
   Dashboard sidebar tiles — the one row style shared by Quick Actions and
   Public Links, so the two cards read as the same family: an icon chip, a
   label (with an optional second line), and an affordance on the right.
   Works as <a> or <button>; both keep identical metrics.
   -------------------------------------------------------------------------- */
/* 24px, the dashboard's one vertical rhythm: the main column's cards, the
   columns themselves (.grid-sidebar) and the stat row above all sit 24 apart. */
.dash-aside { display: flex; flex-direction: column; gap: 24px; }
.dash-tiles { display: flex; flex-direction: column; gap: 8px; }
.dash-tile {
    display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px;
    padding: 10px 12px; text-align: left; text-decoration: none; cursor: pointer;
    font-family: inherit; font-size: inherit;
    background: var(--color-surface-secondary); border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md, 10px);
    transition: border-color 0.14s ease, background 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}
.dash-tile:hover {
    background: var(--color-surface);
    border-color: var(--color-primary);
    box-shadow: 0 4px 14px rgba(20, 95, 255, 0.10);
    transform: translateY(-1px);
}
.dash-tile:active { transform: none; box-shadow: none; }
.dash-tile__icon {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 32px; height: 32px; border-radius: 9px;
    background: var(--color-primary-bg); color: var(--color-primary);
    transition: background 0.14s ease;
}
.dash-tile:hover .dash-tile__icon { background: var(--color-primary-light); }
.dash-tile__body { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.dash-tile__label { font-size: 13px; font-weight: 600; color: var(--color-text); line-height: 1.35; }
.dash-tile__sub {
    font-size: 11.5px; color: var(--color-text-tertiary); line-height: 1.35;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-tile:hover .dash-tile__sub { color: var(--color-primary); }
/* Trailing affordance: the muted chevron on a navigating tile, the copy
   button on a link tile. Both always visible — never hover-revealed. */
.dash-tile__go { display: inline-flex; flex-shrink: 0; color: var(--color-text-tertiary); transition: color 0.14s ease, transform 0.14s ease; }
.dash-tile:hover .dash-tile__go { color: var(--color-primary); transform: translateX(2px); }
.dash-tile__copy {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 30px; height: 30px; padding: 0; border: 1px solid transparent; border-radius: 8px;
    background: none; color: var(--color-text-tertiary); cursor: pointer;
    transition: color 0.14s ease, background 0.14s ease, border-color 0.14s ease;
}
.dash-tile__copy:hover { background: var(--color-surface); border-color: var(--color-border-light); color: var(--color-primary); }

/* An empty card that offers the next real step rather than a dead end. */
.dash-first-step { padding: 40px 20px; text-align: center; }
.dash-first-step__text { margin: 0 0 12px; font-size: 14px; line-height: 1.5; color: var(--color-text-secondary); }

/* Public Links — empty/unpublished state. */
.dash-plinks__off { margin: 0 0 12px; font-size: 13px; line-height: 1.5; color: var(--color-text-secondary); }
.dash-plinks__off-btn { justify-content: flex-start; }

/* Quick Actions picker — the deploy site-picker's two-pane shell (available on
   the left, chosen on the right), with rows built to mirror the card's
   .dash-tile so the picker reads as a preview of the result. */
.qa-pick__intro { margin: 0 0 14px; font-size: 13px; line-height: 1.55; color: var(--color-text-secondary); }
.qa-pick .site-picker__list { padding: 12px; }
.qa-pick .site-picker__right { width: 260px; }
.qa-pick__pane-foot {
    padding: 8px 12px; border-top: 1px solid var(--color-border-light);
    font-size: 11.5px; color: var(--color-text-tertiary); text-align: center;
}
.qa-pick__group + .qa-pick__group { margin-top: 18px; }
.qa-pick__group-name {
    display: flex; align-items: center; gap: 10px;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--color-text-tertiary); margin-bottom: 8px;
}
.qa-pick__group-name::after {
    content: ''; flex: 1; height: 1px; background: var(--color-border-light);
}
.qa-pick__row + .qa-pick__row { margin-top: 6px; }

.qa-pick__row {
    display: flex; align-items: center; gap: 11px; min-height: 54px; padding: 9px 12px;
    background: var(--color-surface-secondary); border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md, 10px); cursor: pointer;
    transition: border-color 0.14s ease, background 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}
.qa-pick__row:hover {
    background: var(--color-surface); border-color: var(--color-primary);
    box-shadow: 0 4px 14px rgba(20, 95, 255, 0.10); transform: translateY(-1px);
}
.qa-pick__row:has(.qa-pick__cb:checked) {
    background: var(--color-primary-bg); border-color: var(--color-primary);
}
.qa-pick__row--off { opacity: 0.4; cursor: not-allowed; }
.qa-pick__row--off:hover { background: var(--color-surface-secondary); border-color: var(--color-border-light); box-shadow: none; transform: none; }

.qa-pick__icon {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 32px; height: 32px; border-radius: 9px;
    background: var(--color-primary-bg); color: var(--color-primary);
    transition: background 0.14s ease;
}
.qa-pick__row:has(.qa-pick__cb:checked) .qa-pick__icon { background: var(--color-primary-light); }
.qa-pick__label { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; color: var(--color-text); line-height: 1.35; }
.qa-pick__url { display: block; font-size: 11px; font-weight: 400; color: var(--color-text-tertiary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The native box, restyled — still a real checkbox, so the JS and keyboard
   behavior are untouched. */
.qa-pick__cb {
    flex-shrink: 0; width: 19px; height: 19px; margin: 0; cursor: inherit;
    -webkit-appearance: none; appearance: none;
    border: 1.5px solid var(--color-border); border-radius: 6px;
    background: var(--color-surface);
    display: inline-flex; align-items: center; justify-content: center;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.qa-pick__cb:checked { background: var(--color-primary); border-color: var(--color-primary); }
.qa-pick__cb:checked::after {
    content: ''; width: 5px; height: 9px; margin-top: -2px;
    border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.qa-pick__cb:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* The right pane: the pinned set in card order — drag a row to move it. */
.qa-pick__chip {
    display: flex; align-items: center; gap: 8px; padding: 7px 8px 7px 7px;
    background: var(--color-surface); border: 1px solid var(--color-border-light);
    border-radius: 8px; cursor: grab; user-select: none;
    transition: border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.qa-pick__chip:hover { border-color: var(--color-primary); box-shadow: 0 2px 8px rgba(20, 95, 255, 0.10); }
.qa-pick__chip--dragging { opacity: 0.4; cursor: grabbing; }
/* House drop indicator: blue dashed border + light blue fill at the target. */
.qa-pick__chip--over { border: 2px dashed var(--color-primary); background: rgba(18, 100, 255, 0.06); }
.qa-pick__chip-num {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 18px; height: 18px; border-radius: 5px;
    background: var(--color-primary); color: #fff; font-size: 10.5px; font-weight: 700;
}
.qa-pick__chip-icon { display: inline-flex; flex-shrink: 0; color: var(--color-primary); }
.qa-pick__chip-label {
    flex: 1; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--color-text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qa-pick__chip-x {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 18px; height: 18px; padding: 0; border: none; border-radius: 5px;
    background: none; color: var(--color-text-tertiary); font-size: 16px; line-height: 1;
    font-family: inherit; cursor: pointer; transition: background 0.12s ease, color 0.12s ease;
}
.qa-pick__chip-x:hover { background: var(--color-danger-bg, rgba(239,68,68,0.1)); color: var(--color-danger, #ef4444); }

.qa-pick__custom { display: flex; gap: 8px; align-items: center; margin-top: 10px; }
.qa-pick__custom .form-input { flex: 1; min-width: 0; }
.qa-pick__custom .btn { flex-shrink: 0; }
.qa-pick__foot-right { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.qa-pick__count { font-size: 12px; font-weight: 500; color: var(--color-text-tertiary); }
.qa-pick__count--full { color: var(--color-warning-text, #92400e); font-weight: 600; }

/* Client-intake picker page (a quick action needs a client before it opens). */
.qa-portal-form__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

/* --------------------------------------------------------------------------
   Detail View
   -------------------------------------------------------------------------- */
.detail-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 24px;
    gap: 16px;
}

.detail-header__info {
    flex: 1;
}

.detail-header__title {
    font-size: 22px;
    font-weight: 700;
    color: var(--color-text);
    margin-bottom: 6px;
    display: flex;
    align-items: center;
    gap: 10px;
}

.detail-header__meta {
    display: flex;
    align-items: center;
    gap: 16px;
    font-size: 14px;
    color: var(--color-text-secondary);
}

.detail-header__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    /* An invoice carries five of these (Edit, View, Send, Record Payment, and
       the kebab). In one un-wrapping row they pushed ~30px past the viewport
       below about 1100px, so the whole page scrolled sideways to reach a
       button. Wrapping costs a row of height and nothing else. */
    flex-wrap: wrap;
    justify-content: flex-end;
}

.detail-section {
    margin-bottom: 24px;
}

/* Site Stats Grid (quick-glance row) */
.site-stats-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 16px;
    margin-bottom: 24px;
}

.site-stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 16px 18px;
}

.site-stat-card__label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--color-text-tertiary);
    margin-bottom: 6px;
}

.site-stat-card__value {
    font-size: 15px;
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Plugin Toggle Pill */
.plugin-toggle-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 6px;
    border-radius: 20px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    cursor: pointer;
    font-size: 12px;
    font-weight: 500;
    font-family: inherit;
    color: var(--color-text-tertiary);
    transition: all var(--transition-fast);
}

.plugin-toggle-pill__dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--color-text-tertiary);
    transition: background var(--transition-fast);
}

.plugin-toggle-pill--active {
    border-color: var(--color-success);
    background: var(--color-success-light);
    color: var(--color-success);
}

.plugin-toggle-pill--active .plugin-toggle-pill__dot {
    background: var(--color-success);
}

.plugin-toggle-pill:hover {
    border-color: var(--color-text-secondary);
}

.plugin-toggle-pill--active:hover {
    border-color: var(--color-warning);
    background: var(--color-warning-light);
    color: var(--color-warning);
}

.plugin-toggle-pill--active:hover .plugin-toggle-pill__dot {
    background: var(--color-warning);
}

.detail-section__title {
    font-size: 15px;
    font-weight: 600;
    color: var(--color-text);
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--color-border-light);
}

.detail-row {
    display: flex;
    padding: 10px 0;
    border-bottom: 1px solid var(--color-border-light);
}

.detail-row:last-child {
    border-bottom: none;
}

.detail-row__label {
    width: 160px;
    flex-shrink: 0;
    font-size: 14px;
    color: var(--color-text-secondary);
    font-weight: 500;
}

.detail-row__value {
    flex: 1;
    font-size: 14px;
    color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Tags
   -------------------------------------------------------------------------- */
.tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.tag {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    background: var(--color-surface-hover);
    border-radius: 20px;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text-secondary);
}

.tag--primary {
    background: var(--color-primary-light);
    color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   Empty State
   -------------------------------------------------------------------------- */
.empty-state {
    text-align: center;
    padding: 48px 24px;
    color: var(--color-text-secondary);
}

.empty-state__icon {
    margin: 0 auto 16px;
    color: var(--color-text-tertiary);
}

.empty-state__title {
    font-size: 16px;
    font-weight: 600;
    color: var(--color-text);
    margin-bottom: 8px;
}

.empty-state__text {
    font-size: 14px;
    margin-bottom: 20px;
}

/* Empty-state action button spacing: the gap is driven by the preceding
   element's margin-bottom, so the button itself never carries a margin-top.
   Inline margin-top="" on buttons inside .empty-state is a bug — don't add it. */
.empty-state__text + .btn,
.empty-state__text + a.btn,
.empty-state__text + button.btn {
    margin-top: 0;
}
.empty-state__title + .btn,
.empty-state__title + a.btn,
.empty-state__title + button.btn {
    margin-top: 12px; /* only when there's no descriptive paragraph */
}

/* --------------------------------------------------------------------------
   Alerts (Notification style)
   -------------------------------------------------------------------------- */
.alert-banner {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 16px;
    border-radius: var(--radius-md);
    margin-bottom: 16px;
    font-size: 14px;
    /* Anchor for __close, which is positioned rather than laid out — see below. */
    position: relative;
}

/* A banner carrying __text centres it. Banners that are still a bare string of
   content (most of them) keep the left-aligned flex row above, so this doesn't
   restyle every flash on the platform. */
.alert-banner__text {
    flex: 1;
    text-align: center;
}

/* Positioned, not a flex child: as a third column it would take width from the
   text and push the centred line off-centre by half a button. Out of flow, the
   text centres on the full banner and the × sits in the corner regardless. */
.alert-banner__close {
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm, 6px);
    background: transparent;
    /* currentColor so one rule works on all four variants — the × picks up
       whichever hue the banner is already carrying. */
    color: inherit;
    /* 0.55 put this at 3.0:1 on the dark success tint — the WCAG floor for a
       control, and the faintest thing on the bar. 0.75 clears it comfortably
       without competing with the message it sits beside. */
    opacity: 0.75;
    cursor: pointer;
    transition: opacity 0.15s, background 0.15s;
}

.alert-banner__close:hover {
    opacity: 1;
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="dark"] .alert-banner__close:hover {
    background: rgba(255, 255, 255, 0.1);
}

.alert-banner--info {
    background: var(--color-info-light);
    color: var(--color-info);
    border: 1px solid rgba(37, 99, 235, 0.15);
}

.alert-banner--success {
    background: var(--color-success-light);
    color: var(--color-success);
    border: 1px solid rgba(5, 150, 105, 0.15);
}

/* --color-warning (#ffb600) on --color-warning-light (#fff3d0) is about 1.5:1 —
   amber copy on an amber tint, effectively unreadable, and the icon strokes with
   currentColor so it faded out too. The other three variants use a dark enough
   hue to carry text; this one never did. Text and icon both take the normal text
   colour (which flips correctly in dark mode); the amber carries the meaning
   through the tint and border. */
.alert-banner--warning {
    background: var(--color-warning-light);
    color: var(--color-text);
    border: 1px solid rgba(217, 119, 6, 0.15);
}

.alert-banner--danger {
    background: var(--color-danger-light);
    color: var(--color-danger);
    border: 1px solid rgba(220, 38, 38, 0.15);
}

/* `.alert` is the older message class still used on ~30 pages (approvals,
   website settings, sponsorships, Studio Admin). It only ever had dark-mode
   colors, so in light mode those messages rendered as bare text. Same look as
   .alert-banner; success and error use the strong shades for contrast. */
.alert { display: block; padding: 14px 16px; border-radius: var(--radius-md); margin-bottom: 16px; font-size: 14px; line-height: 1.5; border: 1px solid transparent; }
.alert--success, .alert--good { background: var(--color-success-light); color: var(--color-success-strong); border-color: rgba(5, 150, 105, 0.15); }
.alert--error, .alert--danger, .alert--bad { background: var(--color-danger-light); color: var(--color-danger-strong); border-color: rgba(220, 38, 38, 0.15); }
.alert--warning { background: var(--color-warning-light); color: var(--color-text); border-color: rgba(217, 119, 6, 0.15); }
.alert--info { background: var(--color-info-light); color: var(--color-info); border-color: rgba(37, 99, 235, 0.15); }

/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */
.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 0;
    margin-top: 16px;
}

.pagination__info {
    font-size: 13px;
    color: var(--color-text-secondary);
}

.pagination__controls {
    display: flex;
    align-items: center;
    gap: 4px;
}

.pagination__btn {
    padding: 6px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    font-size: 13px;
    font-family: inherit;
    color: var(--color-text);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.pagination__btn:hover {
    background: var(--color-surface-hover);
}

.pagination__btn--active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: white;
}

/* --------------------------------------------------------------------------
   Back Link
   -------------------------------------------------------------------------- */
.back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    color: var(--color-text-secondary);
    margin-bottom: 16px;
}

.back-link:hover {
    color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Status Dot
   -------------------------------------------------------------------------- */
.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

.status-dot--online,
.status-dot--success,
.status-dot--active {
    background: var(--color-success);
    box-shadow: 0 0 0 3px var(--color-success-bg);
}

.status-dot--warning,
.status-dot--maintenance,
.status-dot--disconnected {
    background: var(--color-warning);
    box-shadow: 0 0 0 3px var(--color-warning-bg);
}

.status-dot--down,
.status-dot--error,
.status-dot--failed,
.status-dot--restricted {
    background: var(--color-danger);
    box-shadow: 0 0 0 3px var(--color-danger-bg);
}

/* --------------------------------------------------------------------------
   Health Bar
   -------------------------------------------------------------------------- */
.health-bar {
    display: flex;
    height: 8px;
    border-radius: 4px;
    overflow: hidden;
    background: var(--color-surface-hover);
}

.health-bar__segment {
    height: 100%;
    transition: width var(--transition-base);
}

.health-bar__segment--online {
    background: var(--color-success);
}

.health-bar__segment--warning {
    background: var(--color-warning);
}

.health-bar__segment--down {
    background: var(--color-danger);
}

/* --------------------------------------------------------------------------
   Modal
   -------------------------------------------------------------------------- */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 200;
    display: none;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(2px);
}

.modal-overlay.is-open {
    display: flex;
}

.modal {
    background: var(--color-surface);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    overflow-y: auto;
}

.modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px;
    border-bottom: 1px solid var(--color-border-light);
}

.modal__title {
    font-size: 17px;
    font-weight: 600;
}

.modal__close {
    background: none;
    border: none;
    color: var(--color-text-secondary);
    cursor: pointer;
    padding: 4px;
}

.modal__body {
    padding: 24px;
}

.modal__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 16px 24px;
    border-top: 1px solid var(--color-border-light);
}

/* --------------------------------------------------------------------------
   Tabs
   -------------------------------------------------------------------------- */
.tabs {
    display: inline-flex;
    gap: 6px;
    margin-bottom: 0;
}

.tab {
    padding: 8px 12px;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: all 0.15s;
    background: #f1f5f9;
    border: none;
    border-radius: 8px;
    font-family: inherit;
}

.tab:hover {
    background: #dbeafe;
    color: var(--color-text);
}

.tab--active {
    color: var(--color-primary, #1264FF);
    background: #dbeafe;
}

/* --------------------------------------------------------------------------
   Choice cards — a radio group that reads as two or three cards rather than
   a row of dots. Note visibility (Personal / Team) is the original; Add Plugin
   picks its method the same way. Promoted out of the notes views so a second
   module doesn't need a second copy of it.
   -------------------------------------------------------------------------- */
.choice-cards { display: flex; gap: 12px; }
.choice-cards__opt { flex: 1; cursor: pointer; position: relative; }
.choice-cards__opt input { position: absolute; opacity: 0; pointer-events: none; }
.choice-cards__chip {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 100%;
    padding: 14px 16px;
    border: 1px solid var(--color-border-light);
    border-radius: 10px;
    background: var(--color-surface);
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.choice-cards__chip strong { display: block; font-size: 14px; font-weight: 600; color: var(--color-text); }
.choice-cards__chip em { display: block; font-size: 12px; font-style: normal; color: var(--color-text-tertiary); margin-top: 2px; }
.choice-cards__opt input:checked + .choice-cards__chip {
    border-color: var(--color-primary);
    background: var(--color-primary-bg, rgba(59, 130, 246, 0.06));
    box-shadow: 0 0 0 1px var(--color-primary);
}
.choice-cards__opt:hover .choice-cards__chip { border-color: var(--color-border); }
.choice-cards__opt input:focus-visible + .choice-cards__chip { box-shadow: 0 0 0 2px var(--color-primary); }
.choice-cards__chip svg { color: var(--color-text-secondary); flex-shrink: 0; }
.choice-cards__opt input:checked + .choice-cards__chip svg { color: var(--color-primary); }

@media (max-width: 560px) {
    .choice-cards { flex-direction: column; }
}

/* --------------------------------------------------------------------------
   Drag & Drop / Upload
   -------------------------------------------------------------------------- */
.upload-zone {
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-lg);
    padding: 48px 24px;
    text-align: center;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.upload-zone:hover,
.upload-zone.is-dragover {
    border-color: var(--color-primary);
    background: var(--color-primary-light);
}

.upload-zone__icon {
    color: var(--color-text-tertiary);
    margin-bottom: 12px;
}

.upload-zone__text {
    font-size: 15px;
    font-weight: 500;
    color: var(--color-text);
    margin-bottom: 4px;
}

.upload-zone__hint {
    font-size: 13px;
    color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Results List
   -------------------------------------------------------------------------- */
.results-list {
    list-style: none;
}

.results-list__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border-light);
}

.results-list__item:last-child {
    border-bottom: none;
}

.results-list__icon {
    flex-shrink: 0;
}

.results-list__icon--success {
    color: var(--color-success);
}

.results-list__icon--failed {
    color: var(--color-danger);
}

.results-list__info {
    flex: 1;
}

.results-list__name {
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text);
}

.results-list__message {
    font-size: 13px;
    color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Site Selection List
   -------------------------------------------------------------------------- */
.site-select-list {
    list-style: none;
    border: none;
    border-radius: 0;
    overflow-y: auto;
}

.site-select-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 20px;
    border-bottom: 1px solid var(--color-border-light);
    cursor: pointer;
    transition: background var(--transition-fast);
}

.site-select-item:last-child {
    border-bottom: none;
}

.site-select-item:hover {
    background: var(--color-surface-hover);
}

.site-select-item__info {
    flex: 1;
}

.site-select-item__name {
    font-size: 14px;
    font-weight: 500;
}

.site-select-item__url {
    font-size: 13px;
    color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Financial Summary
   -------------------------------------------------------------------------- */
.financial-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-bottom: 24px;
}

.financial-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 20px 24px;
}

.financial-card__label {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-secondary);
    margin-bottom: 8px;
}

.financial-card__value {
    font-size: 26px;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.financial-card--revenue { border-left: 3px solid var(--color-primary); }
.financial-card--cost    { border-left: 3px solid var(--color-warning); }
.financial-card--profit  { border-left: 3px solid var(--color-success); }

/* Stat Card — used for financial summaries and quick-glance metrics */
.stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 20px 24px;
}

.stat-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

.stat-card__label {
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-secondary);
}

.stat-card__icon {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
}

.stat-card__icon--primary {
    background: var(--color-primary-light);
    color: var(--color-primary);
}

.stat-card__icon--success {
    background: var(--color-success-light);
    color: var(--color-success);
}

.stat-card__icon--warning {
    background: var(--color-warning-light);
    color: var(--color-warning);
}

.stat-card__icon--danger {
    background: var(--color-danger-light);
    color: var(--color-danger);
}

.stat-card__value {
    font-size: 28px;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.stat-card__footer {
    margin-top: 6px;
    font-size: 13px;
    color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Settings Sections
   -------------------------------------------------------------------------- */
.settings-nav {
    display: flex;
    gap: 4px;
    margin-bottom: 24px;
}

.settings-nav__link {
    padding: 8px 16px;
    border-radius: var(--radius-md);
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-secondary);
    transition: all var(--transition-fast);
}

.settings-nav__link:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

.settings-nav__link--active {
    background: var(--color-primary-light);
    color: var(--color-primary);
}

.settings-section {
    margin-bottom: 24px;
}

.settings-section__title {
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 4px;
}

.settings-section__desc {
    font-size: 14px;
    color: var(--color-text-secondary);
    margin-bottom: 16px;
}

/* --------------------------------------------------------------------------
   Timeline / Activity
   -------------------------------------------------------------------------- */
.timeline {
    list-style: none;
    position: relative;
    padding-left: 24px;
}

.timeline__item {
    position: relative;
    padding-bottom: 20px;
}

.timeline__item:not(:last-child)::before {
    content: '';
    position: absolute;
    left: -16px;
    top: 14px;
    bottom: 0;
    width: 2px;
    background: var(--color-border-light);
}

.timeline__item:last-child {
    padding-bottom: 0;
}

.timeline__dot {
    position: absolute;
    left: -20px;
    top: 4px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: none;
    background: var(--color-border);
}

.timeline__dot--success {
    border-color: var(--color-success);
    background: var(--color-success);
}

.timeline__dot--failed {
    border-color: var(--color-danger);
    background: var(--color-danger);
}

.timeline__dot--warning {
    border-color: var(--color-warning);
    background: var(--color-warning);
}

/* Was --color-danger, which is not an opinion about "info" — it was a
   copy-paste off the rule above, and it painted every neutral event on every
   timeline in the app (invoice created, invoice opened, note added) the same
   red as a failed charge. */
.timeline__dot--info {
    border-color: var(--color-info);
    background: var(--color-info);
}

.timeline__content {
    font-size: 14px;
    color: var(--color-text);
}

.timeline__time {
    font-size: 12px;
    color: var(--color-text-tertiary);
    margin-top: 4px;
}

/* --------------------------------------------------------------------------
   Monitoring Chart Placeholder
   -------------------------------------------------------------------------- */
.chart-placeholder {
    height: 200px;
    background: linear-gradient(180deg, var(--color-primary-light) 0%, var(--color-surface) 100%);
    border-radius: var(--radius-md);
    display: flex;
    align-items: flex-end;
    padding: 16px;
    position: relative;
    overflow: hidden;
}

.chart-placeholder__bars {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    width: 100%;
    height: 100%;
}

.chart-placeholder__bar {
    flex: 1;
    background: var(--color-primary);
    border-radius: 3px 3px 0 0;
    opacity: 0.6;
    min-height: 8px;
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1200px) {
    .metrics-grid {
        grid-auto-flow: row;
        grid-template-columns: repeat(2, 1fr);
    }

    .grid-sidebar {
        grid-template-columns: 1fr;
    }

    .financial-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .site-stats-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    /* Four number fields on one line need roughly 800px of content column;
       below that they pair up rather than squeezing to nothing. */
    .form-row--4 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    .ccs-sidebar {
        transform: translateX(-100%);
    }

    .ccs-sidebar.is-open {
        transform: translateX(0);
    }

    .ccs-sidebar__toggle {
        display: block;
    }

    .ccs-sidebar__collapse {
        display: none;
    }

    .ccs-main {
        margin-left: 0;
    }

    .ccs-header__menu-btn {
        display: block;
    }

    .ccs-header__search {
        display: none;
    }

    .ccs-content {
        padding: 16px;
    }

    .page-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }

    /* Header buttons wrap onto a second row instead of pushing the page sideways. */
    .page-header,
    .page-header__left,
    .page-header__actions {
        max-width: 100%;
    }

    .page-header__actions {
        flex-wrap: wrap;
    }

    .metrics-grid {
        grid-template-columns: 1fr;
    }

    .grid-2,
    .grid-3 {
        grid-template-columns: 1fr;
    }

    .site-stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .form-row,
    .form-row--3,
    .form-row--4 {
        grid-template-columns: minmax(0, 1fr);
    }

    .toolbar {
        flex-direction: column;
        align-items: flex-start;
    }

    .toolbar__search-input {
        width: 100%;
    }

    /* The search box takes the row's width, never the input's intrinsic width. */
    .toolbar__search {
        max-width: 100%;
    }

    /* A long tab row scrolls inside itself, not the page. */
    .tabs {
        display: flex;
        max-width: 100%;
        overflow-x: auto;
    }

    .tab {
        flex: none;
        white-space: nowrap;
    }

    /* Dashboard upcoming-events row: stats drop under the title instead of widening the card. */
    .dash-ev-row {
        flex-wrap: wrap;
    }

    .dash-ev-row > div:nth-child(2) {
        flex: 1 1 120px;
    }

    .dash-ev-stat {
        margin-right: 0 !important;
        min-width: 0 !important;
    }

    .financial-grid {
        grid-template-columns: 1fr;
    }

    .detail-header {
        flex-direction: column;
    }

    .settings-nav {
        flex-wrap: wrap;
    }

    .ccs-header {
        padding: 0 16px;
    }

    /* A long workspace name truncates instead of pushing the icon bar past
       the right edge (the page scrolled sideways). */
    .ccs-header__left,
    .ccs-header__ws,
    #ws-switcher-btn {
        min-width: 0;
    }

    .ccs-header__ws > span,
    #ws-switcher-btn > span {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* --------------------------------------------------------------------------
   Permission Banner
   -------------------------------------------------------------------------- */
.permission-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: var(--color-warning-light);
    border: 1px solid rgba(217, 119, 6, 0.15);
    border-radius: var(--radius-md);
    margin-bottom: 16px;
    font-size: 13px;
    color: var(--color-warning);
}

.permission-banner svg {
    flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   WordPress Admin Notice Overrides
   -------------------------------------------------------------------------- */
.ccs-content .notice,
.ccs-content .updated,
.ccs-content .error,
.ccs-content .notice-warning,
.ccs-content .notice-error,
.ccs-content .notice-success,
.ccs-content .notice-info {
    border: 1px solid var(--color-border) !important;
    border-left: 1px solid var(--color-border) !important;
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    padding: 14px 16px;
    margin: 0 0 16px;
    font-size: 14px;
    box-shadow: none;
}

.ccs-content .notice p,
.ccs-content .updated p,
.ccs-content .error p {
    color: var(--color-text);
    margin: 0 0 8px;
}

.ccs-content .notice p:last-child,
.ccs-content .updated p:last-child,
.ccs-content .error p:last-child {
    margin-bottom: 0;
}

.ccs-content .notice h3,
.ccs-content .notice strong {
    color: var(--color-text);
}

.ccs-content .notice .button,
.ccs-content .notice .button-primary {
    font-family: inherit;
}

/* --------------------------------------------------------------------------
   Queue Status
   -------------------------------------------------------------------------- */
.queue-item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--color-border-light);
}

.queue-item:last-child {
    border-bottom: none;
}

.queue-item__spinner {
    width: 20px;
    height: 20px;
    border: 2px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

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

.queue-item__info {
    flex: 1;
}

.queue-item__action {
    font-size: 14px;
    font-weight: 500;
}

.queue-item__site {
    font-size: 13px;
    color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Notification Dot for unread alerts
   -------------------------------------------------------------------------- */
.alert-row--unread {
    background: var(--color-primary-light);
}

.alert-row--unread .data-table__name {
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Scrollbar Styling
   -------------------------------------------------------------------------- */
.ccs-sidebar__nav::-webkit-scrollbar,
.site-select-list::-webkit-scrollbar {
    width: 4px;
}

.ccs-sidebar__nav::-webkit-scrollbar-track {
    background: transparent;
}

.ccs-sidebar__nav::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 2px;
}

.site-select-list::-webkit-scrollbar-track {
    background: transparent;
}

.site-select-list::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 2px;
}

/* --------------------------------------------------------------------------
   CCS Modal (JS-driven modals for confirms, alerts, deletes)
   -------------------------------------------------------------------------- */
.ccs-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 9999;
    display: none;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(3px);
}

.ccs-modal-overlay.is-open {
    display: flex;
}

.ccs-modal {
    background: var(--color-surface);
    border-radius: var(--radius-xl);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
    width: 100%;
    max-width: 440px;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    animation: ccs-modal-in 0.2s ease;
}
.ccs-modal .cc-modal-header,
.ccs-modal .ccs-modal__header { flex: none; }
.ccs-modal .cc-modal-body,
.ccs-modal .ccs-modal__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.ccs-modal .cc-modal-footer,
.ccs-modal .ccs-modal__footer { flex: none; }

/* A modal whose header/body/footer are wrapped in a <form>.
   .ccs-modal is a column flex box capped at 88vh, and the rules above expect
   those three to be ITS children. Wrapped, the form is the only flex item and
   the body never scrolls: on a short window the content grows past the cap and
   pushes the footer out through the bottom of the panel, leaving Cancel and
   Save floating on the overlay. Three modals hit this separately before it was
   fixed in one place; the form has to be the flex item AND the flex container. */
.ccs-modal > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.ccs-modal > form > .cc-modal-header,
.ccs-modal > form > .cc-modal-footer { flex: none; }
.ccs-modal > form > .cc-modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

.ccs-modal.ccs-modal--complete {
    max-width: 350px;
}

.ccs-modal--complete .ccs-modal__header {
    padding: 16px 16px 0;
    justify-content: flex-end;
}

.ccs-modal--complete .ccs-modal__header .ccs-modal__title {
    display: none;
}

.ccs-modal--complete .ccs-modal__body {
    padding: 0 24px 8px;
}

.ccs-modal--complete .ccs-modal__footer {
    justify-content: center;
    padding: 0 24px 24px;
}

.ccs-modal--complete .ccs-modal__footer .btn {
    width: 100%;
    text-align: center;
    justify-content: center;
}

.ccs-modal.ccs-modal--wide {
    max-width: none;
    width: 80%;
    height: 80vh;
    display: flex;
    flex-direction: column;
}

.ccs-modal--wide .ccs-modal__body {
    flex: 1;
    overflow-y: auto;
}

.ccs-modal--wide .ccs-modal__footer {
    border-top: 1px solid var(--color-border-light);
    flex-shrink: 0;
}

@keyframes ccs-modal-in {
    from { opacity: 0; transform: scale(0.95) translateY(10px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

.ccs-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px 0;
}

.ccs-modal__title {
    font-size: 17px;
    font-weight: 600;
    color: var(--color-text);
}

.ccs-modal__close {
    background: none;
    border: none;
    color: var(--color-text-tertiary);
    cursor: pointer;
    font-size: 24px;
    line-height: 1;
    padding: 0 4px;
    transition: color var(--transition-fast);
}

.ccs-modal__close:hover {
    color: var(--color-text);
}

.ccs-modal__body {
    padding: 16px 24px 20px;
}

.ccs-modal__footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 0 24px 20px;
}

/* --------------------------------------------------------------------------
   Subtle Delete Button — bottom-right of edit/detail pages
   -------------------------------------------------------------------------- */
.delete-subtle {
    color: var(--color-text-tertiary) !important;
    transition: color var(--transition-fast);
}

.delete-subtle:hover {
    color: var(--color-danger) !important;
}

/* --------------------------------------------------------------------------
   Site Picker — split-pane multi-select for deploys
   -------------------------------------------------------------------------- */
.ccs-modal.ccs-modal--picker {
    max-width: 800px;
}

.site-picker {
    display: flex;
    gap: 0;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md);
    overflow: hidden;
    min-height: 380px;
    max-height: 460px;
}

.site-picker__left {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    border-right: 1px solid var(--color-border-light);
}

.site-picker__right {
    width: 300px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--color-bg);
    transition: width 0.2s ease, opacity 0.2s ease;
}

.site-picker__right--hidden {
    width: 0;
    overflow: hidden;
    opacity: 0;
    border: none;
}

/* Search */
.site-picker__search {
    padding: 12px;
    border-bottom: 1px solid var(--color-border-light);
}

.site-picker__search input {
    width: 100%;
    font-size: 13px;
}

/* Toolbar */
.site-picker__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    border-bottom: 1px solid var(--color-border-light);
    background: var(--color-bg);
}

.site-picker__select-all {
    display: flex;
    align-items: center;
    gap: 14px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    color: var(--color-text);
}

.site-picker__count {
    font-size: 12px;
    color: var(--color-text-tertiary);
}

/* Site list */
.site-picker__list {
    flex: 1;
    overflow-y: auto;
    padding: 0;
}

.site-picker__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 12px;
    cursor: pointer;
    border-bottom: 1px solid var(--color-border-light);
    transition: background var(--transition-fast);
}

.site-picker__item:hover {
    background: var(--color-bg);
}

.site-picker__item:last-child {
    border-bottom: none;
}

.site-picker__item input[type="checkbox"] {
    flex-shrink: 0;
}

.site-picker__item-info {
    flex: 1;
    min-width: 0;
}

.site-picker__item-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.site-picker__item-url {
    font-size: 11px;
    color: var(--color-text-tertiary);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.site-picker__item-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.site-picker__item-dot--success { background: var(--color-success); }
.site-picker__item-dot--warning { background: var(--color-warning); }
.site-picker__item-dot--danger  { background: var(--color-danger); }

/* Selected panel (right) */
.site-picker__selected-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border-light);
}

.site-picker__selected-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.site-picker__selected-count {
    font-size: 11px;
    font-weight: 600;
    background: var(--color-primary);
    color: #fff;
    border-radius: 10px;
    padding: 1px 8px;
    min-width: 20px;
    text-align: center;
}

.site-picker__selected-list {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.site-picker__chip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 6px 8px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-sm);
    font-size: 12px;
}

/* A chip that also carries a job title stacks: name + remove on the first
   row, the input beneath. Same chip, one extra line — a title belongs to the
   affiliation, so it is drawn inside the thing that represents one. */
.site-picker__chip--titled {
    flex-wrap: wrap;
    align-items: flex-start;
}

.site-picker__chip--titled .site-picker__chip-name {
    flex: 1 1 auto;
    padding-top: 2px;
}

.site-picker__chip--titled .pu-chip-title {
    flex: 1 0 100%;
    margin-top: 6px;
    font-size: 12px;
    padding: 5px 8px;
}

.site-picker__chip-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--color-text);
    font-weight: 500;
}

.site-picker__chip-remove {
    background: none;
    border: none;
    color: var(--color-text-tertiary);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 0 2px;
    flex-shrink: 0;
    transition: color var(--transition-fast);
}

.site-picker__chip-remove:hover {
    color: var(--color-danger);
}

.site-picker__empty {
    padding: 20px 8px;
    text-align: center;
    font-size: 12px;
    color: var(--color-text-tertiary);
}

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

/* --------------------------------------------------------------------------
   Rich Content (comments, notes, messages, replies)
   -------------------------------------------------------------------------- */
.comment-content ul,
.comment-content ol {
    padding-left: 24px;
    margin: 6px 0;
}

.comment-content ul ul,
.comment-content ol ol,
.comment-content ul ol,
.comment-content ol ul {
    margin: 2px 0;
}

.comment-content li {
    margin-bottom: 3px;
    line-height: 1.6;
}

.comment-content h3 {
    font-size: 18px;
    font-weight: 700;
    margin: 12px 0 4px;
}

.comment-content h3:first-child {
    margin-top: 0;
}

/* Matches .se__body in partials/simple-editor. `> div` covers content saved
   before the editor emitted <p> on Enter — those had no spacing at all. */
.comment-content p,
.comment-content > div {
    margin: 0 0 10px;
}

.comment-content p:last-child,
.comment-content > div:last-child {
    margin-bottom: 0;
}

.comment-content img {
    max-width: 100%;
    border-radius: 8px;
    margin: 6px 0;
}

/* --------------------------------------------------------------------------
   Avatar Tooltip
   -------------------------------------------------------------------------- */
.ccs-tip-wrap {
    position: relative;
}

.ccs-tooltip {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: #1264FF;
    color: #fff;
    font-size: 11px;
    font-weight: 500;
    padding: 4px 8px;
    border-radius: 5px;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s;
    z-index: 50;
}

.ccs-tooltip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 4px solid transparent;
    border-top-color: #1264FF;
}

.ccs-tip-wrap:hover .ccs-tooltip {
    opacity: 1;
}

/* --------------------------------------------------------------------------
   Modal Structure: .cc-modal-header, .cc-modal-body, .cc-modal-footer
   -------------------------------------------------------------------------- */
.cc-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 24px 28px;
    border-bottom: 1px solid var(--color-border-light, #dde5f1);
}
.cc-modal-header h2,
.cc-modal-header h3 {
    font-size: 18px;
    font-weight: 700;
    color: var(--color-text, #111827);
    margin: 0;
}
.cc-modal-body {
    padding: 24px 28px;
}
.cc-modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 20px 28px;
    border-top: 1px solid var(--color-border-light, #dde5f1);
}
.cc-modal-footer__left { margin-right: auto; }
.cc-modal-close {
    background: none;
    border: none;
    cursor: pointer;
    /* Secondary, not tertiary: tertiary put this at 2.5:1 on a white panel,
       under the 3:1 WCAG asks of a non-text control (SC 1.4.11). Secondary
       clears it in both themes and the X still reads as quieter than the
       heading beside it. */
    color: var(--color-text-secondary, #6b7280);
    padding: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md, 6px);
    transition: color 0.15s, background 0.15s;
}
.cc-modal-close:hover {
    color: var(--color-text, #111827);
    background: var(--color-bg, #f3f4f6);
}

/* Date/time inputs — Flatpickr handles the calendar; keep native icon hidden so we don't show two UIs */
input[type="date"], input[type="datetime-local"], input[type="time"], input[type="month"] {
    cursor: pointer;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator {
    display: none;
    -webkit-appearance: none;
}

/* ────────────────────────────────────────────────────────────────
   Flatpickr custom theme — maps to our CSS vars (light + dark)
   ──────────────────────────────────────────────────────────────── */
.flatpickr-calendar {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
    font-family: inherit;
    width: auto !important;
    padding: 0;
    box-sizing: content-box;
}
.flatpickr-calendar.open { z-index: 10000; }
.flatpickr-calendar::before, .flatpickr-calendar::after { display: none; }
.flatpickr-calendar.arrowTop, .flatpickr-calendar.arrowBottom { margin-top: 4px; }

/* Calendar / clock icon on Flatpickr-powered date & time inputs — scoped to the
   .fp-cal / .fp-clock class (added in onReady), so it works on any base class
   (admin .form-input, portal .portal-input, etc.). */
.fp-cal, .fp-clock { background-repeat: no-repeat !important; background-position: right 12px center !important; background-size: 16px !important; padding-right: 38px !important; }
.fp-cal { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E") !important; }
.fp-clock { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E") !important; }

/* Month / year header */
.flatpickr-months { padding: 4px 10px 8px; align-items: center; background: transparent; }
.flatpickr-months .flatpickr-month {
    background: transparent;
    color: var(--color-text);
    height: 34px;
    overflow: visible;
}
.flatpickr-current-month {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text);
    padding: 4px 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.flatpickr-current-month .flatpickr-monthDropdown-months {
    background: transparent;
    background-image: none;
    color: var(--color-text);
    font-weight: 600;
    font-size: 14px;
    padding: 4px 20px 4px 6px;
    border-radius: 6px;
    transition: background .12s;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-repeat: no-repeat;
    background-position: right 4px center;
    background-size: 10px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
[data-theme="dark"] .flatpickr-current-month .flatpickr-monthDropdown-months {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
}
.flatpickr-current-month .flatpickr-monthDropdown-months:hover { background-color: var(--color-surface-hover); }
.flatpickr-current-month input.cur-year {
    background: transparent;
    color: var(--color-text);
    font-weight: 600;
    font-size: 14px;
    padding: 4px 6px;
    border-radius: 6px;
    width: 56px;
}
.flatpickr-current-month input.cur-year:hover,
.flatpickr-current-month input.cur-year:focus { background-color: var(--color-surface-hover); }
.numInputWrapper:hover { background: transparent; }
.numInputWrapper span { border: none; opacity: 0; transition: opacity .12s; }
.numInputWrapper:hover span { opacity: 1; }
.numInputWrapper span.arrowUp::after { border-bottom-color: var(--color-text-secondary); }
.numInputWrapper span.arrowDown::after { border-top-color: var(--color-text-secondary); }

/* Prev / next arrows */
.flatpickr-months .flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month {
    color: var(--color-text-secondary);
    fill: var(--color-text-secondary);
    padding: 8px;
    border-radius: 8px;
    height: 34px;
    width: 34px;
    top: 2px;
    transition: all .12s;
}
.flatpickr-months .flatpickr-prev-month:hover,
.flatpickr-months .flatpickr-next-month:hover {
    background: var(--color-surface-hover);
    color: var(--color-primary);
    fill: var(--color-primary);
}
.flatpickr-months .flatpickr-prev-month svg,
.flatpickr-months .flatpickr-next-month svg { width: 12px; height: 12px; }
.flatpickr-months .flatpickr-prev-month svg path,
.flatpickr-months .flatpickr-next-month svg path { fill: currentColor; }

/* Weekday labels */
.flatpickr-weekdays { background: transparent; height: 30px; }
.flatpickr-weekdaycontainer { justify-content: space-around; }
span.flatpickr-weekday {
    background: transparent;
    color: var(--color-text-tertiary);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* Days grid — keep Flatpickr's default width constraints */
.flatpickr-day {
    color: var(--color-text);
    font-size: 13px;
    font-weight: 500;
    border-radius: 8px;
    border: none;
    transition: all .12s;
    /* Vertical only — a horizontal margin would break the 7-across wrap.
       Flatpickr stacks rows flush, so any day with a filled background (today,
       selected, a blocked date) runs straight into the row above and a column
       of them reads as one tall block. 2px each side gives a 4px gap, which
       lands next to the 5px Flatpickr already leaves between days in a row —
       so the grid reads evenly instead of tight vertically and loose across. */
    margin: 2px 0;
}
.flatpickr-day:hover,
.flatpickr-day.prevMonthDay:hover,
.flatpickr-day.nextMonthDay:hover {
    background: var(--color-primary-bg);
    color: var(--color-primary);
    border: none;
}
.flatpickr-day.today {
    background: transparent;
    color: var(--color-primary);
    font-weight: 700;
    border: 1px solid var(--color-primary);
}
.flatpickr-day.today:hover { background: var(--color-primary-bg); color: var(--color-primary); }
.flatpickr-day.selected,
.flatpickr-day.selected:hover,
.flatpickr-day.selected.today {
    background: var(--color-primary);
    color: #fff;
    border: none;
    font-weight: 600;
}
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay {
    color: var(--color-text-tertiary);
}
.flatpickr-day.disabled,
.flatpickr-day.flatpickr-disabled {
    color: var(--color-text-tertiary);
    opacity: 0.4;
    background: transparent;
}
.flatpickr-day.flatpickr-disabled:hover { background: transparent; cursor: not-allowed; }

/* Taken, not merely unpickable. The default disabled day fades to 40% grey,
   which reads as "nothing here" — fine for a date outside a min/max range,
   wrong when the day is blocked because something already owns it. Opt in by
   adding `fp-cal--taken` to the calendar container and the blocked days come
   back to full strength on a red tint, so the eye lands on them instead of
   sliding past. Add this to any picker whose `disable` list means "booked". */
.flatpickr-calendar.fp-cal--taken .flatpickr-day.flatpickr-disabled,
.flatpickr-calendar.fp-cal--taken .flatpickr-day.flatpickr-disabled:hover {
    background: var(--color-danger-light);
    color: var(--color-danger-strong);
    opacity: 1;
    font-weight: 600;
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    cursor: not-allowed;
}
/* Adjacent-month days keep their recessed look even when taken — they are
   context, not choices, and full-strength red there fights the current month. */
.flatpickr-calendar.fp-cal--taken .flatpickr-day.flatpickr-disabled.prevMonthDay,
.flatpickr-calendar.fp-cal--taken .flatpickr-day.flatpickr-disabled.nextMonthDay {
    opacity: 0.45;
    font-weight: 500;
}

/* The sentence under the field that says WHY the day is blocked — filled and
   shown by ccsBlockDates(). Hidden until there is something to say. */
.cc-date-taken {
    display: none;
    margin-top: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-danger-light);
    border-radius: var(--radius-md);
    background: var(--color-danger-bg);
    color: var(--color-danger-strong);
    font-size: 13px;
    line-height: 1.5;
}
.cc-date-taken a { color: inherit; text-decoration: underline; }

/* Plan wall — <x-plan-upgrade>. Shown WHERE the feature would have been, not
   after a form is filled and rejected. Blue rather than red on purpose:
   reaching a plan limit is the product working as designed, so it should read
   as an offer. Red would make a routine upgrade moment feel like a fault. */
.cc-plan-upgrade {
    padding: 18px;
    border: 1px solid var(--color-primary-light);
    border-radius: var(--radius-lg, 12px);
    background: var(--color-primary-bg);
    text-align: center;
}
.cc-plan-upgrade__badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 8px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--color-primary);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
}
.cc-plan-upgrade__msg {
    margin: 0 0 6px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.45;
    color: var(--color-text);
}
.cc-plan-upgrade__note {
    margin: 0 0 14px;
    font-size: 12.5px;
    line-height: 1.5;
    /* One step darker than --color-text-secondary, which measures 4.0:1 on the
       blue tint in light mode — under AA for text this size. This is 6.3:1 and
       still clearly secondary to the message above it. Dark mode's secondary
       already clears it (6.8:1), so that one keeps the token. */
    color: #4b5563;
}
[data-theme="dark"] .cc-plan-upgrade__note { color: var(--color-text-secondary); }
/* No reassurance line — the message itself carries the gap above the button. */
.cc-plan-upgrade__msg:last-of-type { margin-bottom: 14px; }

/* Time picker */
/* ─── Time picker row ──────────────────────────────────────────────────
   Flatpickr ships `.flatpickr-time` with a locked 40px height + 40px
   line-height on children, which makes padding double-add visually and
   gives AM/PM its own default padding (0 6px) that doesn't match the
   numeric inputs. Reset those defaults and use flex alignment instead, so
   hour / : / minute / AM-PM all render with the same tap-target shape. */
.flatpickr-time {
    display: flex !important;
    align-items: stretch;
    border-top: 1px solid var(--color-border);
    padding: 10px 14px;
    margin-top: 4px;
    height: auto !important;
    max-height: none !important;
    gap: 4px;
    overflow: visible;
}
/* Time-only mode (`noCalendar: true`): drop the border-top + margin-top that
   were meant to separate the time row from a calendar grid that isn't there. */
.flatpickr-calendar.noCalendar .flatpickr-time {
    border-top: 0;
    margin-top: 0;
    padding: 8px 10px;
}
.flatpickr-time .numInputWrapper {
    display: flex;
    align-items: stretch;
    height: auto;
    flex: 1 1 0;
    width: auto !important;
}
.flatpickr-time input.flatpickr-hour,
.flatpickr-time input.flatpickr-minute,
.flatpickr-time .flatpickr-am-pm {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 40px;
    padding: 0 12px;
    margin: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    box-sizing: border-box;
    transition: background 0.12s;
    -webkit-appearance: none;
    appearance: none;
}
.flatpickr-time input.flatpickr-hour:hover,
.flatpickr-time input.flatpickr-hour:focus,
.flatpickr-time input.flatpickr-minute:hover,
.flatpickr-time input.flatpickr-minute:focus,
.flatpickr-time .flatpickr-am-pm:hover,
.flatpickr-time .flatpickr-am-pm:focus { background: var(--color-surface-hover); }
/* The flatpickr-am-pm is a <span> that gets its own flex sizing; keep it
   matching the input footprint so the row reads as three equal cells. */
.flatpickr-time .flatpickr-am-pm { flex: 1 1 0; cursor: pointer; }
.flatpickr-time .flatpickr-time-separator {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 2px;
    color: var(--color-text-secondary);
    font-weight: 500;
    font-size: 14px;
    line-height: 1;
    flex: 0 0 auto;
}
/* Hide the spinner arrows flatpickr injects — they conflict with the padded
   centered layout. Users can still type or use scroll. */
.flatpickr-time .numInputWrapper span.arrowUp,
.flatpickr-time .numInputWrapper span.arrowDown { display: none !important; }

/* Inner container holds weekdays + days — add horizontal padding so SAT column doesn't clip */
.flatpickr-innerContainer { padding: 0 10px 10px; }


/* =========================================================================
   Empty State — unified component
   ========================================================================= */

.cc-empty-state {
    text-align: center;
    padding: 80px 24px;
}

.cc-empty-state__title {
    font-size: 18px;
    font-weight: 700;
    color: var(--color-text, #111827);
    margin: 0 0 20px;
}

.cc-empty-state__cta {
    padding: 10px 24px;
    font-size: 14px;
    font-weight: 600;
    border-radius: 6px;
}

/* Global: force 6px radius on buttons, text inputs, selects, textareas */
button:not([type="checkbox"]):not([type="radio"]):not(.form-switch__slider),
input[type="text"], input[type="email"], input[type="password"], input[type="url"],
input[type="search"], input[type="number"], input[type="tel"], input[type="date"],
input[type="file"], select, textarea,
[type="button"], [type="submit"], [type="reset"] {
    border-radius: 6px !important;
}

/* Global: styled checkboxes (exclude form-switch hidden inputs) */
input[type="checkbox"]:not(.form-switch input) {
    appearance: none; -webkit-appearance: none;
    width: 16px !important; height: 16px !important;
    min-width: 16px; min-height: 16px;
    background: #fff; border: 1px solid #d1d5db;
    border-radius: 4px !important; cursor: pointer;
    flex-shrink: 0; vertical-align: middle;
}
.form-switch input[type="checkbox"] {
    position: absolute; opacity: 0; width: 0 !important; height: 0 !important; min-width: 0; min-height: 0;
}
input[type="checkbox"]:not(.form-switch input):checked {
    background: #1264FF; border-color: #1264FF;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: center;
}
[data-theme="dark"] input[type="checkbox"]:not(.form-switch input) { background: #2e3140; border-color: #4b5563; }
[data-theme="dark"] input[type="checkbox"]:not(.form-switch input):checked { background: #1264FF; border-color: #1264FF; }

/* ─────────────────────────────────────────────────────────────────────────
   Conversational content (DM message bodies, project comments, message
   replies, support ticket replies). Headings render at body size + bold —
   no visual hierarchy needed in a chat/comment bubble. Keeps lists, code,
   blockquotes from breaking out of the bubble.
   For long-form content (project descriptions, KB articles, message
   originals, donation/event descriptions) DON'T add these classes; real
   heading sizes still apply.
   ───────────────────────────────────────────────────────────────────────── */
.thread-content h1, .thread-content h2, .thread-content h3,
.thread-content h4, .thread-content h5, .thread-content h6,
.comment-content h1, .comment-content h2, .comment-content h3,
.comment-content h4, .comment-content h5, .comment-content h6,
.dm-msg__body h1, .dm-msg__body h2, .dm-msg__body h3,
.dm-msg__body h4, .dm-msg__body h5, .dm-msg__body h6 {
    font-size: inherit;
    font-weight: 700;
    line-height: inherit;
    margin: 0 0 4px;
}
.thread-content ul, .thread-content ol,
.comment-content ul, .comment-content ol {
    margin: 4px 0 6px;
    padding-left: 22px;
}
.thread-content p, .comment-content p,
.thread-content > div, .comment-content > div,
.dm-msg__body p, .dm-msg__body > div {
    margin: 0 0 10px;
}
.thread-content p:last-child, .comment-content p:last-child,
.thread-content > div:last-child, .comment-content > div:last-child,
.dm-msg__body p:last-child, .dm-msg__body > div:last-child {
    margin-bottom: 0;
}

/* =========================================================================
   People-picker option — standardized row inside any modal picker dropdown.
   Avatar + name + email stacked, divider between rows. Used wherever an
   admin chooses a person from a searchable list: scheduler Add Assignment,
   portal-user invite, group member add, worship team add, etc.
   Markup: resources/views/partials/people-picker-option.blade.php
   ========================================================================= */
/* Compound selector (.cc-combo__option.people-picker-option) so these win
   over per-page inline .cc-combo__option styles still scattered across blade
   views. Once those are migrated we can drop the .cc-combo__option prefix. */
.cc-combo__option.people-picker-option,
.people-picker-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border-light, #f2f6fb);
    border-radius: 0;
    cursor: pointer;
    min-width: 0;
}
.cc-combo__option.people-picker-option:last-child,
.people-picker-option:last-child { border-bottom: 0; }
.cc-combo__option.people-picker-option:hover:not(.is-disabled),
.people-picker-option:hover:not(.is-disabled) {
    background: var(--color-primary-light, #eff6ff);
}
.cc-combo__option.people-picker-option.is-disabled,
.people-picker-option.is-disabled {
    color: var(--color-text-tertiary, #9ca3af);
    cursor: not-allowed;
    opacity: 0.7;
}
.people-picker-option__avatar { flex: 0 0 auto; display: inline-flex; }
.people-picker-option__text {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}
.people-picker-option__name {
    font-size: 13px;
    color: var(--color-text, #111827);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: flex;
    align-items: center;
    gap: 6px;
}
.people-picker-option__email {
    font-size: 11px;
    color: var(--color-text-tertiary, #9ca3af);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-top: 1px;
}
.people-picker-option__hint {
    font-size: 11px;
    color: var(--color-text-tertiary, #9ca3af);
    font-weight: 400;
}

/* --------------------------------------------------------------------------
   Table footer + pagination + per-page selector — GLOBAL.
   Previously shipped via @once blocks inside the paginator/footer/per-page
   view components, which dropped out on AJAX-swapped partials (pager fell
   back to bulleted <ul>). Defined here so every list page styles correctly.
   -------------------------------------------------------------------------- */
.studio-table-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 12px 20px;
    border-top: 1px solid var(--color-border-light);
}
.studio-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    font-size: 13px;
    color: var(--color-text-secondary);
}
.studio-pagination__info strong { color: var(--color-text); font-weight: 600; }
.studio-pagination__list {
    display: flex;
    align-items: center;
    gap: 4px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.studio-pagination__item > a,
.studio-pagination__item > span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 10px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-secondary);
    text-decoration: none;
    border: 1px solid transparent;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.studio-pagination__item > a:hover {
    background: var(--color-bg);
    color: var(--color-text);
    border-color: var(--color-border-light);
}
.studio-pagination__item.is-active > span {
    background: var(--color-primary, #1264FF);
    color: #fff;
    font-weight: 600;
}
.studio-pagination__item.is-disabled > span {
    color: var(--color-text-tertiary);
    cursor: not-allowed;
    opacity: 0.5;
}
.studio-pagination__item > a svg,
.studio-pagination__item > span svg { width: 14px; height: 14px; flex-shrink: 0; }
.studio-per-page { display: inline-flex; align-items: center; }
.studio-per-page__label { font-size: 13px; color: var(--color-text-secondary); display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.studio-per-page__select {
    padding: 6px 28px 6px 10px;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    background: var(--color-surface) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") right 8px center / 12px no-repeat;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text);
    cursor: pointer;
}
.studio-per-page__select:focus { outline: 2px solid var(--color-primary, #1264FF); outline-offset: 1px; }

/* Mini rich-text editor (data-me) — styled to match .form-input fields. */
.me, [data-me] { border: 1px solid #cbd5e1 !important; border-radius: var(--radius-md, 8px); overflow: hidden; transition: border-color 150ms, box-shadow 150ms; background: #f2f6fb; }
[data-theme="dark"] .me, [data-theme="dark"] [data-me] { background: #1f222d; border-color: #3a3f4b !important; }
.me:focus-within { border-color: var(--color-primary) !important; box-shadow: 0 0 0 3px var(--color-primary-bg, rgba(20, 95, 255, 0.12)); }
.me__bar { display: flex; align-items: center; gap: 2px; padding: 6px 8px; border-bottom: 1px solid #cbd5e1; background: rgba(0, 0, 0, 0.02); }
[data-theme="dark"] .me__bar { border-bottom-color: #3a3f4b; background: rgba(255, 255, 255, 0.03); }
.me__btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 26px; border: none; background: none; border-radius: 4px; cursor: pointer; color: var(--color-text-secondary, #6b7280); font-size: 13px; font-family: inherit; }
.me__btn:hover { background: var(--color-border-light, #e5e7eb); color: var(--color-text, #111827); }
.me__body { min-height: 96px; max-height: 280px; overflow-y: auto; padding: 10px 14px; font-size: 14px; line-height: 1.55; outline: none; color: var(--color-text, #111827); background: transparent; }
.me__body:empty::before { content: attr(data-placeholder); color: var(--color-text-tertiary, #9ca3af); }
.me__body ul, .me__body ol { margin: 4px 0 4px 20px; padding-left: 16px; }
.me__body ul { list-style: disc; }
.me__body ol { list-style: decimal; }
.me__body h3 { font-size: 16px; font-weight: 700; margin: 6px 0 4px; line-height: 1.3; }
/* Rendered rich text (work-order descriptions etc.) — restore list markers
   + heading sizing that global resets strip. */
[data-rich-text] ul { list-style: disc; margin: 4px 0 4px 20px; padding-left: 16px; }
[data-rich-text] ol { list-style: decimal; margin: 4px 0 4px 20px; padding-left: 16px; }
[data-rich-text] h3 { font-size: 16px; font-weight: 700; margin: 6px 0 4px; line-height: 1.3; }
[data-rich-text] a { color: var(--color-primary, #145fff); text-decoration: underline; }
.me__body a { color: var(--color-primary, #145fff); text-decoration: underline; }

/* ── First steps ──────────────────────────────────────────────────────────
   The "make your first thing" row. Deliberately NOT part of the setup
   checklist's progress ring: these are suggestions, and a percentage that
   folds in optional work can never honestly reach 100 — it stops reading as
   progress and starts reading as a to-do list that never ends. So they live
   here instead, as their own row, and the row can be hidden for good. */
.dash-start { margin-bottom: 24px; }
.dash-start__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 10px;
}
.dash-start__eyebrow {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--color-text-tertiary);
}
.dash-start__eyebrow svg { color: var(--color-primary); }
[data-theme="dark"] .dash-start__eyebrow svg { color: #8b5cf6; }
.dash-start__hide {
    background: none; border: 0; padding: 2px 4px; cursor: pointer;
    font-family: inherit; font-size: 12px; font-weight: 600;
    color: var(--color-text-tertiary); border-radius: 6px;
    transition: color 0.14s ease, background 0.14s ease;
}
.dash-start__hide:hover { color: var(--color-text); background: var(--color-surface-secondary); }

/* Fixed four tracks, never auto-fit. With auto-fit an empty track collapses
   and a lone card stretches the full width — a card the shape of a banner. The
   tracks match .metrics-grid's four, so whatever is left lines up with the
   metric cards below instead of floating at its own size. */
.dash-start__grid {
    display: grid; gap: 16px;
    grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 1200px) { .dash-start__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px)  { .dash-start__grid { grid-template-columns: 1fr; } }

/* These are an invitation, not a reading. The metric cards below are flat
   white with a pale icon chip; if these matched, the row would read as more of
   the same and the eye would skip it. So they get their own language: a real
   gradient hairline border, a faintly warmed surface, a gradient-filled icon
   tile with light under it, and a CTA that's a pill instead of a text link. */
.dash-start-card {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; gap: 6px;
    padding: 18px 18px 16px;
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    /* Two backgrounds make a gradient border: the padding-box layer paints the
       surface, the border-box layer shows through the transparent 1px edge. */
    background:
        linear-gradient(170deg, #ffffff 0%, #f6f9ff 100%) padding-box,
        linear-gradient(135deg, rgba(18, 100, 255, 0.42) 0%, rgba(124, 58, 237, 0.32) 52%, rgba(18, 100, 255, 0.10) 100%) border-box;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 6px 18px rgba(18, 100, 255, 0.07);
    transition: box-shadow 0.18s ease, transform 0.18s ease;
}
/* Corner light, warmed on hover. */
.dash-start-card::before {
    content: ''; position: absolute; top: -70px; right: -70px;
    width: 170px; height: 170px; border-radius: 50%;
    background: radial-gradient(circle, rgba(109, 60, 245, 0.16) 0%, rgba(18, 100, 255, 0.07) 45%, rgba(18, 100, 255, 0) 72%);
    opacity: 0.55; transition: opacity 0.24s ease, transform 0.24s ease; pointer-events: none;
}
.dash-start-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 2px 4px rgba(16, 24, 40, 0.05), 0 14px 30px rgba(18, 100, 255, 0.16);
}
.dash-start-card:hover::before { opacity: 1; transform: scale(1.12); }

/* Filled gradient tile with light beneath it — the single biggest tell that
   this isn't a metric card, whose chip is a flat pale wash. */
.dash-start-card__icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; margin-bottom: 6px; border-radius: 12px;
    background: linear-gradient(135deg, #1264FF 0%, #6d3cf5 100%);
    color: #fff;
    box-shadow: 0 6px 14px rgba(18, 100, 255, 0.30);
    transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.dash-start-card:hover .dash-start-card__icon {
    transform: translateY(-1px) scale(1.04);
    box-shadow: 0 9px 20px rgba(18, 100, 255, 0.40);
}

/* Scoped past the global link colour, which would otherwise paint the title
   blue in dark mode and lose the card's hierarchy. */
.dash-start-card a.dash-start-card__title,
[data-theme="dark"] .dash-start-card a.dash-start-card__title {
    font-size: 14px; font-weight: 650; line-height: 1.35;
    color: var(--color-text); text-decoration: none;
}
.dash-start-card__desc {
    font-size: 12px; line-height: 1.45; color: var(--color-text-tertiary);
    /* Two lines, so cards in a row stay the same height whatever the copy. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* margin-top:auto pins the CTA to the bottom, so it lines up across the row
   whether a card's description ran to one line or two. A tinted block rather
   than a text link — it reads as something to press. 6px to match every other
   button in the app; Studio doesn't do pills. */
.dash-start-card__cta {
    align-self: flex-start;
    display: inline-flex; align-items: center; gap: 5px;
    margin-top: auto; padding: 6px 11px;
    border-radius: 6px;
    background: rgba(18, 100, 255, 0.09);
    font-size: 12px; font-weight: 650; color: var(--color-primary);
    transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}
.dash-start-card__cta svg { transition: transform 0.18s ease; }
.dash-start-card:hover .dash-start-card__cta {
    background: linear-gradient(135deg, #1264FF 0%, #6d3cf5 100%);
    color: #fff;
    box-shadow: 0 4px 12px rgba(18, 100, 255, 0.32);
}
.dash-start-card:hover .dash-start-card__cta svg { transform: translateX(3px); }

/* The whole card is the link; the help pip sits above it so it stays
   clickable in its own right. */
.dash-start-card__link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.dash-start-card__help {
    position: absolute; top: 12px; right: 12px; z-index: 2;
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 6px;
    border: 1px solid rgba(18, 100, 255, 0.20); background: rgba(255, 255, 255, 0.72);
    color: var(--color-text-tertiary); font-size: 11px; font-weight: 700;
    line-height: 1; text-decoration: none;
    transition: color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}
.dash-start-card__help:hover {
    color: var(--color-primary); border-color: var(--color-primary);
    background: #fff;
}

[data-theme="dark"] .dash-start-card {
    background:
        linear-gradient(170deg, #1c2130 0%, #161a26 100%) padding-box,
        linear-gradient(135deg, rgba(96, 165, 250, 0.50) 0%, rgba(167, 139, 250, 0.36) 52%, rgba(96, 165, 250, 0.10) 100%) border-box;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 8px 22px rgba(0, 0, 0, 0.24);
}
[data-theme="dark"] .dash-start-card::before {
    background: radial-gradient(circle, rgba(167, 139, 250, 0.20) 0%, rgba(96, 165, 250, 0.10) 45%, rgba(96, 165, 250, 0) 72%);
}
[data-theme="dark"] .dash-start-card:hover {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45), 0 16px 34px rgba(0, 0, 0, 0.42);
}
[data-theme="dark"] .dash-start-card__icon {
    background: linear-gradient(135deg, #3b7fff 0%, #8b5cf6 100%);
    box-shadow: 0 6px 16px rgba(59, 127, 255, 0.34);
}
[data-theme="dark"] .dash-start-card:hover .dash-start-card__icon { box-shadow: 0 9px 22px rgba(59, 127, 255, 0.46); }
[data-theme="dark"] .dash-start-card__cta { background: rgba(96, 165, 250, 0.16); color: #7aa2ff; }
[data-theme="dark"] .dash-start-card:hover .dash-start-card__cta {
    background: linear-gradient(135deg, #3b7fff 0%, #8b5cf6 100%); color: #fff;
}
[data-theme="dark"] .dash-start-card__help {
    border-color: rgba(129, 140, 248, 0.35); background: rgba(255, 255, 255, 0.06); color: #9aa3b5;
}
[data-theme="dark"] .dash-start-card__help:hover { color: #7aa2ff; border-color: #7aa2ff; background: rgba(99, 102, 241, 0.20); }

/* Hidden row: the wrapper still renders as the mount point for the refresh
   script, so it must take up no space at all when it holds nothing. */
.dash-start--empty { display: none; }

/* ── At-a-glance sidebar summary ──────────────────────────────────────────
   A quiet card, so it gets refinement rather than the first-steps row's
   colour: a hairline gradient edge, a tinted chip per row, rules between
   rows, and tabular figures so the numbers line up in a column instead of
   wandering with the digit widths. */
/* Insets are chosen so the icons in this card land on the same vertical line
   as the icons in the .dash-tile cards below it (Quick Actions, Public Links).
   A tile's icon sits at card border (1) + body padding (20) + tile border (1)
   + tile padding (12) = 34px from the sidebar's edge; these rows have no inner
   border of their own, so they carry 13px to reach the same place. Get this
   wrong and the sidebar reads as two columns that don't quite agree. */


/* Same 32/9 chip as .dash-tile__icon, so every icon in the sidebar is one
   size and one shape. */


/* ── Help pip ─────────────────────────────────────────────────────────────
   The "?" beside a card title. Quiet until you look for it: it sits at the
   title's weight but the border's colour, so it reads as an affordance rather
   than a second heading. 6px like every other button in the app. */
.cc-help-pip {
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0; width: 18px; height: 18px; margin-left: 8px;
    border: 1px solid var(--color-border); border-radius: 6px;
    color: var(--color-text-tertiary);
    font-size: 11px; font-weight: 700; line-height: 1; text-decoration: none;
    vertical-align: middle;
    transition: color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}
.cc-help-pip:hover {
    color: var(--color-primary);
    border-color: var(--color-primary);
    background: var(--color-primary-bg);
}

/* Learn-how link under an empty state's button — the next thing to read when
   the button isn't the next thing you want to do. */
.cc-learn-how {
    display: inline-block; margin-top: 10px;
    font-size: 12px; font-weight: 600; color: var(--color-text-tertiary);
    text-decoration: none;
    transition: color 0.14s ease;
}
.cc-learn-how:hover { color: var(--color-primary); }

/* Glance rows that carry a meter or a word rather than a figure. */

/* ── Plan alert ───────────────────────────────────────────────────────────
   The version that takes the top of the page, and only when something is
   actually wrong: trial nearly out, payment failed, storage nearly full. */
.dash-plan-alert {
    display: flex; align-items: center; gap: 14px;
    padding: 14px 18px; margin-bottom: 24px;
    border: 1px solid; border-radius: var(--radius-lg);
}
.dash-plan-alert__icon {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 38px; height: 38px; border-radius: 11px;
}
.dash-plan-alert__body { flex: 1; min-width: 0; }
.dash-plan-alert__title { font-size: 14px; font-weight: 650; color: var(--color-text); line-height: 1.35; }
.dash-plan-alert__meta { font-size: 12px; color: var(--color-text-secondary); margin-top: 2px; }

.dash-plan-alert--warning { border-color: #fcd34d; background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%); }
.dash-plan-alert--warning .dash-plan-alert__icon { background: #fde68a; color: #92400e; }
.dash-plan-alert--danger  { border-color: #fca5a5; background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%); }
.dash-plan-alert--danger .dash-plan-alert__icon { background: #fecaca; color: #991b1b; }

[data-theme="dark"] .dash-plan-alert--warning {
    border-color: rgba(245, 158, 11, 0.38); background: linear-gradient(135deg, #2a2113 0%, #241c11 100%);
}
[data-theme="dark"] .dash-plan-alert--warning .dash-plan-alert__icon { background: rgba(245, 158, 11, 0.20); color: #fbbf24; }
[data-theme="dark"] .dash-plan-alert--danger {
    border-color: rgba(239, 68, 68, 0.38); background: linear-gradient(135deg, #2a1618 0%, #231214 100%);
}
[data-theme="dark"] .dash-plan-alert--danger .dash-plan-alert__icon { background: rgba(239, 68, 68, 0.20); color: #fca5a5; }
[data-theme="dark"] .dash-plan-alert__title { color: #f3f4f6; }
[data-theme="dark"] .dash-plan-alert__meta { color: #9ca3af; }

/* Neutral tier: 60% storage is a heads-up, not an alarm. Same shape as the
   warning strip so it reads as the same component, brand-coloured so it
   doesn't spend the alarm early. */
.dash-plan-alert--info { border-color: #c7d2fe; background: linear-gradient(135deg, #f8faff 0%, #eff6ff 100%); }
.dash-plan-alert--info .dash-plan-alert__icon { background: #dbeafe; color: #1264FF; }
[data-theme="dark"] .dash-plan-alert--info {
    border-color: rgba(99, 102, 241, 0.35); background: linear-gradient(135deg, #1a2133 0%, #151a27 100%);
}
[data-theme="dark"] .dash-plan-alert--info .dash-plan-alert__icon { background: rgba(18, 100, 255, 0.20); color: #7aa2ff; }

.dash-plan-alert__meter {
    display: block; height: 5px; margin-top: 8px; max-width: 320px;
    border-radius: 3px; overflow: hidden; background: rgba(0, 0, 0, 0.08);
}
.dash-plan-alert__meter > span { display: block; height: 100%; border-radius: 3px; transition: width 0.3s ease; }
.dash-plan-alert__meter--info > span    { background: linear-gradient(90deg, #1264FF 0%, #6d3cf5 100%); }
.dash-plan-alert__meter--warning > span { background: #f59e0b; }
.dash-plan-alert__meter--danger > span  { background: #ef4444; }
[data-theme="dark"] .dash-plan-alert__meter { background: rgba(255, 255, 255, 0.10); }

/* Trailing figure on a summary tile — where a Public Links row keeps its copy
   button. Tabular so a column of them lines up instead of wandering with the
   digit widths. */
.dash-tile__stat {
    flex-shrink: 0; margin-left: auto;
    font-size: 16px; font-weight: 700; color: var(--color-text);
    letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
    transition: color 0.14s ease;
}
.dash-tile__stat--text { font-size: 13px; font-weight: 600; letter-spacing: 0; }
a.dash-tile:hover .dash-tile__stat { color: var(--color-primary); }

/* Storage bar, sitting under the sub inside the tile body. */
.dash-tile__meter {
    display: block; margin-top: 6px; height: 5px;
    border-radius: 3px; overflow: hidden; background: var(--color-border-light);
}
.dash-tile__meter > span {
    display: block; height: 100%; border-radius: 3px;
    background: linear-gradient(90deg, #1264FF 0%, #6d3cf5 100%);
    transition: width 0.3s ease;
}
[data-theme="dark"] .dash-tile__meter { background: rgba(255, 255, 255, 0.10); }
[data-theme="dark"] .dash-tile__meter > span { background: linear-gradient(90deg, #3b7fff 0%, #8b5cf6 100%); }

/* ── Navigation loader ──────────────────────────────────────────────────────
   A brand-blue ring shown between the click and the next paint. Only appears
   once a load is genuinely slow (the 200ms is enforced in JS, not here), and
   fades rather than snapping in. Above modals — a navigation started from
   inside one still has to show through it. */
#ccs-nav-loader {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: none;
    align-items: center;
    justify-content: center;
    /* The light scrim is right for a NAVIGATION: it is over in a moment, and
       seeing the page you came from through it is what makes it feel quick. */
    background: rgba(255, 255, 255, 0.55);
    backdrop-filter: blur(1.5px);
    opacity: 0;
    transition: opacity 0.16s ease;
}
#ccs-nav-loader.is-on { display: flex; }
#ccs-nav-loader.is-visible { opacity: 1; }
[data-theme="dark"] #ccs-nav-loader { background: rgba(10, 12, 18, 0.55); }

/* A determinate, minutes-long job — today only the demo reset — takes the
   screen properly: solid var(--color-bg), the same backdrop the "Switching to
   <workspace>" overlay uses, and no blur. Scoped to progress mode on purpose.
   Every ordinary page-to-page navigation keeps the scrim above; making that
   solid turned every click into a full repaint, which reads as heavier than
   the navigation actually is. */
#ccs-nav-loader.is-progress,
[data-theme="dark"] #ccs-nav-loader.is-progress {
    background: var(--color-bg, #f2f6fb);
    backdrop-filter: none;
}

.ccs-nav-loader__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}

/* Only set by ccsNavLoader.busy(): a navigation is over in a moment and needs
   no caption, but a request that runs for half a minute has to say what it is
   doing or the spinner is just a different flavour of frozen.

   Sized to match the "Switching to <workspace>" overlay (jumper.blade.php,
   layouts/portal.blade.php) — 26px/700. Those two are the app's other
   full-screen wait, and at 14px this one read as a footnote next to them for
   the same kind of pause. The max-width goes with it: these captions are short
   phrases, and 320px at 26px wraps "Checking plugins on the site…" into three
   ragged lines. */
.ccs-nav-loader__label {
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--color-text, #111827);
    text-align: center;
    max-width: min(520px, 86vw);
    line-height: 1.35;
}
[data-theme="dark"] .ccs-nav-loader__label { color: var(--color-text, #e5e7eb); }

/* Progress mode — swapped in for the ring by busy(msg, {progress:true}). Wider
   than the label's max-width so a bar reads as a bar rather than a chip. */
.ccs-nav-loader__progress {
    width: min(420px, 80vw);
    margin-top: 4px;
}

.ccs-nav-loader__track {
    height: 8px;
    border-radius: 999px;
    background: rgba(20, 95, 255, 0.15);
    overflow: hidden;
}

[data-theme="dark"] .ccs-nav-loader__track { background: rgba(255, 255, 255, 0.14); }

.ccs-nav-loader__fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--color-primary, #145fff);
    /* Eases between two real readings 2s apart so the bar glides instead of
       jumping. It never runs ahead on its own — width only ever changes when
       the server reports a new figure. */
    transition: width 0.45s ease;
}

.ccs-nav-loader__meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 8px;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-secondary, #6b7280);
}

/* Tabular figures so a ticking clock doesn't jitter its own width. */
.ccs-nav-loader__elapsed {
    font-variant-numeric: tabular-nums;
    flex: none;
}

.ccs-nav-loader__ring {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 3px solid rgba(20, 95, 255, 0.18);
    border-top-color: var(--color-primary, #145fff);
    animation: ccs-nav-spin 0.7s linear infinite;
}

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

[data-theme="dark"] .ccs-nav-loader__ring { border-color: rgba(20, 95, 255, 0.3); border-top-color: var(--color-primary, #145fff); }

@media (prefers-reduced-motion: reduce) {
    /* The spin is the signal, so it stays — just slower, and without the fade. */
    #ccs-nav-loader { transition: none; }
    .ccs-nav-loader__ring { animation-duration: 1.4s; }
}


/* ---- moved out of a Blade partial (.nfeed-tabs) so it is cached
   instead of re-sent inline on every page render ---- */
.nfeed-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap;padding:14px 18px;border-bottom:1px solid var(--color-border-light,#e5e7eb);}
.nfeed-tab{appearance:none;border:0;background:transparent;font:inherit;font-size:13px;font-weight:500;color:var(--color-text-secondary,#6b7280);padding:6px 12px;border-radius:6px;text-decoration:none;cursor:pointer;white-space:nowrap;}
.nfeed-tab:hover{background:var(--color-surface-hover,#f2f6fb);color:var(--color-text,#111827);}
.nfeed-tab--active{background:var(--color-primary-bg,rgba(20,95,255,.08));color:var(--color-primary,#145fff);font-weight:600;}
.nfeed-tab__count{margin-left:5px;font-size:12px;font-weight:400;opacity:.7;}
.nfeed-actions{margin-left:auto;display:flex;align-items:center;gap:6px;}
.nfeed-action{appearance:none;border:0;background:transparent;font:inherit;font-size:13px;font-weight:600;color:var(--color-primary,#145fff);cursor:pointer;padding:6px 10px;border-radius:var(--radius-sm,6px);}
.nfeed-action:hover{background:var(--color-primary-bg,rgba(20,95,255,.08));}
.nfeed-action--muted{color:var(--color-text-tertiary,#9ca3af);font-weight:500;}

/* Row. The title and the body used to be inline spans, so every row read as
   one run-on sentence — "I'm New: Joshua Davis Landed in Connection Card
   Received". They stack now, which is what gives the list its shape. */
.nfeed-item{display:flex;align-items:flex-start;gap:14px;padding:16px 20px;border-bottom:1px solid var(--color-border-light,#dde5f1);text-decoration:none;color:inherit;transition:background .12s ease;}
.nfeed-item:last-of-type{border-bottom:0;}
.nfeed-item:hover{background:var(--color-surface-hover,#f2f6fb);}
/* Unread is a wash, not a highlight. Most of an active workspace's inbox is
   unread, and the stronger --color-primary-light turned the whole page blue;
   the left bar and the dot are what actually mark the row. */
.nfeed-item--unread{background:var(--color-primary-bg,rgba(20,95,255,.08));box-shadow:inset 3px 0 0 var(--color-primary,#145fff);}
.nfeed-icon{width:38px;height:38px;border-radius:var(--radius-lg,12px);display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--color-surface-secondary,#f9fafb);color:var(--color-text-tertiary,#9ca3af);}
/* A plain surface tile on the tinted row, so the icon lifts instead of
   dissolving into the wash behind it. */
.nfeed-item--unread .nfeed-icon{background:var(--color-surface,#fff);color:var(--color-primary,#145fff);}
.nfeed-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.nfeed-title{display:block;font-size:14px;font-weight:500;color:var(--color-text,#111827);line-height:1.35;}
.nfeed-item--unread .nfeed-title{font-weight:600;}
.nfeed-text{display:block;font-size:13px;color:var(--color-text-secondary,#6b7280);line-height:1.45;}
.nfeed-meta{font-size:12px;color:var(--color-text-tertiary,#9ca3af);margin-top:3px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.nfeed-pill{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--color-primary-bg,rgba(20,95,255,.08));color:var(--color-primary,#145fff);font-size:11px;font-weight:600;}
.nfeed-ws{display:inline-flex;align-items:center;gap:4px;padding:2px 9px 2px 7px;border-radius:999px;background:var(--color-surface-secondary,#f9fafb);color:var(--color-text-secondary,#6b7280);font-size:11px;font-weight:600;}
.nfeed-ws svg{flex-shrink:0;}
/* On an unread row the tinted background already owns the surface colour, so
   the chip lifts off it instead of sinking into it. */
.nfeed-item--unread .nfeed-ws{background:var(--color-surface,#fff);}
.nfeed-dot{width:8px;height:8px;border-radius:50%;background:var(--color-border,#e5e7eb);flex-shrink:0;align-self:center;}
.nfeed-dot--unread{background:var(--color-primary,#145fff);}
.nfeed-empty{text-align:center;padding:60px 24px;}
.nfeed-empty__icon{color:var(--color-border,#d1d5db);margin-bottom:10px;}
.nfeed-empty__title{font-size:15px;font-weight:600;color:var(--color-text,#374151);margin:0 0 4px;}
.nfeed-empty__text{font-size:13px;color:var(--color-text-tertiary,#9ca3af);margin:0;}
.nfeed-foot{padding:12px 18px;border-top:1px solid var(--color-border-light,#e5e7eb);}
.nfeed-count{font-size:13px;color:var(--color-text-secondary,#6b7280);}


/* ---- moved out of a Blade partial (.ccs-timer-widget) so it is cached
   instead of re-sent inline on every page render ---- */
.ccs-timer-widget { display: none; align-items: center; gap: 4px; position: relative; }
.ccs-timer-widget.active { display: flex; }
.ccs-timer-widget__toggle { display: flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 8px; border: 1px solid var(--color-border-light, #e5e7eb); background: var(--color-bg, #fff); color: var(--color-text-secondary, #6b7280); font-size: 13px; font-weight: 600; font-family: 'SF Mono', 'Menlo', monospace; cursor: pointer; transition: all 0.12s ease; white-space: nowrap; }
.ccs-timer-widget__toggle:hover { background: var(--color-bg-hover, #f9fafb); }
.ccs-timer-widget.running .ccs-timer-widget__toggle { background: #ecfdf5; border-color: #a7f3d0; color: #059669; }
.ccs-timer-widget.paused .ccs-timer-widget__toggle { background: #fffbeb; border-color: #fde68a; color: #d97706; }
.ccs-timer-widget__time { min-width: 60px; text-align: center; }
.ccs-timer-widget__controls { display: flex; gap: 2px; }
.ccs-timer-widget__btn { width: 28px; height: 28px; border-radius: 6px; border: 1px solid var(--color-border-light, #e5e7eb); background: var(--color-bg, #fff); color: var(--color-text-secondary, #6b7280); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.12s ease; }
.ccs-timer-widget__btn:hover { background: var(--color-bg-hover, #f2f6fb); color: var(--color-text-primary, #111827); }
.ccs-timer-widget__btn--start { color: #059669; }
.ccs-timer-widget__btn--start:hover { background: #ecfdf5; }
.ccs-timer-widget__btn--pause { color: #d97706; }
.ccs-timer-widget__btn--pause:hover { background: #fffbeb; }
.ccs-timer-widget__btn--reset { color: #9ca3af; }
.ccs-timer-widget__btn--reset:hover { background: #fef2f2; color: #ef4444; }
@media (max-width: 768px) { .ccs-timer-widget__time { display: none; } }

/* ─────────────────────────────────────────────────────────────────────────
   Long-form rich text (note bodies, project descriptions, message originals,
   and the comments and replies underneath them). The counterpart to the
   conversational block above: that one stays tight, which is right for a
   one-line "sounds good" and wrong the moment somebody pastes four labelled
   paragraphs and a nested list into a comment box — which is what actually
   happens on a client project. So comments get the same 16px rhythm and real
   heading sizes as the document they are attached to. A single-paragraph
   comment is unaffected: the first/last-child rules zero the outer margins,
   so nothing is added until there is a second block to separate.

   Add it ALONGSIDE the existing wrapper, e.g. class="comment-content
   rich-prose", so code, images and mention chips keep their styling and only
   the rhythm changes.

   The class is doubled on purpose. Two pages define their own .comment-content
   margins in an inline <style> inside the body, which at equal specificity
   would beat a stylesheet rule no matter where it sits in the file. Doubling
   takes this to (0,2,1) so it wins on specificity instead of source order —
   the alternative was unpicking four competing .comment-content definitions,
   which is a bigger change than a spacing tweak should be.
   ───────────────────────────────────────────────────────────────────────── */
.rich-prose.rich-prose > *:first-child { margin-top: 0; }
.rich-prose.rich-prose > *:last-child { margin-bottom: 0; }

.rich-prose.rich-prose p,
.rich-prose.rich-prose > div { margin: 16px 0; }

.rich-prose.rich-prose ul,
.rich-prose.rich-prose ol { margin: 16px 0; padding-left: 24px; }

/* A nested list belongs to the item above it, so it sits closer than two
   separate lists would. */
.rich-prose.rich-prose ul ul, .rich-prose.rich-prose ul ol,
.rich-prose.rich-prose ol ul, .rich-prose.rich-prose ol ol { margin: 8px 0; }

.rich-prose.rich-prose li { margin: 8px 0; }

/* Headings keep a real scale here — the conversational block collapses them
   to body size, which is right in a comment and wrong in a document. */
.rich-prose.rich-prose h1,
.rich-prose.rich-prose h2,
.rich-prose.rich-prose h3,
.rich-prose.rich-prose h4,
.rich-prose.rich-prose h5,
.rich-prose.rich-prose h6 { margin: 16px 0; font-weight: 700; line-height: 1.3; }
.rich-prose.rich-prose h1 { font-size: 20px; }
.rich-prose.rich-prose h2 { font-size: 18px; }
.rich-prose.rich-prose h3 { font-size: 16px; }
.rich-prose.rich-prose h4,
.rich-prose.rich-prose h5,
.rich-prose.rich-prose h6 { font-size: 15px; }

.rich-prose.rich-prose blockquote { margin: 16px 0; }
.rich-prose.rich-prose img { margin: 16px 0; }
.rich-prose.rich-prose hr { margin: 28px 0; }

/* Dividers. A browser's default <hr> is a 2px inset groove from 1996, and it
   is what every pasted document and every `---` in a note renders as. One rule
   for every prose surface — rendered content and the editor body alike, so a
   divider looks the same while you are writing it as after you save.
   The line fades at both ends so it reads as a pause rather than a border. */
.rich-prose hr,
.comment-content hr,
.note-content hr,
.se__body hr,
.me__body hr,
[data-rich-text] hr {
    border: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        var(--color-border, #d1d5db) 15%,
        var(--color-border, #d1d5db) 85%,
        transparent);
    margin: 28px 0;
    padding: 0;
    overflow: visible;
}
/* Inside the editor a divider is also a thing you can put the caret next to,
   so give it a little more room to be clicked past. */
.se__body hr, .me__body hr { margin: 20px 0; }

/* Search hit excerpt under a note title — why this row matched when the
   title doesn't say. */
.note-hit {
    margin-top: 3px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--color-text-secondary, #6b7280);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.note-hit mark { background: #fef3c7; color: inherit; padding: 0 2px; border-radius: 3px; }
[data-theme="dark"] .note-hit mark { background: #5a4a1a; color: #fde68a; }

/* Public-link control. Set apart from whatever else a share modal offers,
   because it is the one switch that puts a record outside the workspace.
   `.publink` is the name; `.note-publink` is the original, kept because the
   Share Note modal still writes it and this control is not worth a rename
   across two features to make one word shorter. */
.publink,
.note-publink {
    border: 1px solid var(--color-border-light, #dde5f1);
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 18px;
    background: var(--color-bg-subtle, #f2f6fb);
}
.publink__head,
.note-publink__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.publink__title,
.note-publink__title {
    display: flex; align-items: center; gap: 7px;
    font-size: 14px; font-weight: 600; color: var(--color-text, #111827);
}
.publink__sub,
.note-publink__sub { font-size: 12.5px; color: var(--color-text-secondary, #6b7280); margin-top: 3px; max-width: 46ch; }
.publink__url,
.note-publink__url { display: flex; gap: 8px; margin-top: 12px; }
.publink__url input,
.note-publink__url input {
    flex: 1; min-width: 0;
    padding: 7px 10px;
    border: 1px solid var(--color-border-light, #dde5f1);
    border-radius: 7px;
    background: var(--color-surface, #fff);
    color: var(--color-text, #111827);
    font-family: 'SF Mono', SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 12px;
}
/* Fields on the panel's tinted fill are white (the dark surface in dark
   mode), never the grey default, which vanishes into the panel and reads as
   disabled. background-color only, so a select keeps its arrow. Important
   because the global `select` and dark `.form-input` rules otherwise win. */
.publink input[type="text"], .publink select,
.note-publink input[type="text"], .note-publink select {
    background-color: var(--color-surface, #fff) !important;
    border: 1px solid var(--color-border-light, #dde5f1);
    color: var(--color-text, #111827);
}
[data-theme="dark"] .publink input[type="text"], [data-theme="dark"] .publink select,
[data-theme="dark"] .note-publink input[type="text"], [data-theme="dark"] .note-publink select {
    background-color: #1f222d !important;
    border-color: var(--color-border);
    color: var(--color-text);
}

/* "Public link is live" marker. Lives in a record's meta row, next to the
   author and the dates — it is a fact about the record, the same kind of fact
   as who made it, not an action. It was a free-standing pill above the title
   on the facilities pages, which read as a button and was not one. */
.publink-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    background: var(--color-success-light, #d4f5e2);
    color: var(--color-success-strong, #047857);
}

/* ── Links inside rendered rich text ──
   sanitize_autolink() turns bare URLs in comments, messages and notes into
   anchors, so they need to LOOK like links wherever that content lands. The
   selector lists all three containers the app renders sanitized HTML into
   rather than styling a bare <a>, which would repaint buttons and rows that
   happen to be anchors. */
.comment-content a,
.rich-prose a,
.md-render a { color: var(--color-primary, #1264FF); text-decoration: underline; text-underline-offset: 2px; word-break: break-word; }
.comment-content a:hover,
.rich-prose a:hover,
.md-render a:hover { text-decoration-thickness: 2px; }

/* ==========================================================================
   Dashboard trends — sparklines + change badges on metric cards, the day-one
   preview row, the main trend chart and the "who owes you" card.
   Data lives in App\Support\DashboardTrends; partials are _card-trend,
   _ghost-cards, _trend-chart and _aging.
   ========================================================================== */
:root {
    --dash-chart-a: #145fff;
    --dash-chart-a-past: #7aa2ff;
    --dash-chart-b: #bcd0ff;
    --dash-chart-ly: #e3e9f4;
    --dash-chart-ghost: #eef2f9;
    --dash-chart-line: #6d3cf5;
}
[data-theme="dark"] {
    --dash-chart-a-past: #4f7fe6;
    --dash-chart-b: #2f4b8a;
    --dash-chart-ly: rgba(255, 255, 255, 0.10);
    --dash-chart-ghost: rgba(255, 255, 255, 0.05);
    --dash-chart-line: #a78bfa;
}

.metric-card__spark { display: block; width: 100%; height: 36px; margin-top: 12px; overflow: visible; }
.metric-card__spark-area { fill: var(--color-primary-bg); stroke: none; }
.metric-card__spark-line { fill: none; stroke: var(--color-primary); stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.metric-card__spark--bad .metric-card__spark-area { fill: rgba(217, 119, 6, 0.10); }
.metric-card__spark--bad .metric-card__spark-line { stroke: #d97706; }
.metric-card__trend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; font-size: 12px; color: var(--color-text-secondary); }

.dash-delta { display: inline-flex; align-items: center; padding: 1px 7px; border-radius: 6px; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.dash-delta--good { background: #ecfdf5; color: #047857; }
.dash-delta--bad  { background: #fffbeb; color: #92400e; }
[data-theme="dark"] .dash-delta--good { background: rgba(5, 150, 105, 0.16); color: #6ee7b7; }
[data-theme="dark"] .dash-delta--bad  { background: rgba(251, 191, 36, 0.12); color: #fbbf24; }

/* Day-one preview: dashed, quiet, and plainly a promise rather than a zero. */
.dash-preview { display: flex; flex-direction: column; gap: 10px; }
.dash-preview .metrics-grid { margin-bottom: var(--space-5); }
.metric-card--ghost { border-style: dashed; box-shadow: none; }
.metric-card--ghost .metric-card__header { align-items: center; }
.metric-card--ghost .metric-card__label { margin-bottom: 0; }
.metric-card__ghost-line { border-top: 2px dashed var(--color-border-light); margin: 18px 0 12px; }
.metric-card__hint { margin: 0; font-size: 13px; line-height: 1.45; color: var(--color-text-secondary); }

/* Main trend chart */
.dash-chart { margin-bottom: 24px; }
.dash-chart .card__header { flex-wrap: wrap; gap: 12px; }
.dash-chart__sub { font-size: 13px; color: var(--color-text-secondary); margin-top: 2px; }
.dash-chart__head-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; font-size: 13px; color: var(--color-text-secondary); }
.dash-chart__head-meta b { color: var(--color-text); font-variant-numeric: tabular-nums; }
.dash-chart__legend-item { display: inline-flex; align-items: center; gap: 6px; }
.dash-chart__swatch { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.dash-chart__swatch--a { background: var(--dash-chart-a); }
.dash-chart__swatch--b { background: var(--dash-chart-b); }
.dash-chart__swatch--ly { background: var(--dash-chart-ly); }
.dash-chart__swatch--line { width: 16px; height: 3px; background: var(--dash-chart-line); }
.dash-chart__body { display: flex; gap: 10px; padding: 20px 20px 38px; }
.dash-chart__axis { display: flex; flex-direction: column; justify-content: space-between; height: 220px; min-width: 36px; font-size: 11px; color: var(--color-text-secondary); text-align: right; font-variant-numeric: tabular-nums; }
.dash-chart__plot { position: relative; flex: 1; min-width: 0; height: 220px; border-bottom: 1px solid var(--color-border); }
.dash-chart__cols { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 8px; }
.dash-chart__col { position: relative; flex: 1; min-width: 0; height: 100%; display: flex; align-items: flex-end; gap: 3px; }
.dash-chart__ly { flex: 1; background: var(--dash-chart-ly); border-radius: 3px 3px 0 0; }
.dash-chart__stack { flex: 1.4; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; }
.dash-chart__stack > .dash-chart__bar:first-child { border-radius: 4px 4px 0 0; }
.dash-chart__bar--a { background: var(--dash-chart-a-past); }
.dash-chart__bar--b { background: var(--dash-chart-b); }
.dash-chart__col--current .dash-chart__bar--a { background: var(--dash-chart-a); }
.dash-chart__label { position: absolute; bottom: -24px; left: -8px; right: -8px; text-align: center; font-size: 11px; color: var(--color-text-secondary); white-space: nowrap; }
.dash-chart__line { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.dash-chart__line path { fill: none; stroke: var(--dash-chart-line); stroke-width: 2.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.dash-chart--ghost .dash-chart__bar--a { background: var(--dash-chart-ghost); }
.dash-chart__empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 16px; }
.dash-chart__empty-box { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 380px; padding: 20px 24px; text-align: center; background: var(--color-surface); border: 1px solid var(--color-border-light); border-radius: var(--radius-lg); box-shadow: 0 10px 30px rgba(16, 24, 40, 0.08); }
.dash-chart__empty-title { font-size: 15px; font-weight: 600; color: var(--color-text); }
.dash-chart__empty-text { font-size: 13px; line-height: 1.5; color: var(--color-text-secondary); }
@media (max-width: 640px) {
    .dash-chart__cols { gap: 4px; }
    .dash-chart__col:nth-child(even) .dash-chart__label { display: none; }
}

/* Who owes you */
.dash-aging { margin-bottom: 24px; }
/* The app's own meter fills (tokens.css --cc-bar-gradient*): blue while
   nothing is late, amber for the first month, red after that — deepest red
   for anything past 90 days. */
.dash-aging__bar { display: flex; gap: 3px; height: 10px; margin-bottom: 14px; border-radius: 999px; overflow: hidden; background: var(--color-surface-secondary); }
.dash-aging__bar .dash-aging__seg:first-child { border-radius: 999px 0 0 999px; }
.dash-aging__bar .dash-aging__seg:last-child { border-radius: 0 999px 999px 0; }
.dash-aging__bar .dash-aging__seg:only-child { border-radius: 999px; }
.dash-aging__seg--current { background: var(--cc-bar-gradient); }
.dash-aging__seg--1_30    { background: var(--cc-bar-gradient-warn); }
.dash-aging__seg--31_60   { background: linear-gradient(90deg, #f97316, #fb923c); }
.dash-aging__seg--61_90   { background: var(--cc-bar-gradient-danger); }
.dash-aging__seg--90_plus { background: linear-gradient(90deg, #dc2626, #ef4444); }
.dash-aging__row { display: flex; align-items: center; gap: 10px; padding: 9px 0; font-size: 14px; border-top: 1px solid var(--color-border-light); }
.dash-aging__row:first-of-type { border-top: 0; }
.dash-aging__swatch { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.dash-aging__label { flex: 1; min-width: 0; color: var(--color-text); }
.dash-aging__count { font-size: 12px; color: var(--color-text-secondary); }
.dash-aging__amt { min-width: 80px; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--color-text); }

/* Needs attention — one card across the page, a segment per late or broken
   thing (_attention-strip). Replaces the loose .dash-attn pills at the top of
   the dashboard; the small in-card chips keep .dash-attn. */
.dash-attention {
    display: flex; align-items: stretch;
    margin-bottom: var(--space-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.dash-attention__head {
    display: flex; align-items: center; gap: 10px; flex: none;
    padding: 0 22px;
    border-right: 1px solid var(--color-border-light);
    background: var(--color-surface-secondary);
}
.dash-attention__title { font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--color-text-secondary); white-space: nowrap; }
.dash-attention__pulse { position: relative; width: 8px; height: 8px; border-radius: 50%; background: #ef4444; flex-shrink: 0; }
.dash-attention__pulse::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: #ef4444; animation: dash-attn-pulse 1.8s ease-out infinite; }
.dash-attention__items { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.dash-attention__item {
    display: flex; align-items: center; gap: 14px;
    min-height: 72px; padding: 14px 20px;
    border-left: 1px solid var(--color-border-light);
    text-decoration: none; color: inherit;
    transition: background 0.15s ease;
}
.dash-attention__item:first-child { border-left: 0; }
.dash-attention__item:hover { background: var(--color-surface-hover); color: inherit; }
.dash-attention__icon { width: 38px; height: 38px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.dash-attention__count { font-family: var(--font-display); font-size: 26px; font-weight: 600; line-height: 1; color: var(--color-text); font-variant-numeric: tabular-nums; }
.dash-attention__text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.dash-attention__label { font-size: 14px; font-weight: 500; line-height: 1.3; color: var(--color-text); }
.dash-attention__meta { font-size: 12px; font-weight: 600; }
.dash-attention__go { display: inline-flex; color: var(--color-text-tertiary); transition: transform 0.15s ease, color 0.15s ease; }
.dash-attention__item:hover .dash-attention__go { color: var(--color-primary); transform: translateX(3px); }

.dash-attention__item--red   .dash-attention__icon { background: #fef2f2; color: #ef4444; }
.dash-attention__item--amber .dash-attention__icon { background: #fffbeb; color: #d97706; }
.dash-attention__item--blue  .dash-attention__icon { background: #eff6ff; color: #1264FF; }
.dash-attention__item--green .dash-attention__icon { background: #ecfdf5; color: #059669; }
.dash-attention__item--red   .dash-attention__meta { color: #b91c1c; }
.dash-attention__item--amber .dash-attention__meta { color: #b45309; }
.dash-attention__item--blue  .dash-attention__meta { color: #1d4ed8; }
.dash-attention__item--green .dash-attention__meta { color: #047857; }
[data-theme="dark"] .dash-attention__item--red   .dash-attention__icon { background: rgba(239, 68, 68, 0.16); color: #fca5a5; }
[data-theme="dark"] .dash-attention__item--amber .dash-attention__icon { background: rgba(255, 182, 0, 0.16); color: #fcd34d; }
[data-theme="dark"] .dash-attention__item--blue  .dash-attention__icon { background: rgba(20, 95, 255, 0.16); color: #93c5fd; }
[data-theme="dark"] .dash-attention__item--green .dash-attention__icon { background: rgba(28, 198, 109, 0.16); color: #6ee7b7; }
[data-theme="dark"] .dash-attention__item--red   .dash-attention__meta { color: #fca5a5; }
[data-theme="dark"] .dash-attention__item--amber .dash-attention__meta { color: #fcd34d; }
[data-theme="dark"] .dash-attention__item--blue  .dash-attention__meta { color: #93c5fd; }
[data-theme="dark"] .dash-attention__item--green .dash-attention__meta { color: #6ee7b7; }

@media (max-width: 768px) {
    .dash-attention { flex-direction: column; }
    .dash-attention__head { padding: 12px 18px; border-right: 0; border-bottom: 1px solid var(--color-border-light); }
    .dash-attention__items { grid-template-columns: 1fr; }
    .dash-attention__item { border-left: 0; border-top: 1px solid var(--color-border-light); }
    .dash-attention__item:first-child { border-top: 0; }
}

/* Dashboard panels (_panels-main / _panels-aside). Built on the existing
   card, tile, timeline and metric-card type; only the pieces those don't
   cover live here — a two-up card row, labelled meters on the app's own
   --cc-bar-gradient fills, and the goal ring. */
.dash-card-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-bottom: 24px; }
.dash-card-row > .card { margin-bottom: 0; }

.dash-meters { display: flex; flex-direction: column; gap: 14px; }
.dash-meter { display: flex; flex-direction: column; gap: 6px; text-decoration: none; color: inherit; }
.dash-meter--link:hover .dash-meter__label { color: var(--color-primary); }
.dash-meter__row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 14px; }
.dash-meter__label { min-width: 0; font-weight: 500; color: var(--color-text); }
.dash-meter__sub { font-size: 12px; font-weight: 400; color: var(--color-text-secondary); }
.dash-meter__value { white-space: nowrap; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--color-text); }
.dash-meter__track { height: 8px; border-radius: 999px; background: var(--color-bg); overflow: hidden; }
.dash-meter__fill { height: 100%; border-radius: 999px; background: var(--cc-bar-gradient); }
.dash-meter__fill--warn { background: var(--cc-bar-gradient-warn); }
.dash-meter__foot { display: flex; justify-content: space-between; padding-top: 12px; border-top: 1px solid var(--color-border-light); font-size: 13px; color: var(--color-text-secondary); }
.dash-meter__foot b { color: var(--color-text); font-variant-numeric: tabular-nums; }

.dash-goal__body { display: flex; align-items: center; gap: 18px; }
.dash-goal__ring { flex-shrink: 0; }
.dash-goal__track { stroke: var(--color-primary-light); }
.dash-goal__fill { stroke: var(--color-primary); }
.dash-goal__fill--behind { stroke: #f59e0b; }
.dash-goal__pct { font-family: var(--font-display); font-size: 20px; font-weight: 700; fill: var(--color-text); }
.dash-goal__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dash-goal__text .metric-card__label { margin-bottom: 0; }
.dash-goal__of { font-size: 13px; color: var(--color-text-secondary); }
.dash-goal__pace { margin-top: 2px; font-size: 13px; font-weight: 600; }
.dash-goal__pace--good { color: var(--color-success-strong); }
.dash-goal__pace--behind { color: var(--color-warning-strong); }
[data-theme="dark"] .dash-goal__pace--good { color: #6ee7b7; }
[data-theme="dark"] .dash-goal__pace--behind { color: #fcd34d; }
.dash-goal__edit { padding: 10px 20px 14px; border-top: 1px solid var(--color-border-light); }
.dash-goal__edit summary { cursor: pointer; list-style: none; font-size: 13px; font-weight: 600; color: var(--color-primary); }
.dash-goal__edit summary::-webkit-details-marker { display: none; }
.dash-goal__form { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.dash-goal__form .form-input { flex: 1; min-width: 0; }
.dash-chart__ranges { padding: 12px 20px 0; gap: 6px; }

/* Customize: every card on the dashboard is a slot the member can hide or
   reorder (App\Support\DashboardLayout). Columns become flex so CSS `order`
   moves cards without moving their markup; anything that isn't a slot keeps
   its place at the end. A slot whose card drew nothing takes no space. */
.dash-main { display: flex; flex-direction: column; min-width: 0; }
.dash-main > :not(.dash-slot), .dash-aside > :not(.dash-slot) { order: 999; }
.dash-slot:not(:has(*)) { display: none; }
.dash-customize__group { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.dash-customize__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.dash-customize__item { display: flex; align-items: center; gap: 4px; padding: 6px 8px 6px 12px; background: var(--color-surface-secondary); border: 1px solid var(--color-border-light); border-radius: var(--radius-md, 10px); }
.dash-customize__label { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; font-size: 14px; color: var(--color-text); cursor: pointer; }

/* Celebrations (_birthdays): a calendar chip with a two-digit day in tabular
   figures, the person's face, and what the day is. Today is lifted; days
   already gone this month step back. */
.dash-celebrate { display: flex; flex-direction: column; gap: 18px; }
.dash-celebrate__group { display: flex; flex-direction: column; gap: 4px; }
.dash-celebrate__group .dash-start__eyebrow { margin-bottom: 6px; }
.dash-celebrate__row {
    display: flex; align-items: center; gap: 12px;
    margin: 0 -10px; padding: 8px 10px; border-radius: 10px;
    text-decoration: none; color: inherit;
    transition: background 0.14s ease;
}
.dash-celebrate__row:hover { background: var(--color-surface-hover); color: inherit; }
.dash-celebrate__chip {
    display: flex; flex-direction: column; align-items: center; flex-shrink: 0;
    width: 40px; overflow: hidden;
    border: 1px solid var(--color-border-light); border-radius: 9px; background: var(--color-surface);
}
.dash-celebrate__month { width: 100%; padding: 2px 0 1px; text-align: center; font-size: 9px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-primary); background: var(--color-primary-bg); }
.dash-celebrate__day { padding: 2px 0 3px; font-family: var(--font-display); font-size: 15px; font-weight: 600; line-height: 1.2; color: var(--color-text); font-variant-numeric: tabular-nums; }
.dash-celebrate__face { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.dash-celebrate__text { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.dash-celebrate__name { font-size: 14px; font-weight: 600; color: var(--color-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-celebrate__what { font-size: 12px; color: var(--color-text-secondary); }
.dash-celebrate__when { font-size: 12px; color: var(--color-text-secondary); white-space: nowrap; font-variant-numeric: tabular-nums; }
.dash-celebrate__badge { padding: 2px 8px; border-radius: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; color: #fff; background: linear-gradient(135deg, #1264FF 0%, #6d3cf5 100%); white-space: nowrap; }
.dash-celebrate__row--today { background: var(--color-primary-bg); }
.dash-celebrate__row--today .dash-celebrate__chip { border-color: var(--color-primary); }
.dash-celebrate__row--today .dash-celebrate__month { color: #fff; background: var(--color-primary); }
.dash-celebrate__row--past { opacity: 0.55; }
.dash-celebrate__row--past:hover { opacity: 1; }

/* Pro — a tool included in Pro and above, marked on a plan without it
   (event sidebar, buttons, upgrade pages). */
.pro-badge { display: inline-block; margin-left: auto; flex-shrink: 0; padding: 1px 6px; border-radius: 5px;
    font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; line-height: 1.5;
    color: var(--color-primary, #1264ff);
    background: color-mix(in srgb, var(--color-primary, #1264ff) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-primary, #1264ff) 28%, transparent); }
