/* Wesal V2 — Customers surface (NG3).
   Tokens only (tokens.css): no hard-coded colour ever appears here, which is
   what keeps light and dark correct without a second stylesheet.

   The list is ONE DOM in both layouts. On desktop it is a dense grid that
   reads as a table; under 900px each row becomes a real card with its own
   labels — never a table shoved sideways, so the page never scrolls
   horizontally. ARIA roles are declared explicitly in the markup because
   display:block drops the implicit table semantics. */

.cst-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 0;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.cst-wrap:has(.cst-detail:not(.cst-detail-empty)) {
  grid-template-columns: minmax(0, 1fr) minmax(340px, 460px);
}

.cst-list {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border-inline-end: 1px solid var(--w-line);
}

.cst-list-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 16px 20px 10px;
}
.cst-list-head h1 {
  font-size: 20px;
  font-weight: 700;
  margin: 0;
  color: var(--w-ink);
}

.cst-search {
  position: relative;
  flex: 1 1 260px;
  min-width: 200px;
  display: flex;
  align-items: center;
}
.cst-search .s-ico {
  position: absolute;
  inset-inline-start: 10px;
  display: flex;
  color: var(--w-ink-3);
  pointer-events: none;
}
.cst-search .input {
  width: 100%;
  padding-inline-start: 32px;
  padding-inline-end: 32px;
}
.cst-search .s-clear {
  position: absolute;
  inset-inline-end: 4px;
}

/* Desktop/tablet: the filter bar is always visible, so the <details> wrapper
   is transparent and its summary is removed from the accessibility tree too
   (display:none, not just visually hidden — a summary that toggles nothing
   would be a confusing control for a screen-reader user). */
.cst-filters-wrap > .cst-filters-sum { display: none; }

@media (max-width: 760px) {
  .cst-filters-wrap {
    margin: 0 14px 10px;
    border: 1px solid var(--w-line);
    border-radius: 12px;
  }
  .cst-filters-wrap > .cst-filters-sum {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px;
    min-height: 44px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    color: var(--w-ink-2);
  }
  .cst-filters-wrap > .cst-filters-sum:focus-visible {
    outline: 2px solid var(--w-teal);
    outline-offset: -2px;
    border-radius: 12px;
  }
  .cst-filters-wrap[open] > .cst-filters-sum { border-bottom: 1px solid var(--w-line); }
  .cst-filters-wrap .cst-filters { padding: 12px; }
}

/* Filters wrap onto as many lines as they need — chips must never be cut off
   or pushed into a horizontal scroller (E-12 precedent from PR #171). */
.cst-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  padding: 0 20px 12px;
  align-items: flex-end;
}
.cst-f {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.cst-f-l {
  font-size: 11px;
  color: var(--w-ink-3);
}
.cst-f .input.sm {
  min-width: 132px;
  max-width: 200px;
}

.cst-rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0 20px 20px;
  /* Measured before this line: the scrollbar appearing between a full page and
     a short last page moved the table 15px and every column 10px. Reserving
     the gutter always makes the width identical in both states. */
  scrollbar-gutter: stable;
}

.cst-table {
  display: flex;
  flex-direction: column;
}

/* ONE column contract, declared once and read by BOTH the header and every
   row. They used to carry separate identical declarations, which is a latent
   way for the two to drift apart; a single custom property makes divergence
   impossible by construction. */
.cst-table {
  --cst-cols: minmax(180px, 2.2fr) 96px 116px minmax(120px, 1.2fr) 120px 108px;
}

.cst-head,
.cst-row {
  display: grid;
  grid-template-columns: var(--cst-cols);
  gap: 12px;
  align-items: center;
}

.cst-head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--w-surface);
  border-bottom: 1px solid var(--w-line);
  padding: 8px 10px;
  font-size: 11px;
  font-weight: 600;
  color: var(--w-ink-3);
}

.cst-row {
  width: 100%;
  text-align: start;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--w-line-soft, var(--w-line));
  padding: 10px;
  cursor: pointer;
  color: inherit;
  font: inherit;
  /* 44px minimum touch target, met by content height + padding. */
  min-height: 56px;
}
.cst-row:hover { background: var(--w-surface-2); }
/* Selected and hovered must not look the same: hover is surface-2, so a
   selected row that also used surface-2 became invisible the moment the
   pointer rested on it. Inbox already settled this — teal-soft marks the row
   you are looking at. */
.cst-row.active { background: var(--w-teal-soft); box-shadow: inset 3px 0 0 var(--w-teal); }
.cst-row:focus-visible { outline: 2px solid var(--w-teal); outline-offset: -2px; }

.cst-c { min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cst-c-tags { gap: 4px; }

.cst-id { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cst-id-txt { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.cst-name {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: var(--w-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cst-2nd { font-size: 12px; color: var(--w-ink-3); display: flex; align-items: center; gap: 4px; }
.cst-ref { font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.cst-muted { color: var(--w-ink-3); font-size: 12px; }

.cst-skel { display: flex; align-items: center; gap: 10px; padding: 12px 10px; }

/* ── Detail / Customer 360 ─────────────────────────────────────────────── */

.cst-detail {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--w-surface);
}
.cst-detail-empty { display: none; }

.cst-d-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--w-line);
  position: sticky;
  top: 0;
  background: var(--w-surface);
  z-index: 1;
}
.cst-d-head h2 { font-size: 15px; margin: 0; color: var(--w-ink); }
.cst-d-body { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 16px; }

.cst-hero { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; }
.cst-hero-t { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.cst-hero-t h2 { margin: 0; font-size: 18px; color: var(--w-ink); word-break: break-word; }

.cst-sec {
  border: 1px solid var(--w-line);
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cst-sec h3 { margin: 0 0 2px; font-size: 13px; font-weight: 700; color: var(--w-ink-2); }
.cst-sec h4 { margin: 6px 0 0; font-size: 12px; font-weight: 600; color: var(--w-ink-2); }
/* A section the product genuinely cannot fill. Visually quieter, never hidden
   — the merchant is told what is missing and why. */
.cst-sec-off { opacity: .92; }

.cst-kv { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; }
.cst-kv .k { color: var(--w-ink-3); }
.cst-kv .v { color: var(--w-ink); text-align: end; min-width: 0; word-break: break-word; }

.cst-disc summary { cursor: pointer; font-size: 12px; color: var(--w-ink-3); }
.cst-disc[open] summary { margin-bottom: 6px; }

.cst-notes { display: flex; flex-direction: column; gap: 8px; }
.cst-note { border: 1px solid var(--w-line); border-radius: 10px; padding: 8px 10px; }
.cst-note-b { font-size: 13px; color: var(--w-ink); white-space: pre-wrap; word-break: break-word; }
.cst-note-m { font-size: 11px; color: var(--w-ink-3); margin-top: 4px; }
.cst-note-add { display: flex; flex-direction: column; gap: 8px; }
.cst-note-add .input { resize: vertical; }

.cst-tl { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.cst-tl li { font-size: 12px; color: var(--w-ink-2); }

/* ── Duplicate review ──────────────────────────────────────────────────── */

.cst-dup { border: 1px solid var(--w-line); border-radius: 12px; padding: 12px; margin-bottom: 12px; }
.cst-dup-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.cst-dup-m { display: flex; flex-direction: column; gap: 8px; }
.cst-dup-c {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: none; border: 1px solid var(--w-line); border-radius: 10px;
  padding: 8px 10px; cursor: pointer; color: inherit; font: inherit; text-align: start;
  min-height: 44px;
}
.cst-dup-c:hover { background: var(--w-surface-2); }
.cst-dup-c:focus-visible { outline: 2px solid var(--w-teal); outline-offset: 2px; }
.cst-dup-a { margin-top: 10px; }

.cst-plan { margin-top: 12px; border-top: 1px solid var(--w-line); padding-top: 12px; }
.cst-plan h3 { font-size: 13px; margin: 0 0 8px; color: var(--w-ink); }
.cst-plan-g { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; font-size: 13px; align-items: baseline; }
.cst-moves, .cst-conf { margin: 6px 0 0; padding-inline-start: 18px; font-size: 13px; color: var(--w-ink-2); }
.cst-plan-a { margin-top: 12px; }
/* The disabled apply control keeps its reason attached to it, not in a
   tooltip a keyboard user cannot reach. */
.cst-blocked {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--w-ink-2);
  background: var(--w-surface-2);
  border-inline-start: 3px solid var(--w-warn, var(--w-teal));
  border-radius: 8px;
  padding: 8px 10px;
}

/* ── Tablet ────────────────────────────────────────────────────────────── */

@media (max-width: 1180px) {
  .cst-table { --cst-cols: minmax(160px, 2fr) 92px 112px 112px 100px; }
  /* Owner is the first column to go: it is conversation-scoped context, and
     it is still shown in full on the customer's own page. */
  .cst-head > :nth-child(6), .cst-row > :nth-child(6) { display: none; }
}

@media (max-width: 1000px) {
  .cst-wrap:has(.cst-detail:not(.cst-detail-empty)) { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); }
  .cst-table { --cst-cols: minmax(150px, 2fr) 92px 112px 100px; }
  .cst-head > :nth-child(4), .cst-row > :nth-child(4) { display: none; }
}

/* ── Phone: real cards, no horizontal scroll ───────────────────────────── */

@media (max-width: 760px) {
  .cst-wrap, .cst-wrap:has(.cst-detail:not(.cst-detail-empty)) {
    grid-template-columns: minmax(0, 1fr);
  }
  /* One pane at a time: opening a customer pushes a FULL page rather than
     squeezing a drawer next to a list that no longer fits. */
  .cst-wrap.show-detail .cst-list { display: none; }
  .cst-wrap:not(.show-detail) .cst-detail { display: none; }
  .cst-detail { border-inline-start: 0; }
  .cst-list { border-inline-end: 0; }

  .cst-list-head, .cst-rows { padding-inline: 14px; }

  /* Reclaim the fold. The title and the duplicate-review action share one
     line and the search takes the next, instead of three stacked full-width
     blocks — that difference alone is what moves the list from four visible
     customers to six or seven on a 390x844 phone. */
  .cst-list-head {
    padding-block: 12px 8px;
    gap: 8px;
    row-gap: 8px;
  }
  .cst-list-head h1 { font-size: 18px; flex: 1 1 auto; }
  .cst-list-head > .btn { flex: 0 0 auto; }
  .cst-search { flex: 1 1 100%; order: 3; }

  .cst-head { display: none; }

  /* Dense cards. One field per LINE reads cleanly but produced ~450px tall
     cards, so barely three customers fit a phone screen and the list stops
     being scannable. The name owns the first line; everything else flows and
     wraps, which keeps a card near ~120px and puts 6-8 customers in view. */
  .cst-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px 10px;
    border: 1px solid var(--w-line);
    border-radius: 12px;
    padding: 10px 12px;
    margin-bottom: 8px;
    min-height: 0;
  }
  .cst-row.active { box-shadow: 0 0 0 2px var(--w-teal); }
  .cst-row > .cst-c-name { flex: 1 0 100%; }
  .cst-row > .cst-c:not(.cst-c-name) { flex: 0 1 auto; font-size: 12px; }

  /* The tablet rules above hide the Tags and Owner columns because the GRID
     runs out of width. A card has no columns and no width pressure, so those
     rules must not survive here — otherwise a phone shows strictly less about
     a customer than a tablet does, which is backwards. */
  .cst-row > :nth-child(4),
  .cst-row > :nth-child(6) { display: flex; }

  /* Every cell states its own column name, because the header row is gone. */
  .cst-c:not(.cst-c-name)::before {
    content: attr(data-label) ' · ';
    font-size: 11px;
    color: var(--w-ink-3);
  }
  .cst-c-name { padding-bottom: 5px; border-bottom: 1px solid var(--w-line); }
  .cst-name { white-space: normal; }

  .cst-f .input.sm { min-width: 0; max-width: none; width: 100%; }
  .cst-f { flex: 1 1 44%; }

  .cst-plan-g { grid-template-columns: 1fr; }
}

/* Wide-gamut safety: a viewport narrower than the narrowest grid column must
   still not produce a horizontal scrollbar. */
@media (max-width: 360px) {
  .cst-list-head, .cst-rows { padding-inline: 10px; }
  .cst-filters-wrap { margin-inline: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .cst-row, .cst-dup-c { transition: none; }
}

/* ── Pagination bar ─────────────────────────────────────────────────────
   Lives OUTSIDE .cst-rows, so it can never overlap the last row and does not
   scroll away. The rows scroller keeps its own height; this is a sibling. */
.cst-pager {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 20px;
  border-top: 1px solid var(--w-line);
  background: var(--w-surface);
  font-size: 12px;
  color: var(--w-ink-3);
}
.cst-pager-size { display: flex; align-items: center; gap: 6px; }
.cst-pager-size .input.sm { min-width: 72px; }
.cst-pager-range { margin-inline-start: auto; font-variant-numeric: tabular-nums; }
.cst-pager-nav { display: flex; align-items: center; gap: 8px; }
.cst-pager-nav .btn[disabled] { opacity: .45; cursor: default; }

/* Reserve the rows area so a short last page does not collapse the table and
   yank the pager upwards. Deliberately a min-height on the CONTAINER, never
   filler rows — an empty row that looks like a customer is worse than a gap. */
.cst-rows { min-height: 220px; }

@media (max-width: 760px) {
  .cst-pager { padding-inline: 14px; gap: 8px; }
  .cst-pager-range { margin-inline-start: 0; flex: 1 1 100%; order: 3; }
}

@media (max-width: 767px) {
  /* WES-010 (stabilization Wave A): .cst-wrap sits at height:100% inside
     .page with its own overflow:hidden (see the comment at the top of this
     file), so .page's own bottom padding — shell.css's ".page { padding:
     ... 90px }", reserved specifically to clear the fixed mobile tab bar —
     never actually reaches this pager; it is the last flex child of a
     nested, independently-clipped column, not a direct child of .page.
     Measured live at 375x812: the tab bar covered ~65% of the pager's
     height (getBoundingClientRect() showed .cst-pager's bottom flush with
     the viewport's own bottom edge, not with .page's padded content edge),
     hiding the rows-per-page control and the "Next" button entirely.
     Reserving the SAME 90px directly on the pager itself — rather than
     relying on padding propagation through a container this fix does not
     otherwise need to restructure — closes the gap regardless of the
     nested-overflow layout. 767px matches shell.css's own mobile
     breakpoint for .m-tabbar exactly, rather than this file's slightly
     narrower 760px one, so the fix is active for every width the tab bar
     itself is visible at. */
  .cst-pager { margin-bottom: 90px; }
}

/* NG4.1 — the coarse-pointer touch-target floor, applied here the same way
   NG4 applied it to the growth surfaces (growth.css) and the shared shell
   (shell.css).

   Measured at 375x812 with `pointer: coarse`: the search field was 40.4px and
   all seven filter selects 41px. The channel filter this round added inherits
   the same classes, so it arrived under the floor too — fixing only my own
   addition would have left an inconsistent row of controls, eight of which a
   thumb still misses.

   Under `pointer: coarse` only: a mouse does not need the extra area, and
   forcing it would make this surface visibly heavier than the rest of V2. */
@media (pointer: coarse) {
  .cst-wrap .input,
  .cst-wrap .input.sm,
  .cst-wrap select.input {
    min-block-size: 44px;
  }
}

/* Convergence Slice 4a/4g — privacy & data */
.cst-privacy-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.cst-privacy .banner { margin-top: 8px; }
