/* Custom styles for Daily Work Planner */
/* Inspired by professional admin dashboard design */

:root {
    /* ===== XamReady brandbook palette ===== */
    --xr-obsidian: #0B0B0F;
    --xr-ink: #16161B;
    --xr-paper: #F7F7F4;
    --xr-white: #FFFFFF;
    --xr-blue: #2D6BFF;
    --xr-green: #10E07A;
    --xr-red: #FF2E2E;
    --xr-smoke: #9A9AA4;
    --xr-smoke-dk: #6E6E78;
    --xr-line-lt: #E6E6E1;
    --xr-line-dk: #26272F;
    --xr-spectrum: linear-gradient(115deg, #2D6BFF 0%, #10E07A 50%, #FF2E2E 100%);
    --xr-spectrum-soft: linear-gradient(115deg, #2D6BFF 0%, #8A5BFF 45%, #FF2E2E 100%);
    /* Brand spectrum is blue→green→red only, no amber — practical
       exception kept here so warning states have one canonical source. */
    --xr-amber: #ff9f43;

    /* Brand typography */
    --font-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
    --font-mono: 'Space Mono', 'Courier New', monospace;

    /* Bootstrap variable overrides → brand */
    --bs-primary: #2D6BFF;
    --bs-primary-rgb: 45, 107, 255;
    --bs-success: #10E07A;
    --bs-success-rgb: 16, 224, 122;
    --bs-danger: #FF2E2E;
    --bs-danger-rgb: 255, 46, 46;
    --bs-body-font-family: var(--font-sans);
    --bs-body-bg: #F7F7F4;
    --bs-body-color: #16161B;
    --bs-border-color: #E6E6E1;
    --bs-link-color: #2D6BFF;
    --bs-link-color-rgb: 45, 107, 255;
    --bs-link-hover-color: #1B4FD6;

    /* Enhanced Primary Color Palette - XamReady
       (aliased to the --xr-* tokens above so the two can't drift apart) */
    --primary-color: var(--xr-blue);
    --primary-rgb: 45, 107, 255;
    --primary-light: rgba(45, 107, 255, 0.1);
    --primary-glow: rgba(45, 107, 255, 0.4);
    --success-color: var(--xr-green);
    --success-rgb: 16, 224, 122;
    --danger-color: var(--xr-red);
    --danger-rgb: 255, 46, 46;
    --warning-color: var(--xr-amber);
    --warning-rgb: 255, 159, 67;
    --info-color: var(--xr-blue);
    --info-rgb: 45, 107, 255;

    /* Gradient System - Dark Professional */
    --gradient-primary: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%);
    --gradient-success: linear-gradient(135deg, #56ab2f 0%, #a8e063 100%);
    --gradient-danger: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);
    --gradient-info: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
    --gradient-warning: linear-gradient(135deg, #f2994a 0%, #f2c94c 100%);

    /* Light Mode Colors - Paper */
    --body-bg: #F7F7F4;
    --body-color: #16161B;
    --card-bg: #FFFFFF;
    --border-color: #E6E6E1;
    --heading-color: #0B0B0F;
    --muted-color: #6E6E78;

    /* Neutral Colors */
    --gray-50: #f8f9fa;
    --gray-100: #e9ecef;
    --gray-200: #dee2e6;
    --gray-300: #ced4da;
    --gray-500: #adb5bd;
    --gray-700: #495057;
    --gray-900: #212529;

    /* Glassmorphism Base Colors */
    --glass-bg-light: rgba(255, 255, 255, 0.7);
    --glass-border-light: rgba(255, 255, 255, 0.18);
    --glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);

    /* Backdrop Blur Variables */
    --blur-sm: blur(8px);
    --blur-md: blur(16px);
    --blur-lg: blur(24px);

    /* Enhanced Spacing System (8px base) */
    --spacing-xs: 0.25rem;  /* 4px */
    --spacing-sm: 0.5rem;   /* 8px */
    --spacing-md: 1rem;     /* 16px */
    --spacing-lg: 1.5rem;   /* 24px */
    --spacing-xl: 2rem;     /* 32px */
    --spacing-2xl: 3rem;    /* 48px */

    /* Enhanced Shadows for Glassmorphism */
    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
    --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
    --shadow-glass: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
    --shadow-glass-hover: 0 12px 40px 0 rgba(31, 38, 135, 0.25);
    --shadow-float: 0 20px 60px -10px rgba(31, 38, 135, 0.3);

    /* Typography Scale */
    --font-size-xs: 0.75rem;    /* 12px */
    --font-size-sm: 0.875rem;   /* 14px */
    --font-size-base: 1rem;     /* 16px */
    --font-size-lg: 1.125rem;   /* 18px */
    --font-size-xl: 1.25rem;    /* 20px */
    --font-size-2xl: 1.5rem;    /* 24px */
    --font-size-3xl: 1.875rem;  /* 30px */
    --font-size-4xl: 2.25rem;   /* 36px */

    /* Transitions */
    --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
    --transition-base: 250ms cubic-bezier(0.4, 0, 0.2, 1);
    --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);

    /* Semantic INK — text-weight versions of the status colors.
       The brand/Bootstrap fills are tuned for the obsidian theme and wash
       out badly as text on paper (brand green is 1.8:1 on white, amber
       1.6:1, cyan 2.0:1). These are the same hues deepened to clear AA on
       both light surfaces (#FFF and the #F7F7F4 body). Fills are NOT
       changed — only text/border usage. Overridden per-surface below. */
    --ink-success: #0B7A45;   /* 5.4:1 on white, 5.0:1 on paper */
    --ink-danger:  #C81E1E;   /* 5.7:1 / 5.4:1 */
    --ink-warning: #8A5A00;   /* 5.9:1 / 5.5:1 */
    --ink-info:    #1B4FD6;   /* 6.7:1 / 6.2:1 */
}

/* Dark Mode */
[data-bs-theme="dark"] {
    /* On obsidian the bright brand colors are already the readable ones. */
    --ink-success: var(--xr-green);
    --ink-danger:  #FF6B6B;
    --ink-warning: var(--xr-amber);
    --ink-info:    #7FA9FF;

    /* Dark Mode Colors - Obsidian */
    --bs-body-bg: #0B0B0F;
    --bs-body-color: #C9C9D0;
    --bs-border-color: #26272F;
    --body-bg: #0B0B0F;
    --body-color: #C9C9D0;
    --card-bg: #16161B;
    --border-color: #26272F;
    --heading-color: #FFFFFF;
    --muted-color: #9A9AA4;

    /* Dark Mode Neutrals */
    --gray-50: #2b3035;
    --gray-100: #343a40;
    --gray-200: #495057;
    --gray-300: #6c757d;

    /* Dark Mode Glassmorphism */
    --glass-bg-dark: rgba(26, 29, 32, 0.75);
    --glass-border-dark: rgba(255, 255, 255, 0.06);
    --glass-shadow-dark: 0 8px 32px 0 rgba(0, 0, 0, 0.45);

    /* Enhanced Dark Mode Gradients */
    --gradient-primary: linear-gradient(135deg, #2d3436 0%, #1a1d20 100%);

    /* Increased blur in dark mode for better glass effect */
    --blur-sm: blur(12px);
    --blur-md: blur(20px);
    --blur-lg: blur(28px);

    /* Dark Mode Shadows */
    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
    --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px 0 rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 10px 10px -5px rgba(0, 0, 0, 0.4);
    --shadow-glass: 0 8px 32px 0 rgba(0, 0, 0, 0.5);
    --shadow-glass-hover: 0 12px 40px 0 rgba(0, 0, 0, 0.6);
    --shadow-float: 0 20px 60px -10px rgba(0, 0, 0, 0.7);
}

/* Global Styles */
body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    line-height: 1.6;
    letter-spacing: -0.011em;
    background-color: var(--body-bg);
    color: var(--body-color);
    transition: background-color var(--transition-base), color var(--transition-base);
}

main {
    flex: 1;
}

/* Typography Hierarchy */
h1, h2, h3, h4, h5, h6 {
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.2;
    color: var(--heading-color);
}

h1 { font-size: var(--font-size-4xl); }
h2 { font-size: var(--font-size-3xl); }
h3 { font-size: var(--font-size-2xl); }
h4 { font-size: var(--font-size-xl); }
h5 { font-size: var(--font-size-lg); }
h6 { font-size: var(--font-size-base); }

/* White headings only inside dark gradient elements */
.navbar-dark h1,
.navbar-dark h2,
.navbar-dark h3,
.navbar-dark h4,
.navbar-dark h5,
.navbar-dark h6,
.bg-dark h1,
.bg-dark h2,
.bg-dark h3,
.bg-dark h4,
.bg-dark h5,
.bg-dark h6,
.card-header.bg-dark h1,
.card-header.bg-dark h2,
.card-header.bg-dark h3,
.card-header.bg-dark h4,
.card-header.bg-dark h5,
.card-header.bg-dark h6 {
    color: white !important;
}

/* ===================================
   GLASSMORPHISM UTILITY CLASSES
   =================================== */

/* Glassmorphism Base */
.glass {
    background: var(--glass-bg-light);
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
    border: 1px solid var(--glass-border-light);
    box-shadow: var(--shadow-glass);
}

[data-bs-theme="dark"] .glass {
    background: var(--glass-bg-dark);
    border-color: var(--glass-border-dark);
    box-shadow: var(--shadow-glass-dark);
}

.glass-strong {
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: var(--blur-lg);
    -webkit-backdrop-filter: var(--blur-lg);
}

[data-bs-theme="dark"] .glass-strong {
    background: rgba(30, 30, 46, 0.9);
}

.glass-subtle {
    background: rgba(255, 255, 255, 0.4);
    backdrop-filter: var(--blur-sm);
    -webkit-backdrop-filter: var(--blur-sm);
}

[data-bs-theme="dark"] .glass-subtle {
    background: rgba(26, 29, 32, 0.5);
}

/* Floating Effects */
.float {
    box-shadow: var(--shadow-float);
    transform: translateY(-4px);
}

.hover-float {
    transition: all var(--transition-slow);
}

.hover-float:hover {
    transform: translateY(-8px);
    box-shadow: var(--shadow-glass-hover);
}

/* Gradient Overlays */
.gradient-overlay {
    position: relative;
}

.gradient-overlay::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%);
    opacity: 0.1;
    border-radius: inherit;
    pointer-events: none;
}

/* Backdrop Filter Fallback */
@supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)) {
    .glass {
        background: rgba(255, 255, 255, 0.95);
    }

    [data-bs-theme="dark"] .glass {
        background: rgba(26, 29, 32, 0.95);
    }
}

/* Dark Gradient Section Utility */
.bg-gradient-dark {
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%) !important;
    color: white !important;
}

.bg-gradient-dark h1,
.bg-gradient-dark h2,
.bg-gradient-dark h3,
.bg-gradient-dark h4,
.bg-gradient-dark h5,
.bg-gradient-dark h6 {
    color: white !important;
}

/* ===================================
   NAVIGATION - GLASSMORPHISM
   =================================== */

.navbar {
    box-shadow: var(--shadow-md);
    transition: all var(--transition-base);
    z-index: 1030;
    position: relative;
    padding: var(--spacing-md) 0;
}

/* When the expanded nav is too wide for a mid-size desktop (the Center Owner
   has many menus), let it wrap to a second row instead of overflowing the
   viewport. Light roles with few items never wrap, so they're unaffected. */
@media (min-width: 992px) {
    .navbar-expand-lg #navbarNav { flex-wrap: wrap; row-gap: 0.25rem; }
    .navbar-expand-lg #navbarNav .navbar-nav { flex-wrap: wrap; }
}

/* ===================================
   HAMBURGER TOGGLER — animated, morphs into an X
   Bootstrap's Offcanvas plugin (unlike Collapse) doesn't manage
   aria-expanded on its trigger, so the open/closed state comes from a
   small JS listener (planner.js) toggling .is-open on click — the
   animation itself is pure CSS transforms.
   =================================== */
/* display/align-items/justify-content are scoped to the mobile media query
   below, not set here — Bootstrap's own .navbar-expand-lg .navbar-toggler
   rule hides this button at >=992px with the same specificity as an
   unscoped rule here would have, and being later in the cascade this
   stylesheet would otherwise win and un-hide it on desktop. */
.xr-navbar-toggler.navbar-toggler {
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 10px;
    background: transparent;
    box-shadow: none !important;
    transition: background var(--transition-base, 0.2s ease);
}

@media (max-width: 991.98px) {
    .xr-navbar-toggler.navbar-toggler {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

.xr-navbar-toggler.navbar-toggler:hover,
.xr-navbar-toggler.navbar-toggler:focus-visible {
    background: rgba(255, 255, 255, 0.1);
}

.xr-hamburger {
    position: relative;
    width: 22px;
    height: 16px;
    display: inline-block;
    flex-shrink: 0;
}

.xr-hamburger-line {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 2px;
    background: #fff;
    transition: transform 0.25s ease, opacity 0.2s ease, top 0.25s ease;
}

.xr-hamburger-line:nth-child(1) { top: 0; }
.xr-hamburger-line:nth-child(2) { top: 7px; }
.xr-hamburger-line:nth-child(3) { top: 14px; }

.xr-navbar-toggler.is-open .xr-hamburger-line:nth-child(1) {
    top: 7px;
    transform: rotate(45deg);
}

.xr-navbar-toggler.is-open .xr-hamburger-line:nth-child(2) {
    opacity: 0;
    transform: scaleX(0);
}

.xr-navbar-toggler.is-open .xr-hamburger-line:nth-child(3) {
    top: 7px;
    transform: rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
    .xr-hamburger-line { transition: none; }
}

/* ===================================
   MOBILE OFF-CANVAS NAV (below lg)
   Reuses the existing dropdown markup as the accordion: Bootstrap's dropdown
   JS already toggles a `.show` class on open. Below 992px we strip the
   Popper-driven floating position so each group expands inline in the
   drawer instead of floating a popup menu — same links, same role-gating,
   zero new JS.
   =================================== */
@media (max-width: 991.98px) {
    #navbarNav.offcanvas {
        --bs-offcanvas-width: min(340px, 86vw);
        --bs-offcanvas-bg: var(--xr-obsidian);
        --bs-offcanvas-color: #fff;
    }
    #navbarNav .offcanvas-header {
        border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    }
    #navbarNav .offcanvas-title {
        color: #fff;
        font-family: var(--font-serif);
    }
    #navbarNav .navbar-nav {
        flex-wrap: nowrap;
    }
    #navbarNav .nav-item {
        width: 100%;
    }
    #navbarNav .nav-link {
        min-height: 44px;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }
    /* Inline "accordion" groups instead of floating Popper menus.
       !important needed on background/border/backdrop-filter: a later,
       more specific rule (~line 1684, "solid theme-aware dropdowns")
       already forces those with !important for floating dropdowns
       elsewhere in the app; this counters it for the in-drawer case only. */
    #navbarNav .dropdown-menu {
        position: static !important;
        inset: auto !important;
        transform: none !important;
        float: none;
        width: 100%;
        margin: 0 0 0.25rem 0;
        padding: 0 0 0 1.25rem;
        border: 0 !important;
        background: transparent !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        box-shadow: none;
        display: none;
    }
    #navbarNav .dropdown-menu.show {
        display: block;
    }
    #navbarNav .dropdown-item {
        min-height: 44px;
        display: flex;
        align-items: center;
        color: rgba(255, 255, 255, 0.85);
    }
    #navbarNav .dropdown-item:hover,
    #navbarNav .dropdown-item:focus {
        background: rgba(255, 255, 255, 0.08);
        color: #fff;
    }
    #navbarNav .dropdown-toggle::after {
        transition: transform 0.2s ease;
    }
    #navbarNav .dropdown-toggle[aria-expanded="true"]::after {
        transform: rotate(180deg);
    }
    #navbarNav .theme-toggle {
        width: 100%;
        justify-content: flex-start;
        min-height: 44px;
    }
    /* Visually separate the utility cluster (language/theme/notifications/
       preview/account — the second <ul class="navbar-nav"> in base.html)
       from the primary nav groups above it. */
    #navbarNav .navbar-nav + .navbar-nav {
        margin-top: 0.75rem;
        padding-top: 0.75rem;
        border-top: 1px solid rgba(255, 255, 255, 0.12);
    }
}

.navbar-dark {
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%) !important;
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
}

.navbar-brand {
    font-weight: 700;
    font-size: var(--font-size-xl);
    color: white !important;
}

.navbar-dark .navbar-nav .nav-link,
.navbar-dark .navbar-toggler-icon,
.navbar-dark .theme-toggle {
    color: white !important;
}

.nav-link {
    font-weight: 500;
    padding: var(--spacing-sm) var(--spacing-md) !important;
    border-radius: 10px;
    transition: all 0.3s ease;
}

.nav-link:hover {
    background: rgba(13, 110, 253, 0.1);
    transform: translateY(-1px);
}

.navbar-dark .navbar-nav .nav-link:hover,
.navbar-dark .navbar-nav .nav-link:focus {
    background: rgba(255, 255, 255, 0.1);
    color: rgba(255, 255, 255, 0.9) !important;
}

/* Dropdown Menus */
.dropdown-menu {
    background: var(--glass-bg-light);
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
    border: 1px solid var(--glass-border-light);
    border-radius: 16px;
    box-shadow: var(--shadow-glass);
    padding: var(--spacing-sm);
    z-index: 1050;
    position: absolute;
}

[data-bs-theme="dark"] .dropdown-menu {
    background: var(--glass-bg-dark);
    border-color: var(--glass-border-dark);
}

.dropdown-item {
    border-radius: 10px;
    padding: var(--spacing-sm) var(--spacing-md);
    transition: all 0.2s ease;
    color: var(--body-color);
}

.dropdown-item:hover,
.dropdown-item:focus {
    background: rgba(13, 110, 253, 0.15);
    transform: translateX(4px);
    color: var(--heading-color);
}

[data-bs-theme="dark"] .dropdown-item:hover,
[data-bs-theme="dark"] .dropdown-item:focus {
    background: rgba(13, 110, 253, 0.2);
}

.dropdown-divider {
    border-color: var(--glass-border-light);
}

[data-bs-theme="dark"] .dropdown-divider {
    border-color: var(--glass-border-dark);
}

/* ===================================
   CARD COMPONENTS - GLASSMORPHISM
   =================================== */

.card {
    background: var(--glass-bg-light);
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
    border: 1px solid var(--glass-border-light);
    border-radius: 20px;
    box-shadow: var(--shadow-glass);
    transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: visible;
    position: relative;
}

.card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%);
    border-radius: 20px 20px 0 0;
    opacity: 0;
    transition: opacity 0.4s ease;
}

/*
.card:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow-glass-hover);
}
*/
.card:hover::before {
    opacity: 1;
}

[data-bs-theme="dark"] .card {
    background: var(--glass-bg-dark);
    border-color: var(--glass-border-dark);
}

.card-header {
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%);
    border-bottom: 1px solid var(--glass-border-light);
    padding: var(--spacing-lg);
    border-radius: 20px 20px 0 0;
    font-weight: 600;
    color: white;
}

/* Make all headings inside card-header white */
.card-header h1,
.card-header h2,
.card-header h3,
.card-header h4,
.card-header h5,
.card-header h6 {
    color: white !important;
}

[data-bs-theme="dark"] .card-header {
    border-bottom-color: var(--glass-border-dark);
    background: linear-gradient(135deg, #2d3436 0%, #1a1d20 100%);
    color: white;
}

/* Dialogs wear the same header as cards. Nothing styled .modal-header, so
   modals were left with Bootstrap's bg-danger / bg-primary / bg-success —
   the header colour tracked the topic of the dialog rather than the app. */
.modal-header {
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%);
    border-bottom: 1px solid var(--glass-border-light);
    color: white;
    border-radius: 20px 20px 0 0;
}
[data-bs-theme="dark"] .modal-header {
    background: linear-gradient(135deg, #2d3436 0%, #1a1d20 100%);
    border-bottom-color: var(--glass-border-dark);
}
.modal-header h1, .modal-header h2, .modal-header h3,
.modal-header h4, .modal-header h5, .modal-header h6,
.modal-header .modal-title { color: white; }
.modal-header .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }

/* Override for light card headers if needed */
.card-header.bg-light {
    background: var(--card-bg) !important;
    color: var(--heading-color) !important;
}

.card-header.bg-light h1,
.card-header.bg-light h2,
.card-header.bg-light h3,
.card-header.bg-light h4,
.card-header.bg-light h5,
.card-header.bg-light h6 {
    color: var(--heading-color) !important;
}

.card-body {
    padding: var(--spacing-lg);
    background: transparent;
}

/* Card Variants */
.card-glass-primary {
    background: linear-gradient(135deg, rgba(26, 29, 32, 0.1), rgba(45, 52, 54, 0.1));
}

.card-glass-success {
    background: linear-gradient(135deg, rgba(86, 171, 47, 0.1), rgba(168, 224, 99, 0.1));
}

/* ===================================
   BUTTON SYSTEM - GLASSMORPHISM
   =================================== */

.btn {
    font-weight: 500;
    border-radius: 12px;
    padding: 0.625rem 1.5rem;
    transition: all 0.2s ease;
    /* `border: none` used to be here. Solid buttons don't need one, but an
       outline button IS its border — without it 161 controls across 17 pages
       rendered as bare text with nothing to say they were clickable. Keep the
       width and let each variant supply the colour (transparent for solids). */
    border: 1px solid var(--bs-btn-border-color, transparent);
    position: relative;
    overflow: hidden;
}

.btn::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
    transform: translate(-50%, -50%);
    transition: width 0.6s ease, height 0.6s ease;
    pointer-events: none;
}

.btn:active::before {
    width: 300px;
    height: 300px;
}

.btn-primary {
    background: linear-gradient(135deg, #1a1d20 0%, #2d3436 100%);
    box-shadow: 0 4px 15px 0 rgba(0, 0, 0, 0.3);
    color: white;
}

.btn-primary:hover {
    background: linear-gradient(135deg, #2d3436 0%, #3d4446 100%);
    box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.35);
    transform: translateY(-1px);
}

.btn-success {
    background: var(--gradient-success);
    box-shadow: 0 4px 15px 0 rgba(86, 171, 47, 0.35);
    color: white;
}

.btn-success:hover {
    box-shadow: 0 6px 20px 0 rgba(86, 171, 47, 0.45);
    transform: translateY(-1px);
}

.btn-danger {
    background: var(--gradient-danger);
    box-shadow: 0 4px 15px 0 rgba(235, 51, 73, 0.35);
    color: white;
}

.btn-danger:hover {
    box-shadow: 0 6px 20px 0 rgba(235, 51, 73, 0.45);
    transform: translateY(-1px);
}

.btn-warning {
    background: var(--gradient-warning);
    box-shadow: 0 4px 15px 0 rgba(242, 153, 74, 0.35);
    color: white;
}

.btn-warning:hover {
    box-shadow: 0 6px 20px 0 rgba(242, 153, 74, 0.45);
    transform: translateY(-1px);
}

.btn-info {
    background: var(--gradient-info);
    box-shadow: 0 4px 15px 0 rgba(79, 172, 254, 0.35);
    color: white;
}

.btn-info:hover {
    box-shadow: 0 6px 20px 0 rgba(79, 172, 254, 0.45);
    transform: translateY(-1px);
}

/* Glass button variant */
.btn-glass {
    background: var(--glass-bg-light);
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
    border: 1px solid var(--glass-border-light);
    color: var(--heading-color);
}

.btn-glass:hover {
    background: rgba(255, 255, 255, 0.9);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px 0 rgba(31, 38, 135, 0.15);
}

[data-bs-theme="dark"] .btn-glass {
    background: var(--glass-bg-dark);
    border-color: var(--glass-border-dark);
    color: var(--heading-color);
}

[data-bs-theme="dark"] .btn-glass:hover {
    background: rgba(30, 30, 46, 0.9);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.3);
}

/* Form Controls */
/* ===================================
   FORM CONTROLS - GLASSMORPHISM
   =================================== */

.form-control,
.form-select {
    /* background-color, never the `background` shorthand: the shorthand also
       resets background-image, and that is where .form-select keeps its
       dropdown caret. With it gone, every select in the app rendered as a
       plain box with no sign it opened anything. */
    background-color: var(--glass-bg-light);
    backdrop-filter: var(--blur-sm);
    -webkit-backdrop-filter: var(--blur-sm);
    border: 1.5px solid var(--glass-border-light);
    border-radius: 12px;
    padding: 0.75rem 1rem;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    color: var(--body-color);
}

.form-control:focus,
.form-select:focus {
    background-color: rgba(255, 255, 255, 0.95);
    border-color: var(--primary-color);
    box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.15),
                0 4px 12px 0 rgba(31, 38, 135, 0.1);
    transform: translateY(-2px);
    outline: none;
}

[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select {
    background-color: rgba(40, 40, 60, 0.6);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.1);
}

[data-bs-theme="dark"] .form-control:focus,
[data-bs-theme="dark"] .form-select:focus {
    background-color: rgba(50, 50, 70, 0.8);
    border-color: var(--primary-color);
}

/* Fix select option visibility in dark mode */
[data-bs-theme="dark"] .form-select option {
    background-color: #2a2a3e;
    color: #ffffff;
}

.form-select option {
    background-color: #ffffff;
    color: #333333;
}

/* Fix form-select in input-group */
.input-group .form-select {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    flex: 0 0 auto;
    width: auto;
    min-width: 100px;
}

.input-group .form-control {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.form-label {
    font-weight: 500;
    font-size: var(--font-size-sm);
    color: var(--heading-color);
    margin-bottom: var(--spacing-sm);
    letter-spacing: 0.02em;
}

/* Day Planner Styles */
.hour-grid {
    position: relative;
    border: none;
    background: var(--card-bg);
    border-radius: 12px;
    padding: 1.5rem;
    box-shadow: var(--shadow);
}

.hour-row {
    display: flex;
    align-items: center;
    min-height: 70px;
    border-bottom: 1px solid var(--gray-100);
    position: relative;
    padding: 8px 0;
    transition: background-color var(--transition-fast);
}

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

.hour-row:hover {
    background-color: var(--gray-50);
}

.hour-label {
    width: 90px;
    font-weight: 600;
    color: var(--gray-700);
    padding-right: 20px;
    text-align: right;
    font-size: 0.95rem;
}

.hour-content {
    flex: 1;
    position: relative;
    min-height: 60px;
}

/* Task Block Styles */
.task-block {
    background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
    border: none;
    border-left: 4px solid #FF8C00;
    border-radius: 10px;
    padding: 12px 16px;
    margin: 6px 0;
    cursor: pointer;
    transition: all var(--transition-base);
    box-shadow: var(--shadow-md);
}

.task-block:hover {
    transform: translateX(4px) translateY(-2px);
    box-shadow: var(--shadow-lg);
}

.task-block.completed {
    opacity: 0.6;
    background: linear-gradient(135deg, #d4d4d4 0%, #a8a8a8 100%);
    border-left-color: #808080;
}

.task-title {
    font-weight: 600;
    margin-bottom: 6px;
    color: #333;
    font-size: 0.95rem;
}

.task-time {
    font-size: 0.875rem;
    color: #555;
    font-weight: 500;
}

.task-description {
    font-size: 0.9rem;
    color: #444;
    margin-top: 4px;
}

/* Calendar Styles */
.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 12px;
}

.calendar-day {
    aspect-ratio: 1;
    border: 2px solid var(--border-color);
    border-radius: 0;
    padding: 12px;
    text-align: center;
    cursor: pointer;
    transition: box-shadow var(--transition-base);
    background: var(--card-bg);
    box-shadow: var(--shadow-sm);
}

.calendar-day:hover {
    box-shadow: var(--shadow-md);
}

/* Mobile month view: a chronological list of day cards instead of the
   7-column table (which forces horizontal scroll on phones). Reuses the
   base .calendar-day class above for identical weekend/day-off/today/
   holiday/sick coloring — only the shape changes from a square grid cell
   to a left-aligned, full-width stacked card. */
.calendar-day-card {
    aspect-ratio: auto;
    text-align: left;
    width: 100%;
    margin-bottom: 10px;
    min-height: auto;
}

.calendar-day-card-header {
    font-size: 1.05rem;
    margin-bottom: 6px;
}

/* ---- Calendar day states ------------------------------------------------
   Inherited from the earlier planner, which was dark-gradient throughout: a
   weekend was a near-black slab and a holiday a gold flood. Both read fine
   there; on this palette they were three visual languages in one grid, and
   flooding a cell made the classes written inside it unreadable.

   State is a tint plus a left edge now, so the cell keeps its own text
   colour and whatever is written in it stays legible in both themes.

   The tint goes through --bs-table-bg-state because these cells are <td>s
   and Bootstrap paints table cells with `box-shadow: inset 0 0 0 9999px`
   at a higher specificity than a single class -- which is why the old rules
   all carried !important. Setting Bootstrap's own variable co-operates with
   that instead of shouting over it. background-color is set as well for the
   mobile card view, which is a <div> and never sees the table rule. */
.calendar-day.weekend,
.calendar-day.day-off {
    /* Not a working day: recede, do not announce. */
    --bs-table-bg-state: color-mix(in srgb, var(--muted-color) 8%, var(--card-bg));
    background-color: color-mix(in srgb, var(--muted-color) 8%, var(--card-bg));
    border-left: 3px solid color-mix(in srgb, var(--muted-color) 40%, transparent);
}

.calendar-day.today {
    /* Current, marked the way the app marks current everywhere else. */
    --bs-table-bg-state: color-mix(in srgb, var(--primary-color) 10%, var(--card-bg));
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--card-bg));
    border-color: var(--primary-color);
    border-left-width: 3px;
    font-weight: 700;
}

.calendar-day.today .day-number { color: var(--primary-color); }

.calendar-day .day-number {
    font-size: 1.25rem;
    font-weight: 700;
}

.calendar-day .task-count {
    font-size: 0.85rem;
    color: var(--muted-color);
    margin-top: 6px;
    font-weight: 500;
}

/* Month Navigation */
/* Three groups -- month navigation, the details hint, the month's actions.
   space-between pushed them into three columns that had to share whatever
   width was going, so on a tablet "Previous" and "Next" wrapped above and
   below the month title instead of sitting either side of it. They centre and
   wrap as whole groups now: on a wide screen they still sit on one line, and
   on a narrow one they stack cleanly instead of collapsing inwards. */
.month-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: .75rem 1.5rem;
    margin-bottom: 24px;
    padding: 0;
    background: transparent;
    border-radius: 0;
    box-shadow: none;
}

.month-nav > div {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    margin-bottom: 0;
}

.month-nav h2 {
    margin: 0 .25rem;
    font-weight: 700;
    color: var(--heading-color);
    line-height: 1;
    /* Not display:flex -- as a flex item it stopped behaving like a heading
       between the two buttons, which is what pushed them onto their own rows. */
    white-space: nowrap;
}

/* Priority Badges */
.badge {
    font-weight: 600;
    padding: 0.375rem 0.75rem;
    border-radius: 6px;
}

.priority-high {
    background: linear-gradient(135deg, var(--danger-color) 0%, #e33e46 100%);
    color: white;
}

.priority-medium {
    background: linear-gradient(135deg, var(--warning-color) 0%, #ff8c2b 100%);
    color: white;
}

.priority-low {
    background: linear-gradient(135deg, var(--info-color) 0%, #34b5c1 100%);
    color: white;
}

/* Completion Progress */
.progress-wrapper {
    margin: 24px 0;
}

.progress {
    height: 12px;
    border-radius: 10px;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* The gradient here is background-image, so it used to paint straight over
   Bootstrap's .bg-danger/.bg-warning (which only set background-color) and
   every bar rendered green — including an over-budget expense target. Each
   status now gets its own gradient, and the green one only applies when no
   status class is present. */
.progress-bar {
    border-radius: 10px;
}
.progress-bar:not([class*="bg-"]),
.progress-bar.bg-success {
    background: linear-gradient(90deg, var(--success-color) 0%, #1ea752 100%);
}
.progress-bar.bg-warning {
    background: linear-gradient(90deg, var(--warning-color) 0%, #e08a00 100%);
}
.progress-bar.bg-danger {
    background: linear-gradient(90deg, var(--danger-color) 0%, #c81e1e 100%);
}

.completion-stats {
    display: flex;
    justify-content: space-around;
    margin-top: 16px;
    gap: 16px;
}

.stat-box {
    text-align: center;
    padding: 1.5rem;
    background: var(--card-bg);
    border-radius: 12px;
    flex: 1;
    box-shadow: var(--shadow);
    transition: all var(--transition-base);
}

.stat-box:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.stat-number {
    font-size: 2.45rem;
    font-weight: 700;
    background: var(--xr-spectrum);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.stat-label {
    font-size: 0.95rem;
    color: var(--gray-700);
    font-weight: 500;
    margin-top: 4px;
}

/* Notes Editor */
.note-editor {
    min-height: 250px;
    border-radius: 8px;
}

/* Team Member Card */
.team-member-card {
    border: none;
    border-radius: 12px;
    padding: 1.25rem;
    margin-bottom: 12px;
    background: var(--card-bg);
    box-shadow: var(--shadow);
    transition: all var(--transition-base);
}

.team-member-card:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-2px);
}

/* Alerts */
.alert {
    border: none;
    border-radius: 10px;
    box-shadow: var(--shadow);
    border-left: 4px solid;
}

/* Alert text uses the shared ink tokens rather than Bootstrap's stock
   colours — the stock info teal in particular was both off-brand and
   marginal (4.2:1) on its own tinted background. */
.alert-success {
    background-color: rgba(var(--success-rgb), 0.1);
    border-left-color: var(--success-color);
    color: var(--ink-success);
}

.alert-danger {
    background-color: rgba(var(--danger-rgb), 0.1);
    border-left-color: var(--danger-color);
    color: var(--ink-danger);
}

.alert-warning {
    background-color: rgba(var(--warning-rgb), 0.1);
    border-left-color: var(--warning-color);
    color: var(--ink-warning);
}

.alert-info {
    background-color: rgba(var(--info-rgb), 0.1);
    border-left-color: var(--info-color);
    color: var(--ink-info);
}

/* Tables */
.table {
    border-radius: 12px;
    overflow: hidden;
}

.table thead {
    background: linear-gradient(135deg, var(--gray-100) 0%, var(--gray-200) 100%);
}

.table thead th {
  font-weight: 600;
  color: var(--gray-900);
  border-bottom: 2px solid var(--gray-300);
  text-align: center;
}

[data-bs-theme="dark"] .table thead th {
  color: var(--heading-color);
}

/* #10 — all table data centered for a uniform look (client request).
   !important so it also overrides the per-cell .text-start / .text-end
   utilities that made some columns (amounts, totals) left/right-aligned.
   The formal invoice document (invoice_print.html) uses a bare <table>
   with no .table class, so it is deliberately unaffected and keeps its
   right-aligned money. */
.table > :not(caption) > * > th,
.table > :not(caption) > * > td {
  text-align: center !important;
  vertical-align: middle;
}

tfoot.table-danger td,
tfoot.table-danger th,
tfoot.table-success td,
tfoot.table-success th {
    border-color: transparent !important;
    --bs-table-border-color: transparent;
}

[data-bs-theme="dark"] tfoot.table-danger,
[data-bs-theme="dark"] tfoot.table-danger tr,
[data-bs-theme="dark"] tfoot.table-danger td,
[data-bs-theme="dark"] tfoot.table-danger th {
    background: #b02a37 !important;
    color: white !important;
    --bs-table-bg: #b02a37;
    --bs-table-color: white;
}

[data-bs-theme="dark"] tfoot.table-success,
[data-bs-theme="dark"] tfoot.table-success tr,
[data-bs-theme="dark"] tfoot.table-success td,
[data-bs-theme="dark"] tfoot.table-success th {
    background: #146c43 !important;
    color: white !important;
    --bs-table-bg: #146c43;
    --bs-table-color: white;
}

.table-hover tbody tr:hover {
    background-color: var(--gray-50);
}

/* Footer */
footer {
    box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.05);
    transition: background-color var(--transition-base);
}

[data-bs-theme="dark"] footer {
    background-color: var(--card-bg) !important;
    border-top: 1px solid var(--border-color);
}

/* Utility Classes */
.btn-sm-icon {
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
}

.sticky-top-nav {
    position: sticky;
    top: 56px;
    z-index: 100;
    background: white;
    padding: 12px 0;
    border-bottom: 1px solid var(--gray-200);
    box-shadow: var(--shadow-sm);
}

/* Loading States */
.loading {
    opacity: 0.6;
    pointer-events: none;
}

/* Animations */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fade-in {
    animation: fadeIn var(--transition-base);
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .calendar-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 8px;
    }

    .hour-label {
        width: 70px;
        font-size: 0.85rem;
    }

    .stat-number {
        font-size: 1.95rem;
    }

    .stat-box {
        padding: 1rem;
    }

    .task-block {
        padding: 10px 12px;
    }

    .month-nav {
        flex-direction: column;
        gap: 12px;
    }
}

@media (max-width: 576px) {
    .completion-stats {
        flex-direction: column;
    }

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

/* Theme Toggle Button */
.theme-toggle {
    background: transparent;
    border: none;
    color: white;
    font-size: 1.20rem;
    padding: 0.5rem;
    cursor: pointer;
    transition: all var(--transition-fast);
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.theme-toggle:hover {
    background: rgba(255, 255, 255, 0.1);
    transform: rotate(20deg);
}

.theme-toggle i {
    transition: all var(--transition-fast);
}

/* Dark mode specific adjustments */
[data-bs-theme="dark"] .hour-row:hover {
    background-color: var(--gray-100);
}

[data-bs-theme="dark"] .calendar-day:hover {
    background: var(--gray-100);
}

[data-bs-theme="dark"] .sticky-top-nav {
    background: var(--card-bg);
    border-bottom: 1px solid var(--border-color);
}

[data-bs-theme="dark"] .table thead {
    background: var(--gray-100);
}

[data-bs-theme="dark"] .table-hover tbody tr:hover {
    background-color: var(--gray-100);
}

[data-bs-theme="dark"] h1,
[data-bs-theme="dark"] h2,
[data-bs-theme="dark"] h3,
[data-bs-theme="dark"] h4,
[data-bs-theme="dark"] h5,
[data-bs-theme="dark"] h6 {
    color: var(--heading-color);
}

/* Light/Dark mode icon visibility */
.light-mode {
    display: none;
}

[data-bs-theme="dark"] .light-mode {
    display: inline-block;
}

[data-bs-theme="dark"] .dark-mode {
    display: none;
}

/* ---- Holidays and sick days on the calendar -----------------------------
   Amber is the brandbook's one warning colour, so time off wears it; sick
   days take the danger tone so the two are told apart at a glance. Tint and
   edge, never a flood -- the cell still has classes, invoices and totals
   written in it, and those have to stay readable. See the note above about
   --bs-table-bg-state. */
.calendar-day-holiday {
    --bs-table-bg-state: color-mix(in srgb, var(--warning-color) 16%, var(--card-bg));
    background-color: color-mix(in srgb, var(--warning-color) 16%, var(--card-bg));
    border-left: 3px solid var(--warning-color);
}

.calendar-day-holiday.today {
    /* Both at once: today's accent all round, the holiday's edge on the left. */
    border-color: var(--primary-color);
    border-left-color: var(--warning-color);
}

.calendar-day-sick {
    --bs-table-bg-state: color-mix(in srgb, var(--danger-color) 13%, var(--card-bg));
    background-color: color-mix(in srgb, var(--danger-color) 13%, var(--card-bg));
    border-left: 3px solid var(--danger-color);
}

.calendar-day-sick.calendar-day-holiday {
    /* Both kinds on one day: the sick tint, with time off still marked. */
    border-left-color: var(--warning-color);
}

.holiday-indicator,
.sick-day-indicator {
    /* The rule above the names was an inline `2px solid gold` / #dc3545 --
       same hardcoded pair as the cell backgrounds, now on the tokens. */
    font-size: 0.8em;
    padding-top: 3px;
    margin-top: .5rem;
    cursor: help;
}

.holiday-indicator { border-top: 2px solid var(--warning-color); }
.sick-day-indicator { border-top: 2px solid var(--danger-color); }

.holiday-overlap {
    font-weight: 700;
    color: var(--danger-color);
}

/* A month button that contains time off, in the same amber. */
.btn-warning.has-holidays {
    background-color: var(--warning-color);
    border-color: var(--warning-color);
    color: #16161B;
    font-weight: 600;
}

/* Language Dropdown Styles */
.language-dropdown {
    max-height: 400px;
    overflow-y: auto;
    min-width: 180px;
}

.language-dropdown::-webkit-scrollbar {
    width: 6px;
}

.language-dropdown::-webkit-scrollbar-track {
    background: var(--gray-100);
    border-radius: 3px;
}

.language-dropdown::-webkit-scrollbar-thumb {
    background: var(--gray-300);
    border-radius: 3px;
}

.language-dropdown::-webkit-scrollbar-thumb:hover {
    background: var(--gray-500);
}

[data-bs-theme="dark"] .language-dropdown::-webkit-scrollbar-track {
    background: var(--gray-200);
}

[data-bs-theme="dark"] .language-dropdown::-webkit-scrollbar-thumb {
    background: var(--gray-300);
}

.language-dropdown .dropdown-item {
    padding: var(--spacing-sm) var(--spacing-md);
    font-size: var(--font-size-sm);
}

.language-dropdown .dropdown-item.active {
    background: rgba(13, 110, 253, 0.15);
    color: var(--primary-color);
    font-weight: 600;
}

.language-dropdown .dropdown-item.active::before {
    content: '\2713';
    margin-right: 8px;
}

/* Language switcher icon */
#languageDropdown i,
#languageDropdownGuest i {
    margin-right: 4px;
}

/* ============================================================
   XamReady brand layer — overrides Bootstrap & applies brand.
   Appended last so it wins the cascade.
   ============================================================ */

/* Brand typography: Cormorant Garamond display, Inter UI, Space Mono data */
h1, h2, h3,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6,
.navbar-brand,
.font-serif {
    font-family: var(--font-serif);
    font-weight: 700;
    letter-spacing: 0;
}

.font-mono, .text-mono,
code, kbd, samp, pre {
    font-family: var(--font-mono);
}

/* Primary action = Guiding Blue (legible on both Paper and Obsidian) */
.btn-primary {
    --bs-btn-bg: var(--xr-blue);
    --bs-btn-border-color: var(--xr-blue);
    --bs-btn-hover-bg: #1B4FD6;
    --bs-btn-hover-border-color: #1B4FD6;
    --bs-btn-active-bg: #1B4FD6;
    --bs-btn-active-border-color: #1B4FD6;
    --bs-btn-disabled-bg: var(--xr-blue);
    --bs-btn-disabled-border-color: var(--xr-blue);
    background: var(--xr-blue);
    box-shadow: 0 4px 15px 0 rgba(45, 107, 255, 0.30);
    color: #fff;
}
.btn-primary:hover,
.btn-primary:focus {
    background: #1B4FD6;
    box-shadow: 0 6px 20px 0 rgba(45, 107, 255, 0.40);
    transform: translateY(-1px);
}

.btn-outline-primary {
    --bs-btn-color: var(--xr-blue);
    --bs-btn-border-color: var(--xr-blue);
    --bs-btn-hover-bg: var(--xr-blue);
    --bs-btn-hover-border-color: var(--xr-blue);
    --bs-btn-active-bg: var(--xr-blue);
    --bs-btn-active-border-color: var(--xr-blue);
    --bs-btn-hover-color: #fff;
}

.btn-success {
    --bs-btn-bg: var(--xr-green);
    --bs-btn-border-color: var(--xr-green);
    --bs-btn-hover-bg: #0CBF68;
    --bs-btn-hover-border-color: #0CBF68;
    --bs-btn-color: #06231A;
    --bs-btn-hover-color: #06231A;
    background: var(--xr-green);
    color: #06231A;
}

.btn-danger {
    --bs-btn-bg: var(--xr-red);
    --bs-btn-border-color: var(--xr-red);
    --bs-btn-hover-bg: #D61F1F;
    --bs-btn-hover-border-color: #D61F1F;
    background: var(--xr-red);
    color: #fff;
}

/* Colour utilities */
.text-primary { color: var(--xr-blue) !important; }
.bg-primary { background-color: var(--xr-blue) !important; }
.text-bg-primary { background-color: var(--xr-blue) !important; color: #fff !important; }
.text-success { color: var(--xr-green) !important; }
.bg-success { background-color: var(--xr-green) !important; }
.text-danger { color: var(--xr-red) !important; }
.bg-danger { background-color: var(--xr-red) !important; }
.border-primary { border-color: var(--xr-blue) !important; }

/* Resolve through the link token rather than the raw brand blue, so links
   pick up the light-theme ink and the light-on-dark variant used inside
   dark headers. Dark theme is unchanged (the token is the brand blue). */
a { color: var(--bs-link-color); }
a:hover { color: var(--bs-link-hover-color); }

/* Badges */
.badge.bg-primary, .badge.text-bg-primary, .badge.bg-info {
    background-color: var(--xr-blue) !important; color: #fff !important;
}
.badge.bg-success, .badge.text-bg-success {
    background-color: var(--xr-green) !important; color: #06231A !important;
}
.badge.bg-danger, .badge.text-bg-danger {
    background-color: var(--xr-red) !important; color: #fff !important;
}

/* Focus ring → brand blue */
.form-control:focus, .form-select:focus {
    border-color: var(--xr-blue);
    box-shadow: 0 0 0 0.2rem rgba(45, 107, 255, 0.25);
}

/* Navbar — Obsidian with a thin spectrum accent line at the bottom edge */
.navbar-dark {
    background: var(--xr-obsidian) !important;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.navbar-dark::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--xr-spectrum);
}
.nav-link:hover { background: rgba(45, 107, 255, 0.10); }
.navbar-dark .navbar-nav .nav-link:hover,
.navbar-dark .navbar-nav .nav-link:focus {
    background: rgba(45, 107, 255, 0.18);
    color: #fff !important;
}

/* Footer → Obsidian */
footer.bg-light {
    background-color: var(--xr-obsidian) !important;
}
footer.bg-light,
footer.bg-light .text-muted {
    color: var(--xr-smoke) !important;
}
footer.bg-light a { color: var(--xr-paper); }

/* Spectrum accents for hero / brand moments */
.spectrum-bar {
    height: 4px;
    width: 100%;
    background: var(--xr-spectrum);
    border-radius: 999px;
}
.spectrum-text { color: var(--xr-blue); }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .spectrum-text {
        background: var(--xr-spectrum);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
    }
}

/* ============================================================
   XamReady brand v2 — logo, theme correctness, restraint, responsive
   (appended last; wins the cascade)
   ============================================================ */

/* ---- Navbar logo ---- */
.navbar-brand { display: inline-flex; align-items: center; padding-top: 0; padding-bottom: 0; }
.navbar-brand .xr-navbar-logo { height: 30px; width: auto; display: block; }
@media (max-width: 575.98px) { .navbar-brand .xr-navbar-logo { height: 26px; } }

/* ---- Restraint: RGB guides, never floods. Big stats are solid ink/white. ---- */
/* Sans (not serif) so KPI figures are unambiguous — Cormorant's "1"/"0" read as "I"/"O". */
.stat-num { font-family: var(--font-sans); font-weight: 700; line-height: 1; color: var(--heading-color); font-variant-numeric: tabular-nums; }

/* spectrum word-accent washes out (green midpoint) on light grounds, so it is
   solid Guiding Blue on light and only renders as the gradient on dark grounds. */
.spectrum-text { background: none; color: var(--xr-blue); -webkit-text-fill-color: var(--xr-blue); }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    [data-bs-theme="dark"] .spectrum-text,
    .navbar-dark .spectrum-text,
    .on-dark .spectrum-text {
        background: var(--xr-spectrum);
        -webkit-background-clip: text; background-clip: text;
        -webkit-text-fill-color: transparent; color: transparent;
    }
}

/* ---- Cards: solid, consistent surface in both themes ---- */
.card {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.card-header { border-bottom: 1px solid var(--border-color); font-weight: 600; }
.card-header:not([class*="bg-"]) { background-color: transparent; color: var(--heading-color); }

/* ---- Tabs ----------------------------------------------------------------
   Bootstrap's default nav-tabs (link-blue inactive, body-bg active, no hover)
   never matched this theme. Two contexts, same segmented-control language:

   1. Inside a .card-header — that header is a dark gradient in BOTH themes,
      so these are always light-on-dark and must not follow the theme tokens.
      The active tab takes the card's own surface (--card-bg) so it reads as
      the panel it opens onto.
   2. Anywhere else — same shape, but drawn from the theme tokens.        */
.nav-tabs { border-bottom: 0; gap: .25rem; }
.nav-tabs .nav-link {
    border: 0;
    border-radius: 10px;
    padding: .45rem .9rem;
    font-weight: 500;
    color: var(--muted-color);
    background-color: transparent;
    transition: color var(--transition-fast), background-color var(--transition-fast);
}
.nav-tabs .nav-link:hover,
.nav-tabs .nav-link:focus-visible {
    color: var(--heading-color);
    background-color: rgba(var(--primary-rgb), .08);
    isolation: isolate;
}
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
    color: var(--heading-color);
    background-color: rgba(var(--primary-rgb), .12);
}

.card-header .nav-tabs .nav-link { color: rgba(255, 255, 255, .68); }
.card-header .nav-tabs .nav-link:hover,
.card-header .nav-tabs .nav-link:focus-visible {
    color: #fff;
    background-color: rgba(255, 255, 255, .12);
}
.card-header .nav-tabs .nav-link.active,
.card-header .nav-tabs .nav-item.show .nav-link {
    color: var(--heading-color);
    background-color: var(--card-bg);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}

/* ---- Semantic text on light surfaces --------------------------------------
   Only the light theme swaps in the deepened inks; on obsidian the bright
   brand colors already read well and are left untouched.                   */
[data-bs-theme="light"] .text-success { color: var(--ink-success) !important; }
[data-bs-theme="light"] .text-danger  { color: var(--ink-danger)  !important; }
[data-bs-theme="light"] .text-warning { color: var(--ink-warning) !important; }
[data-bs-theme="light"] .text-info    { color: var(--ink-info)    !important; }
[data-bs-theme="light"] .text-primary { color: var(--ink-info)    !important; }

/* Outline buttons carry their meaning in the label and the border, and the
   stock palette doesn't survive the paper background — outline-warning was
   rendering as 1.6:1 yellow-on-white, i.e. invisible. Only the label/border
   colour changes; fills and shapes are untouched. */
[data-bs-theme="light"] .btn-outline-primary   { --bs-btn-color: var(--ink-info);    --bs-btn-border-color: var(--ink-info); }
[data-bs-theme="light"] .btn-outline-success   { --bs-btn-color: var(--ink-success); --bs-btn-border-color: var(--ink-success); }
[data-bs-theme="light"] .btn-outline-danger    { --bs-btn-color: var(--ink-danger);  --bs-btn-border-color: var(--ink-danger); }
[data-bs-theme="light"] .btn-outline-warning   { --bs-btn-color: var(--ink-warning); --bs-btn-border-color: var(--ink-warning); }
[data-bs-theme="light"] .btn-outline-info      { --bs-btn-color: var(--ink-info);    --bs-btn-border-color: var(--ink-info); }
[data-bs-theme="light"] .btn-outline-secondary { --bs-btn-color: #565D64;            --bs-btn-border-color: #565D64; }
[data-bs-theme="light"] .btn-link              { --bs-btn-color: var(--ink-info); --bs-btn-hover-color: #143FAD; }

/* Body links: the brand blue lands at 4.2:1 on the paper background, just
   under AA. The deeper ink clears it, and because links resolve through the
   same token, the ones sitting on dark headers get the light variant. */
[data-bs-theme="light"] {
    --bs-link-color: var(--ink-info);
    --bs-link-color-rgb: 27, 79, 214;
    --bs-link-hover-color: #143FAD;
}

/* …except on the surfaces that stay dark even in the light theme. Those
   re-publish the bright ink set, and because custom properties inherit, every
   .text-* and calendar swatch inside them follows automatically. */
[data-bs-theme="light"] :is(
    .navbar,
    .card-header:not(.bg-light):not(.bg-white):not(.bg-warning),
    footer,
    .calendar-day.weekend,
    .calendar-day.day-off,
    .calendar-day.today
) {
    --ink-success: var(--xr-green);
    --ink-danger:  #FF6B6B;
    --ink-warning: var(--xr-amber);
    --ink-info:    #7FA9FF;
    --bs-link-color: #9EC2FF;
    --bs-link-color-rgb: 158, 194, 255;
    --bs-link-hover-color: #C7DCFF;
}

/* ---- Calendar day-cell content -------------------------------------------
   A cell is light (default) or dark (weekend / day-off / today keep their
   dark gradient in BOTH themes), so its contents can never hardcode a color
   — that's how the weekly-summary block ended up white-on-white whenever a
   month ended on a weekday. Everything here either inherits the cell's own
   colour or reads the inherited ink set.                                   */
.cal-done    { color: var(--ink-success); }
.cal-expense { color: var(--ink-danger); }
.cal-invoice { color: var(--ink-success); }
.cal-warning { color: var(--ink-warning); }
.cal-dim     { opacity: .72; }
.cal-muted   { opacity: .68; }
.cal-rule    { border-top: 1px solid currentColor; }
.cal-rule-dashed { border-top: 1px dashed currentColor; }
.cal-rule, .cal-rule-dashed { border-top-color: color-mix(in srgb, currentColor 32%, transparent); }

/* ---- Dark-theme corrections for Bootstrap's fixed light utilities ---- */
[data-bs-theme="dark"] .bg-light:not(footer) { background-color: var(--xr-ink) !important; color: #E8E8EC; }
[data-bs-theme="dark"] .bg-white { background-color: var(--xr-ink) !important; }
[data-bs-theme="dark"] .text-dark { color: #E8E8EC !important; }
[data-bs-theme="dark"] .table { --bs-table-color: #E8E8EC; --bs-table-bg: transparent; --bs-table-border-color: var(--xr-line-dk); }
[data-bs-theme="dark"] .table-light { --bs-table-bg: var(--xr-ink); --bs-table-color: #fff; }
[data-bs-theme="dark"] .alert-info { --bs-alert-bg: rgba(45,107,255,.12); --bs-alert-border-color: rgba(45,107,255,.30); --bs-alert-color: #bcd2ff; }
[data-bs-theme="dark"] .alert-warning { --bs-alert-bg: rgba(255,159,67,.14); --bs-alert-border-color: rgba(255,159,67,.32); --bs-alert-color: #ffd9ab; }

/* Outline buttons sitting on a dark card header: the light-theme inks are
   tuned for paper and land around 2:1 against the header's gradient. On that
   ground the outline is defined by the white it sits against instead. */
.card-header:not(.bg-light) .btn-outline-primary,
.card-header:not(.bg-light) .btn-outline-secondary,
.card-header:not(.bg-light) .btn-outline-info,
.card-header:not(.bg-light) .btn-outline-light {
    --bs-btn-color: #fff;
    --bs-btn-border-color: rgba(255, 255, 255, .35);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: rgba(255, 255, 255, .14);
    --bs-btn-hover-border-color: rgba(255, 255, 255, .55);
}

/* Anything reached by a #fragment gets a little air above it, so a row you
   were sent back to after acting on it isn't flush against the top edge — and
   so it stays clear if the navbar ever becomes sticky. */
:target {
    scroll-margin-top: 1rem;
}

/* ---- Message toasts ------------------------------------------------------
   Confirmations used to render as a banner above the content. Act on a row
   halfway down a long page and the banner appeared off-screen, so from where
   the user was sitting nothing happened at all.

   Fixed to the bottom, above everything, and deliberately not full width: the
   stack must never cover what was just acted on. pointer-events is off on the
   stack and back on for each toast, so the empty space around them stays
   clickable. */
.toast-stack {
    position: fixed;
    left: 50%;
    bottom: 1.25rem;
    transform: translateX(-50%);
    z-index: 1080;             /* over a modal backdrop (1050), under a modal */
    display: flex;
    flex-direction: column;
    gap: .5rem;
    width: min(34rem, calc(100vw - 2rem));
    pointer-events: none;
}
.toast-message {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .75rem 1rem;
    border-radius: 14px;
    border: 1px solid var(--border-color);
    border-left-width: 4px;
    background: var(--card-bg);
    color: var(--body-color);
    box-shadow: var(--shadow-lg);
    animation: toast-in var(--transition-base) ease-out;
}
[data-bs-theme="dark"] .toast-message {
    background: #1B1B21;
    border-color: var(--glass-border-dark);
    color: #E8E8EC;
}
.toast-message-body { flex: 1 1 auto; min-width: 0; }
.toast-message-close {
    flex: 0 0 auto;
    border: 0;
    background: none;
    color: inherit;
    opacity: .55;
    font-size: 1.35rem;
    line-height: 1;
    padding: 0 .15rem;
    cursor: pointer;
}
.toast-message-close:hover,
.toast-message-close:focus-visible { opacity: 1; }

/* The left edge carries the meaning, so the message itself stays readable
   rather than being white-on-colour. */
.toast-success { border-left-color: var(--ink-success); }
.toast-error,
.toast-danger  { border-left-color: var(--ink-danger); }
.toast-warning { border-left-color: var(--ink-warning); }
.toast-info,
.toast-debug   { border-left-color: var(--ink-info); }
[data-bs-theme="dark"] .toast-success { border-left-color: #2ecc71; }
[data-bs-theme="dark"] .toast-error,
[data-bs-theme="dark"] .toast-danger  { border-left-color: #ff6b6b; }
[data-bs-theme="dark"] .toast-warning { border-left-color: #f2c94c; }
[data-bs-theme="dark"] .toast-info,
[data-bs-theme="dark"] .toast-debug   { border-left-color: #4facfe; }

.toast-message.is-leaving {
    animation: toast-out var(--transition-base) ease-in forwards;
}

@keyframes toast-in {
    from { opacity: 0; transform: translateY(.75rem); }
    to   { opacity: 1; transform: none; }
}
@keyframes toast-out {
    from { opacity: 1; transform: none; }
    to   { opacity: 0; transform: translateY(.5rem); }
}

/* Motion is decoration here; the message is the point. */
@media (prefers-reduced-motion: reduce) {
    .toast-message, .toast-message.is-leaving { animation: none; }
}

/* ---- Segmented view toggles --------------------------------------------
   The same control — a strip that swaps which panel is showing — appeared as
   green on Invoices, red on Expenses, grey on Time Off and blue everywhere
   else, purely because each page picked a different `btn-outline-*`. A view
   switch isn't a semantic action, so it shouldn't carry a semantic colour:
   these rules override the variant so the strip looks the same wherever it
   appears, and page markup only has to mark up which segment is active.

   Applies to `[data-toggle-group]` (JS-driven) and `[data-segmented]` (opt-in,
   for the link-based pickers that navigate instead of toggling). */
.btn-group[data-toggle-group],
.btn-group[data-segmented] {
    background: var(--glass-bg-light);
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    padding: .25rem;
    gap: .25rem;
}
[data-bs-theme="dark"] .btn-group[data-toggle-group],
[data-bs-theme="dark"] .btn-group[data-segmented] {
    background: var(--glass-bg-dark);
    border-color: var(--glass-border-dark);
}
.btn-group[data-toggle-group] > .btn,
.btn-group[data-segmented] > .btn {
    --bs-btn-color: var(--muted-color);
    --bs-btn-hover-color: var(--heading-color);
    --bs-btn-active-color: #fff;
    border: 0;
    border-radius: 10px !important;
    background: transparent;
    font-weight: 500;
    box-shadow: none;
}
.btn-group[data-toggle-group] > .btn:hover,
.btn-group[data-segmented] > .btn:hover {
    background: rgba(var(--primary-rgb), .10);
    transform: none;
}
.btn-group[data-toggle-group] > .btn.active,
.btn-group[data-segmented] > .btn.active {
    /* The accent, not the dark gradient: the gradient is near-black and
       disappears into the obsidian page ground on the dark theme. */
    background: var(--primary-color);
    color: #fff;
    box-shadow: var(--shadow-sm);
}

/* ---- Totals rows --------------------------------------------------------
   Every table that sums something ended it with a different coloured footer
   (green on Invoices, red on Expenses, grey on the rest) because the variant
   tracked the page's topic. A total is a summary, not a verdict — one quiet
   emphasised row everywhere. */
.table > tfoot {
    --bs-table-bg: transparent;
    font-weight: 600;
}
.table > tfoot > tr > * {
    background-color: rgba(var(--primary-rgb), .06);
    border-top: 2px solid var(--border-color);
    color: var(--heading-color);
}
[data-bs-theme="dark"] .table > tfoot > tr > * {
    background-color: rgba(255, 255, 255, .05);
    border-top-color: var(--glass-border-dark);
}

/* ---- Rows and neutral controls: one glass language, app-wide -------------
   These started life scoped to the Staff page. Anything defined per-page is
   by definition inconsistent with every other page, so they live here and
   apply wherever the classes are used.

   Borders come from --border-color, never --glass-border-light: that token is
   a white edge for glass sitting over imagery, and on the flat light theme it
   disappears entirely. */
.list-group-item {
    background: var(--glass-bg-light);
    backdrop-filter: var(--blur-md);
    -webkit-backdrop-filter: var(--blur-md);
    border: 1px solid var(--border-color);
    border-radius: 14px;
    margin-bottom: .6rem;
    transition: transform var(--transition-base), box-shadow var(--transition-base);
}
[data-bs-theme="dark"] .list-group-item {
    background: var(--glass-bg-dark);
    border-color: var(--glass-border-dark);
}
.list-group-item:hover { box-shadow: var(--shadow-glass); }
/* Flush lists are deliberately seamless — leave them alone. */
.list-group-flush > .list-group-item {
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-radius: 0;
    margin-bottom: 0;
    box-shadow: none;
}

/* Compact currency picker: shows the symbol alone, so it only has to fit
   three characters plus the select's arrow. Used wherever the picker sits
   inline in a row (staff rates, a person's billing rate) rather than in a
   form with room for a label. */
.form-select.staff-cur {
    flex: 0 0 auto;
    /* two classes, to outrank the 100px floor `.input-group .form-select`
       puts on every select in a group */
    min-width: 0;
    /* Sized from the content — three uppercase letters plus a tightened caret
       gutter — rather than the blanket 100px floor `.input-group .form-select`
       imposes on every select. */
    width: 4.25rem;
    /* pinned, not inherited: inside an input-group Bootstrap gives this a
       different left padding than it does standing alone, and the widest
       label only fits with the tighter one */
    padding-left: .5rem;
    padding-right: 1.15rem;
    background-position: right .28rem center;
}

/* A neutral control: same dark gradient the card headers wear, white text.
   For utility actions that shouldn't compete with a coloured primary or a
   destructive red. */
.btn-dark-glass {
    background: var(--gradient-primary);
    border: 1px solid rgba(255, 255, 255, .10);
    color: #fff;
    box-shadow: var(--shadow-sm);
}
.btn-dark-glass:hover, .btn-dark-glass:focus-visible {
    color: #fff;
    filter: brightness(1.35);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

/* ---- Dropdowns: solid + theme-aware (replaces the washed-out light glass) ---- */
.dropdown-menu {
    background: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
}
.dropdown-item { color: var(--body-color); border-radius: 8px; }
.dropdown-item:hover, .dropdown-item:focus { background-color: rgba(45, 107, 255, .10); color: var(--xr-blue); }
[data-bs-theme="dark"] .dropdown-item { color: #E8E8EC; }
[data-bs-theme="dark"] .dropdown-item:hover, [data-bs-theme="dark"] .dropdown-item:focus { background-color: rgba(45, 107, 255, .22); color: #fff; }
.dropdown-divider { border-top-color: var(--border-color); }

/* ---- Forms: dark surfaces in dark theme ---- */
/* Light theme: solid, clearly-bordered inputs — the base glass styling
   (translucent white bg + white border) is invisible on the Paper background. */
.form-control,
.form-select {
    background-color: #FFFFFF;
    border: 1px solid #CDCDC6;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    color: var(--xr-ink);
    box-shadow: none;
}
.form-control::placeholder { color: #9A9AA4; }
.form-control:focus,
.form-select:focus { background-color: #FFFFFF; transform: none; }
.form-check-input { border-color: #C7C7C0; }

[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select {
    background-color: #1B1B21;
    border-color: var(--xr-line-dk);
    color: #fff;
}
[data-bs-theme="dark"] .form-check-input:not(:checked) { border-color: var(--xr-line-dk); }
[data-bs-theme="dark"] .form-control::placeholder { color: var(--xr-smoke); }
[data-bs-theme="dark"] .input-group-text { background-color: #222; border-color: var(--xr-line-dk); color: var(--xr-smoke); }

/* ---- Footer: always Obsidian ---- */
footer, footer.bg-light { background-color: var(--xr-obsidian) !important; }
footer, footer.bg-light, footer .text-muted { color: var(--xr-smoke) !important; }
footer a { color: var(--xr-paper); }

/* ---- Responsive type & spacing ---- */
.hero-title { font-size: clamp(2.1rem, 6vw, 3.6rem); line-height: 1.06; }
.lead { font-size: clamp(1rem, 2.3vw, 1.2rem); }
@media (max-width: 575.98px) {
    .display-1, .display-2, .display-3, .display-4 { font-size: calc(1.8rem + 2.2vw); }
    h2 { font-size: 1.5rem; }
    .card-body { padding: 1rem; }
    main.container-fluid { padding-left: .9rem; padding-right: .9rem; }
    .table-responsive { font-size: .9rem; }
}

/* ---- Theme-adaptive logo swap (use light artwork on light, dark on dark) ---- */
.xr-logo-dark { display: none; }
[data-bs-theme="dark"] .xr-logo-light { display: none; }
[data-bs-theme="dark"] .xr-logo-dark { display: inline-block; }

/* ---- Stacked tables: turn a wide data table into bordered cards below
   768px instead of forcing horizontal scroll. CSS-only (display changes
   only) so any JS reading row/cell DOM (e.g. sortTable() in
   client_list.html) keeps working unmodified. Each <td> needs a
   data-label attribute; shown via ::before as the row's left-aligned
   label with the value right-aligned. ---- */
@media (max-width: 767.98px) {
    .table-stack thead { display: none; }
    .table-stack, .table-stack tbody, .table-stack tr, .table-stack td { display: block; width: 100%; }
    .table-stack tr {
        margin-bottom: .75rem;
        border: 1px solid var(--border-color);
        border-radius: 12px;
        padding: .5rem .75rem;
        background: var(--card-bg);
        box-shadow: var(--shadow-sm);
    }
    .table-stack td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .75rem;
        text-align: right;
        border: 0;
        border-bottom: 1px solid var(--border-color);
        padding: .5rem 0;
        min-height: 44px;
    }
    .table-stack td:last-child { border-bottom: 0; }
    .table-stack td:empty { display: none; }
    .table-stack td[data-label]::before {
        content: attr(data-label);
        font-weight: 600;
        color: var(--xr-smoke-dk);
        text-align: left;
        margin-right: auto;
    }
    .table-stack .btn,
    #bulkActionsBar .btn {
        min-height: 44px;
    }
}

/* ---- Multi-date picker (time off) --------------------------------------
   One date input plus the days already added, as removable chips. A month
   grid was too much furniture for picking a few scattered days.

   Built from the same tokens as the rest of the app rather than raw Bootstrap
   ones, so it follows the brand palette into both themes. */
.date-multi-picker .dmp-chip {
    display: inline-flex;
    align-items: center;
    gap: .15rem;
    padding: .35rem .5rem .35rem .6rem;
    border-radius: 10px;
    background: var(--primary-color);
    color: #fff;
    font-weight: 500;
    font-size: .78rem;
    box-shadow: var(--shadow-sm);
}

.date-multi-picker .dmp-chip .btn-close {
    font-size: .55rem;
    padding: .15rem;
    opacity: .85;
}

.date-multi-picker .dmp-chip .btn-close:hover { opacity: 1; }

/* ---- Filter chips -------------------------------------------------------
   Independent on/off filters, as on the classes list. A segmented control
   would be wrong here -- these are not one choice out of several, they are
   several switches -- so they read as pills that dim when they are off,
   borrowing the segmented control's palette so the two look related. */
.filter-chip {
    --bs-btn-padding-y: .25rem;
    --bs-btn-padding-x: .6rem;
    --bs-btn-font-size: .8rem;
    border-radius: 10px !important;
    font-weight: 500;
}

.filter-chip.is-off {
    color: var(--muted-color);
    border-color: var(--border-color);
    background: transparent;
}

.filter-chip.is-empty {
    color: var(--muted-color);
    border-color: var(--border-color);
    background: transparent;
    opacity: .5;
    cursor: not-allowed;
}

/* ---- Sortable table headings --------------------------------------------
   The heading is a link, so it takes the table's own heading colour rather
   than the link accent -- a row of blue headings reads as navigation, which
   these are not. The arrow carries the affordance instead. */
.sortable-th > a {
    color: inherit;
}

.sortable-th > a:hover {
    color: var(--primary-color);
}

.sortable-th > a:hover .bi-arrow-down-up {
    opacity: 1 !important;
}

/* ---------------------------------------------------------------------------
   min-w-0

   A flex child will not shrink below the width of its content unless told it
   may. Several templates already ask for this class; nothing defined it, so
   long names and button rows pushed past the right edge and the page scrolled
   sideways on a phone.
   --------------------------------------------------------------------------- */
.min-w-0 { min-width: 0; }

/* ---------------------------------------------------------------------------
   Minimum readable size

   A badge is sized relative to its parent (0.75em), so one inside .small ends
   up at 10.5px, and a couple of nested labels reached 9.6px. Nobody reads a
   tutor's name at 9.6px. The floor keeps the relative sizing where there is
   room and stops it compounding below roughly 11.5px.
   --------------------------------------------------------------------------- */
.badge { font-size: max(0.75em, 0.72rem); }
.cal-day-summary { font-size: max(0.60em, 0.7rem); }

/* The stacked day cards head themselves with the full date ("Mon, Jul 27"),
   then the shared day-content include printed the bare number underneath it.
   The grid still needs that number -- its cells carry no other date -- so it
   is hidden in card view rather than removed from the include. */
.calendar-day-card .day-number { display: none; }
