/**
 * DataTables, wearing the design system.
 *
 * Loaded on every page that renders a table — around seventy of them — so this file decides what
 * most of the dashboard looks like day to day. Colours are custom properties declared in
 * assets/css/app.css, which is loaded first: the two cannot drift, and changing the palette in one
 * place changes the tables too. It used to be forty-odd hardcoded hexes from the previous grey.
 *
 * THE ONE EXCEPTION is `table.dataTable thead th` and its dark counterpart, which keep their exact
 * original values on purpose. The table header is settled and is not to be restyled; see the note
 * above that rule.
 *
 * Dark mode keys off html.dark, matching the Tailwind config's darkMode:'class'.
 *
 * The !important flags are DataTables' own doing — its stylesheet sets these same properties with
 * high-specificity selectors of its own, and it is loaded after this file on most pages.
 */

/* ============================================================================================
   The shared loading spinner
   ============================================================================================
   Used by setButtonLoading()/setTableLoading() in views/partials/authed-header.php, which every
   page carrying this stylesheet also carries. Plain CSS rather than a Tailwind arbitrary class, so
   it applies regardless of when the CDN runtime next scans the DOM. currentColor lets one class
   look right inside a coloured button and inside the neutral table overlay below. */

.spinner {
    display: inline-block;
    width: 1em;
    height: 1em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
    vertical-align: -0.15em;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .spinner { animation-duration: 1.8s; }
}

.table-loading-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.72);
    z-index: 10;
}

html.dark .table-loading-overlay {
    background: rgba(15, 20, 27, 0.72);   /* --vs-950, the dark surface underneath */
}

.table-loading-overlay .spinner {
    width: 1.5em;
    height: 1.5em;
    color: var(--vs-brand);
}

html.dark .table-loading-overlay .spinner {
    color: var(--vs-brand-text);
}

/* ============================================================================================
   The table
   ============================================================================================ */

table.dataTable {
    width: 100% !important;
    border-collapse: collapse !important;
    font-size: 0.8125rem;
}

/*
 * The header is deliberately NOT on the tokens below. It is the one part of these tables that
 * was already settled, so it keeps its own values exactly — burgundy caps on a pale ground with
 * a pink rule. Do not "tidy" these into var(--vs-…): the nearest token is not the same colour,
 * and the difference is visible on every table in the app.
 */
table.dataTable thead th {
    background-color: #f9fafb;
    color: #800020;
    font-weight: 600;
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-align: center;
    padding: 14px 14px !important;
    border-bottom: 2px solid #fbe0e4 !important;
    border-top: none !important;
}

table.dataTable tbody td {
    padding: 17px 14px !important;
    color: var(--vs-700);
    text-align: center;
    border-bottom: 1px solid var(--vs-100) !important;
    vertical-align: middle;
}

table.dataTable tbody tr:nth-child(even) td {
    background-color: var(--vs-50);
}

/* Rows in these tables open the job they describe, so the hover state is the brand — it means
   "you can act on this", the same as everywhere else the brand appears. */
table.dataTable tbody tr:hover td {
    background-color: var(--vs-brand-soft);
}

table.dataTable.no-footer {
    border-bottom: none !important;
}

table.dataTable td.dt-empty {
    padding: 32px 12px !important;
    color: var(--vs-400);
    font-style: italic;
}

table.dataTable thead .dt-column-order:before,
table.dataTable thead .dt-column-order:after {
    opacity: 0.35;
}

/* ============================================================================================
   The control rows
   ============================================================================================
   DataTables lays a table out as three rows inside .dt-container: the controls, the table, and the
   footer controls. Only the middle one is .dt-layout-table, so :not() reaches exactly the two that
   hold the search box, the entries-per-page select, the row count and the pagination.

   14px is the horizontal padding every cell above uses, so the controls line up with the first
   column instead of the card's edge. The table row is left alone — some pages scroll it sideways in
   its own wrapper, and indenting it would fight that. */

.dt-container .dt-layout-row:not(.dt-layout-table) {
    padding-left: 14px;
    padding-right: 14px;
}

.dt-container .dt-layout-row:not(.dt-layout-table):first-child {
    padding-top: 0.75rem;
}

.dt-container .dt-layout-row:not(.dt-layout-table):last-child {
    padding-bottom: 0.75rem;
}

.dt-search,
.dt-length {
    color: var(--vs-600) !important;
    font-size: 0.8125rem !important;
}

/* Matches $selectClass and $inputClass in views/partials/design-system.php, which app.css now sets
   to 13px: a search box that sits above a filter bar should not be a different size from it, and
   neither should be larger than the table rows underneath. */
.dt-search input,
.dt-length select {
    border: 1px solid var(--vs-200) !important;
    border-radius: 0.5rem !important;
    padding: 0.5rem 0.75rem !important;
    font-size: 0.8125rem !important;
    color: var(--vs-700) !important;
    background-color: #FFFFFF !important;
}

.dt-search input:focus,
.dt-length select:focus {
    outline: none !important;
    border-color: var(--vs-brand-lift) !important;
    box-shadow: 0 0 0 2px rgba(163, 14, 51, 0.2) !important;
}

/* The page numbers carried no size of their own and inherited DataTables' 0.875rem, leaving them a
   step larger than the rows they page through and than .dt-info sitting beside them. */
html div.dt-container .dt-paging .dt-paging-button {
    border-radius: 0.375rem !important;
    margin: 0 2px !important;
    padding: 0.3rem 0.65rem !important;
    font-size: 0.8125rem !important;
    color: var(--vs-600) !important;
    border: 1px solid transparent !important;
}

/* `div.dt-container` IS LOAD-BEARING, do not simplify this selector.
 *
 * DataTables' own sheet carries:
 *
 *     div.dt-container .dt-paging .dt-paging-button.current,
 *     div.dt-container .dt-paging .dt-paging-button.current:hover { color: inherit !important; }
 *
 * That scores (0,4,1). A plain `.dt-paging .dt-paging-button.current` scores (0,3,0) and loses even
 * with !important, so the active page number inherited the body colour and rendered BLACK on the
 * brand fill. The background looked right throughout, because DataTables sets its background without
 * !important — only `color` was being overridden, which is what made it hard to spot.
 *
 * Verified in a browser, not reasoned about: computed colour was rgb(0,0,0) before this change.
 */
html div.dt-container .dt-paging .dt-paging-button.current,
html div.dt-container .dt-paging .dt-paging-button.current:hover {
    background: var(--vs-brand) !important;
    color: #FFFFFF !important;
    border: 1px solid var(--vs-brand) !important;
}

/* MUST exclude .current. `:not(.disabled)` contributes its argument's specificity, so this selector
   scores (0,4,0) against .current's (0,3,0) and wins even though both carry !important — hovering
   the active page turned its text brand-red on a brand-red background, which is unreadable and looks
   like the number has vanished. The rule below restores white under the cursor. */
html div.dt-container .dt-paging .dt-paging-button:hover:not(.disabled):not(.current) {
    background: var(--vs-brand-soft) !important;
    color: var(--vs-brand) !important;
}

.dt-info {
    color: var(--vs-500) !important;
    font-size: 0.8125rem !important;
}

/* ============================================================================================
   Responsive: the row that becomes a list on a narrow screen
   ============================================================================================
   The Responsive extension hides the columns that do not fit and reveals them in a child row. That
   child row is what these tables look like on a phone, so it gets the same treatment as the rest. */

table.dataTable > tbody > tr.child ul.dtr-details {
    width: 100%;
    padding: 0.25rem 0 !important;
}

table.dataTable > tbody > tr.child ul.dtr-details > li {
    border-bottom: 1px solid var(--vs-100) !important;
    padding: 0.4rem 0 !important;
}

table.dataTable > tbody > tr.child ul.dtr-details > li:last-child {
    border-bottom: none !important;
}

table.dataTable > tbody > tr.child span.dtr-title {
    color: var(--vs-500);
    font-weight: 600;
    min-width: 40%;
}

/* Status badges moved to assets/css/app.css, where the rest of the design system lives.
   They were never DataTables-specific, and left here they loaded after app.css and won. */

/* ============================================================================================
   Dark
   ============================================================================================ */

html.dark table.dataTable thead th {
    background-color: #1a1d26;
    color: #ff8fab;
    border-bottom-color: rgba(161, 0, 48, 0.35) !important;
}

html.dark table.dataTable tbody td {
    color: var(--vs-300);
    border-bottom-color: var(--vs-800) !important;
}

html.dark table.dataTable tbody tr:nth-child(even) td {
    background-color: rgba(255, 255, 255, 0.02);
}

html.dark table.dataTable tbody tr:hover td {
    background-color: var(--vs-brand-soft);
}

html.dark table.dataTable td.dt-empty {
    color: var(--vs-500);
}

html.dark .dt-search,
html.dark .dt-length {
    color: var(--vs-300) !important;
}

html.dark .dt-search input,
html.dark .dt-length select {
    background-color: var(--vs-900) !important;
    border-color: var(--vs-800) !important;
    color: var(--vs-100) !important;
}

html.dark div.dt-container .dt-paging .dt-paging-button {
    color: var(--vs-300) !important;
}

/* `color` is set here, not left to the light .current rule above. `html.dark .dt-paging
   .dt-paging-button` scores (0,3,1) against that rule's (0,3,0), so without this line the active
   page inherits --vs-300 and renders grey on the brand fill instead of white. */
/* Same reason as the light rule: DataTables' (0,4,1) `color: inherit !important` matches under
   html.dark too, since its selector says nothing about the theme. This scores (0,5,1). */
html.dark div.dt-container .dt-paging .dt-paging-button.current,
html.dark div.dt-container .dt-paging .dt-paging-button.current:hover {
    background: var(--vs-brand-lift) !important;
    color: #FFFFFF !important;
    border: 1px solid var(--vs-brand-lift) !important;
}

/* Same exclusion as the light rule above, and for the same reason. */
html.dark div.dt-container .dt-paging .dt-paging-button:hover:not(.disabled):not(.current) {
    background: var(--vs-brand-soft) !important;
    color: var(--vs-brand-text) !important;
}

html.dark .dt-info {
    color: var(--vs-400) !important;
}

html.dark table.dataTable > tbody > tr.child ul.dtr-details > li {
    border-bottom-color: var(--vs-800) !important;
}

html.dark table.dataTable > tbody > tr.child span.dtr-title {
    color: var(--vs-400);
}
