:root {
    --tw-empty: ;
}

html.dark *:not(#cke_editor):not(#cke_editor *) {
    border-color: var(--border);
}

html.dark {
    color: var(--text);
    /* light-on-dark text renders visually heavier; thinning it back is the single
       biggest comfort win on a dark theme */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/*html.dark table th {*/
/*    text-transform: uppercase !important;*/
/*}*/

:root {
    --bg: #f8fafc;
    --thead-bg: #cacfd9; /* page background */
    --panel: #cacfd9; /* cards/panels/nav */
    --text: #0f172a; /* main text */
    --muted: #64748b; /* subdued text */
    --border: #e5e7eb; /* borders/dividers */
    --hover: #f1f5f9; /* hover background */
}

/* Dark palette — surfaces climb in ~4 L* steps so elevation reads without harsh jumps.
   Tokens also cover the AMS/UMS shells, which get their own root class. */
html.dark,
html.dark-ams,
html.dark-ums {
    /* surfaces */
    --bg: #0f1218; /* app background */
    --card: #1a1f29; /* cards / panels / nav — one clear step above --bg */
    --panel: #1a1f29;
    --thead-bg: #222836; /* table headers — one step above --card, a shade under the field fill */
    --thead-border: #2f3644; /* th top/bottom lines — a hint above --thead-bg, not a grid line */
    --hover: #232a36; /* row / menu-item hover */
    --elevated: #313a4b; /* raised chips, filled gray blocks */

    /* lines */
    --border: #252b36; /* dividers — quiet, the surfaces carry the structure */
    --card-border: #2a303c; /* card outline — a hairline just above the card; depth comes from the bg step + shadow */

    /* Form fields sit one step ABOVE the card as a soft fill. A dark well plus a
       hard 1px outline turned every field into a heavy box - on a filter panel
       with 20 of them that is all you see. The fill carries the shape now, so
       the border only has to hint at the edge. */
    --input-bg: #252c3a;
    --input-border: #303846;
    --input-border-hover: #434c5e;

    /* text — three steps, never pure white (pure white on near-black haloes) */
    --text: #ccd3df; /* body */
    --text-bright: #e3e8f0; /* headings, labels, field text */
    --text-soft: #aeb8c7;
    --muted: #98a3b4; /* secondary — 6.7:1 on --card */
    --muted-dim: #838d9d; /* placeholders, out-of-range dates — 4.5:1 on --input-bg */
    /* Chart axis/legend text. A step above --muted: this is 11-13px SVG text with
       no font-smoothing help, so the body-text ramp reads better than the
       secondary one. 8.9:1 on --card. */
    --apex-text: var(--text-soft);

    /* accent */
    --accent: #818cf8;
    --accent-muted: #2f3d6b; /* selected rows, select2 highlight */
    --scrollbar: #39424f;

    /* alerts — one tint/edge/text triple per hue. The toast and the inline card
       are the same component at two elevations, so they share the triple and
       differ only in shadow. The tints are alpha so they compose over whatever
       surface the alert lands on (page, card, modal).

       Error runs hue 28, not the 25 the red utilities use. Chroma is what keeps a
       thin tint readable as red: a LOW-chroma red laid thin over this blue-grey
       card composites to plum (#351c24, blue channel above green), which is what
       made the alerts look muddy. Pushing the source to 0.28 C buys the headroom
       to drop the alpha to 22% for the glassy look without losing the hue — the
       fill lands on #48151b, red still 51 clear of green. Both hues share that
       22% so the pair reads as the same material; the toasts add backdrop-blur
       further down, which is what actually sells it over live page content. */
    --alert-error-bg: oklch(58% 0.28 28 / 0.22);
    --alert-error-edge: oklch(70% 0.24 28 / 0.6);
    --alert-error-text: oklch(78% 0.20 28);
    --alert-ok-bg: oklch(62% 0.20 152 / 0.22);
    --alert-ok-edge: oklch(70% 0.18 152 / 0.55);
    --alert-ok-text: oklch(86% 0.16 152);

    /* elevation — 1px hairline ring for the edge, soft shadow for depth.
       The ring is split out because a card that declares its own `border` class
       would otherwise show the ring as a second edge 1px outside its border. */
    --card-ring: 0 0 0 1px var(--card-border);
    /* Ring plus a soft dark drop shadow underneath, no inset lit top edge — next to the
       ring that read as a second border along the top of every card. */
    --card-depth: 0 1px 2px rgb(0 0 0 / 0.3), 0 6px 16px -6px rgb(0 0 0 / 0.45);
    --card-shadow: var(--card-ring), var(--card-depth);
}

/* THEME helpers (use !important to override existing utility classes) */

.theme-bg {
    background-color: var(--bg) !important;
    color: var(--text) !important;
}

.theme-panel {
    background-color: var(--panel) !important;
}

.theme-text {
    color: var(--text) !important;
}

.theme-muted {
    color: var(--muted) !important;
}

.theme-border {
    border-color: var(--border) !important;
}

.theme-hover:hover {
    background-color: var(--hover) !important;
}

/* Cards: 1px ring + soft depth shadow.
   Cards have no hover state: they are containers, not controls, so the edge
   stays put under the cursor.

   Form controls are excluded: Tailwind puts shadow-sm on almost every input and
   select in this app, and a card ring on top of the field's own 1px border is
   what made every field look like a heavy double-bordered box. */
html.dark :is(.shadow, .shadow-sm, .shadow-md, .shadow-lg, .shadow-xl):not(input):not(select):not(textarea) {
    box-shadow: var(--card-shadow) !important;
}

/* Containers the .shadow-* rule above misses. The unqualified .bg-white.shadow-*
   and .rounded-lg.shadow selectors below also match a FIELD carrying bg-white +
   shadow-sm, so form controls are excluded from those too.

   The :has(> div) pair is div-only: menu items are `<a class="rounded-lg ...">`
   wrapping an icon plus a text `<div>`, so an unqualified selector drew a card
   ring around every row of an open dropdown (the AMS topbar menus). Panels that
   really need the ring carry a shadow-* class and the rule above covers them. */
html.dark div.rounded-lg:has(> div),
html.dark div.rounded-md:has(> div),
html.dark form div.shadow,
html.dark div.bg-white.rounded,
html.dark div.bg-white.shadow,
html.dark form div.shadow.sm\:rounded-md,
html.dark div.overflow-hidden.shadow,
html.dark .rounded-lg.shadow:not(input):not(select):not(textarea),
html.dark .bg-white.shadow-sm:not(input):not(select):not(textarea),
html.dark .bg-white.shadow-lg:not(input):not(select):not(textarea),
html.dark .bg-white.shadow-xl:not(input):not(select):not(textarea) {
    box-shadow: var(--card-shadow) !important;
}

/* ...but elevation only belongs to the OUTERMOST panel. Several pages wrap a
   card in a card in a card (the attendance filter panel is
   .shadow > .overflow-hidden.shadow > form > .shadow.sm:rounded-md), and each
   level was drawing its own ring plus a 24px halo — three nested boxes of
   shadow. Inner panels keep a hairline so the edge still reads.

   The hairline must be an OUTER ring, not inset. These panels are filled edge to
   edge by an opaque `bg-white` child, which paints straight over an inset shadow —
   an inset hairline here is invisible. That top ring is also what reads as the
   bottom border under a card's "Search Filters" / section heading, since the
   -mx/px reset below stretches the inner panel to the full card width.

   Positioned children are excluded: dropdown and popover panels are shadow-lg
   inside a card and genuinely float. */
html.dark div:is(.shadow, .shadow-sm, .shadow-md, .shadow-lg) div:is(.shadow, .shadow-sm, .shadow-md, .shadow-lg):not(.absolute):not(.fixed) {
    box-shadow: 0 0 0 1px var(--border) !important;
}

/* Panels that outline themselves with `ring-1 ring-black ring-opacity-5` and carry
   no shadow class - the filter panel on fee-receive is one - were missed by both
   rules above, and a 5% black hairline on a dark card is black on black. In light
   mode that ring's TOP edge is the line under a card heading, so the fix is to
   recolour it, not to draw a new border somewhere else: the boundary then lands
   exactly where light mode already puts it, and there is only ever one of it. */
html.dark .ring-black {
    --tw-ring-color: var(--border) !important;
}

/* Inline notices and summary blocks — a rounded div with its own border colour or
   a tint fill — are flat by design. The broad `div.rounded-*:has(> div)` rule
   above treats any rounded wrapper as a card, which put a card ring on top of the
   block's existing border and a panel halo around alerts sitting INSIDE a modal
   (the yellow payroll notice, the red validation box, the picker's selected-
   lectures card). Anything that really is a card carries a shadow-* class and is
   excluded. */
/* A card that draws its own border keeps the depth but drops the ring layer — the
   ring lands 1px outside that border and reads as a doubled edge (the report
   cards are `rounded-md shadow-sm border`). The :not(input):not(select):not(textarea)
   tail is only there to out-specify `.bg-white.shadow-sm:not(…)` above. */
html.dark div[class*="shadow"]:is(.border, [class*="border-"]):not(input):not(select):not(textarea) {
    box-shadow: var(--card-depth) !important;
}

/* ...and that own border takes the card outline colour, not the global divider one,
   so bordered and ringed cards share one edge. Sides only: a coloured accent
   (border-l-4 border-indigo-500 and the like) keeps its own colour. */
html.dark div[class*="shadow"].border:not([class*="border-l-"]):not([class*="border-t-"]):not([class*="-500"]):not([class*="-600"]) {
    border-color: var(--card-border) !important;
}

/* The Tailwind UI wrapper `shadow overflow-hidden border-b border-gray-200 sm:rounded-lg`
   only has a BOTTOM border, so the depth-only rule above left it with no top or side
   edge (trace-voucher's search card, most table wrappers). Give it the full card ring
   and drop that bottom line so it isn't doubled. Nested panels keep the hairline rule. */
html.dark div:is(.shadow, .shadow-sm, .shadow-md, .shadow-lg).border-b:not(.border):not([class*="-500"]):not([class*="-600"]) {
    box-shadow: var(--card-shadow) !important;
    border-bottom-width: 0 !important;
}
html.dark div:is(.shadow, .shadow-sm, .shadow-md, .shadow-lg) div:is(.shadow, .shadow-sm, .shadow-md, .shadow-lg).border-b:not(.border):not(.absolute):not(.fixed) {
    box-shadow: 0 0 0 1px var(--border) !important;
}

html.dark div[class*="rounded"]:is(
    [class*="border-"],
    .bg-gray-50, .bg-red-50, .bg-orange-50, .bg-amber-50, .bg-yellow-50,
    .bg-green-50, .bg-emerald-50, .bg-teal-50, .bg-blue-50, .bg-sky-50,
    .bg-indigo-50, .bg-violet-50, .bg-purple-50, .bg-pink-50, .bg-rose-50,
    .bg-gray-100, .bg-red-100, .bg-orange-100, .bg-amber-100, .bg-yellow-100,
    .bg-green-100, .bg-emerald-100, .bg-teal-100, .bg-blue-100, .bg-sky-100,
    .bg-indigo-100, .bg-violet-100, .bg-purple-100, .bg-pink-100, .bg-rose-100
):not([class*="shadow"]) {
    box-shadow: none !important;
}

/* Theme toggle — segmented sun | moon control (markup in layouts/master).
   A white thumb slides under the active theme's icon. Borders use !important
   because `html.dark *:not(#cke_editor)` carries an id's specificity and
   repaints every border --border; icon colours are scoped through the switch
   because `html.dark svg` greys every icon. */
.theme-toggle-switch {
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border-radius: 9999px;
    cursor: pointer;
    background: #f1f5f9;
    border: 1px solid #e2e8f0 !important;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.theme-toggle-switch:hover {
    border-color: #cbd5e1 !important;
}

.theme-toggle-switch:focus-visible {
    outline: 2px solid #818cf8;
    outline-offset: 2px;
}

.theme-toggle-thumb {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 26px;
    height: 26px;
    border-radius: 9999px;
    background: #fff;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.12), 0 1px 2px rgba(15, 23, 42, 0.08);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.25s ease;
}

.theme-toggle-switch .theme-toggle-icon {
    position: relative; /* above the thumb */
    width: 26px;
    height: 26px;
    padding: 6px;
    color: #94a3b8;
    transition: color 0.25s ease;
}

.theme-toggle-switch .theme-sun-icon { color: #2A2E6E; }
.theme-toggle-switch:hover .theme-moon-icon { color: #64748b; }

html.dark .theme-toggle-switch {
    background: var(--input-bg);
    border-color: var(--input-border) !important;
}

html.dark .theme-toggle-switch:hover {
    border-color: var(--input-border-hover) !important;
}

html.dark .theme-toggle-thumb {
    transform: translateX(28px);
    background: var(--elevated);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

html.dark-ams .theme-toggle-switch
{
    display: none !important;
}

html.dark .theme-toggle-switch .theme-sun-icon { color: var(--muted-dim); }
html.dark .theme-toggle-switch:hover .theme-sun-icon { color: var(--muted); }
html.dark .theme-toggle-switch .theme-moon-icon { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
    .theme-toggle-thumb { transition: none; }
}


/*Dark Mode Css Start*/
/* Neutral surface utilities. Form controls are excluded: 152 inputs in this app
   carry bg-white, and a bare class selector outranks `html.dark input`, so those
   fields were skipping the field treatment and showing up as card-coloured. */
/* Table headers are excluded: `.bg-gray-50` on a thead/th outranked the table
   header block near the bottom of this file (2 classes + 4 elements beats 2 + 3),
   so every sticky-header report table painted its header --card — the same
   colour as the body, which is why the head stopped reading as a head. The
   header block owns --thead-bg; this utility only owns everything else.
   `th` is excluded wherever it appears, not just inside a thead: the detail cards
   (attendance, admission) use `th.bg-gray-50` as a label column next to a plain
   td, and that grey fill IS the distinction — painting it --card like the td left
   those tables with no header either. The exclusions are thead / thead>tr / th
   only, never `thead *` — a plain div or span inside a header cell still needs
   the utility. The same three exclusions are on .bg-gray-100 and .bg-white. */
html.dark .bg-gray-50:not(input):not(select):not(textarea):not(thead):not(thead tr):not(th) {
    background: var(--card) !important;
}

/* Form/pagination footers (`px-4 py-3 text-right bg-gray-50 ... border-t`, ~575 views): the rule above
   paints them --card, the same as the card, so the Search/Clear bar vanished. Light mode shows them a
   step off the card; dark does the same with the table-header surface. */
html.dark div.bg-gray-50.text-right:is(.border-t, .border-b) {
    background: var(--thead-bg) !important;
}

html.dark .bg-gray-500 {
    background: var(--elevated) !important;
}

/* Modal backdrops are `bg-gray-500 bg-opacity-75`. The rule above uses the `background`
   shorthand, which drops --tw-bg-opacity and turns the scrim into a solid slab that hides
   the page behind it -- so overlays keep their own translucent value. */
html.dark .bg-gray-500.bg-opacity-75 {
    background: rgba(23, 23, 23, .8) !important; /* neutral, not the cool-gray page bg */
}

/* :where keeps both exclusions at zero specificity: #sidebar-nav styles its own current
   row, and icons never take the fill (next rule). */
html.dark .bg-gray-100:not(input):not(select):not(textarea):not(thead):not(thead tr):not(th):not(:where(svg, :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *)) {
    background: var(--bg) !important;
}

/* The accounts (ams) sidebar puts its active-link classes on the icon too
   (`<svg class="{{ $a_current }} …">`): no tile behind a bare icon - except in the sidebar
   menu, where every section icon sits in a tile (SIDEBAR MENU). */
html.dark svg.bg-gray-100:not(:where(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *)) {
    background: transparent !important;
}

html.dark .bg-white:not(input):not(select):not(textarea):not(thead):not(thead tr):not(th) {
    background: var(--card) !important;
}

html.dark .hover\:bg-gray-50:hover {
    background: var(--hover) !important;
}

html.dark .text-gray-900 {
    color: var(--text) !important;
}


html.dark .text-gray-700 {
    color: var(--text) !important;
}


html.dark .text-gray-500 {
    color: var(--muted) !important;
}

html.dark tr {
    border-bottom: 1px solid var(--border) !important;
}

/* ...but only when the markup does not already draw that line. Two dividers on
   the same edge, a pixel apart, is the doubled border on the report tables.
   Both patterns are all over the app: `divide-y` on the tbody (admission list),
   and a `border-b` on every cell (the sticky-header report tables, which are
   border-separate so the row border cannot collapse into the cell one). */
html.dark [class*="divide-y"] > tr,
html.dark tr:has(> :is(td, th)[class*="border-b"]) {
    border-bottom: 0 !important;
}

/* Same defect at the head/body seam: `divide-y` on the <table> draws a line on
   the tbody's top edge, and the tr rule draws another on the last header row.
   Only that one row is exempted — the tbody may still be relying on the tr rule
   for its own row separators. */
html.dark table[class*="divide-y"] > thead > tr:last-child {
    border-bottom: 0 !important;
}

html.dark div.shadow {
    box-shadow: var(--card-shadow) !important;
}

/* Dark mode container */
html.dark input,
html.dark textarea,
html.dark select {
    background-color: var(--input-bg) !important; /* soft fill, one step above the card */
    border-width: 1px !important;
    border-color: var(--input-border) !important; /* hints the edge, does not draw a box */
    box-shadow: none !important;
    color: var(--text-bright) !important;
}

/* Hover: fill and border both lift, so the whole control reads as interactive */
html.dark input:hover:not(:focus),
html.dark textarea:hover:not(:focus),
html.dark select:hover:not(:focus) {
    background-color: #262d3c !important;
    border-color: var(--input-border-hover) !important;
}

html.dark input::placeholder,
html.dark textarea::placeholder,
html.dark select::placeholder {
    color: var(--muted-dim) !important; /* lighter gray placeholder */
}

/* The browser's own "Choose File" button keeps its native light chrome inside a
   dark field, so drop its border and theme it like the rest of the control. */
html.dark input[type="file"]::-webkit-file-upload-button,
html.dark input[type="file"]::file-selector-button {
    border: 0 !important;
    background-color: var(--border) !important;
    color: var(--text-bright) !important;
    border-radius: 4px !important;
    padding: 3px 10px !important;
    margin-right: 10px !important;
    cursor: pointer;
}

html.dark [type='checkbox']:checked, html.dark [type='radio']:checked {
    border-color: transparent !important;
    background-color: rgb(129, 140, 248) !important;
    background-size: 100% 100% !important;
    background-position: center !important;
    background-repeat: no-repeat !important;
}

html.dark [type='checkbox']:checked {
    background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e") !important;
}

html.dark [type='checkbox']:focus, html.dark [type='radio']:focus {
    outline: 2px solid transparent !important;
    outline-offset: 2px !important;
    --tw-ring-inset: var(--tw-empty,) !important;
    --tw-ring-offset-width: 2px !important;
    --tw-ring-offset-color: var(--card) !important;
    --tw-ring-color: rgb(129, 140, 248) !important;;
    --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
    --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
    box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow) !important;
}

/* Dollar sign or prefix */
html.dark .shrink-0.text-gray-500 {
    color: var(--muted); /* lighter text for prefix */
}

/* Focus for input & select: the accent border is the whole indicator. No
   outline (it sat against the border and read as 2px) and no ring. */
html.dark input:focus,
html.dark textarea:focus,
html.dark select:focus {
    outline: none;
    border-color: var(--accent) !important;
    box-shadow: none !important;
}

html.dark .focus\:ring-indigo-500:focus {
    --tw-ring-opacity: 1;
    --tw-ring-color: var(--accent);
}

/* Remove number input arrows */
html.dark input[type=number]::-webkit-inner-spin-button,
html.dark input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* SVG icon */
html.dark svg {
    color: var(--muted);
}

/* The rule above paints every icon directly, so an icon inside a filled button
   never inherited the white label next to it: the Print icon on the timetable
   reports page came out muted grey on indigo. text-white is an explicit choice
   about the text in that element, and the icon is part of it. */
html.dark .text-white svg {
    color: inherit;
}

/* Label */
html.dark label {
    color: var(--text-bright); /* light label */
}

html.dark .select2-container--default .select2-selection--single {
    background-color: var(--input-bg) !important; /* card background */
    color: var(--text-bright) !important; /* light text */
    border-color: var(--input-border) !important; /* input border */
}


html.dark .select2-container--default .select2-selection--single .select2-selection__arrow b {
    color: var(--text-bright) !important; /* light text */
}


html.dark .select2-container--default .select2-selection--single .select2-selection__rendered {
    color: var(--text-bright) !important; /* light text */
}

html.dark .select2-container--default .select2-search--inline .select2-search__field::placeholder, html.dark .select2-selection__placeholder {
    color: var(--text-bright) !important; /* light text */
}

html.dark .select2-dropdown {
    color: var(--text-bright) !important; /* light text */
    background-color: var(--hover) !important; /* card background */
    border-color: var(--input-border); /* input border */
}

html.dark .select2-container--default .select2-results__option--selected {
    /* select2 ships #ddd here, a light band on every selected row -- with everything
       selected the whole dropdown turns pale. */
    background-color: var(--elevated) !important;
    color: var(--text-bright) !important;
}


html.dark .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
    background-color: var(--accent-muted);
    color: var(--text-bright) !important; /* light text */
}

html.dark .select2-container--default .select2-search--dropdown .select2-search__field {
    border-color: var(--input-border); /* input border */
}

html.dark .select2-container--default.select2-container--open.select2-container--below .select2-selection--single, html.dark .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
    border-color: var(--input-border); /* input border */
    background: var(--input-bg);
}

/* The inline search is an <input>, so the generic field fill above turns it into a
   lighter block sitting inside the box. It is part of the box, not a field of its own. */
html.dark .select2-container--default .select2-search--inline .select2-search__field {
    background-color: transparent !important;
    border: none !important;
    color: var(--text-bright) !important;
}

html.dark .select2-container--default .select2-selection--multiple {
    border-color: var(--input-border); /* input border */
    background: var(--input-bg);
}

/* Focus and hover mirror what html.dark input gets, so a select2 field behaves like
   the plain inputs sitting next to it. */
html.dark .select2-container--default .select2-selection--single:hover,
html.dark .select2-container--default .select2-selection--multiple:hover {
    background-color: #262d3c !important;
    border-color: var(--input-border-hover) !important;
}

html.dark .select2-container--default.select2-container--focus .select2-selection--multiple,
html.dark .select2-container--default.select2-container--open .select2-selection--multiple,
html.dark .select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--accent) !important;
}


html.dark .text-indigo-500 {
    color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .text-indigo-500 svg {
    color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .text-indigo-600 {
    color: oklch(67.3% 0.182 276.935) !important;
}

/*html.dark a.text-indigo-600:hover {*/
/*    color: oklch(0.6 0.24 273.12) !important;*/
/*}*/

html.dark button.text-indigo-600:hover {
    color: oklch(0.6 0.24 273.12) !important;
}

html.dark .text-indigo-600 svg {
    color: oklch(67.3% 0.182 276.935) !important;
}

html.dark hover\:text-indigo-900:hover {
    color: oklch(75.3% 0.182 276.935) !important;
}

html.dark .hover\:text-indigo-900:hover svg {
    color: oklch(75.3% 0.182 276.935) !important;
}

html.dark .text-indigo-700 {
    color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .text-indigo-600 button {
    color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .text-indigo-700 svg {
    color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .border-indigo-500 {
    border-color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .border-indigo-500 svg {
    border-color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .border-indigo-600 {
    border-color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .border-indigo-600 svg {
    border-color: oklch(67.3% 0.182 276.935) !important;
}

html.dark .border-transparent {
    border-color: transparent !important;
}


html.dark .text-red-500 {
    color: oklch(70.4% 0.191 22.216) !important;
}

html.dark .text-red-500 svg {
    color: oklch(70.4% 0.191 22.216) !important;
}

html.dark .text-red-600 {
    color: oklch(70.4% 0.191 22.216) !important;
}

html.dark a.text-red-600:hover {
    color: oklch(0.68 0.23 24.32) !important;
}

html.dark .text-red-600 svg {
    color: oklch(70.4% 0.191 22.216) !important;
}

html.dark .hover\:text-red-900:hover,
html.dark .hover\:text-red-900:hover svg {
    color: oklch(0.7 0.24 24.52) !important;
}

html.dark-ams .text-red-900 {
    color: oklch(0.7 0.24 24.52) !important;
}

html.dark .text-green-500 {
    color: oklch(79.2% 0.209 151.711) !important;
}

html.dark .text-teal-600 {
    color: oklch(77.7% 0.152 181.912) !important;
}

html.dark .text-green-500 svg {
    color: oklch(79.2% 0.209 151.711) !important;
}

html.dark .text-yellow-500 {
    color: oklch(85.2% 0.199 91.936) !important;
}

html.dark .text-yellow-500 svg {
    color: oklch(85.2% 0.199 91.936) !important;
}

html.dark .bg-indigo-600 {
    background-color: oklch(56% 0.20 277.1) !important;
}

html.dark .hover\:bg-indigo-700:hover {
    background-color: oklch(50% 0.20 277.1) !important;
}


html.dark .bg-red-600 {
    background-color: oklch(58% 0.19 25.5) !important;
}

html.dark .hover\:bg-red-700:hover {
    background: oklch(0.52 0.17 25.5) !important;
}

html.dark .bg-green-600 {
    background-color: oklch(0.59 0.18 149.56) !important;
}

html.dark .bg-yellow-600 {
    background-color: oklch(79.5% 0.184 86.047) !important;
}

/* Yellow buttons/links: the fill above is bright, so their text-white read at 1.9:1. Dark text
   instead (beats `html.dark button { color: … !important }`), and a matching hover step. */
html.dark :is(a, button).bg-yellow-600,
html.dark :is(a, button).bg-yellow-600 svg {
    color: #1f1600 !important;
}

html.dark :is(a, button).bg-yellow-600:is(.hover\:bg-yellow-700, .hover\:bg-yellow-500):hover {
    background-color: oklch(73% 0.17 80) !important;
}

html.dark .border-gray-300 {
    border-color: var(--border); /* card border */
}


/*sidebar*/

html.dark .sidebar-container .text-gray-600 {
    color: var(--muted) !important;
}

/* submenu hover: same tint as the level-1 hover (--sb-hover-bg) */
html.dark .sidebar-container .hover\:text-gray-900:hover {
    color: var(--text) !important;
    background: var(--hover) !important;
}

html.dark .sidebar-container .hover\:text-gray-900:hover > svg {
    color: var(--text) !important;
}


html.dark .sidebar-container [class*="bg-white"] {
    background-color: var(--card) !important;
}

/* stray borders off; the portals' group divider (#sidebar-nav > .border) stays, see SIDEBAR MENU */
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .border:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) > .border) {
    border: none !important;
}

/* current page row: a light indigo wash, so the filled icon tile reads on top of it */
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100:not(svg) {
    background-color: rgb(129 140 248 / 0.12) !important;
    color: var(--text) !important;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .focus\:ring-2:focus {
    box-shadow: none !important;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100 .text-gray-900,
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100 .text-gray-800,
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100 .text-gray-700,
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100 .text-gray-600,
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100 .text-gray-500 {
    color: var(--text) !important;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-100 svg {
    color: var(--text) !important;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) .bg-gray-50 {
    background-color: var(--hover) !important;
}

/* ============ SIDEBAR MENU ============================================ */
/* The sidebar partials give every dropdown level the same pl-11 indent and
   crowd the edges (px-2, pl-2 pr-1), and there are ~100 of them, so the menu
   is styled here by structure instead. The id outranks the utilities.
   Level 1 = any link/button not inside an isExpanded panel: partials start
   with a bare <a>, a <div> holding a button, or an extra wrapper <div>.
   Look: each section icon sits in a rounded tile; the section holding the
   current page gets a filled indigo tile, an open section an indigo tint.
   Submenus hang off a guide line that lights up beside the current page.
   Light rules here; the html.dark overrides follow right after. This file is
   loaded by layouts/master and by the accounts package (devzone/ams) layout,
   whose nav (nav.flex-1.space-y-1.mt-5, no id) every #sidebar-nav rule also matches via :is() - not .sidebar-container. */
:is(.sb-panel, :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5)) {
    --sb-panel: #fff;
    --sb-line: #e2e8f0;
    --sb-text: #334155;
    --sb-sub-text: #475569;
    --sb-icon: #64748b;
    --sb-arrow: #94a3b8;
    --sb-hover-bg: #f1f5f9;
    --sb-hover-text: #0f172a;
    --sb-hover-icon: #334155;
    --sb-tile-bg: #f1f5f9;
    --sb-tile-hover-bg: #e2e8f0;
    --sb-open-tile-bg: #e0e7ff;
    --sb-open-bg: #eef2ff;
    --sb-open-text: #4338ca;
    --sb-open-icon: #4f46e5;
    --sb-accent: #4f46e5;
    --sb-current-tile: linear-gradient(135deg, #6366f1, #4338ca);
    --sb-current-shadow: 0 3px 8px -2px rgba(79, 70, 229, .45);
}

/* ---- pinned header: logo + search; only the menu under it scrolls ---- */
.sb-head {
    padding: .5rem .25rem .625rem;
    border-bottom: 1px solid var(--sb-line);
    background-color: var(--sb-panel);
}

.sb-logo {
    display: block;
    width: 100%;
    padding: 10px 46px;
}

/* every logo but images/aspire.png (which has its own plate) a little bigger: 32px side inset */
.sb-logo:not(.sb-logo-plate) {
    padding: 10px 32px;
}

/* images/aspire.png is a black wordmark drawn for white paper (sidebar adds the class
   when CLIENT_LOGO is that file): on dark it gets a light plate, inset to hug the logo. */
html.dark .sb-logo.sb-logo-plate {
    width: calc(100% - 64px);
    margin: 6px auto;
    padding: 8px 12px;
    border-radius: 10px;
    background: #f8fafc;
}

html:not(.dark) .sb-search-input {
    background-color: #f8fafc;
    border-color: var(--sb-line);
    border-radius: .5rem;
    box-shadow: none;
    transition: background-color .15s, border-color .15s;
}

html:not(.dark) .sb-search-input:focus {
    background-color: #fff;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) {
    /* the accounts layout's own app.css sets body to plain system-ui; pin the
       main app's stack so both sidebars render the same face */
    font-family: Nunito, ui-sans-serif, system-ui, sans-serif;
    margin-top: .75rem;
    padding-left: .5rem;
    padding-right: .375rem;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) a,
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button {
    padding-left: .5rem;
    padding-right: .625rem;
    white-space: nowrap;
}

/* ---- level 1 ---- */
/* the first section (Dashboard) carries mt-5, a second gap under the header */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) > :first-child > button {
    margin-top: 0;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([x-show^="isExpanded"] *) {
    min-height: 2.625rem;
    padding-top: .375rem;
    padding-bottom: .375rem;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.25;
    /* one line: the tighter right padding and icon gap below leave room for "Transport Management" (bold when open) */
    white-space: nowrap;
    padding-right: .25rem;
    text-align: left;
    color: var(--sb-text);
    border-radius: .625rem;
    transition: background-color .15s, color .15s;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([x-show^="isExpanded"] *):hover {
    background-color: var(--sb-hover-bg);
    color: var(--sb-hover-text);
}

/* section icon in a 30px rounded tile; one stroke weight for every icon */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([x-show^="isExpanded"] *) > svg:first-child {
    flex-shrink: 0;
    width: 1.875rem;
    height: 1.875rem;
    padding: .375rem;
    margin-right: .5rem;
    border-radius: .5rem;
    background: var(--sb-tile-bg);
    color: var(--sb-icon);
    transition: background-color .15s, color .15s, box-shadow .15s;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([x-show^="isExpanded"] *) > svg:first-child[stroke] path {
    stroke-width: 1.75;
}

/* chevron, every level - a step lighter than the icon, turns smoothly */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button > svg:last-child {
    flex-shrink: 0;
    width: 1.125rem;
    height: 1.125rem;
    color: var(--sb-arrow);
    transition: color .15s, transform .2s ease;
}

/* hover darkens icon and arrow too - but not on an open section, which stays indigo */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([aria-expanded="true"]):not(:is(.active-link, a.bg-gray-100)):hover > svg {
    color: var(--sb-hover-icon);
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([aria-expanded="true"]):not(:is(.active-link, a.bg-gray-100)):not([x-show^="isExpanded"] *):hover > svg:first-child {
    background-color: var(--sb-tile-hover-bg);
}

/* open section: indigo label, tinted tile */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button[aria-expanded="true"]:not([x-show^="isExpanded"] *) {
    color: var(--sb-open-text);
    font-weight: 600;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button[aria-expanded="true"]:not([x-show^="isExpanded"] *) > svg {
    color: var(--sb-open-icon);
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button[aria-expanded="true"]:not([x-show^="isExpanded"] *) > svg:first-child {
    background-color: var(--sb-open-tile-bg);
}

/* the section holding the current page (or the current page when it is a
   top-level link): filled tile. !important beats the dark text-gray-500 rule. */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-data]:has(:is(.active-link, a.bg-gray-100)) > button:not([x-show^="isExpanded"] *),
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) a:is(.active-link, a.bg-gray-100):not([x-show^="isExpanded"] *) {
    color: var(--sb-open-text);
    font-weight: 600;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-data]:has(:is(.active-link, a.bg-gray-100)) > button:not([x-show^="isExpanded"] *) > svg:first-child,
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) a:is(.active-link, a.bg-gray-100):not([x-show^="isExpanded"] *) > svg:first-child {
    background: var(--sb-current-tile);
    box-shadow: var(--sb-current-shadow);
    color: #fff !important;
}

/* the student/teacher portals separate groups with an empty .border div */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) > .border {
    margin: .625rem .5rem;
    border-width: 0 0 1px;
    border-color: var(--sb-line);
}

/* ---- levels 2 and 3: each open panel hangs off a guide line ---- */
/* level 2's line runs under the centre of its section's tile: 8px padding + 15px */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] {
    margin-left: 1.4375rem;
    border-left: 1px solid var(--sb-line);
    animation: sb-reveal .18s ease-out;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-show^="isExpanded"] {
    margin-left: 1rem;
}

@keyframes sb-reveal {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
}

@media (prefers-reduced-motion: reduce) {
    :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] {
        animation: none;
    }

    :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button > svg:last-child {
        transition: none;
    }
}

/* the partials wrap every submenu link in its own panel; turn the
   space-y-1 gap between them into padding so the guide line stays unbroken */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] + [x-show^="isExpanded"] {
    margin-top: 0;
    padding-top: .25rem;
}

/* submenu rows hug the guide line (square left corners). Their text lines up with the section
   title's: title text = 8px padding + 30px tile + 8px gap = 46px; guide line = 23px + 1px border,
   so 22px of padding here (custom.css .sb-locked uses the same) */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] :is(a, button) {
    position: relative;
    /* every submenu level the same size: the partials mix inline 13px with bare text-sm (14px) */
    font-size: 13px;
    padding-left: 1.375rem;
    white-space: normal;
    color: var(--sb-sub-text);
    border-radius: 0 .5rem .5rem 0;
    transition: background-color .15s, color .15s;
}

/* level 3 sits one 8px step in from level 2 (46px): its line is at 24 + 16px margin + 1px border,
   so 13px of padding puts its text at 54px */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-show^="isExpanded"] :is(a, button) {
    padding-left: .8125rem;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] :is(a, button):hover {
    background-color: var(--sb-hover-bg);
    color: var(--sb-hover-text);
}

/* a short bar drawn over the guide line: grey on hover, indigo on the current page
   and on the submenu button whose sub-submenu holds it */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] :is(a, button)::before {
    content: "";
    position: absolute;
    left: -1px;
    top: .5rem;
    bottom: .5rem;
    width: 2px;
    border-radius: 0 2px 2px 0;
    background: transparent;
    transition: background-color .15s;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] :is(a, button):hover::before {
    background: var(--sb-arrow);
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-data]:has(:is(.active-link, a.bg-gray-100)) > button {
    background-color: var(--sb-open-bg);
    color: var(--sb-open-text);
    font-weight: 600;
}

/* the admin partials also give every submenu button a bg-gray-50 box; drop it unless its
   sub-submenu holds the current page (that one gets the tint above) */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-data]:not(:has(:is(.active-link, a.bg-gray-100))) > button.bg-gray-50:not(:hover) {
    background-color: transparent;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-data]:not(:has(:is(.active-link, a.bg-gray-100))) > button.bg-gray-50:not(:hover) {
    background-color: transparent !important;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] a:is(.active-link, a.bg-gray-100) {
    background-color: var(--sb-open-bg);
    color: var(--sb-open-text);
    font-weight: 600;
}

:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] a:is(.active-link, a.bg-gray-100)::before,
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-data]:has(:is(.active-link, a.bg-gray-100)) > button::before {
    top: .375rem;
    bottom: .375rem;
    width: 3px;
    background: var(--sb-accent);
}

/* no focus ring on mouse click; keyboard (Tab) focus still shows it */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :focus:not(:focus-visible) {
    outline: none;
    box-shadow: none;
}

/* the browser's default scrollbar is a thick grey slab beside the menu */
html:not(.dark) :is(#sidebar, #sidebar-sm) {
    scrollbar-width: thin;
    scrollbar-color: #cbd5e1 transparent;
}

/* link picked with the arrow keys from the search box (Enter opens it): a tinted
   row with an accent bar, same look as the Reports page; vars cover dark mode */
:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) a.sb-active {
    background-color: var(--sb-open-bg);
    color: var(--sb-open-text);
    box-shadow: inset 3px 0 0 var(--sb-accent);
    outline: none;
}

/* ============ END SIDEBAR MENU ======================================== */

/* sidebar menu, dark tokens. The section buttons carry bg-white and
   text-gray-600, whose dark rules are !important, so the states need it too. */
html.dark :is(.sb-panel, :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5)) {
    --sb-panel: var(--card);
    --sb-line: var(--border);
    --sb-text: var(--text);
    --sb-sub-text: var(--text);
    --sb-icon: var(--muted);
    --sb-arrow: var(--muted-dim);
    --sb-hover-bg: var(--hover);
    --sb-hover-text: var(--text-bright);
    --sb-hover-icon: var(--text-soft);
    --sb-tile-bg: var(--hover);
    --sb-tile-hover-bg: var(--border);
    --sb-open-tile-bg: var(--accent-muted);
    --sb-open-bg: var(--accent-muted);
    --sb-open-text: #c7d2fe; /* indigo-200: stays indigo, reads clearly on the dark tint */
    --sb-open-icon: var(--accent);
    --sb-accent: var(--accent);
    --sb-current-tile: linear-gradient(135deg, #5b63ee, #4840d4); /* a touch below light mode's saturation: full indigo glares on dark */
    --sb-current-shadow: inset 0 1px 0 rgb(255 255 255 / 0.18), 0 2px 6px -2px rgb(0 0 0 / 0.6);
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) :is(a, button):not([x-show^="isExpanded"] *):hover {
    background-color: var(--sb-hover-bg) !important;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button[aria-expanded="true"]:not([x-show^="isExpanded"] *),
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-data]:has(:is(.active-link, a.bg-gray-100)) > button:not([x-show^="isExpanded"] *),
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) a:is(.active-link, a.bg-gray-100):not([x-show^="isExpanded"] *) {
    color: var(--sb-open-text) !important;
}

/* submenu current page: outranks the .bg-gray-100 rule's color: var(--text) !important */
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] a:is(.active-link, a.bg-gray-100),
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-data]:has(:is(.active-link, a.bg-gray-100)) > button {
    color: var(--sb-open-text) !important;
}

/* submenu button whose sub-submenu holds the current page: same tint (beats bg-white/bg-gray-50 !important) */
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-show^="isExpanded"] [x-data]:has(:is(.active-link, a.bg-gray-100)) > button:not(:hover) {
    background-color: var(--sb-open-bg) !important;
}

/* icons carry text-gray-400/500, whose dark rules are !important too */
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) button[aria-expanded="true"]:not([x-show^="isExpanded"] *) > svg {
    color: var(--sb-open-icon) !important;
}

html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) [x-data]:has(:is(.active-link, a.bg-gray-100)) > button:not([x-show^="isExpanded"] *) > svg:first-child,
html.dark :is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) a:is(.active-link, a.bg-gray-100):not([x-show^="isExpanded"] *) > svg:first-child {
    color: #fff !important;
}

html.dark .bg-yellow-300 {
    --tw-bg-opacity: 1;
    background-color: oklch(0.72 0.17 93.13);
}


html.dark .bg-rose-300 {
    --tw-bg-opacity: 1;
    background-color: oklch(59.2% 0.249 0.584);
}

html.dark div.shadow-md {
    box-shadow: var(--card-shadow) !important;
}


html.dark .text-slate-600 {
    color: var(--muted) !important;
}

html.dark .text-slate-700 {
    color: var(--text-soft) !important;
}

html.dark li.text-blue-500.list-group-item {
    color: var(--muted) !important;
}

html.dark li.text-blue-500.list-group-item:hover {
    color: var(--text-bright) !important;
}

html.dark button.text-blue-500 {
    color: #49a4ff !important;
}


html.dark .text-gray-800 {
    color: var(--text);
}

html.dark .text-blue-600 {
    color: oklch(62.3% 0.214 259.815) !important;
}

html.dark .text-black {
    color: var(--text) !important;
}

html.dark .bg-gray-200.border-2.rounded-md.border-gray-400.cursor-pointer {
    background-color: var(--card);
}

/* Card collapse toggle: the doubled class out-ranks the generic .bg-white rule. */
html.dark .collapse-toggle.collapse-toggle {
    background: var(--card) !important;
    border-color: var(--border) !important;
    color: var(--muted) !important;
}

html.dark .collapse-toggle.collapse-toggle:hover {
    background: var(--hover) !important;
    color: var(--text-bright) !important;
}

html.dark .bg-gray-200.border-2.rounded-md.border-gray-400.cursor-pointer:hover,
html.dark-ams .-m-3.p-3.flex.items-center.rounded-lg.hover\:bg-gray-100:hover {
    background-color: var(--hover);
}

html.dark .h-24.w-24.bg-indigo-500.flex.justify-center.items-center svg {
    color: var(--text) !important;
}


/* Chart text splits by what each label sits ON.

   Axis labels, legends and titles sit on the card, so they take the card text
   ramp. Data labels do NOT — they sit on the series fill itself (inside a bar,
   on a slice), where a card-relative grey has nothing to contrast against: that
   is what made the dashboard's "%" labels unreadable against their own bars.
   Those go white with a dark halo, which also covers a label that overhangs the
   end of its bar onto the card. */
html.dark .apexcharts-text,
html.dark .apexcharts-title-text,
html.dark .apexcharts-subtitle-text,
html.dark .apexcharts-xaxis-title,
html.dark .apexcharts-yaxis-title,
html.dark .apexcharts-legend-text,
html.dark .apexcharts-tooltip-title,
html.dark .apexcharts-tooltip-text {
    fill: var(--apex-text) !important; /* for SVG text */
    color: var(--apex-text) !important; /* for tooltips */
}

html.dark .apexcharts-datalabel,
html.dark .apexcharts-datalabel-label,
html.dark .apexcharts-datalabel-value,
html.dark .apexcharts-datalabels text {
    fill: #fff !important;
    paint-order: stroke;
    stroke: rgba(0, 0, 0, .45);
    stroke-width: 3px;
    stroke-linejoin: round;
}

html.dark .apexcharts-tooltip {
    background: var(--card) !important;
    color: var(--text-soft) !important;
    box-shadow: none !important;
}

html.dark .apexcharts-tooltip-title {
    background: var(--bg) !important;
    color: var(--text-soft) !important;
}

html.dark .apexcharts-tooltip-text {
    color: var(--text-soft) !important;
}


html.dark .bg-red-50 {
    background: oklab(63.7% .214213 .1014/.15);
}


html.dark .bg-red-100 {
    background: oklab(0.33 0.13 0.07 / 0.9) !important;
}

html.dark .text-red-700, html.dark .text-red-800 {
    color: oklab(0.79 0.14 0.05 / 0.8) !important;;
}

html.dark .text-red-700 svg {
    color: oklab(0.79 0.14 0.05 / 0.8) !important;;
}

html.dark button.text-red-700 {
    color: oklch(0.71 0.22 23.09) !important;
}

html.dark .bg-yellow-50 {
    background: oklab(79.5% .0126846 .183562/.1) !important;;
}

html.dark .bg-yellow-50 svg {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
    background: transparent !important;
}

/* Accounts topnav layout is `<body class="bg-gray-200">` (devzone/ams); key it on
   html.dark as well so the page bg holds even when dark-ams isn't on the root. */
html.dark-ams,
.dark-ams body,
html.dark body.bg-gray-200 {
    background: #0f1218 !important; /* = --bg, written out for the package page */
}

html.dark-ams .bg-yellow-50 svg {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
    background: transparent !important;
}

html.dark .text-yellow-700 {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
}

html.dark .text-yellow-800 {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
}

html.dark .text-yellow-600 button, html.dark .text-yellow-600 svg, html.dark .text-yellow-600 p {
    color: oklch(85.2% 0.199 91.936) !important;;
}

html.dark .bg-green-50 {
    background: oklab(72.3% -.18885 .110891/.1) !important;;
}

html.dark .text-green-600 {
    color: oklch(79.2% 0.209 151.711) !important;
}

html.dark .text-green-600 svg {
    color: oklch(79.2% 0.209 151.711) !important;
}

html.dark .text-green-700, html.dark .text-green-800 {
    color: oklab(92.5% -.0767348 .0341726/.85) !important;
}

html.dark button.text-green-700, html.dark button.text-green-800 {
    color: var(--text) !important;
}

html.dark-ams .text-green-900 {
    color: oklch(0.68 0.23 154.21) !important;
}


html.dark .bg-blue-50 {
    background: oklab(62.3% -.0378409 -.210628/.1) !important;;
}

html.dark .text-blue-700 {
    color: oklch(80.9% .105 251.813) !important;;
}

html.dark .bg-sky-50 {
    background: oklab(68.5% -.0833424 -.146877/.1) !important;
}

html.dark .text-sky-800 {
    color: oklch(74.6% .16 232.661) !important;
}

html.dark button.text-blue-700 {
    color: oklch(0.75 0.15 251.75) !important;;
}

/* Badges -------------------------------------------------------------------
   A rounded element carrying a Tailwind tint background IS a badge in this app,
   so that pair is all we match on. The old block keyed every badge on its exact
   class list (.rounded-full.text-xs.font-medium.bg-red-100.text-red-800) and
   then repeated the whole set for text-xs/sm/md/lg/xl - ~430 lines that still
   left any badge with a slightly different class list light-on-light.

   Tint backgrounds WITHOUT a rounded class are table-cell highlights; they keep
   their flat rules above and never pick up the ring.

   Shape is identical for every hue - an 18% tint of the hue itself plus a
   hairline ring in currentColor - so only the two colours change per rule. */
html.dark {
    /* Chips are flat: the hairline ring IS the badge edge. The drop shadow that
       used to ride along made every pill look lifted, and a status cell stacking
       five of them read as a pile of shadows. */
    --badge-ring: inset 0 0 0 1px color-mix(in oklab, currentColor 32%, transparent);
}

html.dark [class*="rounded"]:is(.bg-red-100, .bg-red-200, .bg-red-50.ring-inset, .dark\:bg-red-100, .dark\:bg-red-200) {
    color: oklch(70.4% .191 22.216) !important;
    background: oklab(70.4% .176821 .072217/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-orange-100, .bg-orange-200, .bg-orange-50.ring-inset, .dark\:bg-orange-100, .dark\:bg-orange-200) {
    color: oklch(72% 0.19 55) !important;
    background: oklab(80% 0.10 0.17/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-yellow-100, .bg-yellow-200, .bg-yellow-50.ring-inset, .dark\:bg-yellow-100, .dark\:bg-yellow-200) {
    color: oklch(79.5% .184 86.047) !important;
    background: oklab(85.2% -.00672284 .198886/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-green-100, .bg-green-200, .bg-green-50.ring-inset, .dark\:bg-green-100, .dark\:bg-green-200) {
    color: oklch(79.2% .209 151.711) !important;
    background: oklab(79.2% -.184039 .0990491/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-blue-100, .bg-blue-200, .bg-blue-50.ring-inset, .dark\:bg-blue-100, .dark\:bg-blue-200) {
    color: oklch(70.7% .165 254.624) !important;
    background: oklab(70.7% -.0437502 -.159094/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-sky-100, .bg-sky-200, .bg-sky-50.ring-inset, .dark\:bg-sky-100, .dark\:bg-sky-200) {
    color: oklch(74.6% .16 232.661) !important;
    background: oklab(68.5% -.0833424 -.146877/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-indigo-100, .bg-indigo-200, .bg-indigo-50.ring-inset, .dark\:bg-indigo-100, .dark\:bg-indigo-200) {
    color: oklch(67.3% .182 276.935) !important;
    background: oklab(67.3% .0219752 -.180668/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-purple-100, .bg-purple-200, .bg-purple-50.ring-inset, .dark\:bg-purple-100, .dark\:bg-purple-200) {
    color: oklch(62.7% 0.265 303.9) !important;
    background: rgba(147, 51, 234, 0.22) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark [class*="rounded"]:is(.bg-pink-100, .bg-pink-200, .bg-pink-50.ring-inset, .bg-rose-100, .bg-rose-200, .bg-rose-50.ring-inset, .dark\:bg-pink-100, .dark\:bg-rose-100) {
    color: oklch(71.8% .202 349.761) !important;
    background: oklab(71.8% .198783 -.0359065/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

/* Gray is the exception: bg-gray-100/200 is also hover state, avatars and the
   sidebar active item, so a gray badge has to declare its text colour too. */
html.dark [class*="rounded"]:is(.bg-gray-100, .bg-gray-50.ring-inset, .dark\:bg-gray-100):is(.text-gray-800, .text-gray-700) {
    color: var(--muted) !important;
    background: oklab(70.7% -.00331825 -.0217483/.18) !important;
    box-shadow: var(--badge-ring) !important;
}

html.dark .text-gray-700.block.w-full.text-left.px-4.py-2.text-sm.hover\:bg-gray-100.cursor-pointer {
    color: var(--muted) !important;
}

html.dark .text-gray-700.block.w-full.text-left.px-4.py-2.text-sm.hover\:bg-gray-100.cursor-pointer:hover {
    background: var(--border) !important;
    color: var(--text) !important;
}

html.dark .text-red-700.block.w-full.text-left.px-4.py-2.text-sm.hover\:bg-gray-100.cursor-pointer:hover {
    background: var(--border) !important;
}

html.dark .flex.justify-end.text-gray-700.block.px-4.py-2.text-sm.hover\:bg-gray-100.cursor-pointer.w-full:hover {
    background: var(--border) !important;
    color: var(--text) !important;
}

/*html.dark form div.shadow.sm\:rounded-md.sm\:overflow-hidden {*/
/*    border-radius: 0 !important;*/
/*}*/

/*html.dark-ams div form div.shadow.sm\:rounded-md.sm\:overflow-hidden {*/
/*    border-radius: 0.375rem !important*/
/*}*/


html.dark div.shadow div.shadow {
    border-radius: 0 !important;
}

/*UMS Package*/
html.dark-ums body {
    background-color: var(--bg) !important;
}

html.dark-ums form div.shadow.sm\:rounded-md.sm\:overflow-hidden {
    border-radius: 0.375rem !important;
}


/* ============ ACCOUNTS (devzone/ams) SIDEBAR ========================== */
/* Same panel, pinned header and logo as the main portal's .sb-panel / .sb-head / .sb-logo;
   its menu (nav.flex-1.space-y-1.mt-5) takes every #sidebar-nav rule in SIDEBAR MENU.
   The package views can't take classes, so these match by structure: the scroll area
   holds the logo wrapper and then the nav. Light first, dark right after. */
div.flex-col:has(> div > nav.flex-1.space-y-1.mt-5) {
    border-right: 1px solid #e2e8f0;
}

/* desktop column is w-60 in the package; main portal is w-64, so the same logo padding drew a smaller logo */
div.w-60:has(> div > div > nav.flex-1.space-y-1.mt-5) {
    width: 16rem;
}

div:has(> nav.flex-1.space-y-1.mt-5) {
    padding-top: 0;
}

div.flex-shrink-0.mx-auto:has(+ nav.flex-1.space-y-1.mt-5) {
    position: sticky;
    top: 0;
    z-index: 1;
    display: block;
    width: 100%;
    padding: .5rem .25rem .625rem;
    border-bottom: 1px solid #e2e8f0;
    background-color: #fff;
}

div.flex-shrink-0.mx-auto:has(+ nav.flex-1.space-y-1.mt-5) :is(a, img) {
    display: block;
    width: 100%;
    height: auto;
}

div.flex-shrink-0.mx-auto:has(+ nav.flex-1.space-y-1.mt-5) img {
    padding: 10px 46px;
}

/* same as .sb-logo:not(.sb-logo-plate): every logo but images/aspire.png a little bigger */
div.flex-shrink-0.mx-auto:has(+ nav.flex-1.space-y-1.mt-5) img:not([src$="images/aspire.png"]) {
    padding: 10px 32px;
}

html.dark div.flex-col:has(> div > nav.flex-1.space-y-1.mt-5),
html.dark div:has(> nav.flex-1.space-y-1.mt-5) {
    border-right-color: var(--border);
    background: var(--card) !important;
}

html.dark div.flex-shrink-0.mx-auto:has(+ nav.flex-1.space-y-1.mt-5) {
    border-bottom-color: var(--border);
    background-color: var(--card);
}

/* images/aspire.png: the same light plate as .sb-logo-plate */
html.dark div.flex-shrink-0.mx-auto:has(+ nav.flex-1.space-y-1.mt-5) img[src$="images/aspire.png"] {
    width: calc(100% - 64px);
    margin: 6px auto;
    padding: 8px 12px;
    border-radius: 10px;
    background: #f8fafc;
}
/* AMS has its own theme toggle (only its onclick mentions dark-ams); hide it, the theme follows the main portal's choice */
.theme-toggle-switch[onclick*="dark-ams"] {
    display: none;
}
/* ============ END ACCOUNTS SIDEBAR ==================================== */

html.dark tr.bg-green-300, html.dark tr.bg-green-100, html.dark td.bg-green-100 {
    background: oklab(79.2% -.184039 .0990491/.1) !important;
}

html.dark tr.bg-red-300, html.dark tr.bg-red-100, html.dark td.bg-red-100 {
    background: oklab(70.4% .176821 .072217/.1) !important;
}

/*AMS END*/

html.dark table tr:last-child {
    border-bottom: none !important;
}

/* Tailwind focus rings stay on buttons and links, but 79 inputs in the views
   carry focus:ring-2, and a ring on a field is the shadow being removed here */
html.dark .focus\:ring-2:focus:not(input):not(select):not(textarea) {
    --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--card);
    --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
    box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

html.dark button {
    color: rgb(255 255 255 / var(--tw-text-opacity)) !important;
}


html.dark button.bg-green-100 {
    background: oklch(0.58 0.18 149.42) !important;
}


html.dark button.hover\:bg-green-200:hover {
    background: oklch(0.46 0.13 149.7) !important;
}

html.dark h3.text-sm.font-medium.text-red-800 {
    color: oklch(88.5% .062 18.334);
}

html.dark svg.text-red-400 {
    color: oklch(70.4% .191 22.216);
}

html.dark div.animate-spin.rounded-full.border-gray-300 {
    border-color: var(--border) !important;
}

html.dark div.animate-spin.rounded-full.border-t-red-600 {
    border-top-color: rgb(220 38 38 / var(--tw-border-opacity)) !important;
}

html.dark div.animate-spin.rounded-full.border-4 {
    border-width: 4px !important;
}

html.dark div.animate-spin.rounded-full.border-t-blue-600 {
    border-top-color: rgb(37 99 235 / var(--tw-border-opacity)) !important;
}

html.dark a.block.px-4.py-2.text-sm.text-gray-700.hover\:bg-gray-100 {
    color: var(--muted) !important;
}

html.dark a.block.px-4.py-2.text-sm.text-gray-700.hover\:bg-gray-100:hover {
    background: var(--border) !important;
    color: var(--text) !important;
}


html.dark-ums nav a.bg-gray-50.text-indigo-700.hover\:text-indigo-700.hover\:bg-white.group.rounded-md.px-3.py-2.flex.items-center.text-sm.font-medium {
    color: var(--text) !important;
}

/*html.dark-ums nav a.bg-gray-50.text-indigo-700.hover\:text-indigo-700.hover\:bg-white.group.rounded-md.px-3.py-2.flex.items-center.text-sm.font-medium:hover {*/
/*    background: var(--border) !important;*/
/*    color: var(--text) !important;*/
/*}*/

html.dark-ums nav a.text-gray-900.hover\:text-gray-900.hover\:bg-gray-50.group.rounded-md.px-3.py-2.flex.items-center.text-sm.font-medium {
    color: var(--muted) !important;
}

html.dark-ums nav a.text-gray-900.hover\:text-gray-900.hover\:bg-gray-50.group.rounded-md.px-3.py-2.flex.items-center.text-sm.font-medium:hover {
    background: var(--border) !important;
    color: var(--text) !important;
}


html.dark::-webkit-scrollbar {
    width: 12px;
}

html.dark::-webkit-scrollbar-track {
    background: var(--bg);
}

html.dark::-webkit-scrollbar-thumb {
    background-color: var(--scrollbar);
    border-radius: 6px;
    border: 3px solid var(--bg);
}

html.dark * {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar) transparent;
}

html.dark div.overflow-hidden.shadow.ring-1.ring-black.ring-opacity-5:has(table) {
    box-shadow: none !important;
}

html.dark tr:has(th) {
    border-top: 1px solid var(--border) !important;
}

html.dark .hover\:text-gray-700:hover, html.dark .hover\:text-gray-700:hover svg {
    color: var(--text) !important;
}

html.dark .hover\:border-gray-300:hover {
    border-color: var(--input-border-hover) !important;
}

html.dark input:-webkit-autofill,
html.dark textarea:-webkit-autofill,
html.dark select:-webkit-autofill {
    -webkit-box-shadow: 0 0 0px 1000px var(--input-bg) inset !important;
    -webkit-text-fill-color: var(--text-bright) !important;
    border-color: var(--input-border) !important;
}

/* UMS permission lists (multi-selects grouped by section). Rows stripe card / hover - the old
   odd rows used --bg, near-black bands on the card - and the optgroup heading reads like a
   table header. */
html.dark-ums select.stripe {
    background-color: var(--card) !important; /* select background */
    color: var(--text-bright) !important; /* text color */
    border-color: var(--input-border) !important;
}

html.dark-ums select.stripe optgroup {
    background-color: var(--thead-bg);
    color: var(--text-bright);
}

html.dark-ums select.stripe option:nth-child(even) {
    background-color: var(--card);
    color: var(--text);
    white-space: normal !important;
}

html.dark-ums select.stripe option:nth-child(odd) {
    background-color: var(--hover);
    color: var(--text);
    white-space: normal !important;
}

html.dark-ums select.stripe option:checked {
    background: #4f46e5 linear-gradient(0deg, #4f46e5, #4f46e5); /* gradient: Chrome ignores a plain colour on checked options */
    color: #fff;
}

html.dark .bg-gray-100.flex.justify-between.items-center.divide-x:has(button) {
    border: 1px solid var(--border) !important;
    border-radius: 0.375rem !important;
    overflow: hidden !important;
    margin: 2px 0 !important;
}

/* Permission list title bars (unassigned = red, assigned = green): a soft tint with coloured
   text instead of solid 600 blocks glaring on the dark card. The red selector used to say
   bg-green-600, so it never matched. */
html.dark-ums .bg-red-600.text-red-100.font-bold.rounded.p-5 {
    background: rgba(239, 68, 68, .14) !important;
    color: #fca5a5 !important;
    box-shadow: inset 0 0 0 1px rgba(239, 68, 68, .3);
}

html.dark-ums .bg-green-600.text-green-100.font-bold.rounded.p-5 {
    background: rgba(34, 197, 94, .12) !important;
    color: #86efac !important;
    box-shadow: inset 0 0 0 1px rgba(34, 197, 94, .28);
}

html.dark-ums .bg-gray-100.flex.justify-between.items-center.divide-x:has(button) .hover\:bg-gray-200:hover {
    background: var(--elevated) !important;
}

html.dark-ums .bg-gray-100.flex.justify-between.items-center.divide-x:has(button) .hover\:bg-gray-200:hover {
    background: var(--elevated) !important;
}

html.dark-ums .-my-2.overflow-x-auto.sm\:-mx-6.lg\:-mx-8 {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

html.dark-ums .-my-2.overflow-x-auto.sm\:-mx-6.lg\:-mx-8 .py-2.align-middle.inline-block.min-w-full.sm\:px-6.lg\:px-8 {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

html.dark-ums .shadow.overflow-hidden.border-b.border-gray-200.sm\:rounded-lg {
    border-radius: 0 !important;
}


html.dark-ums #adding_permissions_ids {
    border-radius: 0.375rem !important;
    overflow: auto !important;
}

html.dark-ums #removing_permissions_ids {
    border-radius: 0.375rem !important;
    overflow: auto !important;
}


html.dark-ums .bg-yellow-50 {
    background: oklab(79.5% .0126846 .183562/.1) !important;;
}

html.dark-ums .text-yellow-700 {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
}

html.dark-ums .text-yellow-800 {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
}

html.dark-ums .text-yellow-400 {
    color: oklab(97.3% -.0162045 .0691261/.8) !important;;
}

html.dark-ums .rounded-md.bg-yellow-50.p-4 .flex, html.dark-ums .rounded-md.bg-yellow-50.p-4 .ml-3 {
    display: flex;
    align-items: center;
}

html.dark-ums table th.text-gray-500 {
    color: var(--text) !important
}

html.dark-ums table td {
    color: var(--muted) !important;
}


html.dark-ams div main div.max-w-7xl.mx-auto.py-6.sm\:px-6.lg\:px-8 {
    max-width: 100%; /* max-w-full */
    padding-left: 1rem; /* px-4 */
    padding-right: 1rem; /* px-4 */
    margin-left: auto; /* mx-auto */
    margin-right: auto; /* mx-auto */
}

@media (min-width: 640px) {
    /* sm */
    html.dark-ams div main div.max-w-7xl.mx-auto.py-6.sm\:px-6.lg\:px-8 {
        padding-left: 1.5rem; /* sm:px-6 */
        padding-right: 1.5rem; /* sm:px-6 */
    }
}

@media (min-width: 768px) {
    /* md */
    html.dark-ams div main div.max-w-7xl.mx-auto.py-6.sm\:px-6.lg\:px-8 {
        padding-left: 2rem; /* md:px-8 */
        padding-right: 2rem; /* md:px-8 */
    }
}

html.dark-ams .bg-red-200 {
    background: oklab(63.7% .214213 .1014/.15);
}

html.dark-ams .max-w-4xl.mx-auto.py-6.sm\:px-6.lg\:px-8 {
    width: 100% !important;
    margin: 0 !important;
}

html.dark-ams .max-w-4xl {
    width: 100% !important; /* override width */
    max-width: 100% !important; /* override Tailwind's max-width */
    margin: 0 auto !important; /* optional: center it */
}

html.dark-ams a.hover\:bg-indigo-100:hover {
    background-color: transparent !important;
}

html.dark-ams button.hover\:bg-indigo-100:hover {
    background-color: transparent !important;
}

html.dark-ams a.hover\:bg-red-100:hover {
    background-color: transparent !important;
}

html.dark-ams button.hover\:bg-red-100:hover {
    background-color: transparent !important;
}

html.dark .apexcharts-menu {
    background: var(--card) !important;
}

/* Not scoped to .apexcharts-theme-light: charts now run theme.mode 'dark' (set
   globally in layouts/master.blade.php), so Apex stamps apexcharts-theme-dark. */
html.dark .apexcharts-menu-item:hover {
    color: var(--text) !important;
    background: var(--border) !important;
}

/* ===========================================================
   Guest / login page
   =========================================================== */

/* The card carries `border border-2` with no colour class — a 2px slab of
   --border on a dark surface. Thin it to the app's standard 1px card outline and
   drop the shadow: nothing floats over the login page, so the halo only smeared
   the panel edge into the background. */
html.dark .login-container-guest {
    border: 1px solid var(--card-border) !important;
    box-shadow: none !important;
}

/* Client logo is a transparent PNG whose wordmark is black — on the login page
   it sits straight on --bg and the words disappear, leaving a floating crest.
   Same call as the topbar/sidebar copy further down: a light plate keeps the
   brand colours, a filter would flip the red mark to cyan. Only images/aspire.png
   gets `.logo-plate` (auth/login, auth/two-factor), same as .sb-logo-plate. */
html.dark #logo img.logo-plate {
    background: #fff;
    border-radius: 12px;
    padding: 12px;
}

/* Failed-login notice is `bg-red-100 / border-red-500 / text-red-700`, none of
   which have a dark mapping — light pink on a dark card. Take the shared alert
   triple so it matches every other error surface in the app. */
html.dark .login-alert {
    background: var(--alert-error-bg) !important;
    border-color: var(--alert-error-edge) !important;
    color: var(--alert-error-text) !important;
}

html.dark div.-my-2.overflow-x-auto.sm\:-mx-6.lg\:-mx-8:has(div.md\:px-6.lg\:px-8) {
    margin-bottom: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

html.dark div.-my-2.overflow-x-auto.sm\:-mx-6.lg\:-mx-8 div.md\:px-6.lg\:px-8 {
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding-bottom: 0 !important;
}

/* Chip shape lives in custom.css; dark only swaps the colours. */
html.dark .select2-container--default .select2-selection--multiple .select2-selection__choice {
    background-color: var(--accent-muted) !important;
    color: var(--text-bright) !important;
}

html.dark .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    color: var(--accent) !important;
}

html.dark .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
    background: rgba(248, 113, 113, .2) !important;
    color: #f87171 !important;
}

html.dark .text-yellow-500 {
    color: oklch(85.2% 0.199 91.936) !important;
}

html.dark input.p-0.focus\:ring-0.block.text-center.text-sm.border-0.text-white.pointer-events-none {
    background: transparent !important;
    color: transparent !important;
}

html.dark-ams .focus-within\:bg-gray-50:focus-within {
    background-color: var(--hover) !important
}

/* Current-page marker in the AMS topbar (and inside its open dropdowns) is a
   literal bg-gray-100, which the global rule turns into --bg — DARKER than the
   header/panel it sits on, so the active item read as a hole while hover lifted.
   Elevate it instead, one step above hover so it still outranks it. */
html.dark-ams header .bg-gray-100 {
    background: var(--elevated) !important;
}

/* Every other copy of the client logo (AMS sidebar/topbar, online admission, CV follow-up,
   meetings, proforma...) follows the admin sidebar's .sb-logo-plate: images/aspire.png is a
   black wordmark drawn for white paper, so on dark it gets the same soft plate; every other
   logo sits straight on the surface. Those views can't all take a class, so match the path. */
html.dark :is(header > div.absolute img, img[alt="Logo"]:not(.sb-logo))[src$="images/aspire.png"] {
    padding: 8px 12px;
    border-radius: 10px;
    background: #f8fafc;
}

/* AMS tables wrap cell content in bare layout divs (`flex justify-between
   rounded-md`) that own no surface of their own. The generic .rounded-*:has(> div)
   card rule handed each one --card-shadow, whose leading `0 0 0 1px var(--border)`
   reads as a stray border and whose 24px falloff reads as a stray shadow — that is
   what boxed the voucher footer rows. Wrappers that really are cards carry a
   shadow-* or a bg-* class (the attachment dropdown, for one), so those keep it. */
html.dark-ams :is(th, td) div[class*="rounded"]:not([class*="shadow"]):not([class*="bg-"]) {
    box-shadow: none !important;
}

/* Header and total bands in AMS tables are bg-gray-100, which the global rule maps
   to --bg — DARKER than the card the table sits on, so the band sank instead of
   lifting. --thead-bg is the one-step-up surface the app's other tables use.
   Both root classes are on the selector to outrank the global .bg-gray-100 rule. */
html.dark.dark-ams :is(th, td).bg-gray-100 {
    background: var(--thead-bg) !important;
}

/* ===========================================================
   AMS / UMS buttons
   ===========================================================
   Both package shells share one button vocabulary and one dark-mode.css, so they
   share this block: `html.dark:is(.dark-ams, .dark-ums)`. `a` and `label` are in
   every selector because plenty of these buttons are not <button>: anchors ("Back
   to Portal", "Add User") and the file-upload label on the profile page, all
   carrying the identical classes. Every rule is gated on a button-only class
   (bg-white, shadow-*, hover:bg-*), so plain form labels and ordinary links —
   which carry none of them — are not touched.

   Every one of them carries shadow-sm, which the card rule at the top of this file
   swaps for --card-shadow — a 1px ring that doubles the button's own border, plus
   a 24px panel shadow under a 34px control. Buttons are controls, not cards, so
   they take a flat contact shadow, the same call the pagination block makes.
   That halo is not AMS-only, so the shadow rule below is NOT gated on the shell
   class — it runs on plain html.dark too. The :not(input):not(select):not(textarea)
   tail is dead weight on a button; it is there to out-specify
   `.bg-white.shadow-sm:not(input):not(select):not(textarea)` above, which would
   otherwise keep the card halo on every white secondary button. The :hover copy
   keeps hover:shadow-* utilities from adding a halo back. */
html.dark :is(button, a, label, [role="button"]):is(.shadow, .shadow-sm, .shadow-md, .shadow-lg, .shadow-xl):not(input):not(select):not(textarea),
html.dark :is(button, a, label, [role="button"]):is(.shadow, .shadow-sm, .shadow-md, .shadow-lg, .shadow-xl):not(input):not(select):not(textarea):hover {
    box-shadow: 0 1px 2px rgba(0, 0, 0, .35) !important;
}

/* Secondary (bg-white + border-gray-300 + text-gray-700): bg-white maps to --card,
   the exact surface the button sits on, so it dissolved into the panel and only
   the faint border showed. Take the field fill instead — these live in filter bars
   next to inputs and should read as the same class of control. rounded-full is the
   topbar avatar, which is not a button face. */
html.dark:is(.dark-ams, .dark-ums) :is(button, a, label).bg-white:not(.rounded-full):not(.rounded-md) {
    background: var(--input-bg) !important;
    border-color: var(--input-border) !important;
    color: var(--text-bright) !important;
}

/* Their stock hover is hover:bg-gray-50 -> --hover (#232a36), which now sits BELOW
   the resting fill, so hovering read as the button dimming. Lift instead. */
html.dark:is(.dark-ams, .dark-ums) :is(button, a, label).bg-white:not(.rounded-full):hover {
    background: #262d3c !important;
}

/* hover:bg-gray-100 / -gray-200 / -green-100 have no dark mapping at all, so those
   buttons flashed a near-white Tailwind tint under the cursor. */
html.dark:is(.dark-ams, .dark-ums) :is(button, a, label):is(.hover\:bg-gray-100, .hover\:bg-gray-200):hover {
    background: var(--hover) !important;
}

/* Same flash, unscoped: the two rules above only fire on the ams/ums shells, but
   this app sets `.dark` alone, so every button/link/label carrying the stock
   hover:bg-gray-{50,100,200} still lit up near-white here (~200 view files, e.g.
   the lecture-review rating pills). Mapped once, for all of them. */
html.dark :is(button, a, label, [role="button"], .cursor-pointer):is(.hover\:bg-gray-50, .hover\:bg-gray-100, .hover\:bg-gray-200):hover {
    background: var(--hover) !important;
}

html.dark:is(.dark-ams, .dark-ums) :is(button, a, label).hover\:bg-green-100:hover {
    background: oklab(72.3% -.18885 .110891/.22) !important;
}

/* Icon buttons: the stock hover is hover:text-gray-500, a step DOWN the grey ramp,
   which on dark is the icon fading out under the cursor. The svg needs naming
   explicitly — `html.dark svg` colours it directly, so it never inherited the
   button's hover colour and these had no hover feedback at all. */
html.dark:is(.dark-ams, .dark-ums) :is(button, a, label).hover\:text-gray-500:hover,
html.dark:is(.dark-ams, .dark-ums) :is(button, a, label).hover\:text-gray-500:hover svg {
    color: var(--text-bright) !important;
}

/* Filled indigo/red buttons already get their surface from the global
   .bg-indigo-600 / .bg-red-600 rules and keep white labels; only the shadow above
   was wrong for them. */

/* ===========================================================
   Alerts — error / success, toast and inline card
   ===========================================================
   Four components out of include/error-template.blade.php (and the AMS copy,
   which reuses the same classes): a toast pair pinned top-right and an inline
   card pair. They were four unrelated looks — the success toast had a one-off
   38% green wash, the error toast took the global bg-red-100 (a near-solid 90%
   slab) with GREY --muted body text on it, and both inline cards were flat 10-15%
   tints with no edge at all. On top of that the cards matched
   `div.rounded-md:has(> div)` and wore a full card ring plus a 24px panel shadow,
   which is a floating-panel treatment on something that sits inline in the form.

   Now all four run one formula: hue tint + 1px hue edge + hue text, with the only
   difference being elevation. The edge is an inset box-shadow rather than a
   border so adding it costs no layout shift, and it replaces the card ring in the
   same declaration. Toasts add a drop shadow; inline cards stay flat. */

html.dark :is(div.rounded-lg, div.rounded-md):is(.bg-red-50, .bg-red-100) {
    background: var(--alert-error-bg) !important;
}

html.dark :is(div.rounded-lg, div.rounded-md).bg-green-50 {
    background: var(--alert-ok-bg) !important;
}

/* Inline cards: edge only, no elevation. */
html.dark div.rounded-md:is(.bg-red-50, .bg-red-100) {
    box-shadow: inset 0 0 0 1px var(--alert-error-edge) !important;
}

html.dark div.rounded-md.bg-green-50 {
    box-shadow: inset 0 0 0 1px var(--alert-ok-edge) !important;
}

/* Toasts: same edge, plus the depth shadow they need to float off the page. */
html.dark div.rounded-lg.shadow-lg:is(.bg-red-50, .bg-red-100) {
    box-shadow: inset 0 0 0 1px var(--alert-error-edge),
        0 12px 32px -10px rgba(0, 0, 0, .6) !important;
}

html.dark div.rounded-lg.shadow-lg.bg-green-50 {
    box-shadow: inset 0 0 0 1px var(--alert-ok-edge),
        0 12px 32px -10px rgba(0, 0, 0, .6) !important;
}

/* The toasts are pinned over live page content and their fill is a 26% tint, so
   whatever sits underneath — table rows, form text — showed through and competed
   with the message. Blurring the backdrop settles that content into a wash so the
   text reads, without going opaque and losing the layering. Only the toasts get
   this; the inline cards have the page background behind them, not content. */
html.dark div.rounded-lg.shadow-lg:is(.bg-red-50, .bg-red-100, .bg-green-50) {
    backdrop-filter: blur(14px) saturate(1.5);
    -webkit-backdrop-filter: blur(14px) saturate(1.5);
}

/* Body text. The markup hands these text-gray-500 / -900, text-red-700 and
   text-green-800 more or less at random, so the utilities are overridden wholesale
   rather than mapped one by one — an alert's text is its hue, whatever class the
   blade happened to use. svg is named explicitly because `html.dark svg` sets the
   close icon's colour directly and it never inherited. */
html.dark :is(div.rounded-lg, div.rounded-md):is(.bg-red-50, .bg-red-100) :is(p, li, ul, div, span, button, svg) {
    color: var(--alert-error-text) !important;
}

html.dark :is(div.rounded-lg, div.rounded-md).bg-green-50 :is(p, li, ul, div, span, button, svg) {
    color: var(--alert-ok-text) !important;
}

/* Close / dismiss buttons. Their stock hover is hover:text-gray-500 (a step DOWN
   the grey ramp, so the icon faded out under the cursor) or hover:bg-green-100,
   which has no dark mapping and flashed a near-white tint. One neutral wash works
   for both hues and both elevations. */
html.dark :is(div.rounded-lg, div.rounded-md):is(.bg-red-50, .bg-red-100, .bg-green-50) button {
    background: transparent !important;
}

html.dark :is(div.rounded-lg, div.rounded-md):is(.bg-red-50, .bg-red-100, .bg-green-50) button:hover {
    background: rgba(255, 255, 255, .08) !important;
}

/* 1px top line, a touch softer than the table header (--footer-border, set in custom.css). */
html.dark .px-4.py-3.text-right.bg-gray-50.sm\:px-6:has(button) {
    border-top: 1px solid var(--footer-border) !important;
}

html.dark .fc-col-header-cell {
    background-color: var(--card) !important;
    border-color: var(--border) !important;
}

html.dark .fc-col-header-cell-cushion {
    color: var(--muted) !important;
}

html.dark .fc-multimonth {
    background-color: var(--bg) !important;
}

html.dark .fc-multimonth-title {
    background-color: transparent !important;
    color: var(--text) !important;
}

html.dark .fc-multimonth-daygrid {
    background-color: var(--bg) !important;
}

html.dark .fc-multimonth .fc-col-header-cell {
    background-color: var(--card) !important;
}

html.dark .fc-multimonth .fc-col-header-cell-cushion {
    color: var(--muted) !important;
}

html.dark .fc-multimonth .fc-daygrid-day {
    background-color: var(--bg) !important;
}

html.dark .fc-multimonth .fc-daygrid-day-number {
    color: var(--text) !important;
}

html.dark .fc-multimonth .fc-day-other .fc-daygrid-day-number {
    color: var(--muted-dim) !important;
}

html.dark .fc-list-day-cushion {
    background-color: var(--card) !important;
}

html.dark .fc-list-day-text,
html.dark .fc-list-day-side-text {
    color: var(--text) !important;
}

html.dark .fc-list-day {
    background-color: var(--card) !important;
}

html.dark .fc-timegrid-col {
    background-color: var(--bg) !important;
}

html.dark .fc-timegrid-axis,
html.dark .fc-timegrid-slot-label {
    background-color: var(--bg) !important;
}

html.dark .fc-multimonth .fc-daygrid-day,
html.dark .fc-multimonth .fc-daygrid-day > * {
    border-color: var(--border) !important;
}

html.dark .fc-multimonth .fc-col-header-cell,
html.dark .fc-multimonth .fc-col-header-cell-cushion {
    border-color: var(--border) !important;
}

html.dark .fc-multimonth .fc-daygrid-day-inner {
    border-color: var(--border) !important;
}

html.dark .fc-scrollgrid,
html.dark .fc-scrollgrid table {
    border-right: 1px solid var(--border) !important;
}

html.dark .fc-scrollgrid td:last-child,
html.dark .fc-scrollgrid th:last-child {
    border-right: 1px solid var(--border) !important;
    background: var(--card) !important;
}

.fc-daygrid-day:last-child .fc-daygrid-day-number {
    padding-right: 6px !important;
    padding-top: 4px !important;
}

html.dark .event-tooltip {
    background-color: var(--border);
}


html.dark .fc-timegrid-body * {
    background: var(--card) !important;
}

html.dark .fc-multimonth,
html.dark .fc-multimonth .fc-daygrid-day,
html.dark .fc-timegrid-axis,
html.dark .fc-timegrid-slot-label {
    background: var(--card) !important;
}

html.dark .fc .fc-list-empty {
    background-color: var(--card) !important;
}

html.dark .fc .fc-list-event:hover td {
    background-color: var(--border) !important;
}

html.dark .fc-multimonth-title {
    background-color: var(--card) !important;
    color: var(--text) !important;
}

html.dark.fc-popover-title {
    background-color: var(--card) !important;
    color: var(--text) !important;
}

html.dark .fc-popover {
    background-color: var(--card) !important;
}

html.dark .fc-popover-header {
    background-color: var(--border) !important;
    color: var(--text) !important;
}

html.dark .fc-popover-body {
    background-color: var(--card) !important;
}

html.dark .fc-popover-close {
    color: var(--text) !important;
}

html.dark .ac-table {
    border: 1px solid var(--border) !important; /* your color */
}

html.dark .ac-table td,
html.dark .ac-table th {
    border: 1px solid var(--border) !important; /* change this color */
}


/* ===========================================================
   Skeleton loaders (lazy-load placeholders) — light + dark
   =========================================================== */
.skeleton-bar {
    position: relative;
    overflow: hidden;
    border-radius: 6px;
    background-color: #e2e8f0; /* slate-200 */
}

.skeleton-bar::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(
        90deg,
        transparent 0,
        rgba(255, 255, 255, 0.65) 50%,
        transparent 100%
    );
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

@keyframes skeleton-shimmer {
    100% {
        transform: translateX(100%);
    }
}

/* Dark variants — sit a touch lighter than the dark panel */
html.dark .skeleton-bar {
    background-color: var(--hover) !important;
}

html.dark .skeleton-bar::after {
    background: linear-gradient(
        90deg,
        transparent 0,
        rgba(255, 255, 255, 0.08) 50%,
        transparent 100%
    ) !important;
}

/* Respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
    .skeleton-bar::after {
        animation: none;
    }
}
/* ===== Activate / Deactivate confirmation modal & buttons ===== */
html.dark .status-modal .bg-yellow-100 {
    background-color: rgba(161, 98, 7, 0.30) !important;
}
html.dark .status-modal .text-yellow-600,
html.dark .status-modal .text-yellow-600 svg {
    color: oklch(85.2% 0.199 91.936) !important;
}
html.dark .status-modal .bg-green-100 {
    background-color: rgba(21, 128, 61, 0.30) !important;
}
html.dark .status-modal .text-green-600,
html.dark .status-modal .text-green-600 svg {
    color: oklch(79.2% 0.209 151.711) !important;
}
html.dark .status-link.text-yellow-600 {
    color: oklch(85.2% 0.199 91.936) !important;
}
html.dark .status-link.text-green-600 {
    color: oklch(79.2% 0.209 151.711) !important;
}

/* Loader colored top must win over the dark .border-gray-300 shorthand */
html.dark .status-modal .border-t-green-600 {
    border-top-color: oklch(79.2% 0.209 151.711) !important;
}
html.dark .status-modal .border-t-yellow-600 {
    border-top-color: oklch(85.2% 0.199 91.936) !important;
}

/* Inactive course row */
html.dark .row-inactive {
    background-color: rgba(127, 29, 29, 0.30) !important;
}

/* Loader top color via custom classes (no Tailwind build needed) */
.status-modal .spinner-activate {
    border-top-color: #16a34a !important; /* green-600 */
}
.status-modal .spinner-deactivate {
    border-top-color: #ca8a04 !important; /* yellow-600 */
}
html.dark .status-modal .spinner-activate {
    border-top-color: oklch(79.2% 0.209 151.711) !important;
}
html.dark .status-modal .spinner-deactivate {
    border-top-color: oklch(85.2% 0.199 91.936) !important;
}

/* ===== Lecture routine modal: Selected Lectures summary card ===== */
html.dark .selected-lectures-card {
    background: var(--card) !important;
    border-color: rgb(255 255 255 / 15%) !important;
}

/* ===== Lecture picker modal: rail step circles =====
   The step circles are set through Alpine :class, so the state utilities land as real classes.
   Scoped to .lecture-step so these do not touch bg-green-100 / bg-indigo-600 elsewhere. */

/* Completed (attendance marked) step: built like the active step — solid fill, matching border,
   white check and an offset ring — just green instead of indigo. */
html.dark .lecture-step.bg-green-100 {
    background-color: #16a34a !important; /* green-600, like active bg-indigo-600 */
    border-color: #16a34a !important;     /* green-600, like active border-indigo-600 */
    color: #ffffff !important;
    /* ring-2 ring-offset-2 in green, matching the active step's indigo ring */
    box-shadow: 0 0 0 2px var(--card), 0 0 0 4px #22c55e !important; /* offset = panel, ring = green-500 */
}

/* Active (selected) step: bg-indigo-600 is already recoloured globally; the focus ring's offset
   defaults to white, which halos on the dark panel, so match it to the panel background. */
html.dark .lecture-step.ring-offset-2 {
    --tw-ring-offset-color: var(--card) !important;
}

/* ===========================================================
   Dark theme polish — hierarchy, tables, focus, scrollbars
   Everything below reads from the tokens at the top of the file.
   =========================================================== */

/* Headings step one level brighter than body copy; anything with an explicit
   text-* utility still wins, so no !important here. */
html.dark h1,
html.dark h2,
html.dark h3,
html.dark h4 {
    color: var(--text-bright);
    letter-spacing: -0.01em;
}

/* Tables: header lifts off the card, rows get a hover.
   Only NEUTRAL header cells are recoloured — a th carrying a real colour
   utility (the Timetable shift bands: bg-red-600 / bg-yellow-300 / bg-rose-300)
   is deliberate and keeps its own fill and label colour. */
html.dark thead:not([class*="bg-"]),
html.dark thead[class*="bg-gray"],
html.dark thead[class*="bg-white"],
html.dark thead tr:not([class*="bg-"]),
html.dark thead tr[class*="bg-gray"],
html.dark thead tr[class*="bg-white"],
html.dark thead th:not([class*="bg-"]),
html.dark thead th[class*="bg-gray"],
html.dark thead th[class*="bg-white"],
/* A th outside a thead is still a header cell — the label column of the detail
   cards. Matched only when it carries a neutral fill, so bare row-header cells
   keep the row's own background. */
html.dark th[class*="bg-gray"],
html.dark th[class*="bg-white"] {
    background-color: var(--thead-bg) !important;
}

html.dark thead th:not([class*="bg-"]),
html.dark thead th[class*="bg-gray"],
html.dark thead th[class*="bg-white"] {
    color: var(--muted) !important;
}

html.dark thead th {
    font-weight: 600;
    letter-spacing: 0.02em;
}

html.dark table tbody tr:not([class*="bg-"]):hover {
    background-color: var(--hover) !important;
}

/* Keyboard focus was invisible on dark — the accent ring fixes that everywhere */
html.dark a:focus-visible,
html.dark button:focus-visible,
html.dark summary:focus-visible,
html.dark [role="button"]:focus-visible,
html.dark [tabindex]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

html.dark ::selection {
    background: var(--accent-muted);
    color: var(--text-bright);
}

/* Disabled fields read as inert instead of just slightly off */
html.dark input:disabled,
html.dark select:disabled,
html.dark textarea:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Chrome-less inline fields — the date pickers and unit selects sitting in the
   dashboard stat cards, and editable table cells. They ship .border-0 because
   they are meant to look like text, not like a field, so the field treatment
   above (border, well background, inset) must not reach them.
   Replaces four page-specific patches that each fixed one instance of this. */
html.dark input.border-0,
html.dark select.border-0,
html.dark textarea.border-0,
html.dark-ams input.border-0,
html.dark-ams select.border-0,
html.dark-ams textarea.border-0,
html.dark-ums input.border-0,
html.dark-ums select.border-0,
html.dark-ums textarea.border-0,
html.dark input.border-0:hover,
html.dark select.border-0:hover,
html.dark textarea.border-0:hover,
html.dark input.border-0:focus,
html.dark select.border-0:focus,
html.dark textarea.border-0:focus {
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    /* these read as part of the surrounding label/header text, so they take its colour */
    color: inherit !important;
}

/* ...but keyboard users still need to see where they are */
html.dark input.border-0:focus-visible,
html.dark select.border-0:focus-visible,
html.dark textarea.border-0:focus-visible {
    outline: 2px solid var(--accent) !important;
    outline-offset: -2px;
    border-radius: 4px;
}

/* Inner scroll containers had the browser default (bright) scrollbar */
html.dark ::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

html.dark ::-webkit-scrollbar-track,
html.dark ::-webkit-scrollbar-corner {
    background: transparent;
}

html.dark ::-webkit-scrollbar-thumb {
    background-color: var(--scrollbar);
    border-radius: 8px;
    border: 2px solid transparent;
    background-clip: content-box;
}

html.dark ::-webkit-scrollbar-thumb:hover {
    background-color: var(--input-border-hover);
}

/* Chart gridlines matched the light theme and cut across the panel */
html.dark .apexcharts-gridline,
html.dark .apexcharts-grid line,
html.dark .apexcharts-xaxis line,
html.dark .apexcharts-yaxis line,
html.dark .apexcharts-xaxis-tick {
    stroke: var(--border) !important;
}

/* ===========================================================
   Colour-coded table header bands (Timetable shift headers)
   ===========================================================
   White labels on bright fills, as in light mode. The red (#d33b3a) and rose
   (#e60076) fills already carry white at 4.7:1 and 4.5:1, so they stay exactly
   as they were. Only the gold needed moving: bg-yellow-300 resolves to #c9a000,
   where white text sits at 2.5:1 -- that unreadable band is what made the
   header look broken. #9d7300 is the same gold a few steps down, at 4.3:1.

   Scoped to th on purpose: on a tr, bg-yellow-300 / bg-green-300 / bg-red-300
   are a traffic-light row scale with its own faint row tints, and bg-red-600 is
   the fill on ~150 action buttons. */
html.dark th.bg-yellow-300 {
    background-color: #9d7300 !important;
}

/* Labels on any coloured header band, whatever the hue */
html.dark thead th[class*="bg-"]:not([class*="bg-gray"]):not([class*="bg-white"]),
html.dark thead th[class*="bg-"]:not([class*="bg-gray"]):not([class*="bg-white"]) svg {
    color: #ffffff !important;
}

/* Timetable shift row: dark counterparts of the light tints in custom.css
   (slate / sky / violet), light text in the same hue. */
html.dark thead tr.shift-timing-row th[scope="col"].bg-red-600 {
    background-color: #262d3b !important;
    color: #cbd5e1 !important;
}

html.dark thead tr.shift-timing-row th[scope="col"].bg-yellow-300 {
    background-color: #13324a !important;
    color: #bae6fd !important;
}

html.dark thead tr.shift-timing-row th[scope="col"].bg-rose-300 {
    background-color: #2e2752 !important;
    color: #ddd6fe !important;
}

/* ===========================================================
   Pagination
   ===========================================================
   Scoped to nav[aria-label="Pagination Navigation"], which is the hook both
   Livewire's and Laravel's tailwind pagination views emit.

   These are controls, not cards, so they take the field surface (--input-bg)
   rather than bg-white, and the wrapper's shadow-sm must not pull in the card
   ring. The stock hover is hover:text-gray-400/500 — a step DOWN the grey ramp,
   which on a dark theme reads as the button fading out on hover, so fill and
   text both lift here instead. */
html.dark nav[aria-label="Pagination Navigation"] .shadow-sm {
    box-shadow: none !important;
}

html.dark nav[aria-label="Pagination Navigation"] a,
html.dark nav[aria-label="Pagination Navigation"] button,
html.dark nav[aria-label="Pagination Navigation"] span.relative {
    background-color: var(--input-bg) !important;
    border-color: var(--input-border) !important;
    color: var(--muted) !important;
}

html.dark nav[aria-label="Pagination Navigation"] a:hover,
html.dark nav[aria-label="Pagination Navigation"] button:hover {
    background-color: #262d3c !important;
    color: var(--text-bright) !important;
}

html.dark nav[aria-label="Pagination Navigation"] a:hover svg,
html.dark nav[aria-label="Pagination Navigation"] button:hover svg {
    color: var(--text-bright) !important;
}

/* Unavailable prev/next and the "..." gap sit back */
html.dark nav[aria-label="Pagination Navigation"] span.cursor-default {
    color: var(--muted-dim) !important;
}

/* Current page — last, so it wins the tie against the cursor-default rule
   above (the current page carries that class too) */
html.dark nav[aria-label="Pagination Navigation"] [aria-current="page"] span {
    background-color: #414f8f !important;
    border-color: var(--accent) !important;
    color: #ffffff !important;
    position: relative;
    z-index: 10;
}

/* ===========================================================
   Pikaday date picker (Date of Birth, and any other Pikaday field)
   ===========================================================
   The stylesheet comes from the CDN with a hard-coded white theme, so every
   surface in the popup has to be overridden here. The popup is appended to
   <body>, outside any card, but html.dark is on the root so these still apply. */
html.dark .pika-single {
    color: var(--text) !important;
    background: var(--card) !important;
    border-color: var(--card-border) !important;
}

/* Floating popover: lift it further off the page than a card sits. No ring -
   .pika-single already draws its own 1px border, and the two together read as
   a 2px edge. */
html.dark .pika-single.is-bound {
    box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.7) !important;
}

html.dark .pika-lendar {
    color: var(--text) !important;
}

/* Month / year label — ships an opaque white background of its own */
html.dark .pika-label {
    background-color: transparent !important;
    color: var(--text-bright) !important;
}

/* The month/year dropdowns overlay the label; they inherit the field treatment */
html.dark .pika-title select {
    background-color: var(--input-bg) !important;
    color: var(--text-bright) !important;
    border-color: var(--input-border) !important;
}

/* Weekday header row */
html.dark .pika-table th {
    color: var(--muted-dim) !important;
}

html.dark .pika-week {
    color: var(--muted-dim) !important;
}

/* Day cells sit straight on the card, the grid needs no tiles */
html.dark .pika-button {
    background: transparent !important;
    color: var(--text) !important;
}

/* Stock hover is orange (#ff8000) — a soft accent wash instead */
html.dark .pika-button:hover,
html.dark .pika-row.pick-whole-week:hover .pika-button {
    background: var(--accent-muted) !important;
    color: var(--text-bright) !important;
    box-shadow: none !important;
}

/* Today keeps a ring, so it still reads when another day is selected */
html.dark .is-today .pika-button {
    color: var(--accent) !important;
    box-shadow: inset 0 0 0 1px var(--accent-muted) !important;
}

/* Selected day: stock is #33aaff with a light inset that glows on dark */
html.dark .is-selected .pika-button,
html.dark .has-event .pika-button,
html.dark .is-selected .pika-button:hover {
    background: var(--accent) !important;
    color: var(--bg) !important;
    box-shadow: none !important;
}

/* Days that cannot be picked: faded text straight on the card, no tile */
html.dark .is-disabled .pika-button,
html.dark .is-disabled .pika-button:hover,
html.dark .is-inrange .pika-button,
html.dark .is-outside-current-month .pika-button {
    background: transparent !important;
    color: var(--input-border-hover) !important;
    box-shadow: none !important;
}

/* The chevrons are grey SVGs; a background-image cannot take currentColor,
   so they are lightened with a filter. The filter would flip a hover wash to
   near white too, so on dark the hover is a brightness step only. */
html.dark .pika-prev,
html.dark .pika-next {
    filter: invert(0.85);
    opacity: 0.7;
}

html.dark .pika-prev:hover,
html.dark .pika-next:hover {
    background-color: transparent !important;
    opacity: 1;
}

html.dark .pika-prev.is-disabled,
html.dark .pika-next.is-disabled {
    background-color: transparent !important;
    opacity: 0.3;
}

/* Tailwind's field-with-affix idiom: .relative.rounded-md.shadow-sm wrapping an
   input (28 of these in the views, e.g. the CNIC and fee fields). The wrapper
   hugs the field, so the card ring landed right against the field's own 1px
   border and read as a 2px edge. The field carries its own styling. */
html.dark .relative.rounded-md.shadow-sm:has(> input),
html.dark .relative.rounded-md.shadow-sm:has(> select),
html.dark .relative.rounded-md.shadow-sm:has(> textarea) {
    box-shadow: none !important;
}

/* Indigo notice blocks — unreadable on dark without a tint */
html.dark .bg-indigo-50 {
    background: rgba(99, 102, 241, .15) !important;
}

html.dark .text-indigo-800 {
    color: #c7d2fe !important;
}

html.dark .text-gray-600 {
    color: #9ca3af !important;
}

/* Lecture review rating slider */
html.dark .lr-range {
    --lr-fill: #818cf8;
    --lr-track: #374151;
}

html.dark .lr-range::-webkit-slider-thumb {
    background: #818cf8;
    border-color: #1f2937;
}

html.dark .lr-range::-moz-range-thumb {
    background: #818cf8;
    border-color: #1f2937;
}

/* ===== Lecture timetable / weekly schedule =====
   The break and off-day fills are painted inline for a white table, so they are
   re-tinted here for the dark surface. */
html.dark .tt-break {
    background-color: #3a2a12 !important;
    background-image: repeating-linear-gradient(45deg, rgba(251, 146, 60, .12) 0 6px, transparent 6px 12px) !important;
}

html.dark .tt-off {
    background-color: #1f2937 !important;
    background-image: repeating-linear-gradient(45deg, rgba(148, 163, 184, .10) 0 8px, transparent 8px 16px) !important;
}

html.dark th.tt-break, html.dark .tt-break span {
    color: #fdba74 !important;
}

html.dark .tt-break span, html.dark .tt-off span {
    text-shadow: none !important;
}

/* custom.css paints the drag & drop states for a white table — indigo tints and a
   black shadow both vanish on gray-800, so they are re-tinted here. */
html.dark .lt-drag:hover {
    box-shadow: 0 0 0 1px rgba(129, 140, 248, .45);
}

html.dark .lt-drop.is-hint {
    background-color: rgba(99, 102, 241, .10);
    outline-color: #6366f1;
}

html.dark .lt-drop.is-over {
    background-color: rgba(99, 102, 241, .32);
    outline-color: #a5b4fc;
}

/* ===== Generated timetable =====
   The course code chips, teacher chips and hover card are painted in the blade for a
   white table, so their fills are re-tinted here for the dark surface. */
html.dark .ls-code {
    background: #1f2937;
    color: #e5e7eb;
}

/* A cell can hold a dozen of these and a week a few thousand, so the fills are a low
   tint of the hue over whatever is behind them rather than a solid block, and the text
   is a muted shade of it instead of near-white: twelve saturated chips per row is what
   made the grid hard to look at. The hue still tells the courses apart. */
html.dark .ls-c0 { background: rgba(129, 140, 248, .13); color: #a5b0e6 }
html.dark .ls-c1 { background: rgba(52, 211, 153, .11); color: #86d0b4 }
html.dark .ls-c2 { background: rgba(251, 191, 36, .11); color: #d9be7e }
html.dark .ls-c3 { background: rgba(248, 113, 113, .12); color: #e8a3a3 }
html.dark .ls-c4 { background: rgba(56, 189, 248, .11); color: #93c5e8 }
html.dark .ls-c5 { background: rgba(167, 139, 250, .13); color: #bda8e6 }
html.dark .ls-c6 { background: rgba(244, 114, 182, .12); color: #e2a4c4 }
html.dark .ls-c7 { background: rgba(34, 211, 238, .10); color: #8ec9d4 }
html.dark .ls-c8 { background: rgba(163, 230, 53, .10); color: #b3cc8a }
html.dark .ls-c9 { background: rgba(251, 146, 60, .11); color: #dfb08a }
html.dark .ls-c10 { background: rgba(148, 163, 184, .13); color: #adb8c9 }
html.dark .ls-c11 { background: rgba(232, 121, 249, .12); color: #d4a2dd }

/* currentColor is the muted text now, so the hover ring needs to be a touch stronger. */
html.dark .ls-code:hover {
    box-shadow: 0 0 0 1.5px currentColor, inset 0 0 0 999px rgba(148, 163, 184, .06);
}

html.dark .ls-short {
    color: #fca5a5;
}

html.dark .ls-remove:hover {
    color: #fca5a5;
}

html.dark .ls-teacher-all {
    background: #4f46e5;
    color: #eef2ff;
}

/* Tinted the same way as the course chips: the bar can list a hundred teachers, and a
   hundred solid green and red pills over the panel were as loud as the grid. */
html.dark .ls-teacher-off {
    background: rgba(148, 163, 184, .10);
    color: #cbd5e1;
    box-shadow: 0 0 0 1px rgba(148, 163, 184, .22) inset;
}

html.dark .ls-teacher-ok {
    background: rgba(52, 211, 153, .11);
    color: #86d0b4;
    box-shadow: 0 0 0 1px rgba(52, 211, 153, .24) inset;
}

html.dark .ls-teacher-short {
    background: rgba(248, 113, 113, .12);
    color: #e8a3a3;
    box-shadow: 0 0 0 1px rgba(248, 113, 113, .26) inset;
}

html.dark .ls-teacher-on {
    box-shadow: 0 0 0 2px #a5b4fc;
}

html.dark .ls-detail {
    background: #0b1220;
    color: #e5e7eb;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .6);
}

/* Task page (manage-task): the Activity/Comments tab switch is a light-grey pill
   track with a white active pill, and the comment thread rails are bg-gray-200 —
   none of which the generic surface rules cover. */
html.dark .task-tabs {
    background: var(--bg);
}

html.dark .task-tabs > button {
    color: var(--muted);
}

html.dark .task-tabs > button.bg-white {
    background: var(--elevated) !important;
    color: var(--accent) !important;
}

html.dark .task-tabs > button:not(.bg-white):hover {
    color: var(--text-bright);
}

/* comment / reply thread rails and the line above the comment list */
html.dark .comment-rail {
    background: var(--border) !important;
}

html.dark .comment-list {
    border-color: var(--border);
}

/* ---------------------------------------------------------------------------
   CKEditor 5 (super-build) — task description, paper-bank modal, mcqs screens.
   CKEditor themes itself entirely through --ck-color-* variables, so remapping
   the tokens once here beats chasing its ~60 internal class names. Declared on
   html.dark rather than on .ck because balloons, dropdown panels and tooltips
   are appended to <body>, outside the editor's own subtree.
   --------------------------------------------------------------------------- */
html.dark {
    /* base surfaces / text */
    --ck-color-base-background: var(--input-bg);
    --ck-color-base-foreground: var(--card);
    --ck-color-base-border: var(--input-border);
    --ck-color-base-text: var(--text-bright);
    --ck-color-text: var(--text-bright);
    --ck-color-shadow-drop: rgba(0, 0, 0, .45);
    --ck-color-shadow-inner: rgba(0, 0, 0, .3);

    /* toolbar */
    --ck-color-toolbar-background: var(--card);
    --ck-color-toolbar-border: var(--input-border);

    /* buttons */
    --ck-color-button-default-background: transparent;
    --ck-color-button-default-hover-background: var(--hover);
    --ck-color-button-default-active-background: var(--hover);
    --ck-color-button-on-background: var(--elevated);
    --ck-color-button-on-hover-background: var(--input-border-hover);
    --ck-color-button-on-active-background: var(--elevated);
    --ck-color-button-on-color: var(--accent);
    --ck-color-button-disabled-background: transparent;
    --ck-color-button-save: #4ade80;
    --ck-color-button-cancel: #f87171;
    --ck-color-split-button-hover-background: var(--input-border-hover);
    --ck-color-split-button-hover-border: var(--input-border-hover);

    /* dropdown / balloon panels + lists */
    --ck-color-panel-background: var(--card);
    --ck-color-panel-border: var(--card-border);
    --ck-color-dropdown-panel-background: var(--card);
    --ck-color-dropdown-panel-border: var(--card-border);
    --ck-color-list-background: var(--card);
    --ck-color-list-button-hover-background: var(--hover);
    --ck-color-list-button-on-background: var(--accent-muted);
    --ck-color-list-button-on-background-focus: var(--accent-muted);
    --ck-color-list-button-on-text: var(--text-bright);

    /* text inputs inside the editor UI (link href, find & replace, …) */
    --ck-color-input-background: var(--input-bg);
    --ck-color-input-border: var(--input-border);
    --ck-color-input-text: var(--text-bright);
    --ck-color-input-disabled-background: var(--bg);
    --ck-color-input-disabled-border: var(--border);
    --ck-color-input-disabled-text: var(--muted-dim);
    --ck-color-labeled-field-label-background: var(--card);

    /* misc chrome */
    --ck-color-focus-border: var(--accent);
    --ck-color-focus-outer-shadow: rgba(129, 140, 248, .25);
    --ck-color-tooltip-background: var(--elevated);
    --ck-color-tooltip-text: var(--text-bright);
    --ck-color-editable-blur-selection: var(--accent-muted);
    --ck-color-link-default: var(--accent);
    --ck-color-link-selected-background: var(--accent-muted);
    --ck-color-table-column-resizer-hover: var(--accent);
    --ck-color-table-focused-cell-background: var(--hover);
    --ck-color-widget-blurred-border: var(--border);
    --ck-color-widget-hover-border: var(--accent);
}

/* The editable area itself: CKEditor hard-codes white on .ck-editor__editable_inline,
   and the placeholder colour comes from its own var. */
html.dark .ck.ck-editor__editable,
html.dark .ck.ck-editor__editable_inline {
    background: var(--input-bg) !important;
    color: var(--text-bright) !important;
    border-color: var(--input-border) !important;
}

html.dark .ck.ck-editor__editable.ck-focused {
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 1px var(--accent) !important;
}

html.dark .ck.ck-placeholder::before,
html.dark .ck .ck-placeholder::before {
    color: var(--muted-dim) !important;
}

/* Blockquote rail and inline code chip are light-mode greys baked into content styles. */
html.dark .ck-content blockquote {
    border-left-color: var(--input-border-hover);
}

html.dark .ck-content code {
    background: var(--elevated);
    color: var(--text-bright);
}

/* Table cells in the editable get a hard-coded light border. */
html.dark .ck-content .table table,
html.dark .ck-content .table table td,
html.dark .ck-content .table table th {
    border-color: var(--input-border-hover);
}

html.dark .ck-content .table table th {
    background: var(--elevated);
}

html.dark .ck-button{
     border-color: transparent !important;
}
/* Gauge tracks in the last-day lecture evaluation rings. The unfilled arcs use
   `text-gray-100/200` as currentColor, which has no generic dark rule and so
   burned bright against the card. */
html.dark svg circle.text-gray-200 {
    color: var(--elevated);
}

html.dark svg circle.text-gray-100 {
    color: var(--hover);
}

/* Collect payment posting date (light styles in custom.css). The inner input is
   bare text, so the global field treatment — well fill, border, hover, focus,
   disabled fade — is held off it here; the wrapper draws the field instead.
   input.cp-date__input under .cp-date outranks `html.dark input:hover:not(:focus)`. */
html.dark .cp-date {
    background: var(--input-bg);
    border-color: var(--input-border) !important;
    box-shadow: none;
}

html.dark .cp-date:hover {
    background: #262d3c;
    border-color: var(--input-border-hover) !important;
}

html.dark .cp-date:focus-within {
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 1px var(--accent);
}

html.dark .cp-date__icon {
    background: var(--accent-muted);
    color: var(--accent);
}

/* `html.dark svg` paints every icon muted; these follow their tile instead */
html.dark .cp-date__icon svg {
    color: inherit;
}

html.dark .cp-date .cp-date__chevron {
    color: var(--muted);
}

html.dark .cp-date input.cp-date__input,
html.dark .cp-date input.cp-date__input:hover,
html.dark .cp-date input.cp-date__input:focus,
html.dark .cp-date input.cp-date__input:disabled {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--text-bright) !important;
    -webkit-text-fill-color: var(--text-bright);
    opacity: 1;
}

html.dark .cp-date input.cp-date__input::placeholder {
    color: var(--muted-dim) !important;
}

html.dark .cp-date.is-locked,
html.dark .cp-date.is-locked:hover {
    background: var(--card);
    border-color: var(--border) !important;
}

html.dark .cp-date.is-locked .cp-date__icon {
    background: var(--elevated);
    color: var(--muted);
}

html.dark .cp-date.is-locked input.cp-date__input {
    color: var(--text-soft) !important;
    -webkit-text-fill-color: var(--text-soft);
}

html.dark .cp-date__badge {
    background: var(--elevated);
    border-color: var(--card-border) !important;
    color: var(--muted);
}

/* not dark-specific: this file is the only stylesheet both the app and ums layouts load.
   user creation from ums/users/add is disabled (see routes/web.php) */
a[href$="/ums/users/add"]
{
    visibility: hidden !important;
}

/* data-admin is set on <html> by App\Http\Middleware\MarkAdminHtml */
html:not([data-change-password]) a[href$="/ums/change-password"],
html:not([data-admin]) a[href$="/ums/users"],
html:not([data-admin]) a[href$="/ums/permissions-list"],
html:not([data-admin]) a[href$="/ums/user-activity"]
{
    display: none !important;
}

/* ums profile (/ums) is read-only for non-admins */
html:not([data-admin]) form[wire\:submit\.prevent="updateUser"] input,
html:not([data-admin]) form[wire\:submit\.prevent="updateUser"] label[for="file-upload"]
{
    pointer-events: none;
    opacity: 0.6;
}

html:not([data-admin]) form[wire\:submit\.prevent="updateUser"] div:has(> button[type="submit"]),
/* Receivable Account row: the last row, and (unlike the Photo row) its label is for="email" */
html:not([data-admin]) form[wire\:submit\.prevent="updateUser"] .space-y-6 > div:last-child:has(> label[for="email"])
{
    display: none !important;
}

/* ============ COVERAGE SWEEP ==========================================
   Utilities the rules above only handled in one context (the tint badges are
   `[class*="rounded"]` only, gray-200 not at all) or never: found by rendering every
   bg-/text- class used in resources/views on div/span/p/td/button/a under html.dark
   and flagging what stayed light-on-dark or dark-on-dark.
   Everything here is a lower-specificity fallback (exclusions sit in :where(), which adds none): the badge, tr/td and button rules
   above still win where they apply. Same tints as the badge rules, background only —
   text keeps inheriting --text, and the coloured text utilities are mapped below. */
html.dark :is(.bg-red-50, .bg-red-200, .bg-red-300):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(70.4% .176821 .072217/.14) !important;
}

html.dark :is(.bg-orange-50, .bg-orange-100, .bg-orange-200, .bg-amber-100):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(80% 0.10 0.17/.14) !important;
}

html.dark :is(.bg-yellow-100, .bg-yellow-200):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(85.2% -.00672284 .198886/.14) !important;
}

html.dark :is(.bg-green-100, .bg-green-200, .bg-green-300):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(79.2% -.184039 .0990491/.14) !important;
}

html.dark :is(.bg-blue-100, .bg-blue-200):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(70.7% -.0437502 -.159094/.14) !important;
}

html.dark :is(.bg-sky-100, .bg-sky-200):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(68.5% -.0833424 -.146877/.14) !important;
}

html.dark :is(.bg-indigo-100, .bg-indigo-200):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(67.3% .0219752 -.180668/.14) !important;
}

html.dark :is(.bg-purple-100, .bg-purple-200):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: rgba(147, 51, 234, .16) !important;
}

html.dark :is(.bg-pink-100, .bg-rose-100):where(:not(input, select, textarea, thead, thead tr, th)) {
    background: oklab(71.8% .198783 -.0359065/.14) !important;
}

/* Filled grey blocks/buttons (`bg-gray-200`, 128 uses) were left light grey. Not the
   accounts topnav <body class="bg-gray-200">: that is the page, which takes --bg. */
html.dark:not(.dark-ums) .bg-gray-200:where(:not(input, select, textarea, thead, thead tr, th, body)) {
    background: var(--elevated) !important;
}

/* Dark hue text that only the badge rules recoloured. Badges still win (more specific). */
html.dark :is(.text-blue-800, .text-blue-900) {
    color: oklch(80.9% .105 251.813) !important;
}

html.dark :is(.text-purple-700, .text-purple-800) {
    color: oklch(78% .14 304) !important;
}

html.dark :is(.text-orange-700, .text-orange-800, .text-amber-800) {
    color: oklch(80% .13 60) !important;
}

html.dark :is(.text-sky-800, .text-sky-900) {
    color: oklch(80% .11 232) !important;
}

html.dark :is(.text-pink-800, .text-rose-800) {
    color: oklch(80% .13 350) !important;
}

/* Hover/focus surfaces that flashed a light block (`hover:bg-white` alone is on 132 views). */
html.dark :is(.hover\:bg-white, .hover\:bg-gray-100):hover,
html.dark .focus\:bg-gray-100:focus {
    background: var(--hover) !important;
}

html.dark :is(.hover\:bg-gray-200, .hover\:bg-gray-300):hover {
    background: #353e50 !important; /* one step above --elevated, the gray-200 fill */
}

html.dark :is(.hover\:bg-green-100, .hover\:bg-green-200):hover {
    background: oklab(79.2% -.184039 .0990491/.24) !important;
}

html.dark :is(.hover\:bg-indigo-100, .hover\:bg-indigo-200):hover {
    background: oklab(67.3% .0219752 -.180668/.24) !important;
}

/* Hover text that went DARKER (light-theme habit) and vanished: brighten instead. */
html.dark :is(.hover\:text-gray-500, .hover\:text-gray-600, .hover\:text-gray-700, .hover\:text-gray-800, .hover\:text-gray-900):hover,
html.dark .focus\:text-gray-700:focus {
    color: var(--text-bright) !important;
}

html.dark :is(.hover\:text-blue-700, .hover\:text-blue-800, .hover\:text-blue-900):hover {
    color: oklch(85% .09 251) !important;
}

html.dark :is(.hover\:text-indigo-600, .hover\:text-indigo-700, .hover\:text-indigo-800, .hover\:text-indigo-900):hover {
    color: #a5b4fc !important;
}

html.dark :is(.hover\:text-red-600, .hover\:text-red-700, .hover\:text-red-800, .hover\:text-red-900):hover {
    color: #fca5a5 !important;
}

html.dark :is(.hover\:text-yellow-500, .hover\:text-yellow-700, .hover\:text-yellow-900):hover {
    color: #bae6fd !important;
}

html.dark .hover\:text-green-900:hover {
    color: #86efac !important;
}

/* Pasted Word documents (`.word-doc`, e.g. student/general-rules/default-general-rules-university):
   hundreds of inline `background: #ffffff` / `#f5f8fb` paragraphs and `<font color="#444444">`
   text turned into white slabs with grey-on-white text. Let the card surface and theme text
   show through; links keep the accent. */
html.dark .word-doc [style*="background"] {
    background: transparent !important;
}

html.dark .word-doc :is(p, li, td, span, font, b, strong, i, em, u) {
    color: var(--text) !important;
}

html.dark .word-doc a,
html.dark .word-doc a :is(font, span, b, u) {
    color: var(--accent) !important;
}

/* Native controls: tell the browser the page is dark, so <select> drop-down lists, date/time
   pickers, checkboxes and radios render in their dark variant instead of OS-light. The option
   rule covers browsers that ignore color-scheme for the popup list. This already lights the
   date/time picker icon, so it must not also get an invert filter (that turned it back dark). */
html.dark {
    color-scheme: dark;
    /* the only colour the native popups accept: selected day/time, checkbox and radio fill */
    accent-color: var(--accent);
}

html.dark :is(option, optgroup) {
    background-color: var(--input-bg);
    color: var(--text-bright);
}

/* Moved from custom.css: dark-mode.css is the one stylesheet every shell loads (main app, UMS,
   AMS), so these apply everywhere. They style both themes, not only dark. */
/* ===== Badges: one shape everywhere ======================================================
   The admission-list campus badge is the reference (`inline-flex items-center px-2.5 py-0.5
   rounded-full text-xs font-medium`). ~680 badges in the views mixed rounded / rounded-md /
   rounded-full, text-xs / text-sm, px-2…px-3, py-0.5 / py-1 and medium / semibold weight.
   A badge here = a rounded <span> with a light fill (bg-*-50/100/200) and a dark text colour
   (text-*-600…900), not sized (w-/h-) and not a block. Colours: "Badge + alert colours" below. */
span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only) {
    display: inline-flex;
    align-items: center;
    padding: .125rem .625rem;
    border-radius: 9999px;
    font-size: .75rem;
    line-height: 1rem;
    font-weight: 500;
}

/* ===== Inline alerts: one look everywhere ================================================
   Three shapes were in use: the collect-fee notices (`flex items-center bg-*-50 text-*-600
   text-sm font-bold px-4 py-3 rounded`, role=alert, 16px icon), the Tailwind UI alerts
   (`rounded-md bg-*-50 p-4 > flex > flex-shrink-0 svg.h-5 + ml-3 …`, ~120) and `border-l-4 …
   p-4` notices. All now: 12px/16px padding, 6px radius (the cards'), a 1px border (colours: see
   "Badge + alert colours" below), 16px icon with an 8px gap, 14px semibold message; a list of
   errors under a title stays regular. Colours: "Badge + alert colours" below. */
:is(
    div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg),
    div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3
) {
    --alert-border: #e5e7eb;
    padding: .75rem 1rem;
    border: 1px solid var(--alert-border);
    border-radius: .375rem;
}


/* Reference notices: message semibold, icon 16px with an 8px gap. */
div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3 {
    font-weight: 600;
    line-height: 1.25rem;
}

div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3 > svg {
    flex: none;
}

/* Tailwind UI / border-l alerts: same icon, gap and type. */
div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3) > div.flex:has(> div.flex-shrink-0 > svg) {
    align-items: flex-start;
}

div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3) > div.flex > div.flex-shrink-0 > svg {
    width: 1rem;
    height: 1rem;
    margin-top: .125rem; /* centred on the first 20px text line */
}

div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3) > div.flex > div.flex-shrink-0 + div {
    margin-left: .5rem;
}

div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3) > div.flex > div.flex-shrink-0 + div > :is(p, h3) {
    font-size: .875rem;
    line-height: 1.25rem;
    font-weight: 600;
}

div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3) > div.flex > div.flex-shrink-0 + div > div {
    margin-top: .25rem;
    font-size: .875rem;
    font-weight: 400;
}

/* ===== Badge + alert colours: one palette per colour family ===============================
   Same hue, same colours, everywhere: yellow notices used text-yellow-600, the Tailwind UI alerts
   -700/-800 text and -400 icons, badges -800 on -100, and the dark shells had their own set.
   Per family (keyed on the element's bg-* hue; amber=yellow, rose/pink, emerald/teal=green,
   sky=blue, violet/purple):
     badge  light: -100 fill, -800 text            dark: 18% tint of the hue, hue text
     alert  light: -50 fill, -200 border, -800 text, -500 icon
            dark:  10% tint, 28% tint border, hue text and icon */
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-yellow-"], [class*="bg-amber-"]) {
    --tone-50: #fefce8; --tone-100: #fef9c3; --tone-200: #fef08a; --tone-500: #eab308; --tone-800: #854d0e; --tone-dark: oklch(79.5% .184 86.047);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-red-"]) {
    --tone-50: #fef2f2; --tone-100: #fee2e2; --tone-200: #fecaca; --tone-500: #ef4444; --tone-800: #991b1b; --tone-dark: oklch(70.4% .191 22.216);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-pink-"], [class*="bg-rose-"]) {
    --tone-50: #fdf2f8; --tone-100: #fce7f3; --tone-200: #fbcfe8; --tone-500: #ec4899; --tone-800: #9d174d; --tone-dark: oklch(71.8% .202 349.761);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-orange-"]) {
    --tone-50: #fff7ed; --tone-100: #ffedd5; --tone-200: #fed7aa; --tone-500: #f97316; --tone-800: #9a3412; --tone-dark: oklch(72% .19 55);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-green-"], [class*="bg-emerald-"], [class*="bg-teal-"]) {
    --tone-50: #f0fdf4; --tone-100: #dcfce7; --tone-200: #bbf7d0; --tone-500: #22c55e; --tone-800: #166534; --tone-dark: oklch(79.2% .209 151.711);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-blue-"], [class*="bg-sky-"]) {
    --tone-50: #eff6ff; --tone-100: #dbeafe; --tone-200: #bfdbfe; --tone-500: #3b82f6; --tone-800: #1e40af; --tone-dark: oklch(70.7% .165 254.624);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-indigo-"]) {
    --tone-50: #eef2ff; --tone-100: #e0e7ff; --tone-200: #c7d2fe; --tone-500: #6366f1; --tone-800: #3730a3; --tone-dark: oklch(67.3% .182 276.935);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-purple-"], [class*="bg-violet-"]) {
    --tone-50: #faf5ff; --tone-100: #f3e8ff; --tone-200: #e9d5ff; --tone-500: #a855f7; --tone-800: #6b21a8; --tone-dark: oklch(71.4% .203 305.504);
}
:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only), div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([class*="bg-gray-"], [class*="bg-slate-"]) {
    --tone-50: #f9fafb; --tone-100: #f3f4f6; --tone-200: #e5e7eb; --tone-500: #6b7280; --tone-800: #1f2937; --tone-dark: #98a3b4;
}

:is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only)):is([style], :not([style])) {
    background: var(--tone-100, #f3f4f6) !important;
    color: var(--tone-800, #1f2937) !important;
}

:is(div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([style], :not([style])) {
    background: var(--tone-50, #f9fafb) !important;
    border-color: var(--tone-200, #e5e7eb) !important;
    color: var(--tone-800, #1f2937) !important;
}

/* Inner title / message / list / links take the alert's text colour; icons the -500. */
:is(div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3) :is(h3, p, ul, ol, li, span, strong, div, a) {
    color: inherit !important;
}

:is(div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3) svg {
    color: var(--tone-500, #6b7280) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(span[class*="rounded"][class*="bg-"]:is([class*="-50 "], [class$="-50"], [class*="-100"], [class*="-200"])[class*="text-"]:is([class*="-600"], [class*="-700"], [class*="-800"], [class*="-900"]):not([class*="w-"]):not([class*=" h-"]):not([class^="h-"]):not(.block, .flex, .grid, .absolute, .fixed, .sr-only)):is([style], :not([style])) {
    background: color-mix(in oklab, var(--tone-dark, #98a3b4) 18%, transparent) !important;
    color: var(--tone-dark, #98a3b4) !important;
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--tone-dark, #98a3b4) 32%, transparent) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3):is([style], :not([style])) {
    background: color-mix(in oklab, var(--tone-dark, #98a3b4) 10%, transparent) !important;
    border-color: color-mix(in oklab, var(--tone-dark, #98a3b4) 28%, transparent) !important;
    color: var(--tone-dark, #98a3b4) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(div[class*="bg-"]:is([class*="-50 "], [class$="-50"]):is(.p-4, .p-3):has(> div.flex > div.flex-shrink-0 > svg), div[role="alert"][class*="bg-"]:is([class*="-50 "], [class$="-50"]).px-4.py-3) svg {
    color: var(--tone-dark, #98a3b4) !important;
}

/* ===== Buttons: one system, both themes ===================================================
   ~930 buttons. Solid ones (`bg-<hue>-500/600/700 text-white px-*`: indigo 650, red 147,
   yellow 66, green, blue, purple…) took their colours from per-view classes plus a patchwork of
   dark overrides; white text on yellow-600 read at ~2.9:1; in dark mode `html.dark svg` greyed the
   icons inside them; focus rings differed. Now, per hue family: one fill, one hover step, one
   focus ring; every fill but yellow passes 4.5:1 with white text (green and orange sit one step
   darker than Tailwind's -600 for that; yellow is a bright golden by choice, its white text
   semibold with a faint shadow); a soft top highlight + 1px shadow for depth, a
   press state, a keyboard-only focus ring and one disabled look. Outline buttons
   (`bg-white border text-gray-*`) get the same treatment in neutral. Sizes and radii are left
   to the markup (button groups / pagination rely on them). */
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-indigo-"], [class*=" bg-indigo-"]), :is([class^="bg-violet-"], [class*=" bg-violet-"])) { --btn-bg: #4f46e5; --btn-hover: #4338ca; --btn-ring: #6366f1; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-red-"], [class*=" bg-red-"]), :is([class^="bg-rose-"], [class*=" bg-rose-"])) { --btn-bg: #dc2626; --btn-hover: #b91c1c; --btn-ring: #ef4444; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-pink-"], [class*=" bg-pink-"])) { --btn-bg: #db2777; --btn-hover: #be185d; --btn-ring: #ec4899; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-green-"], [class*=" bg-green-"]), :is([class^="bg-emerald-"], [class*=" bg-emerald-"]), :is([class^="bg-teal-"], [class*=" bg-teal-"])) { --btn-bg: #15803d; --btn-hover: #166534; --btn-ring: #22c55e; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-blue-"], [class*=" bg-blue-"]), :is([class^="bg-sky-"], [class*=" bg-sky-"])) { --btn-bg: #2563eb; --btn-hover: #1d4ed8; --btn-ring: #3b82f6; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-purple-"], [class*=" bg-purple-"])) { --btn-bg: #9333ea; --btn-hover: #7e22ce; --btn-ring: #a855f7; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-orange-"], [class*=" bg-orange-"])) { --btn-bg: #c2410c; --btn-hover: #9a3412; --btn-ring: #f97316; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-yellow-"], [class*=" bg-yellow-"]), :is([class^="bg-amber-"], [class*=" bg-amber-"])) { --btn-bg: #eab308; --btn-hover: #ca8a04; --btn-ring: #f59e0b; }
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-gray-"], [class*=" bg-gray-"]), :is([class^="bg-slate-"], [class*=" bg-slate-"])) { --btn-bg: #4b5563; --btn-hover: #374151; --btn-ring: #6b7280; }

:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *) {
    color: var(--btn-fg, #fff) !important;
    background: var(--btn-bg, #4f46e5) !important;
    border-color: transparent !important;
    font-weight: 500;
    box-shadow: inset 0 1px 0 rgb(255 255 255 / .14), 0 1px 2px rgb(0 0 0 / .08) !important;
    transition: background-color .15s, box-shadow .15s, transform .05s;
}

:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *) svg {
    color: inherit !important;
}

:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):hover {
    background: var(--btn-hover, #4338ca) !important;
}

:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):active:not(:disabled) {
    transform: translateY(1px);
    box-shadow: inset 0 1px 2px rgb(0 0 0 / .15) !important;
}

:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):focus-visible {
    outline: 2px solid var(--btn-ring, #6366f1);
    outline-offset: 2px;
}

:is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *) {
    color: #374151 !important;
    background: #fff !important;
    border-color: #d1d5db !important;
    font-weight: 500;
    box-shadow: 0 1px 2px rgb(0 0 0 / .05) !important;
    transition: background-color .15s, border-color .15s, color .15s;
}

:is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):hover {
    color: #111827 !important;
    background: #f9fafb !important;
    border-color: #9ca3af !important;
}

:is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):active:not(:disabled) {
    background: #f3f4f6 !important;
}

:is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):focus-visible {
    outline: 2px solid #6366f1;
    outline-offset: 2px;
}

:is(:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *), :is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *)):is(:disabled, [disabled], [aria-disabled="true"]) {
    opacity: .5 !important;
    cursor: not-allowed;
    transform: none;
}

/* Dark shells: a touch lighter fills so they hold against the dark cards; same text rules. */
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-indigo-"], [class*=" bg-indigo-"]), :is([class^="bg-violet-"], [class*=" bg-violet-"])) { --btn-bg: #5b5bd6; --btn-hover: #4f46e5; --btn-ring: #818cf8; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-red-"], [class*=" bg-red-"]), :is([class^="bg-rose-"], [class*=" bg-rose-"])) { --btn-bg: #dc2626; --btn-hover: #b91c1c; --btn-ring: #f87171; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-pink-"], [class*=" bg-pink-"])) { --btn-bg: #db2777; --btn-hover: #be185d; --btn-ring: #f472b6; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-green-"], [class*=" bg-green-"]), :is([class^="bg-emerald-"], [class*=" bg-emerald-"]), :is([class^="bg-teal-"], [class*=" bg-teal-"])) { --btn-bg: #15803d; --btn-hover: #166534; --btn-ring: #4ade80; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-blue-"], [class*=" bg-blue-"]), :is([class^="bg-sky-"], [class*=" bg-sky-"])) { --btn-bg: #2563eb; --btn-hover: #1d4ed8; --btn-ring: #60a5fa; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-purple-"], [class*=" bg-purple-"])) { --btn-bg: #9333ea; --btn-hover: #7e22ce; --btn-ring: #c084fc; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-orange-"], [class*=" bg-orange-"])) { --btn-bg: #c2410c; --btn-hover: #9a3412; --btn-ring: #fb923c; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-yellow-"], [class*=" bg-yellow-"]), :is([class^="bg-amber-"], [class*=" bg-amber-"])) { --btn-bg: #eab308; --btn-hover: #ca8a04; --btn-ring: #fbbf24; }
html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-gray-"], [class*=" bg-gray-"]), :is([class^="bg-slate-"], [class*=" bg-slate-"])) { --btn-bg: #4b5563; --btn-hover: #374151; --btn-ring: #9ca3af; }

html:is(.dark, .dark-ams, .dark-ums) :is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *) {
    box-shadow: inset 0 1px 0 rgb(255 255 255 / .10), 0 1px 2px rgb(0 0 0 / .35) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *) {
    color: var(--text) !important;
    background: var(--card) !important;
    border-color: var(--border) !important;
    box-shadow: 0 1px 2px rgb(0 0 0 / .3) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):hover {
    color: var(--text-bright, var(--text)) !important;
    background: var(--hover) !important;
    border-color: color-mix(in oklab, var(--border) 60%, #fff 12%) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):active:not(:disabled) {
    background: var(--elevated, var(--hover)) !important;
}

html:is(.dark, .dark-ams, .dark-ums) :is(button, a):is([class^="bg-white"], [class*=" bg-white"])[class*="border"][class*="text-gray-"][class*="px-"]:not(.collapse-toggle):not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *) svg {
    color: inherit !important;
}

/* Yellow buttons: bright golden fill (chosen over a darker amber), so the white label is
   semibold with a faint shadow to hold on it. */
:is(button, a, input[type="submit"], input[type="button"]):is([class^="text-white"], [class*=" text-white"]):is([class^="bg-"], [class*=" bg-"]):is([class*="-500"], [class*="-600"], [class*="-700"])[class*="px-"]:not(:is(#sidebar-nav, nav.flex-1.space-y-1.mt-5) *):is(:is([class^="bg-yellow-"], [class*=" bg-yellow-"]), :is([class^="bg-amber-"], [class*=" bg-amber-"])) {
    font-weight: 600;
    text-shadow: 0 1px 1px rgb(0 0 0 / .25);
}

/* Guest "Sign in" pill — the light gradient glares on dark; use the theme's own
   raised surface + accent instead so it sits with the toggle beside it */
html.dark .guest-login-btn {
    background: var(--elevated);
    border: 1px solid var(--accent-muted);
    color: var(--text-bright);
    box-shadow: none;
}
html.dark .guest-login-btn:hover {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgb(129 140 248 / 0.15);
}
html.dark .guest-login-badge { background: var(--accent); }
html.dark .guest-login-sub { color: var(--muted); opacity: 1; }
/* `html.dark svg` greys every icon; keep these on the pill's own colours */
html.dark .guest-login-btn .guest-login-badge svg { color: #0f1218; }
html.dark .guest-login-btn .guest-login-arrow { color: var(--accent); }

/* `thead th.border-black` (custom.css) forces black; on dark match the body cells */
html.dark thead th.border-black {
    border-top-color: var(--border) !important;
    border-bottom-color: var(--border) !important;
}

/* Sidebar logo: `img[alt="Logo"]` above gives it a white tile, and the image's own
   p-6 made that tile a 300px glare block. Same tile, tight padding, softer white. */
html.dark :is(#sidebar, #sidebar-sm) img[alt="Logo"] {
    padding: 10px;
    width: 150px;
    margin: 16px auto;
    border-radius: 12px;
    background: #f1f5f9;
    box-shadow: 0 0 0 1px var(--card-border);
}
html select.stripe option {
    white-space: normal !important;
}



/* Device attendance: the scanner input stays focused to catch the QR reader, but must
   stay invisible. The generic input fill / border / focus accent would draw a box. */
html.dark #scanner-input,
html.dark #scanner-input:hover,
html.dark #scanner-input:focus {
    background-color: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    outline: none !important;
    color: transparent !important;
    caret-color: transparent;
}


/* 2FA setup QR (auth/two-factor): scanners need dark modules on a light quiet
   zone, so it keeps a white plate instead of sitting raw on the dark card. */
html.dark .two-factor-qr {
    background: #fff;
    padding: 4px;
    border-radius: 8px;
    line-height: 0;
}

/* Tab bars (custom.css .tab-strip) */
html.dark .tab-strip { box-shadow: inset 0 -1px 0 var(--border); }
html.dark .tab-strip nav > a.border-transparent:not(:hover) { border-color: transparent !important; }

/* Fee "Slab Applied" title row (include/collect-fee-head, livewire/admission/collect-fee):
   its bg-white cells are a title band on the card above the column-header row in light
   mode; the generic `thead th[class*="bg-white"]` rule painted it --thead-bg, merging the
   two rows. The extra tr class outranks that rule. */
html.dark thead tr.slab-title th {
    background-color: var(--card) !important;
    color: var(--text-bright) !important;
}

/* Fee collection footer (livewire/admission/collect-fee, include/collect-fee-head): the
   `-my-2` wrapper reset above (margin-bottom: 0) stops cancelling its `my-2` parent here,
   leaving an 8px band of card under the Installments / Admission Form footer that light
   mode does not have. Scoped to this form so the reset stays as-is everywhere else. */
html.dark div.my-2 > div.-my-2.overflow-x-auto.sm\:-mx-6.lg\:-mx-8:has(> form[wire\:submit\.prevent="updateRecords"]) {
    margin-bottom: -0.5rem !important;
}
