@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700&display=swap');

/* ==========================================================================
   shadcn / Linear Slate Dark Design System (Vanilla CSS Tokens)
   ========================================================================== */

:root, [data-theme="dark"] {
    /* Color System (Dark Zinc / Slate) */
    --sys-color-background: #090d16;
    --sys-color-on-background: #f8fafc;
    
    --sys-color-surface: #111726;
    --sys-color-on-surface: #f8fafc;
    --sys-color-surface-variant: #1a2236;
    --sys-color-on-surface-variant: #94a3b8;
    
    --sys-color-surface-container-low: #0e1320;
    --sys-color-surface-container: #131929;
    --sys-color-surface-container-high: #1c2438;
    --sys-color-surface-container-highest: #28334d;

    --sys-color-primary: #6366f1;
    --sys-color-primary-rgb: 99 102 241;
    --sys-color-primary-hover: #4f46e5;
    --sys-color-on-primary: #ffffff;
    --sys-color-primary-container: #1e1b4b;
    --sys-color-on-primary-container: #c7d2fe;

    --sys-color-secondary: #0ea5e9;
    --sys-color-secondary-rgb: 14 165 233;
    --sys-color-on-secondary: #ffffff;
    --sys-color-secondary-container: #075985;
    --sys-color-on-secondary-container: #e0f2fe;

    --sys-color-tertiary-container: #312e81;
    --sys-color-on-tertiary-container: #c7d2fe;
    --sys-color-on-tertiary-container-rgb: 199 210 254;

    --sys-color-error: #ef4444;
    --sys-color-error-rgb: 239 68 68;
    --sys-color-on-error: #ffffff;
    --sys-color-error-container: #450a0a;
    --sys-color-on-error-container: #fecaca;

    --sys-color-warning: #f59e0b;
    --sys-color-on-warning: #451a03;
    --sys-color-warning-container: #451a03;
    --sys-color-on-warning-container: #fde68a;

    --sys-color-success: #22c55e;

    --sys-color-outline: #2d3854;
    --sys-color-outline-variant: #1e293b;

    /* Elevation & Glass Tokens */
    --sys-elevation-1: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
    --sys-elevation-2: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
    --sys-elevation-3: 0 10px 15px -3px rgba(0, 0, 0, 0.6), 0 4px 6px -4px rgba(0, 0, 0, 0.5);
    --sys-elevation-hover: 0 12px 24px -4px rgba(0, 0, 0, 0.6), 0 0 20px rgba(99, 102, 241, 0.15);

    /* Radius Tokens (shadcn Sharp Compact Radii) */
    --sys-shape-corner-xs: 4px;
    --sys-shape-corner-sm: 6px;
    --sys-shape-corner-md: 8px;
    --sys-shape-corner-lg: 12px;
    --sys-shape-corner-full: 9999px;

    /* Layout & Motion Tokens */
    --sys-layout-max-width: 1600px;
    --sys-form-max-width: 580px;
    --sys-motion-standard: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);

    --sys-state-hover: rgba(255, 255, 255, 0.04);
    --sys-state-pressed: rgba(255, 255, 255, 0.08);

    --sys-color-top-bar-overlay: rgba(17, 23, 38, 0.85);
    --sys-focus-ring: 0 0 0 2px rgb(var(--sys-color-primary-rgb) / 0.2);

    /* Chart.js colors are server-rendered once per page load (see DashboardChartFactory
       / chart.colors in config/services.yaml) and can't read these variables directly —
       theme_controller.js reads them live via getComputedStyle() to restyle existing
       chart instances on a client-side theme switch, so these must stay pixel-identical
       to chart.colors.theme.dark. */
    --chart-axis-text: #94a3b8;
    --chart-legend-text: #f1f5f9;
    --chart-grid-line: rgba(255, 255, 255, 0.1);
    --chart-surface: #0b0f19;
}

[data-theme="light"] {
    --sys-color-background: #f8fafc;
    --sys-color-on-background: #0f172a;
    
    --sys-color-surface: #ffffff;
    --sys-color-on-surface: #0f172a;
    --sys-color-surface-variant: #f1f5f9;
    --sys-color-on-surface-variant: #475569;
    
    --sys-color-surface-container-low: #ffffff;
    --sys-color-surface-container: #f8fafc;
    --sys-color-surface-container-high: #f1f5f9;
    --sys-color-surface-container-highest: #e2e8f0;

    --sys-color-primary: #4f46e5;
    --sys-color-primary-rgb: 79 70 229;
    --sys-color-primary-hover: #4338ca;
    --sys-color-on-primary: #ffffff;
    --sys-color-primary-container: #e0e7ff;
    --sys-color-on-primary-container: #1e1b4b;

    --sys-color-secondary: #0284c7;
    --sys-color-secondary-rgb: 2 132 199;
    --sys-color-on-secondary: #ffffff;
    --sys-color-secondary-container: #e0f2fe;
    --sys-color-on-secondary-container: #0369a1;

    --sys-color-tertiary-container: #ede9fe;
    --sys-color-on-tertiary-container: #4c1d95;
    --sys-color-on-tertiary-container-rgb: 76 29 149;

    --sys-color-error: #dc2626;
    --sys-color-error-rgb: 220 38 38;
    --sys-color-on-error: #ffffff;
    --sys-color-error-container: #fee2e2;
    --sys-color-on-error-container: #991b1b;

    --sys-color-warning: #d97706;
    --sys-color-on-warning: #ffffff;
    --sys-color-warning-container: #fef3c7;
    --sys-color-on-warning-container: #78350f;

    --sys-color-success: #16a34a;

    --sys-color-outline: #cbd5e1;
    --sys-color-outline-variant: #e2e8f0;

    --sys-elevation-1: 0 1px 2px 0 rgba(15, 23, 42, 0.05);
    --sys-elevation-2: 0 4px 6px -1px rgba(15, 23, 42, 0.06), 0 2px 4px -2px rgba(15, 23, 42, 0.04);
    --sys-elevation-3: 0 10px 15px -3px rgba(15, 23, 42, 0.08);
    --sys-elevation-hover: 0 12px 20px -3px rgba(79, 70, 229, 0.12);

    --sys-state-hover: rgba(0, 0, 0, 0.03);
    --sys-state-pressed: rgba(0, 0, 0, 0.06);

    --sys-color-top-bar-overlay: rgba(255, 255, 255, 0.85);
    --sys-focus-ring: 0 0 0 2px rgb(var(--sys-color-primary-rgb) / 0.2);

    /* Must stay pixel-identical to chart.colors.theme.light — see the dark block above. */
    --chart-axis-text: #475569;
    --chart-legend-text: #0f172a;
    --chart-grid-line: #e2e8f0;
    --chart-surface: #ffffff;
}

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

body {
    font-family: 'Inter', 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
    background-color: var(--sys-color-background);
    background-image: radial-gradient(at 50% 0%, rgb(var(--sys-color-primary-rgb) / 0.05) 0px, transparent 60%);
    background-attachment: fixed;
    color: var(--sys-color-on-background);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

a {
    color: var(--sys-color-primary);
    text-decoration: none;
    transition: var(--sys-motion-standard);
}

a:hover {
    color: var(--sys-color-secondary);
}

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

/* Container */
.container {
    width: 100%;
    max-width: var(--sys-layout-max-width);
    margin: 0 auto;
    padding: 24px 20px;
    flex: 1;
}

/* Typography Helpers */
.ui-display-lg { font-size: 36px; line-height: 44px; font-weight: 800; letter-spacing: -0.03em; }
.ui-heading-lg { font-size: 24px; line-height: 32px; font-weight: 700; letter-spacing: -0.02em; }
.ui-heading-md { font-size: 18px; line-height: 26px; font-weight: 600; }
.ui-heading-sm { font-size: 16px; line-height: 24px; font-weight: 600; }
.ui-text-muted { color: var(--sys-color-on-surface-variant); font-size: 13px; }
.ui-label { font-size: 11px; line-height: 16px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--sys-color-on-surface-variant); }

/* Top App Bar Header (shadcn Slate Bar) */
.ui-top-bar {
    width: 100%;
    background-color: var(--sys-color-top-bar-overlay);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--sys-color-outline-variant);
    position: sticky;
    top: 0;
    z-index: 100;
}

.ui-top-bar__container {
    width: 100%;
    max-width: var(--sys-layout-max-width);
    margin: 0 auto;
    padding: 12px 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.ui-top-bar__title {
    font-size: 20px;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--sys-color-on-surface);
}
.ui-top-bar__title a {
    color: inherit;
    display: flex;
    align-items: center;
    gap: 8px;
}
.ui-top-bar__logo {
    display: block;
}
[data-theme="light"] .ui-top-bar__logo {
    filter: invert(1);
}

.ui-footer {
    width: 100%;
    border-top: 1px solid var(--sys-color-outline-variant);
}

.ui-footer__container {
    width: 100%;
    max-width: var(--sys-layout-max-width);
    margin: 0 auto;
    padding: 16px 20px;
    font-size: 13px;
}

.ui-footer__container a {
    color: var(--sys-color-on-surface-variant);
}
.ui-top-bar nav ul {
    display: flex;
    align-items: center;
    list-style: none;
    gap: 8px;
}

/* Toggle Group Control (shadcn Segmented Control) */
.ui-toggle-group {
    display: inline-flex;
    align-items: center;
    height: 34px;
    background-color: var(--sys-color-surface-container-low);
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-sm);
    padding: 2px;
    gap: 2px;
}
.ui-toggle-group__option {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 28px;
    padding: 0 10px;
    border-radius: var(--sys-shape-corner-xs);
    border: none;
    background: transparent;
    color: var(--sys-color-on-surface-variant);
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: var(--sys-motion-standard);
}
.ui-toggle-group__option:hover {
    color: var(--sys-color-on-surface);
    background-color: var(--sys-state-hover);
}
.ui-toggle-group__option.active {
    background-color: var(--sys-color-surface-container-high);
    color: var(--sys-color-on-surface);
    box-shadow: var(--sys-elevation-1);
}

/* shadcn Style Buttons */
.ui-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    padding: 0 14px;
    border-radius: var(--sys-shape-corner-sm);
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    border: 1px solid transparent;
    transition: var(--sys-motion-standard);
    text-decoration: none;
    white-space: nowrap;
}
.ui-button--primary {
    background-color: var(--sys-color-primary);
    color: var(--sys-color-on-primary);
    border-color: rgba(255, 255, 255, 0.1);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), var(--sys-elevation-1);
}
.ui-button--primary:hover {
    background-color: var(--sys-color-primary-hover);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), var(--sys-elevation-2);
}
.ui-button--secondary {
    background-color: var(--sys-color-surface-container);
    color: var(--sys-color-on-surface);
    border-color: var(--sys-color-outline-variant);
}
.ui-button--secondary:hover {
    background-color: var(--sys-color-surface-container-high);
    border-color: var(--sys-color-outline);
}
.ui-button--ghost {
    background-color: transparent;
    color: var(--sys-color-on-surface-variant);
    padding: 0 12px;
}
.ui-button--ghost:hover {
    background-color: var(--sys-state-hover);
    color: var(--sys-color-on-surface);
}
.ui-button-full {
    width: 100%;
}

/* Search Bar Component */
.ui-search-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    width: 100%;
    cursor: text;
    background-color: var(--sys-color-surface-container-low);
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-sm);
    padding: 8px 12px;
    transition: var(--sys-motion-standard);
}
.ui-search-bar:focus-within {
    border-color: var(--sys-color-primary);
    box-shadow: var(--sys-focus-ring);
    background-color: var(--sys-color-surface);
}
.ui-search-bar input {
    width: 100%;
    border: none;
    background: transparent;
    color: var(--sys-color-on-surface);
    font-family: inherit;
    font-size: 13px;
    outline: none;
}

/* Cards (shadcn Sharp Rectangles) */
.ui-card {
    border-radius: var(--sys-shape-corner-md);
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    transition: var(--sys-motion-standard);
    position: relative;
    overflow: hidden;
    background-color: var(--sys-color-surface);
    border: 1px solid var(--sys-color-outline-variant);
    box-shadow: var(--sys-elevation-1);
}
.ui-card:hover {
    border-color: var(--sys-color-outline);
    box-shadow: var(--sys-elevation-2);
}

.ui-card__header {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.ui-card__title {
    font-size: 16px;
    font-weight: 600;
    color: var(--sys-color-on-surface);
}
.ui-card__title a {
    color: inherit;
}
.ui-card__title a:hover {
    color: var(--sys-color-primary);
}
.ui-card__content {
    color: var(--sys-color-on-surface-variant);
}

/* Badges (shadcn Badges) */
.ui-badge-container {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.ui-badge {
    display: inline-flex;
    align-items: center;
    height: 24px;
    padding: 0 10px;
    border-radius: var(--sys-shape-corner-sm);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.01em;
    border: 1px solid var(--sys-color-outline-variant);
    background-color: var(--sys-color-surface-container-high);
    color: var(--sys-color-on-surface-variant);
    white-space: nowrap;
}
.ui-badge--primary {
    background-color: var(--sys-color-primary-container);
    color: var(--sys-color-on-primary-container);
    border-color: rgb(var(--sys-color-primary-rgb) / 0.3);
}
.ui-badge--secondary {
    background-color: var(--sys-color-secondary-container);
    color: var(--sys-color-on-secondary-container);
    border-color: rgb(var(--sys-color-secondary-rgb) / 0.3);
}
.ui-badge--tertiary {
    background-color: var(--sys-color-tertiary-container);
    color: var(--sys-color-on-tertiary-container);
    border-color: rgb(var(--sys-color-on-tertiary-container-rgb) / 0.3);
}
.ui-badge--destructive {
    background-color: var(--sys-color-error-container);
    color: var(--sys-color-on-error-container);
    border-color: rgb(var(--sys-color-error-rgb) / 0.3);
}

/* Table (shadcn Slate Table) */
.ui-table-container {
    border-radius: var(--sys-shape-corner-md);
    background-color: var(--sys-color-surface);
    border: 1px solid var(--sys-color-outline-variant);
    box-shadow: var(--sys-elevation-1);
    overflow-x: auto;
}
.ui-table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
}
.ui-table th, .ui-table td {
    padding: 12px 16px;
    border-bottom: 1px solid var(--sys-color-outline-variant);
}
.ui-table th {
    background-color: var(--sys-color-surface-container-low);
    color: var(--sys-color-on-surface-variant);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    position: sticky;
    top: 0;
    z-index: 10;
}
.ui-table td {
    color: var(--sys-color-on-surface);
    font-size: 13px;
    font-weight: 500;
}
.ui-table tbody tr {
    transition: background-color 0.15s ease;
}
.ui-table tbody tr:hover {
    background-color: var(--sys-state-hover);
}
.ui-table-cell--numeric {
    text-align: right;
}

/* Form Container (shadcn Form Box) */
.ui-form-container {
    width: 100%;
    max-width: var(--sys-layout-max-width);
    margin: 16px auto;
    padding: 40px;
    background-color: var(--sys-color-surface);
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-lg);
    box-shadow: var(--sys-elevation-2);
    display: flex;
    flex-direction: column;
    gap: 20px;
}
.ui-form-content {
    max-width: var(--sys-form-max-width);
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 20px;
}
.ui-form-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
}
.ui-form-field label {
    font-size: 12px;
    font-weight: 600;
    color: var(--sys-color-on-surface-variant);
}
.ui-form-field input {
    width: 100%;
    height: 42px;
    padding: 10px 14px;
    border-radius: var(--sys-shape-corner-sm);
    border: 1px solid var(--sys-color-outline-variant);
    background-color: var(--sys-color-surface-container-low);
    color: var(--sys-color-on-surface);
    font-family: inherit;
    font-size: 14px;
    transition: var(--sys-motion-standard);
}
.ui-form-field input:focus {
    outline: none;
    border-color: var(--sys-color-primary);
    box-shadow: var(--sys-focus-ring);
    background-color: var(--sys-color-surface);
}

/* Password Toggle Button */
.toggle-password-container {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
}
.toggle-password-container input {
    width: 100%;
    padding-right: 65px;
}
.toggle-password-button {
    position: absolute;
    right: 8px;
    background: var(--sys-color-surface-container-high);
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-xs);
    cursor: pointer;
    color: var(--sys-color-on-surface-variant);
    font-size: 11px;
    font-weight: 600;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    transition: var(--sys-motion-standard);
}
.toggle-password-button:hover {
    color: var(--sys-color-on-surface);
    background-color: var(--sys-color-surface-container-highest);
}

/* Alerts */
.ui-alert {
    padding: 14px;
    border-radius: var(--sys-shape-corner-sm);
    font-size: 13px;
    font-weight: 500;
}
.ui-alert--destructive {
    background-color: var(--sys-color-error-container);
    color: var(--sys-color-on-error-container);
    border: 1px solid rgb(var(--sys-color-error-rgb) / 0.3);
}
.ui-alert--info {
    background-color: var(--sys-color-secondary-container);
    color: var(--sys-color-on-secondary-container);
    border: 1px solid rgb(var(--sys-color-secondary-rgb) / 0.3);
}

/* Utilities */
.ui-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
    gap: 16px;
}
.ui-flex-between {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.ui-mb-6 {
    margin-bottom: 24px;
}

/* Turbo Progress Bar */
.turbo-progress-bar {
    height: 2px;
    background: var(--sys-color-primary);
    box-shadow: 0 0 8px var(--sys-color-primary);
}

/* ==========================================================================
   Scrollbars

   Two mechanisms are needed for consistent cross-browser theming:
   `scrollbar-width`/`scrollbar-color` (Firefox and modern Chromium) and the
   `::-webkit-scrollbar*` pseudo-elements (Chromium/WebKit's own, older API,
   which the standard properties don't fully override). Applied on `*` so
   every scrollable container picks it up — the page scroll, `.ui-table-container`
   (overflow-x: auto), `.ui-gantt-outer` (overflow: auto), and the tom-select
   dropdown's own `.ts-dropdown-content` — without listing each one by hand.
   ========================================================================== */

* {
    scrollbar-width: thin;
    scrollbar-color: var(--sys-color-outline) var(--sys-color-surface-container-low);
}

*::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}
*::-webkit-scrollbar-track {
    background: var(--sys-color-surface-container-low);
}
*::-webkit-scrollbar-thumb {
    background-color: var(--sys-color-outline);
    border-radius: var(--sys-shape-corner-full);
    border: 2px solid var(--sys-color-surface-container-low);
}
*::-webkit-scrollbar-thumb:hover {
    background-color: var(--sys-color-on-surface-variant);
}
*::-webkit-scrollbar-corner {
    background: var(--sys-color-surface-container-low);
}

/* ==========================================================================
   tom-select (themed native <select> replacement)

   Skins tom-select's generated markup with this app's own tokens instead of
   its canned CSS (disabled in controllers.json, since we don't use any of
   its bundled themes). This app only ever instantiates it on plain
   single-selects with no plugins (see tom_select_controller.js), so the
   multi-select / remove-button / clear-button / drag-drop plugin rules that
   ship in tom-select's own stylesheet are intentionally not ported here —
   only what a bare single `<select>` actually renders.

   Structural rules (positioning, the hidden <input>, the caret geometry) are
   ported from tom-select's own default.css since disabling that stylesheet
   removes them too, not just its colors. Everything color-related uses this
   app's tokens instead, matching the `.ui-search-bar` / `.ui-form-field
   input` language: surface-container-low background, outline-variant
   border, sm corner radius, primary focus ring. No per-theme overrides are
   needed below — every custom property referenced here is already
   redefined per theme earlier in this file.
   ========================================================================== */

:root {
    --ts-pr-caret: 0px;
    --ts-pr-min: .75rem;
}

.ts-wrapper {
    position: relative;
    display: flex;
    width: 100%;
    min-height: 34px;
    font-family: inherit;
}

.ts-control {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    width: 100%;
    overflow: hidden;
    position: relative;
    z-index: 1;
    box-sizing: border-box;
    padding: 7px 12px;
    padding-right: max(var(--ts-pr-min), var(--ts-pr-caret)) !important;
    background-color: var(--sys-color-surface-container-low);
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-sm);
    box-shadow: none;
    color: var(--sys-color-on-surface);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
    transition: var(--sys-motion-standard);
}

.ts-wrapper.single .ts-control,
.ts-wrapper.single .ts-control input {
    cursor: pointer;
}

.ts-wrapper.single.input-active .ts-control,
.ts-wrapper.single.input-active .ts-control input {
    cursor: text;
}

.ts-wrapper.focus .ts-control,
.dropdown-active .ts-control {
    border-color: var(--sys-color-primary);
    box-shadow: var(--sys-focus-ring);
    background-color: var(--sys-color-surface);
}

.ts-control > input {
    flex: 1 1 auto;
    min-width: 4rem;
    display: inline-block !important;
    padding: 0 !important;
    min-height: 0 !important;
    max-height: none !important;
    max-width: 100% !important;
    margin: 0 !important;
    text-indent: 0 !important;
    border: 0 none !important;
    background: none !important;
    line-height: inherit !important;
    box-shadow: none !important;
    color: var(--sys-color-on-surface);
    font-family: inherit;
    font-size: 13px;
}

.ts-control > input::placeholder {
    color: var(--sys-color-on-surface-variant);
}

.ts-control > input:focus {
    outline: none !important;
}

.input-hidden .ts-control > input {
    opacity: 0;
    position: absolute;
    left: -10000px;
}

/* The dropdown caret, drawn as a CSS triangle since tom-select ships no icon for it. */
.ts-wrapper.single .ts-control {
    --ts-pr-caret: 2rem;
}
.ts-wrapper.single .ts-control::after {
    content: " ";
    display: block;
    position: absolute;
    top: 50%;
    right: 15px;
    margin-top: -3px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 5px 5px 0 5px;
    border-color: var(--sys-color-on-surface-variant) transparent transparent transparent;
}
.ts-wrapper.single.dropdown-active .ts-control::after {
    margin-top: -4px;
    border-width: 0 5px 5px 5px;
    border-color: transparent transparent var(--sys-color-on-surface-variant) transparent;
}

.ts-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    box-sizing: border-box;
    margin: 4px 0 0;
    background-color: var(--sys-color-surface);
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-sm);
    box-shadow: var(--sys-elevation-3);
    color: var(--sys-color-on-surface);
    font-family: inherit;
    font-size: 13px;
    z-index: 50;
}

.ts-dropdown-content {
    overflow: hidden auto;
    max-height: 240px;
    scroll-behavior: smooth;
    padding: 4px;
}

.ts-dropdown [data-selectable],
.ts-dropdown .option,
.ts-dropdown .optgroup-header,
.ts-dropdown .no-results,
.ts-dropdown .create {
    padding: 8px 10px;
    border-radius: var(--sys-shape-corner-xs);
    color: var(--sys-color-on-surface);
    cursor: pointer;
}

.ts-dropdown .optgroup:not(:first-child) {
    border-top: 1px solid var(--sys-color-outline-variant);
    margin-top: 4px;
    padding-top: 4px;
}

.ts-dropdown .optgroup-header {
    background: transparent;
    color: var(--sys-color-on-surface-variant);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    cursor: default;
}

.ts-dropdown .no-results,
.ts-dropdown .create {
    color: var(--sys-color-on-surface-variant);
    cursor: default;
}

.ts-dropdown [data-selectable].option:hover,
.ts-dropdown .option.active {
    background-color: var(--sys-state-hover);
    color: var(--sys-color-on-surface);
}

.ts-dropdown .option[aria-selected="true"],
.ts-dropdown .option.selected {
    background-color: var(--sys-color-primary-container);
    color: var(--sys-color-on-primary-container);
}

.ts-hidden-accessible {
    border: 0 !important;
    clip: rect(0 0 0 0) !important;
    clip-path: inset(50%) !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    width: 1px !important;
    white-space: nowrap !important;
}

/* ==========================================================================
   Gantt Chart
   ========================================================================== */

/*
 * This is the first *sticky column* in this file — everywhere else only
 * sticky header rows exist (.ui-table th). Sticky rows and sticky columns
 * both live inside the same scrolling container here, which needs three
 * z-index tiers so the overlaps resolve correctly while scrolling in both
 * directions:
 *
 *   1. .ui-gantt-corner    (sticky top AND left) — must sit above everything
 *      it overlaps with when scrolling either axis, hence the highest z-index.
 *   2. .ui-gantt-header    (sticky top only) — sits above the body content
 *      that scrolls underneath it vertically, but below the corner.
 *   3. .ui-gantt-labels    (sticky left only) — sits above the track content
 *      that scrolls underneath it horizontally, but below both of the above.
 *
 * Without the tiering, whichever element paints last would visually win the
 * overlap, which flickers depending on scroll position rather than being a
 * fixed, predictable stacking order.
 */

:root {
    --gantt-label-width: 280px;
    --gantt-row-height: 36px;
    --gantt-row-height-epic: 40px;
}

.ui-gantt-outer {
    position: relative;
    overflow: auto;
    max-height: 75vh;
    border-radius: var(--sys-shape-corner-md);
    background-color: var(--sys-color-surface);
    border: 1px solid var(--sys-color-outline-variant);
    box-shadow: var(--sys-elevation-1);
}

/* Auto Fit scales the timeline to exactly the visible width (see gantt#autoFit),
   so side-scrolling would only ever reveal empty space beyond it — disabled here
   rather than left to the fit math being pixel-perfect. */
.ui-gantt-outer--fit {
    overflow-x: hidden;
}

.ui-gantt-header {
    display: grid;
    grid-template-columns: var(--gantt-label-width) minmax(0, 1fr);
    position: sticky;
    top: 0;
    z-index: 20; /* tier 2: above body, below corner */
}

.ui-gantt-corner {
    position: sticky;
    left: 0;
    z-index: 30; /* tier 1: highest, overlaps both header and labels */
    display: flex;
    align-items: center;
    padding: 0 16px;
    height: 40px;
    background-color: var(--sys-color-surface-container-low);
    color: var(--sys-color-on-surface-variant);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--sys-color-outline-variant);
    border-right: 1px solid var(--sys-color-outline-variant);
}

.ui-gantt-header-track {
    position: relative;
    min-width: 100%;
    height: 40px;
    background-color: var(--sys-color-surface-container-low);
    border-bottom: 1px solid var(--sys-color-outline-variant);
}

.ui-gantt-header-tick {
    position: absolute;
    top: 0;
    bottom: 0;
    border-left: 1px solid var(--sys-color-outline-variant);
    padding-left: 4px;
    font-size: 10px;
    color: var(--sys-color-on-surface-variant);
    display: flex;
    align-items: center;
    white-space: nowrap;
}

.ui-gantt-body {
    display: grid;
    grid-template-columns: var(--gantt-label-width) minmax(0, 1fr);
}

.ui-gantt-labels {
    position: sticky;
    left: 0;
    z-index: 10; /* tier 3: above tracks, below header and corner */
    background-color: var(--sys-color-surface);
    border-right: 1px solid var(--sys-color-outline-variant);
}

.ui-gantt-row-label {
    height: var(--gantt-row-height);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 16px;
    font-size: 12px;
    border-bottom: 1px solid var(--sys-color-outline-variant);
    overflow: hidden;
    white-space: nowrap;
}

.ui-gantt-row-label__key {
    font-family: monospace;
    font-size: 10px;
    font-weight: 700;
    color: var(--sys-color-primary);
    flex-shrink: 0;
}

.ui-gantt-row-label__summary {
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--sys-color-on-surface);
}

.ui-gantt-row-label--epic {
    height: var(--gantt-row-height-epic);
    background-color: var(--sys-color-surface-container-low);
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--sys-color-on-surface-variant);
}

.ui-gantt-tracks {
    position: relative;
    min-width: 100%;
}

.ui-gantt-row-track {
    position: relative;
    height: var(--gantt-row-height);
    border-bottom: 1px solid var(--sys-color-outline-variant);
}

.ui-gantt-row-track--epic {
    height: var(--gantt-row-height-epic);
    background-color: var(--sys-color-surface-container-low);
}

.ui-gantt-svg-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 5;
}

.ui-gantt-bar {
    position: absolute;
    top: 4px;
    height: calc(var(--gantt-row-height) - 8px);
    border-radius: var(--sys-shape-corner-xs);
    cursor: pointer;
    font-size: 10px;
    font-weight: 600;
    color: #ffffff;
    display: flex;
    align-items: center;
    padding: 0 6px;
    overflow: hidden;
    white-space: nowrap;
    box-shadow: var(--sys-elevation-1);
    border: 1px solid rgba(255, 255, 255, 0.15);
    transition: filter 0.15s ease;
}

.ui-gantt-bar:hover {
    filter: brightness(1.15);
}

.ui-gantt-bar--epic-rollup {
    height: calc(var(--gantt-row-height-epic) - 12px);
    top: 6px;
    opacity: 0.9;
}

.ui-gantt-bar--critical-path {
    outline: 2px solid var(--sys-color-error, #ef4444);
    outline-offset: 1px;
}

.ui-gantt-bar--estimated {
    background-image: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 0, rgba(255, 255, 255, 0.15) 4px, transparent 4px, transparent 8px);
}

.ui-gantt-drawer {
    border: 1px solid var(--sys-color-outline-variant);
    border-radius: var(--sys-shape-corner-md);
    background-color: var(--sys-color-surface);
    color: var(--sys-color-on-surface);
    box-shadow: var(--sys-elevation-2);
    padding: 20px;
    width: min(420px, 90vw);
}

.ui-gantt-drawer::backdrop {
    background-color: rgba(0, 0, 0, 0.5);
}

.ui-gantt-drawer__variance {
    color: var(--sys-color-warning);
    font-size: 12px;
    font-weight: 600;
}

.ui-gantt-drawer__linked-list {
    margin: 0;
    padding-left: 18px;
    font-size: 12px;
}

/* ==========================================================================
   Themed checkbox — native <input type="checkbox"> only ever picks up
   `accent-color`, which most browsers apply to little more than the check
   glyph, leaving the box itself in unstyled OS chrome. This replaces the
   whole box with the design system's own tokens instead.
   ========================================================================== */

.ui-checkbox {
    appearance: none;
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    margin: 0;
    flex-shrink: 0;
    border: 1.5px solid var(--sys-color-outline);
    border-radius: var(--sys-shape-corner-xs);
    background-color: var(--sys-color-surface-container-low);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

.ui-checkbox:hover {
    border-color: var(--sys-color-primary);
}

.ui-checkbox:focus-visible {
    outline: 2px solid var(--sys-color-primary);
    outline-offset: 1px;
}

.ui-checkbox:checked {
    background-color: var(--sys-color-primary);
    border-color: var(--sys-color-primary);
}

.ui-checkbox:checked::after {
    content: '';
    width: 4px;
    height: 8px;
    border: solid var(--sys-color-on-primary);
    border-width: 0 1.5px 1.5px 0;
    transform: rotate(45deg) translate(-1px, -1px);
}

/* ==========================================================================
   Consolidated Components & Utilities (design-system consolidation pass)

   These exist to replace repeated inline `style="..."` attributes in
   templates/dashboard/*.html.twig, templates/project/_card.html.twig, and
   templates/dashboard/_budget_progress.html.twig with named, reusable
   classes. Genuinely per-row dynamic values (a status color, a progress
   percentage) still get set inline, but only ever as a single CSS custom
   property or dynamic property — never a static block that belongs here.
   ========================================================================== */

/* Stat row: labeled-number tiles inside a bordered/shaded container. */
.ui-stat-row {
    display: flex;
    gap: 32px;
    flex-wrap: wrap;
    padding: 18px;
    background-color: var(--sys-color-surface-container-low);
    border-radius: var(--sys-shape-corner-md);
    border: 1px solid var(--sys-color-outline-variant);
}
.ui-stat {
    flex: 1;
    min-width: 160px;
}
.ui-stat__value {
    color: var(--sys-color-on-surface);
}

/* Metric row: labeled values without the stat-row's own container/border,
   for places (like the budget callout) that sit inside another card. */
.ui-metric-row {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    margin-bottom: 16px;
}
/* Fixed 3-column variant so metrics line up with the nav bar above (e.g. the
   monthly-budget widget): left-aligned under the "Previous Month" button, centered
   under the month title, right-aligned under the "Next Month" button — matching
   content position, not just equal column widths. */
.ui-metric-row--grid3 {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}
.ui-metric-row--grid3 > :nth-child(2) {
    text-align: center;
}
.ui-metric-row--grid3 > :last-child {
    text-align: right;
}
.ui-metric-row--grid3 > :last-child .ui-label {
    justify-content: flex-end;
}
.ui-metric-primary {
    color: var(--sys-color-primary);
    font-weight: 700;
}
.ui-metric-percent {
    font-size: 12px;
    font-weight: 700;
}
.ui-metric-warning {
    color: var(--sys-color-warning);
}

/* Toolbar: the search/filter-control/count-badge header bar pattern. */
.ui-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.ui-toolbar--bordered {
    padding: 14px 18px;
    border-bottom: 1px solid var(--sys-color-outline-variant);
    background-color: var(--sys-color-surface-container-low);
}

/* Chart card: the wrapper every render_chart() call sits inside. */
.ui-chart-card {
    position: relative;
    width: 100%;
    height: 280px;
    padding: 12px;
}
.ui-chart-card--lg {
    height: 380px;
    padding: 10px 0;
}
.ui-chart-card--md {
    height: 260px;
}
.ui-chart-card--sparkline {
    height: 48px;
    padding: 0;
}
.ui-chart-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
}

/* Empty state: the centered "no data" card. */
.ui-empty-state {
    text-align: center;
    padding: 64px;
}
.ui-empty-state--compact {
    padding: 48px;
}

/* Badge modifiers, replacing per-instance inline size/font overrides. */
.ui-badge--xs {
    height: 18px;
    font-size: 10px;
    padding: 0 5px;
}
.ui-badge--sm {
    height: 20px;
    font-size: 10px;
    padding: 0 6px;
}
.ui-badge--mono {
    font-family: monospace;
}
.ui-badge--status {
    height: 22px;
    font-size: 10px;
    font-weight: 600;
    border: none;
    color: #ffffff;
    background-color: var(--row-status-color, var(--sys-color-surface-container-high));
}

/* Progress bars (budget-progress callout). Width is set inline per-instance
   since it's the one genuinely dynamic value; everything else is here. */
.ui-progress-track {
    height: 8px;
    border-radius: var(--sys-shape-corner-full);
    background-color: var(--sys-color-surface-container-highest);
    overflow: hidden;
}
.ui-progress-fill {
    height: 100%;
    border-radius: var(--sys-shape-corner-full);
}
.ui-progress-fill--primary {
    background-color: var(--sys-color-primary);
}
.ui-progress-fill--success {
    background-color: var(--sys-color-success);
}
.ui-progress-fill--danger {
    background-color: var(--sys-color-error, #ef4444);
}

/* Callouts */
.ui-callout-warning {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--sys-color-warning);
}

/* Project card link/content modifiers */
.ui-card--link {
    text-decoration: none;
    color: inherit;
    display: flex;
}
.ui-card__header-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
    gap: 8px;
}
.ui-card__title--lg {
    font-size: 18px;
    margin-top: 4px;
}
.ui-card__content--divided {
    border-top: 1px solid var(--sys-color-outline-variant);
    padding-top: 14px;
    margin-top: 4px;
}

/* Small general-purpose utilities used across the templates above. */
.ui-label--sm {
    font-size: 10px;
}
.ui-label--mb {
    margin-bottom: 4px;
}
.ui-unit-suffix {
    margin-left: 4px;
    color: var(--sys-color-on-surface-variant);
}
.ui-text-unit {
    font-size: 12px;
    font-weight: 500;
}
.ui-icon-muted {
    vertical-align: -1px;
    opacity: 0.6;
}
.ui-stack-md {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.ui-table-cell--danger {
    color: var(--sys-color-error, #ef4444);
}
.ui-metric-danger {
    color: var(--sys-color-error, #ef4444);
}
.ui-mt-3 {
    margin-top: 12px;
}
.ui-table-cell--warning {
    color: var(--sys-color-warning);
}
.ui-table-cell--muted {
    color: var(--sys-color-outline-variant);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 900px) {
    .ui-chart-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 720px) {
    .ui-top-bar__container {
        padding: 10px 14px;
    }
    .ui-top-bar nav ul {
        gap: 4px;
    }
    .ui-button span,
    .ui-toggle-group__option span {
        display: none;
    }
    .ui-toggle-group {
        max-width: 100%;
        overflow-x: auto;
    }
    :root {
        --gantt-label-width: 180px;
    }
}

/* ==========================================================================
   Focus visibility

   .ui-checkbox already has its own :focus-visible ring (see above). This
   extends the same primary-color ring treatment to the other interactive
   elements that had none.
   ========================================================================== */

.ui-button:focus-visible,
.ui-toggle-group__option:focus-visible,
a.ui-badge:focus-visible,
a.ui-card--link:focus-visible,
select:focus-visible {
    outline: 2px solid var(--sys-color-primary);
    outline-offset: 2px;
}
