Components · Lists
How a record reads when it isn't a table — a real semantic <dl> of roster field → value pairs, the description list behind every profile and inspector. Each dt/dd is wrapped in a pair so the list flows two-up on a wide surface and collapses to a single column on narrow — the labels sit left and faint, the values right and tabular-nums. A value is whatever the field is: plain text, an accent link, a team dot, a status Badge — or a quiet em-dash when the field is empty, never a blank. The stacked variant puts the term over the value for a tight drawer column.
A genuine <dl> — each dt/dd lives in a .pair wrapper (valid inside a dl), so the list is a two-column grid that becomes one column at ≤640px. dt faint / left, dd tabular / right of the label rail, over a --rule hairline. The empty Vehicle field renders an em-dash, not a gap; the Email link is pinned :hover — tab / hover the rest live.
The same <dl> pairs restacked — an uppercase term over its value, single column, for a sidebar or drawer where a two-up grid would be too wide. Same value flavours (Badge, team dot, mono id); only the label placement changes.
<dl>; each <dt>/<dd> is wrapped in a .pair <div> (valid dl grouping) so the list can be a grid — screen readers still read term → definition.grid-template-columns: 1fr 1fr two-up on a wide surface, collapsing to a single column at ≤640px. Bottom-row hairlines drop per breakpoint so the list never ends on a rule.font-[540] faint, on a minmax(6.5rem,8.5rem) label rail; dd tabular-nums, wraps on word-break. In the stacked variant the dt is an uppercase eyebrow above the value.—), keeping the row present and the alignment intact — the record shows the field exists but is unset, rather than dropping it.Source · @phauna/ds DefGrid / KeyValue (the <dl> + label-rail pattern) · MembershipInspector.tsx + OnboardingInspector.tsx field rows · Badge tones · --color-rule from globals.css. Companion to the Key/value & metadata card.