/* Educore ERP design system - Bootstrap 5 base, visual language ported from the user-supplied
   "Flat-Able" admin template (Phoenixcoded/ThemeWagon, Bootstrap 4 + jQuery source).
   IMPORTANT: Flat-Able's own framework (Bootstrap 4, jQuery, its "pcoded-*" markup/JS) is NOT used
   here - it is incompatible with this app's Bootstrap 5 markup (data-bs-* attributes, form-select,
   text-bg-*, .g-* gap utilities) used consistently across all ~396 views. Swapping frameworks wholesale
   would silently break every dropdown/modal/form-select/badge in the app. Instead, this file
   reimplements Flat-Able's actual colors/typography/spacing/radius/shadow values (read directly from
   the supplied source's src/assets/scss/settings/_theme-variables.scss and the compiled
   dist/assets/css/style.css) inside our existing Bootstrap 5 + custom-class architecture, so every view
   gets the same visual result with zero markup risk. Static-verification only - no browser in this
   session, so re-read every rule for typos/consistency by hand.

   Flat-Able source values used (see the two files above for the originals):
     primary teal #1abc9c, danger #e74c3c, warning #f1c40f, success #2ecc71, info #3498db,
     purple #536dfe, dark/sidebar #2c3e50, sidebar text #d0dcda, body bg #e9e9e9, text #373a3c,
     border #e2e5e8, border-radius 2px (flat design - $enable-shadows:false, $enable-gradients:false
     in their own custom-variables.scss), card shadow 0 2px 1px rgba(0,0,0,.05), header height 56px,
     sidebar width 235px / collapsed 70px, font 'Open Sans' 14px base. */

/* =========================================================================
   FONTS - Open Sans, self-hosted (files copied from the supplied template's
   dist/assets/fonts/opensans/ into wwwroot/fonts/opensans/), matching this
   codebase's own no-CDN-dependency rule (see _Layout.cshtml's own comment
   about on-prem deployments with no guaranteed outbound internet access).

   Weight 400: all 7 unicode-range subsets (incl. the base Latin/ASCII one) were present in the
   supplied files - full local coverage, no fallback risk.
   Weight 600: only 6 of 7 subsets were present locally; the template's own compiled CSS referenced
   the 7th (base Latin/ASCII) subset from Google's CDN directly. That file was deliberately NOT
   vendored here - referencing a CDN for the single subset that covers plain English text would
   silently reproduce the exact "stylesheet doesn't load on a blocked network" failure mode already
   hit once in this project. Basic English semibold/bold text therefore falls back to the next font
   in the stack (Segoe UI) at weight 600 - visually very close to Open Sans SemiBold, and the
   non-Latin subsets (Cyrillic/Greek/Vietnamese/Latin-ext) still use the real bundled Open Sans 600
   where applicable. */
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFWJ0bbck.woff2") format("woff2"); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFUZ0bbck.woff2") format("woff2"); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFWZ0bbck.woff2") format("woff2"); unicode-range: U+1F00-1FFF; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFVp0bbck.woff2") format("woff2"); unicode-range: U+0370-03FF; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFWp0bbck.woff2") format("woff2"); unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFW50bbck.woff2") format("woff2"); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 400; font-display: swap; src: local("Open Sans Regular"), local("OpenSans-Regular"), url("../fonts/opensans/mem8YaGs126MiZpBA-UFVZ0b.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), url("../fonts/opensans/mem5YaGs126MiZpBA-UNirkOX-hpOqc.woff2") format("woff2"); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), url("../fonts/opensans/mem5YaGs126MiZpBA-UNirkOVuhpOqc.woff2") format("woff2"); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), url("../fonts/opensans/mem5YaGs126MiZpBA-UNirkOXuhpOqc.woff2") format("woff2"); unicode-range: U+1F00-1FFF; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), url("../fonts/opensans/mem5YaGs126MiZpBA-UNirkOUehpOqc.woff2") format("woff2"); unicode-range: U+0370-03FF; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), url("../fonts/opensans/mem5YaGs126MiZpBA-UNirkOXehpOqc.woff2") format("woff2"); unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; }
@font-face { font-family: "Open Sans"; font-style: normal; font-weight: 600; font-display: swap; src: local("Open Sans SemiBold"), local("OpenSans-SemiBold"), url("../fonts/opensans/mem5YaGs126MiZpBA-UNirkOXOhpOqc.woff2") format("woff2"); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* =========================================================================
   DESIGN TOKENS - values ported 1:1 from Flat-Able's _theme-variables.scss /
   _custom-variables.scss (see file header). Every component rule below reads
   from these custom properties, never a hardcoded hex, so [data-bs-theme="dark"]
   reskins the whole app via the existing #themeToggle (site.js).
   ========================================================================= */
:root {
    /* --- Brand / primary (Flat-Able's signature teal, $primary-color: #1abc9c) --- */
    --color-primary-50: #e6f9f5;
    --color-primary-100: #c1f0e6;
    --color-primary-200: #91e2d1;
    --color-primary-300: #5cd2ba;
    --color-primary-400: #2ec5a5;
    --color-primary-500: #1abc9c;
    --color-primary-600: #17a589;
    --color-primary-700: #148f76;
    --color-primary-800: #107a64;
    --color-primary-900: #0b5c4b;

    /* --- Neutral / gray scale --- */
    --color-gray-50: #f8f9fa;
    --color-gray-100: #f1f3f5;
    --color-gray-200: #e2e5e8;
    --color-gray-300: #cfd4d8;
    --color-gray-400: #a9b1b8;
    --color-gray-500: #748892;
    --color-gray-600: #57646c;
    --color-gray-700: #3d454b;
    --color-gray-800: #2c3e50;
    --color-gray-900: #1b262f;

    /* --- Semantic colors (Flat-Able's exact hex values) --- */
    --color-success: #2ecc71;
    --color-success-bg: #eafaf1;
    --color-danger: #e74c3c;
    --color-danger-bg: #fdedeb;
    --color-warning: #d4a017;
    --color-warning-bg: #fdf6e3;
    --color-info: #3498db;
    --color-info-bg: #eaf4fc;
    --color-purple: #536dfe;
    --color-purple-bg: #ecefff;

    /* --- Surface / text roles (theme-aware; overridden wholesale in the dark block) --- */
    --surface: #ffffff;
    --surface-muted: #f4f5f6;
    --surface-sunken: #e9e9e9;
    --surface-overlay: #ffffff;
    --border-color: #e2e5e8;
    --border-color-strong: #cfd4d8;
    --text-primary: #373a3c;
    --text-secondary: #4b545a;
    --text-muted: #868e96;
    --text-on-primary: #ffffff;
    --heading-color: #37474f;

    /* --- Brand aliases used throughout the shell/components --- */
    --brand: var(--color-primary-500);
    --brand-hover: var(--color-primary-600);
    --brand-soft: var(--color-primary-50);
    --focus-ring-color: var(--color-primary-300);

    /* --- Sidebar - Flat-Able's own fixed dark palette (#2c3e50), independent of the
         light/dark theme toggle, matching its "menu-dark-background: #2c3e50" default. --- */
    --sidebar-bg: #2c3e50;
    --sidebar-border: rgba(255, 255, 255, 0.06);
    --sidebar-text: #d0dcda;
    --sidebar-text-muted: #93a5ae;
    --sidebar-hover-bg: rgba(255, 255, 255, 0.06);
    --sidebar-active-bg: var(--brand);

    /* --- Type scale (Open Sans, 14px base per Flat-Able's $theme-font-size) --- */
    --font-family-base: "Open Sans", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
    --font-size-xs: 0.75rem;
    --font-size-sm: 0.8125rem;
    --font-size-base: 0.875rem;
    --font-size-lg: 1rem;
    --font-size-xl: 1.15rem;
    --font-size-2xl: 1.6rem;
    --font-size-3xl: 2rem;
    --font-weight-regular: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;
    --line-height-tight: 1.25;
    --line-height-base: 1.5;

    /* --- Spacing scale (rem) --- */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.25rem;
    --space-6: 1.5rem;
    --space-8: 2rem;

    /* --- Radius scale - Flat-Able is a genuinely flat design ($border-radius: 2px
         throughout, not Bootstrap's stock 6-8px), so this scale stays deliberately tight. --- */
    --radius-sm: 2px;
    --radius-md: 3px;
    --radius-lg: 4px;
    --radius-xl: 6px;
    --radius-full: 999px;

    /* --- Shadow scale - Flat-Able disables Bootstrap's default shadows ($enable-shadows: false)
         and uses one very subtle card shadow (0 2px 1px rgba(0,0,0,.05)) instead of layered
         elevation - this scale mirrors that restraint rather than our previous glossy-SaaS shadows. --- */
    --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.04);
    --shadow-sm: 0 2px 1px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 3px 6px rgba(0, 0, 0, 0.08);
    --shadow-lg: 0 8px 20px rgba(0, 0, 0, 0.14);

    /* --- Shell metrics (Flat-Able's own $header-height / $Menu-width / $Menu-collapsed-width) --- */
    --educore-sidebar-width: 235px;
    --educore-sidebar-width-collapsed: 70px;
    --educore-topbar-height: 56px;

    /* --- Back-compat aliases --- */
    --educore-radius: var(--radius-lg);
    --educore-brand: var(--brand);
    --educore-brand-hover: var(--brand-hover);
    --educore-surface: var(--surface);
    --educore-surface-muted: var(--surface-muted);
    --educore-border: var(--border-color);
    --educore-text-muted: var(--text-muted);
    --educore-shadow: var(--shadow-sm);
}

[data-bs-theme="dark"] {
    --color-primary-50: #0b2c25;
    --color-primary-100: #0f3d33;

    --surface: #1c2733;
    --surface-muted: #212f3d;
    --surface-sunken: #263544;
    --surface-overlay: #212f3d;
    --border-color: #2e3e4e;
    --border-color-strong: #3d4f61;
    --text-primary: #eef2f3;
    --text-secondary: #c6cfd4;
    --text-muted: #90a0aa;
    --text-on-primary: #ffffff;
    --heading-color: #f1f5f6;

    --brand: var(--color-primary-500);
    --brand-hover: var(--color-primary-400);
    --brand-soft: rgba(26, 188, 156, 0.16);
    --focus-ring-color: var(--color-primary-400);

    --color-success-bg: rgba(46, 204, 113, 0.14);
    --color-danger-bg: rgba(231, 76, 60, 0.16);
    --color-warning-bg: rgba(212, 160, 23, 0.16);
    --color-info-bg: rgba(52, 152, 219, 0.16);
    --color-purple-bg: rgba(83, 109, 254, 0.16);

    --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.3);
    --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.32);
    --shadow-md: 0 4px 10px rgba(0, 0, 0, 0.38);
    --shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.48);
}

* {
    scrollbar-width: thin;
    scrollbar-color: var(--border-color-strong) transparent;
}

body {
    background-color: var(--surface-sunken);
    color: var(--text-primary);
    font-family: var(--font-family-base);
    font-size: var(--font-size-base);
    line-height: var(--line-height-base);
}

h1, h2, h3, h4, h5, h6 {
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--heading-color);
}

small, .small {
    color: var(--text-muted);
}

a {
    color: var(--brand);
}

a:hover {
    color: var(--brand-hover);
}

/* ---------- Shell layout ---------- */
.app-shell {
    display: flex;
    min-height: 100vh;
}

.app-sidebar {
    width: var(--educore-sidebar-width);
    flex-shrink: 0;
    background: var(--sidebar-bg);
    border-right: 1px solid var(--sidebar-border);
    box-shadow: var(--shadow-md);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    transition: transform 0.2s ease;
}

.app-sidebar__brand {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 1rem 1.25rem;
    margin-bottom: var(--space-2);
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-lg);
    color: #ffffff;
    border-bottom: 1px solid var(--sidebar-border);
}

.app-sidebar__brand i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-md);
    background: var(--brand);
    color: #ffffff;
    font-size: 1.05rem;
}

.app-sidebar__nav {
    padding: var(--space-2) var(--space-2) var(--space-4);
}

.app-sidebar__nav .nav-item {
    margin-bottom: 1px;
}

.app-sidebar__nav .nav-link {
    color: var(--sidebar-text);
    padding: 0.6rem 0.85rem;
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    gap: 0.65rem;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    transition: background-color 0.12s ease, color 0.12s ease;
}

.app-sidebar__nav .nav-link i {
    width: 1.1rem;
    text-align: center;
    font-size: 1rem;
    color: var(--sidebar-text-muted);
    flex-shrink: 0;
    transition: color 0.12s ease;
}

.app-sidebar__nav .nav-link:hover {
    background-color: var(--sidebar-hover-bg);
    color: #ffffff;
}

.app-sidebar__nav .nav-link:hover i {
    color: #ffffff;
}

/* Flat-Able's own active-item treatment: a solid teal block, not a soft tint/accent bar - see
   dist/assets/css/style.css's ".pcoded-inner-navbar > li.active > a { background: #1abc9c; color: #fff }" */
.app-sidebar__nav .nav-link.active {
    background: var(--sidebar-active-bg);
    color: #ffffff;
    font-weight: var(--font-weight-semibold);
}

.app-sidebar__nav .nav-link.active i {
    color: #ffffff;
}

.app-sidebar__group-toggle {
    width: 100%;
    background: none;
    border: none;
    text-align: left;
}

.app-sidebar__chevron {
    margin-left: auto;
    font-size: 0.7rem;
    color: var(--sidebar-text-muted);
    transition: transform 0.15s ease;
}

.app-sidebar__group-toggle[aria-expanded="true"] .app-sidebar__chevron {
    transform: rotate(180deg);
}

.app-sidebar__submenu {
    padding-top: 2px;
    padding-bottom: 2px;
}

.app-sidebar__submenu .nav-link {
    padding-left: 2.6rem;
    font-size: var(--font-size-sm);
    position: relative;
}

.app-sidebar__submenu .nav-link::before {
    content: "";
    position: absolute;
    left: 1.6rem;
    top: 50%;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: var(--sidebar-text-muted);
    transform: translateY(-50%);
}

.app-sidebar__submenu .nav-link.active::before,
.app-sidebar__submenu .nav-link:hover::before {
    background-color: #ffffff;
}

.app-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Flat-Able's header is a plain, solid light bar - no blur/glass effect. */
.app-topbar {
    height: var(--educore-topbar-height);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.5rem;
    background-color: var(--surface);
    border-bottom: 1px solid var(--border-color);
    box-shadow: var(--shadow-xs);
    position: sticky;
    top: 0;
    z-index: 20;
}

.app-topbar__search {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
    max-width: 420px;
    padding: 0.4rem 0.8rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-color);
    background-color: var(--surface-muted);
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.app-topbar__search:hover {
    border-color: var(--brand);
}

.app-topbar__search kbd {
    margin-left: auto;
    font-size: var(--font-size-xs);
    color: var(--text-muted);
    background-color: var(--surface-sunken);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 0.1rem 0.4rem;
}

.app-topbar__actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.btn-icon {
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background-color: var(--surface);
    color: var(--text-secondary);
    transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.btn-icon:hover {
    background-color: var(--surface-sunken);
    border-color: var(--border-color-strong);
    color: var(--text-primary);
}

.app-breadcrumbs {
    padding: 0.85rem 1.5rem 0;
}

.app-breadcrumbs .breadcrumb {
    margin-bottom: 0;
    font-size: var(--font-size-sm);
}

.app-breadcrumbs .breadcrumb-item + .breadcrumb-item::before {
    color: var(--text-muted);
}

.app-breadcrumbs .breadcrumb-item.active {
    color: var(--text-muted);
}

.app-content {
    padding: 1.25rem 1.5rem 2.5rem;
}

/* ---------- Cards / widgets ---------- */
.card,
.educore-card {
    background-color: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.card {
    color: var(--text-primary);
}

.educore-card {
    padding: 1.25rem;
}

.educore-card.p-0 {
    padding: 0;
}

.card-header,
.educore-card__header {
    background-color: transparent;
    border-bottom: 1px solid var(--border-color);
    padding: 1rem 1.25rem;
    font-weight: var(--font-weight-semibold);
    color: var(--heading-color);
}

.card-body {
    padding: 1.25rem;
}

.card-footer {
    background-color: transparent;
    border-top: 1px solid var(--border-color);
    padding: 1rem 1.25rem;
}

.educore-widget__value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: 1.2;
}

.educore-widget__label {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.35rem;
}

/* ---------- Dashboard stat cards ---------- */
/* Icon + number + label pattern used by Home/Index and any other dashboard-style KPI grid. Wrap the
   row in class="stat-grid" (Home/Index.cshtml does) to get the 4-color rotation below, matching
   Flat-Able's own dashboard widget palette (teal/red/purple/info) - flat solid fills, no gradients,
   per this template's own $enable-gradients: false. */
.stat-card {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.25rem;
}

.stat-grid > div:hover .stat-card {
    border-color: var(--border-color-strong);
    box-shadow: var(--shadow-md);
}

.stat-card__icon {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    border-radius: var(--radius-md);
    background-color: var(--brand-soft);
    color: var(--brand);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
}

.stat-grid > div:nth-of-type(4n+1) .stat-card__icon { background: var(--color-primary-500); color: #fff; }
.stat-grid > div:nth-of-type(4n+2) .stat-card__icon { background: var(--color-danger); color: #fff; }
.stat-grid > div:nth-of-type(4n+3) .stat-card__icon { background: var(--color-purple); color: #fff; }
.stat-grid > div:nth-of-type(4n+4) .stat-card__icon { background: var(--color-info); color: #fff; }

.stat-card__body {
    min-width: 0;
}

.stat-card__value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: 1.2;
}

.stat-card__label {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

/* ---------- Tables ---------- */
.table {
    --bs-table-bg: transparent;
    color: var(--text-primary);
    margin-bottom: 0;
}

.table > :not(caption) > * > * {
    padding: 0.75rem 1.25rem;
    border-bottom-width: 1px;
    border-bottom-color: var(--border-color);
}

.table thead th {
    text-transform: uppercase;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.03em;
    color: var(--text-muted);
    background-color: var(--surface-muted);
    border-bottom: 1px solid var(--border-color);
    white-space: nowrap;
}

.table tbody tr:last-child > * {
    border-bottom-width: 0;
}

.table-hover > tbody > tr:hover > * {
    --bs-table-accent-bg: var(--surface-muted);
    color: var(--text-primary);
}

.table-striped > tbody > tr:nth-of-type(odd) > * {
    --bs-table-accent-bg: var(--surface-muted);
}

/* ---------- Buttons ---------- */
/* Flat/solid, small radius, no gradient/hover-lift - matching Flat-Able's own restrained button style
   ($btn-border-radius: 2px, $enable-gradients: false, $enable-shadows: false). */
.btn {
    border-radius: var(--radius-sm);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-sm);
    padding: 0.5rem 1rem;
    transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.btn-sm {
    border-radius: var(--radius-sm);
    padding: 0.3rem 0.65rem;
}

.btn-lg {
    border-radius: var(--radius-md);
    padding: 0.65rem 1.35rem;
}

.btn-primary {
    background-color: var(--brand) !important;
    border-color: var(--brand) !important;
    color: var(--text-on-primary) !important;
}

.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--brand-hover) !important;
    border-color: var(--brand-hover) !important;
}

.btn-outline-secondary {
    color: var(--text-secondary);
    border-color: var(--border-color-strong);
}

.btn-outline-secondary:hover {
    background-color: var(--surface-sunken);
    border-color: var(--border-color-strong);
    color: var(--text-primary);
}

.btn-outline-primary {
    color: var(--brand);
    border-color: var(--brand);
}

.btn-outline-primary:hover {
    background-color: var(--brand);
    border-color: var(--brand);
    color: var(--text-on-primary);
}

/* ---------- Badges ---------- */
.badge {
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-sm);
    padding: 0.32em 0.65em;
    font-size: var(--font-size-xs);
}

.text-bg-success { background-color: var(--color-success-bg) !important; color: var(--color-success) !important; }
.text-bg-danger { background-color: var(--color-danger-bg) !important; color: var(--color-danger) !important; }
.text-bg-warning { background-color: var(--color-warning-bg) !important; color: var(--color-warning) !important; }
.text-bg-info { background-color: var(--color-info-bg) !important; color: var(--color-info) !important; }
.text-bg-primary { background-color: var(--brand-soft) !important; color: var(--brand) !important; }
.text-bg-secondary { background-color: var(--surface-sunken) !important; color: var(--text-secondary) !important; }

/* ---------- Forms ---------- */
.form-control,
.form-select {
    background-color: var(--surface);
    border: 1px solid var(--border-color-strong);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    padding: 0.5rem 0.75rem;
}

/* .form-select needs its right padding wider than .form-control - Bootstrap's own background-image
   dropdown caret icon (unchanged, we don't override background-image) is positioned assuming this
   extra reserved space; without it the caret overlaps the selected option's text. */
.form-select {
    padding-right: 2.25rem;
}

.form-control:focus,
.form-select:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.form-control::placeholder {
    color: var(--text-muted);
    opacity: 1;
}

.form-label {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
}

.form-text {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
}

.form-check-input:checked {
    background-color: var(--brand);
    border-color: var(--brand);
}

.form-check-input:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

/* ---------- Alerts ---------- */
.alert {
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

.alert-success { background-color: var(--color-success-bg); color: var(--color-success); border-color: var(--color-success-bg); }
.alert-danger { background-color: var(--color-danger-bg); color: var(--color-danger); border-color: var(--color-danger-bg); }
.alert-warning { background-color: var(--color-warning-bg); color: var(--color-warning); border-color: var(--color-warning-bg); }
.alert-info { background-color: var(--color-info-bg); color: var(--color-info); border-color: var(--color-info-bg); }

/* ---------- List groups ---------- */
.list-group-item {
    background-color: transparent;
    border-color: var(--border-color);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    padding: 0.65rem 0.25rem;
}

.list-group-item-action:hover,
.list-group-item-action:focus {
    background-color: var(--surface-sunken);
    color: var(--text-primary);
}

/* ---------- Pagination ---------- */
.pagination .page-link {
    border-color: var(--border-color);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    margin: 0 2px;
    font-size: var(--font-size-sm);
}

.pagination .page-item.active .page-link {
    background-color: var(--brand);
    border-color: var(--brand);
    color: var(--text-on-primary);
}

.pagination .page-link:hover {
    background-color: var(--surface-sunken);
    color: var(--text-primary);
}

/* ---------- Dropdowns ---------- */
.dropdown-menu {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    background-color: var(--surface-overlay);
    padding: 0.4rem;
}

.dropdown-item {
    border-radius: var(--radius-sm);
    padding: 0.5rem 0.7rem;
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: var(--surface-sunken);
    color: var(--text-primary);
}

.dropdown-header {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

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

/* ---------- Modals ---------- */
.modal-content {
    background-color: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

.modal-header,
.modal-footer {
    border-color: var(--border-color);
}

/* ---------- Toasts ---------- */
.toast {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
}

/* ---------- Empty states ---------- */
/* Not yet wired into any controller/view - list views today render a plain
   `<tr><td class="text-center text-muted py-4">No records found.</td></tr>` row. This class is ready
   for a future pass that wants a richer icon+text treatment without touching every controller:
     <div class="empty-state">
       <i class="bi bi-inbox empty-state__icon"></i>
       <p class="empty-state__title">No records found</p>
       <p class="empty-state__hint">Try adjusting your filters.</p>
     </div>
*/
.empty-state {
    text-align: center;
    padding: var(--space-8) var(--space-4);
    color: var(--text-muted);
}

.empty-state__icon {
    font-size: 2rem;
    color: var(--text-muted);
    opacity: 0.6;
    margin-bottom: var(--space-3);
    display: block;
}

.empty-state__title {
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    margin-bottom: 0.25rem;
}

.empty-state__hint {
    font-size: var(--font-size-sm);
    margin-bottom: 0;
}

/* ---------- Skeleton loaders ---------- */
.skeleton {
    background: linear-gradient(90deg, var(--border-color) 25%, var(--surface-muted) 37%, var(--border-color) 63%);
    background-size: 400% 100%;
    animation: skeleton-loading 1.4s ease infinite;
    border-radius: var(--radius-sm);
}

@keyframes skeleton-loading {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* ---------- Command palette ---------- */
.command-palette {
    position: fixed;
    inset: 0;
    z-index: 1050;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 10vh;
}

.command-palette__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(38, 50, 56, 0.55);
}

.command-palette__panel {
    position: relative;
    width: min(560px, 90vw);
    background-color: var(--surface-overlay);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.command-palette__input {
    width: 100%;
    border: none;
    padding: 1rem 1.25rem;
    font-size: 1rem;
    border-bottom: 1px solid var(--border-color);
    background: transparent;
    color: var(--text-primary);
    outline: none;
}

.command-palette__results {
    list-style: none;
    margin: 0;
    padding: 0.5rem;
    max-height: 320px;
    overflow-y: auto;
}

.command-palette__results li a {
    display: block;
    padding: 0.6rem 0.75rem;
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    text-decoration: none;
    font-size: var(--font-size-sm);
}

.command-palette__results li a:hover,
.command-palette__results li a.active {
    background-color: var(--surface-sunken);
    color: var(--brand);
}

/* ---------- Focus visibility (WCAG 2.1 AA) ---------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible {
    outline: 2px solid var(--focus-ring-color);
    outline-offset: 2px;
}

@media (max-width: 991.98px) {
    .app-sidebar {
        position: fixed;
        z-index: 30;
        transform: translateX(-100%);
        box-shadow: var(--shadow-lg);
    }

    .app-sidebar.show {
        transform: translateX(0);
    }

    .app-content {
        padding: 1rem 1rem 2rem;
    }

    .app-topbar {
        padding: 0 1rem;
    }

    .app-breadcrumbs {
        padding: 0.75rem 1rem 0;
    }
}

/* ---------- Login screen ---------- */
/* Matches Flat-Able's real .auth-wrapper treatment (dist/assets/css/style.css): a solid teal
   fallback under a full-bleed background photo, with a plain white, minimally-rounded card on top -
   see dist/auth-signin.html. Background image is the template's own img-auth-big.jpg, vendored
   locally (wwwroot/images/auth/) alongside the other self-hosted assets. */
.login-body {
    position: relative;
    min-height: 100vh;
    /* Flat teal fill - one of Flat-Able's own auth variants (no photo). The template's bundled photo
       background was a generic stock airplane image with no relevance to an education ERP, so it was
       dropped rather than kept just for template fidelity; swap in a real campus photo here later via
       background-image: url("../images/auth/<file>.jpg") + background-size/position/attachment: cover/center/fixed. */
    background-color: var(--color-primary-500);
}

.login-wrapper {
    position: relative;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.login-card {
    background-color: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 2.5rem;
    width: min(420px, 100%);
    color: var(--text-primary);
}

.login-card .form-label {
    color: var(--text-secondary);
}

.login-card__brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-xl);
    color: var(--heading-color);
    margin-bottom: 0.35rem;
}

.login-card__brand i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: var(--radius-md);
    background: var(--brand);
    color: #ffffff;
    font-size: 1.2rem;
}

/* ---------- Public self-service portal (Admissions/Portal, unauthenticated) ---------- */
/* Same _LoginLayout shell as the sign-in screen, but wider - these pages hold real forms/tables, not
   just a username/password pair. */
.portal-card {
    position: relative;
    background-color: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 2.5rem;
    width: min(960px, 100%);
    margin: 2rem 0;
}
