/**
 * DHCW Single Record — Stat card
 * Reference HTML/CSS implementation, matched to the Figma "Stat Card" set
 * (431:11996) on page 1517:15118. Consumes @dhcw/sr-tokens.
 *
 * One number, named. A dashboard made of these is a pattern; the card itself is
 * a component, which is why it lives here and the dashboard does not.
 *
 * Anatomy — a two-column grid, content on the left and the icon on the right:
 *   .sr-stat-card          — the card: surface, radius, shadow, optional accent
 *   .sr-stat-card__label   — what the number counts
 *   .sr-stat-card__value   — the number
 *   .sr-stat-card__support — one supporting line: a period, a note, a change
 *   .sr-stat-card__delta   — the signed change inside the supporting line
 *   .sr-stat-card__icon    — decorative, 20x20, hidden from AT
 *
 * The icon is a grid child pinned to the top of the right-hand column, NOT a
 * sibling of the label. It used to sit inside a `__head` row with the label,
 * which meant the value-first layout carried the icon down the card with it —
 * the icon belongs to the card, not to whichever text happens to be first.
 *
 * Layouts, replacing the five `Type` variants the Figma set enumerates
 * (DDR-031). Figma's Title Top / Title_Hint / Trend are one layout with and
 * without a supporting line, so they collapse:
 *   (default)                  — label, value, optional supporting line
 *   .sr-stat-card--value-first — value, then label. Figma `Count Top`
 *   .sr-stat-card--inline      — value and label on one row. Figma `Single line`
 *
 * The accent bar is OPT-IN. The default card has no bar, matching Figma's
 * `Border=Hidden` variants, which are the ones reached for most often.
 *
 * The card is NOT interactive. It has no hover, no focus and no role. If a
 * number should open something, put a Link under it or make the whole tile a
 * Button — a div with a click handler is neither, and this component will not
 * grow into one.
 */

.sr-stat-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-2);
  row-gap: var(--space-1);
  align-content: start;
  box-sizing: border-box;
  /* Surface/Small Cards, which is what all ten Figma variants are bound to. It
     was section-cards here until 2026-09-16 — the same value in both modes, so
     nothing looked wrong, but it meant the dark-mode card had no plane of its
     own. See the dark-mode block at the foot of this file. */
  background-color: var(--sr-color-surface-small-cards);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-raised);

  /* The accent bar is always in the box, transparent when there is no accent,
     and the left padding is short by its width. An accented card and a plain
     one are then the same size and inset their text alike, which is what lets
     the two sit in one row without the text stepping 4px sideways. */
  border-left: 4px solid transparent;
  padding: var(--space-4);
  padding-left: calc(var(--space-4) - 4px);
}

/* ---------- Accent: opt-in emphasis ----------
   Emphasis, not status on its own. A bar that changes colour and nothing else
   carries meaning in colour alone (SC 1.4.1), so a warning or critical card
   must also say so in the supporting line — the accent reinforces the words, it
   does not replace them. See the guidelines. */
.sr-stat-card--accent-primary { border-left-color: var(--sr-color-interactive-primary); }
.sr-stat-card--accent-warning { border-left-color: var(--sr-color-status-warning); }
.sr-stat-card--accent-critical { border-left-color: var(--sr-color-status-critical); }

/* ---------- Content ----------
   Rows are explicit rather than auto-placed, so a layout modifier can move the
   value above the label without dragging the icon along with it. */

/* Figma draws the label in Interactive/Primary. It is not that here, for two
   reasons: nothing on this card is interactive, and in dark mode the dark-mode
   primary lands at 2.07:1 on the dark card surface. Text/Primary is the correct
   semantic and clears 4.5:1 in both modes; the hierarchy is carried by size. */
.sr-stat-card__label {
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  font: var(--sr-type-label-font);
  letter-spacing: var(--sr-type-label-letter-spacing);
  color: var(--sr-color-text-primary);
}

.sr-stat-card__value {
  grid-column: 1;
  grid-row: 2;
  margin: 0;
  font: var(--sr-type-heading-m-font);
  letter-spacing: var(--sr-type-heading-m-letter-spacing);
  color: var(--sr-color-text-primary);
  /* A column of stat cards is read down the digits, so they have to line up. */
  font-variant-numeric: tabular-nums;
}

.sr-stat-card__support {
  grid-column: 1;
  grid-row: 3;
  margin: 0;
  font: var(--sr-type-caption-font);
  letter-spacing: var(--sr-type-caption-letter-spacing);
  color: var(--sr-color-text-secondary);
}

/* Decorative. The label already names the number, so an icon that repeats it
   adds nothing to a screen reader and is marked aria-hidden in the markup.
   Pinned to the top of the card in every layout. */
.sr-stat-card__icon {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  display: inline-flex;
  width: 20px;
  height: 20px;
  color: var(--sr-color-text-secondary);
}
.sr-stat-card__icon svg { width: 100%; height: 100%; }

/* The signed change, as a small tinted chip rather than coloured text.
   Status text straight onto the card surface is a pair the token set does not
   support: the status colours are deliberately pinned to their light-mode 700
   steps "because status surfaces stay light in dark mode", so `status/critical`
   on a dark card is 1.97:1. On its own status surface it is a pair the system
   already asserts and already passes, in both modes — so the delta carries its
   surface with it.

   Colour is still the second signal, never the first: the sign is part of the
   text, so "-5%" reads as a fall in greyscale, to a screen reader, and to
   someone who cannot tell the red from the green. Figma draws the delta bolder;
   it is not bolded here because the scale has no bold caption (DDR-005). */
.sr-stat-card__delta {
  display: inline-block;
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
}
.sr-stat-card__delta--up {
  color: var(--sr-color-status-success);
  background-color: var(--sr-color-status-success-surface);
}
.sr-stat-card__delta--down {
  color: var(--sr-color-status-critical);
  background-color: var(--sr-color-status-critical-surface);
}
/* A movement that is neither good nor bad — a count that simply changed. No
   chip, because a neutral tint would be a colour that means nothing. */
.sr-stat-card__delta--neutral { color: var(--sr-color-text-secondary); }

/* ---------- Value first (Figma `Count Top`) ----------
   The number leads and the label explains it. For a row of cards scanned as
   numbers rather than read as sentences. Only the two text rows swap; the icon
   keeps row 1 of column 2 and stays at the top of the card. */
.sr-stat-card--value-first .sr-stat-card__value { grid-row: 1; }
.sr-stat-card--value-first .sr-stat-card__label { grid-row: 2; }

/* ---------- Inline (Figma `Single line`) ----------
   One row, and deliberately the short card: roughly 40px against the stacked
   card's ~100px. For a strip above a table, a toolbar, or a phone screen where
   a full card would take the space the content needs.

   `align-self: start` is what keeps it short. Grid items stretch to the tallest
   in their row by default, so an inline card sharing a row with a stacked one
   was being pulled to the stacked card's height — short in its own markup and
   not short on the page, which is the only place it matters. */
.sr-stat-card--inline {
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: baseline;
  align-self: start;
  column-gap: var(--space-2);
  row-gap: 0;
  padding: var(--space-2) var(--space-3);
  padding-left: calc(var(--space-3) - 4px);
}
/* The number leads, as the Figma variant draws it. */
.sr-stat-card--inline .sr-stat-card__value {
  grid-column: 1;
  grid-row: 1;
  font: var(--sr-type-heading-s-font);
  letter-spacing: var(--sr-type-heading-s-letter-spacing);
}
.sr-stat-card--inline .sr-stat-card__label {
  grid-column: 2;
  grid-row: 1;
  color: var(--sr-color-text-secondary);
}
.sr-stat-card--inline .sr-stat-card__support { grid-column: 3; grid-row: 1; }
/* No icon at this size: it would be the widest thing in the card and say the
   least. The React component drops it from the markup; this is the backstop for
   hand-written HTML. */
.sr-stat-card--inline .sr-stat-card__icon { display: none; }

/* ---------- Dark mode: everything on the card goes white ----------
   In dark mode Surface/Small Cards is Cyan/850, the teal that makes a stat tile
   read as its own plane against the navy section card behind it (2.70:1, where
   the two matching left it at 1.00:1). See DDR-033.

   Cyan/850 sits in the middle of the luminance range, so almost nothing reads
   on it. White is 4.87:1 — over the 4.5:1 line, but only just, and there is no
   headroom below it: `text/secondary` is 3.56:1, and the lightest grey that
   still reads as grey is under the line too. The full table is in DDR-033.
   So the secondary line cannot stay secondary *by colour* here. It takes
   `text/on-fill`, which is white in both modes precisely for saturated fills,
   and the hierarchy is carried by size instead — 24px value, 14px label, 12px
   support, which is a stronger signal than the tint was anyway.

   This is also why this surface is text-only. A border, a control outline or an
   interactive fill on the teal is under 2:1 and cannot be fixed by choosing a
   different stop, which is what keeps checkbox cards, radio cards, the search
   menu and the footer on section-cards. */
[data-theme="dark"] .sr-stat-card__support,
[data-theme="dark"] .sr-stat-card__icon,
[data-theme="dark"] .sr-stat-card__delta--neutral,
[data-theme="dark"] .sr-stat-card--inline .sr-stat-card__label {
  color: var(--sr-color-text-on-fill);
}

/* ---------- Row of cards ----------
   Provided because every use of this component so far has been a row of them,
   and a grid written from scratch each time is a grid that drifts. Stacked
   cards share a height so their accent bars line up; inline cards opt out. */
.sr-stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4);
}

/* A strip of inline cards: they size to their content rather than sharing a
   twelfth of the width, and wrap onto another line when the row runs out. */
.sr-stat-cards--inline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
