Logo only
Logo + actions
Logo + icon actions
Logo + nav + actions
Logo + search-bar + icon actions
Logo + actions + nav + search
Centered Logo + Centered Nav
Centered SVG Logo + Centered Nav
Default
Centered
This is a paragraph.
With icon before
With chevron after (link)
With icon before + chevron after (link)
h2 tag, h3 size, tight chevron
Long two-line title (h3 size)
Long two-line title (h2 size)
Long two-line title with icon before (h2 size)
Border Input (any surface)
Filled Input (on white surface)
White Input (on gray surface)
Border Input (on gray surface)
Input with Label + Hint Text
Input with Label + Error Message
Select — Bordered (any surface)
Select — Filled, borderless (on white surface)
Select — White, borderless (on gray surface)
Select — Bordered (on gray surface)
Text prefix (input-addon)
Text suffix (input-addon)
Input + one button
Input + two buttons
Select + two buttons
Select + Text Save Button (row, separated — current app style)
Select + Text Save Button, with label + hint
Select + input + button (e.g. phone)
Left Aligned (default)
Center Aligned
Right Aligned
Alert with Title
This is a warning alert with a title, followed by a longer description explaining the issue in more detail.
Inline usage: Notifications 3 and status Active badges.
Placeholder (no image)
Horizontal flex with 1rem gap. No default
alignment — state it. Different words per axis, so the two "centers"
never collide: vertical (align-items)
.top / .middle /
.bottom;
horizontal (justify-content)
.start / .center /
.end / .between.
Vertical — .top /
.middle / .bottom
Horizontal — .center /
.between / .end
Combine axes — .row.middle.between
Gap modifiers — .xs /
.sm / .md / default
Override the default 1rem gap. Compose with
alignment modifiers.
.xs — 0.25rem
.sm — 0.5rem
.md — 0.75rem
default — 1rem
Responsive CSS grid. Collapses to 1 column on mobile (≤48rem).
Combine grid +
cols-N (desktop) +
sm-cols-N (mobile) +
gap-N (spacing).
cols-4 sm-cols-2
cols-4 sm-cols-4
cols-3 gap-6
Label/value metadata (<dl>). Wrap each
<dt><dd> pair in a
<div>; pick a layout modifier.
Colour is not baked in — add .text-muted to
the <dt> (muted label, the common case)
or to the <dd> (muted value) as needed.
.vertical — label above value
.horizontal — side by side
.between — value pushed to the end
.horizontal — dd containing a form (select + save button, for review)
Emphasis — no new classes
Black label, muted value —
<dd class="text-muted">:
Bold label, regular value — both black, wrap the label in
<strong>:
Regular label, bold value — wrap the
<dd> in
<strong>:
Vertical — bold label above regular value:
| Name | Role |
|---|---|
| Alice | Admin |
| Bob | Editor |
| Name | Category | Status |
|---|---|---|
| Item One Longer Name | Category A | Active |
| Item Two | Category B | Pending |
| Item Three Medium | Category A | Inactive |
| # | Product | Description | Qty | Price | Total | Status |
|---|---|---|---|---|---|---|
| 1 | Premium Wireless Headphones | Noise-cancelling, 40hr battery, Bluetooth 5.3 | 2 | $149.99 | $299.98 | In Stock |
| 2 | USB-C Hub | 7-in-1, 4K HDMI, SD card | 1 | $59.00 | $59.00 | In Stock |
| 3 | Mechanical Keyboard | Cherry MX Brown, RGB backlit, full-size aluminum frame | 1 | $189.00 | $189.00 | Low Stock |
| 4 | Monitor Stand | Adjustable height, cable management | 3 | $34.50 | $103.50 | Out of Stock |
| 5 | Webcam HD | 1080p, autofocus, built-in mic | 2 | $79.99 | $159.98 | In Stock |
When a label cell spans multiple rows (rowspan), the browser default is to vertical-center it across the merged
height. Add .align-top
to pin it to the top-left instead — reads better when each row below has
its own distinct content (e.g. one document with several uploaded files,
each on its own row).
| Select | User | Role | Active | Actions | |
|---|---|---|---|---|---|
| Sarah Connor | [email protected] | ||||
| John Doe | [email protected] | ||||
| Maria Garcia | [email protected] |
| Name | Location | Project | Last Active | Revenue | Status | ||
|---|---|---|---|---|---|---|---|
|
|
Anna Lee | [email protected] | 123 Main Street San Francisco, CA 94102 |
Dashboard Redesign | 2 hours ago | $12,450.00 | Active |
|
|
Mark Chen | [email protected] | 456 Oak Avenue, Apt 12B New York, NY 10001 |
API Integration | 3 days ago | $8,200.00 | Away |
|
SM
|
Sara Müller | [email protected] | — | — | Never | — | Inactive |
|
|
James Wright | [email protected] | 789 Pine Road Austin, TX 73301 |
Mobile App v2 | Just now | $23,100.50 | Active |
| # | Task | Assignee | Due Date | Priority | Actions |
|---|---|---|---|---|---|
| 1 | |||||
| 2 | |||||
| 3 |
Content above divider.
Content below divider.
Unordered List
Ordered List
Unstyled List
This is a blockquote for highlighting important text, quotes, or callouts. It uses a left border for visual emphasis.
Inline code: use font-family: monospace for
code elements.
// Code block example
function greet(name) {
return "Hello, " + name;
}
greet("World");
Empty State: Icon + Title + Description + CTA
Empty State: Icon + Title + CTA
Empty State: Icon + Title + Description
Empty State: Title + Description + CTA
Empty State: Title + CTA
Empty State: Icon + Description
Disclosure: Default (closed)
Disclosure content revealed after clicking summary. Hidden by default.
Disclosure: Open by Default
Disclosure content visible on load. Can be collapsed by clicking summary.
Disclosure: With Longer Content
First paragraph of disclosure content with more detail.
Second paragraph showing that disclosure can contain multiple elements and longer text blocks.
Disclosure: FAQ Style (multiple)
Answer to first question in FAQ-style disclosure group.
Answer to second question with more detail in the response.
Answer to third question in FAQ-style disclosure group.
This is a card description.
No dividers (default left-align)
All dividers (.divided)
Divider before section (.dropdown-divider)
Right-aligned (.dropdown.right) — for header/navbar user menus
With icons (.dropdown.right)
Actions menu (button items, no dividers)
Avatar trigger — first letter, right-aligned (user menu pattern)
Icon-button trigger (three dots)
Full-screen image viewer. One shared
<dialog class="lightbox"> per page —
each trigger swaps the <img> source and
calls showModal(). Native
<dialog> closes on Escape automatically;
the close button calls .close(). Image is
centered both axes and capped at viewport size (max-width/height: 100vw/100vh, object-fit: contain) so it never overflows
on any device, big or small.
Click a thumbnail to open
Dropzone-style file input. Click anywhere on the card to open the file
picker; the chosen file previews instantly client-side (image thumbnail
via URL.createObjectURL(), or a file icon +
name for non-images like PDFs) — no upload round-trip needed to see what
was picked. The remove button clears the selection and returns to the
empty state.
Empty state (click to upload) — field label always visible, like any other input
Multiple files (e.g. passport — front and back, or any number of pages)