ComponentsList
List
atomRows of items with lead media, meta and trailing actions or badges.
Library
Your files and account.
Storage
Account
Recipe CSS
This is the exact CSS your kit ships for List — token-driven, so it re-themes with every knob. Get it (and the rest) from the configurator's Use kit panel.
/* === List (Tier 4 #16) ===============================================
* Generic list primitive — sections, dividers, leading slot (icon or
* avatar circle), title + sub, optional trailing slot (chevron / value
* / text-link). Rows volgen het row grammar (--k-row-h-lg). */
.list {
display: flex;
flex-direction: column;
margin: calc(var(--k-s-4) * -1) 0;
}
.list__section {
padding: var(--k-s-12) 0 var(--k-s-4);
font-size: var(--k-type-caption);
font-weight: var(--k-weight-semibold);
letter-spacing: var(--k-track-eyebrow);
text-transform: uppercase;
color: var(--k-fg-faint);
/* Sticky section header (the iOS grouped-list pattern): pins to the top when the
list lives in a scroll container, so the group label stays in view as its rows
scroll under it. A no-op in normal flow. Opaque bg so rows don't show through. */
position: sticky; top: 0; z-index: 1;
background: var(--k-surface);
}
.list__section:first-child { padding-top: var(--k-s-4); }
.list__item {
display: flex;
align-items: center;
gap: var(--k-row-gap, 10px);
/* Horizontal padding + matching negative margin = the hover bg breathes into
the card padding while the CONTENT stays edge-aligned with the section
labels. border-radius makes the hover follow the Box radius (no more square
grey at Soft). Same idiom as menu/nav rows. */
position: relative;
padding: var(--k-s-8);
margin-inline: calc(var(--k-s-8) * -1);
border: 0;
border-radius: var(--k-radius-sm);
background: transparent;
text-align: left;
font: inherit;
color: var(--k-fg);
cursor: pointer;
}
/* Divider = a FLAT top line via a pseudo-element, NOT border-top — so it never
inherits the row's Box radius (border-top would curve down at the corners on
Soft). The radius now rounds only the hover bg; the divider stays straight.
Width follows the Borders control (--k-bw → gone at Off); inset by the radius
so it meets the rounded hover corner cleanly (full-bleed at Box=None). */
.list__item::before {
content: '';
position: absolute;
top: 0;
left: var(--k-radius-sm);
right: var(--k-radius-sm);
height: var(--k-bw, 1px);
background: var(--k-border);
}
.list__item:first-of-type::before { content: none; }
.list__item:hover { background: var(--k-state-hover); }
/* Selected row (Invariant I2) — a row picked in a master/detail or multi-select
list. Was missing (only --unread existed), so the most-used flat row sat a tier
behind its own siblings (.list__row / .navrow both carry it). The chromatic fill
+ the selected-edge match the table/menu selected language → reads at any depth. */
.list__item[aria-selected="true"], .list__item.is-selected {
background: var(--k-state-selected-bg, var(--k-primary-soft));
box-shadow: var(--k-selected-edge);
}
.list__item[aria-selected="true"]:hover, .list__item.is-selected:hover { filter: brightness(0.98); }
/* Hit-target floor (Invariant I4) — an interactive row clears the WCAG-2.2 24px
target even at Compact density; generalises the .tbl guard so list rows stop
being a per-component afterthought. */
button.list__item, a.list__item, .list__item:has(input, button, a, [role="button"]) { min-block-size: var(--k-hit-min); }
.list__lead {
flex-shrink: 0;
width: calc(var(--k-in-h-default) - 0.25rem);
height: calc(var(--k-in-h-default) - 0.25rem);
display: grid;
place-items: center;
border-radius: var(--k-radius-sm);
}
.list__lead--icon {
background: var(--k-primary-soft);
color: var(--k-primary-soft-fg);
}
.list__lead--icon svg { width: var(--k-icon-sm); height: var(--k-icon-sm); }
.list__lead--avatar {
background: var(--k-secondary-soft);
color: var(--k-secondary-soft-fg);
border-radius: 50%;
font-size: var(--k-type-eyebrow);
font-weight: var(--k-weight-semibold);
}
.list__body { flex: 1; min-width: 0; }
.list__title {
font-size: var(--k-type-small);
font-weight: var(--k-weight-medium);
color: var(--k-fg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list__sub {
font-size: var(--k-type-eyebrow);
color: var(--k-fg-muted);
margin-top: 1px;
}
.list__trail {
flex-shrink: 0;
color: var(--k-fg-muted);
display: flex;
align-items: center;
}
.list__trail--text {
font-size: var(--k-type-eyebrow);
font-weight: var(--k-weight-medium);
color: var(--k-primary);
}
/* --- List CONTAINER variants — one row system; the container sets divider +
hover behaviour, the slot/title modifiers do the rest.
.list default — top-divider rows, hover (data / entity lists)
.list--flush no dividers, hover (tight feeds: notifications, inbox)
.list--settings bottom-divider rows, static (settings: title/desc + control) */
.list--flush .list__item::before { content: none; }
.list--settings .list__item {
border-top: 0;
border-bottom: var(--k-divider);
padding: var(--k-s-14) 0;
margin-inline: 0;
border-radius: 0;
cursor: default;
}
/* Settings rows are square (radius 0) + keep their own straight border-bottom. */
.list--settings .list__item::before { content: none; }
.list--settings .list__item:hover { background: transparent; }
.list--settings .list__item:last-of-type { border-bottom: 0; }
.list--settings .list__title { font-weight: var(--k-weight-semibold); }
/* Lead variant — neutral round icon chip (notifications / system rows) */
.list__lead--icon-muted {
background: var(--k-surface-sunken);
color: var(--k-fg-muted);
border-radius: 50%;
}
.list__lead--icon-muted svg { width: var(--k-icon-md); height: var(--k-icon-md); }
/* Title size — larger + wrapping, for notification/feed rows */
.list__title--lg { font-size: var(--k-type-body); white-space: normal; }
/* Unread row — bold title + trailing dot */
.list__item--unread .list__title { font-weight: var(--k-weight-bold); }
.list__dot { width: var(--k-dot); height: var(--k-dot); border-radius: 50%; background: var(--k-primary); flex: none; align-self: center; }
/* --cols: two-column stacked list (Tailwind "stacked list, two columns") — rows
flow into two columns on a wide container, one when narrow; section headings
span the full width. Reset the row's negative inline margin so the hover bg
doesn't bleed into the column gutter. */
.list--cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); column-gap: var(--k-s-24); margin: 0; }
.list--cols .list__item { margin-inline: 0; }
.list--cols .list__section { grid-column: 1 / -1; }
/* --sticky: section headings pin to the top while their group scrolls past
(Tailwind "stacked list with sticky headings"). Put the list in a scroll
container; the heading gets a surface fill so rows don't show through it. */
.list--sticky .list__section { position: sticky; top: 0; z-index: 1; background: var(--k-surface); }