/* ─────────────────────────────────────────────────────────────────────
   Shared component layer — header band + toolbar primitives.

   Consolidates two patterns that were previously repeated as inline class
   strings / duplicated page-scoped CSS across the app:

   1. `.dv-page-band` — the full-bleed white header band that sits at the top
      of (and between sections of) every index/detail page. Previously every
      band was written inline as
        `bg-surface border-b border-hairline dv-full-bleed …`
      on the wrapper div. This sheet folds the three shared invariants
      (surface background, bottom hairline, full-bleed horizontal breakout)
      into one named class.

      IMPORTANT — parity note: the *vertical* padding of each band is NOT
      uniform across pages (head bands use `-mt-10 pt-8 pb-6`, stat strips use
      `py-[22px]` on Today but `py-[18px]` on Dives, toolbars use `py-2` or
      `py-3`, and the bookings tab nav supplies its own padding via
      `.page-tabs`). To guarantee ZERO visual change, `.dv-page-band` owns ONLY
      the shared invariants; callers KEEP their existing per-band padding /
      margin Tailwind utilities. No `--head` / `--stats` padding modifiers are
      defined because that would force a single padding value and shift pixels
      on pages that use a different one.

   2. `.dv-toolbar`, `.dv-divider`, `.chip` (+ `.is-on` / `.count`) — toolbar
      filter primitives that were duplicated byte-for-byte in
      `account/divers.css` and `account/team.css`. Promoted here so both pages
      (and any future page) consume one canonical definition.

   Token-driven; consumes the semantic aliases from tokens.css. Loaded after
   patterns.css (see application.css). The full-bleed breakout reuses the EXACT
   same calc as `.dv-full-bleed` in dashboard.css — keep them in sync.
   ───────────────────────────────────────────────────────────────────── */

/* ── Page band (full-bleed white header band) ─────────────────────────
   Shared invariants only. Callers add their own vertical padding/margin
   utilities (e.g. `-mt-10 pt-8 pb-6`, `py-[18px]`, `py-[22px]`, `py-2`,
   `py-3`) to preserve each band's exact rhythm.

   The horizontal breakout duplicates `.dv-full-bleed` (dashboard.css): it
   extends the band to the .diveos-main edges, then re-insets its content to
   the centered column. Because this is baked in, callers no longer need to
   add `dv-full-bleed` alongside `.dv-page-band`. */
.dv-page-band {
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  margin-left:  min(-48px, calc(712px - 50vw));
  margin-right: min(-48px, calc(712px - 50vw));
  padding-left:  max(48px, calc(50vw - 712px));
  padding-right: max(48px, calc(50vw - 712px));
}

/* ── Toolbar (filter chips + search) ──────────────────────────────────
   Promoted from account/divers.css + account/team.css (identical copies). */
/* ── Page-band typography — canonical h1, h2, sub-copy ───────────────
   Every page header h1 inside .dv-page-band inherits the WL-exact style
   automatically. Views just write <h1>Title</h1> — no Tailwind utilities
   needed on the element. Same for the muted sub-copy <p>. */
.dv-page-band h1 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.025em;
  color: var(--ink);
}

.dv-page-band h1 + p,
.dv-page-band .page-sub-copy {
  font-size: var(--text-sm);
  color: var(--muted);
  margin-top: 4px;
}

.dv-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Vertical separator between chip groups inside a toolbar. */
.dv-toolbar .dv-divider {
  width: 1px;
  height: 22px;
  background: var(--hairline);
  margin: 0 4px;
  flex-shrink: 0;
}

/* ── Chip (filter pill) ───────────────────────────────────────────────
   Promoted from account/divers.css + account/team.css (identical copies). */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background 150ms ease-out, border-color 150ms ease-out;
}
.chip:hover { background: var(--canvas); }
.chip.is-on {
  background: var(--accent-soft);
  border-color: var(--accent-border);
  color: var(--accent);
}
.chip .count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted);
  margin-left: 2px;
}
.chip.is-on .count { color: var(--accent); }

/* ─────────────────────────────────────────────────────────────────────
   Shared index-page primitives — page header, search box, table wrap.

   Previously duplicated byte-for-byte in account/divers.css and
   account/team.css (and consumed by account/gear.css + account/fleet.css).
   Promoted here so the canonical definition lives in one place and the next
   `thead th`-style correction only has to happen once. Loaded before all
   account/* page sheets, so page-scoped variants (e.g. team grouped-row
   rules) still cascade on top. ZERO visual change vs the duplicated copies.
   ───────────────────────────────────────────────────────────────────── */

/* ── Search box ───────────────────────────────────────────────────── */
.search-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 32px;
}
.search-wrap svg,
.search-wrap [data-lucide] {
  position: absolute;
  left: 10px;
  width: 14px;
  height: 14px;
  color: var(--muted-2);
  pointer-events: none;
}
.search-wrap input {
  width: 100%;
  height: 32px;
  padding: 0 10px 0 30px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  color: var(--ink);
}
.search-wrap input::placeholder { color: var(--muted-2); }
.search-wrap input:focus {
  outline: none;
  border-color: var(--hairline-strong);
}

/* ── Table wrap ───────────────────────────────────────────────────── */
.dv-table-wrap {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.dv-table-wrap table {
  min-width: 100%;
  border-collapse: collapse;
}
.dv-table-wrap thead tr {
  background: var(--canvas);
  border-bottom: 1px solid var(--hairline);
}
.dv-table-wrap thead th {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-600);  /* WL table-header color (#4B5563); was --muted (gray-500), one step too light */
}
.dv-table-wrap tbody tr { border-bottom: 1px solid var(--hairline-2); }
.dv-table-wrap tbody tr:last-child { border-bottom: none; }
.dv-table-wrap tbody tr:hover { background: var(--sky-50); }
/* Row/cell links (often dv_link_to names) shouldn't underline on hover inside
   a table — the row hover tint is the affordance; underline reads as noise. */
.dv-table-wrap td a:hover,
.box-table td a:hover { text-decoration: none; }
/* Default cell rhythm — list-table rows are 1rem (16px = --space-4) top+bottom.
   This OVERRIDES per-cell py-* utilities (specificity 0,1,1 > a plain .py-3),
   so the row height is uniform across every list table from the component, not
   from scattered per-cell classes. Dense embedded sub-tables opt out with
   .dv-table--compact (8px). */
.dv-table-wrap td { padding-top: var(--space-4); padding-bottom: var(--space-4); }
.dv-table-wrap.dv-table--compact td,
.dv-table--compact .dv-table-wrap td { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.dv-table-wrap td:first-child,
.dv-table-wrap th:first-child { padding-left: 16px; }
.dv-table-wrap td:last-child,
.dv-table-wrap th:last-child { padding-right: 16px; }
/* The Bullet Train bulk-actions theme ($ThemeStylesheet) leaks
   `.bulk-actions:not(.selectable) th:nth-child(2) { padding-left: 2rem }` — its
   sticky "identity column" inset — onto OUR .dv-table-wrap headers (BT wraps
   index tables in .bulk-actions). That over-pads the 2nd-column header so its
   label no longer sits above its data column (esp. visible on reorderable
   tables where col 2 is the Name). Reset it to the canonical px-3 (12px) gutter
   so headers align with their cells. The leak is (0,3,1) (.bulk-actions +
   :not(.selectable) + th + :nth-child), so we match the .bulk-actions ancestor
   too — (0,3,2) — to win without !important. */
.bulk-actions .dv-table-wrap thead th:nth-child(2) { padding-left: var(--space-3); }
/* The SAME BT leak also lands on the BODY cell:
   `.bulk-actions:not(.selectable) td:nth-child(2) { padding-left: 1.25rem }` (20px)
   over-pads the 2nd-column <td> so the row content (e.g. the Name/Slug link) sits
   8px to the right of its header label (which we pin to 12px above). Reset the td
   to the canonical px-3 (12px) gutter so header text sits directly above row text.
   Leak is (0,3,1); we match the .bulk-actions ancestor + .dv-table-wrap to win
   at (0,3,2) without !important. */
.bulk-actions .dv-table-wrap tbody td:nth-child(2) { padding-left: var(--space-3); }

/* Reorderable tables (drag-handle first column). The leading handle cell is a
   narrow grip, not real content — the first-child 16px inset would push the
   whole table in past the canonical 12px (px-3) gutter and, on the header,
   misalign the labels against their data columns. Pin both the handle <td> and
   its matching leading <th> to 12px so the table's left content lines up at the
   canonical gutter, header above row. */
.dv-table-wrap:has(tbody [data-sortable-target="handle"]) th:first-child,
.dv-table-wrap:has(tbody [data-sortable-target="handle"]) td:first-child { padding-left: var(--space-3); }

/* ── Box table ────────────────────────────────────────────────────────
   The shared themes/light/_box partial already supplies a bordered
   surface card. So `box.table` tables get the canonical .dv-table-wrap
   LOOK (canvas header band, uppercase 10px th, 12px td rhythm, hairline
   rows, hover surface-alt) WITHOUT a second outer border/radius. Mirrors
   the thead/td/hover rules above; intentionally omits the .dv-table-wrap
   outer border + radius (the box owns that chrome). */
.box-table table { min-width: 100%; border-collapse: collapse; }
.box-table thead tr {
  background: var(--canvas);
  border-bottom: 1px solid var(--hairline);
}
.box-table thead th {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-600);
}
.box-table tbody tr { border-bottom: 1px solid var(--hairline-2); }
.box-table tbody tr:last-child { border-bottom: none; }
.box-table tbody tr:hover { background: var(--sky-50); }
.box-table td { padding-top: var(--space-4); padding-bottom: var(--space-4); }
.box-table td:first-child,
.box-table th:first-child { padding-left: 16px; }
.box-table td:last-child,
.box-table th:last-child { padding-right: 16px; }

/* ════════════════════════════════════════════════════════════════════════
   Unified list/index page header (WL handoff — "header-applied-boards").
   ONE general header: row 1 .dv-page-head (title + actions) · row 2
   .dv-page-tools (scope tabs + facet chips + trailing). Replaces the old
   multi-band .dv-page-band stack. Reuses .dv-btn*, .search-wrap, .chip.
   Scope tabs = mutually-exclusive segmentation (one .is-on); chips = facets.
   ════════════════════════════════════════════════════════════════════════ */
/* Row 1 — title bar. White, full-bleed to the pane edges (same calc as
   .dv-full-bleed / .dv-page-band — keep in sync), bleeding up through
   .diveos-content's 40px top padding so the white starts at the pane top. */
.dv-page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  margin-top: calc(-1 * var(--shell-pad-top, 40px));
  margin-left:  min(-48px, calc(712px - 50vw));
  margin-right: min(-48px, calc(712px - 50vw));
  padding: 32px max(48px, calc(50vw - 712px)) 18px;
}
/* Mobile (<1023px): the fixed hamburger (top-left, 12px inset, 44px tall →
   bottom edge ~56px) sits over the band's top-left content. The breadcrumb is
   the first thing in the band (y≈32) and clipped under it ("Catalog" → "…g").
   Push the whole header content clear of the button so breadcrumb AND title
   (on no-breadcrumb pages) start below it. Desktop has no hamburger. */
@media (max-width: 1023px) {
  .dv-page-head, .dv-page-band { padding-top: 72px; }
  /* The fixed hamburger (left 12–56px) also overlaps the STICKY .dv-page-tools
     row once it sticks to the top on scroll (its scope tabs start at ~48px and
     clip under the button — "Active 4" → "e 4"). Reserve a left gutter so the
     tabs clear it and the hamburger reads as part of the sticky bar. */
  .dv-page-tools { padding-left: 64px; }
}
.dv-page-head h1,
h1.dv-page-head__title {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 0;
}
.dv-page-head__sub { font-size: var(--text-sm); color: var(--muted); margin-top: 4px; }
.dv-page-head__actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* Optional breadcrumb inside the head band (Settings/catalogue pages). It sits
   at the top of the title block, above the <h1>. The breadcrumb component is
   margin-free, so the band owns this gap — keeps the breadcrumb IN the header
   band (no stray wrapper div per page). */
.dv-page-head .dv-breadcrumb { margin-bottom: 10px; }

/* Row 2 — scope / tools bar. White, full-bleed (matches row 1).
   Sticky: the scope/tools row pins to the top on scroll (the title row above
   scrolls away under it), so the filters stay reachable down a long list. */
.dv-page-tools {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
  margin-left:  min(-48px, calc(712px - 50vw));
  margin-right: min(-48px, calc(712px - 50vw));
  padding: 12px max(48px, calc(50vw - 712px));
  position: sticky;
  top: 0;
  z-index: 20;
}
/* Body gap — consistent 2rem between a page header and the content below,
   ACROSS ALL ARCHETYPES (#75). The list header is two full-bleed rows:
   row-1 `.dv-page-head`, optional row-2 `.dv-page-tools`; content follows
   whichever is last, the two header rows stay flush. Show/edit/form pages use
   `.page-header` (form/settings header) or a bare `.dv-page-band` (e.g.
   booking show) — those got no top gap before, so the first body element
   stacked flush against the header. The selectors below give every archetype
   the same 2rem gap. padding-top: 0 neutralises `pt-*` on content wrappers so
   the gap is exactly 2rem everywhere.

   Note: `.hero-show__band` (entity show pages) owns its own margin-bottom:2rem
   in patterns.css, so it is intentionally NOT matched here.

   We key the show/edit/form gap on `.page-header` (the form/settings header,
   which is `.dv-page-band.page-header`), NOT on a bare `.dv-page-band`. A bare
   band (e.g. booking show) is followed by a control-row WRAPPER — the
   `tab-panel` controller div that holds the band-2 tab nav — and that wrapper
   must stay flush; its internal nav→panel spacing lives in bookings.css. So a
   bare-`.dv-page-band` selector wrongly pushed the tab nav down 2rem (#75
   regression) and is deliberately absent.

   The `.dv-page-head` row excludes `form:has(> .dv-page-tools)` because a list's
   filter bar is often wrapped in a search `<form>` (e.g. Team) — without the
   exclusion the form (and the sticky tools bar inside it) gets a stray 2rem gap
   instead of sitting flush under the title. */
.dv-page-tools + :not(.dv-page-tools):not(:has(.dv-page-tools)),
.dv-page-head + :not(.dv-page-tools):not(.dv-page-head):not(:has(.dv-page-tools)),
.page-header + :not(.dv-page-tools):not(.dv-page-head):not(.dv-page-band):not(:has(.dv-page-tools)) { margin-top: 2rem; padding-top: 0; }

.dv-spacer { flex: 1 1 auto; }
.dv-vrule { width: 1px; height: 22px; background: var(--hairline); flex-shrink: 0; }

/* Tools select — token-clean native <select> for .dv-page-tools filter rows.
   Native control kept (submit/keyboard); appearance stripped and a Lucide
   chevron overlaid. Matches .search-wrap height/typography. */
.dv-tools-select { position: relative; display: inline-flex; align-items: center; }
.dv-tools-select select {
  appearance: none;
  -webkit-appearance: none;
  height: 32px;
  min-width: 10rem;
  padding: 0 30px 0 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-size: var(--text-xs);
  color: var(--ink);
  cursor: pointer;
}
.dv-tools-select select:hover { border-color: var(--hairline-strong); }
.dv-tools-select select:focus { outline: none; border-color: var(--hairline-strong); }
.dv-tools-select__chev {
  position: absolute;
  right: 10px;
  color: var(--muted-2);
  pointer-events: none;
}
.dv-page-tools__note {
  font-size: var(--text-xs);
  color: var(--muted-2);
  font-family: var(--font-mono, ui-monospace, monospace);
  white-space: nowrap;
}
.dv-toolbtn {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: 8px;
  color: var(--muted); cursor: pointer; text-decoration: none;
}
.dv-toolbtn:hover { background: var(--canvas); color: var(--ink); }

/* Scope tabs — count/amount-forward, mutually-exclusive (one .is-on) */
.dv-scope-tabs { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.dv-scope-tab {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 6px 12px; border-radius: 8px;
  background: transparent; border: 1px solid transparent;
  cursor: pointer; font: inherit; text-decoration: none; white-space: nowrap;
}
.dv-scope-tab:hover { background: var(--canvas); }
.dv-scope-tab__n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-md); font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.dv-scope-tab__l { font-size: var(--text-sm); color: var(--muted); }
.dv-scope-tab.is-on { background: var(--accent-soft); border-color: var(--accent-border, rgba(3,105,161,0.18)); }
.dv-scope-tab.is-on .dv-scope-tab__n,
.dv-scope-tab.is-on .dv-scope-tab__l { color: var(--accent); }
.dv-scope-tab__n--neg  { color: var(--error, #c13028); }
.dv-scope-tab__n--zero { color: var(--muted-2); }

/* Scope-filter hide utility — toggled by the `scope-filter` Stimulus
   controller to show/hide items by the active tab's data-scope. !important
   beats element display rules (grid/flex items) so any item type hides. */
.dv-hide { display: none !important; }

/* #107 — search-filter and cert-filter own their own hide classes so they
   compose with scope-filter (.dv-hide) instead of clobbering one shared class.
   A row is visible only when NONE of the three filters wants it hidden. */
.search-hide, .cert-hide { display: none !important; }

/* Filter control — row-2 of .dv-page-tools (date pickers, toggles, facets).
   Fixed 32px so controls align with each other + the scope tabs by construction.
   Use --pill for toggles/facets; .is-on is the accent-soft active state.
   (Canonical in WL design-system tokens.css#filter-control.) */
.dv-filter-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 12px;
  font-size: var(--text-xs); font-weight: 500;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--hairline);
  color: var(--ink);
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: border-color var(--t-fast) ease, background var(--t-fast) ease, color var(--t-fast) ease;
}
.dv-filter-btn:hover { border-color: var(--hairline-strong); }
.dv-filter-btn svg, .dv-filter-btn [data-lucide] { color: var(--muted-2); flex-shrink: 0; }
.dv-filter-btn__chev { margin-left: 2px; }
.dv-filter-btn--pill { border-radius: 999px; color: var(--muted); }
.dv-filter-btn--pill:hover { color: var(--ink); }
.dv-filter-btn.is-on { background: var(--accent-soft); border-color: var(--accent-border); color: var(--accent); }
.dv-filter-btn.is-on svg, .dv-filter-btn.is-on [data-lucide] { color: var(--accent); }

/* ── Filter bar (full-control row) ────────────────────────────────────
   A wrapping row of full-size form controls (search input, dv-select
   triggers, date pickers, a checkbox toggle, submit + clear buttons).
   Every direct control is normalised to the canonical 46px field height
   so the row aligns on one baseline by construction — no per-control
   height utilities. Pair the buttons with `.dv-btn--field` (also 46px).
   Token-only. */
.dv-filter-bar .diveos-input,
.dv-filter-bar .diveos-select { height: 46px; }
/* Checkbox toggle styled as a bordered control so it reads as a peer of the
   inputs in the row (box + label inside a 46px hairline pill). */
.dv-filter-bar .diveos-check {
  height: 46px;
  align-items: center;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--t-fast) ease;
}
.dv-filter-bar .diveos-check:hover { background: var(--canvas); }

/* Ledger title-level date nav (.dv-pager) + today tag */
.dv-pager { display: inline-flex; align-items: center; border: 1px solid var(--hairline); border-radius: 10px; overflow: hidden; }
.dv-pager__step {
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer; color: var(--muted); text-decoration: none;
}
.dv-pager__step:hover { background: var(--canvas); color: var(--ink); }
.dv-pager__date {
  display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px;
  background: transparent; border: none; border-left: 1px solid var(--hairline); border-right: 1px solid var(--hairline);
  font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; color: var(--accent); cursor: default;
}
.dv-today-tag {
  display: inline-flex; align-items: center; height: 28px; padding: 0 12px;
  border-radius: 999px; background: var(--accent-soft); border: 1px solid var(--accent-border, rgba(3,105,161,0.18));
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent);
  cursor: pointer; text-decoration: none;
}

/* Ledger anchor stat (leads the scope row) */
.dv-anchor-stat { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }
.dv-anchor-stat__label { font-size: var(--text-2xs); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-2); }
/* Money anchor (Ledger "Today net") — Geist Mono tabular per the numerics rule,
   and sign-driven color: ink at zero, green only when positive, rose when
   negative (was hardcoded green, so $0.00 read as a gain). */
.dv-anchor-stat__value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-xl); font-weight: 600; color: var(--ink); letter-spacing: -0.02em; }
.dv-anchor-stat__value--pos { color: var(--confirmed); }
.dv-anchor-stat__value--neg { color: var(--error, #c13028); }
