Default Card
This is the default card style with a subtle background.
Every component, variant, state, and utility — all in one place.
Heading classes, text sizes, and font weights.
Headings
<h1 class="heading-1">Heading 1</h1>
<h2 class="heading-2">Heading 2</h2>
<h3 class="heading-3">Heading 3</h3>
<h4 class="heading-4">Heading 4</h4>
<h5 class="heading-5">Heading 5</h5>
<h6 class="heading-6">Heading 6</h6>
Text Sizes
Text large — .text-lg
Text base (default)
Text small — .text-sm
Text extra small — .text-xs
<p class="text-lg">Text large</p>
<p>Text base (default)</p>
<p class="text-sm">Text small</p>
<p class="text-xs">Text extra small</p>
Text Muted
This text uses .text-muted for secondary content.
<p class="text-muted">Muted text</p>
Font Weights
Font light (300) — .font-light
Font regular (400) — .font-regular
Font medium (500) — .font-medium
Font semibold (600) — .font-semibold
Font bold (700) — .font-bold
<p class="font-light">Light</p>
<p class="font-regular">Regular</p>
<p class="font-medium">Medium</p>
<p class="font-semibold">Semibold</p>
<p class="font-bold">Bold</p>
Material Symbols Outlined icons via the .icon class. Only subseted icons are loaded for performance.
Available Icons
<span class="icon" aria-hidden="true">info</span>
<span class="icon" aria-hidden="true">check_circle</span>
<span class="icon" aria-hidden="true">warning</span>
<span class="icon" aria-hidden="true">error</span>
<span class="icon" aria-hidden="true">close</span>
Usage in Alerts
<div class="alert alert--info" role="alert">
<span class="alert__icon icon" aria-hidden="true">info</span>
<p class="alert__message">Informational message.</p>
</div>
Usage in Modal Close
<a href="#close" class="modal__close" aria-label="Close">
<span class="icon" aria-hidden="true">close</span>
</a>
Link styles for body text, subtle contexts, and navigation.
Nav Links
<a href="#" class="link--nav">Nav Link</a>
<a href="#" class="link--nav" aria-current="page">Active Nav Link</a>
Inputs, textareas, selects, checkboxes, radios, toggles, hints, and fieldsets.
Text Inputs (Various Types)
<div class="form-field">
<label class="form-label" for="name">Name</label>
<input type="text" id="name" class="form-input" placeholder="Enter text">
</div>
Input States
Focus, valid, and invalid states activate on user interaction via :user-valid and :user-invalid.
Textarea
<textarea class="form-textarea" rows="3" placeholder="Enter message..."></textarea>
Select
<select class="form-select">
<option value="">Choose option...</option>
<option value="1">Option 1</option>
</select>
Form Hint
Must be 3-20 characters with no spaces.
<p class="form-hint">Must be 3-20 characters with no spaces.</p>
Checkboxes
<label class="form-checkbox">
<input type="checkbox">
<span class="form-checkbox__indicator"></span>
<span class="form-checkbox__label">Label</span>
</label>
Radio Buttons
<label class="form-radio">
<input type="radio" name="group" value="a">
<span class="form-radio__indicator"></span>
<span class="form-radio__label">Option</span>
</label>
Toggles
<label class="form-toggle">
<input type="checkbox">
<span class="form-toggle__track"></span>
<span class="form-toggle__label">Label</span>
</label>
Fieldset & Legend
<fieldset class="form-fieldset">
<legend class="form-legend">Personal Information</legend>
<!-- fields -->
</fieldset>
Do
<label> with matching for/idemail, tel, url)Don't
.sr-only if visually hidden.form-checkbox__indicator or .form-radio__indicatorplaceholder as a replacement for labelsBase table with striped and bordered variants.
Base Table
| Name | Role | Status |
|---|---|---|
| Alice | Designer | Active |
| Bob | Developer | Active |
| Carol | Manager | Away |
<table class="table">...</table>
Striped
| Name | Role | Status |
|---|---|---|
| Alice | Designer | Active |
| Bob | Developer | Active |
| Carol | Manager | Away |
| Dave | QA | Active |
<table class="table table--striped">...</table>
Bordered
| Name | Role | Status |
|---|---|---|
| Alice | Designer | Active |
| Bob | Developer | Active |
| Carol | Manager | Away |
<table class="table table--bordered">...</table>
Striped + Bordered
| Name | Role | Status |
|---|---|---|
| Alice | Designer | Active |
| Bob | Developer | Active |
| Carol | Manager | Away |
| Dave | QA | Active |
<table class="table table--striped table--bordered">...</table>
Do
<thead> and <tbody> for semantic structuretable--striped for tables with many rowsDon't
<th> elements in the header rowCard container with header, body, footer, and style variants.
Default Card
This is the default card style with a subtle background.
Elevated Card
Elevated card with a shadow for visual depth.
Outlined Card
Outlined card with a visible border for separation.
Glass Card
Glassmorphism effect with backdrop blur. Best on darker or image backgrounds.
<article class="card card--elevated">
<header class="card__header">
<h3 class="card__title">Title</h3>
</header>
<div class="card__body"><p>Content</p></div>
<footer class="card__footer">
<a href="#" class="btn btn--primary btn--sm">Action</a>
</footer>
</article>
Do
<article> as the card containercard--elevated or card--outlined for visual hierarchyDon't
Contextual feedback messages for user actions.
<div class="alert alert--info" role="alert">
<span class="alert__icon icon" aria-hidden="true">info</span>
<p class="alert__message">Informational message.</p>
</div>
Do
role="alert" for screen readersDon't
Expandable content sections using native details/summary.
This accordion item starts open. Content is revealed when the header is clicked.
Click to expand this section. Each item is independent.
Multiple items can be open at once since each is a native details element.
<div class="accordion">
<details class="accordion__item" open>
<summary class="accordion__header">Title</summary>
<div class="accordion__content"><p>Content</p></div>
</details>
</div>
Do
<details>/<summary> — keyboard support built-in.accordion containerDon't
Tab navigation using CSS-only radio input technique.
3 Tabs
Overview panel content. This is the first tab.
Features panel content. This is the second tab.
Setup panel content. This is the third tab.
5 Tabs (Maximum)
Panel 1 content.
Panel 2 content.
Panel 3 content.
Panel 4 content.
Panel 5 content.
<div class="tabs">
<input type="radio" name="tab-group" id="tab-1" class="tabs__input" checked>
<label for="tab-1" class="tabs__label">Tab 1</label>
<!-- repeat for each tab -->
<div class="tabs__panels">
<div class="tabs__panel"><p>Content</p></div>
<!-- one panel per tab -->
</div>
</div>
Do
checked by defaultname attributes per tab groupDon't
name across tab groupsCSS-only modal using :target selector. Click the button to open.
<a href="#my-modal" class="btn btn--primary">Open Modal</a>
<div id="my-modal" class="modal">
<a href="#close" class="modal__overlay" tabindex="-1" aria-hidden="true"></a>
<div class="modal__content" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<header class="modal__header">
<h4 id="modal-title" class="modal__title">Title</h4>
<a href="#close" class="modal__close" aria-label="Close modal"><span class="icon" aria-hidden="true">close</span></a>
</header>
<div class="modal__body"><p>Content</p></div>
<footer class="modal__footer">
<a href="#close" class="btn btn--secondary">Cancel</a>
<a href="#close" class="btn btn--primary">Confirm</a>
</footer>
</div>
</div>
Do
role="dialog" and aria-modal="true"aria-labelledbyDon't
Hover and focus-triggered tooltips via CSS.
Hover Tooltip
<span class="tooltip">
Hover over me
<span class="tooltip__content">Tooltip text</span>
</span>
Focus Tooltip (Accessible)
<button class="tooltip btn btn--secondary" aria-describedby="tip-id">
Focus me
<span class="tooltip__content" role="tooltip" id="tip-id">Tooltip text</span>
</button>
Do
aria-describedby to link trigger to tooltiprole="tooltip" on the content elementDon't
Small status labels and counters.
<span class="badge">Default</span>
<span class="badge badge--primary">Primary</span>
<span class="badge badge--success">Success</span>
<span class="badge badge--warning">Warning</span>
<span class="badge badge--error">Error</span>
Horizontal rules for content separation.
Default Divider
Content above
Content below
Subtle Divider
Content above
Content below
<hr class="divider">
<hr class="divider divider--subtle">
Quotations, inline code, code blocks, and keyboard keys.
Blockquote
The purest water on Earth flows beneath Antarctic ice — untouched, essential, enough.
<blockquote class="blockquote">
<p>Quote text</p>
<footer class="blockquote__footer">
<cite>Attribution</cite>
</footer>
</blockquote>
Inline Code
Use the .container class for centered content with a max-width.
<code class="code">.container</code>
Code Block
<link rel="stylesheet" href="purissimo.css">
Keyboard Keys
Press Ctrl + S to save, or Esc to close.
<kbd>Ctrl</kbd> + <kbd>S</kbd>
Unordered, ordered, and unstyled list variants.
Unordered List
<ul class="list">
<li>Item</li>
</ul>
Ordered List
<ol class="list list--ordered">
<li>Step</li>
</ol>
No Style List
<ul class="list list--none">
<li>Item</li>
</ul>
Images with captions using the figure component.
<figure class="figure">
<img class="figure__image" src="image.jpg" alt="Description">
<figcaption class="figure__caption">Caption text</figcaption>
</figure>
Container widths, 12-column grid, responsive columns, and gap utilities.
Containers
12-Column Grid
Column Spans
<div class="grid gap-2">
<div class="col-8">...</div>
<div class="col-4">...</div>
</div>
Responsive Columns
Resize the browser to see columns reflow at sm (640px), md (768px), lg (1024px) breakpoints.
<div class="col-12 sm:col-6 md:col-4 lg:col-3">...</div>
Gap Variations
gap-1
gap-4
gap-8
<div class="grid gap-1">...</div>
<div class="grid gap-4">...</div>
<div class="grid gap-8">...</div>
Margin and padding utility classes (base-4 scale).
Margin Utilities
Colored area = margin, white area = element
.m-1 (4px)
.m-2 (8px)
.m-4 (16px)
.m-6 (24px)
.m-8 (32px)
Directional: .mt-4, .mb-4, .mx-4, .my-4
<!-- Full margin -->
<div class="m-4">...</div>
<!-- Directional -->
<div class="mt-4">...</div> <!-- top -->
<div class="mb-4">...</div> <!-- bottom -->
<div class="mx-4">...</div> <!-- horizontal -->
<div class="my-4">...</div> <!-- vertical -->
<div class="mx-auto">...</div> <!-- center horizontally -->
Padding Utilities
Colored area = padding, inner area = content
.p-1 (4px)
.p-2 (8px)
.p-4 (16px)
.p-6 (24px)
.p-8 (32px)
Directional: .pt-4, .pb-4, .px-4, .py-4
<!-- Full padding -->
<div class="p-4">...</div>
<!-- Directional -->
<div class="pt-4">...</div> <!-- top -->
<div class="pb-4">...</div> <!-- bottom -->
<div class="px-4">...</div> <!-- horizontal -->
<div class="py-4">...</div> <!-- vertical -->
Display modes, flex direction, justify, and align utilities.
Display Utilities
<div class="block">...</div>
<span class="inline">...</span>
<span class="inline-block">...</span>
<div class="flex">...</div>
<div class="grid">...</div>
<div class="hidden">...</div>
Flex Direction
.flex-row (default)
.flex-col
<div class="flex flex-row gap-2">...</div>
<div class="flex flex-col gap-2">...</div>
Justify Content
.justify-start
.justify-center
.justify-end
.justify-between
Align Items
.items-start
.items-center
.items-end
.items-stretch
<div class="flex items-center justify-between">...</div>
Text alignment and screen reader utility.
Text Alignment
.text-left
.text-center
.text-right
<p class="text-left">...</p>
<p class="text-center">...</p>
<p class="text-right">...</p>
Screen Reader Only
The .sr-only class visually hides content while keeping it accessible to screen readers. The text below is present in the DOM but invisible:
Inspect the DOM to see the hidden <span class="sr-only"> element above.
<span class="sr-only">Accessible label</span>
Width constraints and overflow behavior.
.w-full (100% width)
.w-auto (intrinsic width)
.overflow-auto (scrollable when content overflows)
Line 1 of scrollable content
Line 2 of scrollable content
Line 3 of scrollable content
Line 4 of scrollable content
Line 5 of scrollable content
Line 6 of scrollable content
<div class="w-full">...</div>
<div class="w-auto">...</div>
<div class="overflow-auto">...</div>
Built-in accessibility features and user preference support.
Skip Link
The .skip-link is positioned off-screen and becomes visible when focused via keyboard (Tab). Try pressing Tab on this page to see it.
<a href="#main" class="skip-link">Skip to main content</a>
Prefers Reduced Motion
When the user has prefers-reduced-motion: reduce enabled in their OS settings, all transitions and animations are effectively disabled (set to 0.01ms). This respects users who experience motion sickness or prefer less visual movement.
No demo needed — this is automatic based on OS/browser settings.
/* Applied automatically via CSS */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Prefers High Contrast
When prefers-contrast: more is active, Purissimo enhances borders, removes subtle shadows, and increases contrast on interactive elements like buttons, badges, tooltips, and form toggles.
No demo needed — this is automatic based on OS/browser settings.
/* Applied automatically via CSS */
@media (prefers-contrast: more) {
:root {
--color-border: var(--gray-500);
--shadow-sm: none;
/* ... enhanced styles */
}
}
Focus States
All interactive elements have visible :focus-visible outlines. Tab through these elements to see the focus ring: