/* ─────────────────────────────────────────────────────────
   Trophyst — self-hosted typefaces
   Plus Jakarta Sans (display) + Inter (UI). Both OFL 1.1.
   Self-hosted so customer deployments need no outbound
   internet and there is no flash of fallback text.
   ───────────────────────────────────────────────────────── */
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 500 800;
    font-display: swap;
    src: url('fonts/jakarta-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 500 800;
    font-display: swap;
    src: url('fonts/jakarta-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/inter-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/inter-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ─────────────────────────────────────────────────────────
   Light theme — "paper"
   A warm off-white canvas rather than the cold blue-grey
   every other B2B dashboard uses. This single choice is
   what makes Trophyst read as Trophyst at a glance.
   ───────────────────────────────────────────────────────── */
:root {
    /* ── Typefaces ── */
    --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-display: 'Plus Jakarta Sans', 'Inter', -apple-system, 'Segoe UI', sans-serif;

    /* ── Surfaces ──
       Cards are a warm off-white rather than pure white. Pure #fff against the
       paper canvas separated them far more strongly than the dark theme does,
       which made every card read as a hard cut-out; this keeps them clearly
       lifted off the page but part of the same material. */
    --bg-body: #faf7f2;
    --bg-white: #fdfbf7;
    --bg-card: #fdfbf7;
    --bg-card-hover: #f6f1ea;
    --bg-sidebar: #faf7f2;      /* blends into the canvas */
    --bg-elevated: #fdfbf7;     /* modals, popovers, raised cards */
    --bg-subtle: #f3ece3;       /* subtle fills, tab badges, dividers bg */

    /* ── Text ── */
    --text-primary: #2b2521;
    --text-secondary: #6c6259;
    --text-muted: #9a9088;
    --text-strong: #17130f;     /* headlines, big numbers / KPI values */
    --text-on-accent: #ffffff;

    /* ── Accent ── */
    --accent: #e8681f;
    --accent-hover: #cf5610;
    --accent-light: rgba(232, 104, 31, 0.10);

    /* ── Borders ── */
    --border-color: #e9e1d6;
    --border-subtle: #f2ebe1;

    /* ── Status (warmed slightly so they sit on paper, not on blue-grey) ── */
    --success: #2e9e5b;
    --warning: #e0930f;
    --danger: #dc4c3e;
    --info: #2f7fd1;

    /* Text-weight status colours, used for tinted pills and inline status text.
       Darker than the fills above because they sit on a pale tint. */
    --status-success: #1f7c44;
    --status-warning: #a86c07;
    --status-danger: #bf3729;
    --status-info: #2264ab;
    --status-neutral: #6c6259;

    /* ── Gradient pairs (KPI / metric cards) ── */
    --grad-accent: linear-gradient(135deg, #e67e22, #d35400);
    --grad-success: linear-gradient(135deg, #27ae60, #1e8449);
    --grad-info: linear-gradient(135deg, #3498db, #2980b9);
    --grad-secondary: linear-gradient(135deg, #6c757d, #5a6268);
    --grad-blue: linear-gradient(135deg, #3a7bd5, #2b5ea7);
    --grad-teal: linear-gradient(135deg, #1abc9c, #148f77);
    --grad-purple: linear-gradient(135deg, #f0a35c, #d35400);

    /* ── Radius (generous, matching the reference design) ── */
    --border-radius: 14px;
    --border-radius-sm: 9px;

    /* ── Shadows — barely there; hairline borders do the separating ── */
    --shadow-sm: 0 1px 2px rgba(40, 28, 16, 0.04);
    --shadow-md: 0 6px 20px rgba(40, 28, 16, 0.07);

    /* ── Density scale ── */
    --font-size-base: 14px;
    --line-height-base: 1.45;
    --space-card: 0.85rem;      /* default card body padding */
    --space-card-sm: 0.6rem;
    --scrollbar-thumb: #d8cec1;
    --table-stripe: rgba(90, 60, 25, 0.022);
    --nav-hover-bg: rgba(90, 60, 25, 0.05);

    /* Calendar quarter tints (Q1 yellow, Q2 green, Q3 blue, Q4 purple) */
    --cal-q1-bg: #fff5eb; --cal-q1-fg: #7a3e0c;
    --cal-q2-bg: #ecf6f1; --cal-q2-fg: #1d6a3f;
    --cal-q3-bg: #eef2f9; --cal-q3-fg: #2a4a7f;
    --cal-q4-bg: #f6efff; --cal-q4-fg: #5e3a8f;

    /* Column bands for grouped tables — the calendar's quarter tints, with two
       more in the same key so a six-measure table has one each. A band colours
       its group heading, its column headings and the cells under them alike, so
       a wide table reads as blocks rather than a wall of numbers. */
    --band-1-fg: var(--cal-q1-fg);
    --band-2-fg: var(--cal-q2-fg);
    --band-3-fg: var(--cal-q3-fg);
    --band-4-fg: var(--cal-q4-fg);
    --band-5-fg: #8f3054;
    --band-6-fg: #1f6570;

    /* Mixed from each band's own ink rather than picked separately: the calendar's
       block tints wash out at table density, and a stronger tint of the same hue
       keeps the two screens recognisably the same family. */
    --band-1-bg: color-mix(in srgb, var(--band-1-fg) 11%, var(--bg-card));
    --band-2-bg: color-mix(in srgb, var(--band-2-fg) 11%, var(--bg-card));
    --band-3-bg: color-mix(in srgb, var(--band-3-fg) 11%, var(--bg-card));
    --band-4-bg: color-mix(in srgb, var(--band-4-fg) 11%, var(--bg-card));
    --band-5-bg: color-mix(in srgb, var(--band-5-fg) 11%, var(--bg-card));
    --band-6-bg: color-mix(in srgb, var(--band-6-fg) 11%, var(--bg-card));
}

/* ── Dark theme — "ember": a warm dark, not the usual blue-black ── */
[data-theme="dark"] {
    /* Surfaces */
    --bg-body: #14110d;
    --bg-white: #1d1915;
    --bg-card: #1d1915;
    --bg-card-hover: #272019;
    --bg-sidebar: #14110d;      /* same as the body, as in light — the arc divides */
    --bg-elevated: #272019;
    --bg-subtle: #272019;

    /* Text */
    --text-primary: #e8e0d5;
    --text-secondary: #a89c8d;
    --text-muted: #7d7365;
    --text-strong: #f7f2ea;
    --text-on-accent: #ffffff;

    /* Accent (brighter so it pops on dark) */
    --accent: #f5843c;
    --accent-hover: #e8681f;
    --accent-light: rgba(245, 132, 60, 0.16);

    /* Borders */
    --border-color: #362e24;
    --border-subtle: #272019;

    /* Shadows — deeper on dark */
    --shadow-sm: 0 1px 3px rgba(0,0,0,0.4);
    --shadow-md: 0 6px 18px rgba(0,0,0,0.5);

    /* Status text colours lift on dark so tinted pills stay readable */
    --status-success: #63d394;
    --status-warning: #e8b45c;
    --status-danger: #f08579;
    --status-info: #7db4ec;
    --status-neutral: #a89c8d;

    /* Misc */
    --scrollbar-thumb: #453a2d;
    --table-stripe: transparent;
    --nav-hover-bg: rgba(255, 240, 220, 0.06);

    /* Warm-dark "brothers" of the quarter tints for dark mode */
    --cal-q1-bg: #33291a; --cal-q1-fg: #e8b878;
    --cal-q2-bg: #1b3328; --cal-q2-fg: #74c99e;
    --cal-q3-bg: #1c2940; --cal-q3-fg: #93b6e8;
    --cal-q4-bg: #2a2142; --cal-q4-fg: #c2a4ea;

    --band-1-fg: var(--cal-q1-fg);
    --band-2-fg: var(--cal-q2-fg);
    --band-3-fg: var(--cal-q3-fg);
    --band-4-fg: var(--cal-q4-fg);
    --band-5-fg: #e79fb8;
    --band-6-fg: #7cc7c8;

    /* Dark needs a touch more of the ink to read at all against the card. */
    --band-1-bg: color-mix(in srgb, var(--band-1-fg) 15%, var(--bg-card));
    --band-2-bg: color-mix(in srgb, var(--band-2-fg) 15%, var(--bg-card));
    --band-3-bg: color-mix(in srgb, var(--band-3-fg) 15%, var(--bg-card));
    --band-4-bg: color-mix(in srgb, var(--band-4-fg) 15%, var(--bg-card));
    --band-5-bg: color-mix(in srgb, var(--band-5-fg) 15%, var(--bg-card));
    --band-6-bg: color-mix(in srgb, var(--band-6-fg) 15%, var(--bg-card));
    color-scheme: dark;
}

html {
    font-size: var(--font-size-base);
}

html, body {
    font-family: var(--font-ui);
    background-color: var(--bg-body);
    color: var(--text-primary);
    line-height: var(--line-height-base);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: 'cv05' 1, 'ss03' 1;  /* single-storey l, rounded quotes */
}

/* Tabular figures everywhere numbers are compared down a column */
.table td, .table th,
.stat-ribbon-value, .kpi-value, .hd-kpi-count, .hd-summary-num, .hd-pipeline-count {
    font-variant-numeric: tabular-nums;
}

/* Links */
a, .btn-link {
    color: var(--accent);
}

a:hover, .btn-link:hover {
    color: var(--accent-hover);
}

/* Buttons - rounded and modern */
.btn {
    border-radius: var(--border-radius-sm);
    font-weight: 500;
    transition: all 0.2s ease;
    --bs-btn-padding-y: 0.4rem;
    --bs-btn-padding-x: 0.85rem;
    --bs-btn-font-size: 0.9rem;
}

.btn-sm {
    --bs-btn-padding-y: 0.25rem;
    --bs-btn-padding-x: 0.6rem;
    --bs-btn-font-size: 0.8rem;
}

.btn-primary {
    color: #fff !important;
    background-color: var(--accent) !important;
    border-color: var(--accent) !important;
}

.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
    background-color: var(--accent-hover) !important;
    border-color: var(--accent-hover) !important;
    color: #fff !important;
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn-primary:disabled, .btn-primary.disabled {
    background-color: var(--accent) !important;
    border-color: var(--accent) !important;
    opacity: 0.65;
}

.btn-outline-primary {
    color: var(--accent) !important;
    border-color: var(--accent) !important;
    background-color: transparent !important;
}

.btn-outline-primary:hover, .btn-outline-primary:focus, .btn-outline-primary:active {
    background-color: var(--accent) !important;
    border-color: var(--accent) !important;
    color: #fff !important;
}

.btn-secondary {
    background-color: #6c757d !important;
    border-color: #6c757d !important;
    color: #fff !important;
}

.btn-secondary:hover, .btn-secondary:focus, .btn-secondary:active {
    background-color: #5a6268 !important;
    border-color: #5a6268 !important;
    color: #fff !important;
}

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

.btn-outline-secondary:hover, .btn-outline-secondary:focus, .btn-outline-secondary:active {
    background-color: var(--bg-card-hover) !important;
    border-color: var(--border-color) !important;
    color: var(--text-primary) !important;
}

.btn-success {
    background-color: var(--success) !important;
    border-color: var(--success) !important;
    color: #fff !important;
}

.btn-success:hover, .btn-success:focus, .btn-success:active {
    background-color: #219a52 !important;
    border-color: #219a52 !important;
    color: #fff !important;
}

.btn-outline-success {
    color: var(--success) !important;
    border-color: var(--success) !important;
    background-color: transparent !important;
}

.btn-outline-success:hover, .btn-outline-success:focus, .btn-outline-success:active {
    background-color: var(--success) !important;
    border-color: var(--success) !important;
    color: #fff !important;
}

.btn-warning {
    background-color: var(--warning) !important;
    border-color: var(--warning) !important;
    color: #fff !important;
}

.btn-warning:hover, .btn-warning:focus, .btn-warning:active {
    background-color: #d68910 !important;
    border-color: #d68910 !important;
    color: #fff !important;
}

.btn-danger {
    background-color: var(--danger) !important;
    border-color: var(--danger) !important;
    color: #fff !important;
}

.btn-danger:hover, .btn-danger:focus, .btn-danger:active {
    background-color: #c0392b !important;
    border-color: #c0392b !important;
    color: #fff !important;
}

.btn-outline-danger {
    color: var(--danger) !important;
    border-color: var(--danger) !important;
    background-color: transparent !important;
}

.btn-outline-danger:hover, .btn-outline-danger:focus, .btn-outline-danger:active {
    background-color: var(--danger) !important;
    border-color: var(--danger) !important;
    color: #fff !important;
}

.btn-dark {
    background-color: #343a40 !important;
    border-color: #343a40 !important;
    color: #fff !important;
}

.btn-dark:hover, .btn-dark:focus, .btn-dark:active {
    background-color: #23272b !important;
    border-color: #23272b !important;
    color: #fff !important;
}

/* Focus states */
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 3px var(--accent-light);
}

.content {
    padding-top: 1.1rem;
}

/* Headings carry the display face — this is where the personality lives.
   Tight tracking + a near-black warm ink is what separates an editorial
   look from a generic dashboard. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--font-display);
    color: var(--text-strong);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.021em;
}

h1, .h1 { font-size: 1.9rem; letter-spacing: -0.028em; }
h2, .h2 { font-size: 1.45rem; letter-spacing: -0.024em; }
h3, .h3 { font-size: 1.2rem; }
h4, .h4 { font-size: 1.05rem; }
h5, .h5 { font-size: 0.95rem; letter-spacing: -0.014em; }
h6, .h6 { font-size: 0.85rem; letter-spacing: -0.01em; }

h1:focus {
    outline: none;
}

/* Form controls - rounded */
.form-control, .form-select {
    background-color: var(--bg-white);
    border-color: var(--border-color);
    color: var(--text-primary);
    border-radius: var(--border-radius-sm);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    font-size: 0.9rem;
    padding: 0.4rem 0.7rem;
}

.form-control-sm, .form-select-sm {
    font-size: 0.8rem;
    padding: 0.25rem 0.55rem;
}

/* Bootstrap draws a select's arrow as a background image and reserves room for
   it with padding-right. The padding shorthand above overwrites that, so the
   text of any select wide enough to reach the arrow runs underneath it. Put the
   room back rather than dropping the shorthand, which would lose the theme's
   vertical rhythm. */
.form-select {
    padding-right: 2.1rem;
}

.form-select-sm {
    padding-right: 1.85rem;
}

/* Native file picker button ("Choose Files") — Bootstrap renders it on a light bg */
.form-control::file-selector-button {
    background-color: var(--bg-card-hover);
    color: var(--text-primary);
    border-color: var(--border-color);
}

.form-control:hover:not(:disabled)::file-selector-button {
    background-color: var(--bg-subtle);
    color: var(--text-primary);
}

.form-control:focus, .form-select:focus {
    background-color: var(--bg-white);
    border-color: var(--accent);
    color: var(--text-primary);
    box-shadow: 0 0 0 3px var(--accent-light);
}

.form-control::placeholder {
    color: var(--text-muted);
}

/* Disabled / readonly inputs — Bootstrap defaults to a light grey that stays light in dark mode */
.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
    background-color: var(--bg-subtle);
    color: var(--text-muted);
    border-color: var(--border-color);
}

.form-label {
    color: var(--text-secondary);
    font-weight: 500;
    font-size: 0.875rem;
}

.form-check-input {
    background-color: var(--bg-white);
    border-color: var(--border-color);
    border-radius: 4px;
}

.form-check-input:checked {
    background-color: var(--accent);
    border-color: var(--accent);
}

.form-check-label {
    color: var(--text-primary);
}

/* Cards - rounded with shadow */
.card {
    --bs-card-spacer-y: var(--space-card);
    --bs-card-spacer-x: var(--space-card);
    --bs-card-cap-padding-y: var(--space-card-sm);
    --bs-card-cap-padding-x: var(--space-card);
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-sm);
    color: var(--text-primary);
}

/* Panel headers sit on the card itself, divided by a hairline rather than a
   grey band — fewer boxes-inside-boxes, which is what made the old UI heavy. */
.card-header {
    background-color: transparent;
    border-bottom: 1px solid var(--border-subtle);
    border-radius: var(--border-radius) var(--border-radius) 0 0;
    color: var(--text-strong);
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.014em;
}

.card-footer {
    background-color: transparent;
    border-top: 1px solid var(--border-subtle);
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

/* Tables - modern styling */
.table {
    color: var(--text-primary);
    --bs-table-bg: transparent;
    --bs-table-color: var(--text-primary);
    --bs-table-striped-color: var(--text-primary);
    --bs-table-striped-bg: var(--table-stripe);
    --bs-table-hover-color: var(--text-primary);
    --bs-table-hover-bg: var(--bg-card-hover);
    --bs-table-border-color: var(--border-color);
    /* Bootstrap 5.2 hardcodes .table border-color:#dee2e6 (near-white) and cells inherit it for
       their bottom border — override it so row separators are the theme's thin grey, not white. */
    border-color: var(--border-color);
}

.table {
    --bs-table-cell-padding-y: 0.45rem;
    --bs-table-cell-padding-x: 0.6rem;
    font-size: 0.875rem;
}

.table td, .table th {
    color: var(--text-primary);
    vertical-align: middle;
}

.nav-tabs {
    --bs-nav-tabs-border-color: var(--border-color);
    --bs-nav-tabs-link-hover-border-color: var(--border-subtle) var(--border-subtle) var(--border-color);
    --bs-nav-tabs-link-active-color: var(--accent);
    --bs-nav-tabs-link-active-bg: var(--bg-card);
    --bs-nav-tabs-link-active-border-color: var(--border-color) var(--border-color) var(--bg-card);
}
.nav-tabs .nav-link {
    color: var(--text-secondary);
}
.nav-tabs .nav-link:hover {
    color: var(--accent);
}
.nav-tabs .nav-link.active {
    color: var(--accent);
    background-color: var(--bg-card);
    border-color: var(--border-color) var(--border-color) var(--bg-card);
}

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

.table > thead th {
    color: var(--text-secondary);
    font-weight: 600;
    text-transform: uppercase;
    font-size: 0.75rem;
    letter-spacing: 0.5px;
}

/* Striping is handled by Bootstrap's native --bs-table-striped-bg (set on .table
   above) so contextual row variants like .table-success keep their tint. */

/* Compact tables — tighter padding, smaller text */
.table-sm th {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-weight: 600;
    color: #6c757d;
    white-space: nowrap;
}

.table-sm td {
    font-size: 0.85rem;
}

/* Accordion — make theme-aware (Bootstrap hardcodes a light bg/border) */
.accordion {
    --bs-accordion-bg: var(--bg-card);
    --bs-accordion-color: var(--text-primary);
    --bs-accordion-border-color: var(--border-color);
    --bs-accordion-btn-color: var(--text-primary);
    --bs-accordion-btn-bg: var(--bg-card);
    --bs-accordion-active-bg: var(--bg-card-hover);
    --bs-accordion-active-color: var(--accent);
    --bs-accordion-btn-focus-border-color: var(--accent);
    --bs-accordion-btn-focus-box-shadow: 0 0 0 3px var(--accent-light);
}

/* Bootstrap 5.2 hardcodes accordion colours (#fff / #212529 / #e7f1ff) instead of using the
   --bs-accordion-* vars above, so override the actual properties for the theme. */
.accordion-item {
    background-color: var(--bg-card);
    border-color: var(--border-color);
    color: var(--text-primary);
}
.accordion-button {
    background-color: var(--bg-card);
    color: var(--text-primary);
}
.accordion-button:not(.collapsed) {
    background-color: var(--bg-card-hover);
    color: var(--accent);
    box-shadow: inset 0 -1px 0 var(--border-color);
}
.accordion-body {
    color: var(--text-primary);
}

[data-theme="dark"] .accordion-button::after {
    filter: invert(1) grayscale(100%) brightness(1.6);
}

/* Light table header/rows — make theme-aware (Bootstrap hardcodes a light grey) */
.table-light,
.table-light > th,
.table-light > td,
.table > :not(caption) > .table-light > * {
    --bs-table-bg: var(--bg-card-hover);
    --bs-table-color: var(--text-secondary);
    --bs-table-border-color: var(--border-color);
    background-color: var(--bg-card-hover);
    color: var(--text-secondary);
}

/* Contextual row tints — drive the Bootstrap cell var so text stays readable, and
   darken the tint in dark mode (light cell text needs a deeper background) */
.table-success { --bs-table-bg: rgba(39, 174, 96, 0.10); --bs-table-color: var(--text-primary); }
.table-warning { --bs-table-bg: rgba(243, 156, 18, 0.10); --bs-table-color: var(--text-primary); }
.table-danger  { --bs-table-bg: rgba(231, 76, 60, 0.10); --bs-table-color: var(--text-primary); }

[data-theme="dark"] .table-success { --bs-table-bg: rgba(39, 174, 96, 0.22); }
[data-theme="dark"] .table-warning { --bs-table-bg: rgba(243, 156, 18, 0.22); }
[data-theme="dark"] .table-danger  { --bs-table-bg: rgba(231, 76, 60, 0.28); }

/* List groups */
.list-group-item {
    background-color: var(--bg-card);
    border-color: var(--border-color);
    color: var(--text-primary);
}

.list-group-item-action:hover, .list-group-item-action:focus {
    background-color: var(--bg-card-hover);
    color: var(--text-primary);
}

.list-group-item.active {
    background-color: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

/* ── Badges — tinted pills, not solid blocks ──
   Solid saturated badges are the single loudest thing in a data table.
   Tinting them keeps status legible while letting the data lead, and it
   is what the reference design does. Colour is driven by --badge-tint so
   each status is one line, and dark mode lifts the tints for contrast. */
.badge {
    --badge-tint: var(--status-neutral);
    border-radius: 999px;
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: 0.72rem;
    letter-spacing: 0.015em;
    padding: 0.34em 0.72em;
    background-color: color-mix(in srgb, var(--badge-tint) 13%, var(--bg-card)) !important;
    color: var(--badge-tint) !important;
    border: 1px solid color-mix(in srgb, var(--badge-tint) 26%, transparent);
}

.badge.bg-primary { --badge-tint: var(--accent); }
.badge.bg-secondary { --badge-tint: var(--status-neutral); }
.badge.bg-success { --badge-tint: var(--status-success); }
.badge.bg-warning { --badge-tint: var(--status-warning); }
.badge.bg-danger { --badge-tint: var(--status-danger); }
.badge.bg-info { --badge-tint: var(--status-info); }
.badge.bg-dark { --badge-tint: var(--text-strong); }

/* Some callers pair a badge with .text-dark / .text-white for the old solid
   look; the tint already guarantees contrast, so keep the tinted colour. */
.badge.text-dark, .badge.text-white, .badge.text-light {
    color: var(--badge-tint) !important;
}

/* Alerts - rounded */
.alert {
    border-radius: var(--border-radius-sm);
    border-width: 0;
    border-left-width: 4px;
}

.alert-info {
    background-color: rgba(52, 152, 219, 0.1);
    border-color: var(--info);
    color: #2980b9;
}

.alert-success {
    background-color: rgba(39, 174, 96, 0.1);
    border-color: var(--success);
    color: #1e8449;
}

.alert-danger {
    background-color: rgba(231, 76, 60, 0.1);
    border-color: var(--danger);
    color: #c0392b;
}

.alert-warning {
    background-color: rgba(243, 156, 18, 0.1);
    border-color: var(--warning);
    color: #b7950b;
}

/* Modals - rounded */
.modal-content {
    background-color: var(--bg-card);
    border: none;
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-md);
    color: var(--text-primary);
}

.modal-header {
    border-bottom: 1px solid var(--border-color);
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

.modal-footer {
    border-top: 1px solid var(--border-color);
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

/* Input groups */
.input-group-text {
    background-color: var(--bg-card-hover);
    border-color: var(--border-color);
    color: var(--text-secondary);
    border-radius: var(--border-radius-sm);
}

/* Text utilities */
.text-muted {
    color: var(--text-muted) !important;
}

.text-primary {
    color: var(--accent) !important;
}

/* Validation */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--success);
}

.invalid {
    outline: 1px solid var(--danger);
}

.validation-message {
    color: var(--danger);
}

/* Error boundary */
.blazor-error-boundary {
    background: linear-gradient(135deg, var(--danger), #c0392b);
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
    border-radius: var(--border-radius-sm);
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

.darker-border-checkbox.form-check-input {
    border-color: var(--border-color);
}

/* Dashboard cards */
.card.text-bg-primary {
    background: linear-gradient(135deg, var(--accent), var(--accent-hover)) !important;
    border: none;
}

.card.text-bg-success {
    background: linear-gradient(135deg, var(--success), #1e8449) !important;
    border: none;
}

.card.text-bg-info {
    background: linear-gradient(135deg, var(--info), #2980b9) !important;
    border: none;
}

.card.text-bg-secondary {
    background: linear-gradient(135deg, #6c757d, #5a6268) !important;
    border: none;
}

/* Scrollbar styling */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--bg-body);
}

::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--accent);
}

/* Page title. The old orange underline bar is gone deliberately — the
   display face and weight do that job now, and the bar read as dated. */
h1 {
    color: var(--text-strong);
    border-bottom: none;
    padding-bottom: 0;
    margin-bottom: 0.9rem;
}

/* Subtitle under a page title */
.lead {
    color: var(--text-secondary);
    font-size: 0.95rem;
    font-weight: 400;
}

/* Main content top row — sits on the page canvas, undivided */
main > .top-row {
    background-color: transparent !important;
    border-bottom: none !important;
}

main > .top-row a {
    color: var(--text-secondary) !important;
}

main > .top-row a:hover {
    color: var(--accent) !important;
}

/* Pagination - rounded with orange theme */
.pagination {
    --bs-pagination-bg: var(--bg-white);
    --bs-pagination-border-color: var(--border-color);
    --bs-pagination-color: var(--text-primary);
    --bs-pagination-hover-bg: var(--accent);
    --bs-pagination-hover-border-color: var(--accent);
    --bs-pagination-hover-color: #fff;
    --bs-pagination-focus-box-shadow: 0 0 0 3px var(--accent-light);
    --bs-pagination-active-bg: var(--accent);
    --bs-pagination-active-border-color: var(--accent);
    --bs-pagination-active-color: #fff;
    --bs-pagination-disabled-bg: var(--bg-body);
    --bs-pagination-disabled-border-color: var(--border-color);
    --bs-pagination-disabled-color: var(--text-muted);
}

.page-link {
    border-radius: var(--border-radius-sm);
    margin: 0 2px;
    color: var(--text-primary);
    background-color: var(--bg-white);
    border-color: var(--border-color);
}

.page-link:hover, .page-link:focus {
    color: #fff;
    background-color: var(--accent);
    border-color: var(--accent);
}

.page-item.active .page-link {
    color: #fff;
    background-color: var(--accent);
    border-color: var(--accent);
}

.page-item.disabled .page-link {
    color: var(--text-muted);
    background-color: var(--bg-body);
    border-color: var(--border-color);
}

.page-item:first-child .page-link,
.page-item:last-child .page-link {
    border-radius: var(--border-radius-sm);
}

/* Nav divider for light theme */
.nav-divider {
    border-color: var(--border-color) !important;
    opacity: 1;
}

/* ── Theme toggle button ── */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: 50%;
    background: var(--bg-card);
    color: var(--text-secondary);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.theme-toggle:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.theme-toggle svg {
    width: 17px;
    height: 17px;
}

/* Variant for placement on a colored navbar (white icon/border) */
.theme-toggle.on-accent {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.4);
    color: #fff;
}

.theme-toggle.on-accent:hover {
    background: rgba(255, 255, 255, 0.22);
    border-color: #fff;
    color: #fff;
}

/* Show moon in light mode (click → dark), sun in dark mode (click → light) */
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: inline; }
[data-theme="dark"] .theme-toggle .icon-sun { display: inline; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* Menu-position toggle: each icon previews the layout you would switch to.
   Hidden on narrow viewports, where the top menu falls back to the sidebar
   anyway and the control would be a no-op. */
.nav-layout-toggle .icon-nav-vertical { display: none; }
.nav-layout-toggle .icon-nav-horizontal { display: inline; }
[data-nav="horizontal"] .nav-layout-toggle .icon-nav-vertical { display: inline; }
[data-nav="horizontal"] .nav-layout-toggle .icon-nav-horizontal { display: none; }

@media (max-width: 991.98px) {
    .nav-layout-toggle { display: none !important; }
}

/* Set for a moment while the menu changes position: the request to collapse an
   open group round-trips through Blazor, and without this the panel would be
   briefly visible re-laid-out in the layout being switched to. */
[data-nav-switching] .nav-submenu {
    display: none !important;
}

/* ───────────────────────────────────────────────
   Dark-theme component fixes
   (global components only; per-page scoped CSS is
   handled in the page-by-page cleanup phase)
   ─────────────────────────────────────────────── */

/* Supplier portal layout hardcodes a light body gradient — flatten it on dark */
[data-theme="dark"] body {
    background: var(--bg-body) !important;
}

/* Alert text needs lifting for contrast on dark surfaces */
[data-theme="dark"] .alert-info { color: #6cb6e8; }
[data-theme="dark"] .alert-success { color: #5fd99a; }
[data-theme="dark"] .alert-danger { color: #f08a7f; }
[data-theme="dark"] .alert-warning { color: #f0c060; }

/* Modal close button ('X') is a dark SVG — invert it on dark */
[data-theme="dark"] .btn-close {
    filter: invert(1) grayscale(100%) brightness(1.6);
}

/* Bootstrap text-bg-* helpers default to opaque white/light bg */
[data-theme="dark"] .bg-light {
    background-color: var(--bg-subtle) !important;
    color: var(--text-primary) !important;
}

[data-theme="dark"] .bg-white {
    background-color: var(--bg-card) !important;
}

/* Subtle borders that used Bootstrap defaults */
[data-theme="dark"] .border,
[data-theme="dark"] .border-top,
[data-theme="dark"] .border-bottom,
[data-theme="dark"] .border-start,
[data-theme="dark"] .border-end {
    border-color: var(--border-color) !important;
}

/* ═══════════════════════════════════════════════════════════
   Signature components
   Reusable pieces from the reference design. These are what
   make a Trophyst page recognisable rather than generic; use
   them on new pages instead of rolling one-off card markup.
   ═══════════════════════════════════════════════════════════ */

/* ── Stat ribbon ──────────────────────────────────────────
   One wide card of headline numbers split by hairline rules,
   instead of a row of separate boxes. Reads as a single
   instrument panel and survives any number of stats.

   <div class="stat-ribbon">
     <div class="stat-ribbon-item">
       <span class="stat-ribbon-icon">…svg…</span>
       <span class="stat-ribbon-value">28</span>
       <span class="stat-ribbon-label">Products</span>
     </div>
     …
   </div>
   ───────────────────────────────────────────────────────── */
.stat-ribbon {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.stat-ribbon-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: 1 1 0;
    min-width: 160px;
    padding: 1rem 1.15rem;
    border-left: 1px solid var(--border-subtle);
    text-decoration: none;
    color: inherit;
}

.stat-ribbon-item:first-child { border-left: 0; }

a.stat-ribbon-item:hover { background: var(--bg-card-hover); }

.stat-ribbon-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    color: var(--text-secondary);
}

.stat-ribbon-icon svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.stat-ribbon-text { min-width: 0; }

.stat-ribbon-value {
    display: block;
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.028em;
    color: var(--text-strong);
    font-variant-numeric: tabular-nums;
}

.stat-ribbon-label {
    display: block;
    margin-top: 2px;
    font-size: 0.76rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Accent a single figure in the ribbon */
.stat-ribbon-item.is-accent .stat-ribbon-value,
.stat-ribbon-item.is-accent .stat-ribbon-icon { color: var(--accent); }

@media (max-width: 900px) {
    .stat-ribbon-item {
        flex-basis: 50%;
        border-top: 1px solid var(--border-subtle);
    }
    .stat-ribbon-item:nth-child(-n+2) { border-top: 0; }
    .stat-ribbon-item:nth-child(odd) { border-left: 0; }
}

/* ── Arrow link ───────────────────────────────────────────
   The accent is used as *text* here rather than as another
   filled button. <a class="link-arrow">View all campaigns</a>
   ───────────────────────────────────────────────────────── */
.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    white-space: nowrap;
}

.link-arrow::after {
    content: '→';
    transition: transform 0.18s ease;
}

.link-arrow:hover {
    color: var(--accent-hover);
    text-decoration: none;
}

.link-arrow:hover::after { transform: translateX(3px); }

/* ── Section heading ──────────────────────────────────────
   Title on the left, arrow link on the right. Replaces the
   "card-header grey band" pattern for full-width sections.
   ───────────────────────────────────────────────────────── */
.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.85rem;
}

.section-head-title {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.022em;
    color: var(--text-strong);
    margin: 0;
}

.section-head-caption {
    font-size: 0.82rem;
    color: var(--text-secondary);
    margin: 2px 0 0;
}

/* ── Eyebrow ──────────────────────────────────────────────
   Small uppercase label above a heading or beside a metric. */
.eyebrow {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}

/* ── Paper wash ───────────────────────────────────────────
   The faint warm bloom behind the top-left of a hero area.
   Purely decorative; sits under content and ignores clicks. */
.paper-wash {
    position: relative;
}

.paper-wash::before {
    content: '';
    position: absolute;
    top: -140px;
    left: -180px;
    width: 620px;
    height: 620px;
    border-radius: 50%;
    background: radial-gradient(circle,
        color-mix(in srgb, var(--accent) 13%, transparent) 0%,
        transparent 68%);
    pointer-events: none;
    z-index: 0;
}

.paper-wash > * { position: relative; z-index: 1; }

/* ── Assignment workspace ─────────────────────────────────
   One assignment, laid out the same way whoever is reading it: a header
   carrying the campaign's artwork, a strip of the dates everyone plans
   around, tabs over the work, and the conversation beside it rather than
   behind a tab — you refer to it while doing everything else.

   Shared by the retailer's /assignments/{id} and the Agency Portal's own
   page, so the two applications feel like one product. */
.asgn-hero {
    position: relative;
    border-radius: var(--border-radius);
    overflow: hidden;
    margin-bottom: 1rem;
    min-height: 96px;
    display: flex;
    align-items: center;
}

.asgn-hero.has-art { min-height: 180px; }

/* Masked rather than overlaid with a colour, so it dissolves into whatever
   canvas the theme is using — light or dark — without knowing which. */
.asgn-hero-art {
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: min(44%, 470px);
    background-size: cover;
    background-position: center;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.5) 38%, #000 72%);
    mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.5) 38%, #000 72%);
}

.asgn-hero-copy {
    position: relative;
    z-index: 2;
    padding: 1rem 1.1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    width: 100%;
}

.asgn-hero-main { flex: 1 1 auto; min-width: 0; }

.asgn-hero-eyebrow {
    display: block;
    font-size: .78rem;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-bottom: .15rem;
}

.asgn-hero-eyebrow a { color: inherit; text-decoration: none; }
.asgn-hero-eyebrow a:hover { text-decoration: underline; }

.asgn-hero-title {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    font-weight: 800;
    letter-spacing: -.03em;
    margin: 0 0 .4rem;
}

.asgn-hero-badges { display: flex; flex-wrap: wrap; gap: .35rem; }

/* The buttons that move an assignment on. Kept in the header where the
   status they change is, and held clear of the artwork: buttons over a
   photograph are buttons nobody can read. A narrow window gives up the
   picture rather than the buttons. */
.asgn-hero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
}

.asgn-hero.has-art .asgn-hero-copy { padding-right: min(46%, 490px); }

@media (max-width: 991.98px) {
    .asgn-hero.has-art .asgn-hero-copy { padding-right: 1.1rem; }
}

/* ── Campaign facts ── */
.asgn-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 1.6rem;
    padding: .7rem 1.1rem;
    margin-bottom: 1rem;
    background: var(--bg-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--border-radius);
}

.asgn-fact { display: flex; flex-direction: column; }

.asgn-fact-label {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-muted);
}

.asgn-fact-value { font-weight: 700; }

/* ── Two columns: work, and the conversation beside it ── */
.asgn-columns { display: flex; gap: 1rem; align-items: flex-start; }
.asgn-work { flex: 1; min-width: 0; }

.asgn-thread { width: 340px; flex-shrink: 0; position: sticky; top: 1rem; }
.asgn-thread .card-body { max-height: 70vh; overflow: auto; }

@media (max-width: 1200px) {
    .asgn-columns { flex-direction: column; }
    .asgn-thread { width: 100%; position: static; }
}

/* ── Tabs ── */
.assignment-tabs .nav-link {
    border: none;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--text-secondary);
    font-weight: 600;
    padding: .5rem .9rem;
}

.assignment-tabs .nav-link:hover { color: var(--text-strong); }

.assignment-tabs .nav-link.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
    background: none;
}

/* ── Insight 360 ROI ranking, dark theme ──
   The scoped stylesheet owns these classes; only the shades that depend on the
   theme attribute on the root element live here, where a selector can reach it. */
[data-theme="dark"] .roi-pill-good { color: #5fd99a; }
[data-theme="dark"] .roi-pill-weak { color: #f0c060; }
[data-theme="dark"] .roi-pill-bad  { color: #f08a7f; }
[data-theme="dark"] .cbar-fill-pos { background: #34c07a; }
