/*
 * Dark Theme (opt-in color mode)
 * -----------------------------------------------------------------------
 * Every rule in this file is scoped under `body.theme-dark` (or the more
 * specific `body.theme-material.theme-dark`) so that it is strictly
 * additive: with those classes absent (the default "Light" mode) nothing
 * here applies and the app renders pixel-identical to before this file
 * existed.
 *
 * This is an INDEPENDENT axis from the Modern/Material style switcher
 * (material-theme.css, scoped under body.theme-material). A user can land
 * on any of the 4 combinations:
 *   - Modern  + Light   (default, unaffected by either theme file)
 *   - Modern  + Dark    -> covered by the base `body.theme-dark` rules
 *                          below, layered on top of style.css/sidenav.css
 *   - Material+ Light   (default Material look, unaffected by this file)
 *   - Material+ Dark    -> `body.theme-dark` rules apply first, then the
 *                          `body.theme-material.theme-dark` section further
 *                          down overrides the Material design-token
 *                          variables (--md-*) so every Material component
 *                          that already reads those variables picks up
 *                          dark surfaces/borders/shadows for free.
 *
 * Do NOT edit style.css / sidenav.css / color.css / material-theme.css to
 * add dark-mode rules - add them here instead.
 */

/* =========================================================================
   MODERN + DARK  (body.theme-dark, Material class absent)
   Keeps Modern's soft/rounded aesthetic (rounded corners, gentle shadows)
   but swaps the light palette for a dark one.
   ========================================================================= */

body.theme-dark {
    --dk-bg: #14161f;
    --dk-surface: #1e2230;
    --dk-surface-alt: #262b3a;
    --dk-border: #333a4d;
    --dk-border-strong: #454c62;

    --dk-text: #e6e8ee;
    --dk-text-secondary: #c1c5d1;
    --dk-text-muted: #9aa0b2;

    --dk-shadow: rgba(0, 0, 0, .45);

    /* Lighter tint of the brand primary, used only where the color sits as
       FOREGROUND text/icons directly on a dark surface (outline buttons,
       .text-primary, links) - #5d60ef read as text-on-dark falls under the
       ~4.5:1 AA threshold for normal text, this tint clears it comfortably.
       Solid fills (btn-primary, active nav, badges) keep using the
       unmodified --bs-primary since white-on-#5d60ef is already high
       contrast and shouldn't shift between light/dark mode. */
    --dk-primary-text: #9799ff;

    background-color: var(--dk-bg);
    color: var(--dk-text);
}

/* ---- Page shell ---- */

body.theme-dark .app-wrapper {
    background: var(--dk-bg);
}

body.theme-dark .app-main,
body.theme-dark main.app-content {
    background: var(--dk-bg);
    color: var(--dk-text);
}

body.theme-dark .sidebar {
    background: var(--dk-surface);
    border-right-color: var(--dk-border);
}

body.theme-dark .sidebar-menu li a {
    color: var(--dk-text-muted);
}

body.theme-dark .sidebar-menu li.active a,
body.theme-dark .sidebar-menu li a:hover {
    background: var(--bs-primary);
    color: #fff;
}

body.theme-dark .offcanvas {
    background: var(--dk-surface);
    color: var(--dk-text);
}

body.theme-dark .offcanvas-header {
    border-bottom-color: var(--dk-border);
}

body.theme-dark .offcanvas .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

body.theme-dark .topnav {
    background: var(--dk-surface);
    border-bottom-color: var(--dk-border);
}

body.theme-dark .topnav-left h6 {
    color: var(--dk-text) !important;
}

body.theme-dark .topnav-right > .dropdown > a {
    color: var(--dk-text);
}

body.theme-dark .topnav-right img.rounded-circle {
    border: 1px solid var(--dk-border-strong);
}

/* ---- Text utilities (unmodified Bootstrap defaults are unreadable on a
   dark surface, so give the ones used across the app a dark-aware value) ---- */

body.theme-dark .text-muted,
body.theme-dark .text-secondary {
    color: var(--dk-text-muted) !important;
}

body.theme-dark .text-primary {
    color: var(--dk-primary-text) !important;
}

body.theme-dark .text-danger {
    color: #ff6b7a !important;
}

body.theme-dark small {
    color: inherit;
}

/* =========================================================================
   Buttons
   ========================================================================= */

body.theme-dark .btn {
    color: var(--dk-text);
}

body.theme-dark .btn-primary {
    color: #fff;
}

body.theme-dark .btn-outline-primary {
    background: transparent;
    color: var(--dk-primary-text);
    border-color: var(--dk-primary-text);
}

body.theme-dark .btn-outline-primary:hover,
body.theme-dark .btn-outline-primary:focus,
body.theme-dark .btn-outline-primary:active {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
    color: #fff;
}

body.theme-dark .btn-outline-secondary {
    background: transparent;
    color: var(--dk-text-secondary);
    border-color: var(--dk-border-strong);
}

body.theme-dark .btn-outline-secondary:hover,
body.theme-dark .btn-outline-secondary:focus,
body.theme-dark .btn-outline-secondary:active {
    background-color: var(--dk-surface-alt);
    border-color: var(--dk-border-strong);
    color: var(--dk-text);
}

body.theme-dark .btn-danger {
    color: #fff;
}

body.theme-dark .ui-btn-group .btn:not(.active) {
    background: var(--dk-surface-alt);
    color: var(--dk-primary-text);
}

body.theme-dark .ui-btn-group .btn:not(.active):hover {
    background: rgba(93, 96, 239, .25);
}

body.theme-dark .ui-btn-group .btn.active {
    color: #fff;
}

/* =========================================================================
   Cards / surfaces
   ========================================================================= */

body.theme-dark .card,
body.theme-dark .exam-timer,
body.theme-dark .attendance-date-btn,
body.theme-dark .cover-card,
body.theme-dark .users-page,
body.theme-dark .article-card,
body.theme-dark .bg-soft,
body.theme-dark .feed-card,
body.theme-dark .dashboard-card {
    background-color: var(--dk-surface);
    color: var(--dk-text);
}

body.theme-dark .card,
body.theme-dark .exam-timer,
body.theme-dark .feed-card {
    border-color: var(--dk-border);
    box-shadow: 0 10px 25px var(--dk-shadow);
}

/* .info-card's visible surface is a full-bleed photo (.info-img,
   position:absolute over the card), not the themed --dk-surface fill
   underneath it - .info-title/.info-sub overlaid on that photo must stay
   at their original light-mode dark color regardless of theme, or they
   inherit dark mode's light body text color and become illegible on the
   light photo (confirmed by rendering - "Teachers"/"Students" titles were
   invisible). */
body.theme-dark .info-card {
    box-shadow: 0 10px 30px var(--dk-shadow);
}

body.theme-dark .info-title {
    color: #1f2937;
}

/* .dashboard-card carries its own background-image banner (see
   dashboard.css) rather than a flat surface fill - dark mode only needs to
   darken its border/overlay, not override the background entirely. */
body.theme-dark .dashboard-card {
    border: 1px solid var(--dk-border);
    box-shadow: 0 10px 25px var(--dk-shadow);
}

body.theme-dark .custom-badge {
    background: rgba(255, 255, 255, 0.08);
    color: var(--dk-text);
}

/* dashboard.css defines several classes with hardcoded gray/dark text
   colors (#111, #374151, #6b7280) that have no fixed background of their
   own - they sit directly on the themed .feed-card surface, so in dark
   mode the ambient background goes dark while this text stayed hardcoded
   dark too. Confirmed by real-device screenshot: post author names
   (.user-name-link) were nearly invisible; the same shape of bug applies
   to the post/reaction action buttons, small in-card icons, and the poll
   box's own fixed light background. */
body.theme-dark .user-name-link {
    color: var(--dk-text);
}

body.theme-dark .post-actions button,
body.theme-dark .feed-actions button,
body.theme-dark .reaction-btn {
    color: var(--dk-text-secondary);
}

body.theme-dark .post-actions button:hover,
body.theme-dark .feed-actions button:hover,
body.theme-dark .reaction-btn:hover,
body.theme-dark .poll-option-box:hover {
    background: var(--dk-surface-alt);
}

body.theme-dark .feed-card i {
    color: var(--dk-text-muted);
}

body.theme-dark .poll-box {
    background: var(--dk-surface-alt);
}

/* Bootstrap's .shadow/.shadow-sm/.shadow-lg utilities compile with
   !important and are used directly on several cards app-wide (e.g. the
   login/register/reset auth cards use .shadow-lg) - without this, those
   elements keep Bootstrap's light-mode-tuned shadow color even in dark
   mode, which reads as a pale halo against a dark surface. Re-tint them
   with the same --dk-shadow used for .card/.feed-card above, at roughly
   matching blur/spread per utility size. */
body.theme-dark .shadow {
    box-shadow: 0 .5rem 1rem var(--dk-shadow) !important;
}

body.theme-dark .shadow-sm {
    box-shadow: 0 .125rem .25rem var(--dk-shadow) !important;
}

body.theme-dark .shadow-lg {
    box-shadow: 0 1rem 3rem var(--dk-shadow) !important;
}

/* Bootstrap's .bg-light utility (also !important) is used ~43 times across
   the app for recessed card rows (user list items, online-users rows,
   birthday-celebrant rows, etc.) - confirmed by real phone screenshots
   that without this, dark mode leaves it at Bootstrap's light gray while
   the text inside inherits dark mode's light text color from its
   ancestor .card/.feed-card - light text on a light row, illegible.
   .badge.bg-light already had its own override above; this covers every
   other use of the utility. */
body.theme-dark .bg-light {
    background-color: var(--dk-surface-alt) !important;
}

/* Same photo-backdrop reasoning as .info-title above - stays at its
   original light-mode color (style.css's own #6b7280), not the dark-mode
   muted token. */
body.theme-dark .info-sub {
    color: #6b7280;
}

body.theme-dark .cover-card {
    box-shadow: 0 10px 25px var(--dk-shadow);
}

body.theme-dark .attendance-date-btn {
    background: var(--dk-surface-alt);
}

body.theme-dark .attendance-date-btn .time {
    color: var(--dk-text-muted);
}

body.theme-dark .attendance-date-btn:hover {
    background: var(--bs-primary);
}

body.theme-dark .attendance-date-btn:hover .date,
body.theme-dark .attendance-date-btn:hover .time {
    color: #fff;
}

body.theme-dark .exam-timer .timer-title {
    color: var(--dk-text-secondary);
}

body.theme-dark .timer-box {
    background: var(--dk-surface-alt);
    border-color: var(--dk-border);
}

body.theme-dark .timer-box span {
    color: var(--dk-text-muted);
}

/* =========================================================================
   Forms
   ========================================================================= */

body.theme-dark .form-control,
body.theme-dark .form-select,
body.theme-dark .ui-search input {
    background-color: var(--dk-surface-alt);
    border-color: var(--dk-border-strong);
    color: var(--dk-text);
}

body.theme-dark .form-control:focus,
body.theme-dark .form-select:focus,
body.theme-dark .ui-search input:focus {
    background-color: var(--dk-surface-alt);
    border-color: var(--bs-primary);
    color: var(--dk-text);
    box-shadow: 0 0 0 .2rem rgba(93, 96, 239, .25);
}

body.theme-dark .form-control::placeholder,
body.theme-dark .ui-search input::placeholder {
    color: var(--dk-text-muted);
    opacity: 1;
}

body.theme-dark .ui-search i {
    color: var(--dk-text-muted);
}

/* Bootstrap's <select> caret / native color-scheme so options render on a
   dark surface instead of forcing white-on-white in some browsers. */
body.theme-dark .form-select {
    color-scheme: dark;
}

body.theme-dark .form-check-input {
    background-color: var(--dk-surface-alt);
    border-color: var(--dk-border-strong);
}

body.theme-dark .form-check-input:checked {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
}

/* =========================================================================
   Dropdowns
   ========================================================================= */

body.theme-dark .dropdown-menu {
    background-color: var(--dk-surface);
    border-color: var(--dk-border);
    box-shadow: 0 10px 30px var(--dk-shadow);
}

body.theme-dark .dropdown-item {
    color: var(--dk-text-secondary);
}

body.theme-dark .dropdown-item:hover,
body.theme-dark .dropdown-item:focus {
    background-color: var(--dk-surface-alt);
    color: var(--dk-text);
}

body.theme-dark .dropdown-item.active,
body.theme-dark .dropdown-item:active {
    background-color: var(--bs-primary);
    color: #fff;
}

body.theme-dark .dropdown-item.text-danger {
    color: #ff6b7a !important;
}

body.theme-dark .dropdown-item.text-danger:hover {
    background-color: rgba(255, 107, 122, .12);
}

body.theme-dark .dropdown-divider {
    border-color: var(--dk-border);
}

body.theme-dark .theme-switcher .theme-option.active {
    background-color: rgba(93, 96, 239, .22);
    color: var(--dk-primary-text);
}

/* =========================================================================
   Badges
   ========================================================================= */

body.theme-dark .badge.bg-light {
    background-color: var(--dk-surface-alt) !important;
    color: var(--dk-text) !important;
}

body.theme-dark .badge.bg-secondary {
    color: #fff;
}

/* =========================================================================
   Modals
   ========================================================================= */

body.theme-dark .modal-content {
    background-color: var(--dk-surface);
    color: var(--dk-text);
    border-color: var(--dk-border);
}

body.theme-dark .modal-header,
body.theme-dark .modal-footer {
    border-color: var(--dk-border);
}

body.theme-dark .modal-header .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* =========================================================================
   .ui-table (used across list/index pages app-wide)
   ========================================================================= */

body.theme-dark .ui-table {
    background: var(--dk-surface);
}

body.theme-dark .ui-table thead th {
    background-color: var(--dk-surface-alt);
    color: var(--dk-text-secondary);
    border-bottom-color: var(--dk-border);
}

body.theme-dark .ui-table tbody td {
    color: var(--dk-text);
    border-bottom-color: var(--dk-border);
}

body.theme-dark .ui-table tbody tr:hover {
    background-color: var(--dk-surface-alt);
}

body.theme-dark .ui-table-empty {
    color: var(--dk-text-muted);
}

/* login/register/reset render the PathBuilder wordmark as a single raster
   image (logo.webp) with the "PathBuilder for Schools" text baked in at a
   fixed dark color, sized for a light card background. On a dark card that
   text becomes nearly invisible (confirmed by rendering - only the
   colored icon glyph stays legible). Can't recolor pixels inside a raster
   image with CSS, so give it a light backdrop patch instead, scoped to
   this specific logo via its alt text so it can't accidentally match the
   different sidebar logo image. */
body.theme-dark img[alt="PathBuilder School logo"] {
    background: #fff;
    border-radius: 12px;
    padding: 8px;
}

/* =========================================================================
   MATERIAL + DARK  (body.theme-material.theme-dark)
   material-theme.css builds every Material component off of a shared set
   of --md-* design-token variables declared on `body.theme-material`.
   Re-declaring those same variables here - under the more specific
   `body.theme-material.theme-dark` selector - is enough to make every
   Material surface/border/text-on-surface pick up dark values without
   duplicating each component rule; only the few things that need a
   genuinely different treatment on dark (borders needing to read lighter,
   elevation shadows needing more contrast against an already-dark
   surface) get an explicit rule below.
   ========================================================================= */

body.theme-material.theme-dark {
    --md-primary: var(--bs-primary, #5d60ef);
    --md-primary-dark: #4547c9;
    /* white-on-filled-primary stays high contrast in both modes - the
       Material top app bar/active nav/filled buttons don't need to change. */
    --md-on-primary: #ffffff;
    --md-primary-tint: rgba(93, 96, 239, .22);
    --md-on-primary-tint: #b8baff;

    --md-surface: var(--dk-surface);
    --md-surface-alt: var(--dk-surface-alt);
    --md-on-surface: var(--dk-text);
    --md-on-surface-variant: var(--dk-text-muted);

    /* Material leans on visible 1px borders more than Modern does, so give
       them extra lightness/contrast against the dark surface rather than
       reusing Modern's slightly dimmer --dk-border. */
    --md-border: #454c62;
    --md-border-strong: #59617c;

    --md-error: #ff6b7a;
    --md-error-tint: rgba(255, 107, 122, .15);

    /* Elevation shadows read as depth cues against a LIGHT surface in the
       original Material spec; on a dark surface a same-toned shadow all
       but disappears, so darken/strengthen them instead of trying to
       fully replicate Material's dark-theme surface-tint elevation system. */
    --md-elevation-1: 0 1px 2px 0 rgba(0, 0, 0, .55), 0 1px 3px 1px rgba(0, 0, 0, .35);
    --md-elevation-2: 0 1px 2px 0 rgba(0, 0, 0, .55), 0 2px 6px 2px rgba(0, 0, 0, .35);
    --md-elevation-4: 0 2px 3px 0 rgba(0, 0, 0, .55), 0 6px 10px 4px rgba(0, 0, 0, .35);
    --md-elevation-8: 0 4px 4px 0 rgba(0, 0, 0, .55), 0 8px 12px 6px rgba(0, 0, 0, .35);
    --md-elevation-16: 0 8px 10px -5px rgba(0, 0, 0, .5), 0 16px 24px 2px rgba(0, 0, 0, .45), 0 6px 30px 5px rgba(0, 0, 0, .4);

    background-color: var(--dk-bg);
}

body.theme-material.theme-dark .app-wrapper {
    background: var(--dk-bg);
}

/* Material's sidebar nav rows use --md-on-surface-variant for idle text and
   a solid --md-primary fill for the active row - both already flip to dark
   values via the variable overrides above, no extra rule needed. */

body.theme-material.theme-dark .topnav > .btn:hover,
body.theme-material.theme-dark .topnav > .btn:focus {
    background-color: rgba(255, 255, 255, .12);
}
