/* ============================================================================
   responsive-table.css — column tiers + bottom sheet for MudDataGrid
   ----------------------------------------------------------------------------
   Adapted from a Blazor handoff drop-in (since deleted; its substance is recorded in
   ../SAMSVoice/RESPONSIVE_GRID_NOTES.md). Two deliberate departures
   from that drop-in, both forced by this app:

   1. NO BOOTSTRAP. The handoff's whole mechanism is Bootstrap 5.3 display
      utilities (d-none / d-lg-table-cell / d-lg-none) plus .offcanvas and
      Bootstrap Icons. This portal loads MudBlazor + app.css and nothing else
      (see App.razor), so every one of those classes would match no rule —
      the columns would never hide AND the sheet rows would never hide, so each
      field would render TWICE and the sheet would sit unstyled in normal flow.
      It fails silently, which is why it is rewritten here under rt- names.

   2. THIS APP'S BREAKPOINTS, NOT BOOTSTRAP'S. app.css already gives 600px and
      900px meaning (page chrome; the grid card treatment), and MudBlazor uses
      600/960/1280/1920. Bootstrap's 576/768/992/1200 would have been a third
      system. Tiers below are 600 / 900 / 1280 / 1920.

   THE CORE IDEA IS UNCHANGED and it is the good part: the table-cell class and
   the sheet-row class are exact inverses, so a field is visible in exactly one
   place at any width, enforced by CSS with no state to keep in sync and no
   breakpoint round-trip to the server (Blazor Server would make every resize a
   SignalR message — see trap #3 in HANDOFF.md).

       column .rt-md   -> hidden below 900, table-cell from 900 up
       sheet   .rt-o-md -> shown below 900, hidden from 900 up

   Selectors are written as .mud-table-cell.rt-* (0,2,0) so they outrank
   MudBlazor's own .mud-table-cell (0,1,0) regardless of stylesheet order.
   ============================================================================ */

/* ── Column tiers ─────────────────────────────────────────────────────────── */
.mud-table-cell.rt-sm,
.mud-table-cell.rt-md,
.mud-table-cell.rt-lg,
.mud-table-cell.rt-xl { display: none; }

@media (min-width: 600px)  { .mud-table-cell.rt-sm { display: table-cell; } }
@media (min-width: 900px)  { .mud-table-cell.rt-md { display: table-cell; } }
@media (min-width: 1280px) { .mud-table-cell.rt-lg { display: table-cell; } }
@media (min-width: 1920px) { .mud-table-cell.rt-xl { display: table-cell; } }

/* ── Sheet rows — the exact inverse of the above ──────────────────────────── */
/* No base display declaration on purpose: .rt-k and .rt-v are grid items and must
   keep their natural block box. (display:contents here would remove them from the
   grid entirely and the two columns would collapse.) Only the hide half is stated. */
@media (min-width: 600px)  { .rt-o-sm { display: none; } }
@media (min-width: 900px)  { .rt-o-md { display: none; } }
@media (min-width: 1280px) { .rt-o-lg { display: none; } }
@media (min-width: 1920px) { .rt-o-xl { display: none; } }

/* ── Per-column percentage widths must stand down once columns are hidden ──── */
/* app.css sizes these grids with nth-child percentages tuned for the FULL column
   set (.svai-conv-grid nth-child(1)=15%, (2)=20%, … summing to ~100% across 11).
   :nth-child counts DOM POSITION, not visibility, so a hidden column keeps its
   share reserved and the visible ones still ask for only their original slice.
   At 393px that left ~65% of the table unclaimed, and table-layout:fixed handed
   the surplus to whatever had no percentage — the 44px trigger column, which is
   why the details button was rendering about half the table wide.

   Reset to auto below the top tier so the columns that ARE showing divide the
   width between them, and pin the trigger back to its real size. Four classes
   (0,4,0) outranks both .svai-conv-grid .mud-table-cell:nth-child(n) (0,3,0) and
   .svai-stk--conv .mud-table-root th:nth-child(n) (0,3,1) without !important. */
@media (max-width: 1279.98px) {
    .mud-data-grid.rt-tiered .mud-table-cell:nth-child(n) { width: auto; }
    .mud-data-grid.rt-tiered .mud-table-cell.rt-more:nth-child(n) { width: 44px; }
}

/* ── The sheet trigger column ─────────────────────────────────────────────── */
/* Vanishes exactly when the last tiered column returns. The highest tier in use
   on a page decides this, so it is set per page alongside the column classes. */
.mud-table-cell.rt-more { width: 44px; text-align: center; padding: 0 4px !important; }

@media (min-width: 1920px) { .mud-table-cell.rt-more.rt-more-xl { display: none; } }
@media (min-width: 1280px) { .mud-table-cell.rt-more.rt-more-lg { display: none; } }
@media (min-width: 900px)  { .mud-table-cell.rt-more.rt-more-md { display: none; } }
@media (min-width: 600px)  { .mud-table-cell.rt-more.rt-more-sm { display: none; } }

.rt-more-btn {
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    border-radius: 6px;
    width: 28px; height: 28px; padding: 0;
    line-height: 1; cursor: pointer;
    color: var(--mud-palette-text-secondary);
    display: inline-flex; align-items: center; justify-content: center;
}
.rt-more-btn:hover { background: var(--mud-palette-action-default-hover); color: var(--mud-palette-text-primary); }
.rt-more-btn .mud-icon-root { font-size: 18px; }

/* ── The loading stub: fix the layout, don't hide the header ───────────────── */
/* .svai-conv-grid pins `table-layout: fixed !important` so the sort arrow cannot
   widen the active column and shift every header on each sort click. Fixed layout
   takes its widths from the first row and IGNORES content — fine with 11 columns and
   authored percentages, but once tiers hide most of them the remaining auto-width
   columns had nothing to size against while loading and resolved to 0px and 1px.
   Only .rt-more's literal 44px painted: the blue stub in table issue.png.

   An earlier attempt hid the header cells while loading. That removed the stub but
   also removed the header, which is worse — the blue header with its column names is
   exactly what should be on screen while you wait.

   Handing the layout back to `auto` was tried and is WRONG: content then sizes the
   columns, so a full patient name and phone number widened the table past the viewport
   and the horizontal scrollbar came straight back, with the trigger column clipped off
   the right edge. That is the exact problem the tiers exist to remove.

   So `fixed` stays, and the columns are given EXPLICIT widths per tier instead of
   `auto`. Fixed layout then has real numbers at the first paint, with no row to measure
   and no dependence on how a browser distributes `auto` in a fixed table — the header
   renders correctly while loading, and content can never widen the table.

   COST, stated plainly: these nth-child indices are Conversations' column order, so
   this block is page-specific and must be re-derived for each page that adopts tiers.
   Column order here (1-indexed):
     1 Date/Time  2 Patient  3 Direction  4 Outcome  5 Answered By  6 ID Verified
     7 Caller Type  8 Sentiment  9 Language  10 Campaign  11 Duration  12 trigger
   Visible per tier: <600 -> 1,2 | 600-899 -> +3,4 | 900-1279 -> +5,6,11 */



/* ── THE LOADING COLLAPSE IS colspan="1000" ───────────────────────────────────
   MudDataGrid renders its loader as the FIRST row of the tbody, and the no-records
   branch the same way:
       <tr><td colspan="1000" class="mud-table-loading">   <MudProgressLinear/>
       <tr><th colspan="1000" class="mud-table-empty-row"> "No conversations match…"

   A table's column grid is its widest row, so that one cell gives the table 1000
   columns. Fixed layout then does exactly what CSS 2.1 17.5.2.1 rule 3 specifies —
   remaining columns equally divide the remaining space — and 999 phantom columns
   share it with ours:
       .rt-more at 44px  ->  (351 - 44) / 999  = 0.31px  ->  [0, 0, 44]
       .rt-more at auto  ->   351      / 1000  = 0.35px  ->  [0, 0,  0]
   Both are the measured numbers. The table width was NEVER unresolved; it was being
   divided by 1000. That is why only an absolute px width ever survived, and why
   removing that anchor made the collapse worse rather than better.

   Reproduce in one line, no loading state and no build needed:
     document.querySelector('.rt-tiered .mud-table-root').insertAdjacentHTML('beforeend',
       '<tbody><tr><td colspan="1000">x</td></tr></tbody>')
   Measured: [154,154,44] -> [0,0,44] with colspan 1000, and back to [154,154,44] at 3.

   THE FIX: colspan is an HTML presentational hint that only applies to a box whose
   display is table-cell. display:block drops it, the <tr> wraps the cell in an
   anonymous single-column cell, and the table is back to the columns the header row
   declares. The cell then takes its width from the CONTAINER rather than the column
   grid — .mud-table-container is width:100% and the table is width:100% of it, so as
   an inline-size query container 100cqi is the table width.

   This replaces a stack of workarounds that all treated the symptom: table-layout:auto
   below 1280 with lowered padding, a hidden avatar, per-column min-widths, and a
   :has(tr:only-child) switch whose selector was wrong anyway (the loader is the FIRST
   tbody row, so with rows present it is never :only-child). All deleted. */
.mud-data-grid.rt-tiered .mud-table-container {
    container-type: inline-size;
    position: relative;
    z-index: 20;
}

/* .rt-fixed, not .rt-tiered alone. Everything below is a FIXED-LAYOUT fix and it is
   actively harmful under table-layout: auto - the same anonymous-cell mechanic described
   in the group-row note above. Approval Queue is auto, and with this rule ungated its
   loading row stretched column 0 to the container width on every reload: the header
   visibly jumped wide and snapped back each time Apply or Clear was pressed. Conversations
   sets table-layout: fixed in its own <style> block and carries .rt-fixed to say so. */
.mud-data-grid.rt-tiered.rt-fixed .mud-table-body > tr > td.mud-table-loading,
.mud-data-grid.rt-tiered.rt-fixed .mud-table-body > tr > th.mud-table-empty-row {
    display: block;
    box-sizing: border-box;
    width: 100cqi;
    max-width: none;
}

/* GROUP HEADER ROWS are NOT given this treatment, and that is a measured decision.
   Approval Queue is the first grouped grid converted, and applying the rule above to its
   group rows made things worse, not better:

     with the rule      table 2226 wide in a 1440 viewport, column 0 = 1288px
     without it         table 1288, column 0 = 42px
     rule on, group rows deleted from the DOM   table 1288, column 0 = 42px

   The reason is that colspan="1000" only destroys the column grid under
   table-layout: FIXED, which is what Conversations sets. Approval Queue is
   table-layout: auto, where a 1000-colspan cell is harmless - the browser never
   builds 1000 columns for it. display:block then does real damage instead: the row
   wraps the block cell in an ANONYMOUS table-cell, that anonymous cell lands in
   COLUMN 0, and its 100cqi width drags column 0 out to the full container width.

   So the fix belongs to fixed-layout tables only. If a grouped grid is ever given
   table-layout: fixed, add the group-row selector THERE, next to the widths, rather
   than here - and re-measure column 0 both ways before keeping it. */

/* Pin the loader under the header instead of letting it scroll away with the rows.
   Sticky on the ROW, not the cell: the cell is display:block above, so its containing
   block is the anonymous cell the row wraps it in — sticking that would pin it to a box
   a few pixels tall. The row is still a table-row and spans the table.

   This is only safe now. While the loader was part of the column grid, anything that
   kept it in flow reproduced the collapse; display:block on the cell took its colspan
   out of the grid, so the row no longer influences column widths at all and can sit in
   flow harmlessly. The offset is this page's sticky-header offset plus the 37px header
   height, the same pair the header itself pins at. */
/* The loader row pins below the pinned header. This is safe WITHOUT .rt-fixed - it only
   sets position on the ROW, which stays a table-row either way, and touches no cell display,
   so it cannot trigger the anonymous-cell column-0 blowout that made the display:block rules
   fixed-layout-only. Verified on Campaigns (table-layout:auto): injecting a colspan=1000
   loading row left the header widths identical at [211, 96, 44]. */
.mud-data-grid.rt-tiered .mud-table-body > tr:has(> td.mud-table-loading) {
    position: sticky;
    /* --svai-thead-h is the pinned HEADER's own height, defaulting to the single-line 37px
       every other grid renders. It is a variable because a page whose header wraps to two
       lines needs a bigger number: Campaigns measures 53px at >=900, where an eleven-column
       header wraps, and a hard 37 there put the loader 16px UP, overlapping the header it is
       supposed to sit beneath. */
    top: calc(var(--svai-thead-top, 20px) + var(--svai-thead-h, 37px));
    z-index: 21;
}

/* MudDataGrid's OWN loader, exactly as every other grid in this app uses it — Campaigns,
   Approvals, Appointments, Consent and Facilities all just set Loading="@_loading" and
   render nothing extra. Conversations does the same; there is no custom loader here.

   OPEN DEFECT, do not assume this is solved: MudDataGrid appends its loading row to the
   tbody during a reload, and with table-layout:fixed every auto/percentage column then
   resolves to 0 in those frames — only an absolute px width survives. Measured at 393px:
     .rt-more at 44px    -> header widths [0, 0, 44], 38 bad frames of 141
     .rt-more at auto    -> header widths [0, 0,  0], 91 bad frames of 140
   So dropping the px anchor makes it worse, not better. table-layout:auto full-time
   removes the collapse but overflows (table 371 in a 351 container at 393px) because the
   avatar div and the nowrap outcome pills set a min-content floor. */

/* ── Pager on medium and small screens ────────────────────────────────────── */
/* MudDataGridPager's toolbar is: spacer(flex) · "Rows per page:" · select ·
   "1-25 of 178" · four 48px buttons. Measured at 393px that is 594px of content in
   a 325px bar, so it wrapped into three ragged lines with the buttons running past
   the footer edge.
   The spacer exists only to shove the group right, which is wrong once the bar has
   to wrap — so it goes, and everything aligns left. */
@media (max-width: 900px) {
    .mud-data-grid.rt-tiered .mud-table-pagination-spacer { display: none; }

    /* nowrap, not wrap: the bar has to read as ONE line. The budget at 393px is a
       325px bar — select 62 + caption ~78 + four 32px buttons 128 + gaps ~18 = 286,
       so it fits with room to spare, and shrinks further on a 320px screen. */
    .mud-data-grid.rt-tiered .mud-table-pagination-toolbar {
        flex-wrap: nowrap;
        justify-content: flex-start;
        gap: 0 6px;
        padding-left: 10px !important;
        padding-right: 6px !important;
        height: auto !important;
        min-height: 0;
    }

    /* "Rows per page:" is the FIRST caption; "1-25 of 178" is the second and must
       stay — it is the only thing telling you where you are in the set. :first-of-type
       counts p siblings, and the spacer is a div, so this targets exactly the label. */
    .mud-data-grid.rt-tiered .mud-table-pagination-toolbar > p.mud-table-pagination-caption:first-of-type {
        display: none;
    }

    /* The select is 152px wide with desktop margins — far more than "25" needs.
       88px. This has been narrowed twice too far already: at 62 the value clipped to
       "2" and at 76 the three-digit option showed as "10" with the last 0 cut off —
       both worse than a wide box, because a clipped number reads as a real (and wrong)
       page size rather than as a layout fault. 88 fits "100" plus the arrow.
       Budget at 393px: 325 bar = 88 select + 78 caption + 128 buttons + 18 gaps. */
    .mud-data-grid.rt-tiered .mud-table-pagination-select {
        margin: 0 !important;
        width: 88px;
        min-width: 0;
    }
    .mud-data-grid.rt-tiered .mud-table-pagination-toolbar > .mud-select {
        width: 88px;
        min-width: 0;
        flex: 0 0 auto;
    }
    .mud-data-grid.rt-tiered .mud-table-pagination-select .mud-input-slot,
    .mud-data-grid.rt-tiered .mud-table-pagination-select input {
        font-size: 13px;
        padding-right: 0;
        text-overflow: clip;
    }
    /* The dropdown arrow keeps a desktop-sized hit box the 76px box cannot afford. */
    .mud-data-grid.rt-tiered .mud-table-pagination-select .mud-input-adornment { margin: 0; }
    .mud-data-grid.rt-tiered .mud-table-pagination-select .mud-input-adornment .mud-icon-root {
        font-size: 18px;
    }

    /* "1-25 of 178" must not wrap mid-range or it costs a second line. */
    .mud-data-grid.rt-tiered p.mud-table-pagination-caption {
        font-size: 12px;
        white-space: nowrap;
        margin: 0;
    }

    /* Nav buttons: 4 x 48px + ripple padding overran the bar on its own. */
    .mud-data-grid.rt-tiered .mud-table-pagination-actions {
        margin-left: auto;
        flex: 0 0 auto;
        display: flex;
    }
    .mud-data-grid.rt-tiered .mud-table-pagination-actions .mud-icon-button {
        width: 32px; height: 32px; padding: 4px; min-width: 0;
    }
}

/* iPhone SE and similar. Measured at 320px the four buttons ended at 324 — a 4px
   overhang, which is still a horizontal scrollbar. Trim the buttons and the gaps
   rather than dropping first/last-page, which are the two hardest to reach by
   repeated tapping and so the most worth keeping on the smallest screen. */
@media (max-width: 360px) {
    .mud-data-grid.rt-tiered .mud-table-pagination-toolbar {
        gap: 0 4px;
        padding-left: 6px !important;
        padding-right: 2px !important;
    }
    .mud-data-grid.rt-tiered .mud-table-pagination-actions .mud-icon-button {
        width: 28px; height: 28px; padding: 2px;
    }
    .mud-data-grid.rt-tiered p.mud-table-pagination-caption { font-size: 11px; }
}

/* ── Bottom sheet body ────────────────────────────────────────────────────── */
/* The panel itself is a MudDrawer Anchor="Bottom", so open/close, the overlay
   and the transition come from MudBlazor. Only the inside is styled here. */
.rt-sheet .mud-drawer-content { display: flex; flex-direction: column; }

/* Cap the height so a row with many hidden fields cannot fill the screen — and so
   the closed offset below is always enough to clear the viewport. */
.rt-sheet { max-height: 80vh; }

/* THE CLOSED POSITION MUST NOT DEPEND ON MEASURED HEIGHT.
   MudDrawer hides a bottom-anchored drawer with an inline `bottom: -<height>px`,
   measured when the drawer first renders. This sheet renders EMPTY until a row is
   picked (its fields are inside @if (_sheetRow is not null)), so MudBlazor captured
   130px — the height of just the header and button. The first close then applied
   bottom:-129.5px to a sheet that had grown to 399px, leaving 270px of it on screen:
   the "stuck in mid way" first close. The second close worked only because by then
   MudBlazor had re-measured.

   A percentage resolves against the viewport for a fixed-position element, so -100%
   clears the screen whatever the content measures. !important is required and is not
   laziness: MudBlazor writes `bottom` as an INLINE style, which a stylesheet cannot
   otherwise outrank. Same reasoning as the .mud-drawer-pos-right width override in
   app.css. */
.rt-sheet.mud-drawer--closed { bottom: -100% !important; }

.rt-sheet-head {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 14px 16px 10px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}
.rt-sheet-head h2 {
    margin: 0; font-size: 15px; font-weight: 600;
    color: var(--mud-palette-text-primary);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rt-sheet-sub { font-size: 12.5px; color: var(--mud-palette-text-secondary); margin-top: 2px; }
.rt-sheet-x { margin-left: auto; flex: 0 0 auto; }

/* Scrolls independently: a 3-field sheet and an 11-field sheet both behave. */
.rt-sheet-body { padding: 12px 16px 16px; overflow-y: auto; }

/* Label column FIRST and floored; value column takes the rest and wraps.
   It used to be `minmax(0, 1fr) auto`: the value column sized to its content and the
   label column, free to shrink to 0, collapsed underneath it. Conversations never showed
   it because its values are short words - Approval Queue has "Unspecified blepharitis
   left upper eyelid" and a full rationale sentence, and there the label vanished behind
   the value. The value keeps overflow-wrap:anywhere so a long unbroken code still wraps
   inside its own column instead of pushing the label out. */
.rt-sheet-grid {
    display: grid; grid-template-columns: minmax(96px, 34%) minmax(0, 1fr);
    gap: 9px 14px; align-items: baseline;
}
.rt-k { font-size: 11px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase;
        color: var(--mud-palette-text-secondary); }
.rt-v { text-align: right; overflow-wrap: anywhere; color: var(--mud-palette-text-primary); }

/* The sheet never replaces the row-click drawer — it offers it. */
.rt-sheet-open { margin-top: 14px; width: 100%; }

/* NOTE: there is deliberately no :empty fallback for "every column is visible".
   :empty would never match — the sheet rows are always PRESENT in the DOM and only
   hidden by media query, so the grid has children at every width. The trigger button
   is display:none once the last tier is satisfied, so the sheet cannot be opened at
   a width where it would have nothing to show. */
