/* ==========================================================================
   THE TABLE STANDARD -- decision 3A, Scott 09/28/2026 (pick A), for the whole
   site. Served LAST, after fields.css, so source order settles every tie.

   The Cowork audit that day measured 65 table looks on 30 pages: the header
   row in NINE looks (11px/700 CAPS in the house's colour on the dashboards;
   11px/600 CAPS elsewhere; 14px sentence case on the profile; 13px white on
   teal on Staffing Stats; 13px CAPS on Call-Offs; 12.5px on Meetings), numbers
   right-aligned in ONE table of 65, banding on 21 and absent on 26.

   ONE header row, ONE stripe, numbers to the right. Row heights are Scott's
   own and are not touched here (09/25/2026: "not this round's business").
   ⛔ A rule that colours a table header by its section or its house is a
   page-local look and belongs nowhere; the ones that did were deleted the day
   this file was written. tools/design_check.py rules TB-HEAD, TB-NUM,
   TB-BAND and TB-FIT measure every page for what this file says.
   ========================================================================== */

/* ---- the header row: 11px caps, weight 700, --text-subtle, a quiet ground */
/* ⛔ `!important`, DELIBERATELY, like spacing.css: the Cowork audit counted
   nine header looks written by nine pages at up to four classes of
   specificity each, and one standard rule has to win over all of them without
   anybody hunting the next one down. */
body.ds-c main table thead th {
  font-size: 11px !important; line-height: 16px; font-weight: 700 !important; letter-spacing: .06em;
  text-transform: uppercase !important; color: var(--text-subtle) !important;
  background: var(--surface-2) !important; opacity: 1 !important;
  vertical-align: middle;
  border-bottom: 1px solid var(--border-1);
}

/* ---- a "move-in – move-out" pair stays on one line (the archive tables;
   Scott, 09/29/2026: "all the dates need to be on one line, not wrap"). */
.ds-dates { white-space: nowrap; }

/* ---- numbers to the right, in figures that line up.
   layout() marks every cell that holds a bare number, amount or percentage
   with `num` (applib/screening.py, mark_numeric_cells), so the page's own
   markup does not have to know. */
body.ds-c main table:not(.kv) td.num, body.ds-c main table:not(.kv) th.num {
  text-align: right !important; font-variant-numeric: tabular-nums;
}

/* ---- a count and its percentage are ONE unit: "10 (100%)" on one line, the
   pieces side by side at the cell's right edge, under the header that is
   right-aligned over them (`th.num` above). Scott's screenshot, 09/29/2026,
   8:44 PM Central: the census table's "1" and "(10%)" sat 38px apart with an
   invisible correcting pencil between them. A pencil (ro_field) goes on the
   LEFT of the number, so the figure and its percentage stay together whether
   or not the pencil is showing. tools/design_rules/tables.py rules TB-ALIGN
   and TB-WIDTH measure it. */
body.ds-c main table .ds-fig {
  display: inline-flex; align-items: center; justify-content: flex-end; gap: 4px;
  white-space: nowrap; vertical-align: middle;
}
body.ds-c main table .ds-fig .ro-pencil { order: -1; }
/* ...and the same for a lone pencil figure (ro_field) in a number column. Its pencil drew AFTER
   the figure -- invisible until pointed at, but still 28px wide -- so a pencil row's numbers
   stood 34px left of a plain row's (Scott, 10/03/2026, Projections: "pieces of data are not
   aligned"). On the left, every figure in the column shares the header's right edge. */
body.ds-c main table td.num .ro-cell .ro-pencil { order: -1; }

/* ---- banded rows on every list (a table with a header row).
   The stripe is --row-stripe, MEASURED 3.4 from white on 09/18/2026 (Scott:
   between the 1.3 he could not see and the 4.5 he found too loud). A pair of
   rows that belong together -- a row and its edit row (rates, contacts) --
   stripe by the pair, and keep their own rule. */
body.ds-c main table:has(> thead):not(.rates-table):not(.contacts-table):not(:has(> tbody > tr.edit-row)) > tbody > tr:nth-child(even) > :is(td, th) {
  background: var(--row-stripe);
}
/* a table whose every row carries a hidden edit row under it (the Playbook's
   registers) stripes by the PAIR, so the visible rows still alternate */
body.ds-c main table:has(> thead):has(> tbody > tr.edit-row) > tbody > tr:nth-child(4n+3) > :is(td, th),
body.ds-c main table:has(> thead):has(> tbody > tr.edit-row) > tbody > tr:nth-child(4n+4) > :is(td, th) {
  background: var(--row-stripe);
}
/* a table that keeps each row in its own row group with its edit tray (row-edit.js:
   Staff Accounts, Interviewees) stripes by the GROUP; a row being edited keeps its gold */
body.ds-c main table:has(> thead):has(> tbody > tr.re-row) > tbody:nth-of-type(even) > tr.re-row:not(.re-editing) > :is(td, th) {
  background: var(--row-stripe);
}

/* ---- a pointed-at row lights up in its SECTION's color (Scott, 09/18/2026), striped or not.
   25% of the kind's or the house's tone, so link and muted words keep 4.5:1 on every kind;
   outside a section, the site's teal. Not an empty room, an empty state or a row being edited.
   ONLY WHERE THERE IS A POINTER (Scott, 10/04/2026, of the Current Waitlist on a phone: a tile
   "turns green after you touch it"). A phone keeps :hover on the last thing touched, so a tapped
   card stayed lit; on a touch screen no row lights up. */
@media (hover: hover) {
body.ds-c main table:is(.data-table, .ds-table):not(.rates-table):not(.contacts-table) > tbody > tr:not(.vacant-row, .empty-row, .edit-row, .re-editing, .re-tray):hover > :is(td, th) {
  background: color-mix(in srgb, var(--ds-tone, var(--teal-500)) 25%, var(--surface));
}
}

/* ==========================================================================
   THE TYPED TABLE (c_ds_typed_table, D1 + D9, 09/30/2026): the column's type
   sets the side (num right via the rules above), the actions, the totals row,
   the sort arrows and the one "show more".
   ========================================================================== */
body.ds-c main table th.ds-actions, body.ds-c main table td.ds-actions {
  text-align: right; white-space: nowrap; width: 1%;
}
body.ds-c main table .ds-row-actions { display: inline-flex; align-items: center; gap: 4px; justify-content: flex-end; }
/* Rows that open an edit tray (row_edit=): each row has its hidden tray under it, so the visible
   rows stripe by the pair; the open row and its tray wear the edit gold instead. */
body.ds-c main table.ds-typed:has(> thead):has(> tbody > tr.re-tray) > tbody > tr.re-row:nth-child(4n+3) > td { background: var(--row-stripe); }
body.ds-c main table.ds-typed:has(> thead):has(> tbody > tr.re-tray) > tbody > tr.re-row.re-editing:nth-child(odd) > td,
body.ds-c main table.ds-typed:has(> thead):has(> tbody > tr.re-tray) > tbody > tr.re-tray:nth-child(even) > td { background: var(--gold-50); }
/* ...its small pencil (28px) fits a 35px row, and a number's box is as wide as its number. */
body.ds-c main table.ds-typed td.ds-actions { padding-top: 3px; padding-bottom: 3px; }
body.ds-c main table.ds-typed tr.re-row td.num .re-in { width: 58px; text-align: right; }
/* ...and an OPEN row's choice and words have room to be read: a narrow column showed "Not…" and a list
   popping out of a box too small to say what was chosen (Scott, 10/23/2026, Payroll & Staffing's agency shifts). */
body.ds-c main table.ds-typed tr.re-row.re-editing td:not(.num) select.re-in { min-width: 10.5rem; }
body.ds-c main table.ds-typed tr.re-row.re-editing td:not(.num) input.re-in { min-width: 7.5rem; }
/* TAP TO EDIT (tap_to_edit=True), for a table that stays a table on a phone: no pencil column
   there; the value is tapped to open its row (Scott, 09/18/2026, of Census Tracking: "we
   don't need a pencil icon next to every single number ... it clutters up the screen on mobile"). */
@media (max-width: 760px) {
  body.ds-c main table.ds-typed.ds-tap-edit:not(:has(tr.re-editing)) th.ds-actions,
  body.ds-c main table.ds-typed.ds-tap-edit tr:not(.re-editing) > td.ds-actions { width: 0; padding: 0; }
  body.ds-c main table.ds-typed.ds-tap-edit tr:not(.re-editing) .ds-row-actions { display: none; }
  body.ds-c main table.ds-typed.ds-tap-edit tr.re-row:not(.re-editing) .re-ro {
    text-decoration: underline dotted var(--text-subtle); text-underline-offset: 3px; cursor: pointer;
    padding: 4px 2px;
  }
  /* ...and the OPEN row shows its check at its right end: it is what saves the row (10/03/2026). */
  /* While a row is open its column is given the check's room (the census table's columns are
     fixed, so a column with no width of its own came out 3px and the check hung outside the
     frame -- MEASURED at 390px), and the check is pinned to the frame's right edge on the row's
     own gold, so it is in reach without scrolling the table. */
  body.ds-c main table.ds-typed.ds-tap-edit:has(tr.re-editing) th.ds-actions { width: 36px; padding: 0; }
  body.ds-c main table.ds-typed.ds-tap-edit tr.re-row.re-editing > td.ds-actions {
    padding: 2px 4px; position: sticky; right: 0; background: var(--gold-50); }
  body.ds-c main table.ds-typed.ds-tap-edit tr.re-tray > td { display: table-cell; width: auto; padding: 0; }
  body.ds-c main table.ds-typed.ds-tap-edit tr.re-row td.num .re-in { width: 44px; padding: 0 4px; }
}
/* ON A PHONE a row-edit table's row is a CARD (Staff Accounts, Interviewees): its lines keep the card's own
   tight spacing, with no rule between them and no stripe inside the card (Scott, 10/01/2026: "too much space
   between each field in the tiles"). The 12px a computer's table cell wears was reaching the card.
   Not a typed table (Census Tracking), which stays a table on a phone. */
@media (max-width: 760px) {
  body.ds-c main table.data-table:not(.ds-typed):has(> thead) > tbody > tr.re-row > td { padding-top: 4px; padding-bottom: 4px; border-bottom: 0; }
  body.ds-c main table.data-table:not(.ds-typed):has(> thead):has(> tbody > tr.re-row) > tbody:nth-of-type(even) > tr.re-row:not(.re-editing) > :is(td, th) { background: transparent; }
  /* A typed table whose rows open in place (Licenses, Business Reminders) is cards on a phone too.
     MEASURED at 390px, 10/03/2026: the computer's `width: 1%` on the actions cell left its buttons
     a 0px box, so all but the last hung off the card's left edge; and the pair-stripe painted the
     inside of every other card gray (TB-BAND: a phone's cards are not banded). */
  body.ds-c main table.data-table.ds-typed:not(.ds-tap-edit) td.ds-actions { width: auto; }
  body.ds-c main table.ds-typed:not(.ds-tap-edit):has(> thead):has(> tbody > tr.re-tray) > tbody > tr.re-row:not(.re-editing) > td { background: transparent; }
}
body.ds-c main table td.num.ds-neg { color: var(--danger); font-weight: 700; }
body.ds-c main table > tfoot > tr.ds-total-row > td {
  font-weight: 700; border-top: 2px solid var(--border-2); background: var(--surface-2);
}
body.ds-c main table thead th a.ds-sort {
  color: inherit; font-weight: inherit; text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
}
body.ds-c main table thead th a.ds-sort:hover { color: var(--text); }
body.ds-c main table thead th.num a.ds-sort { flex-direction: row-reverse; }
.ds-sort-arrow { font-size: 11px; opacity: .45; }
.ds-sort.on .ds-sort-arrow { opacity: 1; }

/* ---- the one "show more" (c_ds_fold). Checkbox and label, no script. The
   rows' own rule is 0-3-2 so a page's phone `tr { display: table-row }`
   (0-2-2) cannot unfold it. */
.ds-more-check { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
/* the fold's pieces keep a card's inside gap, as they did as the card's own children */
main.container .ds-fold > * + * { margin-top: var(--inside-gap); }
body.ds-c .ds-fold tr.ds-more-row, body.ds-c .ds-fold .ds-more-row { display: none; }
body.ds-c .ds-fold > .ds-more-check:checked ~ .ds-table-wrap tr.ds-more-row { display: table-row; }
body.ds-c .ds-fold > .ds-more-check:checked ~ * .ds-more-row:not(tr),
body.ds-c .ds-fold > .ds-more-check:checked ~ .ds-more-row:not(tr) { display: block; }
.ds-more-btn {
  display: inline-block; cursor: pointer;
  padding: 0.4rem 0.9rem;
  font-size: var(--fs-sm); font-weight: 700; color: var(--navy);
  background: var(--wash-mint-row); border: 1px solid var(--border); border-radius: var(--r-sm);
}
.ds-more-btn:hover { background: var(--wash-teal-3); }
.ds-more-btn::before { content: "\25B8  "; }
.ds-more-check:checked ~ .ds-more-btn::before { content: "\25BE  "; }
.ds-more-check:focus-visible ~ .ds-more-btn { outline: 2px solid var(--navy); outline-offset: 2px; }
.ds-more-hide { display: none; }
.ds-more-check:checked ~ .ds-more-btn .ds-more-show { display: none; }
.ds-more-check:checked ~ .ds-more-btn .ds-more-hide { display: inline; }
/* a "change" column: up and green when better, down and red when worse */
body.ds-c main table td.num.ds-up { color: var(--ok); font-weight: 700; }
body.ds-c main table td.num.ds-down { color: var(--danger); font-weight: 700; }

/* THE SHEET OF SMALL PICTURES -- c_ds_thumbs() (D7): each page's computer and phone pictures, its name under them. */
.ds-thumbs { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px 12px;
  grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); }
.ds-thumb { margin: 0; min-width: 0; }
.ds-thumb-pics { display: flex; gap: 6px; align-items: flex-start; }
.ds-thumb-pic { display: block; line-height: 0; border: 1px solid var(--border); border-radius: var(--r-xs);
  overflow: hidden; background: var(--surface); flex: none; }
.ds-thumb-pic img { display: block; height: 92px; width: auto; }
.ds-thumb-name { font-size: var(--fs-sm); line-height: var(--lh-sm); margin: 6px 0 0; overflow-wrap: anywhere; }
@media (max-width: 760px) {
  .ds-thumbs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ds-thumb-pic img { height: 70px; }
}
/* The large sheet (Staff Badges' preview, 10/20/2026): pictures big enough to read, each as tall as
   400px allows and never wider than the section -- they wrap to the next row instead. DP-114 */
.ds-thumbs-lg { display: flex; flex-wrap: wrap; gap: 16px 24px; }
.ds-thumbs-lg .ds-thumb { max-width: 100%; }
.ds-thumbs-lg .ds-thumb-pic { flex: 0 1 auto; max-width: 100%; }
.ds-thumbs-lg .ds-thumb-pic img { width: auto; height: auto; max-width: 100%; max-height: 400px; }
@media (max-width: 760px) {
  .ds-thumbs-lg { gap: 16px 12px; }
  .ds-thumbs-lg .ds-thumb { flex: 1 1 calc(50% - 6px); min-width: 0; }
}


/* A ROW'S OWN SMALL FORM -- Approved / Needs edits on the Project Tracker (T3): buttons in a row, the note box opens under them. */
.ds-row-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; justify-content: flex-end; margin: 0; }
.ds-row-form details > summary { list-style: none; cursor: pointer; }
.ds-row-form details > summary::-webkit-details-marker { display: none; }
.ds-row-form details[open] { flex-basis: 100%; display: grid; gap: 8px; }

/* A GRID OF DAYS THAT STAYS A TABLE ON A PHONE (10/03/2026, the ADLs tab's Last 14
   Days): a row of fourteen days read across is the point, so it keeps its table and
   scrolls sideways inside its own frame -- as the census grid does -- instead of
   becoming one card per row. c_ds_typed_table(..., look="data", wrap_cls="ds-grid-wrap"). */
.ds-grid-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
@media (max-width: 760px) {
  .ds-grid-wrap table.data-table { display: table; width: auto; min-width: 100%; }
  .ds-grid-wrap table.data-table thead { display: table-header-group; }
  .ds-grid-wrap table.data-table tbody { display: table-row-group; }
  .ds-grid-wrap table.data-table tr { display: table-row; border: none; border-radius: 0; box-shadow: none;
                                      margin: 0; padding: 0; }
  .ds-grid-wrap table.data-table td, .ds-grid-wrap table.data-table th { display: table-cell; padding: 6px 8px;
                                                                          white-space: nowrap !important; }
  .ds-grid-wrap table.data-table td[data-label]::before { content: none; }
}
/* ...its first column (what the row is) stays in view while the days scroll under it */
.ds-grid-wrap table.data-table > * > tr > :first-child { position: sticky; left: 0; z-index: 1; background: var(--surface); }

/* BOXES THAT SAVE THEMSELVES, ALWAYS OPEN, IN A TABLE (page_spec.py's "live" cell; Resident Cheat
   Sheets, Scott 10/16/2026: every field free text, "Save automatically like the other pages do").
   Each box is its own little form; live-edit.js sends it when the box is left. A wide sheet scrolls
   sideways inside its own section rather than squeezing ten columns of boxes. */
table.ds-table:has(.ps-live) { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.ds-table:has(.ps-live) td { padding: 4px 4px; vertical-align: middle; }
table.ds-table:has(.ps-live) td:first-child { text-align: center; width: 48px; }
.ps-live { min-width: 140px; }
.ps-live form { margin: 0; }
.ps-live-in { width: 100%; min-width: 0; }
.ps-live-alert { color: var(--danger); font-weight: 800; }
.ps-live-strong { font-weight: 800; }
table.ds-table:has(.ps-live) td:nth-child(2) .ps-live { min-width: 0; width: 52px; }
table.ds-table:has(.ps-live) td:nth-child(3) .ps-live { min-width: 200px; }
table.ds-table:has(.ps-live) td:last-child .ps-live { min-width: 260px; }

/* A box of checks (c_ds_check_groups; Payroll & Staffing's Checks, Scott 10/26/2026): a slim bar, then groups,
   each a header line (icon, title, "X of Y correct") over its Not right rows. DESIGN-PENDING: DP-120 */
body.ds-c .ds-checkbar { margin: 0 0 var(--sp-3, 12px); padding: 8px 12px; }
body.ds-c .ds-checkbar-why { font-weight: 400; }
body.ds-c .ds-checkgroup + .ds-checkgroup { margin-top: var(--sp-4, 16px); }
body.ds-c .ds-checkgroup-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 6px; }
body.ds-c .ds-checkgroup-head .ico { width: 18px; height: 18px; color: var(--text-muted); }
body.ds-c .ds-checkgroup-title { font-weight: 700; }

/* Normal against actual as a plain list (c_ds_gap_card; Payroll & Staffing's Clean baseline, Scott 10/26/2026).
   DESIGN-PENDING: DP-121 */
body.ds-c .ds-gap-card p { margin: 0; }
body.ds-c .ds-gap-when { color: var(--text-muted); font-size: 13px; }
body.ds-c .ds-gap-pair { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 6px !important; }
body.ds-c .ds-gap-big { font-size: 26px; font-weight: 700; margin-top: 4px !important; }
body.ds-c .ds-gap-success, body.ds-c .ds-gap-down { color: var(--ok); }
body.ds-c .ds-gap-danger, body.ds-c .ds-gap-up { color: var(--danger); }
body.ds-c .ds-gap-why-title { margin: 14px 0 6px; font-size: 14px; }
body.ds-c .ds-gap-list { list-style: none; margin: 0; padding: 0; }
body.ds-c .ds-gap-why { display: flex; gap: 12px; padding: 4px 0; border-top: 1px solid var(--border); }
body.ds-c .ds-gap-why-amt { min-width: 110px; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
body.ds-c .ds-gap-why-words { color: var(--text); }
