.auth-card {
    max-width: 420px;
    margin: 40px auto;
}

/*
 * v79 -- the login page's two-column layout: an info panel introducing
 * the software (see views/auth/login.php's own comment for why this was
 * added and what it deliberately does/doesn't highlight) beside the
 * unchanged login card. .login-page-row just adds a little breathing room
 * above the whole row so it doesn't sit flush under the top navbar.
 */
.login-page-row {
    margin-top: 8px;
}

.login-info-panel {
    background: linear-gradient(160deg, #1b2430 0%, #26374d 100%);
    color: #eef2f7;
    border-radius: var(--bs-border-radius-lg, .5rem);
    padding: 32px 30px;
}

.login-info-title {
    font-weight: 700;
    font-size: 1.35rem;
    line-height: 1.4;
    margin-bottom: 14px;
}

.login-info-lead {
    color: #c3cedd;
    margin-bottom: 24px;
}

.login-info-feature {
    margin-bottom: 18px;
}

.login-info-feature:last-child {
    margin-bottom: 0;
}

.login-info-feature h6 {
    color: #8fb8ff;
    font-weight: 700;
    text-transform: uppercase;
    font-size: .78rem;
    letter-spacing: .04em;
    margin-bottom: 8px;
}

.login-info-feature ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.login-info-feature li {
    position: relative;
    padding-left: 22px;
    margin-bottom: 6px;
    font-size: .92rem;
    color: #dde5ee;
}

.login-info-feature li:last-child {
    margin-bottom: 0;
}

.login-info-feature li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    top: 0;
    color: #6fd08c;
    font-weight: 700;
}

/*
 * v79.2 -- a contact line at the bottom of the login info panel (phone
 * number to reach Saiful for more details). A thin top border separates it
 * from the feature list above it, same idea as a card footer.
 */
.login-info-contact {
    margin-top: 22px;
    padding-top: 16px;
    border-top: 1px solid rgba(255, 255, 255, .15);
    font-size: .88rem;
    color: #dde5ee;
}

.login-info-contact strong {
    color: #8fb8ff;
    letter-spacing: .02em;
}

/*
 * v87 -- User Manual download button on the login page. Bright amber so it
 * stands out against the dark navy info panel.
 */
.login-manual-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin: 0 0 20px;
    padding: .7rem 1rem;
    background: #ffc107;
    color: #1c2430;
    font-weight: 700;
    text-decoration: none;
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(255, 193, 7, .35);
}

.login-manual-btn:hover,
.login-manual-btn:focus {
    background: #ffcd39;
    color: #1c2430;
}

.login-manual-link {
    font-weight: 600;
}

/*
 * Left sidebar shell for a school-scoped session (School Admin,
 * Accountant, Teacher, Report Viewer) -- see views/layout/header.php.
 * Not used for a guest or a Super Admin session, which keep the simple
 * top navbar instead.
 */
.app-shell {
    min-height: 100vh;
    align-items: stretch;
}

.app-sidebar {
    width: 230px;
    flex-shrink: 0;
    background: var(--sfc-sidebar-bg, #212529);
    color: var(--sfc-sidebar-text, #fff);
    display: flex;
    flex-direction: column;
    padding: 20px 14px;
}

.app-sidebar .sidebar-brand {
    font-family: var(--sfc-font-head, inherit);
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1.3;
    margin-bottom: 20px;
}

.app-sidebar .sidebar-footer {
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid color-mix(in srgb, var(--sfc-sidebar-text, #fff) 15%, transparent);
}

/*
 * Phase 25 -- the signed-in user's name/role in the sidebar footer used to
 * be Bootstrap's own .text-light/.text-secondary (hardcoded white/grey),
 * which is invisible on the light-sidebar themes (Slate Minimal, Sunrise
 * Amber, Rose Garden, Graphite Contrast) -- caught from an actual
 * screenshot during Phase 25 testing, where the name was unreadable
 * against Sunrise Amber's cream sidebar. Both now derive from the theme's
 * own sidebar text color instead, at full and reduced opacity.
 */
.app-sidebar .sidebar-user-name {
    color: var(--sfc-sidebar-text, #fff);
}

.app-sidebar .sidebar-user-role {
    color: var(--sfc-sidebar-text, #fff);
    opacity: .65;
}

/*
 * Phase 25 -- sidebar nav links. Used to be plain `btn btn-outline-light`
 * buttons, which assumed a dark sidebar background; that breaks on the
 * light-sidebar themes (Slate Minimal, Sunrise Amber, Rose Garden,
 * Graphite Contrast), where a white outline on a near-white background is
 * nearly invisible. This class instead derives its resting, hover, and
 * active colors from the current theme's own sidebar tokens, so it reads
 * correctly against any sidebar background/text pairing. .active is
 * applied by views/layout/header.php based on the current request path.
 */
.sidebar-link {
    display: block;
    width: 100%;
    text-align: left;
    padding: .5rem .75rem;
    margin-bottom: .35rem;
    border-radius: var(--bs-border-radius-sm, .25rem);
    font-size: .875rem;
    font-weight: 500;
    text-decoration: none;
    color: var(--sfc-sidebar-text, #fff);
    background: transparent;
    border: none;
}

.sidebar-link:hover,
.sidebar-link:focus {
    background: color-mix(in srgb, var(--sfc-sidebar-text, #fff) 15%, transparent);
    color: var(--sfc-sidebar-text, #fff);
    text-decoration: none;
}

.sidebar-link.active {
    background: var(--sfc-sidebar-active-bg, #495057);
    color: var(--sfc-sidebar-active-text, #fff);
}

/*
 * Phase 25 -- Bootstrap's .btn-primary hardcodes its own --bs-btn-* colors
 * rather than reading a shared --bs-primary variable, so retheming it
 * needs an explicit override here rather than a single :root variable.
 * Falls back to Bootstrap's own default blue when no theme block has set
 * --sfc-primary (Super Admin/guest pages, which are not school-themed).
 *
 * v85 -- Saiful's own request: buttons read a bit washed out on some of
 * the 9 themes (e.g. Sunrise Amber's orange, Slate Minimal's teal)
 * against typical monitor brightness/contrast. Rather than hand-editing
 * ThemeRegistry's 9 hand-picked hex triples (which would also shift
 * everything else that reads --sfc-primary directly -- outline-button
 * borders, table headers, stat-card accents), every button color below
 * is now a small color-mix() toward black, the same "derive a shade
 * automatically for all themes" technique Phase 28 already established
 * for .btn-outline-secondary/.table-light. A consistent ~12% darken
 * reads as "deeper"/more saturated on every theme without touching a
 * single theme's own token values or anything non-button that shares
 * them.
 */
.btn-primary {
    --bs-btn-bg: color-mix(in srgb, var(--sfc-primary, #0d6efd) 88%, black);
    --bs-btn-border-color: color-mix(in srgb, var(--sfc-primary, #0d6efd) 88%, black);
    --bs-btn-hover-bg: color-mix(in srgb, var(--sfc-primary-hover, #0b5ed7) 88%, black);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--sfc-primary-hover, #0b5ed7) 88%, black);
    --bs-btn-active-bg: color-mix(in srgb, var(--sfc-primary-active, #0a58ca) 88%, black);
    --bs-btn-active-border-color: color-mix(in srgb, var(--sfc-primary-active, #0a58ca) 88%, black);
    --bs-btn-disabled-bg: color-mix(in srgb, var(--sfc-primary, #0d6efd) 88%, black);
    --bs-btn-disabled-border-color: color-mix(in srgb, var(--sfc-primary, #0d6efd) 88%, black);
    --bs-btn-color: var(--sfc-primary-text, #fff);
    --bs-btn-hover-color: var(--sfc-primary-text, #fff);
    --bs-btn-active-color: var(--sfc-primary-text, #fff);
    --bs-btn-disabled-color: var(--sfc-primary-text, #fff);
}

/* Phase 25 -- heading font follows the theme's head-font pairing. */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--sfc-font-head, inherit);
}

/*
 * Phase 28 -- extends Phase 25's per-school theming past just the
 * primary button and sidebar: outline buttons, table headers, and
 * dashboard/summary "stat" cards now pick up the school's own theme
 * colors too, so a themed school reads as consistently "branded" on
 * every screen rather than just the sidebar and Save/Filter buttons.
 * Saiful asked for this after seeing a sample mockup of all 9 themes.
 *
 * Deliberately left untouched: .badge/.text-bg-* status colors
 * (Posted/green, Cancelled/red, Edited/blue, etc.) and the semantic
 * .btn-outline-danger/-success/-warning buttons -- these carry a fixed
 * meaning across the whole app (green = fine, red = a problem) and
 * retheming them per school would make that meaning less reliable to
 * read at a glance. Only "chrome" (buttons, headers, card accents)
 * follows the theme; status/meaning colors do not.
 *
 * Uses color-mix() to derive tints/shades of --sfc-primary rather than
 * hand-picking a matching light/dark color per theme -- the same
 * technique .sidebar-link:hover already uses above -- so this works
 * automatically for all 9 (and any future) themes with no per-theme
 * color list to maintain. Falls back to Bootstrap's own neutral grays
 * when --sfc-primary isn't set (Super Admin/guest pages, which are not
 * school-themed), via color-mix()'s own var() fallback argument.
 */

/*
 * Outline-primary buttons (View/Refresh/etc.) -- same primary color as
 * the solid button, just as an outline, instead of Bootstrap's default
 * blue regardless of theme. The resting outline/text color is left as
 * the theme's plain --sfc-primary (it's a border/text color here, not a
 * filled background, so it doesn't read "washed out" the way a filled
 * button does) -- only hover/active, which DO fill solid, get the same
 * v85 color-mix() darken .btn-primary above uses, so a hovered outline
 * button matches its solid sibling's "deeper" fill exactly.
 */
.btn-outline-primary {
    --bs-btn-color: var(--sfc-primary, #0d6efd);
    --bs-btn-border-color: var(--sfc-primary, #0d6efd);
    --bs-btn-hover-bg: color-mix(in srgb, var(--sfc-primary, #0d6efd) 88%, black);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--sfc-primary, #0d6efd) 88%, black);
    --bs-btn-hover-color: var(--sfc-primary-text, #fff);
    --bs-btn-active-bg: color-mix(in srgb, var(--sfc-primary-active, #0a58ca) 88%, black);
    --bs-btn-active-border-color: color-mix(in srgb, var(--sfc-primary-active, #0a58ca) 88%, black);
    --bs-btn-active-color: var(--sfc-primary-text, #fff);
    --bs-btn-disabled-color: var(--sfc-primary, #0d6efd);
    --bs-btn-disabled-border-color: var(--sfc-primary, #0d6efd);
}

/*
 * Outline-secondary buttons -- by far the most common secondary-action
 * button in this app (Back/View/Print/Edit and so on, ~40 uses across
 * the views). Previously plain Bootstrap gray on every theme; now a
 * soft, theme-tinted "chip" (a light tint fill + a matching tinted
 * border) instead of a flat gray outline, matching the sample mockup's
 * "soft" button style.
 */
.btn-outline-secondary {
    --bs-btn-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 80%, #1c2430);
    --bs-btn-border-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 35%, white);
    --bs-btn-bg: color-mix(in srgb, var(--sfc-primary, #6c757d) 8%, white);
    --bs-btn-hover-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 85%, #1c2430);
    --bs-btn-hover-bg: color-mix(in srgb, var(--sfc-primary, #6c757d) 18%, white);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 45%, white);
    --bs-btn-active-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 85%, #1c2430);
    --bs-btn-active-bg: color-mix(in srgb, var(--sfc-primary, #6c757d) 24%, white);
    --bs-btn-active-border-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 50%, white);
    --bs-btn-disabled-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 80%, #1c2430);
    --bs-btn-disabled-border-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 35%, white);
}

/*
 * Table headers -- <thead class="table-light"> is used on nearly every
 * data table in the app (students, receipts, reports, fee structures,
 * and so on). Previously plain Bootstrap gray; now a faint tint of the
 * theme's own primary color, so every table reads as part of the same
 * branded page instead of a generic gray grid. Bootstrap paints this
 * per-cell via --bs-table-bg (see .collect-fee-lines above for the
 * same mechanism), so overriding these three variables on .table-light
 * itself is enough to retint every th/td inside it, sticky headers
 * included.
 */
.table-light {
    --bs-table-bg: color-mix(in srgb, var(--sfc-primary, #6c757d) 7%, white);
    --bs-table-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 70%, #1c2430);
    --bs-table-border-color: color-mix(in srgb, var(--sfc-primary, #6c757d) 18%, white);
}

/*
 * "Stat" summary cards (Dashboard's Active Students/Today's
 * Collection/etc., Collection Summary's Receipts/Total Collected/etc.)
 * -- a colored left accent bar plus an icon in a soft tinted circle,
 * both keyed to the theme's primary color, in place of a plain white
 * card. .stat-icon is sized for a small inline SVG (see the two views
 * that use it); any icon markup works as long as it fills the circle.
 */
.stat-card {
    border-left: 4px solid var(--sfc-primary, #0d6efd);
}

.stat-card .card-body {
    display: flex;
    align-items: center;
    gap: 14px;
}

.stat-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--bs-border-radius, .375rem);
    background: color-mix(in srgb, var(--sfc-primary, #0d6efd) 15%, white);
    color: var(--sfc-primary, #0d6efd);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.stat-icon svg {
    width: 20px;
    height: 20px;
}

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

/* The school branding card at the top of every school-scoped page. */
.school-header-card {
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: var(--bs-border-radius-lg, .5rem);
    padding: 14px 20px;
    margin-bottom: 20px;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.school-header-card img {
    width: 56px;
    height: 56px;
    object-fit: contain;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: var(--bs-border-radius, .375rem);
    padding: 4px;
}

.school-header-card .school-name {
    font-family: var(--sfc-font-head, inherit);
    font-weight: 700;
    font-size: 1.15rem;
    margin: 0;
}

.school-header-card .school-address {
    color: #6c757d;
    font-size: .85rem;
}

.school-header-card .school-meta {
    color: #495057;
    font-size: .85rem;
    margin-top: 2px;
}

/*
 * Collect Fee screen: highlight the whole row (Fee Item, Type, Previous
 * Deposit, Starting/Ending Month, Collect Now) while the cursor is in any
 * of that row's inputs, so the item you're entering an amount for stays
 * visually anchored across a long fee-item list. :focus-within covers the
 * month pickers and the Collect Now amount field alike, without any JS.
 *
 * Bootstrap 5.3's own .table CSS paints an opaque background on every
 * *cell* (`.table > :not(caption) > * > * { background-color:
 * var(--bs-table-bg); }`), not on the <tr> -- so a plain background-color
 * set here on tr would be invisible, painted over by each <td>'s own
 * white background. Overriding the --bs-table-bg custom property instead
 * (exactly how Bootstrap implements .table-active/.table-hover) cascades
 * down to every cell in this row automatically. The plain background-color
 * below is only a fallback for if Bootstrap's CSS fails to load.
 */
.collect-fee-lines tbody tr:focus-within {
    --bs-table-bg: var(--bs-warning-bg-subtle, #fff3cd);
    background-color: var(--bs-warning-bg-subtle, #fff3cd);
}

/*
 * Phase 26 -- client-requested hard stop against overpaying a fee item
 * that has a genuine, pre-determined Required Amount (an ad-hoc item like
 * Fine, priced at 0, is exempt -- see checkOverpay() in collect.php and
 * edit.php, and FeeCollectionService::assertWithinRequiredAmount() for
 * the real, server-side enforcement this is only a live preview of). A
 * solid, unambiguous red -- not one of the app's usual "-subtle" tints --
 * on the input itself, so it reads clearly as "this will be rejected"
 * even inside an already-highlighted (focused) row. !important overrides
 * Bootstrap's own form-control background.
 */
.amount-overpay {
    background-color: var(--bs-danger, #dc3545) !important;
    color: #fff !important;
}

/*
 * The opposite, positive cue: Previous Deposit + Collect Now exactly
 * equals the item's Required Amount, i.e. this item will be fully
 * settled by this receipt. Same scope as .amount-overpay (only items
 * with a genuine Required Amount > 0). Solid green, !important for the
 * same reasons as .amount-overpay above (beats Bootstrap's own
 * form-control background, also on a disabled already-paid row).
 */
.amount-exact {
    background-color: var(--bs-success, #198754) !important;
    color: #fff !important;
}

/*
 * Phase 17 -- a tighter row height than Bootstrap's own .table-sm, for a
 * long list (the Defaulter List is the first user of this) where the
 * person mainly wants to scan as many rows as fit on screen at once.
 * Bootstrap's .table-sm already halves the default cell padding to
 * .5rem 0.5rem-ish; this halves it again.
 */
.table-tight > :not(caption) > * > * {
    padding-top: .2rem;
    padding-bottom: .2rem;
    line-height: 1.2;
}

/*
 * Phase 17 -- Collect Fee's fee-item list runs 12-20+ rows once every
 * one-time item plus a monthly item like Tuition Fee is listed, pushing
 * Payment Date/Discount/Post Receipt far down the page (client feedback:
 * screenshots showed only ~6 rows fitting before scrolling the whole
 * page). This caps the list to roughly 8 rows' worth of height and
 * scrolls the rest inside its own small box instead -- nested inside the
 * existing .table-responsive wrapper below, so horizontal scrolling on a
 * narrow screen still works too. .table-tight (above) supplies the
 * tighter row height the client picked (their "Option B") so 8 rows fit
 * in a shorter box than the default row height would allow. The header
 * stays pinned via position: sticky so the column labels are never
 * scrolled out of view -- an explicit box-shadow stands in for a bottom
 * border, since Bootstrap's .table-light background alone wouldn't show
 * a division line against the sticky header once rows scroll under it.
 */
.collect-fee-scroll {
    max-height: 300px;
    overflow-y: auto;
}

.collect-fee-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    box-shadow: inset 0 -1px 0 var(--bs-border-color, #dee2e6);
}

@media (max-width: 767.98px) {
    .app-shell {
        flex-direction: column;
    }

    .app-sidebar {
        width: 100%;
        min-height: auto;
    }
}

/*
 * Phase 25 -- Super Admin's theme picker (views/schools/edit.php). Each
 * theme is a radio input wrapped in a <label>, so clicking anywhere on the
 * card selects it; the input itself is visually hidden but stays in the
 * tab order and reachable by keyboard. The card highlights (border +
 * shadow) when its radio is :checked, using the plain sibling combinator
 * rather than JS.
 */
.theme-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
}

.theme-option-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.theme-option-card {
    display: block;
    cursor: pointer;
    border: 2px solid #dee2e6;
    border-radius: .5rem;
    padding: 12px;
    height: 100%;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.theme-option-input:checked + .theme-option-card {
    border-color: #0d6efd;
    box-shadow: 0 0 0 .2rem rgba(13, 110, 253, .15);
}

.theme-option-input:focus-visible + .theme-option-card {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
}

.theme-option-swatch {
    display: flex;
    border-radius: .35rem;
    overflow: hidden;
    height: 34px;
    margin-bottom: 8px;
    border: 1px solid rgba(0, 0, 0, .08);
}

.theme-option-swatch span {
    flex: 1;
}

.theme-option-name {
    display: block;
    font-weight: 700;
    font-size: .92rem;
}

.theme-option-name-bn {
    display: block;
    font-size: .85rem;
    color: #495057;
    margin-bottom: 4px;
}

.theme-option-blurb {
    display: block;
    font-size: .78rem;
    color: #6c757d;
}

.theme-option-current {
    display: inline-block;
    margin-top: 6px;
}

/*
 * Site-wide: hide the browser's built-in up/down spinner arrows on every
 * <input type="number"> (fee amounts, Roll, sort_order, extra_rows, and
 * so on) -- a plain, unstyled text-style entry field everywhere instead,
 * matching how amounts already look on most of this app's forms. Applies
 * globally since app.css is loaded on every school-scoped, guest, Super
 * Admin, and Student Portal page alike; no per-page opt-in needed.
 */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}

/* v87 -- Large theme radii (Royal Sapphire / Sunrise Amber / Rose Garden use
 * 999px "pill" radii) made wide, multi-line cards curve so much that text hugged
 * or crossed the edge. Cards, the school header card and tab panes now cap their
 * corner radius; small controls (buttons, inputs, badges) keep the full pill. */
:root {
    --sfc-card-radius-cap: 45px;
}
.card,
.school-header-card {
    --bs-card-border-radius: min(var(--bs-border-radius, .375rem), var(--sfc-card-radius-cap));
    --bs-card-inner-border-radius: calc(min(var(--bs-border-radius, .375rem), var(--sfc-card-radius-cap)) - 1px);
    border-radius: min(var(--bs-border-radius, .375rem), var(--sfc-card-radius-cap));
}
.school-header-card {
    border-radius: min(var(--bs-border-radius-lg, .5rem), var(--sfc-card-radius-cap));
}
/* Extra side padding when the cap is in effect, so text stays clear of the curve. */
.card-body {
    padding-inline: max(var(--bs-card-spacer-x, 1rem), calc(min(var(--bs-border-radius, 0px), var(--sfc-card-radius-cap)) * .6));
}
