/* ─────────────────────────────────────────────
   Rishs International School — Design Tokens
   All colours as CSS custom properties.
   Dark mode = one override block, zero component changes.
   ───────────────────────────────────────────── */

:root {
    /* Brand */
    --color-primary:          #1E3A8A;
    --color-primary-light:    #2563EB;
    --color-primary-dark:     #1a3d6e;
    --color-primary-bg:       #f0f4ff;
    --color-accent:           #2563EB;

    /* Semantic */
    --color-success:          #16A34A;
    --color-success-bg:       #F0FDF4;
    --color-warning:          #F59E0B;
    --color-warning-bg:       #FFFBEB;
    --color-danger:           #DC2626;
    --color-danger-bg:        #FEF2F2;
    --color-info:             #2563EB;
    --color-info-bg:          #EFF6FF;

    /* Surfaces */
    --color-bg:               #F8FAFC;
    --color-surface:          #FFFFFF;
    --color-surface-raised:   #FFFFFF;
    --color-border:           #E2E8F0;
    --color-border-light:     #F1F5F9;
    --color-border-subtle:    rgba(0,0,0,0.04);

    /* Text */
    --color-text:             #0F172A;
    --color-text-secondary:   #64748B;
    --color-text-muted:       #94A3B8;
    --color-text-inverse:     #FFFFFF;

    /* Charts — semantic mapping that should be the same in every chart on
       the dashboard. Collected = green, pending/missing = neutral grey,
       attention = amber, danger = red, trend line = sky. Kept independent
       of brand --color-primary so the dark navy doesn't dominate small
       donuts and gauges. */
    --chart-collected:        #15803d;
    --chart-pending:          #cbd5e1;
    --chart-paid:             #1d4ed8;
    --chart-unpaid:           #fbbf24;
    --chart-trend:            #0ea5e9;
    --chart-grid:             #f1f5f9;

    /* Sidebar */
    --color-sidebar-bg:       #FFFFFF;
    --color-sidebar-active:   var(--color-primary);
    --color-sidebar-active-bg: var(--color-primary-bg);
    --color-sidebar-active-text: var(--color-primary);
    --color-sidebar-hover:    #F1F5F9;

    /* Nav */
    --nav-height:             3.5rem;
    --sidebar-width:          15rem;

    /* Card */
    --card-radius:            20px;
    --card-radius-sm:         16px;
    --card-border:            var(--color-border-subtle);
    --card-shadow:            0 1px 2px rgba(15,23,42,0.04), 0 8px 24px rgba(15,23,42,0.04);
    --card-shadow-sm:         0 4px 12px rgba(0,0,0,0.03);

    /* Buttons */
    --btn-radius:             12px;
    --input-radius:           12px;

    /* Shadows */
    --shadow-dropdown:        0 4px 12px rgba(0,0,0,0.10);
    --shadow-btn-primary:     0 4px 14px rgba(30, 58, 138, 0.25);

    /* Transitions */
    --transition-fast:        150ms ease;
    --transition-base:        200ms ease;

    /* Gradient (login page) */
    --gradient-brand:         linear-gradient(160deg, #0f2b4a 0%, #1a47a8 60%, #2563eb 100%);
}

/* ── Future dark mode ── */
/* [data-theme="dark"] { ... } */

/* ── Base resets (unlayered — always applies) ── */
[x-cloak] { display: none !important; }

body {
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Tailwind's preflight resets the native pointer cursor on <button>. Restore
   it globally so bare buttons (Waive / Cancel / row actions) feel clickable
   without each one needing `cursor-pointer` or `.btn`. Disabled buttons get
   the not-allowed cursor instead. */
button:not(:disabled), [role="button"]:not(:disabled) { cursor: pointer; }
button:disabled, [role="button"][aria-disabled="true"] { cursor: not-allowed; }

/* ── Component styles ──
   Wrapped in @layer components so Tailwind utilities (pl-9, py-2, etc.)
   can override them. Layer priority: base < components < utilities. */
@layer components {

/* ── Card components ── */
.card {
    background: var(--color-surface);
    border-radius: var(--card-radius);
    border: 1px solid transparent;
    box-shadow: var(--card-shadow);
}

.card-sm {
    background: var(--color-surface);
    border-radius: var(--card-radius-sm);
    border: 1px solid transparent;
    box-shadow: var(--card-shadow-sm);
}

/* ── Section labels ── */
.section-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
}

/* ── Stat chip ── a compact "label · value · count" pill for summary
   breakdowns (e.g. collection report "by mode / by source"). Clear hierarchy:
   muted label, prominent value, count set off by a hairline divider. */
.stat-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    font-size: 12px;
    line-height: 1.1;
    padding: 5px 11px;
    border-radius: 999px;
    background: var(--color-surface-alt, #f1f5f9);
    border: 1px solid var(--color-border, #e2e8f0);
    white-space: nowrap;
}
.stat-chip__label {
    color: var(--color-text-muted);
}
.stat-chip__value {
    font-weight: 600;
    color: var(--color-text);
}
.stat-chip__count {
    color: var(--color-text-muted);
    font-size: 11px;
    padding-left: 7px;
    border-left: 1px solid var(--color-border, #e2e8f0);
}

/* ── Status badges ── */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 500;
    padding: 2px 10px;
    border-radius: 6px;
}
.badge-success { background: var(--color-success-bg); color: var(--color-success); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-danger  { background: var(--color-danger-bg);  color: var(--color-danger); }
.badge-info    { background: var(--color-info-bg);    color: var(--color-info); }

/* ── Status dots ── */
.dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    display: inline-block;
}
.dot-success { background: var(--color-success); }
.dot-warning { background: var(--color-warning); }
.dot-danger  { background: var(--color-danger); }

/* ── Empty state ──
   Centered icon-in-circle + title + body. Use inside any container (card,
   table cell, full-page). Compose with a tone modifier on the inner icon
   wrapper. Page-level usage:
     <div class="empty-state">
       <div class="empty-state__icon empty-state__icon--success"><i class="ph ph-check-circle"></i></div>
       <p class="empty-state__title">All caught up</p>
       <p class="empty-state__body">Optional supporting sentence.</p>
     </div>
   For empty rows inside a table, add `empty-state--compact` to halve the padding. */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 2.5rem 1rem;
    text-align: center;
}
.empty-state--compact { padding: 1.5rem 1rem; }
.empty-state__icon {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-bg-alt);
}
.empty-state__icon i { font-size: 1.75rem; color: var(--color-text-muted); }
.empty-state__icon--success { background: var(--color-success-bg); }
.empty-state__icon--success i { color: var(--color-success); }
.empty-state__icon--info { background: var(--color-info-bg); }
.empty-state__icon--info i { color: var(--color-primary); }
.empty-state__icon--warning { background: var(--color-warning-bg); }
.empty-state__icon--warning i { color: var(--color-warning); }
.empty-state__title { font-size: 0.875rem; font-weight: 500; color: var(--color-text); margin: 0; }
.empty-state__body { font-size: 0.75rem; color: var(--color-text-muted); margin: 0; max-width: 28rem; line-height: 1.5; }
.empty-state__body a { color: var(--color-primary); text-decoration: underline; }

/* ── Buttons ── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 20px;
    border-radius: var(--btn-radius);
    font-size: 14px;
    font-weight: 500;
    transition: all var(--transition-base);
    cursor: pointer;
    border: none;
    outline: none;
    min-height: 44px;
}

.btn-primary {
    background: linear-gradient(135deg, var(--color-primary-light) 0%, var(--color-primary) 100%);
    color: var(--color-text-inverse);
    box-shadow: var(--shadow-btn-primary);
    border: none;
}
.btn-primary:hover {
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
}
.btn-primary:disabled {
    opacity: 0.7;
    cursor: not-allowed;
}

.btn-secondary {
    background: transparent;
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border);
}
.btn-secondary:hover {
    background: var(--color-border-light);
    color: var(--color-text);
}

.btn-success {
    background: linear-gradient(135deg, #22C55E 0%, var(--color-success) 100%);
    color: var(--color-text-inverse);
    box-shadow: 0 1px 2px rgba(22, 163, 74, 0.25), 0 4px 12px rgba(22, 163, 74, 0.18);
    border: none;
}
.btn-success:hover {
    background: linear-gradient(135deg, var(--color-success) 0%, #15803D 100%);
}

.btn-warning {
    background: linear-gradient(135deg, #FBBF24 0%, var(--color-warning) 100%);
    color: var(--color-text-inverse);
    box-shadow: 0 1px 2px rgba(245, 158, 11, 0.25), 0 4px 12px rgba(245, 158, 11, 0.18);
    border: none;
}
.btn-warning:hover {
    background: linear-gradient(135deg, var(--color-warning) 0%, #B45309 100%);
}

/* Compact pill — for inline bulk-action bars and toolbars. */
.btn-sm {
    padding: 6px 14px;
    font-size: 12px;
    font-weight: 500;
}

/* ── Form inputs ── */
.form-input {
    width: 100%;
    background: #F1F5F9;
    border: 1px solid transparent;
    border-radius: var(--input-radius);
    padding: 12px 16px;
    font-size: 14px;
    transition: all var(--transition-base);
    outline: none;
}
.form-input::placeholder {
    color: var(--color-text-muted);
}
.form-input:focus {
    background: var(--color-surface);
    border-color: var(--color-primary-light);
    box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
/* Inline-validation error state. Painted by the x-email directive on
   blur when the value is non-empty and not a syntactically valid
   email; cleared when the user fixes it. Generic enough that other
   directives can opt in by setting aria-invalid="true". */
.form-input[aria-invalid="true"] {
    border-color: var(--color-danger);
    background: var(--color-danger-bg);
}
.form-input[aria-invalid="true"]:focus {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.12);
}
.form-input-error {
    font-size: 12px;
    font-weight: 500;
    color: var(--color-danger);
    margin-top: 4px;
    display: block;
    line-height: 1.4;
}

/* ── Checkboxes & radios ──
   Default browser-native checkboxes render with a very faint border on
   white cards, which parents with poor vision have flagged as hard to see.
   We re-style with appearance-none + a higher-contrast border + a filled
   primary state so the control is clearly visible checked or unchecked. */
input[type="checkbox"],
input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    background: var(--color-surface);
    border: 1.5px solid var(--color-text-muted);   /* slate-400 — much more visible than slate-200 */
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color var(--transition-base), background-color var(--transition-base), box-shadow var(--transition-base);
    vertical-align: middle;
}
input[type="checkbox"] { border-radius: 4px; }
input[type="radio"]    { border-radius: 50%; }

input[type="checkbox"]:hover:not(:disabled),
input[type="radio"]:hover:not(:disabled) {
    border-color: var(--color-text-secondary);
}

input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
    outline: none;
    border-color: var(--color-primary-light);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.22);
}

input[type="checkbox"]:checked,
input[type="radio"]:checked {
    background: var(--color-primary);
    border-color: var(--color-primary);
}

input[type="checkbox"]:checked {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='3.5 8.5 7 12 13 4.5'/></svg>");
    background-size: 80% 80%;
    background-position: center;
    background-repeat: no-repeat;
}

input[type="radio"]:checked {
    background-image: radial-gradient(circle, #fff 32%, transparent 36%);
}

input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

input[type="checkbox"].rounded { border-radius: 4px; }
input[type="checkbox"].rounded-full { border-radius: 50%; }

.form-label {
    display: block;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text-secondary);
    margin-bottom: 6px;
}
.form-label-optional {
    font-weight: 400;
    color: var(--color-text-muted);
    margin-left: 4px;
}

/* ── Table styles ── */
.table-header {
    background: rgba(248, 250, 252, 0.5);
    border-bottom: 1px solid var(--color-border-light);
}
.table-header th {
    padding: 12px 20px;
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
}
.table-row {
    border-bottom: 1px solid var(--color-border-light);
    background: var(--color-surface);
    transition: background var(--transition-fast);
}
.table-row:nth-child(even) {
    background: rgba(248, 250, 252, 0.5);
}
.table-row td.sticky,
.table-header th.sticky {
    background: #FFFFFF;
    box-shadow: 2px 0 4px rgba(0,0,0,0.04);
}
.table-header th.sticky {
    background: #F8FAFC;
}
.table-row:nth-child(even) td.sticky {
    background: rgba(248, 250, 252, 0.5);
}
.table-row:hover {
    background: #E2E8F0;
}
.table-row:hover td.sticky {
    background: #E2E8F0;
}
.table-row td {
    padding: 12px 20px;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

/* ── Sidebar ── */
.sidebar-section-label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    padding: 0 12px;
    margin-bottom: 4px;
}

.sidebar-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-secondary);
    transition: all var(--transition-fast);
}
.sidebar-link:hover {
    background: var(--color-sidebar-hover);
    color: var(--color-text);
}
.sidebar-link.active {
    background: var(--color-sidebar-active-bg);
    color: var(--color-sidebar-active-text);
}
.sidebar-link i {
    font-size: 18px;
    color: var(--color-text-muted);
}
.sidebar-link.active i {
    color: var(--color-sidebar-active-text);
}

/* Desktop staff sidebar: a viewport-tall sticky column anchored just below
   the sticky h-14 navbar. Capping the height here (rather than via a Tailwind
   arbitrary class, which needs a build step) keeps the three flex zones —
   pinned toolbar, scrolling section list, pinned footer — bounded so the
   footer stays put no matter how tall the page content is. The class-on-tag
   selector outranks the mobile `.fixed` / `.top-14` utilities regardless of
   stylesheet order. Mobile keeps its fixed top-14/bottom-0 framing. */
@media (min-width: 1024px) {
    aside.staff-sidebar {
        position: sticky;
        top: 3.5rem;
        left: auto;
        bottom: auto;
        height: calc(100vh - 3.5rem);
    }
}

/* Pinned sidebar toolbar — quick search + collapse/expand-all. Stays at the
   top while the sections below scroll. */
.sidebar-toolbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: #fff;
    border-bottom: 1px solid var(--color-border-light);
}
.sidebar-search {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 8px;
    height: 34px;
    padding: 0 10px;
    border-radius: 8px;
    background: var(--color-border-light);
    color: var(--color-text-muted);
    font-size: 13px;
    transition: background var(--transition-fast);
}
.sidebar-search:hover {
    background: var(--color-sidebar-hover);
}
.sidebar-search i { font-size: 15px; }
.sidebar-search kbd {
    font-size: 10px;
    padding: 1px 5px;
    border-radius: 4px;
    background: #fff;
    color: var(--color-text-muted);
}
.sidebar-toolbar-btn {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    color: var(--color-text-muted);
    transition: background var(--transition-fast), color var(--transition-fast);
}
.sidebar-toolbar-btn:hover {
    background: var(--color-sidebar-hover);
    color: var(--color-text);
}
.sidebar-toolbar-btn i { font-size: 16px; }

/* Collapsible section header — sticks to the top of the scrolling section
   list (which sits below the pinned toolbar) so the group you're in stays
   labelled even when its links scroll past. */
.sidebar-section-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 6px 12px;
    border-radius: 8px;
    background: #fff;
    /* Paint an opaque white band above the chip so links scrolling beneath it
       (through the scroll area's top padding) can't peek out when the chip is
       locked to the top. */
    box-shadow: 0 -14px 0 0 #fff;
    position: sticky;
    top: 0;
    z-index: 2;
    cursor: pointer;
    transition: background var(--transition-fast);
}
.sidebar-section-toggle:hover {
    background: var(--color-sidebar-hover);
}
.sidebar-section-toggle .sidebar-section-label {
    padding: 0;
    margin: 0;
}
.sidebar-section-caret {
    font-size: 12px;
    color: var(--color-text-muted);
    transition: transform var(--transition-fast);
}

/* Slim, unobtrusive scrollbar — overrides the chunky native one. Thumb is
   faint at rest and firms up on hover; track is invisible. Firefox uses the
   standard properties; WebKit/Blink use the pseudo-elements. */
.scrollbar-slim {
    scrollbar-width: thin;
    scrollbar-color: rgba(100, 116, 139, 0.35) transparent;  /* thumb, track */
}
.scrollbar-slim::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
.scrollbar-slim::-webkit-scrollbar-track {
    background: transparent;
}
.scrollbar-slim::-webkit-scrollbar-thumb {
    background-color: rgba(100, 116, 139, 0.35);
    border-radius: 9999px;
    border: 2px solid transparent;   /* inset the thumb so it reads as ~4px */
    background-clip: content-box;
}
.scrollbar-slim:hover::-webkit-scrollbar-thumb {
    background-color: rgba(100, 116, 139, 0.55);
}

/* ── Toast notifications ── */
.toast {
    padding: 12px 20px;
    border-radius: var(--card-radius-sm);
    font-size: 14px;
    font-weight: 500;
    box-shadow: var(--shadow-dropdown);
    max-width: 420px;
    width: max-content;
}
.toast-success { background: var(--color-success); color: white; }
.toast-error   { background: var(--color-danger);  color: white; }
.toast-info    { background: var(--color-info);    color: white; }

/* ── Progress bar ── */
.progress-bar {
    width: 100%;
    height: 8px;
    background: var(--color-border-light);
    border-radius: 999px;
    overflow: hidden;
}
.progress-bar-fill {
    height: 100%;
    border-radius: 999px;
    background: var(--color-primary);
    transition: width 0.5s ease;
}

/* ── Spinner ── */
.spinner {
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255,255,255,0.3);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
}

/* ── Safe area (mobile) ── */
.safe-area-bottom {
    padding-bottom: env(safe-area-inset-bottom);
}

/* ── Tom Select overrides ── */
.ts-wrapper {
    font-family: 'Inter', system-ui, sans-serif !important;
}
.ts-wrapper.single .ts-control,
.ts-wrapper.multi .ts-control {
    background: #F1F5F9 !important;
    border: 1px solid transparent !important;
    border-radius: 0.75rem !important;
    padding: 0.4375rem 0.75rem !important;
    font-size: 0.875rem !important;
    color: var(--color-text) !important;
    box-shadow: none !important;
    min-height: 0 !important;
    line-height: 1.25rem !important;
}
.ts-wrapper.single .ts-control:hover,
.ts-wrapper.multi .ts-control:hover {
    border-color: var(--color-primary-light) !important;
}
.ts-wrapper.focus .ts-control {
    background: var(--color-surface) !important;
    border-color: var(--color-primary-light) !important;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15) !important;
}
.ts-wrapper.single .ts-control::after {
    border-color: var(--color-text-muted) transparent transparent !important;
    margin-top: -2px !important;
}
.ts-control > input {
    color: var(--color-text) !important;
    font-size: 0.875rem !important;
    min-height: 0 !important;
    padding: 0 !important;
}
.ts-control > input::placeholder {
    color: var(--color-text-muted) !important;
}
.ts-wrapper .ts-control .item {
    color: var(--color-text) !important;
}
.ts-dropdown {
    border: 1px solid var(--color-border) !important;
    border-radius: 0.75rem !important;
    box-shadow: 0 4px 16px rgba(0,0,0,0.08) !important;
    font-size: 0.875rem !important;
    margin-top: 4px !important;
    overflow: hidden;
    /* Tom Select dropdowns render to document.body, so they're siblings of the
       modal, not children — the z-index must beat the highest overlay it can be
       opened from. The parent-portal onboarding gates sit at z-[119]/[120], so
       this has to clear those, not just the ordinary modal backdrop (z-50). */
    z-index: 130 !important;
}
.ts-dropdown .option {
    padding: 0.4375rem 0.75rem !important;
    color: var(--color-text) !important;
}
.ts-dropdown .option:hover,
.ts-dropdown .active {
    background: var(--color-primary-bg) !important;
    color: var(--color-primary) !important;
}
.ts-dropdown .option.selected {
    background: var(--color-primary) !important;
    color: white !important;
}

/* ── Flowbite Datepicker overrides ── */
.datepicker .datepicker-picker {
    background: var(--color-surface) !important;
    border: 1px solid var(--color-border) !important;
    border-radius: 0.75rem !important;
    box-shadow: 0 4px 16px rgba(0,0,0,0.08) !important;
    font-family: 'Inter', system-ui, sans-serif !important;
    padding: 0.75rem !important;
}
.datepicker .datepicker-cell {
    border-radius: 0.5rem !important;
    color: var(--color-text) !important;
    font-size: 0.8125rem !important;
}
.datepicker .datepicker-cell:hover {
    background: var(--color-primary-bg) !important;
    color: var(--color-primary) !important;
}
.datepicker .datepicker-cell.selected,
.datepicker .datepicker-cell.range-start,
.datepicker .datepicker-cell.range-end {
    background: var(--color-primary) !important;
    color: white !important;
}
.datepicker .datepicker-cell.range {
    background: var(--color-primary-bg) !important;
    background-color: var(--color-primary-bg) !important;
    color: var(--color-primary) !important;
    border-radius: 0 !important;
}
.datepicker .datepicker-cell.range-start {
    background: var(--color-primary) !important;
    background-color: var(--color-primary) !important;
    color: white !important;
    border-radius: 0.5rem 0 0 0.5rem !important;
}
.datepicker .datepicker-cell.range-end {
    background: var(--color-primary) !important;
    background-color: var(--color-primary) !important;
    color: white !important;
    border-radius: 0 0.5rem 0.5rem 0 !important;
}
.datepicker .datepicker-cell.disabled {
    color: var(--color-text-muted) !important;
    opacity: 0.4 !important;
}
.datepicker .datepicker-header .datepicker-controls .button {
    background: transparent !important;
    border: none !important;
    color: var(--color-text) !important;
    border-radius: 0.375rem !important;
    font-weight: 600 !important;
    font-size: 0.875rem !important;
    cursor: pointer;
}
.datepicker .datepicker-header .datepicker-controls .button:hover {
    background: var(--color-primary-bg) !important;
    color: var(--color-primary) !important;
}
.datepicker .dow {
    color: var(--color-text-muted) !important;
    font-size: 0.75rem !important;
    font-weight: 500 !important;
}
.datepicker .datepicker-footer .datepicker-controls .button {
    background: var(--color-primary) !important;
    color: white !important;
    border: none !important;
    border-radius: var(--input-radius) !important;
    padding: 0.375rem 1rem !important;
    font-size: 0.8125rem !important;
    font-weight: 500 !important;
    cursor: pointer;
}
.datepicker .datepicker-footer .datepicker-controls .button:hover {
    background: var(--color-primary-light) !important;
}

/* ── Dual-list picker ──
   Two-pane "available / selected" widget for deep-dive multi-selection
   (e.g. Payment Links → Custom batch). Opt-in only — chip-based
   tom-select stays the default multi-select primitive across the app.
   Composed in views/partials/dual-list.php + Alpine.data('dualList').
   Scroll panes are fixed-height so the dual-list never pushes the rest
   of the page around as items move between panes. */
.dual-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    /* Grid default `align-items: stretch` makes the two panes equal height
       (height = taller pane's natural content). Combined with the scroll
       area's `flex: 1` below, both footers always sit at the same y. */
}
.dual-list__pane {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--card-radius-sm);
    min-width: 0;
    min-height: 200px;
}
.dual-list__pane-header {
    padding: 0.5rem;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg-alt);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    flex: 0 0 auto;
}
.dual-list__scroll {
    /* flex:1 makes the scroll area fill the pane's height, so the footer
       always sits at the bottom of the row instead of immediately under
       whatever items happen to be in this pane. min-height keeps the
       pane usable when both sides are empty; max-height caps growth
       for long lists (scroll-within-pane kicks in past this). */
    flex: 1 1 auto;
    min-height: 120px;
    max-height: 360px;
    overflow-y: auto;
    background: var(--color-surface);
}
.dual-list__pane-footer { flex: 0 0 auto; }
.dual-list__row {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    font-size: 0.8125rem;
    line-height: 1.2;
    color: var(--color-text);
}
.dual-list__row:hover { background: var(--color-bg-alt); }
.dual-list__row:last-child { border-bottom: none; }
.dual-list__row-title { font-weight: 500; }
.dual-list__row-sub {
    font-size: 0.6875rem;
    color: var(--color-text-muted);
}
.dual-list__pane-footer {
    padding: 0.5rem 0.75rem;
    border-top: 1px solid var(--color-border);
    background: var(--color-bg-alt);
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
}
.dual-list__count { font-weight: 600; color: var(--color-text); }

/* Modifiers used by surfaces where the dual-list represents an N+1 state
   model (e.g. Section Assignment) rather than the default binary
   selected/unselected. They sit alongside `.dual-list__row` so the visual
   diff is encoded in the row itself — green left border = staged-in,
   muted check = already saved here. */
.dual-list__row--staged-in {
    background: rgba(4, 120, 87, 0.06);
    border-left: 3px solid var(--color-success, #047857);
    padding-left: calc(0.75rem - 3px);
}
.dual-list__row--saved {
    cursor: default;
    color: var(--color-text-muted);
}
.dual-list__row--saved:hover { background: var(--color-surface); }
.dual-list__row--saved .dual-list__row-title::before {
    content: '\2713  ';
    color: var(--color-text-muted);
    font-weight: 700;
}

} /* end @layer components */

/* ── Flowbite datepicker utility overrides (unlayered — must beat @layer utilities) ──
   The datepicker JS adds Flowbite-specific classes (bg-brand, rounded-base, etc.)
   that only exist in its bundled Tailwind v4 CSS. We remap them to our design tokens. */
.datepicker .bg-brand,
.datepicker .datepicker-cell.bg-brand {
    background-color: var(--color-primary) !important;
    color: white !important;
}
.datepicker .bg-neutral-tertiary-medium,
.datepicker .datepicker-cell.bg-neutral-tertiary-medium {
    background-color: var(--color-primary-bg) !important;
    color: var(--color-primary) !important;
}
.datepicker .bg-neutral-primary-medium {
    background-color: var(--color-surface) !important;
}
.datepicker .text-body {
    color: var(--color-text) !important;
}
.datepicker .text-heading {
    color: var(--color-text) !important;
}
.datepicker .text-fg-disabled {
    color: var(--color-text-muted) !important;
}
.datepicker .rounded-base {
    border-radius: 0.5rem !important;
}
.datepicker .rounded-s-base {
    border-start-start-radius: 0.5rem !important;
    border-end-start-radius: 0.5rem !important;
}
.datepicker .rounded-e-base {
    border-start-end-radius: 0.5rem !important;
    border-end-end-radius: 0.5rem !important;
}

/* ── Print styles (unlayered — always applies) ── */
/* Hidden on screen; revealed inside @media print below. */
.print-only {
    display: none;
}

@media print {
    nav, aside, .no-print, .toast, .btn-bar {
        display: none !important;
    }
    body {
        background: white;
        color: black;
        font-size: 12pt;
    }
    .card {
        box-shadow: none;
        border: 1px solid #ccc;
    }
    .print-only {
        display: block !important;
    }
    .page-break {
        page-break-before: always;
    }
}

@keyframes spin {
    to { transform: rotate(360deg); }
}
