/* server-grid.css — chrome for the reusable server-side grid (_ServerGrid partial + server-grid.js).
   Implements the DataTables UI/UX standards (see tr-webui/CLAUDE.md). Colours come from Bootstrap CSS
   variables only (no hardcoded hex), per the theming rules. */

/* ── 1. Fixed column widths — every column has a defined width; the table never auto-sizes. ──────────────── */
.sg table.dataTable {
    table-layout: fixed;
}

/* ── 2. Cell content: vertically centred, horizontally left-aligned (ALL cells, incl. numeric). ─────────── */
/* ── 4. Long cell content truncates with an ellipsis (full text shown via a title tooltip set in JS). ───── */
.sg table.dataTable > tbody > tr > td {
    vertical-align: middle;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── 4a. OPT-OUT from the truncation above, per column. A cell whose content carries `.serial-full` shows its
   value IN FULL: no clipping, no ellipsis (GCC observation #87 — a serial is a permanent public record, and a
   half-serial is worse than none). The column is sized to fit and the table scrolls inside .table-responsive.
   Opt-in only, so every other grid and column keeps the standard one-line + tooltip behaviour. ───────────── */
.sg table.dataTable > tbody > tr > td:has(.serial-full) {
    overflow: visible;
    text-overflow: clip;
}

/* Horizontal padding + comfortable rows. */
.sg table.dataTable > tbody > tr > td,
.sg table.dataTable > thead > tr > th {
    padding-left: .75rem;
    padding-right: .75rem;
}

.sg table.dataTable > tbody > tr > td:first-child,
.sg table.dataTable > thead > tr > th:first-child {
    padding-left: 1.25rem;
}

.sg table.dataTable > tbody > tr > td {
    padding-top: .7rem;
    padding-bottom: .7rem;
    line-height: 1.35;
}

/* ── 1 (headers) + 2/8 + 3 + 5. Header cell.
      • The title and its icon cluster form ONE flex row that is vertically CENTRED in the cell — so a short header and
        a header that wraps to 2–3 lines are both centred as a block (item 1 applied to HEADERS, not just data cells).
      • The icon cluster (sort indicator, filter funnel, three-dot menu) is a flex sibling with a fixed gap between
        every icon. Because the icons live in a non-shrinking flex box and the NATIVE DataTables sort arrow is
        suppressed (below), the icons can NEVER overlap each other or an arrow at ANY column width: when a column is
        too narrow, the TITLE shrinks/wraps while the icon box keeps its size and its gaps (items 2 + 8). This holds
        for the narrowest column and for a wrapped multi-line header alike — there is no width at which two icons share
        space. ───────────────────────────────────────────────────────────────────────────────────────────────────── */
.sg-head > th {
    vertical-align: middle;              /* 1. centre the header block vertically (incl. wrapped titles) */
}

.sg-th {
    display: flex;
    align-items: center;                 /* icons stay centred against the (possibly multi-line) title */
    gap: .5rem;
}

.sg-th-title {
    flex: 1 1 auto;                      /* the title takes the slack and SHRINKS/wraps first… */
    min-width: 0;                        /* …allow it to shrink below its content width so the icons never get pushed */
    white-space: normal;                 /* 5. long headers wrap instead of clipping */
    word-break: break-word;
    line-height: 1.25;
}

.sg-th-icons {
    flex: 0 0 auto;                      /* the icon cluster never shrinks — guarantees the fixed gaps hold */
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    white-space: nowrap;
}

/* Suppress the DataTables NATIVE sort arrow for our grid. It is absolutely positioned at the cell's right edge and was
   the source of the sort-arrow ⇄ icon overlap. We render our own indicator (.sg-sort-ind) inside the flex cluster
   instead, so there is no free-floating arrow to collide with anything. */
.sg table.dataTable > thead > tr > th.sorting::before,
.sg table.dataTable > thead > tr > th.sorting::after,
.sg table.dataTable > thead > tr > th.sorting_asc::before,
.sg table.dataTable > thead > tr > th.sorting_asc::after,
.sg table.dataTable > thead > tr > th.sorting_desc::before,
.sg table.dataTable > thead > tr > th.sorting_desc::after {
    content: none !important;
}
/* …and reclaim the right padding DataTables reserved for that arrow (else every sortable header carries dead space). */
.sg table.dataTable > thead > tr.sg-head > th.sorting,
.sg table.dataTable > thead > tr.sg-head > th.sorting_asc,
.sg table.dataTable > thead > tr.sg-head > th.sorting_desc {
    padding-right: .75rem;
}

/* ── 6. Vertical separator between column HEADERS only (never between data cells). ──────────────────────── */
.sg-head > th:not(:last-child) {
    border-right: 1px solid var(--bs-border-color);
}

/* ── 3 + 7. Header icons are DARK and clearly visible — not faint. `currentColor` = the header's own text colour: the
      dark body colour on the default light header, and the WCAG-computed readable colour on a program-themed header,
      so the icons stay clearly visible on either. No opacity dimming on the funnel. ─────────────────────────────── */
.sg-filter-icon,
.sg-sort-ind {
    color: currentColor;
    cursor: pointer;
    font-size: .85rem;
    line-height: 1;
    opacity: 1;
}

/* Active filter → the prominent primary "blue dot". */
.sg-filter-icon.sg-filter-on {
    color: var(--bs-primary);
    position: relative;
}

.sg-filter-icon.sg-filter-on::after {
    content: '';
    position: absolute;
    top: -2px;
    inset-inline-end: -4px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--bs-primary);
}

/* Sort indicator: a faint neutral up/down glyph until this column is the active sort, then primary + full strength. */
.sg-sort-ind {
    opacity: .55;
}

.sg-sort-ind.sg-sort-active {
    opacity: 1;
    color: var(--bs-primary);
}

/* ── Filter row beneath the headers. ───────────────────────────────────────────────────────────────────── */
.sg-filter-row > th {
    padding: .3rem .5rem;
    background: var(--bs-tertiary-bg);
    border-bottom: 2px solid var(--bs-border-color);   /* clear separation from the first data row */
}

.sg-filter-row input,
.sg-filter-row select {
    max-width: 100%;
}

.sg-filter-row input:disabled {
    background: var(--bs-secondary-bg);
    cursor: not-allowed;
}

/* Flatpickr date filters: the visible input (Flatpickr copies the .form-control-sm class onto its altInput) must fill
   the filter cell like the other inputs. Range mode shows one box ("12 Jul 2026 to 31 Aug 2026"); single mode one date. */
.sg-filter-row .flatpickr-input,
.sg-filter-row input.form-control.input {
    width: 100%;
    background-color: var(--bs-body-bg);   /* Flatpickr's readonly altInput otherwise looks disabled */
}

/* Docked side panels. */
.sg-offcanvas {
    --bs-offcanvas-width: 20rem;
}

/* ── Click-to-copy (A1) ─────────────────────────────────────────────────────────────────────────────
   An .sg-copy control (the Account Id cell, each admin email) copies its value on click/Enter/Space. It reads as an
   inline interactive token — pointer cursor, a subtle copy affordance on hover, and a brief "copied" flash. HTML cells
   opt in via ServerGridColumn.Html; the copy behaviour itself lives in server-grid.js (delegated on the grid root). */
.sg-copy {
    cursor: pointer;
    border-radius: 0.2rem;
    padding: 0 0.15rem;
    transition: background-color 0.12s ease-in-out;
    outline: none;
}
.sg-copy:hover,
.sg-copy:focus-visible {
    background-color: var(--bs-secondary-bg, rgba(0, 0, 0, 0.06));
}
.sg-copy:focus-visible {
    box-shadow: 0 0 0 0.15rem var(--bs-primary-border-subtle, rgba(13, 110, 253, 0.35));
}
/* The transient "copied" cue (server-grid.js toggles .sg-copied for ~1.2s). */
.sg-copy.sg-copied {
    background-color: var(--bs-success-bg-subtle, #d1e7dd);
    color: var(--bs-success-text-emphasis, #0a3622);
}
.sg-copy.sg-copied::after {
    content: "\2713";                 /* ✓ — a small confirmation glyph next to the copied value */
    margin-left: 0.25rem;
    font-weight: 600;
}
/* Stacked cell items (two admins / two emails — one per line). */
.sg-stacked {
    display: block;
    line-height: 1.35;
}

/* ── Columns chooser panel (UI-GRID-STANDARDS 1b + 1c) ───────────────────────────────────────────────────────────
   The search box, select-all and count are pinned above a scrolling, grouped list. With 50+ columns a panel that
   scrolls its own controls out of reach makes the user hunt for them. */
.sg-offcanvas .sg-cols-tools {
    padding-top: .25rem;
    background-color: var(--bs-offcanvas-bg, var(--bs-body-bg));
}
.sg-offcanvas .sg-cols-list {
    overflow-y: auto;
}
/* A group heading sits with its entries, with air above it so the sections read as sections rather than as one run
   of checkboxes — which is what made the old panel feel crowded. */
.sg-offcanvas .sg-cols-group + .sg-cols-group {
    padding-top: .25rem;
    border-top: 1px solid var(--bs-border-color-translucent, rgba(0, 0, 0, .08));
}
.sg-offcanvas .sg-cols-group-title {
    letter-spacing: .04em;
}
.sg-offcanvas .sg-colvis-row {
    padding-block: .15rem;               /* comfortable spacing without turning the list into a long scroll */
}

/* ── User-resizable columns (UI-GRID-STANDARDS 5) ────────────────────────────────────────────────────────────────
   A narrow grab strip on the header's TRAILING EDGE. It is absolutely positioned, so it is not a flex item and
   cannot disturb the title/icon layout above — rule 2 (sort and filter icons untouched) and rule 3 (headers wrap)
   both still hold. It sits outside the icon cluster's own box, so it never swallows an icon's click. */
.sg-head > th {
    position: relative;
}
.sg-resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    width: 6px;                          /* narrow enough to stay clear of the icons, wide enough to grab */
    height: 100%;
    cursor: col-resize;
    user-select: none;
    touch-action: none;
}
.sg-resize-handle:hover,
body.sg-resizing .sg-resize-handle {
    background-color: var(--bs-primary-border-subtle, rgba(13, 110, 253, .35));
}
/* While dragging, stop the pointer selecting header text and keep the resize cursor everywhere. */
body.sg-resizing {
    cursor: col-resize;
    user-select: none;
}

/* ── Columns chooser: a light separator between entries (Tushar, observation 10, 8 Oct 2026) ─────────────────────
   The group headings already separate the sections; within a section a long run of checkboxes still reads as one
   block. A hairline between rows gives the eye something to track along without adding weight. */
.sg-offcanvas .sg-colvis-row + .sg-colvis-row {
    border-top: 1px solid var(--bs-border-color-translucent, rgba(0, 0, 0, .06));
}
