/* ─── Font Faces ─────────────────────────────────────────────────────────── */

@font-face {
    font-family: 'Inter';
    src: url("../fonts/Inter-Regular-1yuqbHl.woff2") format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Inter';
    src: url("../fonts/Inter-Medium-jTHbkkM.woff2") format('woff2');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Inter';
    src: url("../fonts/Inter-SemiBold-MMOJDHD.woff2") format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Inter';
    src: url("../fonts/Inter-Bold-xj8qcQQ.woff2") format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url("../fonts/JetBrainsMono-Regular-am2WezT.woff2") format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* ─── Typography ─────────────────────────────────────────────────────────── */

:root {
    --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace;
    /* Override Bootstrap's font-family variables so all components pick up Inter */
    --bs-font-sans-serif: var(--font-sans);
    --bs-body-font-family: var(--font-sans);
    --bs-font-monospace: var(--font-mono);
}

body {
    font-family: var(--font-sans);
    font-feature-settings: 'cv11', 'ss01', 'ss03';
}

/* JetBrains Mono with tabular numerics for data values */
.font-mono,
code, kbd, samp, pre,
input.time-input,
#totalTime,
.stat-number {
    font-family: var(--font-mono);
    font-feature-settings: 'tnum';
}

/* ─── Stat Cards ─────────────────────────────────────────────────────────── */

.stat-card {
    border: 1px solid #e0e0e0;
    box-shadow: none !important;
}

.stat-card .card-body {
    padding: 1.25rem 1.5rem;
}

.stat-label {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #888;
    margin-bottom: 0.35rem;
}

.stat-number {
    font-size: 2.5rem;
    font-weight: 700;
    line-height: 1.1;
    color: #1a1a1a;
}

.stat-unit {
    font-size: 1.25rem;
    font-weight: 600;
    color: #1a1a1a;
    vertical-align: baseline;
    margin-left: 0.1em;
}

/* Four stat cards across instead of three — trim the padding and let the number
   shrink so a seven-figure amount still fits on one line. */
.stat-row-4 .stat-card .card-body {
    padding: 1rem 1.15rem;
}

.stat-row-4 .stat-number {
    font-size: clamp(1.5rem, 2.6vw, 2.5rem);
}

.stat-row-4 .stat-unit {
    font-size: clamp(0.9rem, 1.3vw, 1.25rem);
}

/* Qualifies a headline number whose label alone is ambiguous. */
.stat-sublabel {
    font-size: 0.7rem;
    color: #888;
    margin-top: 0.2rem;
}

/* ─── Financial Summary (job income pipeline) ────────────────────────────── */

.fin-summary dt {
    font-weight: 400;
    color: #666;
    padding-top: 0.2rem;
    padding-bottom: 0.2rem;
}

.fin-summary dd {
    margin-bottom: 0;
    padding-top: 0.2rem;
    padding-bottom: 0.2rem;
    font-family: var(--font-mono);
    font-feature-settings: 'tnum';
}

/* The two figures people are actually reading off this card. */
.fin-summary .fin-summary-key {
    font-weight: 700;
    color: #1a1a1a;
    border-top: 1px solid #e5e5e5;
    margin-top: 0.2rem;
    padding-top: 0.4rem;
}

/* ─── Data Tables ────────────────────────────────────────────────────────── */

/* Card wrapper: swap Bootstrap shadow for a clean hairline border */
.card:has(.table-data) {
    border: 1px solid #e5e5e5 !important;
    box-shadow: none !important;
}

/* Header: all-caps, spaced, muted — no background fill */
.table-data thead th {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #8a8a8a;
    background: transparent !important;
    border-bottom: 1px solid #e0e0e0 !important;
    padding-top: 0.625rem;
    padding-bottom: 0.625rem;
    vertical-align: middle;
    white-space: nowrap;
}

/* Body cells */
.table-data tbody td {
    vertical-align: middle;
    border-color: #f0f0f0;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

/* Hover: a pale cool tint, so it can't be mistaken for the warm-grey
   subtotal / group-header rows. Light enough that muted text still clears AA. */
.table-data tbody tr:hover > td {
    background-color: oklch(0.955 0.025 240);
}

/* Action buttons inside table cells — borderless, compact */
.table-data td .btn[class*="btn-outline"] {
    border: none;
    background-color: transparent;
    padding: 0.1rem 0.4rem;
    box-shadow: none;
}
.table-data td .btn[class*="btn-outline"]:hover {
    background-color: rgba(0, 0, 0, 0.05);
    text-decoration: none;
}

/* Group header rows (client/resource sections in reports) */
.table-data .row-group-header > td {
    background-color: #f5f5f3 !important;
    color: #666;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    border-top: 1px solid #e5e5e5 !important;
}

/* Sub-total rows (per-group totals) */
.table-data .row-subtotal > td {
    background-color: #f7f7f5 !important;
    font-weight: 600;
    border-top: 1px solid #e0e0e0 !important;
}

/* Footer totals row */
.table-data tfoot.table-totals td {
    background-color: #f0f0ee !important;
    color: #1a1a1a;
    font-weight: 600;
    border-top: 2px solid #d0d0d0 !important;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

/* Sticky header — keeps column headings visible while scrolling a long report.
   Bootstrap's .table-responsive sets overflow-x:auto, which makes the wrapper a
   scroll container and stops the header anchoring to the page; drop it so the
   header sticks to the viewport instead. */
.table-responsive.sticky-head {
    overflow: visible;
}
.table-responsive.sticky-head thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: #fff !important; /* opaque: table rows must not show through */
}
@media (max-width: 767.98px) {
    .table-responsive.sticky-head {
        overflow-x: auto; /* restore horizontal scroll on narrow screens */
    }
}

/* ─── Inline Edit Cells ──────────────────────────────────────────────────── */

.inline-edit-cell {
    position: relative;
}

.inline-edit-display {
    display: inline-block;
    min-width: 60px;
    padding: 2px 6px;
    border-radius: 4px;
    transition: background-color 0.15s ease;
}

.inline-edit-display:hover {
    background-color: rgba(13, 110, 253, 0.08);
}

.inline-edit-input {
    width: 110px;
    text-align: right;
}

@keyframes inline-edit-flash {
    0%   { background-color: rgba(25, 135, 84, 0.25); }
    100% { background-color: transparent; }
}

.inline-edit-saved {
    animation: inline-edit-flash 0.8s ease forwards;
}

/* ─── Page-header toolbar ────────────────────────────────────────────────── */
/*
 * Apply to the header row at the top of list/report pages
 * so title + search + buttons stack instead of overflowing on narrow screens.
 */
.page-header-toolbar {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
}

/* ─── Mobile tweaks (< 768px) ────────────────────────────────────────────── */
@media (max-width: 767.98px) {
    /* Tighter container padding on small screens — reclaim ~16px each side */
    .container {
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }

    /* Large page titles chew up space; scale them down on mobile */
    h1 {
        font-size: 1.5rem;
    }

    /* Make sure the header toolbar wraps cleanly and Create-New buttons
       drop under the search field instead of being pushed off-screen. */
    .page-header-toolbar > * {
        flex-wrap: wrap;
    }
    .page-header-toolbar form.d-flex,
    .page-header-toolbar .d-flex {
        flex-wrap: wrap;
    }

    /* btn-group-sm action columns get cramped side-by-side on phones;
       let them wrap rather than overflow. */
    .table .btn-group-sm,
    .table .btn-group {
        flex-wrap: wrap;
        gap: 2px;
    }
    .table .btn-group-sm > .btn,
    .table .btn-group > .btn {
        border-radius: 0.25rem !important;
        border-left-width: 1px !important;
    }

    /* Inline edit input is a bit too wide on mobile */
    .inline-edit-input {
        width: 88px;
    }

    /* Time tracking: fatter touch targets for +/- 15 min buttons */
    .time-increment-btn,
    .time-decrement-btn {
        padding-top: 0.25rem !important;
        padding-bottom: 0.25rem !important;
        padding-left: 0.5rem !important;
        padding-right: 0.5rem !important;
        line-height: 1.2 !important;
        min-width: 32px;
    }

    /* Time tracking: let the entries table use all the width and drop
       the fixed Notes column width so it doesn't squash the time input. */
    #timeEntriesList .time-input {
        min-width: 70px;
    }
    #timeEntriesList .notes-input {
        min-width: 120px;
    }

    /* Dashboard weekly grid: narrow min-width so we don't force
       gigantic horizontal scroll on a phone. */
    .dashboard-week-table th,
    .dashboard-week-table td {
        min-width: 120px !important;
    }
    .dashboard-week-table .badge {
        font-size: 0.72rem;
    }

    /* Report filter selects have hardcoded widths — override on mobile */
    .form-select[style*="width: 130px"],
    .form-select[style*="width: 90px"] {
        width: auto !important;
        min-width: 90px;
    }

    /* Avatar dropdown: hide the username to save space; keep the avatar */
    .navbar .nav-item.dropdown .dropdown-toggle > span {
        display: none;
    }
}

/* ─── Link consistency ───────────────────────────────────────────────────── */

/* All non-button links inside table cells: enforce blue, underline on hover.
 * !important needed to override Bootstrap's text-reset (color: inherit !important)
 * and text-decoration-none (text-decoration: none !important) utilities. */
.table td a:not([class*="btn"]),
.table th a:not([class*="btn"]) {
    color: #0d6efd !important;
    text-decoration: none;
}
.table td a:not([class*="btn"]):hover,
.table th a:not([class*="btn"]):hover {
    text-decoration: underline !important;
}

/* Non-button text links that suppress decoration: underline on hover.
 * Excludes stat-card wrappers (handled separately below). */
a.text-decoration-none:not([class*="btn"]):not(:has(.stat-card)):hover,
a.text-reset:not([class*="btn"]):hover {
    text-decoration: underline !important;
}

/* Stat card link wrapper: underline only the big number on hover, not the label */
a:has(.stat-card):hover .stat-number {
    text-decoration: underline;
}

/* The stat card acting as the active filter. Needs its own rule because
   .stat-card sets the border shorthand and would beat Bootstrap's
   .border-primary; the variable keeps it right in both themes. */
.stat-card.stat-card-active {
    border-color: var(--bs-primary);
}

/* ─── Tom Select ─────────────────────────────────────────────────────────── */

/* Bootstrap's form theme copies form-select onto the ts-wrapper, which gives it
   a background-image chevron that duplicates Tom Select's own caret. Strip it. */
.ts-wrapper.form-select {
    background-image: none;
    padding: 0;
    border: none;
}

/* ─── Buttons ────────────────────────────────────────────────────────────── */

/* All non-link buttons: remove Bootstrap's bold weight, shadow, and pill radius */
.btn:not(.btn-link) {
    font-weight: 400;
    border-radius: 6px;
    box-shadow: none !important;
}

/* btn-primary → neutral outlined (replaces Bootstrap's blue fill) */
.btn-primary {
    --bs-btn-bg: #fff;
    --bs-btn-border-color: #d0d0d0;
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-bg: #f5f5f5;
    --bs-btn-hover-border-color: #b8b8b8;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-bg: #ebebeb;
    --bs-btn-active-border-color: #b0b0b0;
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-disabled-bg: #f5f5f5;
    --bs-btn-disabled-border-color: #e0e0e0;
    --bs-btn-disabled-color: #aaa;
}

/* btn-outline-secondary → same neutral style */
.btn-outline-secondary {
    --bs-btn-bg: #fff;
    --bs-btn-border-color: #d0d0d0;
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-bg: #f5f5f5;
    --bs-btn-hover-border-color: #b8b8b8;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-bg: #ebebeb;
    --bs-btn-active-border-color: #b0b0b0;
    --bs-btn-active-color: #1a1a1a;
}

/* btn-outline-primary → same neutral style */
.btn-outline-primary {
    --bs-btn-bg: #fff;
    --bs-btn-border-color: #d0d0d0;
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-bg: #f5f5f5;
    --bs-btn-hover-border-color: #b8b8b8;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-bg: #ebebeb;
    --bs-btn-active-border-color: #b0b0b0;
    --bs-btn-active-color: #1a1a1a;
}

/* btn-success → same neutral style */
.btn-success {
    --bs-btn-bg: #fff;
    --bs-btn-border-color: #d0d0d0;
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-bg: #f5f5f5;
    --bs-btn-hover-border-color: #b8b8b8;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-bg: #ebebeb;
    --bs-btn-active-border-color: #b0b0b0;
    --bs-btn-active-color: #1a1a1a;
}

/* btn-outline-danger → keep red semantic hint, same clean base */
.btn-outline-danger {
    --bs-btn-bg: #fff;
    --bs-btn-border-color: #e8c5c5;
    --bs-btn-color: #b91c1c;
    --bs-btn-hover-bg: #fef2f2;
    --bs-btn-hover-border-color: #d08080;
    --bs-btn-hover-color: #991b1b;
    --bs-btn-active-bg: #fee2e2;
    --bs-btn-active-border-color: #c06060;
    --bs-btn-active-color: #991b1b;
}

/* ─── Dark mode overrides ────────────────────────────────────────────────── */

[data-bs-theme="dark"] .stat-card {
    border-color: var(--bs-border-color);
}
[data-bs-theme="dark"] .stat-label {
    color: var(--bs-secondary-color);
}
[data-bs-theme="dark"] .stat-number,
[data-bs-theme="dark"] .stat-unit {
    color: var(--bs-body-color);
}

[data-bs-theme="dark"] .stat-sublabel {
    color: var(--bs-secondary-color);
}

[data-bs-theme="dark"] .fin-summary dt {
    color: var(--bs-secondary-color);
}
[data-bs-theme="dark"] .fin-summary .fin-summary-key {
    color: var(--bs-body-color);
    border-top-color: var(--bs-border-color);
}

[data-bs-theme="dark"] .card:has(.table-data) {
    border-color: var(--bs-border-color) !important;
}
[data-bs-theme="dark"] .table-data thead th {
    color: var(--bs-secondary-color);
    border-bottom-color: var(--bs-border-color) !important;
}
[data-bs-theme="dark"] .table-responsive.sticky-head thead th {
    background: var(--bs-body-bg) !important;
}
[data-bs-theme="dark"] .table-data tbody td {
    border-color: var(--bs-border-subtle);
}
[data-bs-theme="dark"] .table-data tbody tr:hover > td {
    background-color: oklch(0.27 0.03 240);
}
[data-bs-theme="dark"] .table-data .row-group-header > td {
    background-color: var(--bs-secondary-bg) !important;
    color: var(--bs-secondary-color);
    border-top-color: var(--bs-border-color) !important;
}
[data-bs-theme="dark"] .table-data .row-subtotal > td {
    background-color: var(--bs-tertiary-bg) !important;
    border-top-color: var(--bs-border-color) !important;
}
[data-bs-theme="dark"] .table-data tfoot.table-totals td {
    background-color: var(--bs-secondary-bg) !important;
    color: var(--bs-body-color);
    border-top-color: var(--bs-border-color) !important;
}
[data-bs-theme="dark"] .table-data td .btn[class*="btn-outline"]:hover {
    background-color: rgba(255, 255, 255, 0.08);
}

[data-bs-theme="dark"] .btn-primary,
[data-bs-theme="dark"] .btn-outline-secondary,
[data-bs-theme="dark"] .btn-outline-primary,
[data-bs-theme="dark"] .btn-success {
    --bs-btn-bg: var(--bs-tertiary-bg);
    --bs-btn-border-color: var(--bs-border-color);
    --bs-btn-color: var(--bs-body-color);
    --bs-btn-hover-bg: var(--bs-secondary-bg);
    --bs-btn-hover-border-color: var(--bs-border-color);
    --bs-btn-hover-color: var(--bs-body-color);
    --bs-btn-active-bg: var(--bs-secondary-bg);
    --bs-btn-active-border-color: var(--bs-border-color);
    --bs-btn-active-color: var(--bs-body-color);
    --bs-btn-disabled-bg: var(--bs-tertiary-bg);
    --bs-btn-disabled-border-color: var(--bs-border-subtle);
    --bs-btn-disabled-color: var(--bs-secondary-color);
}

/* btn-dark is the primary action button. Bootstrap's fill (#212529) is identical
   to the dark theme's --bs-body-bg, so it vanishes — invert it to a light fill so
   it stays the highest-contrast button on the page, as it is in light mode. */
[data-bs-theme="dark"] .btn-dark {
    --bs-btn-bg: #e9ecef;
    --bs-btn-border-color: #e9ecef;
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-bg: #f8f9fa;
    --bs-btn-hover-border-color: #f8f9fa;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-bg: #ffffff;
    --bs-btn-active-border-color: #ffffff;
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-disabled-bg: var(--bs-tertiary-bg);
    --bs-btn-disabled-border-color: var(--bs-border-subtle);
    --bs-btn-disabled-color: var(--bs-secondary-color);
}

[data-bs-theme="dark"] .btn-outline-danger {
    --bs-btn-bg: transparent;
    --bs-btn-border-color: rgba(239, 68, 68, 0.35);
    --bs-btn-color: #fca5a5;
    --bs-btn-hover-bg: rgba(239, 68, 68, 0.12);
    --bs-btn-hover-border-color: rgba(239, 68, 68, 0.55);
    --bs-btn-hover-color: #fca5a5;
    --bs-btn-active-bg: rgba(239, 68, 68, 0.20);
    --bs-btn-active-border-color: rgba(239, 68, 68, 0.55);
    --bs-btn-active-color: #fca5a5;
}

[data-bs-theme="dark"] .table td a:not([class*="btn"]),
[data-bs-theme="dark"] .table th a:not([class*="btn"]) {
    color: #6ea8fe !important;
}

/* Dashboard weekly bar chart */
.dashboard-bar-track {
    background: #ebebeb;
}
.dashboard-bar-fill {
    background: #666;
}
.dashboard-bar-fill.today {
    background: #111;
}
[data-bs-theme="dark"] .dashboard-bar-track {
    background: var(--bs-secondary-bg);
}
[data-bs-theme="dark"] .dashboard-bar-fill {
    background: var(--bs-secondary-color);
}
[data-bs-theme="dark"] .dashboard-bar-fill.today {
    background: var(--bs-body-color);
}

/* Dashboard: the day's location under each bar. The chips reuse the grid's
   .sc-day-status look; the toggle is a button, so it needs the button chrome
   taken off and something that says it can be clicked. */
.dashboard-day-location .sc-day-status {
    align-self: auto;
    max-width: 100%;
    white-space: nowrap;
}
.sc-day-status-toggle {
    border: 1px dashed transparent;
    cursor: pointer;
    font: inherit;
    font-size: 11px;
    padding: 2px 6px;
    font-weight: 500;
}
.sc-day-status-toggle:not(.wfh):not(.offsite) {
    background: var(--sc-bg-sunken);
}
.sc-day-status-toggle:hover,
.sc-day-status-toggle:focus-visible {
    border-color: currentColor;
}
.sc-day-status-toggle:disabled {
    cursor: progress;
    opacity: 0.6;
}
.sc-day-status-toggle.is-error {
    border-color: var(--sc-danger);
    border-style: solid;
}
/* The dashboard chip is two lines — where, then the hours — stacked so the
   day column keeps its width. */
.dashboard-day-location .sc-day-status-toggle {
    flex-direction: column;
    gap: 0;
    line-height: 1.25;
    padding: 3px 7px;
}
.sc-day-hours {
    font-size: 10px;
    font-weight: 400;
    color: var(--sc-fg-subtle);
    font-variant-numeric: tabular-nums;
}
.sc-day-status-toggle.wfh .sc-day-hours,
.sc-day-status-toggle.offsite .sc-day-hours {
    color: inherit;
    opacity: 0.8;
}
/* On the grid the same button keeps the cell chip's size, with the hours
   beside the location (an asterisk marks a day with its own hours). */
.sc-grid-cell .sc-day-status-toggle {
    font-size: 10.5px;
    padding: 1px 4px;
}
.sc-grid-cell .sc-day-status-toggle .sc-day-hours {
    font-size: 10px;
    margin-left: 2px;
}
.sc-grid-cell .sc-day-status-toggle:not(.wfh):not(.offsite) {
    background: transparent;
}

/* ─── Work-day modal ─────────────────────────────────────────────────────── */
.sc-work-day-dialog { max-width: 440px; }
.sc-work-day-locations { display: flex; gap: 6px; flex-wrap: wrap; }
.sc-work-day-locations .sc-btn { flex: 1 1 0; justify-content: center; }
.sc-work-day-time { width: 9.5em; font-variant-numeric: tabular-nums; }

/* ─── Global header search ───────────────────────────────────────────────── */
/* Sits at the right-hand end of the nav links, just before the utility icons.
   Everything here builds on the sc-* tokens; the panel, rows and headings are
   the existing .sc-ctx-menu family, so only layout and the search-specific bits
   live here. */

.sc-global-search {
    position: relative;
    /* Shrinks before the nav links do when the bar gets tight, rather than
       growing to claim space the links need — but not below a width you can
       actually read a job name in. Past that the navbar wraps instead. */
    flex: 0 1 260px;
    min-width: 150px;
    margin-right: 10px;
}

.sc-global-search-input {
    width: 100%;
    padding-right: 42px; /* room for the ⌘K hint */
}

.sc-global-search-hint {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    pointer-events: none;
    opacity: 0.7;
}

/* Hide the hint once the field is in use — it would otherwise sit on top of the
   text. :placeholder-shown covers the case where text is left in an unfocused
   box, which :focus alone would miss. */
.sc-global-search-input:focus ~ .sc-global-search-hint,
.sc-global-search-input:not(:placeholder-shown) ~ .sc-global-search-hint {
    display: none;
}

.sc-global-search-panel {
    position: absolute;
    top: calc(100% + 4px);
    /* Anchored right and grown leftward: the panel is wider than the input, and
       at the right-hand end of the bar anchoring left would push it off-screen. */
    right: 0;
    left: auto;
    min-width: 340px;
    max-height: 70vh;
    overflow-y: auto;
}

/* .sc-ctx-item is a single-line flex row; search results are two lines. */
.sc-global-search-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    text-decoration: none;
}

.sc-global-search-row:hover,
.sc-global-search-row.is-active {
    background: var(--sc-surface-hover);
    text-decoration: none;
}

/* Keyboard focus must be as obvious as hover, or arrowing through the list
   looks like nothing is happening. */
.sc-global-search-row.is-active {
    box-shadow: inset 2px 0 0 var(--sc-accent-line);
}

.sc-global-search-main {
    display: flex;
    align-items: baseline;
    gap: 6px;
    width: 100%;
}

.sc-global-search-prefix {
    color: var(--sc-fg-subtle);
    font-size: 12px;
    flex: none;
}

.sc-global-search-title {
    color: var(--sc-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sc-global-search-subtitle {
    color: var(--sc-fg-muted);
    font-size: 11.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.sc-global-search-badge {
    flex: none;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sc-fg-subtle);
    border: 1px solid var(--sc-border-strong);
    border-radius: var(--sc-radius-sm);
    padding: 0 4px;
}

.sc-global-search-empty,
.sc-global-search-seeall {
    color: var(--sc-fg-muted);
    font-size: 12px;
    text-decoration: none;
}

.sc-global-search-seeall:hover,
.sc-global-search-seeall.is-active {
    background: var(--sc-surface-hover);
    color: var(--sc-fg);
    text-decoration: none;
}

/* Below the navbar-expand-lg breakpoint the search is a full-width row inside
   the collapsed panel, so it stops competing for horizontal space entirely. */
@media (max-width: 991.98px) {
    .sc-global-search {
        flex: 1 1 auto;
        width: 100%;
        margin: 4px 0 8px;
    }

    /* No physical keyboard to press it with. */
    .sc-global-search-hint {
        display: none;
    }

    /* Full-width parent, so span it rather than growing leftward. */
    .sc-global-search-panel {
        left: 0;
        min-width: 0;
    }
}

/* ─── Tiny phones (< 400px) ──────────────────────────────────────────────── */
@media (max-width: 399.98px) {
    h1 { font-size: 1.3rem; }

    /* Stack search input-group vertically on very narrow screens */
    .page-header-toolbar .input-group {
        width: 100%;
    }

    /* Hide the heavy "Create New …" button label on very narrow screens
       — users can still reach creation from the detail pages. */
}

/* ─── Job resource allocations (/job/{id}/allocation) ─────────────────────── */

/* The rest of the team, listed under the allocations with their fields already
   in place. Same idea as the team roster: the person is the unit of the page,
   so allocating someone is one button rather than a dropdown first. */
.table-data .sc-alloc__heading > td {
    background: var(--sc-bg-alt);
    border-top: 1px solid var(--sc-divider);
    color: var(--sc-fg-muted);
    letter-spacing: .04em;
}

/* Muted until there is something in it — these rows are an offer, not a record,
   and must not read as allocations that happen to be blank. */
.table-data .sc-alloc__offer > td {
    background: var(--sc-surface);
}

.table-data .sc-alloc__offer:hover > td {
    background: var(--sc-surface-hover);
}

.sc-alloc__offer .fw-medium {
    color: var(--sc-fg-muted);
}

.sc-alloc__offer:focus-within .fw-medium {
    color: var(--sc-fg);
}

/* ─── Job team roster (/manage/job/{id}/team) ────────────────────────────── */

/* Sticky department headings, so you always know whose list you are in while
   scrolling 30-odd staff. */
.sc-team__group {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--sc-bg-alt);
    border-bottom: 1px solid var(--sc-divider);
    color: var(--sc-fg-muted);
    letter-spacing: .04em;
}

.sc-team__row {
    min-height: 48px;
    padding-top: .35rem;
    padding-bottom: .35rem;
    transition: background-color .12s;
}

.sc-team__row:hover {
    background: var(--sc-surface-hover);
}

/* Anyone on the job. This is set only after the server confirms the change —
   never optimistically — so the tint always reflects stored state. */
.sc-team__row--on {
    background: var(--sc-accent-soft);
    box-shadow: inset 3px 0 0 var(--sc-accent-line);
}

.sc-team__row--busy {
    opacity: .6;
}

.sc-team__avatar {
    width: 28px;
    height: 28px;
    font-size: 12px;
}

/* Reserve the status column so a "Saved" tick appearing cannot shove the role
   dropdown sideways mid-interaction. */
.sc-team__status {
    flex: 0 0 auto;
    min-width: 5.5rem;
    text-align: right;
    color: var(--sc-fg-muted);
}

.sc-team__role {
    flex: 0 0 auto;
    width: 11rem;
}

.sc-team__quick {
    flex: 0 0 auto;
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    /* Wrap onto two lines rather than crushing the role select. */
    .sc-team__row {
        flex-wrap: wrap;
    }

    .sc-team__status {
        min-width: 0;
        order: 3;
    }

    .sc-team__quick,
    .sc-team__role {
        order: 4;
    }

    .sc-team__role {
        width: auto;
        flex: 1 1 8rem;
    }
}

/* ─── Staff leave calendar (/report/staff-leave) ──────────────────────────── */

/*
   Per-type colours. Mixed into the surface rather than used at full strength:
   the calendar is mostly bars, and a page of saturated fills is unreadable in
   dark mode. Because the mix is against --sc-surface, one set of hues covers
   both themes — the tint follows the background instead of being restated.
*/
.sc-leave-cal,
.sc-filter-row {
    --sc-leave-annual: oklch(0.60 0.13 240);
    --sc-leave-sick: oklch(0.58 0.17 25);
    --sc-leave-remote-working: oklch(0.60 0.12 165);
    --sc-leave-bereavement: oklch(0.55 0.13 300);
    --sc-leave-other: oklch(0.58 0.02 90);
}

/* No `overflow: hidden` here: it would make the weekday header's `position:
   sticky` stick to a container that never scrolls, i.e. not at all. */
.sc-leave-cal {
    --sc-leave-lane-h: 22px;
}

/* Weekday header. Sticky so the columns stay named on a six-week month. */
.sc-leave-dow {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--sc-bg-alt);
    border-bottom: 1px solid var(--sc-border-strong);
}

.sc-leave-dow-cell {
    padding: 6px 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sc-fg-muted);
    text-align: center;
}

.sc-leave-dow-cell.is-weekend { color: var(--sc-fg-faint); }

/*
   One grid per week. Day backgrounds span every row (grid-row: 1 / -1) so a bar
   can run across them uninterrupted — which is the whole point of the layout,
   and is why the row template is written out inline per week rather than left
   to auto-flow.
*/
.sc-leave-week {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    row-gap: 2px;
    min-height: 96px;
    position: relative;
}

.sc-leave-week + .sc-leave-week { border-top: 1px solid var(--sc-border); }

.sc-leave-daybg {
    border-left: 1px solid var(--sc-divider);
    background: var(--sc-surface);
}

.sc-leave-daybg:first-child { border-left: 0; }
.sc-leave-daybg.is-weekend { background: var(--sc-bg-sunken); }
.sc-leave-daybg.is-outside { background: var(--sc-bg-alt); }
.sc-leave-daybg.is-holiday { background: color-mix(in oklab, var(--sc-warn) 10%, var(--sc-surface)); }
.sc-leave-daybg.is-today {
    background: color-mix(in oklab, var(--sc-warn) 14%, var(--sc-surface));
    box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--sc-warn) 55%, transparent);
}

.sc-leave-daynum {
    z-index: 1;
    padding: 4px 6px 2px;
    text-align: right;
    line-height: 1.2;
    pointer-events: none;
}

.sc-leave-daynum-n {
    font-size: 12px;
    font-weight: 600;
    color: var(--sc-fg-muted);
    font-feature-settings: 'tnum';
}

.sc-leave-daynum.is-outside .sc-leave-daynum-n { color: var(--sc-fg-faint); font-weight: 400; }

/* Public holiday name under the date. Clipped rather than wrapped: it must not
   change the header row's height, or the week rows stop lining up. */
.sc-leave-holiday {
    display: block;
    font-size: 10px;
    line-height: 1.3;
    color: var(--sc-warn);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── The bars ── */

.sc-leave-bar {
    --bar: var(--sc-leave-other);
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    margin: 0 3px;
    padding: 0 6px;
    height: calc(var(--sc-leave-lane-h) - 2px);
    border-radius: var(--sc-radius-sm);
    background: color-mix(in oklab, var(--bar) 20%, var(--sc-surface));
    border: 1px solid color-mix(in oklab, var(--bar) 45%, var(--sc-surface));
    border-left: 3px solid var(--bar);
    color: var(--sc-fg);
    font-size: 11.5px;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    cursor: default;
}

.sc-leave-bar[data-type="annual"] { --bar: var(--sc-leave-annual); }
.sc-leave-bar[data-type="sick"] { --bar: var(--sc-leave-sick); }
.sc-leave-bar[data-type="remote-working"] { --bar: var(--sc-leave-remote-working); }
.sc-leave-bar[data-type="bereavement"] { --bar: var(--sc-leave-bereavement); }
.sc-leave-bar[data-type="other"] { --bar: var(--sc-leave-other); }

.sc-leave-bar-icon { font-size: 10px; color: var(--bar); flex: none; }

/* On a one-day bar there is room for about one of these, so the type gives way
   first: "Angela Collins (Ann…)" is more use than "Angela Colli… (Annual)". */
.sc-leave-bar-name { flex: 0 1 auto; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
/* Zero flex-basis: the type claims only the space the name has not used, so a
   one-day bar clips "(Annual)" rather than the person's surname. */
.sc-leave-bar-type { flex: 1 1 0; min-width: 0; color: var(--sc-fg-muted); overflow: hidden; text-overflow: ellipsis; }

/* A run that carries on into the next week loses its cap on that side, so the
   two halves read as one absence rather than two bookings. */
.sc-leave-bar.continues-left {
    margin-left: 0;
    border-left-width: 0;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    padding-left: 8px;
}

.sc-leave-bar.continues-right {
    margin-right: 0;
    border-right-width: 0;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

/* Pending leave is booked but not yet agreed — drawn hollow and dashed so it
   never reads as settled, but still drawn, because it is what a resourcing
   decision needs to know about. */
.sc-leave-bar.is-pending {
    background: repeating-linear-gradient(
        135deg,
        color-mix(in oklab, var(--bar) 12%, var(--sc-surface)) 0 6px,
        var(--sc-surface) 6px 12px
    );
    border-style: dashed;
    border-left-style: solid;
}

/* Half a day: the fill covers the half that is actually gone. */
.sc-leave-bar.is-half-am { background-image: linear-gradient(to right, color-mix(in oklab, var(--bar) 26%, var(--sc-surface)) 50%, transparent 50%); }
.sc-leave-bar.is-half-pm { background-image: linear-gradient(to right, transparent 50%, color-mix(in oklab, var(--bar) 26%, var(--sc-surface)) 50%); }
.sc-leave-bar.is-half { background-color: var(--sc-surface); }

/* ── Legend chips (they are also the type filter) ── */

/* `.sc-filter-row` is a single row everywhere else in the app; this one carries
   two chip groups, so it is allowed to wrap rather than clip the last type. */
.sc-leave-filter-row { flex-wrap: wrap; row-gap: 8px; }

.sc-leave-chip { display: inline-flex; align-items: center; gap: 6px; }

.sc-leave-swatch {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    flex: none;
    background: var(--swatch, var(--sc-leave-other));
}

.sc-leave-chip[data-type="annual"] { --swatch: var(--sc-leave-annual); }
.sc-leave-chip[data-type="sick"] { --swatch: var(--sc-leave-sick); }
.sc-leave-chip[data-type="remote-working"] { --swatch: var(--sc-leave-remote-working); }
.sc-leave-chip[data-type="bereavement"] { --swatch: var(--sc-leave-bereavement); }
.sc-leave-chip[data-type="other"] { --swatch: var(--sc-leave-other); }

.sc-leave-chip-count {
    font-feature-settings: 'tnum';
    color: var(--sc-fg-subtle);
    font-size: 11px;
}

.sc-chip.active .sc-leave-chip-count { color: inherit; opacity: 0.75; }

/* Below tablet the seven columns can't hold a name, so the calendar scrolls
   sideways rather than crushing every bar to an ellipsis. */
@media (max-width: 767.98px) {
    .sc-leave-cal { overflow-x: auto; }
    .sc-leave-dow,
    .sc-leave-week { min-width: 760px; }
}

/* ── The header row of a record's page ──────────────────────────────────── */
/*
 * Every page about one job (`job/_page_title.html.twig`) and the client page
 * open the same way: the heading block on the left, that page's actions on the
 * right. A class rather than the utility classes it replaces, because the rules
 * below only make sense together — and because names run long here ("Fonterra
 * Research and Development Centre: Interactive Innovation Timeline" and
 * "Ministry of Business, Innovation & Employment (MBIE)" are both real) and a
 * long one broke every page of both families the same way.
 */
.sc-record-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

/* The heading is always the first child, and takes what is left over.
   `min-width: 0` is the part that lets it be narrower than the name — without
   it a flex item will not shrink below its content, so the name pushes the
   actions along instead of wrapping. */
.sc-record-header > :first-child {
  flex: 1 1 18rem;
  min-width: 0;
}

/* Actions keep their natural width, always. As ordinary flex items they shrink
   like anything else, and a long name squeezed them until their own labels
   wrapped — "Add Workstream" over two lines, a button twice the height of its
   neighbour. A button is as wide as its label or it is broken; below ~18rem of
   heading the row wraps and they drop to a line of their own instead. */
.sc-record-header > :not(:first-child) {
  flex: 0 0 auto;
}

.sc-record-header .btn {
  white-space: nowrap;
}

/* Bootstrap's 2.5rem is tuned for a page title of two or three words, which a
   job or client name is not. This scales with the viewport and tops out lower,
   so a long name wraps to two lines rather than three and leaves room beside
   it. The floor is under the mobile `h1` rules this out-specifies, so it stays
   in step with them. `min-width` + `overflow-wrap` are for the job someone
   names after a URL. */
.sc-record-header h1 {
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 2rem);
  line-height: 1.2;
  min-width: 0;
  overflow-wrap: break-word;
}

/* The favourite star (and anything else that belongs to the title rather than
   to the page) trails the last word, inside the h1. As a flex sibling of the
   h1 it sat at the right-hand edge of the heading instead, which for a name
   long enough to wrap put it hard against the page's buttons, where it read as
   one of them. Empty on most pages, and an empty inline-flex box occupies
   nothing, so the margin is conditional and nothing else needs to know. */
.sc-heading-extra {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  vertical-align: middle;
}

.sc-heading-extra:not(:empty) {
  margin-left: 0.4rem;
}

/* ── Job number under a job page's heading ──────────────────────────────── */

/* Rendered by `templates/job/_page_title.html.twig` on every job-scoped page.
   Red and monospaced because the number is what people search a screenful of
   text for; the "Job" label is muted and in the body face so the eye lands on
   the digits rather than reading the pair as one string. */
.sc-job-heading {
  min-width: 0;
}

/* ─── Click to copy ─────────────────────────────────────────────────────── */
/*
 * One click on a job number copies it (`copy_to_clipboard_controller`), on the
 * job list, both month reports and every job-scoped page. The control is a real
 * <button> so it is reachable by keyboard and announces itself, stripped back
 * to nothing so the number it wraps goes on looking exactly as it did.
 */
.sc-copy {
  position: relative;
  /* Padding gives the hover tint room to breathe. It is static, so the number
     does not move when the pointer arrives; the negative margin keeps the
     column aligned with the cells that have no button in them. */
  padding: 0 3px;
  margin: 0 -3px;
  border: 0;
  border-radius: 4px;
  background: none;
  color: inherit;
  font: inherit;
  line-height: inherit;
  vertical-align: baseline;
  cursor: pointer;
}

.sc-copy:hover {
  background: var(--sc-surface-hover);
}

.sc-copy:focus-visible {
  outline: 2px solid var(--sc-accent);
  outline-offset: 1px;
}

/* The affordance is a tint and a dotted underline — deliberately nothing that
   occupies space. These sit in a column of numbers, and a copy icon appearing
   on hover would shove every row's number sideways as the pointer ran down it. */
.sc-copy:hover code,
.sc-copy:hover .sc-job-number-value,
.sc-copy:focus-visible code,
.sc-copy:focus-visible .sc-job-number-value {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

/*
 * The "Copied" badge. It sits to the *right* of the number rather than above
 * it: `.table-responsive` is an `overflow-x: auto` scroll container, which
 * clips on both axes, so a badge above the first row (or below the last) would
 * be cut off by the very wrapper that makes these tables scroll. To the right
 * it stays inside the table's vertical bounds, and the Job ID column is the
 * leftmost one, so it has a whole neighbouring column to hang over for the
 * second and a bit that it is up.
 */
.sc-copy.is-copied::after,
.sc-copy.is-copy-failed::after {
  content: attr(data-copy-message);
  position: absolute;
  left: calc(100% + 6px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--sc-success);
  color: #fff;
  font-family: var(--sc-font-sans);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0;
  white-space: nowrap;
  text-transform: none;
  pointer-events: none;
}

.sc-copy.is-copy-failed::after {
  background: var(--sc-danger);
}

.sc-job-number {
  margin-top: 1px;
  font-size: 13px;
  line-height: 1.25;
}

.sc-job-number-label {
  margin-right: 5px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--sc-fg-subtle);
}

.sc-job-number-value {
  font-family: var(--sc-font-mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--sc-danger);
  /* One click takes the whole number, since it gets pasted into emails and
     invoices constantly. */
  user-select: all;
}

/* `--sc-danger` is tuned for light surfaces and is not restated in the dark
   block, so it goes dim against `--sc-bg`. Lift it here rather than change the
   token, which every other status colour depends on. */
[data-bs-theme="dark"] .sc-job-number-value {
  color: oklch(0.72 0.16 25);
}

/* ─── Expense reconciliation report (/report/expenses) ───────────────────── */
/*
 * The month's expenses, line by line, each with a box to tick when it has been
 * found in Reckon. The two jobs of this block are to make a checked line
 * unmistakable without hiding it, and to keep an unchecked one perfectly
 * legible — this is a page somebody reads down for twenty minutes.
 */

/* Job and job-total rows sit between the report family's client group header
   and its sub-total, so they are deliberately quieter than both: the client is
   the section, the job is a heading inside it. */
.table-data .row-job-header > td {
  background-color: #fbfbfa !important;
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
  border-top: 1px solid #ececea !important;
}

.table-data .row-job-total > td {
  font-size: 0.85rem;
  padding-top: 0.15rem;
  padding-bottom: 0.35rem;
  color: var(--sc-fg-muted);
}

.sc-recon-job {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.sc-recon-jobcount {
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--sc-fg-muted);
  white-space: nowrap;
}

.sc-recon-jobcount.is-complete {
  color: var(--sc-success);
  font-weight: 600;
}

/* The tick column. Narrow and fixed, because it is the leftmost column of a
   table whose other columns are all content-sized — left to itself it would
   grow with the header text. */
.sc-recon-col {
  width: 3.25rem;
  text-align: center;
}

.sc-recon-cell {
  text-align: center;
  white-space: nowrap;
}

.sc-recon-box {
  /* Bigger than Bootstrap's 1em default: this is the control the page exists
     for, and it is clicked a few hundred times in a sitting. */
  width: 1.15rem;
  height: 1.15rem;
  cursor: pointer;
}

.sc-recon-box:disabled {
  /* Only ever true while its write is in flight. */
  opacity: 0.5;
  cursor: progress;
}

/* When the line was ticked, under the box. The full "who and when" is in the
   title — the column has room for a date and nothing else. */
.sc-recon-meta {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.65rem;
  line-height: 1;
  color: var(--sc-fg-subtle);
  font-variant-numeric: tabular-nums;
  /* Reserve the line whether or not there is a date in it, so ticking a box
     does not jog the row — and with it the whole column below the pointer. */
  min-height: 0.65rem;
}

/*
 * A checked line. Muted and tinted rather than struck through: the text still
 * has to be readable, because the reason to look at a checked line is usually
 * to check it was the right one. The left accent is what carries the state at
 * a glance down a long page, and it survives a printer with background
 * graphics turned off in a way a fill does not.
 */
.table-data tr.is-reconciled > td {
  background-color: color-mix(in srgb, var(--sc-success) 7%, transparent) !important;
  color: var(--sc-fg-muted);
}

.table-data tr.is-reconciled > td:first-child {
  box-shadow: inset 3px 0 0 var(--sc-success);
}

.table-data tr.is-reconciled a {
  color: var(--sc-fg-muted) !important;
}

/* Descriptions are printed in full — they are what a line is matched against
   in Reckon — but a pasted supplier breakdown must not push the money column
   off the table. */
.sc-recon-desc {
  min-width: 16rem;
  max-width: 34rem;
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}

/* ─── How far through the month someone is ───────────────────────────────── */

.sc-recon-progress {
  min-width: 13rem;
}

.sc-recon-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--sc-border);
  overflow: hidden;
}

.sc-recon-bar > span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: var(--sc-success);
  transition: width 120ms ease-out;
}

.sc-recon-progress-label {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--sc-fg-muted);
  font-variant-numeric: tabular-nums;
}

/* ─── Dark mode ──────────────────────────────────────────────────────────── */
/*
 * The two job rows paint literal light greys (they belong with the report
 * family's own group-header and sub-total rows, which do the same), so they
 * need a pair here. Everything else above is already drawn from tokens that
 * flip themselves.
 */
[data-bs-theme="dark"] .table-data .row-job-header > td {
  background-color: var(--bs-tertiary-bg) !important;
  border-top-color: var(--bs-border-subtle) !important;
}

[data-bs-theme="dark"] .table-data tr.is-reconciled > td {
  background-color: color-mix(in srgb, var(--sc-success) 14%, transparent) !important;
}

/* ─── Job project overview (/manage/job/{id}/project) ────────────────────── */

/* Everything here is token-driven — colours mix against --sc-surface — so the
   dark theme needs no second set of rules. The fill hue is --sc-fg rather
   than --sc-accent: the two are the same near-black in the light theme, but
   the dark theme does not restate the accent, which would leave a black bar
   on a black track. */

/* ── Headline meters ── */

.sc-proj-meter .stat-number { margin-bottom: 0.5rem; }
.sc-proj-meter-none { color: var(--sc-fg-faint); }

.sc-proj-verdict {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 1.05rem;
    color: var(--sc-fg);
}
.sc-proj-verdict .bi { color: var(--sc-fg-muted); }
.sc-proj-verdict.is-muted { color: var(--sc-fg-muted); font-size: 0.9rem; }
.sc-proj-verdict.is-muted .bi { color: var(--sc-fg-faint); }

/* ── Progress tracks (shared by the meters and the two bar sections) ── */

.sc-proj-track {
    display: flex;
    height: 10px;
    border-radius: var(--sc-radius-sm);
    background: var(--sc-border);
    overflow: hidden;
}
.sc-proj-track.is-thin { height: 6px; border-radius: 3px; }

.sc-proj-fill {
    display: block;
    height: 100%;
    background: var(--sc-fg);
    border-radius: inherit;
    flex: none;
}
/* A second fill is the overrun: a 2px surface gap between the two, so the
   limit reads as an edge rather than a gradient. */
.sc-proj-fill + .sc-proj-fill { margin-left: 2px; }
.sc-proj-fill.is-over { background: var(--sc-danger); }
/* Nothing to measure against: full, and quiet about it. */
.sc-proj-fill.is-unbounded { background: var(--sc-fg-faint); }

/* ── The bar sections ── */

.sc-proj-bars { padding-top: 0.5rem; padding-bottom: 0.5rem; }

.sc-proj-row {
    display: grid;
    grid-template-columns: minmax(160px, 1fr) minmax(0, 3fr) auto;
    align-items: center;
    gap: 0 1rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--sc-divider);
}
.sc-proj-row:last-child { border-bottom: 0; }
.sc-proj-row.is-total {
    font-weight: 600;
    border-top: 1px solid var(--sc-border-strong);
    border-bottom: 0;
    margin-top: 0.25rem;
    padding-top: 0.8rem;
}
.sc-proj-row.is-parent-direct .sc-proj-label-name { color: var(--sc-fg-muted); font-style: italic; }

.sc-proj-row-label {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-width: 0;
    gap: 2px;
}
.sc-proj-label-name {
    color: var(--sc-fg);
    text-decoration: none;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
a.sc-proj-label-name:hover { text-decoration: underline; }
.sc-proj-row-label .sc-copy code,
.sc-proj-label-num { font-size: 11px; color: var(--sc-fg-muted); }
.sc-proj-row-sublabel { font-size: 11px; color: var(--sc-fg-muted); font-weight: 400; }

.sc-proj-row-caption {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-align: right;
    font-size: 0.9rem;
}

@media (max-width: 767.98px) {
    .sc-proj-row { grid-template-columns: 1fr auto; }
    .sc-proj-row .sc-proj-track { grid-column: 1 / -1; order: 3; margin-top: 4px; }
}

/* ── The timeline ── */

.sc-proj-gantt {
    --proj-label-w: 220px;
    --proj-head-h: 28px;
    --proj-row-h: 34px;
    display: grid;
    grid-template-columns: var(--proj-label-w) repeat(var(--proj-weeks), minmax(0, 1fr));
    grid-template-rows: var(--proj-head-h) repeat(var(--proj-rows), var(--proj-row-h));
    position: relative;
    font-size: 12px;
}

@media (max-width: 767.98px) {
    .sc-proj-gantt { --proj-label-w: 130px; }
}

/* Week backgrounds. A hairline at each month start carries the calendar; the
   weeks between are separated only by the faintest divider. */
.sc-proj-week {
    border-left: 1px solid var(--sc-divider);
    min-width: 0;
}
.sc-proj-week.is-month-start { border-left-color: var(--sc-border-strong); }

.sc-proj-corner { border-bottom: 1px solid var(--sc-border); }
.sc-proj-month {
    z-index: 1;
    padding: 0 6px;
    line-height: var(--proj-head-h);
    color: var(--sc-fg-muted);
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-bottom: 1px solid var(--sc-border);
}

.sc-proj-label {
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
    padding-right: 10px;
    border-bottom: 1px solid var(--sc-divider);
    line-height: 1.2;
}
.sc-proj-label.is-parent .sc-proj-label-name { color: var(--sc-fg-muted); }

/* Bars: the staff-leave recipe — a soft fill and a solid left edge in one hue,
   mixed against the surface so it holds in both themes. */
.sc-proj-bar {
    --bar: var(--sc-fg);
    z-index: 2;
    align-self: center;
    display: flex;
    align-items: center;
    min-width: 0;
    height: 22px;
    margin: 0 2px;
    padding: 0 8px;
    border-radius: var(--sc-radius-sm);
    background: color-mix(in oklab, var(--bar) 22%, var(--sc-surface));
    border: 1px solid color-mix(in oklab, var(--bar) 45%, var(--sc-surface));
    border-left: 3px solid var(--bar);
    color: var(--sc-fg);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    transition: background 120ms ease-out;
}
.sc-proj-bar:hover { background: color-mix(in oklab, var(--bar) 34%, var(--sc-surface)); color: var(--sc-fg); }
.sc-proj-bar-text { overflow: hidden; text-overflow: ellipsis; font-weight: 600; font-size: 11.5px; }

/* The parent's span is the envelope, not work: hollow. */
.sc-proj-bar.is-parent {
    --bar: var(--sc-fg-muted);
    background: transparent;
    border-style: dashed;
    border-left-style: solid;
    height: 18px;
}
.sc-proj-bar.is-parent .sc-proj-bar-text { color: var(--sc-fg-muted); font-weight: 500; }
.sc-proj-bar.is-done { --bar: var(--sc-fg-subtle); }
.sc-proj-bar.is-done .sc-proj-bar-text { color: var(--sc-fg-muted); text-decoration: line-through; }

/* A bar with one end unknown loses its cap on that side. */
.sc-proj-bar.open-end {
    border-right-style: dashed;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    -webkit-mask-image: linear-gradient(to right, #000 60%, transparent);
    mask-image: linear-gradient(to right, #000 60%, transparent);
}
.sc-proj-bar.open-start {
    border-left-width: 1px;
    border-left-style: dashed;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    -webkit-mask-image: linear-gradient(to left, #000 60%, transparent);
    mask-image: linear-gradient(to left, #000 60%, transparent);
}

/* Go-live: a flag on its day (the Long Grid's deadline colour and glyph). */
.sc-proj-flag-cell { position: relative; z-index: 3; pointer-events: none; }
.sc-proj-flag {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    color: var(--sc-danger);
    font-size: 15px;
    line-height: 1;
    pointer-events: auto;
    filter: drop-shadow(0 0 2px var(--sc-surface));
}

/* Today: a rule through every row, tagged in the header. */
.sc-proj-today-cell { position: relative; z-index: 4; pointer-events: none; }
.sc-proj-today {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 1.5px solid var(--sc-fg);
}
.sc-proj-today-tag {
    position: absolute;
    top: 4px;
    left: 3px;
    padding: 1px 5px;
    border-radius: 3px;
    background: var(--sc-fg);
    color: var(--sc-bg);
    font-size: 10px;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0.03em;
}

/* Legend swatches (layout comes from .sc-grid-legend). */
.sc-proj-legend i.workstream { background: color-mix(in oklab, var(--sc-fg) 22%, var(--sc-surface)); border-left: 3px solid var(--sc-fg); }
.sc-proj-legend i.parent { border: 1px dashed var(--sc-fg-muted); border-left: 3px solid var(--sc-fg-muted); }
.sc-proj-legend i.done { background: color-mix(in oklab, var(--sc-fg-subtle) 22%, var(--sc-surface)); border-left: 3px solid var(--sc-fg-subtle); }
.sc-proj-legend i.open { background: linear-gradient(to right, color-mix(in oklab, var(--sc-fg) 22%, var(--sc-surface)) 50%, transparent); border-left: 3px solid var(--sc-fg); }
.sc-proj-legend i.today { width: 2px; border-radius: 0; background: var(--sc-fg); }
.sc-proj-legend-flag { color: var(--sc-danger); font-size: 11px; width: auto; height: auto; }

.sc-proj-unscheduled { font-size: 0.9rem; }
.sc-proj-unscheduled a { text-decoration: none; }
.sc-proj-unscheduled a:hover { text-decoration: underline; }

.sc-proj-empty-icon { font-size: 2.5rem; color: var(--sc-fg-faint); }

/* ── Job timesheet report: selecting rows to move ───────────────────────── */
.sc-ts-pick { width: 2rem; }
.sc-ts-bulk {
    position: sticky;
    bottom: 1rem;
    z-index: 5;
    margin-bottom: 1rem;
    padding: 0.75rem 1rem;
    background: var(--sc-surface);
    border: 1px solid var(--sc-border-strong);
    border-radius: var(--sc-radius);
    box-shadow: var(--sc-shadow-pop);
}
.sc-ts-bulk-job { width: 10rem; }
