/*
 * Critical index-table shell styles.
 *
 * These mirror the Tailwind component primitives so operational table screens
 * keep a Shopify/Stripe-style surface even when the generated Tailwind bundle
 * is stale in a deployed browser cache.
 *
 * Tokenised against design-variables.css: colours come from --theme-* tokens
 * that auto-flip for dark, so this file no longer carries a parallel hardcoded
 * dark palette. `.dark` overrides remain ONLY where a surface needs a different
 * contrast MECHANISM per theme (the active view-tab inverts to a dark pill in
 * light — white is the ceiling, it can't lift — but raises to an elevated pill
 * in dark; the inactive count badge needs a visible fill on the dark toolbar).
 */

.wm-index-surface {
  overflow: hidden;
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-lg, 0.5rem);
  background: var(--theme-card-bg);
  /* Hairline border only — no card shadow (design system). */
}

.wm-index-surface > .overflow-x-auto {
  width: 100%;
  -webkit-overflow-scrolling: touch;
  scrollbar-gutter: stable;
}

.wm-index-surface > .overflow-x-auto::-webkit-scrollbar {
  height: 0.5rem;
}

.wm-index-surface > .overflow-x-auto::-webkit-scrollbar-track {
  background: transparent;
}

.wm-index-surface > .overflow-x-auto::-webkit-scrollbar-thumb {
  border-radius: 9999px;
  background: var(--theme-scrollbar-thumb);
}

.wm-index-surface > .overflow-x-auto::-webkit-scrollbar-thumb:hover {
  background: var(--theme-scrollbar-thumb-hover);
}

:where(.wm-data-table) {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--wm-type-body);
  line-height: 1.25rem;
}

:where(.wm-data-table thead) {
  background: var(--theme-card-bg);
}

:where(.wm-data-table thead th) {
  padding: 0.75rem 1rem;
  /* Zero-specificity (:where) so a bare <th> aligns left to match its cells —
     the browser default for <th> is center, which would misalign headers once
     the per-th `text-left` utility is removed. `.text-right` / `.text-center`
     utility classes (specificity 0,1,0) still override this. */
  text-align: left;
  color: var(--theme-text-secondary);
  font-size: var(--wm-type-label);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1rem;
  text-transform: none;
  vertical-align: middle;
  white-space: nowrap;
}

:where(.wm-data-table tbody td) {
  border-top: 1px solid var(--border-divider);
  padding: 0.875rem 1rem;
  color: var(--theme-text);
  vertical-align: top;
}

:where(.wm-data-table tbody tr:first-child td) {
  border-top: 0;
}

:where(.wm-data-table tbody tr) {
  transition: background-color 150ms ease, box-shadow 150ms ease;
}

:where(.wm-data-table tbody tr:hover) {
  background: var(--theme-hover);
}

:where(.wm-data-table tbody tr:focus-within) {
  /* bg-tint only — no colored left-rail (design system: no active rails). */
  background: var(--tint-brand-05);
}

:where(.wm-data-table tfoot td) {
  border-top: 1px solid var(--theme-border);
  padding: 0.75rem;
  color: var(--theme-text);
  font-weight: 600;
}

:where(.wm-data-table-compact thead th),
:where(.wm-data-table-compact tbody td) {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

:where(.wm-data-num) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ── Dense KPI strip ──────────────────────────────────────────────────
   The shared "new" KPI treatment, mirroring the dashboard/Reports rep-kpi
   pattern. Replaces the old Operations-page strip — a fixed `grid-cols-4`
   of `wm-card` + `kpi_stat(compact)` boxes that stretched full-width into
   wide, airy cards. auto-fit + minmax packs 6–7 narrow cards per row;
   tight padding, mono uppercase label, 22px display value. Raw CSS (no
   Tailwind build), so it renders on the live site directly. */
.wm-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  grid-auto-flow: dense;
  gap: var(--space-3, 0.75rem);
  align-items: start;
}
.wm-kpi {
  background: var(--theme-card-bg);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 0.5rem);
  padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
  min-width: 0;
}
.wm-kpi-label {
  color: var(--theme-text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wm-kpi-value {
  margin-top: 4px;
  font-family: var(--font-family-heading);
  font-size: var(--wm-type-body);
  font-weight: 500;
  line-height: 1.05;
  color: var(--theme-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.wm-kpi-value.is-pos {
  color: var(--success-text);
}
.wm-kpi-value.is-warn {
  color: var(--warning-text);
}
.wm-kpi-value.is-danger {
  color: var(--danger-text);
}
@media (max-width: 720px) {
  .wm-kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2, 0.5rem);
  }
  .wm-kpi-value {
    font-size: var(--wm-type-body);
  }
}

/* Mobile: reflow wm-data-table to stacked cards — no horizontal scroll on a
   phone. Cells are self-describing, so no per-<td> data-label needed; cascades
   to every wm-data-table page (orders, admin, partnerships, …). */
/* 767px, not 640: the mobile shell (bottom tab bar, md:hidden topbar) runs
   to 768; between 641 and 767 the legacy tables stayed tables and clipped —
   the same shell-breakpoint bug the v2 families had. */
@media (max-width: 767px) {
  /* A two-word KPI label clipped to "AVAILABLE VEHICL…" in a half-width
     tile; on phones the label wraps instead of hiding its meaning. */
  .wm-kpi-label { white-space: normal; overflow: visible; text-overflow: clip; }
  .wm-index-surface > .overflow-x-auto { overflow-x: visible; }
  .wm-data-table { display: block; }
  .wm-data-table thead { display: none; }
  .wm-data-table tbody { display: block; }
  .wm-data-table tbody tr {
    display: block;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md, 0.375rem);
    background: var(--theme-card-bg);
    padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
    margin-bottom: var(--space-3, 0.75rem);
  }
  .wm-data-table tbody td {
    display: block;
    padding: 0;
    text-align: left;
    white-space: normal;
  }
  /* Hairline separators between stacked cells so a label-less mobile card
     reads as distinct fields instead of one run-together block (the airy/
     ambiguous "Recent Orders" card bug). The first cell carries the row's
     primary content and needs no rule above it; empty cells collapse so they
     don't leave a phantom separated line. Cascades to all wm-data-table pages. */
  .wm-data-table tbody td + td {
    /* Measured 2026-09-02 on /fleet at 390: 12px + 12px per cell put one
       driver at ~500px — five fields, four dividers. 8px + 8px keeps the
       separators (the fields are label-less) and takes ~30px off each card. */
    margin-top: var(--space-2, 0.5rem);
    padding-top: var(--space-2, 0.5rem);
    border-top: 1px solid var(--border-divider);
  }
  .wm-data-table tbody td:empty { display: none; }
}

/* MEASURED, then reverted — do not re-add without new numbers.
   Tightening the stacked-card spacing for .wm-data-table-compact (halved
   separator gap and card padding) was tried here on 2026-08-01. Measured on
   Inventory's low-stock row at 390px: 309px → 289px. Twenty pixels, 6%, in
   exchange for a special-case rule inherited by 22 templates. Not worth it.

   It was proposed on the strength of "~570px per row", which was wrong: that
   figure was read off a 2×-DPR screenshot, so device pixels were mistaken for
   CSS pixels and the problem was double its real size. Measure in the page,
   not off the image.

   The rows ARE too tall — 289px for four fields — but the cost is content, not
   spacing: every cell gets a full-width line, and Inventory spends one of them
   on "No SKU". Fixing that means deciding per table which fields earn a line on
   a phone, which a shared rule cannot guess. */

/* ── Cell text helpers ────────────────────────────────────────────────
   Token-driven replacements for the per-cell Tailwind color utilities
   (`text-gray-900 dark:text-white`, `text-gray-500 dark:text-gray-400`)
   that used to be hand-written on every table cell. Defined once here so
   every wm-data-table consumer cascades to the correct light/dark color
   without sprinkling `dark:` variants in the markup. */
.wm-cell-strong {
  color: var(--theme-text);
  font-weight: 500;
}
.wm-cell-sub {
  color: var(--theme-text-secondary);
  font-size: var(--wm-type-label);
  line-height: 1rem;
}
.wm-cell-sub-mono {
  font-family: var(--font-family-mono);
  font-variant-numeric: tabular-nums;
}
.wm-cell-warn {
  color: var(--warning-text);
}

/* ── Generic token text-color helpers ────────────────────────────────
   Light/dark-correct text colors WITHOUT `dark:` Tailwind variants, for
   use anywhere (tables, forms, detail pages). Replace the old
   `text-gray-900 dark:text-white` / `text-warning-700 dark:text-warning-300`
   pairs. Primary text is already the token default, so there is no
   `.wm-t` — just drop the utility to inherit primary. */
.wm-t {
  color: var(--theme-text);
}
.wm-t-sub {
  color: var(--theme-text-secondary);
}
.wm-t-mut {
  color: var(--theme-text-tertiary);
}
.wm-t-ok {
  color: var(--success-text);
}
.wm-t-bad {
  color: var(--danger-text);
}
.wm-t-warn {
  color: var(--warning-text);
}
.wm-t-info {
  color: var(--info, var(--brand-primary));
}
.wm-t-brand {
  color: var(--brand-text);
}

/* ── Token surface helpers ───────────────────────────────────────────
   Replace hand-written `bg-gray-50 dark:bg-slate-800/60` panel chrome and
   `divide-gray-100 dark:divide-slate-700` dividers with token-driven
   surfaces that are correct in both themes without `dark:` variants. */
.wm-panel-head {
  background: var(--theme-bg-secondary);
  border-bottom: 1px solid var(--border-subtle);
}
.wm-divide-tok > * + * {
  border-color: var(--border-subtle);
}
.wm-track {
  background: var(--theme-bg-tertiary);
}

/* Soft semantic tints — replace `bg-info-50 dark:bg-info-900/20` style pairs.
   Solid fallback first, color-mix override for modern browsers; both stay
   theme-correct because they mix against the live card surface token. */
.wm-tint-info {
  background: #eff6ff;
  background: color-mix(in srgb, var(--info) 12%, var(--theme-card-bg));
}
.wm-tint-ok {
  background: #ecfdf5;
  background: color-mix(in srgb, var(--success) 12%, var(--theme-card-bg));
}
.wm-tint-warn {
  background: #fffbeb;
  background: color-mix(in srgb, var(--warning) 14%, var(--theme-card-bg));
}
.wm-tint-bad {
  background: #fff1f2;
  background: color-mix(in srgb, var(--danger) 12%, var(--theme-card-bg));
}
.wm-bordered {
  border: 1px solid var(--border-subtle);
}

/* ── page_tip — calm, on-brand first-run explainer ───────────────────
   Replaces the old hardcoded blue Bootstrap-alert look (bg-blue-50 etc.),
   which clashed with the monochrome + single-brand-accent v2 system. Faint
   brand wash, hairline border, brand only on the icon + link; text stays
   monochrome (theme tokens). color-mix auto-adapts to light/dark. */
.wm-tip {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 1rem;
  padding: 0.875rem 2.25rem 0.875rem 1rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 0.5rem);
  background: #f7f7fb;
  background: color-mix(in srgb, var(--brand-primary) 5%, var(--theme-card-bg));
}
.wm-tip-icon {
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: var(--wm-type-icon);
  color: var(--brand-text);
  background: #ecebff;
  background: color-mix(in srgb, var(--brand-primary) 12%, transparent);
}
.wm-tip-title {
  font-size: var(--wm-type-body);
  font-weight: 600;
  color: var(--theme-text);
}
.wm-tip-body {
  margin-top: 2px;
  font-size: var(--wm-type-body);
  line-height: 1.5;
  color: var(--theme-text-secondary);
}
.wm-tip-link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.5rem;
  font-size: var(--wm-type-label);
  font-weight: 500;
  color: var(--brand-text);
}
.wm-tip-link:hover {
  text-decoration: underline;
}
.wm-tip-dismiss {
  position: absolute;
  top: 0.625rem;
  right: 0.625rem;
  padding: 0.25rem;
  line-height: 1;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--theme-text-tertiary);
  transition: color 150ms ease;
}
/* The whole button is 0.25rem of padding around a 12px glyph — about 20x20,
   under the 24px minimum target size, and the only control in the app that is.
   Every other icon-only button here is 40x40 (`.sf-btn-xs`, `.sf-icon-btn`,
   `.sfx-icon-btn`, the storefront pager), so this is that standard applied to
   the one that missed it.

   Grown with a pseudo-element rather than min-width/min-height, because the
   button is absolutely positioned in the corner of the tip: a real 40x40 box
   would push the glyph down and left and change a layout that is otherwise
   fine. The ::after inherits the button's hit testing, so the target is 40x40
   while the icon stays exactly where it was. */
.wm-tip-dismiss::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 40px;
  height: 40px;
  transform: translate(-50%, -50%);
}
.wm-tip-dismiss:hover {
  color: var(--theme-text);
}

.wm-index-toolbar {
  border-bottom: 1px solid var(--theme-border);
  background: var(--theme-card-bg);
}

.wm-index-views {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  overflow-x: auto;
  padding: 1rem 1rem 0;
  scrollbar-width: thin;
}

.wm-index-view-tab {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: 0.5rem;
  min-height: 2rem;
  border-radius: var(--radius-md);
  padding: 0 0.75rem;
  font-size: var(--wm-type-body);
  font-weight: 500;
  line-height: 1.25rem;
  text-decoration: none;
  transition: background-color 150ms ease, color 150ms ease, box-shadow 150ms ease;
}

.wm-index-view-tab:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}

/* Active tab: light inverts to a solid dark pill (white is the ceiling, it
   cannot lift); dark raises to an elevated pill instead — hence the .dark rule. */
.wm-index-view-tab-active {
  background: var(--theme-text);
  color: var(--theme-text-inverted);
}

.dark .wm-index-view-tab-active {
  background: var(--theme-bg-elevated);
  color: var(--theme-text);
}

.wm-index-view-tab-inactive {
  color: var(--theme-text-secondary);
}

.wm-index-view-tab-inactive:hover {
  background: var(--theme-hover);
  color: var(--theme-text);
}

.wm-index-view-count {
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.15);
  padding: 0.125rem 0.375rem;
  font-size: var(--wm-type-label);
  font-weight: 600;
  line-height: 1rem;
  font-variant-numeric: tabular-nums;
}

.wm-index-view-tab-inactive .wm-index-view-count {
  background: var(--theme-bg-tertiary);
  color: var(--theme-text-tertiary);
}

/* Inactive count badge needs a visible fill on the dark toolbar (bg-tertiary
   equals the card there, so it would vanish). */
.dark .wm-index-view-tab-inactive .wm-index-view-count {
  background: var(--theme-border-strong);
  color: var(--theme-text-secondary);
}

.wm-index-filter-bar {
  display: grid;
  gap: 0.75rem;
  padding: 1rem;
}

.wm-index-search {
  position: relative;
  min-width: 0;
  flex: 1 1 auto;
}

.wm-index-search .wm-input,
.wm-index-search input {
  width: 100%;
}

.wm-index-search-icon {
  pointer-events: none;
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--theme-text-tertiary);
}

.wm-index-filter-controls,
.wm-index-filter-actions {
  align-items: center;
  gap: 0.5rem;
}

.wm-index-filter-controls {
  display: grid;
  /* 9rem (144px), not 10rem. This rule — not the Tailwind component of the
     same name — is the one in effect: with a 160px minimum, two selects plus
     the 8px gap need 328px and a phone's filter box is 316px, so auto-fit fell
     back to ONE column and Orders stacked three selects into 130px above the
     order list. 144px fits two (2x144+8 = 296 <= 316) and still yields three
     columns wherever there is room for them. */
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  min-width: 0;
}

.wm-index-filter-actions {
  display: flex;
  flex-wrap: wrap;
}

.wm-index-filter-controls .wm-input,
.wm-index-filter-controls select {
  width: 100%;
  min-width: 0;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: var(--wm-type-body);
  line-height: 1.25rem;
}

.wm-index-active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  border-top: 1px solid var(--theme-border);
  background: var(--theme-bg-secondary);
  padding: 0.5rem 1rem;
  font-size: var(--wm-type-label);
  line-height: 1rem;
}

/* Chip is one surface step above the secondary-tinted filter bar it sits on, in
   both themes (card-bg > bg-secondary), so it reads without a per-theme rule. */
.wm-index-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  border: 1px solid var(--theme-border);
  border-radius: 9999px;
  background: var(--theme-card-bg);
  padding: 0.25rem 0.625rem;
  color: var(--theme-text-secondary);
  font-weight: 500;
  /* hairline border only (line above) — no pill shadow (no-card-shadows). */
}

.wm-index-selection-bar {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  border-bottom: 1px solid var(--theme-border);
  background: var(--theme-bg-secondary);
  padding: 1rem;
  transition: background-color 150ms ease;
}

/* An author `display` beats the UA stylesheet's `[hidden] { display: none }`,
   so the bar rendered at full height with the attribute set — 180px of "0
   orders selected / Selected orders cannot move to one shared next status" on
   every visit to Orders, pushing the first order further down a phone screen.
   The idx-* family already guards this exact trap
   (`.idx-bulk-bar[hidden]`, `.idx-grid-bar[hidden]`, index_v2.css:291); the
   wm- variant simply never got it. Same pattern, same file convention.

   Any element that both carries `hidden` and sets `display` needs this — the
   attribute alone is not enough once you style the element. */
.wm-index-selection-bar[hidden] { display: none; }

.wm-index-selection-bar-active {
  background: var(--tint-brand-05);
}

.wm-index-selection-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--theme-text-secondary);
  font-size: var(--wm-type-body);
  font-weight: 500;
  line-height: 1.25rem;
}

.wm-index-selection-count {
  display: inline-flex;
  min-width: 2rem;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: var(--theme-card-bg);
  padding: 0.25rem 0.5rem;
  color: var(--theme-text);
  font-size: var(--wm-type-body);
  font-weight: 600;
  line-height: 1.25rem;
  box-shadow: inset 0 0 0 1px var(--theme-border);
}

.wm-index-table {
  min-width: 100%;
}

.wm-index-table thead th {
  border-bottom: 1px solid var(--theme-border);
  padding: 0.75rem 1rem;

  vertical-align: middle;
}

.wm-index-table tbody td {
  padding: 0.75rem 1rem;
  vertical-align: top;
}

.wm-index-table.wm-data-table-compact thead th,
.wm-index-table.wm-data-table-compact tbody td {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.wm-index-table tbody tr[data-href] {
  cursor: pointer;
}

.wm-index-empty {
  border-top: 1px solid var(--theme-border);
  background: var(--theme-card-bg);
}

/* See .idx-empty in pages/index_v2.css — same centred-in-a-bounded-block
   treatment for the legacy index-table shell. */
.wm-index-empty > .text-center {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

@media (min-width: 640px) {
  .wm-index-filter-actions {
    justify-content: flex-end;
  }
}

@media (min-width: 1024px) {
  .wm-index-selection-bar {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

/* ─── Laptop widths (768–1180px) beside the sidebar ─────────────────────────
   The legacy tables (alerts, drivers, …) carry 6–7 nowrap columns and no
   per-page priority hook; at 1024 they overflowed by 84–120px, hiding the
   "Next step" action behind the overlay scrollbar. Tighter cells and a
   smaller type step recover ~130px across seven columns without deciding
   which column yields — the v2 families do that per page; here the family
   is on its way out (38 templates) and a padding rule is the honest fix. */
@media (min-width: 768px) and (max-width: 1180px) {
  .wm-data-table thead th,
  .wm-data-table tbody td { padding-left: 0.4rem; padding-right: 0.4rem; }
  .wm-data-table tbody td { font-size: var(--wm-type-body); }
  .wm-data-table .wm-table-action-link { white-space: nowrap; }
}

/* Supporting information stays available without preceding the current task. */
.wm-workspace-summary {
  margin-block: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--theme-card-bg);
  color: var(--theme-text);
  min-width: 0;
}
.wm-workspace-summary > summary {
  cursor: pointer;
  padding: var(--space-3) var(--space-4);
  min-height: 44px;
  font-size: var(--wm-type-body);
  font-weight: 600;
}
.wm-workspace-summary > summary:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
.wm-workspace-summary > :is(.idx-kpi-grid, .rep-kpi-grid, .wm-kpi-grid, .grid) { padding: var(--space-3); margin: 0; }
.wm-workspace-summary:not([open]) > :not(summary) { display: none; }
/* Native tables retain one consistent typographic hierarchy across dashboards. */
.wm-index-table tbody tr:focus-within { background-color: var(--theme-hover); }
.wm-index-table tbody td { font-variant-numeric: tabular-nums; }
.wm-workspace-summary > .idx-kpi-grid { border: 0; }
