/* Tables — Phase 1 (MVP). See docs/specs/2026-05-05-tables-phase-1-design.md */

/* Wrap creates the card chrome */
.lsh-table-wrap {
  background: var(--bg-primary);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* Internal scroll container creates the sticky context */
.lsh-table-scroll {
  max-height: var(--table-scroll-max-height, 600px);
  overflow-y: auto;
  overflow-x: auto;   /* Phase 5: allow horizontal scroll when col widths exceed container */
}

/* The table itself.
   Phase 5: width: 100% keeps the table flush with the container at default
   widths, so columns truncate with ellipsis. When the user resizes a column
   wider, inline col[style] widths take effect and the table grows beyond
   100% to accommodate; .lsh-table-scroll's overflow-x: auto then activates. */
.lsh-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--bg-primary);
}

/* Headers — sticky inside the scroll container */
.lsh-table thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--bg-secondary);
  color: var(--text-secondary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  padding: var(--spacing-3);
  border-bottom: 1px solid var(--border-primary);
  white-space: nowrap;
  user-select: none;
}

/* Sortable headers cursor + hover */
.lsh-table th[data-sortable] {
  cursor: pointer;
  transition: background 100ms ease;
}

.lsh-table th[data-sortable]:hover {
  background: var(--bg-tertiary);
}

.lsh-table th[data-sortable]:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: -2px;
}

/* Body cells */
.lsh-table tbody td {
  padding: var(--spacing-3);
  font-size: var(--font-size-sm);
  color: var(--text-primary);
  border-bottom: 1px solid var(--border-tertiary);
  vertical-align: middle;
}

.lsh-table tbody tr:last-child td {
  border-bottom: none;
}

.lsh-table tbody tr:hover td {
  background: var(--bg-secondary);
}

/* ── Header content layout (label + sort icon) ── */
.lsh-table-th-content {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
}

/* ── Sort icon ── */
.lsh-table-sort-icon {
  display: inline-flex;
  align-items: center;
  width: 14px;
  height: 14px;
  color: var(--text-quaternary);
  font-size: 12px;
  line-height: 1;
  flex-shrink: 0;
}

/* Active sort — color shift on the whole icon group */
.lsh-table th[data-sort="asc"] .lsh-table-sort-icon,
.lsh-table th[data-sort="desc"] .lsh-table-sort-icon {
  color: var(--text-primary);
}

/* -----------------------------------------------------------------------------
   Phase 5 — Column widths
   Sizing modes (Fill / Hug longest / Fixed) + per-cell-type minimums.
   All pixel values are element-scoped custom properties (--col-min-width)
   exposed to consumers via the data-cell + data-sizing attribute combo.
   Spec: docs/specs/2026-05-20-tables-phase-5-design.md
   ----------------------------------------------------------------------------- */

.lsh-table th[data-sizing="fill"],
.lsh-table col[data-sizing="fill"]  { width: auto; }

.lsh-table th[data-sizing="hug"],
.lsh-table col[data-sizing="hug"]   { width: 1px; }

.lsh-table th[data-sizing="fixed"],
.lsh-table col[data-sizing="fixed"] { width: var(--col-min-width); }

/* Hug requires nowrap on the *cells* so the column shrinks to longest
   content; without this the 1 px hint would wrap every word. */
.lsh-table td[data-sizing="hug"]    { white-space: nowrap; }

/* Each rule covers both <th> and <col>: <th> is the pre-init safety net,
   <col> is the post-init source of truth once the engine auto-generates
   the colgroup (Task 4). */
.lsh-table th[data-cell="checkbox"], .lsh-table col[data-cell="checkbox"] { --col-min-width: 44px;  min-width: 44px;  }
.lsh-table th[data-cell="radio"],    .lsh-table col[data-cell="radio"]    { --col-min-width: 44px;  min-width: 44px;  }
.lsh-table th[data-cell="lead"],     .lsh-table col[data-cell="lead"]     { --col-min-width: 240px; min-width: 240px; }
.lsh-table th[data-cell="text"],     .lsh-table col[data-cell="text"]     { --col-min-width: 120px; min-width: 120px; }
.lsh-table th[data-cell="text-ico"], .lsh-table col[data-cell="text-ico"] { --col-min-width: 140px; min-width: 140px; }
.lsh-table th[data-cell="link"],     .lsh-table col[data-cell="link"]     { --col-min-width: 120px; min-width: 120px; }
.lsh-table th[data-cell="lab"],      .lsh-table col[data-cell="lab"]      { --col-min-width: 140px; min-width: 140px; }
.lsh-table th[data-cell="avatar"],   .lsh-table col[data-cell="avatar"]   { --col-min-width: 56px;  min-width: 56px;  }
.lsh-table th[data-cell="icon"],     .lsh-table col[data-cell="icon"]     { --col-min-width: 48px;  min-width: 48px;  }
.lsh-table th[data-cell="tag"],      .lsh-table col[data-cell="tag"]      { --col-min-width: 96px;  min-width: 96px;  }
.lsh-table th[data-cell="actions"],  .lsh-table col[data-cell="actions"]  { --col-min-width: 96px;  min-width: 96px;  }
.lsh-table th[data-cell="more"],     .lsh-table col[data-cell="more"]     { --col-min-width: 56px;  min-width: 56px;  }
.lsh-table th[data-cell="input"],    .lsh-table col[data-cell="input"]    { --col-min-width: 160px; min-width: 160px; }
.lsh-table th[data-cell="button"],   .lsh-table col[data-cell="button"]   { --col-min-width: 140px; min-width: 140px; }

/* Overflow contract — every <td> truncates with ellipsis by default; the
   engine (Task 10, js/tables-resize.js) adds a native title= attribute to
   any <td> whose scrollWidth exceeds clientWidth, so screen readers and
   hover tooltips show the full content. Multi-line cell types opt out
   below. */
.lsh-table tbody td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Multi-line cell types opt out (Lab Results renders value + unit + range). */
.lsh-table td.lsh-table-lab-cell {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

/* Cells that anchor absolutely-positioned children (kebab menus, popovers)
   opt out — Phase 3 More cell hosts a .lsh-table-menu via position: relative,
   and overflow: hidden would clip it. */
.lsh-table td.lsh-table-more-cell {
  overflow: visible;
  text-overflow: clip;
}

/* -----------------------------------------------------------------------------
   Phase 5 — Resize handle (header-hover affordance)
   Per Q5 brainstorm: quiet by default, fades in 1 px dividers when any
   header is hovered, brand-coloured 3 px on the specific column being
   approached. Q8 brainstorm: full WAI-ARIA separator semantics, focusable.
   ----------------------------------------------------------------------------- */

.lsh-table th { position: relative; }   /* anchor for the handle */

.lsh-table-col-resize {
  position: absolute;
  top: 0;
  right: -3px;            /* half-overhang for a comfortable 6 px hit area */
  width: 6px;
  height: 100%;
  cursor: col-resize;
  user-select: none;
  z-index: 1;
  display: block;
  background: transparent;
  border: 0;
  padding: 0;
}

.lsh-table-col-resize:focus { outline: none; }

/* Quiet by default: invisible 1 px divider line, vertically centred. */
.lsh-table-col-resize::after {
  content: '';
  position: absolute;
  top: 25%;
  right: 2px;
  width: 1px;
  height: 50%;
  background: var(--border-secondary);
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease, width 0.15s ease;
  border-radius: 2px;
}

/* Header-row hover OR handle focus: fade in every divider. */
.lsh-table thead:hover .lsh-table-col-resize::after,
.lsh-table-col-resize:focus-visible::after {
  opacity: 1;
}

/* Specific handle hover/focus: thicker + brand-coloured. */
.lsh-table th:hover .lsh-table-col-resize::after,
.lsh-table-col-resize:hover::after,
.lsh-table-col-resize:focus-visible::after {
  width: 3px;
  background: var(--border-brand);
}

/* Active drag: the dragged handle stays brand-coloured everywhere. */
body.is-resizing-table .lsh-table-col-resize.is-active::after {
  opacity: 1;
  width: 3px;
  background: var(--border-brand);
}

body.is-resizing-table {
  cursor: col-resize;
  user-select: none;
}

/* Keyboard focus indicator — matches the .lsh-table th[data-sortable]:focus-visible
   precedent at line 51-54 (outline, not just the ::after bar). The bar still appears
   on focus per the rules above; the outline adds the project-standard 2 px ring. */
.lsh-table-col-resize:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .lsh-table-col-resize::after { transition-duration: 0s; }
}

/* ── Pagination footer ── */
.lsh-table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-3) var(--spacing-4);
  border-top: 1px solid var(--border-primary);
  background: var(--bg-primary);
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  gap: var(--spacing-3);
  flex-wrap: wrap;
}

.lsh-table-pagination__left,
.lsh-table-pagination__right {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

/* Page size selector */
.lsh-pagination-size-select {
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-sm);
  padding: var(--spacing-1) var(--spacing-2);
  background: var(--bg-primary);
  font-size: var(--font-size-sm);
  color: var(--text-primary);
  cursor: pointer;
}

.lsh-pagination-size-select:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
}

/* Pagination buttons */
.lsh-pagination-btn {
  min-width: 32px;
  height: 32px;
  border: 1px solid var(--border-secondary);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  padding: 0 var(--spacing-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}

.lsh-pagination-btn:hover:not([disabled]) {
  background: var(--bg-secondary);
}

.lsh-pagination-btn:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
}

.lsh-pagination-btn[aria-current="page"] {
  background: var(--bg-secondary);
  color: var(--text-primary);
  border-color: var(--border-primary);
}

.lsh-pagination-btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

.lsh-pagination-ellipsis {
  color: var(--text-quaternary);
  padding: 0 var(--spacing-1);
  user-select: none;
}

/* ── Status pill — preview-only in Phase 1 (formal Tag cell type lands in Phase 3) ── */
.lsh-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-1-5);
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
}
.lsh-pill::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.lsh-pill--ok    { background: var(--bg-success-primary, #ECFDF3); color: var(--text-success-primary, #027A48); }
.lsh-pill--warn  { background: var(--bg-warning-primary, #FEF0C7); color: var(--text-warning-primary, #B54708); }
.lsh-pill--alert { background: var(--bg-error-primary,   #FEE4E2); color: var(--text-error-primary,   #B42318); }

/* ============================================================
   Phase 2 — Density (data-density on .lsh-table)
   Md is the default; Sm + Lg opt in. Font sizes constant.
   ============================================================ */

.lsh-table[data-density="sm"] thead th,
.lsh-table[data-density="sm"] tbody td {
  padding: var(--spacing-2) var(--spacing-3);   /* 8px V / 12px H */
}

.lsh-table[data-density="lg"] thead th,
.lsh-table[data-density="lg"] tbody td {
  padding: var(--spacing-4);                     /* 16px all */
}

/* ============================================================
   Phase 2 — Priority row backgrounds (data-priority on <tr>)
   :where() flattens specificity to 0 so selection wins naturally.
   ============================================================ */

.lsh-table tbody tr:where([data-priority="high"])   td { background: var(--priority-high-bg); }
.lsh-table tbody tr:where([data-priority="medium"]) td { background: var(--priority-medium-bg); }
.lsh-table tbody tr:where([data-priority="low"])    td { background: var(--priority-low-bg); }

/* Priority preserves on hover — priority is persistent semantic, hover is transient */
.lsh-table tbody tr:where([data-priority="high"]):hover   td { background: var(--priority-high-bg-hover); }
.lsh-table tbody tr:where([data-priority="medium"]):hover td { background: var(--priority-medium-bg-hover); }
.lsh-table tbody tr:where([data-priority="low"]):hover    td { background: var(--priority-low-bg-hover); }

/* ============================================================
   Phase 2 — Selection bg (data-selected on <tr>)
   Selection wins over priority (Q7 lock). Specificity 1 beats
   :where()-flattened priority's 0. MUST come after priority.
   ============================================================ */

.lsh-table tbody tr[data-selected="true"] td {
  background: var(--bg-brand-secondary);
}

/* ============================================================
   Phase 2 — Selection-bar (preceding sibling of .lsh-table-wrap)
   Bold brand-solid theme per Q4 lock + Figma node 3558:30152.
   ============================================================ */

.lsh-table-selection-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-3) var(--spacing-4);
  border-radius: var(--radius-md) var(--radius-md) 0 0;  /* top-only — flush with wrap */
  background: var(--bg-brand-solid-secondary);
  color: var(--text-primary-on-brand);
  font-size: var(--font-size-sm);
  font-family: inherit;
}

.lsh-table-selection-bar[hidden] {
  display: none;
}

.lsh-table-selection-bar__left {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
}

.lsh-table-selection-bar__count {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  font-weight: var(--font-weight-medium);
}

.lsh-table-selection-bar__actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

.lsh-table-selection-bar__clear {
  background: none;
  border: none;
  color: var(--text-primary-on-brand);
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  text-decoration: underline;
  padding: var(--spacing-1) var(--spacing-2);
  border-radius: var(--radius-sm);
}

.lsh-table-selection-bar__clear:hover {
  background: rgba(255, 255, 255, 0.1);
}

.lsh-table-selection-bar__clear:focus-visible {
  outline: 2px solid var(--text-primary-on-brand);
  outline-offset: 2px;
}

/* Adjacent-sibling corner alignment — square the wrap's top corners
   only when the bar is its preceding sibling AND visible. The
   :not([hidden]) guard matters in multi-mode with zero selections:
   the bar is in the DOM with [hidden] but still a structural sibling,
   so without the guard the wrap would render with squared top corners
   floating with no bar above it. */
.lsh-table-selection-bar:not([hidden]) + .lsh-table-wrap {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* ============================================================
   Phase 2 — Helper class for consumer-authored bulk-action buttons
   Visual harmony with the bar's bold brand-solid theme.
   ============================================================ */

.lsh-bulk-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-3);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.15);
  color: var(--text-primary-on-brand);
  font-family: inherit;
  font-size: var(--font-size-sm);
  cursor: pointer;
}

.lsh-bulk-btn:hover {
  background: rgba(255, 255, 255, 0.25);
}

.lsh-bulk-btn:focus-visible {
  outline: 2px solid var(--text-primary-on-brand);
  outline-offset: 2px;
}

/* ============================================================
   Phase 2 — Checkbox column (auto-inserted in multi-mode)
   Uses the DS Checkbox component (.checkbox-group). The cell-scoped
   overrides below make the label fill the cell so the entire 40px
   region is a click hit-target, and remove the label's default
   padding + top-margin (which are designed for label-text alignment,
   not in-cell centering).
   ============================================================ */

.lsh-table-checkbox-cell {
  width: var(--table-checkbox-cell-width, 40px);
  text-align: center;
}

.lsh-table-checkbox-cell .checkbox-group {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
  padding: 0;
}

.lsh-table-checkbox-cell .checkbox-input {
  margin-top: 0;
}


/* ============================================================
   Phase 3 — Cell alignment helper
   data-align="right|center" on <th> or <td>. left is the implicit
   default (no rule needed). Cells must carry the attribute on
   header AND every td of the column — CSS doesn't propagate
   text-align from <col> to descendant cells.
   ============================================================ */
.lsh-table [data-align="right"]  { text-align: right; }
.lsh-table [data-align="center"] { text-align: center; }


/* ============================================================
   Phase 3 — Menu engine styling
   Used by More cell + reusable beyond tables. Lives here for
   Phase 3's single consumer; extracts to css/components/menu.css
   in Phase 4 when the second consumer arrives (spec §11.7 + §18).
   ============================================================ */
.lsh-table-menu {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 4px;
  min-width: 200px;
  max-width: 320px;
  background: var(--bg-primary);
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  padding: 4px 0;
  z-index: 100;
}

.lsh-table-menu[hidden] {
  display: none;
}

.lsh-table-menu.is-above {
  top: auto;
  bottom: 100%;
  margin-top: 0;
  margin-bottom: 4px;
}

.lsh-table-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 12px;
  border: none;
  background: transparent;
  text-align: left;
  font-family: var(--font-primary);
  font-size: 13px;
  color: var(--text-primary);
  cursor: pointer;
  transition: background 80ms;
  line-height: 1.3;
}

.lsh-table-menu-item:hover,
.lsh-table-menu-item:focus-visible {
  background: var(--bg-secondary);
  outline: none;
}

.lsh-table-menu-item > i {
  width: 16px;
  text-align: center;
  color: var(--text-tertiary);
  flex-shrink: 0;
}

.lsh-table-menu-item.is-danger {
  color: var(--text-error-primary);
}

.lsh-table-menu-item.is-danger > i {
  color: var(--text-error-primary);
}

.lsh-table-menu-item[aria-disabled="true"],
.lsh-table-menu-item:disabled {
  color: var(--text-tertiary);
  cursor: not-allowed;
  background: transparent;
}

.lsh-table-menu-divider {
  border: none;
  border-top: 1px solid var(--border-tertiary);
  margin: 4px 0;
}

/* ============================================================
   Phase 3 — Lab Results cell
   Markup-driven hybrid anatomy: -value required; -unit, -ref, inline
   .tag all optional sub-elements. data-lab-show on the table controls
   per-table visibility (developer-authored, not user-facing).
   See spec §9.2 + §9.3.
   ============================================================ */
.lsh-table-lab-cell {
  font-feature-settings: 'lnum', 'tnum';
  /* Default: left-aligned. Opt-in to right or center via data-align on the
     column's <th> — the framework propagates that to every <td> at init
     time (see propagateColumnAlignment in js/tables.js). The generic
     .lsh-table [data-align="right|center"] rule handles text-align; the
     inner inline-flex rows below need their own justify-content overrides. */
}

.lsh-table-lab-cell > .lsh-table-lab-line,
.lsh-table-lab-cell > .lsh-table-lab-value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-content: flex-start;
}

.lsh-table-lab-cell > .lsh-table-lab-line {
  width: 100%;
}

/* data-align overrides for the inline-flex inner rows. text-align on the
   cell handles non-flex children (notably .lsh-table-lab-ref via inherit). */
.lsh-table-lab-cell[data-align="right"] > .lsh-table-lab-line,
.lsh-table-lab-cell[data-align="right"] > .lsh-table-lab-value {
  justify-content: flex-end;
}
.lsh-table-lab-cell[data-align="center"] > .lsh-table-lab-line,
.lsh-table-lab-cell[data-align="center"] > .lsh-table-lab-value {
  justify-content: center;
}

.lsh-table-lab-value {
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
}

.lsh-table-lab-unit {
  color: var(--text-tertiary);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-xs);
}

.lsh-table-lab-ref {
  display: block;
  text-align: inherit;   /* follows the cell's text-align (set by [data-align] rule) */
  font-size: var(--font-size-xs);
  line-height: var(--line-height-xs);
  color: var(--text-tertiary);
  margin-top: 2px;
}

/* Out-of-range value coloring — opt-in via .is-out class on the cell */
.lsh-table-lab-cell.is-out .lsh-table-lab-value {
  color: var(--text-error-primary);
}

/* data-lab-show visibility — developer-authored attribute on .lsh-table.
   When the attribute is absent, all sub-elements are visible (default).
   When present, only the listed parts are visible. Value is always shown. */
.lsh-table[data-lab-show]:not([data-lab-show*="unit"]) .lsh-table-lab-unit { display: none; }
.lsh-table[data-lab-show]:not([data-lab-show*="ref"])  .lsh-table-lab-ref  { display: none; }
.lsh-table[data-lab-show]:not([data-lab-show*="tag"])  .lsh-table-lab-cell .tag { display: none; }

/* ============================================================
   Phase 3 — Remaining cell wrapper classes
   See spec §8 (Display), §10 (Interactive). Each wrapper bakes in
   alignment + layout responsibilities. Sub-element classes follow
   the `.lsh-table-{type}-{part}` pattern (hyphenated children;
   NOT BEM __).
   ============================================================ */

/* ─── Lead cell (Display) — avatar + name + optional meta ─── */
.lsh-table-lead-cell {
  display: flex;
  align-items: center;
  gap: 12px;
}

.lsh-table-lead-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.lsh-table-lead-name {
  color: var(--text-primary);
  font-weight: var(--font-weight-medium);
  line-height: 1.3;
}

.lsh-table-lead-meta {
  font-size: var(--font-size-xs);
  line-height: var(--line-height-xs);
  color: var(--text-secondary);
  font-feature-settings: 'lnum', 'tnum';  /* tabular Kennitala */
}

.lsh-table[data-density="sm"] .lsh-table-lead-cell { gap: 8px; }
.lsh-table[data-density="lg"] .lsh-table-lead-cell { gap: 14px; }


/* ─── Icon cell (Display) — single centered icon ─── */
.lsh-table-icon-cell {
  text-align: center;
}

.lsh-table-icon-cell > i,
.lsh-table-icon-cell > svg {
  font-size: 16px;
  line-height: 1;
  vertical-align: middle;
  color: var(--text-secondary);
}

.lsh-table[data-density="sm"] .lsh-table-icon-cell > i,
.lsh-table[data-density="sm"] .lsh-table-icon-cell > svg { font-size: 14px; }

.lsh-table[data-density="lg"] .lsh-table-icon-cell > i,
.lsh-table[data-density="lg"] .lsh-table-icon-cell > svg { font-size: 18px; }


/* ─── Actions cell (Interactive) — icon-button row, always-visible ─── */
.lsh-table-actions-cell {
  text-align: right;
  white-space: nowrap;
  padding-right: 6px;
}

.lsh-table-action-btn {
  width: 30px;
  height: 30px;
  border: none;
  background: transparent;
  border-radius: var(--radius-xs);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
  transition: background 100ms, color 100ms;
  font-size: 13px;
  padding: 0;
  vertical-align: middle;
}

.lsh-table-action-btn:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.lsh-table-action-btn:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: -2px;
}

.lsh-table-action-btn.is-danger:hover {
  color: var(--text-error-primary);
}

.lsh-table[data-density="sm"] .lsh-table-action-btn { width: 26px; height: 26px; font-size: 12px; }
.lsh-table[data-density="lg"] .lsh-table-action-btn { width: 34px; height: 34px; font-size: 14px; }


/* ─── More cell (Interactive) — kebab trigger anchoring menu ─── */
.lsh-table-more-cell {
  text-align: right;
  white-space: nowrap;
  padding-right: 6px;
  position: relative;  /* anchors absolute-positioned .lsh-table-menu */
}

.lsh-table-more-btn {
  /* Modifier on .lsh-table-action-btn — currently empty, reserved
     for any kebab-specific tweaks (e.g., larger hit area in future). */
}


/* ─── Radio cell (Interactive) — parallels Phase 2's checkbox cell.
   Uses the DS Radio component (.radio-group). Cell-scoped overrides
   mirror those on .lsh-table-checkbox-cell — label fills the cell so
   the full 40px is clickable, padding stripped to let cell centering
   take over. ─── */
.lsh-table-radio-cell {
  width: var(--table-radio-cell-width, 40px);
  text-align: center;
  vertical-align: middle;
  padding-left: 0;
  padding-right: 0;
}

.lsh-table-radio-cell .radio-group {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
  padding: 0;
}

.lsh-table-radio-cell .radio-input {
  margin-top: 0;
}


/* ─── Input cell (Interactive) — in-row editable text / numeric.
   Composes the existing .input-field markup but presents it as a cell:
   no border, no radius, no outer focus ring (would overflow into
   neighboring cells). Hover + focus tinting comes from --bg-brand-primary-alt
   to match Figma node 5663-49524 ("Input cell" component set).
   All input variants — .input-error, .input-disabled, .input-secondary-text,
   .input-icon — work for free because we reuse .input-field internally. */

.lsh-table tbody td.lsh-table-input-cell {
  padding: 0; /* input-field fills the cell — beats default td padding */
}

.lsh-table-input-cell .input-field {
  width: 100%;
  height: auto;
  border: none;
  border-radius: 0;
  background-color: transparent;
  /* Vertical padding matches the natural .lsh-table tbody td (var(--spacing-3))
     so input-cell row height equals neighboring static-cell row height.
     Horizontal padding matches the cell's natural horizontal padding so the
     hover/focus bg appears flush with the cell edges (cell itself has padding:0). */
  padding: var(--spacing-3) 12px;
  transition: background-color 0.12s ease, box-shadow 0.12s ease;
}

/* Typography — match the regular table-cell text (14px / line-height-sm)
   rather than .input-field's default 16px. Keeps the input visually
   indistinguishable from neighboring static cells until hover/focus. */
.lsh-table-input-cell .input-field input,
.lsh-table-input-cell .input-field .input-el,
.lsh-table-input-cell .input-field .input-secondary-text {
  font-size: var(--font-size-sm);
  line-height: var(--line-height-sm);
}

/* Right-aligned cells (data-align="right" — typically numeric columns):
   the cell's text-align rule doesn't cascade into form elements, so we
   explicitly right-align the input's value. With .input-field's flex
   layout (input flex:1, gap:8px), this puts the number directly next
   to the trailing .input-secondary-text — "30 mg" reads as one unit
   instead of "30 ............ mg". */
.lsh-table-input-cell[data-align="right"] .input-field input,
.lsh-table-input-cell[data-align="right"] .input-field .input-el {
  text-align: right;
}

/* Sm density — tighter padding to match table row height (32px) */
.lsh-table[data-density="sm"] .lsh-table-input-cell .input-field {
  padding: var(--spacing-2) 8px;
}

/* Lg density — wider padding to match table row height (48px) */
.lsh-table[data-density="lg"] .lsh-table-input-cell .input-field {
  padding: var(--spacing-4) 16px;
}

/* Hover — subtle brand-tinted bg (Figma's #F6F8FE) */
.lsh-table-input-cell:hover .input-field:not(.input-disabled) {
  background-color: var(--bg-brand-primary-alt);
}

/* Focused (active editing) — same tint + inset 1px brand border.
   Inset shadow stays INSIDE the cell so it doesn't overflow into
   adjacent cells (regular .input uses 4px outer ring — unsafe here). */
.lsh-table-input-cell:focus-within .input-field:not(.input-disabled):not(.input-error) {
  background-color: var(--bg-brand-primary-alt);
  box-shadow: inset 0 0 0 1px var(--border-brand);
}

/* Error — inset 1px red border, regardless of focus state.
   Reuses the existing .input-field.input-error class — author opts in
   by adding .input-error to the inner .input-field. */
.lsh-table-input-cell .input-field.input-error {
  box-shadow: inset 0 0 0 1px var(--border-error);
}

.lsh-table-input-cell:focus-within .input-field.input-error {
  background-color: var(--bg-brand-primary-alt);
  box-shadow: inset 0 0 0 1px var(--border-error);
}

/* Disabled — explicit bg tint so disabled cells are visibly distinct
   from empty editable cells. Cell-level hover/focus is suppressed
   (see :not(.input-disabled) above), so the bg stays --bg-disabled
   regardless of pointer/keyboard state. */
.lsh-table-input-cell .input-field.input-disabled {
  background-color: var(--bg-disabled);
}

/* ============================================================
   Phase 4 — Toolbar (Outer shell + zones + density inheritance)
   See docs/specs/2026-05-18-tables-phase-4-design.md
   ============================================================ */

/* Optional outer container — takes ownership of the visual frame
   when present. Phase 1–3 standalone tables (no shell) render unchanged. */
.lsh-table-shell {
  border: 1px solid var(--border-primary);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  overflow: hidden;
}

/* When inside a shell, the wrap loses its frame so they read as one panel */
.lsh-table-shell > .lsh-table-wrap {
  border: none;
  border-radius: 0;
  background: transparent;
}

/* When inside a shell, the pagination footer loses its top border collision +
   any margin so it sits flush */
.lsh-table-shell > .lsh-table-pagination {
  border-radius: 0;
  margin: 0;
}

/* ── Toolbar root ── */
.lsh-table-toolbar {
  background: var(--bg-primary);
  font-family: inherit;  /* inherit from shell so toolbar text matches table text */
}

/* Between-zone separators — applied conditionally based on what follows.
   Title and tabs flow together as one continuous block at the top with no
   inter-zone border. Filters and chips each draw a bottom border to
   separate from what follows. The toolbar owns the boundary against the
   table: the last visible zone always carries a bottom border (toolbar JS
   marks it with .is-last), so the table thead doesn't need a border-top
   and Phase 1 standalone tables stay untouched. */
.lsh-table-toolbar > .lsh-table-toolbar-filters,
.lsh-table-toolbar > .lsh-table-toolbar-chips {
  border-bottom: 1px solid var(--border-primary);
}

.lsh-table-toolbar > .is-last {
  border-bottom: 1px solid var(--border-primary);
}

/* When the shell is present, the toolbar's outer left/right/top corners
   are clipped by the shell's overflow:hidden. No extra rules needed. */

/* ── Title row ── */
.lsh-table-toolbar-title-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-4);
}

.lsh-table-toolbar-title {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-1);
  margin: 0;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  line-height: 1.4;
}

.lsh-table-toolbar-title-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  margin-left: var(--spacing-1);
  border: none;
  background: transparent;
  border-radius: var(--radius-xs);
  color: var(--text-quaternary);
  cursor: pointer;
  font-size: var(--font-size-xs);
  font-family: inherit;
  transition: background 100ms ease, color 100ms ease;
}

.lsh-table-toolbar-title-trigger:hover {
  background: var(--bg-secondary);
  color: var(--text-secondary);
}

.lsh-table-toolbar-title-trigger:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
}

/* Title-actions inline-marker slot — right-aligned */
.lsh-table-toolbar-title-row [data-table-title-actions] {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
  margin-left: auto;
}

/* ── Title-row action button (utility icons or labeled CTAs) ── */
.lsh-table-toolbar-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-xs);
  color: var(--text-secondary);
  cursor: pointer;
  font-size: var(--font-size-sm);
  font-family: inherit;
  transition: background 100ms ease;
}

.lsh-table-toolbar-action-btn:hover {
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.lsh-table-toolbar-action-btn:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
}

/* Labeled-button variant — when the consumer slots a labeled button
   instead of an icon. Auto-grows in width. */
.lsh-table-toolbar-action-btn.has-label {
  width: auto;
  padding: 0 var(--spacing-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
}

/* ── Tabs row — consumes the shared Tabs component (.tabs/.tab) ──
   The standalone Tabs paint + engine (css/components/tabs.css + js/tabs.js)
   own the tab look, selection, roving tabindex, keyboard and overflow. The
   toolbar markup is `class="tabs lsh-table-toolbar-tabs"` + `class="tab"`,
   wrapped in `.tabs-frame` with a `.tabs-fade`. tables.css keeps ONLY the
   genuine table-specific deltas on top of the component:
     · horizontal zone padding so the strip aligns with the other zones;
     · the compact 14px font + original `normal` line-height (the standalone
       md tab is 16px / line-height-md);
     · the thin brand scrollbar (the standalone hides the scrollbar);
     · NO baseline border — title + tabs flow together as one block (see the
       between-zone separators note near the top of the toolbar section).
   Because tables.css loads before tabs.css, every override below out-specifies
   the component rules it replaces. */
.lsh-table-toolbar-tabs-frame {
  overflow: hidden;            /* clip to bounds; .tabs-frame supplies position: relative */
}

.lsh-table-toolbar-tabs {
  padding: 0 var(--spacing-4); /* align the strip with the toolbar's other zones */
  min-width: 0;
}

/* Suppress the standalone tablist's 1px baseline border — the toolbar
   deliberately flows the title + tabs together with no inter-zone border. */
.tabs.lsh-table-toolbar-tabs {
  border-bottom: none;
}

/* The toolbar tab is more compact than the standalone md tab (14px vs 16px) and
   keeps its original `normal` line-height (the standalone uses line-height-md). */
.lsh-table-toolbar-tabs .tab {
  font-size: var(--font-size-sm);
  line-height: normal;
}

/* Keep the thin brand scrollbar — the standalone hides the scrollbar in favour
   of the fade-edge alone. Out-specifies .tabs[data-overflow="scroll"]. */
.lsh-table-toolbar-tabs.tabs[data-overflow="scroll"] {
  scrollbar-width: thin;
  scrollbar-color: var(--border-brand) transparent;
}

.lsh-table-toolbar-tabs.tabs[data-overflow="scroll"]::-webkit-scrollbar {
  height: 4px;
  display: block;
}

.lsh-table-toolbar-tabs.tabs[data-overflow="scroll"]::-webkit-scrollbar-track {
  background: transparent;
}

.lsh-table-toolbar-tabs.tabs[data-overflow="scroll"]::-webkit-scrollbar-thumb {
  background: var(--border-brand);
  border-radius: 2px;
}

/* ── Filter row ── */
.lsh-table-toolbar-filters {
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
  padding: var(--spacing-2) var(--spacing-4);
  flex-wrap: wrap;
}

/* Leading placeholder slot — reserved for future Advanced Filter component */
.lsh-table-toolbar-filters [data-table-filter-placeholder] {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

/* Pinned slot — laid out inline with the pinned filter buttons */
.lsh-table-toolbar-filters [data-table-filter-pinned] {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  flex-wrap: wrap;
}

/* Toolbar menu anchor — any toolbar trigger that opens an absolute-positioned
   menu/dropdown lives inside this wrapper so the overlay anchors to the
   trigger, not whatever positioned ancestor sits higher up the tree. First
   consumer was the pinned filter triggers in Phase 4 (inside
   [data-table-filter-pinned]); the gear settings button in the title row
   is the second consumer. The class name is intentionally generic — the
   role is "popover positioning context," not anything filter-specific. */
.lsh-table-toolbar-menu-anchor {
  position: relative;
  display: inline-block;
}

/* ── Column-visibility menu bridges (engine: js/tables-cols-visibility.js) ──
   The menu reuses the design-system dropdown component's classes for
   visual consistency with the rest of the site (.dropdown-menu,
   .dropdown-group-header, .dropdown-item--checkbox, .checkbox-box,
   .dropdown-divider). Two small bridges below let it work with menu.js's
   semantics:

   1. menu.js toggles visibility via the [hidden] attribute, not via
      .is-open class. Add a sibling rule so a .dropdown-menu reveals
      when hidden is absent — scoped to role="menu" so the dropdown
      component's listbox menus are unaffected.

   2. The per-column toggles + tristate master use role="menuitemcheckbox"
      with aria-checked (true | mixed | false), not the dropdown
      component's aria-selected. Mirror the dropdown-item--checkbox
      brand-solid paint for both true and mixed, and reveal the matching
      icon (.fa-check for true, .fa-minus for mixed). */

.dropdown-menu[role="menu"]:not([hidden]) {
  display: block;
}

/* The dropdown component's left: 0; right: 0 stretches the menu to the
   parent's full width — fine for an input-style trigger inside a .dropdown
   wrapper, broken for an icon button hosted inside a narrow <th>. Anchor
   to the trigger's right edge with a sensible width range. Also reset
   text-align (the <th> parent inherits center per the browser UA default
   for table headers, which would center the .dropdown-group-header text). */
.dropdown-menu[role="menu"] {
  top: 100%;
  left: auto;
  right: 0;
  margin-top: 4px;
  min-width: 240px;
  max-width: 320px;
  /* Reset inherited typography from the <th> parent — browser UA stylesheets
     give table headers text-align: center + font-weight: 600 by default.
     The dropdown component assumes a neutral container, so set explicit
     left/normal here. */
  text-align: left;
  font-weight: normal;
}

/* When .dropdown-item is rendered as a <button> (column-visibility menu
   uses buttons for the menuitemcheckbox semantics — keyboard activatable
   focusable elements), reset the browser's native button chrome so it
   reads as a plain dropdown row. The dropdown component itself uses
   <div role="option">, so it doesn't need this. */
button.dropdown-item {
  background: transparent;
  border: none;
  font-family: inherit;
  text-align: inherit;
  width: 100%;
}

.dropdown-item--checkbox[aria-checked="true"] .checkbox-box,
.dropdown-item--checkbox[aria-checked="mixed"] .checkbox-box {
  background: var(--bg-brand-solid);
  border-color: var(--bg-brand-solid);
  color: var(--text-primary-on-brand);
}

.dropdown-item--checkbox[aria-checked="true"] .checkbox-box i.fa-check {
  display: block;
}

.dropdown-item--checkbox[aria-checked="mixed"] .checkbox-box i.fa-minus {
  display: block;
}

/* ─── Column visibility toggle (engine: js/tables-cols-visibility.js) ───
   Opt-in via `data-table-cols-toggle` on any <th>. Engine auto-injects
   a button + menu into that <th>. Hidden columns get
   `data-col-hidden="true"` on the <th>, every <td> in the column, and
   the matching <col> element. */

th[data-table-cols-toggle] {
  position: relative;  /* anchor the absolute-positioned .lsh-table-menu */
}

.lsh-table-cols-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-xs);
  cursor: pointer;
  color: var(--text-tertiary);
  font-size: 13px;
  font-family: inherit;
  transition: background 100ms, color 100ms;
  vertical-align: middle;
}

.lsh-table-cols-trigger:hover {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

.lsh-table-cols-trigger:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: -2px;
}

.lsh-table-cols-trigger[aria-expanded="true"] {
  background: var(--bg-tertiary);
  color: var(--text-primary);
}

/* Hidden columns — same attribute on <th>, every <td> in the column, and
   the <col> element (set together by tablesSetColumnVisibility). */
.lsh-table th[data-col-hidden="true"],
.lsh-table td[data-col-hidden="true"],
.lsh-table col[data-col-hidden="true"] {
  display: none;
}

/* ── Pinned filter button ──
   The filter button now composes the design-system Secondary Gray button
   at Sm size. Apply `.btn .btn-secondary-gray .btn-sm` for the visual
   paint, and `.lsh-table-toolbar-filter-btn` as a hook for the active-state
   brand-tint override and JS selectors. No self-painting here. */
.lsh-table-toolbar-filter-btn {
  white-space: nowrap;
}

/* Trigger-class collision override — when `.datetime-trigger` (Tímabil)
   or `.dropdown-trigger` (Læknir / Staða / Stofa) is composed onto the
   filter-btn hook, those bare single-class selectors load AFTER buttons.css
   in index.html and silently win the cascade against `.btn-secondary-gray`
   (transparent bg + border on datetime; placeholder text colour on
   dropdown). Re-assert the Secondary Gray paint at two-class specificity
   (0,2,0) so the trigger classes lose without `!important`. The standalone
   Dropdown and Datetime Picker pages are untouched. */
.lsh-table-toolbar-filter-btn.datetime-trigger,
.lsh-table-toolbar-filter-btn.dropdown-trigger {
  background-color: var(--bg-primary);
  border-color: var(--border-secondary);
  color: var(--fg-secondary);
}
.lsh-table-toolbar-filter-btn.datetime-trigger:hover:not(:disabled),
.lsh-table-toolbar-filter-btn.dropdown-trigger:hover:not(:disabled) {
  background-color: var(--bg-secondary-hover);
  border-color: var(--border-secondary);
  color: var(--fg-secondary-hover);
}

/* Active state — applied when this filter dimension has chips. Higher
   specificity than .btn-secondary-gray (two classes) so the brand-tint
   wins. */
.lsh-table-toolbar-filter-btn.is-active {
  background-color: var(--bg-brand-primary-alt);
  border-color: var(--border-brand);
  color: var(--text-brand-primary);
}
.lsh-table-toolbar-filter-btn.is-active:hover:not(:disabled) {
  background-color: var(--bg-brand-primary);
  border-color: var(--border-brand);
  color: var(--text-brand-primary);
}

/* Chevron tint follows the active state — picks up brand colour when the
   button is engaged, default quaternary otherwise. */
.lsh-table-toolbar-filter-btn .lsh-filter-chev,
.lsh-table-toolbar-filter-btn .fa-chevron-down {
  color: var(--text-quaternary);
}
.lsh-table-toolbar-filter-btn.is-active .lsh-filter-chev,
.lsh-table-toolbar-filter-btn.is-active .fa-chevron-down {
  color: var(--text-brand-primary);
}

/* Dropdown wrapper inside a menu-anchor — neutralise the dropdown
   component's column-layout + full-width assumptions so the trigger
   sizes naturally as a button. (Filter dropdowns nest a full .dropdown
   component inside the anchor; the gear menu skips the wrapper and uses
   .dropdown-menu directly — the latter is sized by the
   .dropdown-menu[role="menu"] bridge above, not by these rules.) */
.lsh-table-toolbar-menu-anchor .dropdown {
  width: auto;
  max-width: none;
  gap: 0;
  display: inline-block;
}
.lsh-table-toolbar-menu-anchor .dropdown-menu {
  width: auto;
  min-width: 220px;
}
/* Dropdown menu chevron rotation also applies to the button-classed
   chevron icon — the dropdown engine reads aria-expanded on the trigger. */
.lsh-table-toolbar-filter-btn[aria-expanded="true"] .lsh-filter-chev,
.lsh-table-toolbar-filter-btn[aria-expanded="true"] .fa-chevron-down {
  transform: rotate(180deg);
  transition: transform 0.2s ease;
}

/* Leading filter-icon button (placeholder, no behavior in Phase 4) */
.lsh-table-toolbar-filter-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--border-primary);
  background: var(--bg-primary);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  font-family: inherit;
  cursor: pointer;
  flex-shrink: 0;
}

.lsh-table-toolbar-filter-icon-btn:hover:not(:disabled) {
  background: var(--bg-secondary);
  color: var(--text-primary);
}

.lsh-table-toolbar-filter-icon-btn:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
}

/* Disabled — family standard (mirrors .btn-primary:disabled + .btn:disabled cursor) */
.lsh-table-toolbar-filter-icon-btn:disabled {
  background: var(--bg-disabled);
  color: var(--fg-disabled);
  border-color: transparent;
  cursor: not-allowed;
}

/* ── Filter chips row ── */
.lsh-table-toolbar-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-1-5);
  padding: var(--spacing-1) var(--spacing-4) var(--spacing-2);
}

.lsh-table-toolbar-chips[hidden] {
  display: none;
}

/* Single filter chip — Figma node 2290:11432 */
.lsh-table-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-1);
  padding: var(--spacing-0-5) var(--spacing-1) var(--spacing-0-5) var(--spacing-2);
  background: var(--bg-brand-primary-alt);
  border: 1px solid var(--brand-300);
  border-radius: var(--radius-xs);
  color: var(--text-brand-primary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  font-family: inherit;
  cursor: pointer;
  transition: background 100ms ease;
}

.lsh-table-filter-chip:hover {
  background: var(--bg-brand-primary);
}

.lsh-table-filter-chip:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
}

.lsh-table-filter-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-xxs);
  color: inherit;
  font-size: 10px;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 100ms ease, background 100ms ease;
}

.lsh-table-filter-chip-x:hover {
  opacity: 1;
  background: rgba(78, 101, 158, 0.15);  /* --brand-700 @ 15% — no transparency token */
}

/* Clear-all link */
.lsh-table-filter-clear-all {
  margin-left: var(--spacing-1);
  padding: 0 var(--spacing-1);
  border: none;
  background: transparent;
  color: var(--text-brand-primary);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  font-family: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  opacity: 0.75;
}

.lsh-table-filter-clear-all:hover {
  opacity: 1;
}

.lsh-table-filter-clear-all:focus-visible {
  outline: 2px solid var(--border-brand);
  outline-offset: 1px;
  opacity: 1;
}

/* ============================================================
   Phase 4 — Density-scaling (Sm + Lg overrides for toolbar)
   Default Md needs no override — base rules above are Md.
   ============================================================ */

/* ── Density: Sm (tight) ── */
.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-title-row {
  padding: var(--spacing-1-5) var(--spacing-3);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-title {
  font-size: var(--font-size-md);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-action-btn {
  width: 22px;
  height: 22px;
  font-size: var(--font-size-xs);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-tabs {
  padding: 0 var(--spacing-3);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-tabs .tab {
  padding: var(--spacing-1) var(--spacing-2-5);
  font-size: var(--font-size-xs);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-filters {
  padding: var(--spacing-1-5) var(--spacing-3);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-filter-btn {
  padding: var(--spacing-0-5) var(--spacing-2);
  font-size: var(--font-size-xs);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-filter-icon-btn {
  width: 24px;
  height: 24px;
  font-size: var(--font-size-xs);
}

.lsh-table-shell[data-density="sm"] .lsh-table-toolbar-chips {
  padding: var(--spacing-0-5) var(--spacing-3) var(--spacing-1-5);
}

.lsh-table-shell[data-density="sm"] .lsh-table-selection-bar {
  padding: var(--spacing-0-5) var(--spacing-3);
}

/* ── Density: Lg (spacious) ── */
.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-title-row {
  padding: var(--spacing-3) var(--spacing-5);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-title {
  font-size: var(--font-size-xl);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-action-btn {
  width: 32px;
  height: 32px;
  font-size: var(--font-size-md);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-tabs {
  padding: 0 var(--spacing-5);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-tabs .tab {
  padding: var(--spacing-2-5) var(--spacing-4);
  font-size: var(--font-size-md);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-filters {
  padding: var(--spacing-3) var(--spacing-5);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-filter-btn {
  padding: var(--spacing-1-5) var(--spacing-3);
  font-size: var(--font-size-md);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-filter-icon-btn {
  width: 32px;
  height: 32px;
  font-size: var(--font-size-md);
}

.lsh-table-shell[data-density="lg"] .lsh-table-toolbar-chips {
  padding: var(--spacing-1-5) var(--spacing-5) var(--spacing-2-5);
}

.lsh-table-shell[data-density="lg"] .lsh-table-selection-bar {
  padding: var(--spacing-1-5) var(--spacing-5);
}

/* ============================================================
   Phase 4 — Selection bar inside shell (strip margin + radius)
   Phase 2 standalone usage (no shell) renders unchanged.
   ============================================================ */

/* When the selection bar lives inside a shell, lose its margin + radius
   so it sits flush below filters/chips and above the table head.
   Default Md padding (4px 16px per Figma node 3549:178614) — Sm + Lg
   density variants are defined in the density section above. */
.lsh-table-shell > .lsh-table-selection-bar {
  margin: 0;
  border-radius: 0;
  padding: var(--spacing-1) var(--spacing-4);
}

/* ─── Column reorder (engine: js/tables-cols-reorder.js + js/sortable-list.js) ───
   Tables-specific overrides for the generic sortable-list handle visual.
   The cols-visibility menu's items are .dropdown-item--checkbox; the
   generic primitive injects a .sortable-list-handle as the last child of
   each. We scope tables overrides to that menu so unrelated sortable
   lists on the page keep the generic visual. */

.lsh-table-wrap .dropdown-menu[role="menu"] .dropdown-item--checkbox {
  position: relative;
  /* Reserve space on the right edge for the handle so its hover-reveal
     doesn't shift the label. */
  padding-right: 36px;
}

.lsh-table-wrap .dropdown-menu[role="menu"] .sortable-list-handle {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  font-size: var(--font-size-sm);
}

/* Tighter drop indicator inside the narrow menu — 2 px brand line is fine,
   but tuck it slightly inset so it doesn't clash with the menu's border-
   radius corners. */
.lsh-table-wrap .dropdown-menu[role="menu"] .is-sortable-drop-above::before,
.lsh-table-wrap .dropdown-menu[role="menu"] .is-sortable-drop-below::after {
  left: 6px;
  right: 6px;
}

