/* v3 grid (reference §3, plan §7, §11 #72–#74). Desktop: a bordered table on
   --surface, label-type header with a --border-strong rule (sticky on long
   grids), --border between rows, --row-hover, numbers right-aligned in mono,
   footer with range, pager, go to page and rows per page. Phones (< 40em): the
   same rows become cards (title + status, sub line, label/value facts, action)
   and a "Show 25 more" button. Macro: core/components/_lg_grid.html. */

.lg-grid {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}
.lg-grid__scroll { overflow-x: auto; border-radius: var(--radius-card) var(--radius-card) 0 0; }
/* Sideways-scroll cue (decision 310, audit P0-4): a shade on the edge that has
   more columns behind it. grid.js toggles lg-grid--more-start / --more-end
   (classes only: no style attribute). A grid with a sticky ⋯ column casts the
   end shade from that column instead. Ledger 2 phase 3 fits the columns; this
   keeps nothing hidden until then. */
.lg-grid__frame { position: relative; }
.lg-grid__frame::before,
.lg-grid__frame::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inline-size: 1.5rem;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease);
  z-index: calc(var(--layer-sticky-head) + 1);
}
.lg-grid__frame::before { inset-inline-start: 0; background: linear-gradient(to right, var(--scroll-shade), transparent); border-start-start-radius: var(--radius-card); }
.lg-grid__frame::after { inset-inline-end: 0; background: linear-gradient(to left, var(--scroll-shade), transparent); border-start-end-radius: var(--radius-card); }
.lg-grid--more-start .lg-grid__frame::before,
.lg-grid--more-end:not(:has(.lg-grid__act)) .lg-grid__frame::after { opacity: 1; }
.lg-grid--sticky .lg-grid__scroll {
  overflow: auto;
  max-block-size: calc(100dvh - var(--bar-height) - 12rem);
}
.lg-grid__table { inline-size: 100%; border-collapse: collapse; }
.lg-grid__th {
  padding: var(--space-3) var(--space-4);
  border-block-end: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--size-label);
  line-height: var(--leading-label);
  font-weight: 500;
  text-align: start;
  white-space: nowrap;
}
.lg-grid--sticky .lg-grid__th,
.lg-grid--sticky .lg-grid__check:is(th) { position: sticky; top: 0; z-index: var(--layer-sticky-head); }
.lg-grid__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin: calc(-1 * var(--space-1));
  padding: var(--space-1);
  border-radius: var(--radius-pill);
  color: inherit;
  text-decoration: none;
}
.lg-grid__sort:hover { color: var(--text); background: var(--neutral-tint); }
.lg-grid__th[aria-sort="ascending"],
.lg-grid__th[aria-sort="descending"] { color: var(--text); }
.lg-grid__td {
  padding: var(--space-3) var(--space-4);
  border-block-end: 1px solid var(--border);
  vertical-align: middle;
  white-space: nowrap;           /* dense grid: values stay on one line */
}
/* The row header (title cell) looks like a data cell, not a bold centred th. */
th.lg-grid__td { font-weight: inherit; text-align: start; }
/* Long text (names, event titles) opts in to wrapping (column "wrap"). */
.lg-grid__td--wrap { white-space: normal; min-inline-size: 14rem; overflow-wrap: break-word; }

/* The actions column stays on screen while a wide grid scrolls sideways. */
@media (min-width: 40em) {
  .lg-grid__act {
    position: sticky;
    inset-inline-end: 0;
    padding-inline: var(--space-2);   /* an icon column needs no text padding (fit at 1,440px) */
    background: var(--surface);
    box-shadow: inset 1px 0 0 var(--border);
  }
  th.lg-grid__act { z-index: calc(var(--layer-sticky-head) + 1); }
  /* More columns behind the sticky ⋯ column: it casts the scroll shade (decision 310). */
  .lg-grid--more-end .lg-grid__act::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-end: 100%;
    inline-size: 1.5rem;
    background: linear-gradient(to left, var(--scroll-shade), transparent);
    pointer-events: none;
  }
  .lg-grid__row:hover .lg-grid__act { background: var(--row-hover); }
  .lg-grid__row:has([data-lg-select]:checked) .lg-grid__act { background: var(--row-selected); }
}
.lg-grid__row:last-child .lg-grid__td,
.lg-grid__row:last-child .lg-grid__check { border-block-end: 0; }
.lg-grid__row:hover { background: var(--row-hover); }
.lg-grid__row:has([data-lg-select]:checked) { background: var(--row-selected); }
.lg-grid__num { text-align: end; }

/* While rows are selected, each row's own actions are off (Carbon, batch
   mode); js/v3/grid.js sets `inert` on them. */
.lg-grid__act[inert] .lg-btn { color: var(--disabled-text); }

/* Rows that open their item (plan §11 #75): the title is the real link. */
.lg-grid__row--link { cursor: pointer; }
.lg-grid__link { color: inherit; font-weight: 500; text-decoration: none; }
.lg-grid__row--link:hover .lg-grid__link { color: var(--primary); text-decoration: underline; text-underline-offset: 0.15em; }
.lg-grid__link:focus-visible { outline: var(--focus-ring) solid var(--focus); outline-offset: 2px; border-radius: var(--radius-pill); }
/* A value in a cell that opens its own list (a scanner's "Checked in 42"):
   blue + underlined like any link, so it reads apart from the row's own link. */
.lg-grid__cell-link { color: var(--primary); text-decoration: underline; text-underline-offset: 0.15em; }
.lg-grid__cell-link:hover { color: var(--primary-hover); }
.lg-grid__cell-link:focus-visible { outline: var(--focus-ring) solid var(--focus); outline-offset: 2px; border-radius: var(--radius-pill); }
.lg-grid__check {
  box-sizing: border-box;
  inline-size: 3.5rem;            /* = the bulk bar's start (below) */
  min-inline-size: 3.5rem;
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
  border-block-end: 1px solid var(--border);
  background: inherit;
}
th.lg-grid__check { border-block-end-color: var(--border-strong); background: var(--surface); }

/* Column widths come from classes, never style="width:…" (reference §3).
   They are minimums; the table shares out the rest and scrolls sideways
   inside its card when it can't fit. */
.lg-col--xs { min-inline-size: 4rem; }
.lg-col--sm { min-inline-size: 8rem; }
.lg-col--md { min-inline-size: 12rem; }
.lg-col--lg { min-inline-size: 16rem; }
.lg-col--xl { min-inline-size: 22rem; }

/* Two-line cells: a name with its email / order number under it. */
/* One line, cut with "…" (an email must never break mid-word); the full text
   is on the item's own page and in the title tooltip. */
.lg-grid__sub {
  display: block;
  max-inline-size: 16rem;          /* Ledger 2 (304): was 18rem; wide grids fit at 1,440px */
  overflow: hidden;
  color: var(--text-muted);
  font-size: var(--size-caption);
  line-height: var(--leading-caption);
  font-weight: 400;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Desktop: a status's reason (Message log failure text) is cut sooner; the full
   text is in its tooltip and on the item's page (Ledger 2, 304: fit at 1,440px). */
@media (min-width: 40em) {
  td[data-phone="status"] .lg-grid__sub { max-inline-size: 14rem; }
}

/* A title cell led by a small visual (the event date-stub on the Events list,
   reference §1b: "first column; card corner on phones"). The gap keeps titles
   lined up when an event has no date yet. */
.lg-grid__lead { display: flex; align-items: center; gap: var(--space-3); min-inline-size: 0; }
.lg-grid__lead-text { display: block; min-inline-size: 0; }
/* A long venue line must not push Status off a 1024px screen (full text in the tooltip). */
.lg-grid__lead-text .lg-grid__sub { max-inline-size: 13rem; }
.lg-grid__lead-gap { flex: none; inline-size: 2.75rem; }
@media (max-width: 39.99em) { .lg-grid__lead-gap { display: none; } }   /* cards: nothing to line up with */

/* Bulk bar: replaces the header area while rows are selected (#74). */
/* Starts right of the checkbox column (3.5rem, border-box), so "select all"
   stays usable: it is the way to unselect the page too. */
.lg-grid__bulk {
  position: absolute;
  inset: 0 0 auto 3.5rem;
  z-index: calc(var(--layer-sticky-head) + 2);   /* over the sticky Actions header too */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-block-size: 2.875rem;
  padding: var(--space-2) var(--space-4);
  border-block-end: 1px solid var(--border-strong);
  border-radius: 0 var(--radius-card) 0 0;
  background: var(--primary-tint);
  color: var(--primary-ink);
}
.lg-grid__bulk-count { margin-inline-end: var(--space-2); font-weight: 600; }

/* Footer. */
.lg-grid__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
  padding: var(--space-3) var(--space-4);
  border-block-start: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--size-label);
}
.lg-grid__range { margin: 0; margin-inline-end: auto; font-variant-numeric: tabular-nums; }
.lg-grid__pager { display: flex; align-items: center; gap: var(--space-2); }
.lg-grid__pager [aria-disabled="true"] {
  border-color: transparent;
  background: var(--disabled-bg);
  color: var(--disabled-text);
  cursor: not-allowed;
}
.lg-grid__pagelist { display: flex; align-items: center; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.lg-grid__pagenum {
  display: inline-grid;
  place-items: center;
  min-inline-size: var(--control-height-sm);
  min-block-size: var(--control-height-sm);
  padding: 0 var(--space-2);
  border-radius: var(--radius-control);
  color: var(--text);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
a.lg-grid__pagenum:hover { background: var(--neutral-tint); }
.lg-grid__pagenum[aria-current="page"] { background: var(--primary-tint); color: var(--primary-ink); font-weight: 600; }
.lg-grid__goto, .lg-grid__size { display: flex; align-items: center; gap: var(--space-2); margin: 0; }
.lg-grid__goto .lg-field__input--sm { inline-size: 3.5rem; }
.lg-grid__pages-link { color: var(--primary); }
.lg-grid__more { display: none; }

/* The phone meta line is a phone-only cell (built by the macro). */
.lg-grid__meta { display: none; }

/* ---------- Phones: two-line rows in one list (Ledger 2, decisions 303, 324; preview §5) ----------
   Line 1: title (bold) + the "key" number right. Line 2: one meta line (the sub
   and fact values joined with commas, cut with "…") + the status pill. Created /
   Modified and empty values are not shown (desktop and the item's page keep them).
   The rows sit in one --surface list with dividers; "Show 25 more" below it. */
@media (max-width: 39.99em) {
  /* The list keeps its --surface card, footer included: "Show 25 more" is a grey
     secondary and those sit only on --surface (decision 313). */
  .lg-grid__frame { overflow: hidden; border-radius: var(--radius-card) var(--radius-card) 0 0; }
  .lg-grid__scroll { overflow: visible; }
  .lg-grid--sticky .lg-grid__scroll { max-block-size: none; }
  .lg-grid__table, .lg-grid__table tbody { display: block; }
  .lg-grid__table thead { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .lg-grid__row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "check title key act" "check meta status act";
    align-items: center;
    column-gap: var(--space-3);
    row-gap: 0.125rem;
    min-block-size: 3.5rem;
    padding: var(--space-3) var(--space-4);
    border-block-end: 1px solid var(--border);
  }
  .lg-grid__row:last-child { border-block-end: 0; }
  /* No checkbox column (a grid without bulk actions): no empty first column. */
  .lg-grid__row:not(:has(> [data-phone="check"])) {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas: "title key act" "meta status act";
  }
  .lg-grid__row:hover { background: var(--surface); }
  .lg-grid__row:has([data-lg-select]:checked) { background: var(--row-selected); }
  .lg-grid__row > * { display: block; min-inline-size: 0; padding: 0; border: 0; text-align: start; white-space: normal; }
  .lg-grid__row > td[data-phone="check"] { grid-area: check; align-self: start; inline-size: auto; padding-block-start: 0.125rem; }
  .lg-grid__row > [data-phone="title"] { grid-area: title; font-weight: 600; overflow-wrap: anywhere; }
  .lg-grid__row .lg-grid__sub { max-inline-size: 100%; }   /* still one line + "…": an email never breaks mid-word */
  .lg-grid__row > td[data-phone="key"] { grid-area: key; justify-self: end; text-align: end; white-space: nowrap; }
  .lg-grid__row > td.lg-grid__meta {
    grid-area: meta;
    overflow: hidden;
    color: var(--text-muted);
    font-size: var(--size-caption);
    line-height: var(--leading-caption);
    font-family: var(--font-sans);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* One line of plain text: a cell's own second line (email under a name, time
     under a date) follows after a comma, in the line's sans type. */
  .lg-grid__meta :not(.lg-pill, .lg-pill *) { display: inline; font: inherit; color: inherit; }
  .lg-grid__meta .lg-grid__sub::before { content: ", "; }
  .lg-grid__row > td[data-phone="status"] { grid-area: status; justify-self: end; }
  /* A status with a reason under it (Message log: the failure text) gets its own
     full-width line under the row; in the auto column it took the whole row and
     squeezed the name to one letter per line (decision 310, audit P0-3). */
  .lg-grid__row > td[data-phone="status"]:has(.lg-grid__sub) { grid-area: auto / 1 / auto / -1; justify-self: stretch; }
  .lg-grid__row > td[data-phone="status"] .lg-grid__sub { white-space: normal; overflow-wrap: break-word; }
  /* The sub and fact cells are on the meta line instead. */
  .lg-grid__row > td:is([data-phone="sub"], [data-phone="fact"], [data-phone="hide"]) { display: none; }
  /* ⋯ sits top-right (the row itself opens the item). */
  .lg-grid__row > td[data-phone="action"] { grid-area: act; align-self: center; margin-inline-end: calc(-1 * var(--space-2)); }
  .lg-grid__row > [class*="lg-col--"] { inline-size: auto; }

  .lg-grid__bulk { position: sticky; inset-block-start: calc(var(--bar-height) + env(safe-area-inset-top)); border-radius: var(--radius-card); margin-block-end: var(--space-3); }

  /* "Show 25 more" replaces the Rows select and the page numbers (303, #73). */
  .lg-grid__foot { flex-direction: column; align-items: stretch; padding: var(--space-3) var(--space-4) var(--space-4); }
  .lg-grid__range { margin: 0; text-align: center; }
  .lg-grid__more { display: inline-flex; }
  .lg-grid__foot:has(.lg-grid__more) .lg-grid__pager,
  .lg-grid__goto, .lg-grid__pagelist, .lg-grid__size { display: none; }
  .lg-grid__pager { justify-content: space-between; }
}
