:root {
    --brand: #4f46e5;
    --brand-dark: #4338ca;
    --brand-soft: #eef0ff;
    /* Deliberately their own fixed variables, never overridden by the
       Branding accent-color setting — the active sidebar/nav highlight and
       primary buttons always stay this default blue regardless of what
       accent color is chosen. */
    --sidebar-active-bg: #4f46e5;
    --btn-primary-bg: #4f46e5;
    /* Same idea, for anywhere the accent color is used as literal text (or a
       flat background) rather than blended into a gradient — an accent color
       someone picks (e.g. white) could otherwise render invisible against its
       own background (white-on-white). Only the two gradient spots below
       (sidebar logo fallback, avatar) keep the real accent, because they're
       always mixed with a second fixed color and can't fully wash out. */
    --accent-safe: #4f46e5;
    --bg: #f5f6fb;
    --card-bg: #ffffff;
    --border: #e7e9f2;
    --text-muted: #6b7280;
    --sidebar-bg: #14162a;
    --sidebar-bg-alt: #1b1e38;
    --sidebar-text: #b6b9d6;
    --sidebar-text-active: #ffffff;
    --sidebar-border: rgba(255, 255, 255, .07);
    --success: #16a34a;
}

* { -webkit-tap-highlight-color: transparent; }

/* Skip-to-content link (WCAG 2.4.1 / EN 301 549) — invisible until focused via keyboard. */
.skip-link {
    position: fixed;
    top: .5rem;
    left: .5rem;
    z-index: 2000;
    background: var(--accent-safe);
    color: #fff;
    padding: .6rem 1rem;
    border-radius: 8px;
    text-decoration: none;
    font-weight: 600;
}

body {
    background: var(--bg);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: #1f2430;
}

/* ============ App shell: sidebar + header + content ============ */
.app-shell {
    display: flex;
    min-height: 100vh;
    align-items: stretch;
}

/*
 * The sidebar is a plain Bootstrap Offcanvas (NOT the "-lg" responsive
 * variant — that class hides the whole header at >=992px and forces the
 * background transparent via !important, which fights a custom dark
 * sidebar). Instead: let it behave as Bootstrap's normal off-screen mobile
 * drawer by default, and force it into a static, always-visible column
 * ourselves at the desktop breakpoint below. Width/background are set via
 * Bootstrap's own --bs-offcanvas-* custom properties so its built-in rules
 * (which read those variables) pick up our values with no specificity fight.
 */
.app-sidebar {
    --bs-offcanvas-width: 260px;
    --bs-offcanvas-bg: var(--sidebar-bg);
    --bs-offcanvas-color: var(--sidebar-text);
    --bs-offcanvas-border-color: var(--sidebar-border);
    display: flex;
    flex-direction: column;
}
@media (min-width: 992px) {
    .app-sidebar {
        position: sticky !important;
        top: 0;
        left: auto;
        height: 100vh;
        max-height: 100vh;
        flex: 0 0 260px;
        transform: none !important;
        visibility: visible !important;
        box-shadow: none;
    }
    .app-sidebar .offcanvas-header .btn-close {
        display: none;
    }
}

.sidebar-brand-row {
    padding: 1.25rem 1.1rem;
    border-bottom: 1px solid var(--sidebar-border);
}
.sidebar-brand {
    display: flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    color: #fff;
    font-weight: 600;
    font-size: 1.02rem;
}
.sidebar-brand-icon {
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: linear-gradient(135deg, var(--brand), #7c6cf0);
    color: #fff;
    font-size: 1rem;
    flex: none;
}

.sidebar-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: 1rem .75rem;
    overflow-y: auto;
}
.sidebar-nav { display: flex; flex-direction: column; gap: .15rem; flex: 1 1 auto; }
.sidebar-section-label {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: rgba(255, 255, 255, .35);
    padding: .9rem .75rem .35rem;
}
.sidebar-link {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .55rem .75rem;
    border-radius: 10px;
    color: var(--sidebar-text);
    text-decoration: none;
    font-size: .92rem;
    font-weight: 500;
    transition: background-color .12s ease, color .12s ease;
}
.sidebar-link i { font-size: 1.05rem; width: 1.2rem; text-align: center; flex: none; }
.sidebar-link:hover { background: rgba(255, 255, 255, .06); color: #fff; }
.sidebar-link.active {
    background: var(--sidebar-active-bg);
    color: #fff;
    box-shadow: 0 4px 14px rgba(79, 70, 229, .35);
}
.sidebar-footer {
    border-top: 1px solid var(--sidebar-border);
    padding-top: .75rem;
    margin-top: .75rem;
}

/* ============ Content area + header ============ */
.app-content {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.app-header {
    height: 62px;
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: 0 1rem;
    background: var(--card-bg);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 1020;
}
.header-icon-btn {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    color: #444b5a;
    font-size: 1.15rem;
    border: 1px solid transparent;
}
.header-icon-btn:hover { background: var(--bg); border-color: var(--border); }
.header-mobile-brand {
    display: flex;
    align-items: center;
    gap: .4rem;
    text-decoration: none;
    color: #1f2430;
    font-weight: 600;
}
.header-actions { display: flex; align-items: center; gap: .4rem; }
.header-dropdown .dropdown-toggle::after { display: none; }
.header-badge {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: #e0567b;
    color: #fff;
    font-size: .65rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    border: 2px solid var(--card-bg);
}
.header-user-btn {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .3rem .6rem .3rem .3rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: #fff;
    font-size: .88rem;
    font-weight: 500;
    color: #1f2430;
}
.header-user-btn:hover { background: var(--bg); }
.header-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--brand), #7c6cf0);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: .85rem;
    flex: none;
}

.header-dropdown-menu {
    min-width: 300px;
    padding: .6rem;
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 16px 40px rgba(16, 24, 40, .12);
}
.header-dropdown-title {
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
    padding: .3rem .5rem .5rem;
}
.header-dropdown-empty {
    padding: .5rem;
    color: var(--text-muted);
    font-size: .85rem;
}
.header-activity-item {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .5rem .5rem;
    border-radius: 10px;
}
.header-activity-item:hover { background: var(--bg); }
.activity-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--success);
    flex: none;
    box-shadow: 0 0 0 rgba(22, 163, 74, .5);
    animation: pulse-dot 2s infinite;
}
@keyframes pulse-dot {
    0% { box-shadow: 0 0 0 0 rgba(22, 163, 74, .45); }
    70% { box-shadow: 0 0 0 6px rgba(22, 163, 74, 0); }
    100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}
.activity-info { display: flex; flex-direction: column; line-height: 1.25; }
.activity-name { font-weight: 600; font-size: .85rem; }
.activity-timer {
    font-variant-numeric: tabular-nums;
    font-size: .78rem;
    color: var(--text-muted);
}
.header-dropdown-link {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem;
    border-radius: 10px;
    color: var(--brand-dark);
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
}
.header-dropdown-link:hover { background: var(--brand-soft); }

/* Sticky footer, pure flexbox — the footer link bar (Privacy/Accessibility)
   sits pinned to the bottom of the viewport when a page's content is short,
   but is pushed down naturally with the rest of the page (never overlapping
   it) once content is tall enough to scroll. No position:fixed anywhere —
   that would risk covering content on a long page, which is exactly the
   "data invisibility" this avoids. .app-main-content is the one growing
   flex item; .app-footer-links takes only its own height and lands right
   after it, so it's flush to the bottom precisely when there's nothing
   else below it. */
.app-main {
    padding: 1.5rem;
    width: 100%;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}
.app-main-content { flex: 1 1 auto; }
.app-footer-links { flex: none; }

/* Fixed-height wrapper for a responsive Chart.js canvas (maintainAspectRatio:
   false in its config) — without this, a chart's height is derived from its
   container's WIDTH, so once the main content area went full-width (no more
   max-width cap), a full-width chart card grew tall along with it. This
   pins the visual size to something sensible regardless of screen width.
   Every pie/doughnut chart in the app uses the same base size (.dashboard-
   chart-box) deliberately, for visual consistency — only the "hero" trend
   line chart on Reports gets the taller -lg variant. */
.dashboard-chart-box { position: relative; width: 100%; height: 270px; overflow: hidden; }
.dashboard-chart-box-lg { height: 280px; }

/* Standalone live timer (e.g. member dashboard clock-in card) */
.live-timer {
    font-variant-numeric: tabular-nums;
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--accent-safe);
    letter-spacing: .02em;
}

/* Value-rating radio button group — options + colors are admin-defined
   (App\Models\ValueRating), so each label carries its color as --vr-color
   inline rather than a fixed set of Bootstrap outline-* classes; picking
   one fills it solid via the :checked sibling selector below. */
.value-rating-group .btn { font-size: .85rem; }
.value-rating-group .btn i { margin-right: .25rem; }
.value-rating-group .btn-value-rating {
    background: transparent;
    border: 1px solid var(--vr-color, #898781);
    color: var(--vr-color, #898781);
}
.value-rating-group .btn-check:checked + .btn-value-rating {
    background: var(--vr-color, #898781);
    color: #fff;
}
.value-rating-group .btn-check:focus-visible + .btn-value-rating {
    outline: 2px solid var(--vr-color, #898781);
    outline-offset: 1px;
}

/* Admin dashboard "Awaiting approval" queue — each item (name/date, work
   description, rating buttons, approve/reject) is tall enough that letting
   the list grow unbounded quickly outgrows the chart card beside it.
   Capped to roughly 3 items' worth of height with its own scrollbar past
   that, so the card's height stays constant regardless of queue size. */
.approval-queue {
    max-height: 440px;
    overflow-y: auto;
    scrollbar-gutter: stable;
}

/* Reports: value breakdown legend swatch */
.value-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: none;
}

/* ============ Toast notifications (system messages) ============ */
/* Fixed overlay — appearing/disappearing never shifts page content. */
.toast-stack {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1080;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    width: min(380px, calc(100vw - 2rem));
    pointer-events: none;
}
.toast-notification {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent-safe);
    border-radius: 12px;
    box-shadow: 0 16px 36px rgba(16, 24, 40, .14);
    padding: .85rem 1rem;
    pointer-events: auto;
    animation: toast-in .25s cubic-bezier(.2, .8, .2, 1);
}
.toast-notification.hiding {
    animation: toast-out .2s ease-in forwards;
}
.toast-success { border-left-color: var(--success); }
.toast-danger { border-left-color: #e0567b; }
.toast-info { border-left-color: #2fa1e8; }
.toast-icon { margin-top: .15rem; flex: none; }
.toast-success .toast-icon { color: var(--success); }
.toast-danger .toast-icon { color: #e0567b; }
.toast-info .toast-icon { color: #2fa1e8; }
.toast-message { flex: 1 1 auto; font-size: .88rem; line-height: 1.4; color: #1f2430; }
.toast-close {
    flex: none;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: 1.1rem;
    line-height: 1;
    padding: 0 0 0 .25rem;
    cursor: pointer;
}
.toast-close:hover { color: #1f2430; }
@keyframes toast-in {
    from { opacity: 0; transform: translateY(-8px) translateX(6px); }
    to { opacity: 1; transform: translateY(0) translateX(0); }
}
@keyframes toast-out {
    to { opacity: 0; transform: translateX(16px); }
}
@media (max-width: 575.98px) {
    .toast-stack { left: 1rem; right: 1rem; width: auto; }
}

/* ============ Task quick-complete circle ============ */
.task-check {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2px solid var(--border);
    background: transparent;
    flex: none;
    padding: 0;
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease;
}
.task-check:hover {
    border-color: var(--success);
    background: rgba(22, 163, 74, .12);
}

/* ============ Assignee checklist (push task to multiple members) ============ */
.assignee-checklist {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: .35rem;
}
.assignee-option {
    display: flex;
    align-items: center;
    gap: .4rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: .4rem .85rem;
    font-size: .85rem;
    cursor: pointer;
    background: var(--card-bg);
    transition: border-color .12s ease, background-color .12s ease;
}
.assignee-option:has(input:checked) {
    border-color: var(--accent-safe);
    background: var(--brand-soft);
    font-weight: 600;
}
.assignee-option input { margin: 0; }

/* ============ Cards / stats ============ */
.card {
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
}
.card-header {
    background: transparent;
    border-bottom: 1px solid var(--border);
    font-weight: 600;
}

.stat-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.1rem 1.25rem;
    height: 100%;
}
.stat-value { font-size: 1.6rem; font-weight: 700; color: var(--accent-safe); line-height: 1.1; }
.stat-label { color: var(--text-muted); font-size: .85rem; margin-top: .25rem; }

/* Admin dashboard stat-card icon badges — one per stat, colored by theme
   rather than all sharing the brand color, so the row reads at a glance
   instead of as four identical numbers. */
.stat-icon {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    color: #fff;
    flex: none;
}
/* --accent-safe, not --brand — an org can set its own accent color to
   anything in Branding (including near-white), and this icon must stay
   visible regardless of that choice. Same fixed variable .skip-link and
   .stat-value already use for exactly this reason. */
.stat-icon-indigo { background: var(--accent-safe); }
.stat-icon-blue { background: #2a78d6; }
.stat-icon-teal { background: #1c8577; }
.stat-icon-amber { background: #b3661b; }
.stat-icon-gray { background: #6c7684; }

/* "vs last week" indicator on the Logged this week stat */
.stat-trend { font-size: .75rem; font-weight: 600; margin-left: .35rem; white-space: nowrap; }
.stat-trend-up { color: #0a8a3f; }
.stat-trend-down { color: #c8372f; }

/* ============ Buttons / forms ============ */
.btn-primary { background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); }
.btn-primary:hover, .btn-primary:focus { background: var(--brand-dark); border-color: var(--brand-dark); }
.btn { border-radius: 10px; }
.form-control, .form-select { border-radius: 10px; }

/* ============ Modals (pop-up forms) — always solid, never see-through ============ */
.modal-content {
    background-color: #fff;
    opacity: 1;
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: 0 20px 50px rgba(16, 24, 40, .18);
}
.modal-header, .modal-footer {
    background-color: transparent; /* shows through to the solid white .modal-content above, not the page behind it */
    border-color: var(--border);
}
.modal-backdrop.show { opacity: .5; }

/* ============ Guest / public-page background (privacy, accessibility — NOT the auth forms below) ============ */
.guest-body { background: linear-gradient(160deg, #eef1ff 0%, var(--bg) 60%); }

/*
 * ============ Auth forms (login / forgot-password / reset-password / 2FA) ============
 * Split panel on desktop: a fixed dark brand panel (deliberately NOT tied to
 * --brand — see the app.css note further down about --btn-primary-bg/
 * --sidebar-active-bg — a login screen should look sharp regardless of
 * whatever accent color is picked) alongside a plain white form panel.
 * Collapses to a short header band + an overlapping card below 992px.
 */
.auth-body { background: #f3f4fb; }
.auth-shell { min-height: 100vh; display: flex; }

.auth-brand-panel {
    flex: 0 0 42%;
    max-width: 560px;
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 3rem 3rem 2rem;
    color: #fff;
    overflow: hidden;
    background:
        radial-gradient(120% 140% at 15% 0%, rgba(124, 108, 240, .55) 0%, transparent 55%),
        radial-gradient(130% 120% at 100% 100%, rgba(56, 70, 160, .6) 0%, transparent 60%),
        linear-gradient(155deg, #12142c 0%, #1b1f45 45%, #2a2f6e 100%);
}
.auth-brand-panel::before {
    /* Faint diagonal facets for texture — CSS-only, no image asset. */
    content: "";
    position: absolute;
    inset: -20% -10%;
    background:
        repeating-linear-gradient(115deg, rgba(255, 255, 255, .05) 0 2px, transparent 2px 64px),
        repeating-linear-gradient(25deg, rgba(255, 255, 255, .04) 0 1px, transparent 1px 90px);
    pointer-events: none;
}
.auth-brand-panel-inner { position: relative; z-index: 1; flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
.auth-logo { display: flex; align-items: center; gap: .7rem; margin-bottom: 2.5rem; }
.auth-logo-icon {
    width: 42px;
    height: 42px;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: rgba(255, 255, 255, .12);
    font-size: 1.3rem;
}
.auth-logo-mark { max-width: 42px; max-height: 42px; object-fit: contain; }
.auth-logo-text { font-size: 1.15rem; font-weight: 700; letter-spacing: .01em; }
.auth-brand-copy h2 { font-size: 1.7rem; font-weight: 700; margin-bottom: .75rem; line-height: 1.25; }
.auth-brand-copy p { color: rgba(255, 255, 255, .78); font-size: .98rem; line-height: 1.6; max-width: 34ch; }
.auth-brand-footer { position: relative; z-index: 1; color: rgba(255, 255, 255, .55); font-size: .82rem; }

.auth-form-panel {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    padding: 2rem 1.5rem;
}
.auth-form-wrap { width: 100%; max-width: 400px; }
.auth-form-header { margin-bottom: 1.75rem; }
.auth-form-header h1 { font-size: 1.6rem; font-weight: 700; margin-bottom: .4rem; }
.auth-form-header p { color: var(--text-muted); font-size: .92rem; margin-bottom: 0; }

@media (max-width: 991.98px) {
    .auth-shell { flex-direction: column; }
    .auth-brand-panel {
        flex: none;
        max-width: none;
        min-height: 200px;
        padding: 2rem 1.5rem 3.5rem;
    }
    .auth-brand-panel-inner { flex: none; }
    .auth-brand-copy { display: none; } /* keeps the mobile header compact — logo + tagline only */
    .auth-logo { margin-bottom: 0; }
    .auth-brand-footer { display: none; }
    .auth-form-panel {
        flex: none;
        margin-top: -2.5rem;
        padding: 0 1.25rem 2.5rem;
        background: transparent;
        position: relative;
        z-index: 2;
    }
    .auth-form-wrap {
        background: var(--card-bg);
        border-radius: 20px 20px 16px 16px;
        box-shadow: 0 16px 40px rgba(16, 24, 40, .16);
        padding: 1.75rem 1.5rem;
    }
}
@media (max-width: 575.98px) {
    .auth-brand-panel { min-height: 160px; padding: 1.5rem 1.25rem 3rem; }
}

/* ============ Public informational pages (privacy, accessibility) ============ */
.public-header {
    padding: 1.25rem 1.5rem;
    background: var(--card-bg);
    border-bottom: 1px solid var(--border);
}
.public-page {
    max-width: 780px;
    margin: 0 auto;
    padding: 2rem 1.25rem 3rem;
}
.public-page-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 2rem;
    line-height: 1.65;
}
.public-page-card h1 { margin-bottom: .25rem; }
.public-page-card h2 { margin-top: 1.75rem; font-size: 1.15rem; }
.public-page-card table { margin: 1rem 0; }
.public-footer {
    max-width: 780px;
    margin: 0 auto;
    padding: 0 1.25rem 3rem;
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
    font-size: .9rem;
}

/* ============ Mobile tweaks ============ */
@media (max-width: 991.98px) {
    .app-sidebar { width: 270px; }
}
@media (max-width: 767.98px) {
    .app-main { padding: 1rem 1rem 3rem; }
    .table td, .table th { white-space: nowrap; }
    .btn { min-height: 38px; }
    .stat-value { font-size: 1.35rem; }
    .header-dropdown-menu { min-width: 86vw; }
}
