/* ============================================================================
   STRATAMIZE — "THE LEDGER" · DATA DISPLAY  (data.css)
   ----------------------------------------------------------------------------
   The readout layer of the global design system: tables / data-grids, lists,
   key-value + detail layouts, pagination, and the empty-state pattern. This is
   where the brand DNA — a LIVE READOUT, the instrument showing the state of
   your money — is most literal. Hairline structure over card-soup; money set
   in mono + tabular-nums so columns lock to the pixel and never dance on update.

   Theme-agnostic — every value derives from a semantic token in tokens.css, so
   the SAME classes render the dark operator cockpit ([data-theme="dark"]) and
   the light customer paper ([data-theme="light"]).

   RULES OBEYED
     • Tokens only. No hex literals, no new --vars (locals are --_scoped).
     • Mint is the single live signal: the live-row signal-rail, the active sort
       column, the selected row — never sprayed as decoration.
     • Every figure that means money rides mono + tabular-nums (.col-num/.num).
     • State is double-encoded (shape + color): trend ▲/▼, status dot/diamond/
       triangle/✕/dash — survives a glance and color-vision deficiency.
     • Every interactive affordance has hover / focus-visible / active states and
       honors prefers-reduced-motion. Motion is compositor-only (transform/opacity).

   Load order: tokens.css → data.css   (sits alongside elements.css/actions-forms.css)
   MAP
     1  table frame (scroll shell, sticky head)
     2  table base (head / body / foot, cell roles, alignment)
     3  density + zebra + row states (hover / selected / live-rail)
     4  sortable header affordance (aria-sort, carets)
     5  pinned first column
     6  trend / delta + inline status cell (shape-encoded)
     7  lists (data list, interactive, divided)
     8  key-value + detail layouts
     9  pagination (pager, summary, rows-per-page)
    10  empty state
   10b  KPI tiles (compact metric readout)
    11  loading skeleton
    12  reduced motion
   ============================================================================ */

/* ── 1 · TABLE FRAME ───────────────────────────────────────────────────────── */
/* The shell owns the border + radius + scroll so the table itself stays flush.
   overflow:auto gives horizontal scroll on dense grids without breaking layout. */
.table-wrap{
  position:relative;
  border:1px solid var(--hairline);
  border-radius:var(--r-md);
  background:var(--surface-raised);
  overflow:auto;
  box-shadow:var(--shadow-1);
}
/* a captioned/toolbarred wrapper variant — header strip above the scroll area */
.table-toolbar{
  display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  padding:var(--s-3) var(--s-4);
  border-bottom:1px solid var(--hairline);
  background:var(--surface-header);
}
.table-toolbar .table-title{
  font:600 var(--fs-sm)/1 var(--font-text);color:var(--ink);
  text-transform:uppercase;letter-spacing:var(--tracking-caps);
}
.table-toolbar .table-count{
  font:500 var(--fs-meta)/1 var(--font-mono);font-variant-numeric:tabular-nums;
  color:var(--ink-4);
}
.table-toolbar .spacer{margin-inline-start:auto}

/* ── 2 · TABLE BASE ────────────────────────────────────────────────────────── */
.table{
  --_pad-y:var(--s-3);          /* comfortable default; .table--dense lowers it */
  --_pad-x:var(--s-4);
  width:100%;
  border-collapse:separate;     /* separate keeps sticky-head borders crisp */
  border-spacing:0;
  font-size:var(--fs-sm);
  color:var(--ink-2);
}
.table caption{
  caption-side:top;text-align:left;padding:var(--s-3) var(--s-4);
  font:600 var(--fs-kicker)/1.2 var(--font-text);
  text-transform:uppercase;letter-spacing:var(--tracking-kicker);color:var(--ink-3);
}

/* head — sticky, the table's instrument label strip */
.table thead th{
  position:sticky;top:0;z-index:var(--z-raised);
  padding:var(--s-3) var(--_pad-x);
  text-align:left;vertical-align:middle;white-space:nowrap;
  font:600 var(--fs-meta)/1 var(--font-text);
  text-transform:uppercase;letter-spacing:var(--tracking-caps);
  color:var(--ink-3);
  background:var(--surface-header);
  border-bottom:1px solid var(--hairline-strong);
}
/* hairline keylines between header labels read as an instrument grid */
.table thead th + th{box-shadow:inset 1px 0 0 0 var(--hairline-faint)}

/* body */
.table tbody td{
  padding:var(--_pad-y) var(--_pad-x);
  vertical-align:middle;
  border-bottom:1px solid var(--hairline-faint);
  color:var(--ink-2);
}
.table tbody tr:last-child td{border-bottom:0}

/* foot — totals row, ink-strong, mono-aligned, top hairline like a ledger rule */
.table tfoot td{
  padding:var(--_pad-y) var(--_pad-x);
  border-top:1px solid var(--hairline-strong);
  background:var(--surface-header);
  color:var(--ink);font-weight:600;
}

/* cell roles ---------------------------------------------------------------- */
/* money / counts — right-aligned, mono, tabular: columns lock to the pixel */
.table .col-num,.table td.num,.table th.num{
  text-align:right;
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1,"zero" 1;
  color:var(--ink);letter-spacing:0;white-space:nowrap;
}
.table thead th.num,.table thead th.col-num{justify-items:end}
/* the emphatic money figure (a row total) */
.table .num--strong{color:var(--ink);font-weight:600}
/* IDs / MIDs / refs — mono, mint text = "this is a live reference" */
.table .cell-id{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  color:var(--accent-text);white-space:nowrap;
}
/* a quiet secondary line beneath a primary cell value */
.table .cell-sub{display:block;margin-top:2px;font-size:var(--fs-meta);color:var(--ink-4)}
.table .cell-strong{color:var(--ink);font-weight:600}
.table .cell-muted{color:var(--ink-4)}
/* checkbox / control column — tight, centered */
.table .col-check,.table th.col-check{width:1px;white-space:nowrap;text-align:center;padding-inline:var(--s-3)}
/* trailing action column — right, tight */
.table .col-actions{text-align:right;white-space:nowrap;width:1px}
.table .col-actions .btn{vertical-align:middle}

/* alignment utilities */
.table .ta-left{text-align:left}
.table .ta-center{text-align:center}
.table .ta-right{text-align:right}

/* ── 3 · DENSITY + ZEBRA + ROW STATES ──────────────────────────────────────── */
/* comfortable is default (set in §2). dense for operator data-grids. */
.table--dense{--_pad-y:var(--s-2);--_pad-x:var(--s-3);font-size:var(--fs-meta)}
.table--dense thead th{padding-block:var(--s-2)}
.table--comfortable{--_pad-y:var(--s-4);--_pad-x:var(--s-5)}

/* zebra — sunken alternate rows (reads as ledger ruling, not stripes) */
.table--zebra tbody tr:nth-child(even) td{
  background:color-mix(in oklab,var(--surface-sunken) 55%,transparent);
}

/* hover — one quiet mint wash; the live readout responding to the eye */
.table--hover tbody tr{transition:background var(--dur-1) var(--ease-out)}
.table--hover tbody tr:hover td{background:var(--row-hover)}

/* selected row — mint wash + a left signal-rail marking the active record */
.table tbody tr[aria-selected="true"] td,
.table tbody tr.is-selected td{
  background:var(--accent-wash);
  color:var(--ink);
}
.table tbody tr[aria-selected="true"] td:first-child,
.table tbody tr.is-selected td:first-child{
  box-shadow:inset var(--rail-w) 0 0 0 var(--accent);
}

/* LIVE row — the signal-rail left edge marks a surface that is updating now.
   One per view, per the rationing rule. Pair with aria-live in the markup. */
.table tbody tr.is-live td:first-child{
  box-shadow:inset var(--rail-w) 0 0 0 var(--accent);
}
.table tbody tr.is-live td{background:color-mix(in oklab,var(--accent) 5%,transparent)}

/* clickable rows */
.table--rows-link tbody tr{cursor:pointer}
.table--rows-link tbody tr:focus-within td{background:var(--row-hover)}

/* ── 4 · SORTABLE HEADER AFFORDANCE ────────────────────────────────────────── */
/* th carries aria-sort; the trigger is a real <button> for keyboard + a11y.
   Carets are drawn from borders — no asset. Inactive = faint pair; active =
   mint single caret in the sort direction. */
.th-sort{
  display:inline-flex;align-items:center;gap:var(--s-2);
  width:100%;padding:0;border:0;background:none;cursor:pointer;
  font:inherit;color:inherit;text-transform:inherit;letter-spacing:inherit;
  text-align:left;
  transition:color var(--dur-2) var(--ease-out);
}
.table th.num .th-sort,.table th.col-num .th-sort{justify-content:flex-end}
.th-sort:hover{color:var(--ink)}
.th-sort:focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--r-1)}
/* the caret stack */
.th-sort .sort-ind{position:relative;display:inline-flex;flex-direction:column;gap:3px;width:8px;height:14px;flex:none}
.th-sort .sort-ind::before,
.th-sort .sort-ind::after{
  content:"";width:0;height:0;margin-inline:auto;
  border-inline:4px solid transparent;
  opacity:.35;
  transition:opacity var(--dur-1) var(--ease-out),border-color var(--dur-1) var(--ease-out);
}
.th-sort .sort-ind::before{border-bottom:5px solid currentColor}  /* ▲ asc */
.th-sort .sort-ind::after{border-top:5px solid currentColor}      /* ▼ desc */
/* active states reflect aria-sort on the th */
.table th[aria-sort="ascending"]{color:var(--ink)}
.table th[aria-sort="ascending"] .sort-ind::before{opacity:1;border-bottom-color:var(--accent)}
.table th[aria-sort="ascending"] .sort-ind::after{opacity:.18}
.table th[aria-sort="descending"]{color:var(--ink)}
.table th[aria-sort="descending"] .sort-ind::after{opacity:1;border-top-color:var(--accent)}
.table th[aria-sort="descending"] .sort-ind::before{opacity:.18}

/* ── 5 · PINNED FIRST COLUMN ───────────────────────────────────────────────── */
/* For wide grids: keep the identifier column visible while scrolling X. */
.table--pin-first td:first-child,
.table--pin-first th:first-child{
  position:sticky;left:0;z-index:var(--z-raised);
  background:var(--surface-raised);
}
.table--pin-first thead th:first-child{z-index:calc(var(--z-raised) + 1);background:var(--surface-header)}
.table--pin-first td:first-child{box-shadow:inset -1px 0 0 0 var(--hairline)}
.table--pin-first.table--zebra tbody tr:nth-child(even) td:first-child{
  background:color-mix(in oklab,var(--surface-sunken) 88%,var(--surface-raised));
}

/* ── 6 · TREND / DELTA + INLINE STATUS CELL (shape-encoded) ────────────────── */
/* deltas in a data cell: mono figure + a shape that survives CVD.
   up = ▲ mint (success), down = ▼ danger, flat = – neutral. Color never alone. */
.trend{
  display:inline-flex;align-items:center;gap:var(--s-1);
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-weight:500;
  letter-spacing:0;white-space:nowrap;
}
.trend::before{content:"";width:0;height:0;flex:none}
.trend--up{color:var(--success)}
.trend--up::before{border-inline:4px solid transparent;border-bottom:6px solid currentColor} /* ▲ */
.trend--down{color:var(--danger)}
.trend--down::before{border-inline:4px solid transparent;border-top:6px solid currentColor}   /* ▼ */
.trend--flat{color:var(--ink-4)}
.trend--flat::before{width:8px;height:2px;border-radius:var(--r-full);background:currentColor} /* – */

/* inline status dot for a cell (lighter than the full status-pill component) —
   double-encoded shape+color. Use inside a cell to label a record's state. */
.cell-state{display:inline-flex;align-items:center;gap:var(--s-2);white-space:nowrap;color:var(--ink-2)}
.cell-state::before{content:"";width:8px;height:8px;flex:none}
.cell-state--success{color:var(--success)}
.cell-state--success::before{border-radius:var(--r-full);background:currentColor}                 /* ● dot */
.cell-state--info{color:var(--info)}
.cell-state--info::before{transform:rotate(45deg);background:currentColor}                          /* ◆ diamond */
.cell-state--warn{color:var(--warn)}
.cell-state--warn::before{clip-path:polygon(50% 0,100% 100%,0 100%);background:currentColor}        /* ▲ triangle */
.cell-state--danger{color:var(--danger)}
.cell-state--danger::before{clip-path:polygon(20% 0,0 20%,30% 50%,0 80%,20% 100%,50% 70%,80% 100%,100% 80%,70% 50%,100% 20%,80% 0,50% 30%);background:currentColor} /* ✕ */
.cell-state--neutral{color:var(--ink-4)}
.cell-state--neutral::before{height:2px;align-self:center;background:currentColor}                  /* – dash */

/* ── 7 · LISTS ─────────────────────────────────────────────────────────────── */
/* A data list — same hairline discipline as the table, for non-tabular records. */
.list{
  list-style:none;margin:0;padding:0;
  border:1px solid var(--hairline);border-radius:var(--r-md);
  background:var(--surface-raised);overflow:hidden;
}
.list > li,.list-item{
  display:flex;align-items:center;gap:var(--s-4);
  padding:var(--s-4) var(--s-5);
  border-bottom:1px solid var(--hairline-faint);
}
.list > li:last-child,.list-item:last-child{border-bottom:0}

/* item parts — leading mark, title block, trailing figure */
.list-item .item-lead{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:2.25rem;height:2.25rem;border-radius:var(--r-2);
  background:var(--surface-sunken);border:1px solid var(--hairline);
  color:var(--ink-3);font:600 var(--fs-sm)/1 var(--font-mono)}
.list-item .item-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.list-item .item-title{font:500 var(--fs-base)/1.2 var(--font-text);color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.list-item .item-meta{font:400 var(--fs-meta)/1.3 var(--font-text);color:var(--ink-4)}
.list-item .item-meta .mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.list-item .item-trail{flex:none;margin-inline-start:auto;text-align:right;
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;color:var(--ink);font-weight:500}

/* divided / flush variants */
.list--flush{border:0;border-radius:0;background:transparent}
.list--flush > li,.list--flush .list-item{padding-inline:0}

/* interactive list (rows are links/buttons) */
.list--interactive .list-item{transition:background var(--dur-1) var(--ease-out);cursor:pointer}
.list--interactive .list-item:hover{background:var(--row-hover)}
.list--interactive .list-item:active{background:var(--accent-wash)}
.list--interactive .list-item:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--accent);border-radius:var(--r-1)}
/* a live list-item carries the signal-rail */
.list-item.is-live{box-shadow:inset var(--rail-w) 0 0 0 var(--accent)}

/* ── 8 · KEY-VALUE + DETAIL LAYOUTS ────────────────────────────────────────── */
/* key-value — a labelled record (invoice meta, settlement detail). Labels are
   tracked-uppercase ink-3; values are ink, money values mono. */
.kv{display:grid;grid-template-columns:minmax(8rem,auto) 1fr;gap:var(--s-2) var(--s-6);margin:0}
.kv dt{
  font:600 var(--fs-meta)/1.4 var(--font-text);
  text-transform:uppercase;letter-spacing:var(--tracking-caps);color:var(--ink-3);
}
.kv dd{margin:0;font:400 var(--fs-base)/1.4 var(--font-text);color:var(--ink)}
.kv dd.mono,.kv dd .mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
/* stacked variant for narrow / mobile detail panels */
.kv--stack{grid-template-columns:1fr;gap:var(--s-1)}
.kv--stack dt{margin-top:var(--s-3)}
.kv--stack dt:first-child{margin-top:0}

/* detail rows — a bordered list of label/value pairs with a hairline ledger rule
   between each, for a single-record detail surface. */
.detail{display:flex;flex-direction:column;border-top:1px solid var(--hairline)}
.detail-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-6);
  padding:var(--s-3) 0;border-bottom:1px solid var(--hairline-faint);
}
.detail-row .detail-label{font:600 var(--fs-meta)/1.3 var(--font-text);
  text-transform:uppercase;letter-spacing:var(--tracking-caps);color:var(--ink-3);flex:none}
.detail-row .detail-value{text-align:right;color:var(--ink);font:400 var(--fs-base)/1.3 var(--font-text)}
.detail-row .detail-value.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
/* an emphasized total row (ledger close) */
.detail-row--total{border-bottom:0;border-top:1px solid var(--hairline-strong);margin-top:var(--s-1)}
.detail-row--total .detail-label{color:var(--ink);font-size:var(--fs-sm)}
.detail-row--total .detail-value{font-size:var(--fs-num-s);font-weight:600;
  font-family:var(--font-mono);font-variant-numeric:tabular-nums}

/* ── 9 · PAGINATION ────────────────────────────────────────────────────────── */
.pager{
  display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  padding:var(--s-3) var(--s-1);margin-top:var(--s-4);
}
.pager .pager-summary{font:400 var(--fs-meta)/1 var(--font-text);color:var(--ink-4)}
.pager .pager-summary .mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;color:var(--ink-3)}
.pager .pager-nav{display:inline-flex;align-items:center;gap:var(--s-1);margin-inline-start:auto}

/* a page control — square, hairline, mono numeral */
.pager-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s-1);
  min-width:2rem;height:2rem;padding:0 var(--s-2);
  font:500 var(--fs-sm)/1 var(--font-mono);font-variant-numeric:tabular-nums;
  color:var(--ink-2);background:transparent;
  border:1px solid var(--hairline);border-radius:var(--r-2);cursor:pointer;
  -webkit-appearance:none;appearance:none;
  transition:background var(--dur-1) var(--ease-out),border-color var(--dur-1) var(--ease-out),color var(--dur-1) var(--ease-out);
}
.pager-btn:hover{border-color:var(--accent-edge);color:var(--accent-text)}
.pager-btn:active{background:var(--surface-sunken)}
.pager-btn:focus-visible{outline:none;box-shadow:var(--ring)}
.pager-btn[aria-current="page"]{
  background:var(--accent-wash);color:var(--accent-text);
  border-color:var(--accent-edge);font-weight:600;
}
.pager-btn:disabled,.pager-btn[aria-disabled="true"]{opacity:.4;pointer-events:none}
.pager-ellipsis{display:inline-flex;align-items:center;justify-content:center;
  min-width:1.5rem;height:2rem;color:var(--ink-4);font-family:var(--font-mono)}

/* rows-per-page control sits inline */
.pager .pager-size{display:inline-flex;align-items:center;gap:var(--s-2);
  font:400 var(--fs-meta)/1 var(--font-text);color:var(--ink-4)}

/* ── 10 · EMPTY STATE ──────────────────────────────────────────────────────── */
/* The dual-read empty: an operator reads "no records / clear filter", a customer
   reads "nothing here yet". Dashed instrument-housing frame, mono mark, one CTA. */
.empty{
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:var(--s-3);
  padding:var(--s-16) var(--s-6);
  border:1px dashed var(--hairline-strong);border-radius:var(--r-md);
  background:color-mix(in oklab,var(--surface-sunken) 40%,transparent);
}
/* the mark — a hairline instrument tile with a lit mint signal-rail + tick,
   echoing the favicon S-rail housing; built from box-shadows, no asset */
.empty .empty-mark{
  position:relative;width:48px;height:48px;border-radius:var(--r-2);
  border:1px solid var(--hairline-strong);background:var(--surface-sunken);
}
.empty .empty-mark::before{content:"";position:absolute;inset-block:8px;inset-inline-start:0;
  width:var(--rail-w);background:var(--accent);border-radius:var(--r-full)} /* lit left rail */
.empty .empty-mark::after{content:"";position:absolute;left:8px;right:12px;top:50%;height:var(--rail-w);
  transform:translateY(-50%);background:var(--accent);opacity:.7;border-radius:var(--r-full)} /* mid tick */
.empty .empty-title{font:600 var(--fs-h4)/1.15 var(--font-display);color:var(--ink)}
.empty .empty-msg{max-width:42ch;font:400 var(--fs-sm)/1.5 var(--font-text);color:var(--ink-4)}
.empty .empty-actions{display:flex;flex-wrap:wrap;gap:var(--s-3);justify-content:center;margin-top:var(--s-2)}
/* compact inline empty (inside a panel/table body) */
.empty--inline{padding:var(--s-10) var(--s-5)}
.empty--inline .empty-mark{width:36px;height:36px}

/* a full-width empty row that lives inside a table body */
.table .empty-row td{padding:0;border-bottom:0}
.table .empty-row .empty{border:0;border-radius:0;background:transparent}

/* ── 10b · KPI TILES — the compact metric readout (simple instrument cell) ────
   A labelled mono figure with a shape+color delta and a top keyline that can be
   lit by accent/status. This is the dense dashboard KPI. The RICHER stat tile —
   with inline sparkline / sparkbars slots and the data-viz kit — lives in
   surfaces-viz.css as .stat; the two compose cleanly and never collide. */
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:var(--grid-gap)}
.kpi{
  position:relative;padding:var(--s-5);
  background:var(--surface-raised);border:1px solid var(--hairline);
  border-radius:var(--r-md);border-top:2px solid var(--hairline-strong);
  box-shadow:var(--shadow-1);
}
.kpi--live{border-top-color:var(--accent)}
.kpi--warn{border-top-color:var(--warn)}
.kpi--danger{border-top-color:var(--danger)}
.kpi--info{border-top-color:var(--info)}
.kpi-label{
  font:600 var(--fs-kicker)/1 var(--font-text);text-transform:uppercase;
  letter-spacing:var(--tracking-kicker);color:var(--ink-3);margin-bottom:var(--s-3);
}
.kpi-value{
  font:500 var(--fs-num-m)/1 var(--font-mono);font-variant-numeric:tabular-nums;
  letter-spacing:var(--tracking-tight);color:var(--ink);
}
.kpi-delta{
  display:inline-flex;align-items:center;gap:var(--s-1);margin-top:var(--s-2);
  font:500 var(--fs-meta)/1 var(--font-mono);font-variant-numeric:tabular-nums;
}
.kpi-delta--up{color:var(--success)}
.kpi-delta--down{color:var(--danger)}

/* ── 11 · LOADING SKELETON ─────────────────────────────────────────────────── */
/* placeholder rows while data settles; shimmer is opacity-only (compositor-safe) */
.skeleton{
  display:block;height:0.9em;border-radius:var(--r-1);
  background:color-mix(in oklab,var(--ink) 12%,transparent);
  animation:skeleton-pulse 1.4s var(--ease-out) infinite;
}
.skeleton--num{margin-inline-start:auto;width:4.5rem}
.skeleton--wide{width:70%}
.skeleton--full{width:100%}
@keyframes skeleton-pulse{0%,100%{opacity:.55}50%{opacity:1}}

/* ── 12 · REDUCED MOTION ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce){
  .table--hover tbody tr,.list--interactive .list-item,
  .th-sort,.th-sort .sort-ind::before,.th-sort .sort-ind::after,
  .pager-btn{transition-duration:1ms !important}
  .skeleton{animation:none;opacity:.7}
}
