Cards
Three containers carry the whole app: the NDO card, the section panel, and a dashed box that means "nothing here yet, or nothing built yet".
NDO card — NdoCard.svelte
Badges first, then the name, then a two-line clamped description, then the truncated hash. Badges above the title is unusual and it is the app's actual order.
<a class="block rounded-lg border border-gray-200 bg-white p-4 shadow-sm transition-shadow hover:shadow-md">
<div class="mb-2 flex flex-wrap items-center gap-2"><!-- badges --></div>
<h3 class="text-lg font-semibold text-gray-900">{name}</h3>
<p class="mt-1 line-clamp-2 text-sm text-gray-600">{description}</p>
<p class="mt-1 font-mono text-xs text-gray-400">#{hash.slice(0, 12)}…</p>
</a>Section panel — NdoBrowser.svelte
The same border and radius as a card, with a hairline-divided header. The browser's filter bar and its grid are two regions of one panel.
NDO browser
<section class="rounded-lg border border-gray-200 bg-white shadow-sm">
<div class="border-b border-gray-100 px-4 py-3"><!-- filters --></div>
<div class="p-4"><!-- content --></div>
</section>List row — MemberList.svelte
Name left, role pill right. The only rounded-full in the app is this role pill.
Members
- Ada Riverstone Member
- Kesse Nyarko
<li class="flex items-center justify-between rounded border border-gray-200 bg-white px-3 py-2 text-sm">
<span class="font-medium text-gray-800">{name}</span>
<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-500">{role}</span>
</li>Dashed placeholder
A dashed border means one of two things: an empty collection, or a feature that is not built. Both read the same, which is a problem worth naming — an empty group and an unimplemented Composition tab look alike.
No members yet.
Composition view is not wired yet.
Create or join a group to see NDOs
NDOs are scoped to groups.
<p class="rounded border border-dashed border-gray-300 p-4 text-sm text-gray-400 italic">No members yet.</p>
<div class="rounded-lg border border-dashed border-gray-400 bg-white p-6"><!-- coming soon --></div>