/* ════════════════════════════════════════════════════════
   PLACE BRIDGE — portal skin
   Maroon #6F0D0E · Gold #D4B78C · taken from the public site

   Tailwind's config (partials/pb-theme.blade.php) retargets the
   utility palette. This file does the three things a config
   cannot:

     1. the tokens themselves, for hand-written CSS
     2. typography — DM Serif Display on headings
     3. the vendor widgets, which ship their own colours and
        would otherwise sit on the page in Bootstrap blue:
        DataTables, select2, toastr, SweetAlert, Bootstrap.

   Dark mode keys off html.dark, which is what the portal has
   always toggled, and mirrors data-theme so anything lifted
   from the public site works unchanged.
   ════════════════════════════════════════════════════════ */

:root {
    --maroon: #6F0D0E;
    --maroon-deep: #4E0A0B;
    --gold: #D4B78C;
    --gold-deep: #B99763;

    --accent: #6F0D0E;
    --accent-soft: #F6EFE3;
    --gold-soft: #FAF4EA;

    --paper: #F5F0E6;
    --surface: #F1E9DC;
    --surface-2: #EBE0CE;
    --card: #FDFCFA;

    --ink: #1C1A19;
    --body: #514B45;
    --mute: #847C72;
    --line: #E4D8C2;

    --eyebrow: #7A5620;

    /* Aliases. Views and the older stylesheets reach for --brand and
       --brand-color, mostly with no fallback, so they resolved to nothing and
       the odd one fell through to a teal left over from an earlier palette.
       Defining them here is what makes those places brand-coloured at all. */
    --brand: #6F0D0E;
    --brand-color: #6F0D0E;

    --sh-sm: 0 1px 3px rgba(28, 26, 25, .05);
    --sh-md: 0 8px 28px rgba(111, 13, 14, .07);
    --sh-lg: 0 24px 60px rgba(111, 13, 14, .10);

    --r: 12px;
    --ease: cubic-bezier(.22, .68, .28, 1);
}

html.dark,
[data-theme="dark"] {
    --maroon: #5A0A0B;
    --maroon-deep: #3A0607;
    --gold: #DCC299;
    --gold-deep: #C2A87F;

    --accent: #E0C49C;
    --accent-soft: #241C14;
    --gold-soft: #241D16;

    --paper: #12100F;
    --surface: #191514;
    --surface-2: #201A18;
    --card: #1C1817;

    --ink: #F6F1EA;
    --body: #BEB4AC;
    --mute: #8B8078;
    --line: #302825;

    --eyebrow: #C2A87F;

    --brand: #E0C49C;
    --brand-color: #E0C49C;

    --sh-sm: 0 1px 3px rgba(0, 0, 0, .4);
    --sh-md: 0 8px 28px rgba(0, 0, 0, .45);
    --sh-lg: 0 24px 60px rgba(0, 0, 0, .55);
}

/* ════════════════════════════════════════════════════════
   BOOTSTRAP'S UTILITIES, WHICH WERE WINNING SILENTLY

   Bootstrap and Tailwind are both loaded, and they share 42
   class names — .bg-white, .border, .p-4, .gap-2, .text-white,
   .shadow-lg and so on. Bootstrap marks every one !important,
   so Bootstrap has been winning all of them, in both themes,
   for as long as both have been loaded.

   It is why `bg-white` rendered pure #fff rather than the
   card colour the Tailwind config asks for, and why the dark
   rules below could not reach it: nothing outranks !important
   except !important later in the cascade. This file loads
   after Bootstrap, so this is that.

   Only the colour collisions are corrected here. The spacing
   and layout ones — .p-4, .px-3, .gap-2, .mt-2 — are also
   Bootstrap's, and have been all along; every page in the
   portal was laid out while that was true, so "fixing" them
   would reflow the entire application. That is a separate job
   and wants its own set of eyes.
   ════════════════════════════════════════════════════════ */

.bg-white { background-color: var(--card) !important; }
.bg-light { background-color: var(--surface) !important; }
.text-muted { color: var(--mute) !important; }

/* Colour only. The width stays Bootstrap's, which is 1px and
   matches Tailwind's, so nothing moves. */
.border { border-color: var(--line) !important; }

/* ════════════════════════════════════════════════════════
   DARK MODE, FOR MARKUP THAT NEVER ASKED FOR IT

   1,390 places across 86 files paint a light surface or dark
   text with no `dark:` counterpart — a bright cream card on a
   near-black page, or near-black text on it. Writing 1,390
   dark: variants by hand is the churn the palette retarget
   existed to avoid, and every one of them is a chance to miss
   one.

   So the base utilities are made theme-aware instead. The
   author's own dark: variant still wins where they wrote one,
   because of how these selectors are weighted:

     .bg-white                       (0,1,0)  the utility
     html.dark :where(.bg-white)     (0,1,1)  this file
     .dark .dark\:bg-dark-card       (0,2,0)  an author's dark:

   :where() contributes nothing, so this sits above the plain
   utility and below any deliberate dark: variant. Nothing
   already handled is overridden, and nothing unhandled is
   left bright.

   Opacity matters here. bg-white/70 is a translucent card and
   has to flip; bg-white/5 through /30 are highlight overlays
   already sitting on something dark — the login panel's stat
   tiles, a nav hover — and flipping those would erase them.
   Only /40 and above are treated as surfaces.
   ════════════════════════════════════════════════════════ */

html.dark :where(.bg-white) { background-color: var(--card); }

html.dark :where(.bg-white\/95) { background-color: rgb(28 24 23 / .95); }
html.dark :where(.bg-white\/90) { background-color: rgb(28 24 23 / .90); }
html.dark :where(.bg-white\/80) { background-color: rgb(28 24 23 / .80); }
html.dark :where(.bg-white\/70) { background-color: rgb(28 24 23 / .70); }
html.dark :where(.bg-white\/60) { background-color: rgb(28 24 23 / .60); }
html.dark :where(.bg-white\/50) { background-color: rgb(28 24 23 / .50); }
html.dark :where(.bg-white\/40) { background-color: rgb(28 24 23 / .40); }

/* The faint fills: a zebra row, an inset panel, a hover. One step
   up from the page rather than one step down from white. */
html.dark :where(.bg-gray-50, .bg-slate-50, .bg-zinc-50, .bg-neutral-50, .bg-stone-50) {
    background-color: var(--surface);
}

html.dark :where(.bg-gray-50\/50, .bg-slate-50\/50) { background-color: rgb(25 21 20 / .5); }
html.dark :where(.bg-slate-50\/60) { background-color: rgb(25 21 20 / .6); }
html.dark :where(.bg-slate-50\/80) { background-color: rgb(25 21 20 / .8); }
html.dark :where(.bg-slate-50\/90) { background-color: rgb(25 21 20 / .9); }

html.dark :where(.bg-gray-100, .bg-slate-100, .bg-zinc-100, .bg-neutral-100, .bg-stone-100) {
    background-color: var(--surface-2);
}

html.dark :where(.bg-slate-100\/50) { background-color: rgb(32 26 24 / .5); }

/* Hover states are their own utilities — .hover\:bg-slate-50:hover is a
   different class from .bg-slate-50 — so a page can be perfectly dark until
   the mouse crosses a row and it flashes white. Row hovers, dropdown items
   and list hovers all land here. */
html.dark :where(.hover\:bg-white):hover {
    background-color: var(--surface);
}

html.dark :where(
    .hover\:bg-gray-50, .hover\:bg-slate-50,
    .hover\:bg-zinc-50, .hover\:bg-neutral-50, .hover\:bg-stone-50
):hover {
    background-color: var(--surface);
}

html.dark :where(
    .hover\:bg-gray-100, .hover\:bg-slate-100,
    .hover\:bg-zinc-100, .hover\:bg-neutral-100, .hover\:bg-stone-100
):hover {
    background-color: var(--surface-2);
}

html.dark :where(.hover\:bg-gray-50\/50, .hover\:bg-slate-50\/50):hover {
    background-color: rgb(32 26 24 / .55);
}

html.dark :where(.hover\:text-gray-900, .hover\:text-slate-900):hover {
    color: var(--ink);
}

html.dark :where(.hover\:border-gray-300, .hover\:border-slate-300):hover {
    border-color: var(--gold-deep);
}

/* Text. Three steps, matching the site: ink for headings and
   figures, body for prose, mute for labels and captions. */
html.dark :where(.text-gray-900, .text-slate-900, .text-zinc-900, .text-neutral-900, .text-stone-900),
html.dark :where(.text-gray-800, .text-slate-800, .text-zinc-800, .text-neutral-800, .text-stone-800) {
    color: var(--ink);
}

html.dark :where(.text-gray-700, .text-slate-700, .text-zinc-700, .text-neutral-700, .text-stone-700),
html.dark :where(.text-gray-600, .text-slate-600, .text-zinc-600, .text-neutral-600, .text-stone-600) {
    color: var(--body);
}

html.dark :where(.text-gray-500, .text-slate-500, .text-gray-400, .text-slate-400),
html.dark :where(.text-zinc-500, .text-neutral-500, .text-stone-500) {
    color: var(--mute);
}

/* Maroon type does not survive a dark page.

   `text-brand` is a fixed hex — #6F0D0E — used 375 times for headings and
   links. On paper it is the brand; on #12100F it is barely a shade above the
   background, which is why "Welcome back" was unreadable in dark. The site
   solves this by swapping its accent to gold in dark, and so does this.

   Filled surfaces are left alone: white on maroon reads in either theme, so
   bg-brand stays maroon and only the type moves. */
html.dark :where(.text-brand) { color: var(--accent); }
html.dark :where(.hover\:text-brand):hover { color: var(--accent); }
html.dark :where(.border-brand) { border-color: var(--accent); }

/* Anything fainter than 400 was already near-invisible on paper;
   on a dark page it has to come up, not go down. */
html.dark :where(.text-gray-300, .text-slate-300, .text-gray-200, .text-slate-200) {
    color: var(--mute);
}

/* Borders and dividers. One line colour, as the site has one. */
html.dark :where(
    .border-gray-100, .border-gray-200, .border-gray-300,
    .border-slate-100, .border-slate-200, .border-slate-300,
    .border-zinc-100, .border-zinc-200, .border-zinc-300,
    .border-neutral-100, .border-neutral-200, .border-neutral-300,
    .border-stone-100, .border-stone-200, .border-stone-300
) {
    border-color: var(--line);
}

html.dark :where(.border-slate-100\/50, .border-slate-200\/50) {
    border-color: rgb(48 40 37 / .5);
}

html.dark :where(.border-white) { border-color: var(--line); }
html.dark :where(.border-white\/40, .border-white\/60) { border-color: rgb(48 40 37 / .6); }

html.dark :where(.divide-gray-100, .divide-gray-200, .divide-slate-100, .divide-slate-200) > :where(* + *) {
    border-color: var(--line);
}

/* Inputs. A form left on white is the most obvious thing on a
   dark page, and the one people actually have to read. */
html.dark :where(input, select, textarea):not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
    background-color: var(--surface);
    border-color: var(--line);
    color: var(--ink);
}

html.dark :where(input, select, textarea)::placeholder {
    color: var(--mute);
}

/* The date and time pickers ship a black glyph that vanishes. */
html.dark :where(input[type="date"], input[type="time"], input[type="datetime-local"])::-webkit-calendar-picker-indicator {
    filter: invert(1) opacity(.65);
}

/* The tinted status pills — emerald, amber, rose, sky — are
   meaning, not decoration, so their text and border stay. Only
   the 50-level fill is dropped to something that reads on a
   dark card instead of glowing. */
html.dark :where(
    .bg-emerald-50, .bg-green-50, .bg-amber-50, .bg-yellow-50, .bg-orange-50,
    .bg-red-50, .bg-rose-50, .bg-blue-50, .bg-sky-50, .bg-indigo-50,
    .bg-violet-50, .bg-purple-50, .bg-teal-50, .bg-cyan-50, .bg-pink-50
) {
    background-color: rgb(255 255 255 / .06);
}

/* ════════ TYPOGRAPHY ════════ */

body {
    background: var(--paper);
    color: var(--body);
    font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    -webkit-font-smoothing: antialiased;
}

/* The serif is the site's signature. Applied to real headings only:
   the portal uses <h2> for card titles that are set in bold sans by a
   utility class, and those keep their utility — `font-display` is the
   opt-in for anything that wants the serif deliberately. */
h1,
.font-display {
    font-family: 'DM Serif Display', Georgia, serif;
    font-weight: 400;
    color: var(--ink);
    letter-spacing: -.015em;
    line-height: 1.12;
}

.pb-eyebrow {
    display: block;
    font-size: 11px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--eyebrow);
    font-weight: 700;
}

::selection {
    background: var(--gold);
    color: #1C1A19;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ════════ TABLE ROW TEXT ════════
   The student list's rows are built as HTML strings in PHP and inserted by
   DataTables after the page has loaded. Their colour used to be
   `text-slate-900`, which meant the most important text on the busiest screen
   in the portal was legible only if a utility override landed — and a name
   that renders dark-on-dark is not a cosmetic fault, it is the row being
   unreadable. These two classes take the tokens directly, so there is no
   cascade to lose. */

.pb-row-name { color: var(--ink); }
.pb-row-meta { color: var(--mute); }

/* ════════ SCROLLBARS ════════
   A cold grey scrollbar on a warm page is the kind of detail that
   makes a skin look half-applied. */

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

*::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

*::-webkit-scrollbar-track {
    background: transparent;
}

*::-webkit-scrollbar-thumb {
    background: var(--line);
    border-radius: 100px;
    border: 2px solid transparent;
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
    background: var(--gold-deep);
    background-clip: content-box;
}

/* ════════ FORM CONTROLS ════════
   Browsers paint these from the accent colour; without this they stay
   system blue against a maroon page. */

input,
select,
textarea,
button {
    font-family: inherit;
}

input[type="checkbox"],
input[type="radio"],
progress,
input[type="range"] {
    accent-color: var(--maroon);
}

/* ════════ BOOTSTRAP ════════
   Loaded for its grid and a few components. Its buttons, links and
   focus rings are Bootstrap blue out of the box. */

.btn-primary,
.bg-primary {
    --bs-btn-bg: var(--maroon);
    --bs-btn-border-color: var(--maroon);
    --bs-btn-hover-bg: var(--maroon-deep);
    --bs-btn-hover-border-color: var(--maroon-deep);
    --bs-btn-active-bg: var(--maroon-deep);
    --bs-btn-active-border-color: var(--maroon-deep);
    --bs-btn-disabled-bg: var(--maroon);
    --bs-btn-disabled-border-color: var(--maroon);
    background-color: var(--maroon);
    border-color: var(--maroon);
}

.btn-outline-primary {
    --bs-btn-color: var(--maroon);
    --bs-btn-border-color: var(--maroon);
    --bs-btn-hover-bg: var(--maroon);
    --bs-btn-hover-border-color: var(--maroon);
    --bs-btn-active-bg: var(--maroon);
}

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

.form-control:focus,
.form-select:focus {
    border-color: var(--gold-deep);
    box-shadow: 0 0 0 .2rem rgba(111, 13, 14, .12);
}

.page-item.active .page-link {
    background-color: var(--maroon);
    border-color: var(--maroon);
}

.page-link {
    color: var(--maroon);
}

/* Bootstrap's own surfaces, which are white from its stylesheet. */
html.dark .card,
html.dark .modal-content,
html.dark .dropdown-menu,
html.dark .list-group-item,
html.dark .form-control,
html.dark .form-select,
html.dark .input-group-text {
    background-color: var(--card);
    border-color: var(--line);
    color: var(--ink);
}

html.dark .table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--body);
    --bs-table-border-color: var(--line);
}

/* ════════ DATATABLES ════════
   The student list is a DataTable, so these controls are on the screen
   the team spends its day in. */

.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_processing,
.dataTables_wrapper .dataTables_paginate {
    color: var(--body) !important;
}

.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 9px;
    padding: 6px 10px;
    color: var(--ink);
}

.dataTables_wrapper .dataTables_paginate .paginate_button {
    border-radius: 8px !important;
    border: 1px solid transparent !important;
    color: var(--body) !important;
}

.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
    background: var(--maroon) !important;
    border-color: var(--maroon) !important;
    color: #fff !important;
}

.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
    background: var(--accent-soft) !important;
    border-color: var(--line) !important;
    color: var(--maroon) !important;
}

table.dataTable thead th {
    border-bottom-color: var(--line) !important;
    color: var(--mute);
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    font-size: 11px;
}

table.dataTable tbody td {
    border-top-color: var(--line) !important;
}

/* DataTables paints its own rows white, from its own stylesheet, so
   the token-based rules above do not reach them. The student list is
   the screen the team lives in; a white grid on a dark page is the
   single most visible thing that can be wrong here. */
html.dark table.dataTable tbody tr,
html.dark table.dataTable tbody tr > * {
    background-color: var(--card);
    color: var(--body);
}

html.dark table.dataTable.stripe tbody tr.odd,
html.dark table.dataTable.display tbody tr.odd {
    background-color: var(--surface);
}

html.dark table.dataTable tbody tr:hover,
html.dark table.dataTable.hover tbody tr:hover {
    background-color: var(--surface-2);
}

html.dark table.dataTable thead th {
    background-color: var(--card);
}

/* With scrollX, DataTables clones the header into its own table inside
   wrapper divs of its own. Those wrappers are white from its stylesheet, so a
   dark grid gets a light band across the top where the header sits — which is
   exactly what a re-skin that stops at the visible table looks like. */
html.dark .dataTables_scroll,
html.dark .dataTables_scrollHead,
html.dark .dataTables_scrollHeadInner,
html.dark .dataTables_scrollBody,
html.dark .dataTables_scrollFoot,
html.dark .dataTables_wrapper {
    background-color: transparent;
    border-color: var(--line);
}

html.dark .dataTables_scrollHead table.dataTable thead th,
html.dark .dataTables_scrollHead th {
    background-color: var(--card);
    color: var(--mute);
    border-bottom-color: var(--line);
}

/* Sticky cells float above their row and carry their own background, so they
   stay light unless told otherwise — the first and last columns of the
   student list. */
html.dark td.sticky,
html.dark th.sticky {
    background-color: var(--card);
}

/* A stale row — a month with a sourcing coordinator and no movement — is
   tinted faint rose so it is visible while scrolling. A 40%-alpha rose over
   a near-black card reads as nothing at all, so the dark tint is warmer and
   stronger rather than fainter. */
html.dark #studentsTable tbody tr.stale-student-row,
html.dark tr.stale-student-row,
html.dark tr.stale-student-row > td {
    background-color: rgb(120 30 35 / .22) !important;
}

html.dark tr.stale-student-row:hover > td {
    background-color: rgb(120 30 35 / .34) !important;
}

/* ════════ SELECT2 ════════ */

.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 9px;
    min-height: 40px;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
    color: var(--ink);
    line-height: 38px;
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 38px;
}

.select2-dropdown {
    background: var(--card);
    border-color: var(--line);
    border-radius: 12px;
    box-shadow: var(--sh-lg);
    overflow: hidden;
}

.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted {
    background: var(--maroon);
    color: #fff;
}

.select2-container--default .select2-results__option[aria-selected="true"] {
    background: var(--accent-soft);
    color: var(--maroon);
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: var(--accent-soft);
    border-color: var(--line);
    color: var(--maroon);
    border-radius: 6px;
}

.select2-search--dropdown .select2-search__field {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 8px;
    color: var(--ink);
}

/* ════════ TOASTR ════════
   Success and error keep their green and red — a confirmation that
   matched the brand would stop reading as a confirmation. Only the
   neutral ones move. */

#toast-container > .toast-info {
    background-color: var(--maroon) !important;
}

#toast-container > div {
    border-radius: 10px !important;
    box-shadow: var(--sh-md) !important;
}

/* ════════ SWEETALERT ════════ */

.swal2-popup {
    border-radius: 16px;
    background: var(--card);
    color: var(--body);
    font-family: 'DM Sans', sans-serif;
}

.swal2-title {
    font-family: 'DM Serif Display', Georgia, serif;
    font-weight: 400;
    color: var(--ink);
}

.swal2-styled.swal2-confirm {
    background: var(--maroon) !important;
    border-radius: 9px !important;
}

.swal2-styled.swal2-cancel {
    background: transparent !important;
    border: 1.5px solid var(--line) !important;
    color: var(--body) !important;
    border-radius: 9px !important;
}

/* ════════ FULLCALENDAR ════════
   The placement roster. Its own chrome is blue-grey by default. */

.fc .fc-button-primary {
    background: var(--maroon);
    border-color: var(--maroon);
}

.fc .fc-button-primary:hover,
.fc .fc-button-primary:not(:disabled).fc-button-active {
    background: var(--maroon-deep);
    border-color: var(--maroon-deep);
}

.fc .fc-toolbar-title {
    font-family: 'DM Serif Display', Georgia, serif;
    font-weight: 400;
    color: var(--ink);
}

.fc-theme-standard td,
.fc-theme-standard th,
.fc-theme-standard .fc-scrollgrid {
    border-color: var(--line);
}

.fc .fc-day-today {
    background: var(--accent-soft) !important;
}

/* The placement window highlight, defined here rather than inline so
   it follows the theme. */
.fc-day-in-range {
    background: var(--gold-soft);
}

html.dark .fc-day-in-range {
    background: rgba(212, 183, 140, .08);
}

/* ════════ THE LOADER ════════ */

.loader-ring {
    border-color: var(--line) !important;
    border-top-color: var(--maroon) !important;
}

/* ════════ PRINT ════════
   Paper stock on paper is a waste of toner. */

@media print {
    body {
        background: #fff;
    }
}
