Design system — page navigation

Design system

A scalable interface system built for performance, accessibility, and real-world product workflows.

  • Light / Dark
  • Token-driven
  • WCAG-minded
  • Component-based

How the interface behaves: tokens constrain color, type, surfaces, and spacing so composed UI stays consistent.Full tokens & typography → Style guide

In practice

The same tokens compose into predictable UI: surface, label, field, and action working together.

Color system

Primary (brand ramp)

--brand-50
--brand-100
--brand-200
--brand-300
--brand-400
--brand-500
--brand-600
--brand-700
--brand-800
--brand-900

Secondary (violet ramp)

--secondary-50
--secondary-100
--secondary-200
--secondary-300
--secondary-400
--secondary-500
--secondary-600
--secondary-700
--secondary-800
--secondary-900

Semantic

--success
--warning
--danger
--info

Typography

Heading 1Heading 2Heading 3

Body text uses the default size and line height for long-form reading and UI copy.

Small text for captions, hints, and secondary metadata.

const primary = 'var(--brand-700)';

Surfaces & elevation

Surface steps stack from page (--surface-0) through raised cards; elevation uses shared shadow tokens. Toggle light/dark in the header to verify contrast.

--surface-0
--surface-1
--surface-2
--surface-3
--surface-4
--surface-5
--surface-6
--surface-7
--surface-8
--shadow-sm
--shadow-md
--shadow-lg

Spacing & radius

Spacing scale

  • --space-2
  • --space-3
  • --space-4
  • --space-5
  • --space-6

Corner radius

--radius-sm
--radius-md
--radius-lg
--radius-pill

Layout & composition

Reusable layout primitives for responsive composition—grids, asides, and card patterns. Visual tokens live in System overview.

Grid

Three patterns cover most product layouts: a balanced four-column grid, a content-friendly three-column grid, and a main region paired with an aside.

On viewports below 768px, the grid examples are hidden so cards stay readable; the main + aside pattern below still demonstrates responsive behavior.

Balanced layout (4 columns)

Card default styling.

Card surface 2 color.

Card surface 3 color.

Card surface 4 color.

Content-friendly layout (3 columns)

Card default styling.

Card surface 2 color.

Card surface 3 color.

Grid with Aside

Grid with Aside Article

Heading Button
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6

Article using the card styles for visual consistency.

Article using the card styles for visual consistency.

HTML
<div class="grid-4">
  <article class="card card-1">Column</article>
  <article class="card card-2">Column</article>
  <article class="card card-3">Column</article>
  <article class="card">Column</article>
</div>
<div class="grid-3">
  <article class="card">Column</article>
  <article class="card">Column</article>
  <article class="card">Column</article>
</div>

Actions

Interactive elements used to trigger user intent.

Buttons

Hierarchy is intentional: one primary action per region, secondary for supporting work, tertiary for lighter emphasis. Outline and ghost are style variants—not extra tiers. Destructive and warning styles are for risky or system-level states—not decoration.

Primary action

Primary: the main CTA per block—the hierarchy anchor.

HTML
<button class="btn btn-primary" type="button">
  <span class="label">Continue</span>
</button>

Secondary & tertiary actions

Secondary & tertiary actions: alternatives that support the primary without competing with it.

HTML
<button class="btn btn-secondary" type="button">
  <span class="label">Secondary</span>
</button>

<button class="btn btn-tertiary" type="button">
  <span class="label">Tertiary</span>
</button>

Variants & styles

Outline, ghost, and icon placement—visual treatments, not hierarchy tiers.

Outline

Outline white

White stroke for dark or colored surfaces, such as a hero.

HTML
<button class="btn btn-outline-white" type="button">
  <span class="label">Outline white</span>
</button>

Ghost

Quiet actions on bold or busy backgrounds—same style tier as outline, different surface.

Icon buttons

Leading, trailing, and icon-only patterns.

HTML
<button class="btn btn-outline" type="button">
  <span class="label">Outline</span>
</button>

<button class="btn btn-outline-primary" type="button">
  <span class="label">Outline primary</span>
</button>

<button class="btn btn-outline-secondary" type="button">
  <span class="label">Outline secondary</span>
</button>

<button class="btn btn-outline-tertiary" type="button">
  <span class="label">Outline tertiary</span>
</button>

<button class="btn btn-ghost" type="button">
  <span class="label">Ghost</span>
</button>

<button class="btn btn-secondary" type="button">
  <span class="iconify" aria-hidden="true">✓</span>
  <span class="label">Leading icon</span>
</button>

States

Disabled, loading, and link-styled actions.

As link
HTML
<button class="btn btn-primary" type="button" disabled>
  <span class="label">Disabled</span>
</button>

<button class="btn btn-primary is-loading" type="button" aria-busy="true">
  <span class="label">Loading</span>
</button>

<a class="btn btn-link" href="#buttons" role="button">As link</a>

Destructive & system feedback

Use for irreversible actions, alerts, and validation—not for everyday navigation.

HTML
<button class="btn btn-warning" type="button">
  <span class="label">Warning</span>
</button>

<button class="btn btn-danger" type="button">
  <span class="label">Danger</span>
</button>

<button class="btn btn-outline-warning" type="button">
  <span class="label">Outline warning</span>
</button>

<button class="btn btn-outline-danger" type="button">
  <span class="label">Outline danger</span>
</button>

Sizes

HTML
<button class="btn btn-primary btn-sm" type="button">
  <span class="label">Small</span>
</button>

<button class="btn btn-primary" type="button">
  <span class="label">Default</span>
</button>

<button class="btn btn-primary btn-lg" type="button">
  <span class="label">Large</span>
</button>

Layout

HTML
<button class="btn btn-primary btn-block" type="button">
  <span class="label">Full width</span>
</button>

Example: dialog actions

Typical footer: dismiss, commit, and destructive control aligned together.

Loaders

The Loader component is a small, customizable spinner used for showing loading states. It accepts width, heightand border props (strings or numbers) and sets matching CSS variables (--loader-width, --loader-height,--loader-border) so the pseudo-element spinner can be styled consistently. Place the loader inside a centered container or use a positioned parent (e.g. position: relative) when showing an overlay.

HTML
<div class="loader" role="status" aria-label="Loading" style="--loader-width: 3.2rem; --loader-height: 3.2rem; --loader-border: 4px solid var(--brand-700);"></div>

CTA Band

A prominent call-to-action band for demos, downloads, or contact.

Ready to align your study team?

Get a demo tailored to your protocol and timelines.

HTML
<div class="card cta">
  <div>
    <h3>Ready to align your study team?</h3>
    <p>Get a demo tailored to your protocol and timelines.</p>
  </div>
  <div class="row btn-row">
    <a class="btn btn-primary" href="mailto:hello@example.com"><span class="label">Request a demo</span></a>
    <a class="btn btn-secondary" href="#"><span class="label">Download overview</span></a>
  </div>
</div>
Forms & validation

Advanced inputs

Specialized pickers, uploads, and composite fields—useful for dense tools; keep them behind the core patterns when telling the system story.

Combobox / Autocomplete

Single-select and multi-select with chips. Arrow keys + Enter, click to choose.

Single-select

  • Projects
  • Teams
  • Reports
  • Documents
  • Billing
  • Settings

Multi-select

  • Front-end development
  • Accessibility
  • Design systems
  • TypeScript
  • UX research
  • Performance
HTML
<div class="combo" data-combo>
  <label class="hint" for="workspace">Workspace</label>
  <input id="workspace" class="combo-field" type="text" role="combobox" aria-expanded="false" />
</div>

File Uploader

Drag files here or browse. Shows basic validation and mock progress.

HTML
<div class="uploader">
  <input class="uploader-input" type="file" />
  <div class="card dropzone">
    <div class="dropzone-inner">Drop files here</div>
  </div>
</div>

File Uploader (Images)

Drag & drop or browse. Shows live thumbnails with remove & size checks.

Drop images here
or click to — up to 10 files, max 10 MB each
HTML
<div class="card dropzone">
  <div class="dropzone-inner">Drop an image</div>
  <input type="file" accept="image/*" />
</div>

Meter / Score

Linear score with thresholds + native <meter> styling. Drag to preview values.

72 • Fair
0–49: Poor • 50–74: Fair • 75–89: Good • 90–100: Excellent
HTML
<label for="score">Score</label>
<meter id="score" class="xmeter" min="0" max="100" low="50" high="75" optimum="100" value="72">72</meter>

Date-Range Picker

Select start and end dates using the calendar or the quick presets. Click a day to set the start date, then click another day to set the end date (clicking an earlier day will swap start and end). Use the presets for common ranges and the Clear button to reset.

Use the arrow keys to move between days, Page Up/Page Down to move between months, Home/End to jump to the start/end of the week, and Enter or Space to select the focused date.

October 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HTML
<div class="card drp" data-daterange>
  <div class="drp-inputs">
    <input type="text" aria-label="Start" />
    <span class="separator"></span>
    <input type="text" aria-label="End" />
  </div>
  <div class="drp-presets">
    <button class="chip" type="button">Last 7 days</button>
  </div>
</div>

Date Picker

Pick a single date with “Today” and “Clear”.

October 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HTML
<label for="date">Date</label>
<input id="date" type="date" />

Date Input (Popover)

Calendar opens on input/focus; ESC/outside to dismiss.

Start date
HTML
<label for="date-popover">Date</label>
<input id="date-popover" type="text" placeholder="YYYY-MM-DD" />

Navigation & structure

Wayfinding, pagination, and command-driven shortcuts—tabs and accordion live at the end of this page.

Pagination

Reusable pager with first/prev/number/next/last, accessible keyboard shortcuts, and a page-size selector.

Keyboard: ← → (prev/next), Home/End (first/last), PageUp/PageDown (skip pages). The demo uses a skip step of 5 pages.
53 items • Page 1 of 7
  • Record #1
    Placeholder row for pagination demo.
  • Record #2
    Placeholder row for pagination demo.
  • Record #3
    Placeholder row for pagination demo.
  • Record #4
    Placeholder row for pagination demo.
  • Record #5
    Placeholder row for pagination demo.
  • Record #6
    Placeholder row for pagination demo.
  • Record #7
    Placeholder row for pagination demo.
  • Record #8
    Placeholder row for pagination demo.
HTML
<div class="card pagination-card">
  <ul class="pagi-list">
    <li class="card">Row</li>
  </ul>
</div>

Command Palette

Quickly jump to design system sections (same anchors as the slide-over nav). Press ⌘/Ctrl + K or click the button to open the palette. Type to filter, use ↑/↓ to navigate, Enter to run, and Esc to close.

HTML
<div class="overlay" role="dialog" aria-modal="true">
  <div class="card modal-window size-md cmdk-panel">
    <header class="modal-header"><h3 class="modal-title">Search</h3></header>
    <div class="modal-body">
      <input type="search" aria-label="Command" />
    </div>
  </div>
</div>

Search Suggest

Header-anchored search field with a filtered suggestion card. Sits below the header and above page content so header links stay clickable. Wire any opener — typically a SearchToggle in your header — to its imperative handle (or to searchSuggestBus for cross-tree openers). Click the button below, then start typing — use ↑/↓ to navigate, Enter to pick, and Esc or the × to close.

HTML
<label for="site-search">Search</label>
<input id="site-search" type="search" />
<ul class="suggest-list" role="listbox">
  <li role="option">Buttons</li>
</ul>

Multi-step Modal Wizard

Guided flow with validation per step. Reuses your modal system.

HTML
<div class="card modal-window size-md">
  <header class="modal-header"><h3 class="modal-title">Step 1 of 3</h3></header>
  <div class="modal-body"><p>Choose a starting point.</p></div>
  <footer class="modal-footer">
    <button class="btn btn-ghost" type="button">Back</button>
    <button class="btn btn-primary" type="button">Next</button>
  </footer>
</div>

Data & feedback

Tables, filters, and feedback surfaces—empty, error, and success—so dense UIs stay understandable.

Toasts

Toasts are used to display brief, auto-dismissing notifications.

Toasts

HTML
<div class="card toast toast-info">
  <div class="card-header">
    <b>Room invite</b>
    <button class="btn btn-close toast-close" type="button" aria-label="Close">
      <span class="label">×</span>
    </button>
  </div>
  <p class="toast-message">This stays open until you join or dismiss it.</p>
  <div class="toast-action">
    <button class="btn btn-primary" type="button">
      <span class="label">Join room</span>
    </button>
  </div>
</div>

Inline Alerts

Success: Your settings have been saved.
Info: New template guidance is available.
Warning: A site has overdue tasks.

Tooltips & Popovers

Short hints (hover/focus) and richer, non-modal popovers (click/ESC/outside).

Tooltips

Link with tooltipHover/focus chip

Popovers

Popovers Examples

HTML
<button class="btn btn-ghost tooltip-trigger" type="button">Hover</button>
<div class="tooltip tooltip-top is-show" role="tooltip">Helpful hint</div>

<button class="btn popover-trigger" type="button">Open</button>
<div class="popover popover-bottom">
  <div class="popover-header">Title</div>
  <div class="popover-body">More detail.</div>
</div>

Modals & Overlays

Centered modal and slide-over overlay. Keyboard: ESC to close. Focus is trapped inside.

HTML
<div class="overlay" role="dialog" aria-modal="true">
  <div class="overlay-backdrop"></div>
  <div class="card modal-window size-md" role="document">
    <header class="modal-header">
      <h3 class="modal-title">Schedule a consult</h3>
      <button class="btn btn-close" type="button" aria-label="Close"></button>
    </header>
    <div class="modal-body">
      <p>Tell us a bit about your study.</p>
    </div>
    <footer class="modal-footer">
      <button class="btn btn-ghost" type="button"><span class="label">Cancel</span></button>
      <button class="btn btn-primary" type="button"><span class="label">Send</span></button>
    </footer>
  </div>
</div>

Empty, error & success

Reserve these surfaces for recoverable context—pair a short explanation with a clear next step, including positive confirmation after success.

Empty list

No projects match these filters.

Clear filters or create a project to get started.

Error

Could not load results.

Check your connection and try again.

Success

Changes saved.

Your team can see the update.

HTML
<article class="card surface-1">
  <h4>Empty</h4>
  <p class="small">Nothing here yet.</p>
</article>

Pattern: data dashboard slice

Filters, density, and tabular data are composed below—this block previews how those pieces align in one toolbar.

Status: ActiveRegion: All

See Data table and Filters for full implementations and accessibility behavior.

HTML
<article class="card metric">
  <span class="metric-title">Open items</span>
  <div class="metric-value">24</div>
</article>

Cards

Modular card layouts with header support, variant styling, and interactive hover/focus states for clear content grouping and visual hierarchy.

Quarterly roadmap

Prioritized themes for the next cycle, with owners and target dates.

Updated 2h ago · Strategy · 4 owners

With Header

This card has a header with an icon and text.

This card has no header. Just content.

Card 0 alternate styling.

Card 1 alternate styling.

Card 2 alternate styling.

Card inverse styling.

HTML
<article class="card">
  <div class="card-header"><h3>Title</h3></div>
  <p>Body copy</p>
  <div class="row btn-row gap">
    <button class="btn btn-primary" type="button"><span class="label">View plan</span></button>
    <button class="btn btn-secondary" type="button"><span class="label">Share</span></button>
  </div>
</article>
<article class="card card-0">Card 0</article>
<article class="card card-1">Card 1</article>
<article class="card card-2">Card 2</article>
<article class="card card-inverse">Inverse</article>

Data Table

Sortable columns, sticky header, and client-side pagination.

Sort by:
IDPhaseVersionStatusTask
1000UI DesignISprint Planning12
1001UI DevelopmentIIIn Review19
1002Accessibility FixesIIIDeployed26
1003Bugs & IssuesISprint Planning33
1004UI DesignIIIn Review40
1005UI DevelopmentIIIDeployed47
1006Accessibility FixesISprint Planning54
1007Bugs & IssuesIIIn Review61
Click headers to sort. Rows per page selectable below.
Page 1 / 4
HTML
<div class="table-container">
  <table>
    <thead>
      <tr><th class="th-sort">Name</th><th>Status</th></tr>
    </thead>
    <tbody>
      <tr><td>Alpha</td><td>Open</td></tr>
    </tbody>
  </table>
</div>

Metric Cards

Small metric cards for dashboards and summaries.

...…
—
...…
—
...…
—
HTML
<article class="card metric">
  <div class="metric-top">
    <span class="metric-title">Active</span>
    <span class="change up">+4%</span>
  </div>
  <div class="metric-value">128</div>
</article>

Timeline Sample

A vertical timeline using the .timeline and .step classes for sequential layouts.

1
Step 1

Start your project and set up the basics.

2
Step 2

Develop features and iterate quickly.

3
Step 3

Test, deploy, and monitor your app.

HTML
<div class="timeline">
  <div class="step">
    <div class="dot">1</div>
    <div class="body">
      <div class="h3">Step</div>
      <p>What happened.</p>
    </div>
  </div>
</div>

Filters

Toggle chips with counts, “Clear all,” and live results.

0 selected

Result 1

Sample result

Result 2

Sample result

Result 3

Sample result

Result 4

Sample result

Result 5

Sample result

Result 6

Sample result

Result 7

Sample result

Result 8

Sample result
HTML
<div class="card filters-card">
  <div class="row filters-chips">
    <button class="chip-toggle is-on" type="button">Open <span class="count">12</span></button>
    <button class="chip-toggle" type="button">Closed</button>
    <button class="btn btn-ghost btn-sm" type="button">Clear all</button>
  </div>
</div>

Logic Pills (Selected Filters)

Removable filter chips with AND/OR logic and quick “clear all”.

No filters selected
18 results

Result 1

Version: II • Status: Deployed • Phase: UI Design

Result 2

Version: I • Status: Sprint Planning • Phase: UI Development

Result 3

Version: II • Status: Sprint Planning • Phase: UI Development

Result 4

Version: I • Status: Deployed • Phase: UI Development

Result 5

Version: II • Status: Sprint Planning • Phase: UI Design

Result 6

Version: I • Status: Sprint Planning • Phase: UI Development

Result 7

Version: II • Status: Deployed • Phase: UI Development

Result 8

Version: I • Status: Sprint Planning • Phase: UI Development

Result 9

Version: II • Status: Sprint Planning • Phase: UI Design

Result 10

Version: I • Status: Deployed • Phase: UI Development

Result 11

Version: II • Status: Sprint Planning • Phase: UI Development

Result 12

Version: I • Status: Sprint Planning • Phase: UI Development

Result 13

Version: II • Status: Deployed • Phase: UI Design

Result 14

Version: I • Status: Sprint Planning • Phase: UI Development

Result 15

Version: II • Status: Sprint Planning • Phase: UI Development

Result 16

Version: I • Status: Deployed • Phase: UI Development

Result 17

Version: II • Status: Sprint Planning • Phase: UI Design

Result 18

Version: I • Status: Sprint Planning • Phase: UI Development
Add:
HTML
<div class="logic-pill-row" role="list">
  <button class="lp-pill chip btn-sm" type="button">Status</button>
  <span class="lp-connector">AND</span>
  <button class="lp-pill chip btn-sm" type="button">Owner</button>
</div>

System principles

Guidelines that define how the system is applied across interfaces.

  • One primary action per region

    Primary actions are used sparingly to maintain clarity and focus.

  • Semantic colors are reserved for feedback

    Warning and error states communicate system status, not hierarchy.

  • Core patterns precede advanced inputs

    Common interactions are prioritized before introducing complexity.

  • Consistency is driven by tokens

    Design tokens ensure alignment across components, themes, and states.

  • Accessibility is a baseline, not an afterthought

    All components are designed to meet contrast, focus, and usability standards.

Built for real products

This system is designed to scale across production environments, balancing performance, accessibility, and usability.

Tabs & accordion

Disclosure patterns placed here so the workflow example stays the primary narrative for multi-step content.

Tabs

Accessible tab interface with ARIA roles, keyboard navigation (←/→, Home/End), focus management, and horizontal scrolling for overflow. Only one tab panel is visible at a time, and all controls are screen reader friendly.

Overview

High-level snapshot of the study—sites, milestones, and current risks.

Pill style tabs.

Overview

High-level snapshot of the study—sites, milestones, and current risks.

Rounded tabs with a flat bottom that sits on the panel.

Overview

High-level snapshot of the study—sites, milestones, and current risks.
HTML
<div class="tabs" data-tabs>
  <div class="tabs-desktop">
    <div class="tablist scrollable" role="tablist">
      <button class="tab is-active" type="button" role="tab" aria-selected="true">Overview</button>
      <button class="tab" type="button" role="tab">Details</button>
    </div>
    <div class="card tab-panels">
      <div class="panel" role="tabpanel">Panel content</div>
    </div>
  </div>
</div>

<div class="tabs tabs-pills" data-tabs></div>
<div class="tabs tabs-rounded" data-tabs></div>

Accordion

One panel at a time (type="accordion", the default). Opening another header closes the previous. Click the open header to collapse all.

Use the sign-in screen, choose “Forgot password,” and follow the email link. Links expire after a short window for security.

Collapsible

Any number of panels open (type="collapsible", or the Collapsible alias). Each header toggles only its own panel.

Use the sign-in screen, choose “Forgot password,” and follow the email link. Links expire after a short window for security.

Open Billing → Invoices and select a period. PDF exports include your account ID and tax details when available.

HTML
<div class="accordion" id="acc-demo">
  <div class="card acc-item is-open">
    <h3 class="acc-header">
      <button class="acc-trigger" type="button" aria-expanded="true">
        Title
        <span class="acc-indicator" aria-hidden="true"></span>
      </button>
    </h3>
    <div class="acc-panel">
      <div class="acc-panel-inner">Panel content</div>
    </div>
  </div>
</div>

<div class="accordion collapsible">
  <div class="card acc-item is-open">
    <h3 class="acc-header">
      <button class="acc-trigger" type="button" aria-expanded="true">Title</button>
    </h3>
    <div class="acc-panel"><div class="acc-panel-inner">Panel content</div></div>
  </div>
</div>