/* ============================================================
 * Batch periods — summary strip, period list, banded month grid
 * (.ng-period-strip, .ng-period-list, .ng-period-grid)
 * ------------------------------------------------------------
 * The payment batch detail page has to say three things about
 * money that a single "total" hid until #1115: what the operator
 * asked for (the declared cycle), what else the batch settled
 * (back-pay for earlier months), and the authoritative batch
 * total the two must add up to. Markup and rationale:
 * resources/views/pages/payment/details.blade.php and
 * docs/design.md, "Batch periods".
 *
 * TWO SIGNALS, NOT ONE. Back-pay is tinted AND named — the band
 * header, the strip label and the per-period tag all carry the
 * word. Tint alone would fail WCAG 1.4.1: an operator who cannot
 * discriminate hue would see one undifferentiated run of month
 * columns, which is the state this page was in before.
 *
 * Colour comes from one semantic group added for this component,
 * `--color-period-*` (_tokens.css), so every surface that names a
 * period agrees and the whole thing flips with the dark theme:
 *   selected cycle  --color-period-selected  (brand primary/navy)
 *   back-pay        --color-period-backpay   (brand rust)
 *   later periods   --color-period-later     (warning tone) —
 *                   rare, and NOT back-pay: a period after the
 *                   declared window is not money owed for the
 *                   past, and someone should look at it (#1053).
 *
 * Nothing here reaches for a raw palette step. A border or wash
 * taken from a `-50`/`-100` rung stays light in the dark theme;
 * the pairs above are overridden there.
 * ============================================================ */

/* ---------- SUMMARY STRIP ---------- */

.ng-period-strip {
    display: flex;
    flex-wrap: wrap;
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md) var(--radius-md) 0 0;
}

/* The strip and the period list are one object: the list hangs off
   the strip's bottom edge, so the strip only rounds its top when a
   list follows it. */
.ng-period-strip:last-child {
    border-radius: var(--radius-md);
    margin-bottom: var(--space-4);
}

.ng-period-strip__cell {
    flex: 1 1 190px;
    min-width: 0;
    padding: var(--space-3) var(--space-4);
    border-right: 1px solid var(--color-border-subtle);
}

.ng-period-strip__cell:last-child {
    border-right: 0;
}

.ng-period-strip__label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: 3px;
    font-size: 11px;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-faint);
}

.ng-period-strip__value {
    font-family: var(--font-family-data);
    font-size: 19px;
    font-weight: 660;
    line-height: 1.2;
    color: var(--color-text-strong);
    font-variant-numeric: tabular-nums;
}

/* The batch total leads the strip, so it is the largest figure on it. */
.ng-period-strip__value--total {
    font-size: 23px;
}

/* A zero that is a fact rather than a gap ("no back-pay"). */
.ng-period-strip__value--quiet {
    color: var(--color-text-muted);
}

.ng-period-strip__note {
    margin-top: 2px;
    font-size: 11px;
    color: var(--color-text-muted);
}

/* Ties each cell to its band in the table below. Decoration only —
   the label beside it carries the meaning. */
.ng-period-strip__swatch {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 2px;
}

.ng-period-strip__swatch--selected { background: var(--color-period-selected); }
.ng-period-strip__swatch--backpay  { background: var(--color-period-backpay); }
.ng-period-strip__swatch--later    { background: var(--color-period-later); }

/* ---------- PER-PERIOD LIST ---------- */

.ng-period-list {
    margin-bottom: var(--space-4);
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-top: 0;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    overflow: hidden;
}

.ng-period-list > summary {
    padding: var(--space-2) var(--space-4);
    font-size: 12px;
    font-weight: 620;
    color: var(--color-text-muted);
    cursor: pointer;
    list-style: none;
}

.ng-period-list > summary::-webkit-details-marker {
    display: none;
}

.ng-period-list > summary::before {
    content: '\25B8';                       /* ▸ */
    display: inline-block;
    margin-right: var(--space-2);
    font-size: 11px;
    color: var(--color-text-faint);
    transition: transform var(--motion-fast) ease;
}

.ng-period-list[open] > summary::before {
    transform: rotate(90deg);
}

.ng-period-list > summary:hover,
.ng-period-list > summary:focus-visible {
    color: var(--color-text-strong);
}

.ng-period-list__body {
    padding: 0 var(--space-4) var(--space-3);
}

/* A quiet inner table: it is a breakdown of the strip above it, not
   a second data grid competing with the members table below. */
.ng-period-list__table {
    margin-bottom: 0;
    font-size: 12px;
}

.ng-period-list__table > thead > tr > th {
    padding: 5px 8px;
    font-size: 10px;
    font-weight: 650;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-faint);
    border-bottom: 1px solid var(--color-border-subtle);
}

.ng-period-list__table > tbody > tr > td,
.ng-period-list__table > tfoot > tr > td {
    padding: 5px 8px;
    font-variant-numeric: tabular-nums;
}

.ng-period-list__table > tfoot > tr > td {
    font-weight: 660;
    color: var(--color-text-strong);
    border-top: 1px solid var(--color-border-default);
}

/* ---------- PERIOD TAGS ---------- */

/* No border: the tone pairs are the whole signal, and a border drawn
   from a light palette step would stay light in the dark theme —
   the same trap .ng-status-pill avoids by using fill + text only. */
.ng-period-tag {
    display: inline-block;
    margin-right: 7px;
    padding: 1px 6px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-radius: var(--radius-sm);
}

.ng-period-tag--backpay {
    background: var(--color-period-backpay-bg);
    color: var(--color-period-backpay);
}

.ng-period-tag--selected {
    background: var(--color-period-selected-bg);
    color: var(--color-period-selected);
}

.ng-period-tag--later {
    background: var(--color-period-later-bg);
    color: var(--color-period-later);
}

/* The title pill. Reuses .ng-status-pill's geometry (_profile.css)
   with the back-pay tone, and is an anchor, so it also has to stop
   looking like body-text link. */
.ng-status-pill--backpay {
    background: var(--color-period-backpay-bg);
    color: var(--color-period-backpay);
    text-decoration: none;
}

/* Hover lifts the TEXT rather than darkening the wash: the wash is a
   themed token and a hover step of it would need its own dark
   override to stay legible. */
.ng-status-pill--backpay:hover,
.ng-status-pill--backpay:focus-visible {
    color: var(--color-text-strong);
    text-decoration: none;
}

/* ---------- BANDED MONTH GRID ---------- */

/* The band row sits above the real header row and groups the month
   columns. Its blanks must read as page background, not as header
   cells, or the row looks like a header with empty labels. */
.ng-period-grid__bands > th {
    text-align: center;
    padding: 6px 10px;
    font-size: 11px;
    font-weight: 650;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    background: var(--color-bg-raised);
    border-bottom: 1px solid var(--color-border-default);
}

.ng-period-grid__band--blank {
    background: var(--color-bg-surface);
    border-bottom-color: transparent;
}

/* 3px inset underline rather than a border: the band's job is to
   claim the columns beneath it, and a solid rule of the band's own
   colour reads as ownership where a border reads as a box. */
.ng-period-grid__band--selected {
    color: var(--color-period-selected);
    box-shadow: inset 0 -3px 0 var(--color-period-selected);
}

.ng-period-grid__band--backpay {
    color: var(--color-period-backpay);
    background: var(--color-period-backpay-bg);
    box-shadow: inset 0 -3px 0 var(--color-period-backpay);
}

.ng-period-grid__band--later {
    color: var(--color-period-later);
    background: var(--color-period-later-bg);
    box-shadow: inset 0 -3px 0 var(--color-period-later);
}

/* Column tints, header and body alike. Kept faint: they run the
   whole height of a long table, and the band + tag carry the
   meaning.

   `!important` defeats one of our own, the same one the frozen columns
   below have to defeat: _data-display.css sets `background:
   transparent !important` on every table cell so the row carries the
   zebra. Without it these rules are in the stylesheet, matching the
   right cells, and painting nothing — which is how the tint shipped
   invisible in the first draft. Winning that also wins over the row
   hover, so the hover state is restated here rather than lost. */
table.ng-period-grid > thead > tr > th.ng-period-grid__cell--backpay,
table.ng-period-grid > tbody > tr > td.ng-period-grid__cell--backpay {
    background: var(--color-period-backpay-bg) !important;
}

table.ng-period-grid > thead > tr > th.ng-period-grid__cell--later,
table.ng-period-grid > tbody > tr > td.ng-period-grid__cell--later {
    background: var(--color-period-later-bg) !important;
}

table.ng-period-grid.table-hover > tbody > tr:hover > td.ng-period-grid__cell--backpay {
    background: var(--color-period-backpay-bg-hover) !important;
}

table.ng-period-grid.table-hover > tbody > tr:hover > td.ng-period-grid__cell--later {
    background: var(--color-period-later-bg-hover) !important;
}

/* The collapsed back-pay subtotal column, and its expand control. */
.ng-period-grid__collapsed {
    min-width: 130px;
    white-space: nowrap;
}

.ng-period-grid__toggle {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-weight: 650;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-period-backpay);
    cursor: pointer;
    white-space: nowrap;
}

.ng-period-grid__toggle::after {
    content: '\25B8';                       /* ▸ */
    display: inline-block;
    margin-left: var(--space-2);
    font-size: 10px;
    transition: transform var(--motion-fast) ease;
}

.ng-period-grid__toggle[aria-expanded='true']::after {
    transform: rotate(90deg);
}

/* ---------- FROZEN EDGES ----------
   Reg no + Name hold the left edge and Total the right, so the band
   above the month columns still names what you are reading however
   far the grid has scrolled inside .ng-tablescroll. The left offsets
   are published per draw as custom properties by the page's
   applyFrozenOffsets(): the first frozen column's position depends
   on permission-dependent columns (bulk-select, account) and on the
   content width of Reg no, so a stylesheet cannot know it. The
   fallbacks keep the columns merely un-offset rather than stacked if
   the script never runs. */
/* Selectors carry the table class as well as the cell class on
   purpose: DataTables ships `table.dataTable thead th { position:
   relative }` for its sort arrows, which outweighs a single class
   and silently turns every frozen header cell back into a normal
   one. Two classes beat one — measured, not assumed (the first
   browser pass had position:relative on the Reg no header). */
table.ng-period-grid > thead > tr > th.ng-period-grid__freeze,
table.ng-period-grid > tbody > tr > td.ng-period-grid__freeze,
table.ng-period-grid > thead > tr > th.ng-period-grid__total,
table.ng-period-grid > tbody > tr > td.ng-period-grid__total {
    position: sticky;
    z-index: 2;
    background: var(--color-bg-surface);
}

table.ng-period-grid > thead > tr > th.ng-period-grid__freeze--reg,
table.ng-period-grid > tbody > tr > td.ng-period-grid__freeze--reg {
    left: var(--ng-freeze-reg, 0);
}

table.ng-period-grid > thead > tr > th.ng-period-grid__freeze--name,
table.ng-period-grid > tbody > tr > td.ng-period-grid__freeze--name {
    left: var(--ng-freeze-name, 0);
    box-shadow: 1px 0 0 var(--color-border-default);
}

table.ng-period-grid > thead > tr > th.ng-period-grid__total,
table.ng-period-grid > tbody > tr > td.ng-period-grid__total {
    right: 0;
    font-weight: 650;
    color: var(--color-text-strong);
    background: var(--color-bg-raised);
    box-shadow: -1px 0 0 var(--color-border-default);
}

/* NOTE: this grid stays on the app's collapsed borders
   (_data-display.css sets `border-collapse: collapse !important` for
   every table). Sticky cells and collapsed borders were long a bad
   pair, but they hold in current engines — verified in the browser
   here, body and header both — and forcing `separate` for one table
   would have changed its rules and spacing to fix nothing. */

/* Header cells outscroll the body ones, so they need to sit above
   them as well as above the rows.

   `!important` here defeats an `!important` of OUR OWN:
   _data-display.css pins `position: relative` on DataTables' sortable
   header cells so the sort arrows can be absolutely placed, and that
   silently unsticks every frozen header — the column scrolls away
   from its own heading while the body cells stay. One level more
   specific plus the same weapon is the only way past it; the arrows
   still position correctly against a sticky cell, which is also a
   positioned ancestor. */
table.ng-period-grid > thead > tr > th.ng-period-grid__freeze,
table.ng-period-grid > thead > tr > th.ng-period-grid__total {
    position: sticky !important;
    z-index: 4;
    background: var(--color-bg-sunken);
}

/* In the band row the frozen positions are blanks, so they take the
   page surface like the rest of the row. */
.ng-period-grid__bands th.ng-period-grid__band--blank {
    z-index: 3;
}

/* A frozen cell MUST be opaque — the columns scrolling beneath it
   show through otherwise, which is not subtle: two rows of text on
   top of each other.

   `!important` again defeats one of our own: _data-display.css sets
   `background: transparent !important` on every table cell so the
   row carries the zebra. So the frozen columns restate the zebra
   themselves, and restate the hover tint too, or they would be the
   only cells in the row that do not light up under the pointer. */
table.ng-period-grid > tbody > tr > td.ng-period-grid__freeze {
    background: var(--color-bg-surface) !important;
}

table.ng-period-grid > tbody > tr:nth-child(even) > td.ng-period-grid__freeze {
    background: var(--color-bg-raised) !important;
}

table.ng-period-grid > tbody > tr > td.ng-period-grid__total {
    background: var(--color-bg-raised) !important;
}

table.ng-period-grid.table-hover > tbody > tr:hover > td.ng-period-grid__freeze,
table.ng-period-grid.table-hover > tbody > tr:hover > td.ng-period-grid__total {
    background: var(--color-bg-app) !important;
}

/* ---------- MISMATCH ALERT ----------
   The control's voice: the page is reporting on itself, so it is a
   warning about the page rather than about the batch. Deliberately
   full-width above the strip — it must not be dismissible and must
   not be mistaken for a filter hint. */
.ng-period-mismatch {
    margin-bottom: var(--space-4);
}
