Selectable table
A dense table with row checkboxes, status pills and a bar of bulk actions that appears, with a live count, as soon as a row is picked.
214 members · 3 seats free on the Business plan
It is live: hover, focus and its own controls respond. Actions that would change data (approve, send, delete) are for your app to wire. The width is a real 390 px, 768 px or 1280 px box, shrunk to fit your screen.
<style>
.odl-member-list { box-sizing: border-box; inline-size: 100%; max-inline-size: 760px; background: var(--ds-color-surface-raised); color: var(--ds-color-text-primary);
border: var(--ds-border-width-default) solid var(--ds-color-border-subtle); border-radius: var(--ds-radius-container); box-shadow: var(--ds-elevation-raised);
font: var(--ds-text-body-md); text-wrap: pretty; container-type: inline-size; overflow: hidden; }
.odl-member-list *, .odl-member-list *::before { box-sizing: border-box; }
.odl-member-list svg { flex: none; inline-size: var(--ds-size-icon-sm); block-size: var(--ds-size-icon-sm); }
.odl-member-list .odl-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--ds-space-stack-sm) var(--ds-space-inline-md);
padding: var(--ds-space-inset-md) var(--ds-space-inset-lg); border-block-end: var(--ds-border-width-default) solid var(--ds-color-border-subtle); }
.odl-member-list h3 { margin: 0; font: var(--ds-text-title-sm); }
.odl-member-list .odl-head p { margin: var(--ds-space-2) 0 0; color: var(--ds-color-text-secondary); font: var(--ds-text-body-sm); font-variant-numeric: tabular-nums; }
.odl-member-list button { display: inline-flex; align-items: center; justify-content: center; gap: var(--ds-space-inline-xs); min-block-size: var(--ds-size-control-md); min-inline-size: var(--ds-size-target-min);
padding: 0 var(--ds-space-inset-sm); border-radius: var(--ds-radius-control); font: var(--ds-text-label-lg); font-weight: var(--ds-font-weight-label); cursor: pointer; white-space: nowrap;
transition: background-color var(--ds-motion-duration-short) var(--ds-motion-easing-standard); }
.odl-member-list .odl-invite { border: 0; background: var(--ds-color-bg-action-primary); color: var(--ds-color-text-on-action); }
.odl-member-list .odl-invite:hover { background: var(--ds-color-bg-action-primary-hover); }
.odl-member-list .odl-quiet { border: var(--ds-border-width-default) solid var(--ds-color-border-default); background: var(--ds-color-surface-raised); color: var(--ds-color-text-primary); min-block-size: var(--ds-size-control-sm); }
.odl-member-list .odl-quiet:hover { background: var(--ds-color-bg-neutral-subtle-hover); }
.odl-member-list button:focus-visible, .odl-member-list select:focus-visible { outline: var(--ds-focus-ring-width) solid var(--ds-color-border-focus); outline-offset: var(--ds-focus-ring-offset); }
.odl-member-list .odl-cols, .odl-member-list li { display: grid; grid-template-columns: minmax(0, 1fr) 9.5rem 7rem; align-items: center; gap: var(--ds-space-inline-md);
padding: 0 var(--ds-space-inset-lg); }
.odl-member-list .odl-cols { min-block-size: var(--ds-size-row-sm); background: var(--ds-color-surface-sunken); color: var(--ds-color-text-tertiary); font: var(--ds-text-label-md);
border-block-end: var(--ds-border-width-default) solid var(--ds-color-border-subtle); }
.odl-member-list .odl-cols span:last-child, .odl-member-list .odl-when { text-align: end; }
.odl-member-list ul { list-style: none; margin: 0; padding: 0; }
.odl-member-list li { min-block-size: var(--ds-size-row-two-line); padding-block: var(--ds-space-inset-xs); }
.odl-member-list li + li { border-block-start: var(--ds-border-width-default) solid var(--ds-color-border-separator); }
.odl-member-list li:hover { background: var(--ds-color-bg-neutral-subtle); }
.odl-member-list .odl-who { display: flex; align-items: center; gap: var(--ds-space-inline-sm); min-inline-size: 0; }
.odl-member-list .odl-avatar { flex: none; display: grid; place-items: center; inline-size: var(--ds-size-control-sm); block-size: var(--ds-size-control-sm); border-radius: var(--ds-radius-person);
background: var(--ds-color-bg-accent-subtle); color: var(--ds-color-text-accent); font: var(--ds-text-label-sm); font-weight: var(--ds-font-weight-heading); }
.odl-member-list .odl-avatar.is-b { background: var(--ds-color-bg-info-subtle); color: var(--ds-color-text-info); }
.odl-member-list .odl-avatar.is-c { background: var(--ds-color-bg-neutral-subtle); color: var(--ds-color-text-secondary); }
.odl-member-list .odl-avatar.is-pending { background: transparent; color: var(--ds-color-icon-subtle); border: var(--ds-border-width-default) dashed var(--ds-color-border-strong); }
.odl-member-list .odl-name { min-inline-size: 0; display: grid; }
.odl-member-list .odl-name strong { display: flex; flex-wrap: wrap; min-inline-size: 0; align-items: center; gap: var(--ds-space-inline-xs); font: var(--ds-text-label-lg); font-weight: var(--ds-font-weight-label); }
.odl-member-list .odl-name > span { min-inline-size: 0; color: var(--ds-color-text-secondary); font: var(--ds-text-body-sm); overflow-wrap: anywhere; }
.odl-member-list .is-pending-row .odl-name > span { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-space-2) var(--ds-space-inline-xs); overflow-wrap: normal; }
.odl-member-list .odl-mail { min-inline-size: 0; overflow-wrap: anywhere; }
.odl-member-list .odl-you, .odl-member-list .odl-pill { flex: none; }
.odl-member-list .odl-you { padding: 0 var(--ds-space-6); border-radius: var(--ds-radius-detail); background: var(--ds-color-bg-neutral-subtle); color: var(--ds-color-text-secondary); font: var(--ds-text-label-sm); }
.odl-member-list .odl-pill { padding: 0 var(--ds-space-6); border-radius: var(--ds-radius-detail); background: var(--ds-color-bg-warning-subtle); color: var(--ds-color-text-warning); font: var(--ds-text-label-sm); }
.odl-member-list .odl-role { position: relative; display: flex; align-items: center; }
.odl-member-list select { appearance: none; inline-size: 100%; min-block-size: var(--ds-size-target-min); padding: 0 var(--ds-space-32) 0 var(--ds-space-inset-sm);
border: var(--ds-border-width-default) solid var(--ds-color-border-input); border-radius: var(--ds-radius-control); background: var(--ds-color-bg-field); color: var(--ds-color-text-primary);
font: var(--ds-text-body-md); cursor: pointer; }
.odl-member-list select:hover { border-color: var(--ds-color-border-strong); }
.odl-member-list .odl-role > svg { position: absolute; inset-inline-end: var(--ds-space-inset-sm); pointer-events: none; color: var(--ds-color-icon-subtle); }
.odl-member-list .odl-locked { display: flex; align-items: center; gap: var(--ds-space-inline-xs); min-block-size: var(--ds-size-target-min); padding: 0 var(--ds-space-inset-sm); color: var(--ds-color-text-secondary); }
.odl-member-list .odl-locked svg { color: var(--ds-color-icon-subtle); }
.odl-member-list .odl-when { color: var(--ds-color-text-tertiary); font: var(--ds-text-body-sm); font-variant-numeric: tabular-nums; white-space: nowrap; }
.odl-member-list .odl-when .is-online { color: var(--ds-color-text-success); }
.odl-member-list .is-pending-row .odl-when { display: flex; justify-content: flex-end; }
@container (max-width: 600px) {
.odl-member-list .odl-cols { display: none; }
.odl-member-list li { grid-template-columns: minmax(0, 1fr) 6.5rem; grid-template-areas: "who who" "role when"; row-gap: var(--ds-space-stack-sm); padding: var(--ds-space-inset-sm) var(--ds-space-inset-md); }
.odl-member-list .odl-head { padding: var(--ds-space-inset-md); }
.odl-member-list .odl-long { display: none; }
.odl-member-list .odl-who { grid-area: who; }
.odl-member-list .odl-role, .odl-member-list .odl-locked { grid-area: role; margin-inline-start: calc(var(--ds-size-control-sm) + var(--ds-space-inline-sm)); }
.odl-member-list .odl-locked { padding-inline-start: 0; }
.odl-member-list .odl-when { grid-area: when; }
}
@media (prefers-reduced-motion: reduce) { .odl-member-list, .odl-member-list *, .odl-member-list *::before { transition: none !important; animation: none !important; } }
</style>
<section class="odl-member-list" aria-labelledby="odl-ml-title">
<div class="odl-head">
<div><h3 id="odl-ml-title">Members</h3><p>214 members · 3 seats free on the Business plan</p></div>
<button type="button" class="odl-invite" aria-label="Invite members"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M8 3v10M3 8h10"/></svg>Invite<span class="odl-long"> members</span></button>
</div>
<div class="odl-cols" aria-hidden="true"><span>Name</span><span>Role</span><span>Last active</span></div>
<ul aria-label="Members of Quenwick Mutual">
<li>
<div class="odl-who"><span class="odl-avatar" aria-hidden="true">RT</span>
<div class="odl-name"><strong>Ragnhild Torvik <span class="odl-you">You</span></strong><span>ragnhild.torvik<wbr>@quenwickmutual.example</span></div></div>
<div class="odl-locked" title="The owner's role can be changed only by transferring ownership"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="3" y="7" width="10" height="7" rx="1.5"/><path d="M5.5 7V5a2.5 2.5 0 0 1 5 0v2"/></svg>Owner</div>
<span class="odl-when"><span class="is-online">Active now</span></span>
</li>
<li>
<div class="odl-who"><span class="odl-avatar is-b" aria-hidden="true">RN</span>
<div class="odl-name"><strong>Radek Nowicki</strong><span>radek.nowicki<wbr>@quenwickmutual.example</span></div></div>
<div class="odl-role"><select aria-label="Role for Radek Nowicki"><option selected>Admin</option><option>Member</option><option>Viewer</option></select>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="m4.5 6.5 3.5 3.5 3.5-3.5"/></svg></div>
<span class="odl-when"><time datetime="2026-10-21T09:40">12 min ago</time></span>
</li>
<li>
<div class="odl-who"><span class="odl-avatar is-c" aria-hidden="true">TC</span>
<div class="odl-name"><strong>Thiago Carvalho</strong><span>thiago.carvalho<wbr>@quenwickmutual.example</span></div></div>
<div class="odl-role"><select aria-label="Role for Thiago Carvalho"><option>Admin</option><option selected>Member</option><option>Viewer</option></select>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="m4.5 6.5 3.5 3.5 3.5-3.5"/></svg></div>
<span class="odl-when"><time datetime="2026-10-20">Yesterday</time></span>
</li>
<li>
<div class="odl-who"><span class="odl-avatar" aria-hidden="true">YA</span>
<div class="odl-name"><strong>Yerlan Abenov</strong><span>yerlan.abenov<wbr>@quenwickmutual.example</span></div></div>
<div class="odl-role"><select aria-label="Role for Yerlan Abenov"><option>Admin</option><option>Member</option><option selected>Viewer</option></select>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="m4.5 6.5 3.5 3.5 3.5-3.5"/></svg></div>
<span class="odl-when"><time datetime="2026-10-02">Oct 2</time></span>
</li>
<li class="is-pending-row">
<div class="odl-who"><span class="odl-avatar is-pending" aria-hidden="true"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="2" y="3.5" width="12" height="9" rx="1.5"/><path d="m2.5 4.5 5.5 4 5.5-4"/></svg></span>
<div class="odl-name"><strong><span class="odl-mail">hanne.varga<wbr>@quenwickmutual.example</span></strong><span><span class="odl-pill">Pending invite</span> <span>Sent by Radek Nowicki · expires Oct 24</span></span></div></div>
<div class="odl-role"><select aria-label="Role for pending invite to hanne.varga@quenwickmutual.example"><option>Admin</option><option selected>Member</option><option>Viewer</option></select>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="m4.5 6.5 3.5 3.5 3.5-3.5"/></svg></div>
<span class="odl-when"><button type="button" class="odl-quiet" aria-label="Resend invite to hanne.varga@quenwickmutual.example">Resend</button></span>
</li>
</ul>
</section>
A dense table with row checkboxes, status pills and a bar of bulk actions that appears, with a live count, as soon as a row is picked.
Four headline numbers in one band, each with a plain note under it, and a small bar where a share matters.
A record's history: who did what and when, with field changes shown as old value, new value and the difference.