/* ===========================================================================
 * DD02 StatCard · DD03 SectionCard · DD04 Leaderboard · DD05 Donut ·
 * DD06 Table · DD07 Timeline · DD08 BadgeGrid · DD10 DecisionThread.
 *
 * These are the components the dashboard and the history log are made of. They
 * all obey the same two rules as everything else: washes for depth, 12%
 * hairlines for separation, and no shadow anywhere.
 * ======================================================================== */

/* --- DD02 Stat card — a title over key/value rows split by 12% hairlines.
       Values are 16/600 and right-aligned so a column of them scans. ------ */
.ui-stat-list { display: flex; flex-direction: column; }

.ui-stat-list__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: var(--border-width) solid var(--divider);
}

.ui-stat-list__row:last-child { border-bottom: 0; padding-bottom: 0; }
.ui-stat-list__row:first-child { padding-top: 0; }

/* A label is a name and is never broken across lines; in a narrow column the
   VALUE wraps instead ("Named / trophy" beside a long trophy name read as two
   labels). The value may be one unbroken run — a pasted name — so it may
   break anywhere rather than push the row wider. */
.ui-stat-list__label {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  color: var(--text-tertiary);
}

.ui-stat-list__value {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--type-body-lg-size);
  line-height: var(--type-body-lg-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  text-align: right;
}

.ui-stat-list__value--gold { color: var(--gold-100); }

/* --- DD04 Leaderboard / activity feed ----------------------------------
 * One construction serves both. A 2px left rule replaces the bullet or the
 * rank badge another system would use; #1 takes gold and the rest take the
 * divider colour, so the ranking is legible before any number is read.
 * --------------------------------------------------------------------- */
.ui-rank-list { display: flex; flex-direction: column; gap: var(--space-3); list-style: none; margin: 0; padding: 0; }

.ui-rank-list__item {
  border-left: var(--rule-width) solid var(--divider-strong);
  padding-left: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.ui-rank-list__item--lead { border-left-color: var(--gold-100); }

.ui-rank-list__title {
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.ui-rank-list__meta {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

/* --- DD05 Donut ---------------------------------------------------------
 * Gold arc on a 12% groove with rounded caps, and the percentage at 24/600 in
 * the middle. Drawn as an SVG rather than a conic-gradient because the rounded
 * end knobs are the detail that makes it look drawn rather than computed, and
 * a conic gradient cannot round its own ends.
 * --------------------------------------------------------------------- */
.ui-donut { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }

.ui-donut__figure { position: relative; width: var(--donut-size); height: var(--donut-size); }
.ui-donut__svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ui-donut__groove { stroke: var(--divider); }
.ui-donut__arc { stroke: var(--gold-100); transition: stroke-dashoffset var(--duration-base) var(--easing-standard); }

.ui-donut__centre {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--type-display-size);
  line-height: var(--type-display-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.ui-donut__caption {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
  text-align: center;
}

/* --- DD06 Table ---------------------------------------------------------
 * 40px eyebrow header on a 5.5% wash, 56px body rows (48 in the admin
 * shells, D177), 12% dividers, numeric columns right-aligned, trailing 24px
 * icon actions with no container, and a chevron column on an interactive
 * table.
 * --------------------------------------------------------------------- */
.ui-table-wrap { overflow-x: auto; }

.ui-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
}

/* The header is the top of the table, square, in the eyebrow voice (D177).
   It had rounded end cells and read as a lozenge floating inside its card,
   and at 14px semibold it did not read as a header at all. */
.ui-table th {
  height: var(--table-header-height);
  padding: 0 var(--space-4);
  background: var(--surface-header);
  border-bottom: var(--border-width) solid var(--divider);
  text-align: left;
  font-size: var(--type-eyebrow-size);
  line-height: var(--type-eyebrow-leading);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-weight: var(--font-weight-semibold);
  color: var(--text-tertiary);
  white-space: nowrap;
}

/* Inside a padded card the header band stays a rounded band, inset from the
   card's edges. Where the table is its card's whole content (a flush card,
   D177) the header is the card's top edge: square, and its first and last
   cells line up with the frame's inner edge. */
.ui-table th:first-child { border-top-left-radius: var(--radius-md); border-bottom-left-radius: var(--radius-md); }
.ui-table th:last-child { border-top-right-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); }

.ui-card--flush .ui-table th { border-radius: 0; }
.ui-card--flush .ui-table th:first-child,
.ui-card--flush .ui-table td:first-child { padding-left: var(--space-5); }
.ui-card--flush .ui-table th:last-child,
.ui-card--flush .ui-table td:last-child { padding-right: var(--space-5); }

.ui-table td {
  height: var(--table-row-height);
  padding: 0 var(--space-4);
  border-bottom: var(--border-width) solid var(--divider);
  color: var(--text-secondary);
}

.ui-table tbody tr:last-child td { border-bottom: 0; }

/* Denser in the admin shells, where a table is read, not tapped (D177). */
.shell--admin .ui-table td { height: var(--table-row-height-dense); }

/* A row's subject over a quieter second line. */
.ui-table__note {
  display: block;
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  font-weight: var(--font-weight-regular);
  color: var(--text-tertiary);
}

.ui-table .ui-table__cell--truncate { max-width: var(--table-truncate-width); }

.ui-table__clip {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The chevron column: the table's own, on every interactive table. */
.ui-table .ui-table__chevron {
  width: var(--table-chevron-width);
  padding-left: 0;
  text-align: right;
  color: var(--text-tertiary);
}

.ui-table .ui-table__chevron .icon { vertical-align: middle; transition: transform var(--duration-fast) var(--easing-standard); }
.ui-table--interactive tbody tr:hover .ui-table__chevron { color: var(--text-primary); }
.ui-table--interactive tbody tr:hover .ui-table__chevron .icon { transform: translateX(var(--space-1)); }

/* A list with nothing in it keeps its header and says so in one row. */
.ui-table .ui-table__empty {
  height: auto;
  padding: var(--space-8) var(--space-5);
  text-align: center;
  color: var(--text-tertiary);
}

.ui-table--interactive tbody tr.ui-table__empty-row:hover { background: none; cursor: default; }

/* Inside the frame, under the rows: where this page sits, and the pager. */
.ui-table__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--table-footer-height);
  padding: var(--space-2) var(--space-5);
  border-top: var(--border-width) solid var(--divider);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

.ui-table__count { font-variant-numeric: tabular-nums; }

/* Scoped to `.ui-table` so these beat `.ui-table th`, which sets `text-align:
   left` for the header row. Unscoped they are one class against a class plus an
   element and LOSE — so a numeric column's values were right-aligned under a
   left-aligned heading, which is exactly the misalignment a right-aligned
   column exists to avoid. Shipped that way since the component library landed;
   the Credits column in the DD06 catalogue section shows it. */
.ui-table .ui-table__cell--numeric { text-align: right; font-variant-numeric: tabular-nums; }
.ui-table .ui-table__cell--primary { color: var(--text-primary); font-weight: var(--font-weight-semibold); }
/* A row of icon actions, laid out rather than left to inline flow. `button_to`
   renders a <form>, which is display:block — so a destroy action beside an edit
   link wrapped onto its own line and the column grew to two rows tall. The flex
   row also keeps `nowrap`'s promise, which `white-space` alone cannot make once
   a block-level child is in the cell. */
.ui-table .ui-table__cell--actions {
  text-align: right;
  white-space: nowrap;
}

.ui-table .ui-table__cell--actions > * {
  display: inline-flex;
  vertical-align: middle;
}

/* 4% — quieter than a menu item's 7%, because twenty rows are on screen and
   the wash has to survive being next to nineteen others. */
.ui-table--interactive tbody tr:hover { background: var(--surface-hover-row); cursor: pointer; }

/* A row action is a bare 24px icon with no container (component-list §2). */
.ui-table__action {
  display: inline-flex;
  padding: var(--space-1);
  margin-left: var(--space-2);
  color: var(--text-tertiary);
  background: none;
  border: 0;
  border-radius: var(--radius-control);
  cursor: pointer;
}

.ui-table__action:hover { color: var(--gold-100); }
.ui-table__action:focus-visible { outline: var(--focus-ring-outline); outline-offset: var(--focus-ring-offset); outline-color: var(--focus-colour-neutral); }


/* --- DD07 Timeline ------------------------------------------------------ */
.ui-timeline { list-style: none; margin: 0; padding: 0; }

.ui-timeline__item { display: flex; gap: var(--space-4); }

/* The rail is drawn on the node column rather than as a pseudo-element on the
   item, so the last item's rail stops at its own dot instead of running on
   into whatever follows the list. */
.ui-timeline__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: none;
  width: var(--space-3);
}

.ui-timeline__node {
  width: var(--space-3);
  height: var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--gold-100);
  flex: none;
  margin-top: var(--space-2);
}

.ui-timeline__line { width: var(--rule-width); flex: 1; background: var(--divider-strong); margin-top: var(--space-2); }
.ui-timeline__item:last-child .ui-timeline__line { display: none; }

.ui-timeline__body {
  flex: 1;
  display: flex;
  gap: var(--space-3);
  align-items: center;
  padding-bottom: var(--space-4);
}

.ui-timeline__text { display: flex; flex-direction: column; gap: var(--space-1); }

/* An entry with an href is a link ROW, not a link title. `min-width: 0` on the
   text block so a long award name wraps inside the row instead of pushing the
   chevron off a 393px column. D28: hover changes the fill, never the opacity. */
.ui-timeline__body--link {
  border-radius: var(--radius-md);
  padding: var(--space-2);
  margin: calc(var(--space-2) * -1);
  margin-bottom: var(--space-2);
  color: inherit;
  text-decoration: none;
}

.ui-timeline__body--link .ui-timeline__text { min-width: 0; flex: 1; }

/* Hover only where there is a pointer that hovers. On a phone WebKit leaves
   :hover on whatever sat under the last tap, and the next page renders under
   the same finger, so its first row stayed lit. A tap gets :active instead
   (iOS applies it only because application.js listens for touchstart). */
@media (hover: hover) {
  .ui-timeline__body--link:hover { background: var(--gold-wash-hover); text-decoration: none; }
}

.ui-timeline__body--link:active { background: var(--gold-wash-hover); }

.ui-timeline__body--link:focus-visible {
  outline: var(--focus-ring-outline);
  outline-offset: var(--focus-ring-offset);
}

/* The visible half of the row-level affordance. Muted until the row is
   hovered, so a list of ten does not read as ten gold arrows. */
.ui-timeline__chevron {
  display: flex;
  margin-left: auto;
  color: var(--text-tertiary);
}

.ui-timeline__body--link:hover .ui-timeline__chevron { color: var(--text-gold); }

.ui-timeline__title {
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  /* A plaque line may run to 120 characters with no space in it (D155). */
  overflow-wrap: anywhere;
}

.ui-timeline__meta {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

/* Compact: the cabinet's INDEX under the strip (D124). The strip is the
   display, so each row here drops to one line of title and one of meta, with
   no thumbnail and a tighter rhythm — a player with thirty awards scans it
   rather than scrolls it. */
.ui-timeline--compact .ui-timeline__body { min-width: 0; padding-bottom: var(--space-2); }
.ui-timeline--compact .ui-timeline__body--link { margin-bottom: 0; }
.ui-timeline--compact .ui-timeline__node { margin-top: var(--space-1); }
.ui-timeline--compact .ui-timeline__text { gap: 0; min-width: 0; flex: 1; }

.ui-timeline--compact .ui-timeline__title,
.ui-timeline--compact .ui-timeline__meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- DD09 Cabinet strip ------------------------------------------------
 * A sideways row of troph-e cards, snapped by CSS alone (D124). The card is
 * narrower than the column, so the next one peeks in at the edge — the only
 * signal a reader gets that the row scrolls.
 *
 * THE PADDING IS FOR THE FOCUS RING. A scroll container clips at its padding
 * box, so a card flush against the edge would lose the outside of its D30
 * ring. The padding is exactly ring plus offset, the negative margin puts the
 * cards back on the column's edge, and `scroll-padding` makes a snapped card
 * land there too.
 * --------------------------------------------------------------------- */
.ui-cabinet-strip {
  display: flex;
  gap: var(--space-3);
  margin: calc(var(--space-1) * -1);
  padding: var(--space-1);
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--space-1);
  /* The thin light thumb, the one scrollbar the mocks draw (see FM10). Kept
     rather than hidden: on a touch screen it is invisible anyway, and with a
     mouse it is the only way to reach the fourth card. */
  scrollbar-width: thin;
  scrollbar-color: var(--border-raised) transparent;
}

.ui-cabinet-strip__item {
  flex: 0 0 calc(100% - var(--space-16));
  max-width: var(--cabinet-card-max);
  /* Without this a long club name's min-content width overrides the basis and
     widens the card, eating the peek that says the row scrolls. */
  min-width: 0;
  scroll-snap-align: start;
  display: flex;
}

.ui-cabinet-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
  background: var(--surface-1);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-lg);
  overflow: hidden;
  color: inherit;
  text-decoration: none;
}

.shell--player .ui-cabinet-card { border-radius: var(--radius-md); }

/* D28: hover changes the fill, one wash level up — the interactive card's own
   rule. Pointer hover only, for the timeline's reason above. */
@media (hover: hover) {
  .ui-cabinet-card:hover { background: var(--surface-2); text-decoration: none; }
}

.ui-cabinet-card:active { background: var(--surface-2); }

/* D30: gold, because the card is a neutral wash and not a gold fill. */
.ui-cabinet-card:focus-visible,
.ui-cabinet-card.is-focus {
  outline: var(--focus-ring-outline);
  outline-offset: var(--focus-ring-offset);
  outline-color: var(--focus-colour-neutral);
}

/* The render plate: CONTENT, not chrome (F08). Square, because the pending
   state has no picture to take a ratio from and the card must not change
   height when one arrives. */
.ui-cabinet-card__art {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  background: var(--plate-render);
}

.ui-cabinet-card__art--placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  color: var(--text-muted);
}

.ui-cabinet-card__note {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
}

.ui-cabinet-card__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4) var(--space-4);
  min-width: 0;
}

/* Two lines for the award, one for each meta line. A long club name must
   neither widen the card nor push the date out of it. */
.ui-cabinet-card__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  /* Break an unbroken 120-character line (D155) so the clamp has two lines to
     work with, rather than clipping one. */
  overflow-wrap: anywhere;
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.ui-cabinet-card__meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

/* --- DD08 Badge grid ----------------------------------------------------
 * Two columns, 16px gap, --surface-2 tiles. A locked badge is the whole tile
 * at 50% — not a greyed icon, because the label matters as much as the glyph:
 * knowing what you have not earned yet is the point of showing it.
 * --------------------------------------------------------------------- */
.ui-badge-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

.ui-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--surface-2);
  border-radius: var(--radius-md);
  text-align: center;
}

.ui-badge .icon { color: var(--gold-100); }

.ui-badge__label {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-secondary);
}

.ui-badge--locked { opacity: 0.5; }
.ui-badge--locked .icon { color: var(--text-tertiary); }

/* The real link inside an interactive row's primary cell.
 *
 * The row is clickable through row_link_controller, but a <tr> cannot be
 * focused, does not appear in a screen reader's link list, and cannot be
 * opened in a new tab. This is the control that can. It inherits the cell's
 * colour so the row still reads as one object rather than as a link with some
 * text beside it. */
.ui-table__link {
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
}

.ui-table__link:hover { color: inherit; text-decoration: none; }

.ui-table__link:focus-visible {
  outline: var(--focus-ring-outline);
  outline-offset: var(--focus-ring-offset);
  outline-color: var(--focus-colour-neutral);
}

/* --- DD10 Decision thread — one open decision as a collapsible row (D126,
       D127). A native <details>: the row opens from an anchor with no
       JavaScript. Collapsed it is one line — id, question, status — so a page
       of twenty questions scans; open, it carries the context, the thread and
       the form. The settling answer is marked in gold and nothing else: gold is
       the only chromatic colour in the chrome, and an "answered" green would
       be a second one. --------------------------------------------------- */
.ui-decision {
  background: var(--surface-1);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-lg);
}

.shell--player .ui-decision { border-radius: var(--radius-md); }

.ui-decision[open] { border-color: var(--border-raised); }

.ui-decision__summary {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  cursor: pointer;
  list-style: none;
}

.ui-decision__summary::-webkit-details-marker { display: none; }
.ui-decision__summary:hover,
.ui-decision.is-hover > .ui-decision__summary { background: var(--surface-hover-row); }

.ui-decision__summary:focus-visible,
.ui-decision.is-focus > .ui-decision__summary {
  outline: var(--focus-ring-outline);
  outline-color: var(--focus-colour-neutral);
  outline-offset: var(--focus-ring-offset);
}

.ui-decision__id {
  flex: none;
  color: var(--text-gold);
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  font-weight: var(--font-weight-semibold);
  white-space: pre;
}

.ui-decision__ask {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  color: var(--text-primary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
}

/* What an answered question chose, on the collapsed row — so the Answered
   list reads as answers without opening each one. */
.ui-decision__summary-choice {
  color: var(--text-secondary);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
}

.ui-decision__status,
.ui-decision__chevron { flex: none; align-self: center; }

.ui-decision__chevron {
  color: var(--text-tertiary);
  transition: transform var(--duration-fast) var(--easing-standard);
}

.ui-decision[open] .ui-decision__chevron { transform: rotate(180deg); }

.ui-decision__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: var(--border-width) solid var(--divider);
}

/* Stacked label-above-value, not key/value rows: these are paragraphs, and a
   right-aligned value against a label reads as truncated. */
.ui-decision__fields { display: flex; flex-direction: column; gap: var(--space-3); }
.ui-decision__field,
.ui-decision__section { display: flex; flex-direction: column; gap: var(--space-2); }

.ui-decision__label {
  color: var(--text-tertiary);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
}

.ui-decision__value {
  color: var(--text-primary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
}

.ui-decision__thread { display: flex; flex-direction: column; gap: var(--space-3); }

.ui-decision__answer {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--surface-2);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-md);
}

/* The one answer that moved the question: a gold border, the selection
   language (§2.3), and a gold label. No new hue. */
.ui-decision__answer--settling {
  border-color: var(--gold-rest);
  background: var(--gold-wash-selected);
}

.ui-decision__settles {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--text-gold);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  font-weight: var(--font-weight-semibold);
}

/* The option an answer picked leads it, at the weight of a title: it IS the
   answer, and the note beneath it is commentary. */
.ui-decision__chosen {
  color: var(--text-primary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  font-weight: var(--font-weight-semibold);
}

/* pre-line: an answer keeps the paragraphs it was typed with. overflow-wrap:
   a pasted URL must not push the card wider than the column. */
.ui-decision__answer-text {
  color: var(--text-primary);
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.ui-decision__meta,
.ui-decision__empty,
.ui-decision__hint {
  color: var(--text-tertiary);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
}

/* The register entry for Harley — a closed disclosure inside the open row, so
   a founder reading the thread does not meet markdown by default. */
.ui-decision__amendment-summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: fit-content;
  border-radius: var(--radius-sm);
  cursor: pointer;
  list-style: none;
}

.ui-decision__amendment-summary::-webkit-details-marker { display: none; }
.ui-decision__amendment-summary:hover .ui-decision__label { color: var(--text-secondary); }

.ui-decision__amendment-summary:focus-visible {
  outline: var(--focus-ring-outline);
  outline-color: var(--focus-colour-neutral);
  outline-offset: var(--focus-ring-offset);
}

.ui-decision__amendment-chevron {
  color: var(--text-tertiary);
  transition: transform var(--duration-fast) var(--easing-standard);
}

.ui-decision__amendment[open] .ui-decision__amendment-chevron { transform: rotate(180deg); }

.ui-decision__amendment-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.ui-decision__snippet {
  margin: 0;
  padding: var(--space-4);
  background: var(--surface-2);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ui-decision__form { gap: var(--space-4); }

/* The option cards: a bare fieldset, so the group is a real radio group with
   a legend, and the cards themselves are FM08's — one selection language. */
.ui-decision__options {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.ui-decision__legend {
  padding: 0;
  margin-bottom: var(--space-3);
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

/* Submitted with neither an option nor a note. Brick on the unselected cards'
   borders and a quiet brick wash, as an invalid input has (D27). */
.ui-decision__options--invalid .ui-choice-card {
  border-color: var(--danger-border);
  background: var(--danger-field-wash);
}

.ui-decision__error {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--danger-text);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
}

.ui-decision__actions { display: flex; justify-content: flex-end; }

/* --- DD11 Stat tile (D178) ------------------------------------------------
 * One label, one figure, an optional note. A row of them is equal height by
 * construction, which a row of stat-list cards never was. */
.ui-stat-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--stat-tile-min), 1fr));
  gap: var(--space-4);
}

.ui-stat-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
  border: var(--border-width) solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  color: inherit;
  text-decoration: none;
}

.ui-stat-tile__label {
  font-size: var(--type-eyebrow-size);
  line-height: var(--type-eyebrow-leading);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-weight: var(--font-weight-semibold);
  color: var(--text-tertiary);
}

.ui-stat-tile__value {
  font-size: var(--type-stat-size);
  line-height: var(--type-stat-leading);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.ui-stat-tile__note {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

.ui-stat-tile--gold .ui-stat-tile__value { color: var(--gold-100); }

.ui-stat-tile--link { transition: background-color var(--duration-fast) var(--easing-standard); }
.ui-stat-tile--link:hover,
.ui-stat-tile--link.is-hover { background: var(--surface-2); }
.ui-stat-tile--link:focus-visible,
.ui-stat-tile--link.is-focus {
  outline: var(--focus-ring-outline);
  outline-offset: var(--focus-ring-offset);
  outline-color: var(--focus-colour-neutral);
}

/* --- DD12 Fact list (D178) ------------------------------------------------
 * A record's facts in a rail: label over value, stacked, left-aligned. */
.ui-facts {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
}

.ui-facts__row { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }

.ui-facts__label {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

.ui-facts__value a { color: var(--text-gold); text-decoration: none; }
.ui-facts__value a:hover { text-decoration: underline; }

.ui-facts__value {
  margin: 0;
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* --- F10 Avatar (D187) — a person's initials on a round wash. Nobody has a
       photo, so this is the whole avatar, not a fallback for one. -------- */
.ui-avatar {
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  border: var(--border-width) solid var(--border-default);
  color: var(--text-primary);
  font-weight: var(--font-weight-semibold);
  line-height: 1;
}

.ui-avatar--sm {
  width: var(--avatar-sm);
  height: var(--avatar-sm);
  font-size: var(--type-caption-size);
}

.ui-avatar--md {
  width: var(--avatar-md);
  height: var(--avatar-md);
  font-size: var(--type-body-size);
}

/* --- DD13 Comment (D187) — initials, a name and a time on one line, the
       words under them, and small text controls under those. ----------- */
.ui-comment {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.ui-comment__main {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.ui-comment__header {
  margin: 0;
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  overflow-wrap: anywhere;
}

.ui-comment__author {
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.ui-comment__author--link:focus-visible {
  outline: var(--focus-ring-outline);
  outline-offset: var(--focus-ring-offset);
}

.ui-comment__time {
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-leading);
  color: var(--text-tertiary);
}

.ui-comment__body {
  font-size: var(--type-body-size);
  line-height: var(--type-body-leading);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

.ui-comment__body p { margin: 0; }
.ui-comment__body p + p { margin-top: var(--space-2); }

/* Text buttons, pulled left so their label lines up with the words above. */
.ui-comment__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-left: calc(var(--space-3) * -1);
}
