/* Screen Ferry — shared controls stylesheet.
   Owns every pixel of controls/dialog.js, controls/datatable.js and
   controls/select.js. The controls' JS carries no colour and emits no
   inline style attribute (CSP is style-src 'self'); it sets geometry through
   el.style.* only, exactly as the ember originals did.

   ┌───────────────────────────────────────────────────────────────────────────┐
   │ RULES THIS FILE FOLLOWS (same contract as module CSS, see style.css)      │
   │  1. Every colour is a var(--token) from style.css. No hex literal, no     │
   │     colour function and no named colour appears below.                    │
   │  2. Nothing is added to :root. Component-scoped custom properties         │
   │     (--dt-height, --sf-dlg-w/h) are declared on the component, never on   │
   │     :root, and always carry a fallback.                                   │
   │  3. Every selector is scoped: .sf-dialog, .sf-datatable, .sf-select.      │
   │     No bare element selectors — this sheet is loaded alongside module CSS │
   │     and is never unloaded.                                                │
   │     The one structure that is not a DESCENDANT of its root is the select  │
   │     popup: it is portaled to <body> so an overflow/transform ancestor     │
   │     cannot clip it. Every one of its selectors still begins .sf-select__. │
   │  4. Motion is --dur-* / --ease. prefers-reduced-motion is handled         │
   │     globally in style.css and is not re-implemented here.                 │
   │  5. There is no success / error / warning colour on this site. Weight,    │
   │     size, wording and an inverted fill carry destructive intent (G1).     │
   └───────────────────────────────────────────────────────────────────────────┘

   Stacking, since style.css has no z-index scale (reported as a gap):
     40/45 nav scrim + panel · 50 site header · 80 toasts · 90 skip link
     100 dialog · 110 select popup (must beat a dialog it is used inside)
     the datatable filter popup is 20, inside the table's own positioned wrap.
*/

/* ═══════════════════════════════════════════════════════════════════════════
   DIALOG — <sf-dialog>. The host element IS the scrim.
   ═══════════════════════════════════════════════════════════════════════════ */
.sf-dialog {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  background: var(--scrim);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.sf-dialog__modal {
  width: min(26rem, 100%);
  max-height: calc(100vh - var(--sp-8));
  overflow: auto;
  background: var(--surface);
  color: var(--ink);
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  padding: var(--sp-5);
  animation: sf-dialog-pop var(--dur-1) var(--ease);
}
.sf-dialog__title {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-h3);
  font-weight: 640;
  line-height: 1.3;
  letter-spacing: var(--tr-head);
  color: var(--ink);
}
.sf-dialog__msg {
  margin: 0 0 var(--sp-5);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  overflow-wrap: break-word;
}
.sf-dialog__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-3);
}
.sf-dialog__btn {
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -.005em;
  padding: .5rem 1.125rem;
  min-height: 2.25rem;
  border: var(--hairline) solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease);
}
.sf-dialog__btn--ghost {
  background: var(--surface);
  border-color: var(--line-strong);
  color: var(--ink);
}
.sf-dialog__btn--ghost:hover {
  background: var(--surface-2);
  border-color: var(--ink-2);
}
.sf-dialog__btn--primary {
  background: var(--accent);
  color: var(--on-accent);
}
.sf-dialog__btn--primary:hover { background: var(--accent-hover); }
/* Destructive. No red exists on this site, so the weight goes up a step and the
   fill inverts to ink-on-background — the same device .badge--strong uses. It is
   the heaviest thing on the dialog in both themes, which is the point. */
.sf-dialog__btn--danger {
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
  letter-spacing: .002em;
}
.sf-dialog__btn--danger:hover {
  background: var(--ink-2);
  color: var(--bg);
}
.sf-dialog__btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Panel mode — a modal shell hosting arbitrary content. */
.sf-dialog__modal--panel {
  width: var(--sf-dlg-w, 54rem);
  height: var(--sf-dlg-h, 36rem);
  max-width: 100%;
  max-height: calc(100vh - var(--sp-6));
  padding: 0;
  overflow: hidden;
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
}
.sf-dialog__modal--panel:focus { outline: none; }
.sf-dialog__modal--panel > * {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

@keyframes sf-dialog-pop {
  from { transform: translateY(8px) scale(.98); }
  to   { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SELECT — <sf-select> trigger, plus the popup portaled to <body>.
   ═══════════════════════════════════════════════════════════════════════════ */
.sf-select { display: block; min-width: 0; }
.sf-select__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 2.25rem;
  padding: .4375rem .625rem;
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.sf-select__trigger:hover { border-color: var(--ink-2); }
.sf-select__trigger:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-halo);
}
.sf-select[disabled] .sf-select__trigger {
  opacity: .55;
  cursor: default;
}
.sf-select__label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sf-select__label--placeholder { color: var(--ink-ui); }
/* currentColor, so the chevron follows the theme with no second asset and no
   colour literal — the ember original shipped two hard-coded data: URIs. */
.sf-select__chev {
  width: .75rem;
  height: .75rem;
  flex: none;
  color: var(--ink-ui);
  transition: transform var(--dur-1) var(--ease);
}
.sf-select__trigger[aria-expanded="true"] .sf-select__chev { transform: rotate(180deg); }

/* Borderless in-card variant: value right-aligned and muted; [stacked] makes it
   read like a text field instead. */
.sf-select[flat] .sf-select__trigger {
  border: 0;
  background-color: transparent;
  min-height: 0;
  padding: 0;
}
.sf-select[flat] .sf-select__trigger:focus-visible {
  box-shadow: none;
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.sf-select[flat] .sf-select__label {
  text-align: right;
  color: var(--ink-2);
}
.sf-select[flat][stacked] .sf-select__label {
  text-align: left;
  color: var(--ink);
}
.sf-select[flat] .sf-select__label--placeholder { color: var(--ink-ui); }

.sf-select__pop {
  position: fixed;
  z-index: 110;
  box-sizing: border-box;
  padding: var(--sp-1);
  background: var(--surface);
  color: var(--ink);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-2);
  overflow-y: auto;
  overscroll-behavior: contain;
  font-family: var(--font);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
}
.sf-select__opt {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.3;
  color: var(--ink);
}
.sf-select__opt:hover,
.sf-select__opt--active { background: var(--surface-2); }
.sf-select__opt--selected {
  font-weight: 640;
  background: var(--accent-quiet);
}
.sf-select__opt--selected.sf-select__opt--active { background: var(--accent-quiet); }
.sf-select__opt--selected::after {
  content: "\2713";
  margin-left: auto;
  padding-left: var(--sp-2);
  color: var(--accent);
}
.sf-select__empty {
  padding: var(--sp-2) var(--sp-3);
  color: var(--ink-ui);
  cursor: default;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DATATABLE — <sf-datatable>.
   Fills its box: full width of the parent, and by default the viewport height
   minus a frame. Override with --dt-height (e.g. --dt-height:auto plus flex:1
   to fill a flex parent). Flex column: toolbar and footer are fixed, the scroll
   area flexes.
   ═══════════════════════════════════════════════════════════════════════════ */
.sf-datatable {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  min-width: 0;
  /* No margin of its own. A control that insets itself fights every layout it
     is dropped into; the host page decides where it sits. Height still comes
     from --dt-height so a host can hand it one. */
  margin: 0;
  height: var(--dt-height, auto);
  /* The table stacks on ITS OWN width, not the window's. On an iPad the
     dashboard's 15rem side rail leaves the table far less room than the
     viewport suggests, so a viewport media query gets this wrong in exactly the
     case that matters. A container query asks the only question that decides
     it: is there room for the grid, here? */
  container-type: inline-size;
  container-name: sf-datatable;
  font-family: var(--font);
  font-size: var(--fs-xs);
  color: var(--ink);
}
.sf-datatable__wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

/* ── toolbar ──────────────────────────────────────────────────────────────── */
.sf-datatable__toolbar {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border-bottom: var(--hairline) solid var(--line);
}
.sf-datatable__search {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 1 1 12rem;
  min-width: 0;
  max-width: 20rem;
  height: 2.25rem;
  padding: 0 var(--sp-3);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-ui);
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.sf-datatable__search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus-halo);
  color: var(--ink-2);
}
.sf-datatable__search svg { width: .9375rem; height: .9375rem; flex: none; }
.sf-datatable__search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
}
.sf-datatable__search-input::placeholder { color: var(--ink-ui); }
.sf-datatable__actions {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}
.sf-datatable__act {
  width: 2.125rem;
  height: 2.125rem;
  flex: none;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              background var(--dur-1) var(--ease);
}
.sf-datatable__act svg { width: 1rem; height: 1rem; }
.sf-datatable__act:hover {
  color: var(--ink);
  border-color: var(--ink-2);
  background: var(--surface-2);
}
.sf-datatable__act:active { transform: translateY(.5px); }
/* Destructive toolbar action. No red: the fill inverts on hover, which is the
   loudest state available in a one-hue system. */
.sf-datatable__act--danger:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}
.sf-datatable__refresh--spinning {
  color: var(--accent);
  pointer-events: none;
}
.sf-datatable__refresh--spinning svg {
  transform-origin: 50% 50%;
  animation: sf-dt-spin .7s linear infinite;
}
@keyframes sf-dt-spin { to { transform: rotate(360deg); } }

/* ── scroll region + table ────────────────────────────────────────────────── */
.sf-datatable__scroll {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  overflow: auto;          /* the TABLE scrolls sideways, never the page (G6) */
  outline: none;
}
.sf-datatable__scroll:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}
.sf-datatable__table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.sf-datatable__table th {
  position: sticky;
  top: 0;
  z-index: 2;
  height: 2.5rem;
  padding: 0 var(--sp-3);
  background: var(--surface-2);
  border-bottom: var(--hairline) solid var(--line);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--ink-2);
  user-select: none;
}
.sf-datatable__th { position: relative; }
.sf-datatable__th-label {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  vertical-align: middle;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  text-align: inherit;
}
.sf-datatable__th-label--sortable { cursor: pointer; }
.sf-datatable__th-label--sortable:hover { color: var(--ink); }
.sf-datatable__th-label:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.sf-datatable__th-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sf-datatable__sort {
  display: inline-flex;
  flex: none;
  color: var(--ink);
}
.sf-datatable__sort svg { width: .75rem; height: .75rem; }
.sf-datatable__th-filter {
  position: absolute;
  right: var(--sp-4);
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  padding: var(--sp-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--ink-ui);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.sf-datatable__th-filter svg { width: .8125rem; height: .8125rem; }
.sf-datatable__table th:hover .sf-datatable__th-filter,
.sf-datatable__th-filter:focus-visible { opacity: 1; }
.sf-datatable__th-filter:hover { background: var(--surface); color: var(--ink); }
.sf-datatable__th-filter--on { opacity: 1; color: var(--ink); }
.sf-datatable__grip {
  position: absolute;
  right: 0;
  top: 0;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  touch-action: none;
}
.sf-datatable__grip:hover { box-shadow: inset -2px 0 0 var(--line-strong); }

.sf-datatable__table td {
  height: 2.5rem;
  padding: 0 var(--sp-3);
  border-bottom: var(--hairline) solid var(--line);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ink);
}
.sf-datatable__table tbody tr { cursor: pointer; }
.sf-datatable__table tbody tr:hover { background: var(--surface-2); }
.sf-datatable__row--sel {
  background: var(--accent-quiet);
  box-shadow: inset 2px 0 0 var(--accent);
}
.sf-datatable__empty td {
  height: 4rem;
  text-align: center;
  color: var(--ink-ui);
  cursor: default;
}
.sf-datatable__table tbody tr.sf-datatable__empty:hover { background: transparent; }

/* per-column alignment, a class because the CSP forbids an inline style attr */
.sf-datatable__c--left   { text-align: left; }
.sf-datatable__c--right  { text-align: right; }
.sf-datatable__c--center { text-align: center; }

/* sticky-right column (row actions): stays pinned during horizontal scroll */
.sf-datatable__sticky-r {
  position: sticky;
  right: 0;
  z-index: 1;
  background: var(--surface);
  border-left: var(--hairline) solid var(--line);
}
.sf-datatable__table tbody tr:hover .sf-datatable__sticky-r { background: var(--surface-2); }
.sf-datatable__table tbody tr.sf-datatable__row--sel .sf-datatable__sticky-r { background: var(--accent-quiet); }
.sf-datatable__table thead th.sf-datatable__sticky-r { z-index: 3; background: var(--surface-2); }

/* ── in-cell controls ─────────────────────────────────────────────────────── */
.sf-datatable__btn {
  font: inherit;
  font-weight: 550;
  padding: .25rem var(--sp-3);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.sf-datatable__btn:hover { background: var(--surface-2); border-color: var(--ink-2); }
.sf-datatable__btn--ghost {
  border-color: transparent;
  background: transparent;
  color: var(--ink-2);
}
.sf-datatable__btn--ghost:hover { background: var(--surface-2); color: var(--ink); }
.sf-datatable__sel {
  font: inherit;
  padding: .1875rem var(--sp-2);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}
/* Icon-only actions centre in their column — there is no label for them to
   align with, so left-aligning them just leaves a gap on the right. */
.sf-datatable__actcell { white-space: nowrap; text-align: center; }
.sf-datatable__actcell .sf-datatable__rowact { margin-inline: 2px; }
.sf-datatable__rowact {
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  flex: none;
  vertical-align: middle;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: var(--hairline) solid transparent;
  /* Circular: a row action is a target, not a control with a label. */
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              background var(--dur-1) var(--ease);
}
.sf-datatable__rowact svg { width: 1.0625rem; height: 1.0625rem; }
/* Circular tint on hover. The default is the accent; a destructive action is
   red, which is the second departure from the single hue and, like the toast's,
   is meaning rather than decoration — it is the one action in a row that cannot
   be undone. Both reuse the tokens already in the block; nothing new here. */
.sf-datatable__rowact:hover {
  color: var(--accent);
  border-color: transparent;
  background: var(--accent-quiet);
}
.sf-datatable__rowact--danger:hover {
  /* A tint, not a slab. The point is "this one is different and cannot be
     undone", which a soft wash carries as well as a solid fill and without
     shouting at someone who is only passing the pointer over it. */
  color: var(--status-error-bg);
  border-color: transparent;
  background: var(--status-error-quiet);
}
.sf-datatable__rowact:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.sf-datatable__rowact:disabled { opacity: .32; cursor: not-allowed; }
.sf-datatable__rowact:disabled:hover {
  color: var(--ink-2);
  border-color: transparent;
  background: transparent;
}

/* Switch, for control:"checkbox" cells only. */
.sf-datatable__cell input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  box-sizing: border-box;
  flex: 0 0 auto;
  vertical-align: middle;
  width: 2.25rem;
  height: 1.25rem;
  margin: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease);
}
.sf-datatable__cell input[type="checkbox"]::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--on-accent);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-2) var(--ease);
}
.sf-datatable__cell input[type="checkbox"]:checked { background: var(--accent); }
.sf-datatable__cell input[type="checkbox"]:checked::before { transform: translateX(1rem); }
.sf-datatable__cell input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ── Excel-style filter popup (inside the table's own positioned wrap) ─────── */
.sf-datatable__fpop {
  position: absolute;
  z-index: 20;
  width: 14.375rem;
  max-width: calc(100% - var(--sp-4));
  padding: var(--sp-2);
  background: var(--surface);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-2);
}
.sf-datatable__fpop[hidden] { display: none; }
.sf-datatable__fpop-search {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  height: 2rem;
  margin-bottom: var(--sp-2);
  padding: 0 var(--sp-2);
  border: var(--hairline) solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink-ui);
}
.sf-datatable__fpop-search svg { width: .875rem; height: .875rem; flex: none; }
.sf-datatable__fpop-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
}
.sf-datatable__fpop-search input::placeholder { color: var(--ink-ui); }
.sf-datatable__fpop-all {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2);
  font-weight: 600;
  border-bottom: var(--hairline) solid var(--line);
  cursor: pointer;
}
.sf-datatable__fpop-list {
  max-height: 13.75rem;
  overflow: auto;
  padding: var(--sp-2) 0;
}
.sf-datatable__fopt {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sf-datatable__fopt:hover { background: var(--surface-2); }
.sf-datatable__fpop-foot {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: var(--hairline) solid var(--line);
}
/* A tick box, not a switch — a switch in a value list reads as a setting. */
.sf-datatable__fpop input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  margin: 0;
  border: var(--hairline) solid var(--line-strong);
  border-radius: 4px;
  background: var(--surface);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.sf-datatable__fpop input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.sf-datatable__fpop input[type="checkbox"]:checked::before {
  content: "\2713";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  line-height: 1;
  color: var(--on-accent);
}
.sf-datatable__fpop input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ── pagination footer ────────────────────────────────────────────────────── */
.sf-datatable__foot {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sp-4);
  padding: var(--sp-2) var(--sp-4);
  border-top: var(--hairline) solid var(--line);
  color: var(--ink-2);
}
.sf-datatable__range { font-variant-numeric: tabular-nums; }
.sf-datatable__psize {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}
.sf-datatable__psize-sel { width: 4.5rem; }
.sf-datatable__nav { display: inline-flex; align-items: center; gap: 2px; }
.sf-datatable__pgn {
  padding: 0 var(--sp-2);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.sf-datatable__pg {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.875rem;
  height: 1.875rem;
  flex: none;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease);
}
.sf-datatable__pg svg { width: .9375rem; height: .9375rem; }
.sf-datatable__pg:hover:not(:disabled) { background: var(--surface-2); }
.sf-datatable__pg:disabled { color: var(--ink-ui); opacity: .5; cursor: default; }

/* 320px: the toolbar and footer stack rather than push the table wider, and the
   table itself keeps its own sideways scroll. The page body never scrolls. */
@media (max-width: 30rem) {
  .sf-datatable { margin: var(--sp-3); }
  .sf-datatable__toolbar { justify-content: stretch; }
  .sf-datatable__search { flex: 1 1 100%; max-width: none; }
  .sf-datatable__foot {
    justify-content: space-between;
    gap: var(--sp-2);
    padding-inline: var(--sp-3);
  }
  .sf-datatable__fpop { width: 12.5rem; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE — the table stops being a table below 46rem
   ═══════════════════════════════════════════════════════════════════════════
   A grid of columns is the wrong shape for a phone. Every alternative that
   keeps the grid — shrink the type, drop columns, scroll sideways — either
   hides data or makes the reader drag to see it, and the instruction was
   "uncut".

   So each ROW becomes a CARD and each cell becomes a label/value line. Nothing
   is hidden and nothing is truncated: the same cells, stacked. The header row
   goes because every value now carries its own label (`data-label`, set in
   _td), and a header would be a caption for a grid that no longer exists.

   Presentation only. Sorting, filtering, search, paging, selection and the
   row-action events are untouched — the same DOM, laid out differently, so
   nothing that reads or drives the control has to know which layout is on.
   ═══════════════════════════════════════════════════════════════════════════ */
@container sf-datatable (max-width: 44rem) {
  /* Nothing to scroll sideways any more; the list flows. */
  .sf-datatable__scroll { overflow: visible; background: transparent; border: 0; }

  table, tbody, tr, td { display: block; inline-size: auto; }
  thead, colgroup, col { display: none; }

  /* THE SHELL GETS OUT OF THE WAY — ALL OF IT.
     A card inside a bordered panel is a box in a box: two edges arguing about
     where one record ends. Keeping the panel and drawing cards inside it was
     the mistake. On a phone the cards ARE the list, and the toolbar and pager
     sit above and below them unhoused.
     The panel itself is styled from outside this query (a container cannot
     match itself) — see the host block in this file. */
  tbody { display: grid; gap: var(--sp-3); background: transparent; padding: 0; }
  /* `__wrap` is the panel — the white surface, the border and the radius all
     live here, not on the host element. Styling the host was styling the wrong
     box, which is why the frame survived two attempts to remove it. */
  .sf-datatable__wrap {
    border: 0;
    background: transparent;
    box-shadow: none;
    border-radius: 0;
  }
  .sf-datatable__toolbar { padding-inline: 0; border: 0; background: transparent; }
  .sf-datatable__foot { padding-inline: 0; border: 0; background: transparent; }

  /* Each row IS a card. */
  tr {
    border: var(--hairline) solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-1);
    padding: var(--sp-4) var(--sp-5) var(--sp-3);
    margin: 0;
  }
  tr.sf-datatable__row--sel {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), var(--shadow-1);
  }
  tr.sf-datatable__empty { box-shadow: none; text-align: center; color: var(--ink-2); }

  /* THE FIRST COLUMN IS THE CARD'S TITLE, NOT A FIELD.
     "HOST — Rayman's Mac Studio" is how a table thinks. A card is about one
     thing and should say what it is at the top, in the size of a name, with no
     caption: the reader already knows a list of Macs contains a Mac. */
  td:first-child {
    display: block;
    font-size: var(--fs-h3);
    font-weight: 640;
    letter-spacing: var(--tr-head);
    color: var(--ink);
    padding: 0 0 var(--sp-3);
    border: 0;
    text-align: start;
  }
  td:first-child::before { content: none; }

  /* Everything after it is a label/value line — the shape of a spec sheet,
     which is what a single record is once it stops being a row. */
  td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: var(--sp-2) 0;
    border: 0;
    border-block-start: var(--hairline) solid var(--line);
    text-align: start;
    min-block-size: 0;
    font-size: var(--fs-sm);
  }
  td::before {
    content: attr(data-label);
    flex: none;
    color: var(--ink-2);
    font-weight: 600;
  }
  td:not([data-label])::before { content: none; }

  /* Actions sit at the foot of the card, right-aligned, with air above them —
     they act on the whole card, not on the last field. */
  td.sf-datatable__actcell {
    justify-content: flex-end;
    gap: var(--sp-2);
    padding-block-start: var(--sp-3);
    margin-block-start: var(--sp-1);
  }
  .sf-datatable__sticky-r { position: static; }

  /* Toolbar and pager wrap instead of overflowing. */
  .sf-datatable__toolbar { flex-wrap: wrap; gap: var(--sp-2); }
  .sf-datatable__toolbar .sf-datatable__search { flex: 1 1 100%; }
  .sf-datatable__foot { flex-wrap: wrap; justify-content: center; gap: var(--sp-3); row-gap: var(--sp-2); }
}


/* The datatable's own box on a narrow VIEWPORT. This cannot live in the
   container query above: an element is not matched by a query on itself.
   44rem here mirrors the container's breakpoint — the two only disagree when a
   narrow table sits on a wide screen, and there the panel staying is correct. */
@media (max-width: 44rem) {
  .sf-datatable {
    border: 0;
    background: transparent;
    box-shadow: none;
    border-radius: 0;
    /* Auto, not stretched: a stretched panel leaves dead space under a short
       list, which is what a fixed height buys on a phone and nothing else. */
    height: auto;
    flex: none;
  }
}
