/* =====================================================================
   Booking Portal - Application Stylesheet
   Centralized custom CSS (Requirement #154). Works with Bootstrap 5's
   `data-bs-theme` attribute for light/dark mode (Requirement #76).
   ===================================================================== */

:root {
    --bp-primary: #0d6efd;
    --bp-secondary: #6c757d;
    --bp-primary-text: var(--bp-primary);
    --bp-font: 'Inter', -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --bp-radius-input: 10px;
    --bp-radius-menu: 12px;
    --bp-radius-modal: 16px;
    --bp-sidebar-width: 240px;
    --bp-sidebar-collapsed-width: 64px;
    --bp-header-height: 56px;
    --bp-border: #e2e5ea;
    --bp-bg: #f4f6f9;
    --bp-surface: #ffffff;
    --bp-text: #212529;
    /* A shared "depth and roundness" scale so cards/buttons across the
       app read as one deliberate, current look instead of Bootstrap's
       flat stock defaults - used below and reused by the timeline board
       and calendar's own page-specific styles. */
    --bp-radius-sm: 8px;
    --bp-radius: 14px;
    --bp-shadow-sm: 0 1px 3px rgba(15, 23, 42, .06);
    --bp-shadow: 0 4px 16px rgba(15, 23, 42, .07);
    --bp-shadow-lg: 0 12px 32px rgba(15, 23, 42, .12);
    /* Semantic status tones, each a solid + a subtle "-bg" tint, paired
       with a dark-mode override below - the single source both the
       unified .badge-status-* classes and any future status UI should
       read from, instead of hardcoding a color per call site. */
    --bp-success: #198754;
    --bp-success-bg: #e9f7ef;
    --bp-warning: #b8860b;
    --bp-warning-bg: #fff8e6;
    --bp-danger: #dc3545;
    --bp-danger-bg: #fdecec;
    --bp-info: #0dcaf0;
    --bp-info-bg: #e7f9fc;
    --bp-neutral: #6c757d;
    --bp-neutral-bg: #eef0f2;
    /* Low weight on the org's own primary keeps this reliably dark even
       for a pale brand color, while still visibly tinting toward it -
       same color-mix() approach as the auth gradient below, just a much
       lower percentage since a nav rail needs to stay dark enough for
       light text on top of it, not "pop" the way a hero gradient should.
       Applies in both themes (see .app-sidebar) - deliberately NOT a
       [data-bs-theme="dark"] override, since it's meant to read the same
       dark navy regardless of the page's own light/dark toggle. */
    --bp-sidebar-bg: color-mix(in srgb, var(--bp-primary) 28%, #0d1526);
    --bp-dash-tint: 9%;
}

[data-bs-theme="dark"] {
    --bp-border: #33383e;
    --bp-bg: #15181c;
    --bp-surface: #1f2327;
    --bp-text: #e9ecef;
    --bp-success-bg: color-mix(in srgb, var(--bp-success) 20%, var(--bp-surface));
    --bp-warning-bg: color-mix(in srgb, var(--bp-warning) 20%, var(--bp-surface));
    --bp-danger-bg: color-mix(in srgb, var(--bp-danger) 20%, var(--bp-surface));
    --bp-info-bg: color-mix(in srgb, var(--bp-info) 20%, var(--bp-surface));
    --bp-neutral-bg: color-mix(in srgb, var(--bp-neutral) 20%, var(--bp-surface));
    --bp-dash-tint: 5%;
}

body.app-body {
    background: var(--bp-bg);
    color: var(--bp-text);
    font-family: var(--bp-font);
    margin: 0;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Dashboard-only soft brand wash - scoped to the dashboard route via
   $__isDashboard (templates/layouts/main.php), fading back to the app's
   normal --bp-bg so it reads as atmosphere, not a themed page. */
body.bp-dashboard-page {
    background:
        radial-gradient(1100px 560px at 12% -10%, color-mix(in srgb, var(--bp-primary) var(--bp-dash-tint), var(--bp-bg)) 0%, var(--bp-bg) 55%),
        var(--bp-bg);
}

.dash-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 1rem; }
.dash-grid > * { min-width: 0; }
@media (max-width: 991.98px) {
    .dash-grid { grid-template-columns: 1fr; }
    .dash-grid > * { grid-column: 1 / -1 !important; }
}

.bp-ring { position: relative; width: 100px; height: 100px; flex: none; }
.bp-ring svg { transform: rotate(-90deg); }
.bp-ring circle { fill: none; stroke-width: 10; }
.bp-ring .track { stroke: var(--bp-bg); }
.bp-ring .fill { stroke: var(--bp-primary); stroke-linecap: round; }
.bp-ring .pct { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; font-weight: 800; }

.dash-grid .accordion-item { background: var(--bp-surface); border-color: var(--bp-border); border-radius: var(--bp-radius); }
.dash-grid .accordion-button { background: var(--bp-surface); color: var(--bp-text); font-weight: 700; font-size: .92rem; border-radius: var(--bp-radius); }
.dash-grid .accordion-button:not(.collapsed) { background: color-mix(in srgb, var(--bp-primary) 8%, var(--bp-surface)); color: var(--bp-primary-text); box-shadow: none; }
.dash-grid .accordion-button:focus { box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--bp-primary) 20%, transparent); }
.dash-grid .accordion-button::after { filter: none; }

.bp-app-tile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.bp-app-tile { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: var(--bp-radius-sm); padding: 18px 14px; text-align: center; text-decoration: none; color: inherit; transition: border-color .12s ease, box-shadow .12s ease; font-size: .82rem; font-weight: 600; }
.bp-app-tile:hover { border-color: var(--bp-primary); box-shadow: var(--bp-shadow-sm); color: inherit; }
.bp-app-tile i { font-size: 1.6rem; color: var(--bp-primary-text); margin-bottom: 8px; display: block; }

/* Derived from the org's own brand color (same --bp-primary the two
   current_branding() call sites in templates/layouts/{main,auth}.php
   already emit) via color-mix(), not a hardcoded hex - previously this
   was a literal #0d6efd/#084298 gradient, so an organization with a
   custom brand color still saw the stock blue gradient behind their own
   login card. */
body.auth-body {
    background: linear-gradient(135deg, color-mix(in srgb, var(--bp-primary) 85%, black) 0%, var(--bp-primary) 100%);
    font-family: var(--bp-font);
}

.auth-card { border: none; border-radius: var(--bp-radius); box-shadow: var(--bp-shadow-lg); }
.auth-logo {
    width: 64px; height: 64px; margin: 0 auto 12px; border-radius: 50%;
    background: color-mix(in srgb, var(--bp-primary) 12%, var(--bp-surface));
    color: var(--bp-primary-text); font-size: 1.7rem;
    display: flex; align-items: center; justify-content: center;
}

/* ---------- Header ---------- */
.app-header {
    height: var(--bp-header-height);
    background: var(--bp-surface);
    border-bottom: 1px solid var(--bp-border);
    position: sticky;
    top: 0;
    z-index: 1030;
}
.app-brand { color: var(--bp-text); font-size: 1.05rem; }
.app-brand i { color: var(--bp-primary-text); font-size: 1.3rem; }
.avatar-circle {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--bp-accent, var(--bp-primary)); color: var(--bp-on-accent, #fff);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: .8rem; font-weight: 600;
}

/* Header search box - opens the command palette below, same "readonly
   input as a button" trick Workforce Hub's own .hub-search uses, so a
   real text cursor never appears in it before the palette takes over. */
.app-search { flex: 1 1 auto; max-width: 420px; position: relative; }
.app-search input {
    width: 100%; background: var(--bp-bg); border: 1px solid var(--bp-border);
    border-radius: var(--bp-radius-sm); padding: .45rem .7rem .45rem 2.1rem;
    font-size: .85rem; color: var(--bp-text); cursor: pointer;
}
.app-search input:focus {
    outline: none; border-color: var(--bp-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--bp-primary) 18%, transparent);
}
.app-search i.bi-search { position: absolute; left: .95rem; z-index: 1; pointer-events: none; top: 50%; transform: translateY(-50%); color: var(--bp-secondary); font-size: .85rem; }
.app-search kbd {
    position: absolute; right: .5rem; top: 50%; transform: translateY(-50%);
    font-size: .68rem; color: var(--bp-secondary); background: var(--bp-surface);
    border: 1px solid var(--bp-border); border-radius: 4px; padding: 1px 5px;
}
@media (max-width: 767.98px) { .app-search { display: none; } }

/* Shared treatment for the header's right-side icon buttons (quick
   create, notifications, theme) so all of them - including the existing
   theme toggle - read as one consistent row instead of the theme toggle
   looking different from its new neighbors. */
.app-icon-btn {
    width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
    border-radius: var(--bp-radius-sm); border: 1px solid transparent; background: none;
    color: var(--bp-secondary); padding: 0;
}
.app-icon-btn:hover { background: var(--bp-bg); color: var(--bp-text); }

/* Command palette (Ctrl/Cmd+K) - opened by assets/js/app.js. */
.bp-cmdk-backdrop {
    position: fixed; inset: 0; background: rgba(15, 23, 42, .45); z-index: 1095;
    display: none; align-items: flex-start; justify-content: center; padding-top: 12vh;
}
.bp-cmdk-backdrop.show { display: flex; }
.bp-cmdk { width: 560px; max-width: 92vw; background: var(--bp-surface); border-radius: var(--bp-radius); box-shadow: var(--bp-shadow-lg); overflow: hidden; }
.bp-cmdk input { width: 100%; border: none; border-bottom: 1px solid var(--bp-border); padding: 14px 18px; font-size: .95rem; background: var(--bp-surface); color: var(--bp-text); }
.bp-cmdk input:focus { outline: none; }
.bp-cmdk-list { max-height: 320px; overflow-y: auto; padding: 6px; }
.bp-cmdk-item { display: flex; align-items: center; gap: .6rem; padding: .55rem .7rem; border-radius: var(--bp-radius-sm); font-size: .86rem; color: var(--bp-text); cursor: pointer; }
.bp-cmdk-item i { color: var(--bp-secondary); width: 18px; text-align: center; }
.bp-cmdk-item.active, .bp-cmdk-item:hover { background: var(--bp-bg); }
.bp-cmdk-empty { padding: 24px; text-align: center; color: var(--bp-secondary); font-size: .85rem; }
.bp-cmdk-group-label { padding: .5rem .7rem .25rem; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--bp-secondary); }

/* ---------- Shell / Sidebar ---------- */
.app-shell { display: flex; min-height: calc(100vh - var(--bp-header-height)); }

/* Permanently dark, brand-tinted - unlike the rest of the app, the
   sidebar does NOT follow the light/dark theme toggle (same pattern
   Workforce Hub's own sidebar uses, and the same reasoning Notion/
   Linear/Vercel-style dashboards use it for: a confident, always-dark
   nav rail against a light-or-dark content area reads as more
   "designed" than a sidebar that just blends into the page). */
.app-sidebar {
    width: var(--bp-sidebar-width);
    background: var(--bp-sidebar-bg);
    border-right: none;
    padding: 16px 8px;
    flex-shrink: 0;
    transition: width .15s ease, transform .15s ease;
}
body.sidebar-collapsed .app-sidebar { width: var(--bp-sidebar-collapsed-width); }
body.sidebar-collapsed .app-sidebar .nav-link span,
body.sidebar-collapsed .app-sidebar .nav-section-title,
body.sidebar-collapsed .app-sidebar .nav-subtitle { display: none; }
/* Hiding the label span with display:none is correct, but flexbox's own
   "hypothetical main size" for a .nav-link (a nested flex container)
   doesn't reliably shrink back down to icon-only width once the
   sidebar's own width has already transitioned down - the active
   item's highlighted background can end up rendered far wider than the
   64px rail, bleeding into the page content next to it. Forcing a hard
   width cap here, only while collapsed, guarantees that can never
   happen regardless of that underlying sizing quirk. */
body.sidebar-collapsed .app-sidebar .nav-link { width: 100%; max-width: 100%; overflow: hidden; }

/* Fixed, theme-independent light tones rather than var(--bp-text) - that
   token flips dark-on-light-mode text to light-on-dark-mode text, either
   of which would go illegible once the sidebar itself is always dark
   regardless of the page's own theme. */
.app-sidebar .nav-link {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 12px; border-radius: 8px; color: var(--bp-sb-text, #aebbd4);
    font-size: .9rem; margin-bottom: 2px; font-weight: 500;
}
.app-sidebar .nav-link i { width: 18px; text-align: center; color: var(--bp-sb-text, #aebbd4); }
.app-sidebar .nav-link:hover { background: var(--bp-sb-hover-bg, rgba(255,255,255,.07)); color: var(--bp-sb-text-strong, #fff); }
.app-sidebar .nav-link:hover i { color: var(--bp-sb-text-strong, #fff); }
.app-sidebar .nav-link.active { background: var(--bp-accent, var(--bp-primary)); color: var(--bp-on-accent, #fff); font-weight: 600; }
.app-sidebar .nav-link.active i { color: var(--bp-on-accent, #fff); }
/* "My Requests" group: collapsible, closed by default unless a page inside it is open. */
.app-sidebar .nav-group-toggle { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 12px; margin-bottom: 2px; border: 0; border-radius: 8px; background: transparent; color: var(--bp-sb-text, #aebbd4); font-size: .9rem; font-weight: 500; text-align: left; cursor: pointer; }
.app-sidebar .nav-group-toggle i { width: 18px; text-align: center; color: var(--bp-sb-text, #aebbd4); }
.app-sidebar .nav-group-toggle span { flex: 1 1 auto; }
.app-sidebar .nav-group-toggle:hover { background: var(--bp-sb-hover-bg, rgba(255,255,255,.07)); color: var(--bp-sb-text-strong, #fff); }
.app-sidebar .nav-group-toggle:hover i { color: var(--bp-sb-text-strong, #fff); }
.app-sidebar .nav-group-toggle .nav-group-chevron { width: auto; font-size: .75rem; transition: transform .2s; }
.app-sidebar .nav-group.open > .nav-group-toggle .nav-group-chevron { transform: rotate(180deg); }
.app-sidebar .nav-group-body { display: none; margin: 0 0 4px 14px; padding-left: 8px; border-left: 1px solid var(--bp-sb-border, rgba(255,255,255,.12)); }
.app-sidebar .nav-group.open > .nav-group-body { display: block; }
.app-sidebar .nav-group-body .nav-link { font-size: .86rem; padding: 7px 10px; }
/* Icon-only rail: show the links themselves (no room for a toggle). */
body.sidebar-collapsed .app-sidebar .nav-group-toggle { display: none; }
body.sidebar-collapsed .app-sidebar .nav-group-body { display: block; margin: 0; padding: 0; border: 0; }
body.sidebar-collapsed .app-sidebar .nav-group-body .nav-link { padding: 9px 12px; }
.app-sidebar .nav-link.disabled { color: var(--bp-sb-disabled, #6b7a99); opacity: .65; cursor: not-allowed; }
.nav-section-title {
    display: block; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
    color: var(--bp-sb-muted, #6b83ad); margin: 18px 12px 6px;
}

/* Small group label inside the Administration section (Organization / Resources / People & Access ...). */
.nav-subtitle {
    font-size: .66rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
    color: var(--bp-sb-subtle, #55698f); margin: 12px 12px 3px; opacity: .9;
}

.app-content { flex: 1; padding: 24px; min-width: 0; }

@media (max-width: 991.98px) {
    .app-sidebar {
        position: fixed; left: 0; top: var(--bp-header-height); bottom: 0;
        transform: translateX(-100%); z-index: 1025; width: var(--bp-sidebar-width) !important;
    }
    body.mobile-sidebar-open .app-sidebar { transform: translateX(0); box-shadow: 4px 0 12px rgba(0,0,0,.15); }
}

/* ---------- Cards / Tables ---------- */
/* A softer, more elevated card than Bootstrap's flat 1px-border default
   - rounder corners plus a gentle shadow reads as considerably less
   "generic admin panel" for very little risk, since it only adds depth/
   roundness rather than changing any layout or color. */
.card { border-color: var(--bp-border); border-radius: var(--bp-radius); box-shadow: var(--bp-shadow-sm); }
.card-header { border-radius: var(--bp-radius) var(--bp-radius) 0 0 !important; font-weight: 600; }
.card-header:last-child { border-radius: var(--bp-radius); }
.page-header { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:12px; margin-bottom: 20px; }
.page-header h1 { font-size: 1.55rem; font-weight: 700; margin: 0 0 8px; letter-spacing: -.01em; line-height: 1.3; }
.page-header .text-secondary { font-size: .875rem; line-height: 1.4; }

/* Shortcut tabs shared by Book a Resource / Find a Room / My Bookings / My
   Waiting List (templates/components/booking_nav.php). */
.bk-tabs { position: sticky; top: var(--bp-header-height); z-index: 20; display: flex; gap: 4px; margin: 0 0 20px; padding-top: 6px; background: var(--bp-bg); border-bottom: 1px solid var(--bp-border); overflow-x: auto; scrollbar-width: none; }
.bk-tabs::-webkit-scrollbar { display: none; }
.bk-tab { display: inline-flex; align-items: center; gap: .45rem; padding: .65rem 1.1rem; margin-bottom: -1px; border-bottom: 3px solid transparent; white-space: nowrap; font-weight: 600; font-size: .92rem; color: var(--bp-text); opacity: .75; text-decoration: none; transition: color .15s, border-color .15s, background .15s; border-radius: var(--bp-radius-sm) var(--bp-radius-sm) 0 0; }
.bk-tab:hover { opacity: 1; color: var(--bp-text); background: var(--bp-neutral-bg); }
.bk-tab.active { opacity: 1; color: var(--bp-primary-text); font-weight: 700; border-bottom-color: var(--bp-primary); background: color-mix(in srgb, var(--bp-primary) 10%, transparent); }
.bk-tab.active i { color: var(--bp-primary-text); }
/* Every Bootstrap tab strip (Settings, Import, ...) matches: plain underline tabs. */
.nav-tabs { gap: 4px; border-bottom: 1px solid var(--bp-border); flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.nav-tabs::-webkit-scrollbar { display: none; }
.nav-tabs .nav-link { display: inline-flex; align-items: center; gap: .45rem; padding: .65rem 1.1rem; margin-bottom: -1px; border: 0; border-bottom: 3px solid transparent; border-radius: var(--bp-radius-sm) var(--bp-radius-sm) 0 0; white-space: nowrap; font-weight: 600; font-size: .9rem; color: var(--bp-neutral); background: transparent; transition: color .15s, border-color .15s, background .15s; }
.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus-visible { color: var(--bp-text); background: var(--bp-neutral-bg); border-color: transparent; }
.nav-tabs .nav-link.active { color: var(--bp-primary-text); font-weight: 700; background: color-mix(in srgb, var(--bp-primary) 10%, transparent); border-bottom-color: var(--bp-primary); }
.breadcrumb { font-size: .82rem; margin-bottom: 6px; }

.stat-card { border-radius: var(--bp-radius); }
.stat-card .stat-value { font-size: 1.8rem; font-weight: 700; }
.stat-card .stat-label { font-size: .8rem; color: var(--bp-secondary); text-transform: uppercase; letter-spacing: .03em; }
.stat-tile-link { display: block; cursor: pointer; }
.stat-tile-link .stat-card { transition: box-shadow .15s ease, transform .15s ease; }
.stat-tile-link:hover .stat-card { box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .08); transform: translateY(-2px); }

table.table thead th { font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; color: var(--bp-secondary); border-bottom-width: 1px; }

.email-chip-box { min-height: calc(2.5em + 2px); padding-top: .3rem; padding-bottom: .3rem; cursor: text; }
.email-chip-input { border: 0; outline: none; background: transparent; flex: 1 1 auto; min-width: 160px; padding: .15rem 0; }
.email-chip-box .badge { font-weight: 500; }
.email-chip-box .btn-close { font-size: .55em; }

/* Buttons: a touch rounder than Bootstrap's stock corners, with a
   quick, deliberate hover transition instead of an instant color snap -
   small details that read as "designed" rather than left on defaults. */
.btn { border-radius: var(--bp-radius-sm); font-weight: 600; transition: box-shadow .15s ease, transform .1s ease; }
.btn-primary:hover, .btn-primary:focus { box-shadow: 0 6px 16px color-mix(in srgb, var(--bp-primary) 28%, transparent); }
.btn:active { transform: scale(.98); }

/* Bootstrap's stock pagination renders square-cornered, flat-bordered
   buttons - the one remaining stock-Bootstrap-looking control sitting
   next to this app's rounded/shadowed cards and inputs (both the manual
   Audit Log pager and DataTables' own bootstrap5-themed pager pick this
   up automatically, no markup changes needed anywhere). */
.pagination .page-link { border-radius: var(--bp-radius-sm) !important; margin-left: 4px; border-color: var(--bp-border); color: var(--bp-text); }
.pagination .page-item.active .page-link { background-color: var(--bp-primary); border-color: var(--bp-primary); }
.pagination .page-item.disabled .page-link { background-color: var(--bp-surface); border-color: var(--bp-border); }

/* A small rounded status dot, shared by the timeline board's and
   calendar's own legends (both still define their own .legend-swatch
   rule scoped to that page - this just gives the class its shared
   modern "dot" shape instead of each page separately deciding it). */
.legend-swatch { border-radius: 50% !important; }

/* Unified with the semantic status tokens above - previously these were
   flat, always-solid hex values with no dark-mode pairing at all (the
   one real inconsistency vs. every ad hoc `badge bg-{color}-subtle`
   status badge elsewhere, which already adapts to dark mode via
   Bootstrap's own subtle utilities). Solid backgrounds, not the subtle
   tint, since -status- badges are meant to read as slightly stronger/
   more final than an in-progress `-subtle` badge. */
.badge-status-active { background: var(--bp-success); }
.badge-status-disabled { background: var(--bp-neutral); }
.badge-status-locked { background: var(--bp-danger); }
.badge-status-pending { background: var(--bp-warning); }
.badge-status-expired { background: color-mix(in srgb, var(--bp-neutral) 60%, var(--bp-surface)); }

/* Small global polish - no markup changes needed anywhere, since every
   page already uses these Bootstrap classes as-is. */
.form-control:focus, .form-select:focus {
    border-color: var(--bp-primary);
    box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--bp-primary) 20%, transparent);
}
.alert { border: 1px solid var(--bp-border); border-left: 4px solid var(--bp-secondary); border-radius: var(--bp-radius-sm); }
.alert-success { border-left-color: var(--bp-success); }
.alert-warning { border-left-color: var(--bp-warning); }
.alert-danger { border-left-color: var(--bp-danger); }
.alert-info { border-left-color: var(--bp-info); }
.dropdown-menu { border-color: var(--bp-border); border-radius: var(--bp-radius-sm); box-shadow: var(--bp-shadow); }

.permission-matrix label { font-weight: 400; font-size: .85rem; }
.permission-module-title { font-weight: 600; font-size: .85rem; text-transform: uppercase; color: var(--bp-secondary); margin-top: 14px; }

/* ---------- Shared components (templates/components/) ---------- */
.empty-state { text-align: center; padding: 48px 24px; color: var(--bp-secondary); }
.empty-state-icon { font-size: 2.4rem; color: var(--bp-border); margin-bottom: 12px; }
.empty-state-title { font-weight: 700; font-size: 1.05rem; color: var(--bp-text); margin-bottom: 4px; }
.empty-state-body { font-size: .88rem; max-width: 420px; margin: 0 auto; }
.empty-state-action { margin-top: 16px; }

/* ---------- Notification bell + notification list ---------- */
.bp-bell-badge { position: absolute; top: -3px; right: -3px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 999px; background: #dc3545; color: #fff; font-size: .66rem; font-weight: 700; line-height: 17px; text-align: center; box-shadow: 0 0 0 2px var(--bp-surface); }
.bp-bell-panel { width: 380px; max-width: 92vw; border-radius: var(--bp-radius); overflow: hidden; box-shadow: var(--bp-shadow-lg); }
.bp-bell-head { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--bp-border); }
.bp-bell-list { max-height: 420px; overflow-y: auto; }
.bp-bell-empty { padding: 28px 16px; text-align: center; color: var(--bp-secondary); font-size: .9rem; }
.bp-bell-item { display: flex; gap: 12px; align-items: flex-start; padding: 12px 16px; text-decoration: none; color: var(--bp-text); border-bottom: 1px solid var(--bp-border); }
.bp-bell-item:hover { background: var(--bp-bg); color: var(--bp-text); }
.bp-bell-item.unread { background: color-mix(in srgb, var(--bp-primary) 6%, var(--bp-surface)); }
.bp-bell-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.bp-bell-title { font-weight: 600; font-size: .88rem; line-height: 1.3; }
.bp-bell-body { font-size: .8rem; color: var(--bp-secondary); line-height: 1.35; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.bp-bell-ago { font-size: .72rem; color: var(--bp-secondary); margin-top: 2px; }
.bp-bell-foot { display: block; text-align: center; padding: 11px; font-size: .86rem; font-weight: 600; text-decoration: none; border-top: 1px solid var(--bp-border); }
.bp-bell-foot:hover { background: var(--bp-bg); }
.bp-n-icon { flex: none; width: 34px; height: 34px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 1rem; }
.bp-n-info { background: color-mix(in srgb, var(--bp-primary) 14%, var(--bp-surface)); color: var(--bp-primary-text); }
.bp-n-success { background: color-mix(in srgb, #198754 16%, var(--bp-surface)); color: #198754; }
.bp-n-warning { background: color-mix(in srgb, #f59f00 20%, var(--bp-surface)); color: #b45309; }
.bp-n-danger { background: color-mix(in srgb, #dc3545 16%, var(--bp-surface)); color: #dc3545; }
.bp-n-dot { flex: none; width: 9px; height: 9px; margin-top: 6px; border-radius: 50%; background: var(--bp-primary); }
.bp-n-unread { background: color-mix(in srgb, var(--bp-primary) 5%, var(--bp-surface)); }
.bp-toast { position: fixed; right: 18px; bottom: 18px; z-index: 2000; display: flex; gap: 12px; align-items: flex-start; width: 340px; max-width: calc(100vw - 36px); padding: 14px 16px; background: var(--bp-surface); color: var(--bp-text); border: 1px solid var(--bp-border); border-radius: var(--bp-radius); box-shadow: var(--bp-shadow-lg); text-decoration: none; transform: translateY(20px); opacity: 0; transition: transform .25s, opacity .25s; }
.bp-toast.show { transform: none; opacity: 1; }
.bp-toast:hover { color: var(--bp-text); }

/* ---------- Avatars (photo / emoji / initials) ---------- */
.av-photo { padding: 0; overflow: hidden; background: color-mix(in srgb, var(--bp-secondary) 18%, transparent) !important; }
.av-photo img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }
.av-emoji, .av-color { background: linear-gradient(135deg, var(--av1, var(--bp-primary)), var(--av2, var(--av1, var(--bp-primary)))) !important; color: #fff !important; }
.av-emoji { font-size: 1.35em; line-height: 1; font-weight: 400; }
.avatar-circle.avatar-sm { width: 26px; height: 26px; font-size: .68rem; }
.avatar-circle.avatar-lg { width: 56px; height: 56px; font-size: 1.25rem; }
.avatar-circle.avatar-xl { width: 88px; height: 88px; font-size: 1.9rem; box-shadow: 0 6px 18px rgba(15, 23, 42, .18); }
.avatar-circle.avatar-xl.av-emoji { font-size: 3rem; }
.avatar-card-head { display: flex; gap: 16px; align-items: center; margin-bottom: 14px; }
.avatar-tabs { display: inline-flex; gap: 4px; padding: 4px; border-radius: 10px; background: color-mix(in srgb, var(--bp-secondary) 12%, transparent); margin-bottom: 14px; }
.avatar-tabs button { border: 0; background: none; padding: 6px 14px; border-radius: 7px; font: inherit; font-weight: 600; font-size: .85rem; color: var(--bp-secondary); cursor: pointer; }
.avatar-tabs button.is-active { background: var(--bp-surface); color: var(--bp-text); box-shadow: 0 1px 3px rgba(0, 0, 0, .12); }
.avatar-pane { display: grid; gap: 14px; justify-items: start; }
.avatar-pane[hidden] { display: none; }
.avatar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 8px; width: 100%; max-width: 560px; }
.avatar-opt input, .avatar-swatch input { position: absolute; opacity: 0; pointer-events: none; }
.avatar-opt { position: relative; cursor: pointer; display: grid; place-items: center; padding: 3px; border-radius: 50%; }
.avatar-opt .avatar-circle { width: 46px; height: 46px; font-size: 1.5rem; transition: transform .12s; }
.avatar-opt:hover .avatar-circle { transform: scale(1.08); }
.avatar-opt input:checked + .avatar-circle { box-shadow: 0 0 0 3px var(--bp-surface), 0 0 0 5px var(--bp-primary); }
.avatar-opt input:focus-visible + .avatar-circle, .avatar-swatch input:focus-visible + span { outline: 2px solid var(--bp-primary); outline-offset: 3px; }
.avatar-colors { display: flex; flex-wrap: wrap; gap: 8px; }
.avatar-swatch { position: relative; cursor: pointer; }
.avatar-swatch span { display: block; width: 26px; height: 26px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
.avatar-swatch input:checked + span { box-shadow: 0 0 0 2px var(--bp-surface), 0 0 0 4px var(--bp-text); }
.avatar-preview-row { display: flex; gap: 12px; align-items: center; }
.avatar-cropper { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.avatar-crop-stage { width: 200px; height: 200px; border-radius: 50%; overflow: hidden; box-shadow: 0 0 0 4px var(--bp-surface), 0 0 0 6px color-mix(in srgb, var(--bp-primary) 40%, transparent); background: #111; }
.avatar-crop-stage canvas { width: 200px; height: 200px; display: block; cursor: grab; touch-action: none; }
.avatar-crop-stage canvas:active { cursor: grabbing; }
.avatar-crop-controls { display: grid; gap: 8px; max-width: 360px; }
.avatar-zoom { display: flex; gap: 8px; align-items: center; font-size: .85rem; }
.avatar-zoom input { flex: 1; }


/* =====================================================================
   Design polish v4 - calmer neutrals, a clearer type scale, quieter tables,
   softer icon actions, a more confident sidebar. Everything reads the
   existing --bp-* tokens, so organization branding and dark mode still apply.
   ===================================================================== */
:root[data-bs-theme="light"] {
    --bp-bg: #f5f7fb;
    --bp-border: #e3e8f0;
    --bp-text: #1a2236;
    --bp-neutral: #64748b;
    --bp-neutral-bg: #eef2f7;
    --bp-shadow-sm: 0 1px 2px rgba(16, 24, 40, .04), 0 1px 3px rgba(16, 24, 40, .06);
    --bp-shadow: 0 6px 18px rgba(16, 24, 40, .08);
}

body.app-body, body.auth-body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
h1, h2, h3, h4, h5, h6 { letter-spacing: -.015em; }
.page-header h1 { font-size: 1.7rem; font-weight: 750; color: var(--bp-text); }
.page-header .text-secondary { font-size: .9rem; }
.breadcrumb { --bs-breadcrumb-divider-color: var(--bp-neutral); }
.breadcrumb-item a { text-decoration: none; font-weight: 500; }
.breadcrumb-item a:hover { text-decoration: underline; }
.text-secondary { color: var(--bp-neutral) !important; }

/* ---------- Header: glassy, with a hairline instead of a hard border ---------- */
.app-header {
    background: color-mix(in srgb, var(--bp-surface) 90%, transparent);
    -webkit-backdrop-filter: saturate(1.5) blur(10px); backdrop-filter: saturate(1.5) blur(10px);
    box-shadow: 0 1px 0 var(--bp-border), 0 6px 20px -12px rgba(16, 24, 40, .14);
    border-bottom: 0;
}
.app-search input { border-radius: 999px; padding-left: 2.4rem; background: color-mix(in srgb, var(--bp-neutral) 8%, var(--bp-surface)); border-color: transparent; transition: border-color .15s, box-shadow .15s, background .15s; }
.app-search input:hover, .app-search input:focus { background: var(--bp-surface); border-color: color-mix(in srgb, var(--bp-primary) 35%, var(--bp-border)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--bp-primary) 12%, transparent); }

/* ---------- Sidebar: roomier items, a lit-up active pill, readable section labels ---------- */
.app-sidebar { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .2) transparent; }
.app-sidebar::-webkit-scrollbar { width: 6px; }
.app-sidebar::-webkit-scrollbar-thumb { background: var(--bp-sb-scroll, rgba(255, 255, 255, .18)); border-radius: 6px; }
.app-sidebar .nav-link { border-radius: var(--bp-radius-input); padding: 8px 12px; margin-bottom: 2px; transition: background .15s, color .15s, box-shadow .15s; }
.app-sidebar .nav-link.active {
    background: linear-gradient(135deg, var(--bp-accent, var(--bp-primary)), color-mix(in srgb, var(--bp-accent, var(--bp-primary)) 78%, #fff));
    box-shadow: 0 6px 16px -4px color-mix(in srgb, var(--bp-accent, var(--bp-primary)) 55%, transparent), inset 0 1px 0 rgba(255, 255, 255, .18);
}
.nav-section-title { color: var(--bp-sb-muted, #8fa3c8); letter-spacing: .09em; }
.nav-subtitle { color: var(--bp-sb-subtle, #6f85ad); }
.app-sidebar .nav-group-body { border-left-color: var(--bp-sb-border, rgba(255, 255, 255, .14)); }

/* ---------- Cards ---------- */
.card { border-color: var(--bp-border); }
.card-header { background: transparent; border-bottom: 1px solid var(--bp-border); padding: .85rem 1.1rem; }
.card-header.bg-transparent, .card-header.bg-white { background: transparent !important; }
.card-body { padding: 1.15rem; }
.card.border-0 { border: 1px solid var(--bp-border) !important; }
.alert { border-radius: var(--bp-radius-sm); }

/* ---------- Tables: quiet header, comfortable rows, a hover wash ---------- */
.table { --bs-table-bg: transparent; --bs-table-hover-bg: color-mix(in srgb, var(--bp-primary) 5%, var(--bp-surface)); --bs-table-border-color: color-mix(in srgb, var(--bp-border) 80%, transparent); margin-bottom: 0; }
.table > thead > tr > th, .table > thead th {
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--bp-neutral);
    background: color-mix(in srgb, var(--bp-neutral) 6%, var(--bp-surface)); border-bottom: 1px solid var(--bp-border);
    padding: .7rem .9rem; white-space: nowrap;
}
.table > tbody > tr > td { padding: .8rem .9rem; vertical-align: middle; }
.table td.text-end, .table th.text-end { white-space: nowrap; }
.table-responsive { border-radius: inherit; }
.card > .table-responsive:first-child > .table > thead th:first-child, .card-body > .table-responsive > .table > thead th:first-child { border-top-left-radius: 8px; }
.card > .table-responsive:first-child > .table > thead th:last-child, .card-body > .table-responsive > .table > thead th:last-child { border-top-right-radius: 8px; }

/* Icon-only row actions: soft ghost buttons that tint on hover, never wrapping onto a second line. */
.table td .btn-sm:has(> i:only-child) {
    width: 32px; height: 32px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
    border-color: transparent; border-radius: 9px; background: transparent; box-shadow: none; --bs-btn-hover-border-color: transparent;
}
.table td .btn-outline-primary:has(> i:only-child) { color: var(--bp-primary-text); }
.table td .btn-outline-primary:has(> i:only-child):hover { background: color-mix(in srgb, var(--bp-primary) 13%, transparent); color: var(--bp-primary-text); }
.table td .btn-outline-secondary:has(> i:only-child) { color: var(--bp-neutral); }
.table td .btn-outline-secondary:has(> i:only-child):hover { background: var(--bp-neutral-bg); color: var(--bp-text); }
.table td .btn-outline-info:has(> i:only-child) { color: #0a8ca8; }
.table td .btn-outline-info:has(> i:only-child):hover { background: color-mix(in srgb, #0dcaf0 16%, transparent); color: #0a8ca8; }
.table td .btn-outline-danger:has(> i:only-child) { color: var(--bp-danger); }
.table td .btn-outline-danger:has(> i:only-child):hover { background: color-mix(in srgb, var(--bp-danger) 12%, transparent); color: var(--bp-danger); }
.table td .btn-outline-success:has(> i:only-child) { color: var(--bp-success); }
.table td .btn-outline-success:has(> i:only-child):hover { background: color-mix(in srgb, var(--bp-success) 12%, transparent); color: var(--bp-success); }
.table td .btn-outline-warning:has(> i:only-child) { color: #b45309; }
.table td .btn-outline-warning:has(> i:only-child):hover { background: color-mix(in srgb, #f59f00 16%, transparent); }
.table td.text-end > form { display: inline-block; vertical-align: middle; margin: 0; }

/* ---------- Buttons ---------- */
.btn { letter-spacing: -.005em; }
.btn-primary { box-shadow: 0 1px 2px rgba(16, 24, 40, .14), inset 0 1px 0 rgba(255, 255, 255, .16); }
.btn-primary:hover, .btn-primary:focus { box-shadow: 0 8px 18px -6px color-mix(in srgb, var(--bp-primary) 60%, transparent), inset 0 1px 0 rgba(255, 255, 255, .16); }
.btn-outline-secondary { border-color: var(--bp-border); color: var(--bp-text); background: var(--bp-surface); }
.btn-outline-secondary:hover { background: var(--bp-neutral-bg); border-color: color-mix(in srgb, var(--bp-neutral) 35%, var(--bp-border)); color: var(--bp-text); }

/* ---------- Forms ---------- */
.form-label { font-weight: 600; font-size: .82rem; color: var(--bp-text); margin-bottom: .35rem; }
.form-control:not(.form-control-sm), .form-select:not(.form-select-sm) { border-radius: var(--bp-radius-input); padding-top: .55rem; padding-bottom: .55rem; border-color: color-mix(in srgb, var(--bp-neutral) 28%, var(--bp-border)); }
.form-control-sm, .form-select-sm { border-radius: var(--bp-radius-sm); }
.form-text { color: var(--bp-neutral); }
.form-check-input:checked { background-color: var(--bp-primary); border-color: var(--bp-primary); }

/* ---------- Badges ---------- */
.badge { font-weight: 600; letter-spacing: .01em; border-radius: 999px; padding: .38em .72em; }

/* ---------- Dropdowns, modals, tooltips ---------- */
.dropdown-menu { border-radius: var(--bp-radius-menu); padding: 6px; box-shadow: var(--bp-shadow-lg); }
.dropdown-item { border-radius: var(--bp-radius-sm); padding: .45rem .7rem; }
.modal-content { border-radius: var(--bp-radius-modal); border: 1px solid var(--bp-border); box-shadow: var(--bp-shadow-lg); }
.modal-header, .modal-footer { border-color: var(--bp-border); }

/* ---------- Thin, tidy scrollbars in scrollable panels ---------- */
.table-responsive, .timeline-scroll, .bp-bell-list { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--bp-neutral) 40%, transparent) transparent; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* Dark mode: lift the muted text tone so table headers, captions and hints stay readable. */
:root[data-bs-theme="dark"] { --bp-neutral: #9aa5b4; --bp-neutral-bg: #272d34; }

/* Continuity with the Workforce Hub Console: the brand mark follows the theme, and every page has a faint glow of the theme colour. */
.bp-logo { flex: none; }
body.app-body {
    background-image:
        radial-gradient(900px 380px at 88% -120px, color-mix(in srgb, var(--bp-primary) 10%, transparent), transparent 72%),
        radial-gradient(700px 320px at 0% 100%, color-mix(in srgb, var(--bp-primary) 5%, transparent), transparent 70%);
    background-attachment: fixed;
}

/* Dark-mode / bright-accent contrast fixes (found by an automated contrast audit): a label sitting on the accent colour uses the readable
   "on" colour the theme computed, grey outline buttons and the neutral badge are legible on the dark surface. */
[data-bs-theme="dark"] .btn-outline-secondary { --bs-btn-color: #b8c0ca; --bs-btn-hover-color: #fff; }
[data-bs-theme="dark"] .badge-status-disabled { color: #15181c; }
#calendar .fc-button-primary:not(:disabled).fc-button-active,
#calendar .fc-button-primary:not(:disabled):active { color: var(--bp-on-primary, #fff) !important; }
#calendar .fc-day-today .fc-daygrid-day-number { color: var(--bp-on-primary, #fff) !important; }

/* cards ease in as they scroll into view (added by the script below; nothing is hidden if it does not run) */
.rv{opacity:0;transform:translateY(18px) scale(.985)}
.rv.rv-in{opacity:1;transform:none;transition:opacity .5s ease,transform .55s cubic-bezier(.2,.7,.2,1),border-color .12s ease,box-shadow .12s ease}
@media (prefers-reduced-motion:reduce),print{.rv{opacity:1;transform:none;transition:none}}
