Speyer UI v3.5.0

Speyer UI System

Built around four constraints: accessibility is mandatory, no build tools required, components work with or without JS, and status is never communicated by color alone. Lightweight and zero runtime dependencies. Scores 100 on Lighthouse accessibility.

Components
50+
v3.5.0
Dependencies
0
Zero
A11y Target
AA
WCAG 2.1
Lighthouse
100
A11y

Design Philosophy

Five principles that guide every decision in SUI.

Readability
Text and data must be easy to scan and understand at a glance.
Accessibility
WCAG 2.1 AA compliance. Color is never the sole way to convey information.
Mobile-First
Layouts designed for small screens, then scaled up. 44px touch targets.
Color-Blind Friendly
No red/green only patterns. Every status uses icon + text label.
Consistency
Same components, same behavior, everywhere. Tokens are the contract.

Architecture

Four files, zero runtime dependencies, instant deployment.

sui-tokens.css
Design tokens — colors, spacing, typography, shadows, z-index
Required
sui-components.css
All component classes — buttons, cards, badges, tables, and more
Required
sui.js
Interactive toolkit — modals, toasts, dropdowns, tooltips, accordion
Optional

CDN Ready
Minified files in /dist — served via jsDelivr. No signup required.
CDN

AI-Ready
Paste a prompt, get SUI-compliant code. Works with any AI tool.
AI

Component Library

Every SUI component, live and interactive. All built from design tokens, all accessible by default.

Accordion

Collapsible content sections. Keyboard accessible (Enter/Space). Multiple sections can be open.

SUI is a lightweight, accessible design system built on CSS custom properties. It provides design tokens, reusable component classes, and an optional JavaScript toolkit for interactive components — no heavy frameworks required.

Alerts

Every alert uses icon + text. Color is never the sole indicator.

Avatars

Initials-based, deterministic colors. Privacy-friendly, no image dependencies.

Sizes
AS JK ML DT RW BN
Profile header pattern (XL)
AS
Adrian Speyer
VP Marketing & Technology
Avatar group
AS JK ML +4

Badges

Always paired with icon or text. Covers every SaaS status and labeling need.

Status badges
Active Pending Failed Stable Inactive
Feature badges
New Beta Pro
Modifiers
Outline Small Online Offline 3 99+
Radius utilities
Square Rounded Default Pill
Shields
built withSUI buildpassing coverage47% licenseMIT version2.3.0

Bottom Sheet

Mobile-first slide-up drawer. Handles safe areas, scroll trapping, and Escape key.

Buttons

44px touch-friendly. Visible focus states. Tab through to test keyboard navigation.

Card Variants

Default (border), elevated (shadow), muted, and flush.

Default

Border-based separation. The standard card.

Shadow

Opt-in elevation with sui-card-shadow.

Muted

Elevated background for nested cards.

Structured Card

Header, body, and the action footer — sui-card-footer right-aligns buttons with a top border, matching the modal footer anatomy.

Muted + Interactive

Subtle hover lift. Lower visual weight than regular interactive.

Avoid double padding. If you use .sui-card-header / .sui-card-body / .sui-card-footer, pair the wrapper with .sui-card-flush to zero out the card’s own padding. Use .sui-card-compact for dense layouts like KPI grids.

Chips / Tags

Visual pill component. Behaviour (add, remove, keyboard) is bring-your-own JS — same as icons.

Default chips
Design Frontend Accessibility React
Colour variants
Approved Pending Rejected Review Premium

Dropzone

File upload area. CSS only — drag-and-drop behaviour is bring-your-own JS.

Drop files here or click to browse

PNG, JPG, PDF up to 10MB

Embed & Keyboard

Responsive video embeds and keyboard shortcut styling.

Responsive video embed (16:9)

16:9 video area

Keyboard shortcuts

Toggle theme: Ctrl + Shift + T

Search: Ctrl + K

Save: Ctrl + S

Empty State

The "no data yet" pattern every table, list, and dashboard needs.

No projects yet
Create your first project to get started. It only takes a few seconds.

Form Inputs

Clear borders, visible focus rings, and accessible error messages.

As it appears on your account.
Please enter a valid email address.
Username is available.
Preferred contact

Input Action v2.5.0

Embed a button inside an input — for search, copy, clear, or show/hide password.

Click the eye to toggle visibility.

Interactive Components

Powered by sui.js. Modals, toasts, dropdowns, and tooltips.


Settings Help & Support

Layout Utilities

Grid auto-fit, horizontal scroll, flex-nowrap, interactive cards, and container queries.

Interactive card (hover for elevation)
Project Alpha
Click or tap to navigate. Hover reveals shadow.
Project Beta
Keyboard-accessible with focus ring.
Project Gamma
Composes with any card variant.
Grid auto-fit (flexible column count)
Auto
Auto
Auto
Auto
Auto
Horizontal scroll (sui-scroll-x)
Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
Container queries (sui-container opt-in)
CQ
Responsive to container
This text hides in narrow containers.
CQ
Same component
Adapts to its container, not the viewport.

Mark / Highlight

Search result highlighting. Automatic dark mode and print handling.

Search results: The quick brown fox jumped over the lazy dog while the quick cat watched.

sui-mark = all matches (soft yellow) · sui-mark-current = current match (strong amber)

Metadata Line

Compact metadata with automatic dot separators. No separator markup needed — CSS handles it.

1,234 words 5 min read Updated 3h ago
Adrian Speyer Draft 12 comments v2.1

Navigation

Breadcrumbs, pagination, and dividers for structured content.

Breadcrumb
Pagination
Dividers
Item A Item B Item C
Nav links

Panel

Side panel / slide-over — the third overlay type. Dialog blocks, sheet slides up, panel slides from the right. Desktop: coexists with main content. Mobile: full-screen.

CRM Contact Detail

Click to open a panel with contact details. Desktop: panel appears alongside this content. Mobile: full-screen overlay.

Dual focus model

Desktop (≥769px): Focus moves to the panel but is not trapped. Both the panel and main content remain interactive — panels are parallel content, not blocking content. Trapping focus would prevent keyboard users from referencing the main view.

Mobile (<769px): Panel goes full-screen. The user can no longer see main content, so the interaction model changes to a blocking overlay with focus trap enabled.

If the viewport resizes while the panel is open, the trap toggles automatically.

Usage
<!-- Trigger -->
<button data-sui-panel="#my-panel" aria-expanded="false">Open</button>

<!-- Panel (outside main for stacking context) -->
<div class="sui-panel" id="my-panel" aria-label="Detail" aria-hidden="true">
  <div class="sui-panel-header">
    <span class="sui-panel-title">Title</span>
    <button class="sui-panel-close sui-btn sui-btn-ghost sui-btn-sm" type="button"
            aria-label="Close panel">&times;</button>
  </div>
  <div class="sui-panel-body">Content</div>
  <div class="sui-panel-footer">
    <button class="sui-btn sui-btn-ghost">Cancel</button>
    <button class="sui-btn sui-btn-primary">Save</button>
  </div>
</div>

<!-- Custom width -->
<div class="sui-panel" style="--sui-panel-width: 50vw">...</div>

<!-- No backdrop (desktop) -->
<div class="sui-panel sui-panel-no-backdrop">...</div>
JavaScript API
SUI.panel.open('#my-panel');
SUI.panel.close('#my-panel');
SUI.panel.toggle('#my-panel');

Progress Bars

Accessible with aria attributes. Status-colored variants and indeterminate mode.

Project completion72%
Storage used45%
Disk space89%
Uploading…
Labeled (text inside bar)
75%
92%
58%
34%
67%

Prose

Long-form typography for articles, docs, and rendered Markdown. One class, it works. Size variants and width constraints available.

sui-prose (default — 18px base)

The Human Advantage

In a world where AI automates everything else, human connection becomes the last competitive advantage. This is not a metaphor — it's a measurable business outcome.

Why Connection Wins

The companies that thrive in the next decade will be the ones that invest in meaningful relationships — with customers, partners, and communities.

The best technology disappears. What remains is the relationship it enabled.

Key Metrics

  • Customer retention increases 23% with community investment
  • NPS scores correlate with depth of connection, not frequency
  • Enterprise deals close 40% faster when champions exist
const roi = connections.map(c => c.lifetime_value)
  .reduce((sum, v) => sum + v, 0);

StrategyInvestmentReturn
Community$50K/yr3.2x
Events$120K/yr4.1x
sui-prose sui-prose-sm

Compact prose at 15px. Tighter line height for dense content like sidebars, footnotes, or auxiliary text panels.

  • Smaller base size
  • Tighter leading
sui-prose sui-prose-lg

Generous prose at 20px. Wider line height for immersive reading — book chapters, long articles.

  • Larger base size
  • Relaxed leading

Screen Layout

Full-viewport app shell for mobile-first apps. Sticky header, scrollable body, pinned footer with safe area insets.

sui-screen mock
My App
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7

Classes

sui-screen — full-viewport flex column (100dvh)

sui-screen-header — sticky top with safe-area-inset-top

sui-screen-body — scrollable area (flex:1)

sui-screen-footer — pinned bottom with safe-area-inset-bottom


Multi-view

Wrap screens in data-sui-screens and toggle with .is-active. Inactive screens are hidden. Use sui-screen-solo for single-screen apps.

Segmented Control

Value picker with radio semantics. Arrow keys navigate. Not tabs — semantically distinct.

View mode
Billing period

Skeleton Loaders

Placeholder shimmer for content that's still loading.

Stepper

Multi-step workflows. CSS-only. Horizontal on desktop, vertical on mobile. States communicated by shape + colour — never colour alone.

3 steps — step 2 active
  1. Account
  2. 2 Details
  3. 3 Review
5 steps — step 3 active
  1. Cart
  2. Shipping
  3. 3 Payment
  4. 4 Review
  5. 5 Confirm
7 steps — all complete
  1. Register
  2. Verify
  3. Profile
  4. Settings
  5. Import
  6. Review
  7. Launch

Tables

Responsive tables with mobile stacking, striped and hover variants.

Team Members

NameRoleStatusJoined
ASAdrian Speyer
Admin Active Jan 2024
JKJane Kim
Developer Active Mar 2024
MLMike Lee
Designer Away Jun 2024
RWRiya Wang
PM Offline Sep 2024

Sortable + Interactive

CompanyRevenueStageOwner
Acme Corp $120,000 Closed Won Adrian S.
Globex Inc $85,000 Negotiation Jane K.
Initech $45,000 Discovery Mike L.

Table Modifiers v2.5.0

Combine with any sui-table. Sticky header, dense rows, and tablet card stacking.

Sticky + Dense

IDMetricValueChange
001Page views12,482+8%
002Sessions4,291+3%
003Bounce rate34.2%+2%
004Avg. duration2m 41s-5%
005Conversions847+12%
006Revenue$24,100+6%

Stack (tablet card mode)

sui-table-stack stacks at 768px. Resize your browser below tablet width to see the card layout.

NameDepartmentStatus
Dana ReevesEngineeringActive
Alex ChenDesignAway

Timeline

Activity feed layout. Avatar left, content right, vertical connector. Content is flexible — badges, text, timestamps all compose inside.

DK
David Kim 2h ago
Email

Updated proposal attached — ready for review.

SC
Sarah Chen Yesterday
Call

30 min discovery call. Interested in Enterprise tier.

AR
Alex Rivera 2 days ago
Meeting

Quarterly review. Action items assigned.

JL
Jordan Lee 3 days ago
Note

Contract renewal due next month. Flag for follow-up.

Toolbar

Horizontal scrolling action bar for formatting, filters, or controls. Hidden scrollbar, touch-friendly.

Default
Bordered + Compact

Visibility Utilities

Two-tier visibility: completely hidden vs. screen-reader only.

sui-hidden

Removes from layout and accessibility tree. Use for toggling panels, tabs, and conditional content.

display: none !important
You cannot see this.
sui-visually-hidden

Hidden visually but remains accessible to screen readers. Use for skip links and descriptive labels.

clip-path: inset(50%) Screen readers can see this.

For Designers

Token reference, geometry specs, and workflow guidance for Figma or any design tool.

538 Purpose-Built Icons New in v3

Original SVG icons for SaaS interfaces — 28 categories, accessibility built in, works in both themes.

Navigation Actions Status Data Commerce AI Dev Brand Travel + 19 more
Browse all 538 icons

Token-first workflow

Design in layers: background → surface → border → text → accents.

Contrast rule
Target 4.5:1 for body text. Use token pairs: --sui-text-primary on --sui-bg-card.
Red/green safe
Never rely on colour alone. Always pair icon + label + (optional) shape.
Spacing system
Use the 8px grid: --sui-space-2 (8px), --sui-space-3 (16px), --sui-space-4 (24px).
Typography
Inter via Google Fonts. H1 32/700, H2 24/600, H3 20/600, Body 16/400.

Quick reference

The most common tokens for day-to-day layouts.

Background--sui-bg-primary
Card--sui-bg-card
Elevated--sui-bg-elevated
Border--sui-border
Primary action--sui-blue-primary
Shadow (opt-in)--sui-shadow-md

Component Geometry

Consistent border radius, sizing, and elevation from the token system.

Buttons / Inputs
12px
--sui-radius-md
Cards / Panels
16px
--sui-radius-lg
Touch target
44px
--sui-touch-target
Max width
1280
--sui-max-width

AI Prompt

Paste into any AI tool to generate SUI-compliant code. Works with ChatGPT, Claude, Copilot, Cursor, and more.

Quick Prompt

Recommended for most tasks.

I want you to use the Speyer UI System (SUI) for this project.

## Step 1: Fetch the design system
Fetch the official SUI CSS and JS from CDN:
- Tokens: https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-tokens.min.css
- Components: https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-components.min.css
- JS (optional, defer): https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui.min.js

Place CSS <link> tags in <head>. Place <script> tags before </body> with the defer attribute.

Icons — SUI ships 538 purpose-built icons. Add the icon CSS and sprite loader:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-icons.min.css">
<script defer>
  fetch('https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-icons.min.svg')
    .then(r => r.text())
    .then(svg => { var d=document.createElement('div'); d.style.display='none'; d.innerHTML=svg; document.body.prepend(d); });
</script>

Or bring your own icons (Lucide, Heroicons, Phosphor, Font Awesome, or plain SVG).

Or fetch the readable source files from:
- https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/sui-tokens.css
- https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/sui-components.css
- https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/sui.js

Use the CSS custom properties (--sui- prefix) and component classes as your foundation.

## Step 2: Confirm display mode
Before writing any code, ask me:
"Would you like light mode only, dark mode only, or both (with a toggle)?"
Then implement accordingly:
- Light mode = default :root tokens
- Dark mode = [data-theme="dark"] tokens
- Both = include both + a toggle using the data-theme attribute

## Step 3: Apply SUI design rules
Core Principles: readability, accessibility, mobile-friendly, color-blind friendly, consistency.

Typography: Inter font (Google Fonts). Fallback: system-ui.
Scale: H1 32px/700, H2 24px/600, H3 20px/600, Body 16px/400, Small 14px/400, Meta 12px/400.

Layout: 8px spacing grid (--sui-space-1 through --sui-space-6). Mobile-first. Max width: 1280px. Min touch target: 44px.

Components (use SUI classes):
- Buttons: sui-btn, sui-btn-primary, sui-btn-secondary, sui-btn-outline, sui-btn-ghost, sui-btn-dashed, sui-btn-danger, sui-btn-success, sui-btn-sm, sui-btn-lg, sui-btn-full
- Cards: sui-card, sui-card-lg, sui-card-muted, sui-card-shadow, sui-card-flush, sui-card-header, sui-card-body, sui-card-footer
- Inputs: sui-input, sui-input-group, sui-input-label, sui-input-error, sui-input-success, sui-select, sui-checkbox-label
- Toggle: sui-toggle-label, sui-toggle, sui-toggle-track
- Badges: sui-badge + sui-badge-success/warning/error/info/neutral/new/beta/pro
- Badge modifiers: sui-badge-outline, sui-badge-sm, sui-badge-dot, sui-badge-count
- Alerts: sui-alert + sui-alert-success/warning/error/info (always icon + text)
- Avatars: sui-avatar + sui-avatar-sm/md/lg (initials-first, optional photo with onerror fallback)
- Tables: sui-table-wrap > sui-table (use data-label on td for mobile stacking)
- Table modifiers: sui-table-stack (card stacking at tablet), sui-table-sticky (sticky thead), sui-table-dense (compact padding)
- Input action: sui-input-action (embedded button inside input — search, copy, clear)
- Progress: sui-progress + sui-progress-bar + status variants + sui-progress-indeterminate
- Navigation: sui-breadcrumb, sui-pagination, sui-page-btn
- Accordion: sui-accordion (requires sui.js for interactivity)
- Dropdown: sui-dropdown (requires sui.js)
- Modal: dialog.sui-dialog (recommended, native) — or legacy sui-modal-overlay + sui-modal. Both work with SUI.modal.open/close.
- Toast: SUI.toast.success/error/warning/info (requires sui.js)
- Tooltip: sui-tooltip + sui-tooltip-content
- Empty state: sui-empty + sui-empty-icon + sui-empty-title + sui-empty-text
- Skeleton: sui-skeleton + sui-skeleton-text/heading/avatar/card
- Bottom sheet: sui-sheet + sui-sheet-panel/handle/header/body/footer (requires sui.js). SUI.sheet.open/close.
- Sidenav: sui-sidenav + sui-sidenav-panel/link/heading/toggle/close (requires sui.js). Sticky sidebar desktop, slide-in mobile. SUI.sidenav.open/close/toggle.
  - Collapsible groups: use sui-sidenav-group-toggle (aria-expanded + aria-controls) + sui-sidenav-group-links (+ optional sui-sidenav-group-count). SUI.sidenav.collapseAll/expandAll.
- Panel: sui-panel + sui-panel-header/title/close/body/footer (requires sui.js). Slides from right. Desktop: no focus trap (parallel content). Mobile: full-screen with trap. Width: --sui-panel-width. No backdrop: sui-panel-no-backdrop. SUI.panel.open/close/toggle.
- Segmented control: sui-segmented + sui-segment (role="radiogroup" + role="radio", requires sui.js)
- Chip/Tag: sui-chip + sui-chip-remove (CSS only, behaviour is bring-your-own JS)
- Interactive card: sui-card-interactive (clickable card with hover shadow elevation)
- Tables: sui-table-interactive (clickable rows), sui-table-sortable (th[data-sort] visual indicators)
- Progress labeled: sui-progress-labeled + sui-progress-text (text inside bar, contrast-safe in both themes)
- Prose: sui-prose (long-form typography container), sui-prose-sm/lg (size), sui-prose-narrow/wide (width)
- Mark: sui-mark (search highlight), sui-mark-current (active match)
- Meta: sui-meta (dot-separated metadata line)
- Toolbar: sui-toolbar + sui-toolbar-btn + sui-toolbar-sep, sui-toolbar-bordered, sui-toolbar-compact
- Screen: sui-screen (100dvh app shell), sui-screen-header, sui-screen-body, sui-screen-footer, sui-screen-solo
- Dropzone: sui-dropzone (CSS only, .is-dragover state, behaviour is bring-your-own JS)
- Timeline: sui-timeline + sui-timeline-item + sui-timeline-content (activity feed, role="feed", optimised for sui-avatar-sm)
- Stepper: sui-stepper + sui-step + sui-step-indicator (states: is-complete, is-active, is-pending; aria-current="step" on active)
- Topbar aligned: sui-topbar-aligned modifier (flex alternative to grid, brand left, nav+actions right)
- Avatars: sui-avatar + sui-avatar-sm/md/lg/xl (initials-first, optional photo with onerror fallback)
- Scoped tabs: wrap in data-sui-tabs to isolate multiple tab sets on one page
- Layout: sui-grid, sui-grid-2/3/4, sui-grid-auto, sui-section, sui-flex, sui-flex-col, sui-flex-nowrap, sui-scroll-x
- Container queries: sui-container (opt-in), sui-cq-stack, sui-cq-full, sui-cq-hide

CRITICAL: Check Recipes Before Building Custom CSS
SUI uses composition — complex SaaS patterns combine existing classes.
Before writing custom CSS, check if a recipe exists:

| Pattern | Composes From | Type |
|---------|--------------|------|
| Kanban / Board | sui-flex-nowrap + sui-scroll-x + sui-card | Recipe |
| Master-Detail / Inbox | sui-table-interactive + sui-panel | Recipe |
| Notification Panel | sui-panel + stacked sui-card + sui-badge | Recipe |
| Floating Action Bar | sui-card-shadow + sui-btn + fixed position | Recipe |
| Panel Push Mode | CSS grid toggle resizing main content | Recipe |
| Inline Edit | sui-input + sui-btn-sm + click-to-edit | Recipe |
| Settings / Preferences | sui-toggle + sui-input + sui-segmented | Recipe |
| Action Sheet | sui-sheet + sui-btn-ghost + sui-divider | Recipe |
| Button Group | sui-grid + sui-btn + role="radiogroup" | Recipe |
| App Shell | sui-screen + sui-segmented | Recipe |
| Blog Post | sui-prose + sui-meta + sui-avatar | Recipe |
| Document Library | sui-table + sui-badge + sui-avatar | Recipe |
| Profile Page | sui-avatar-xl + sui-badge + sui-card | Recipe |
| Split Pane | CSS grid + sui-card + sui-avatar | Recipe |
| Sidenav Search | sui-input + filter JS hiding sui-sidenav-link | Recipe |
| Sidenav Context | SUI.sidenav.collapseAll() + expand active | Recipe |

Common names → SUI solutions:
- Sidebar / Side menu → sui-sidenav (Component). Collapsible groups: sui-sidenav-group-toggle + sui-sidenav-group-links.
- Modal / Popup / Dialog → sui-dialog with native <dialog> (Component)
- Drawer / Slide-over → sui-panel (right) or sui-sheet (bottom) (Component)
- Toast / Snackbar → SUI.toast.success/error/warning/info() (JS API)
- Wizard / Steps → sui-stepper + sui-step + sui-step-indicator (Component)
- Activity feed / Log → sui-timeline + sui-timeline-item (Component)
- Search highlight → sui-mark + sui-mark-current (Component)
- Action bar → sui-toolbar + sui-toolbar-btn + sui-toolbar-sep (Component)
- Tag / Chip → sui-chip + sui-chip-remove (Component)
- Segmented toggle → sui-segmented + sui-segment (Component)
- Empty state → sui-empty + sui-empty-icon/title/text (Component)
- File upload → sui-dropzone (Component)
- App shell / SPA → sui-screen + sui-screen-header/body/footer (Component)

For the comprehensive reference (all class names, ARIA requirements, recipes with code), fetch:
https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/.claude/instructions.md

Accessibility (mandatory):
- WCAG 2.1 AA contrast ratios
- Colour must NEVER be the only indicator — always pair with icon + text
- Colour-blind friendly: no red/green-only patterns
- Keyboard navigation, visible focus states, ARIA labels
- Tabs MUST use: role="tablist" on container, role="tab" on buttons, role="tabpanel" on panels, aria-label on each
- Any text hidden via display:none at any breakpoint needs aria-label backup on its parent
- Never use aria-selected without role="tab"
- Respect prefers-reduced-motion
- Skip link pattern: add a skip link as the first child of <body>: <a href="#main" class="sui-visually-hidden">Skip to main content</a> and add id="main" to your <main> element

Icons: SUI works with any icon library. Always add aria-hidden="true" on decorative icons. Always pair icons with visible text labels — never use an icon alone to communicate meaning.

Status patterns (always icon + text):
- Success: ✓ + text | Warning: ⚠ + text | Error: ✕ + text | Info: ℹ + text

Elevation: Borders are the default card separation. Shadows are opt-in (sui-card-shadow).
Motion: 150-250ms ease-out. Feedback only. No decorative animations.
Brand colours: SUI semantic tokens (--sui-blue-primary, etc.) shift between themes. Do NOT use them for logos or brand marks — hardcode brand colours or use a custom property instead.

If you notice a component or pattern SUI doesn't cover yet, mention it — we welcome contributions at the GitHub repo.

Full docs: https://github.com/adrianspeyer/speyer-ui

Minimal Prompt

For quick tasks.

Use the Speyer UI System (SUI).
CDN: https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-tokens.min.css and sui-components.min.css
Optional JS: https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui.min.js
CSS links go in <head>. Scripts go before </body> with defer.
Icons: SUI ships 538 purpose-built icons. Add sui-icons.min.css + sprite loader (see docs). Or bring your own (Heroicons, Phosphor, Font Awesome, plain SVG). Always pair icons with text labels.
Ask me if I want light mode, dark mode, or both before coding.
Key rules: Inter font, 8px spacing grid, 44px min touch targets, 12px button radius, 16px card radius, borders default (shadows opt-in), WCAG 2.1 AA, all status indicators must use icon + text (never colour alone), mobile-first, colour-blind friendly, tabs must use role="tablist"/role="tab"/role="tabpanel".
Avatars are initials-first (optional photo with onerror fallback). Modals use native <dialog class="sui-dialog">. Bottom sheet: sui-sheet. Sidenav: sui-sidenav with collapsible groups (sui-sidenav-group-toggle + aria-expanded + aria-controls). Panel: sui-panel (slides from right, --sui-panel-width, sui-panel-no-backdrop). SUI.panel.open/close/toggle. Desktop: no focus trap. Mobile: focus trap. Segmented control: sui-segmented. Chips: sui-chip. Tables: sui-table-interactive (clickable rows), sui-table-sortable (sort indicators), sui-table-stack (card stacking at tablet), sui-table-sticky (sticky thead), sui-table-dense (compact). Input with button: sui-input-action. Timeline: sui-timeline. Dropzone: sui-dropzone. Stepper: sui-stepper + sui-step + sui-step-indicator (is-complete/is-active/is-pending). Scoped tabs: wrap in data-sui-tabs. SUI.tabs.activate(tabElement) for programmatic switching. Accordion: SUI.accordion.toggle(trigger), .expandAll(container), .collapseAll(container). Prose: sui-prose for long-form content. Mark: sui-mark for search highlights. Meta: sui-meta for dot-separated metadata. Toolbar: sui-toolbar for action bars. Screen layout: sui-screen (100dvh), sui-screen-header, sui-screen-body, sui-screen-footer. Topbar: sui-topbar (grid default) or sui-topbar-aligned (flex, brand left, nav+actions right). Multi-view: toggle .is-active. Single-screen: sui-screen-solo. Buttons: sui-btn + sui-btn-primary/secondary/ghost/dashed/danger/success. Use sui-* component classes for everything.
CRITICAL: Before building custom CSS, check if a recipe exists. SUI composes patterns like Kanban (flex-nowrap + scroll-x + card), Master-Detail (table-interactive + panel), Notification Panel (panel + card + badge), Floating Action Bar (card-shadow + btn + fixed position), and 5 integration recipes (Flatpickr, Tom Select, FilePond, Quill, Chart.js) with SUI token overrides. 29 recipes total. Full recipe list and comprehensive AI reference: https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/.claude/instructions.md
Skip link: add <a href="#main" class="sui-visually-hidden">Skip to main content</a> as first child of <body>.
If a component is missing from SUI, mention it — contributions welcome.
Full docs: https://github.com/adrianspeyer/speyer-ui

System Prompt

For custom instructions or Cursor rules.

When the user says "use SUI", "use the Speyer UI System", or "Speyer UI":

1. Fetch the SUI design files from CDN:
   https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-tokens.min.css
   https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui-components.min.css
   https://cdn.jsdelivr.net/gh/adrianspeyer/speyer-ui@latest/dist/sui.min.js (optional, for modals/toasts/dropdowns)
   Or readable source from: https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/
   CSS <link> tags go in <head>. <script> tags go before </body> with defer.
2. Icons: SUI ships 538 purpose-built icons via sui-icons.min.css + sprite loader. Add the CSS and use <svg class="sui-icon"><use href="#sui-icon-{category}-{name}"/></svg>. Or bring your own icons (Heroicons, Phosphor, Font Awesome, or plain SVG). Ask if they have a preference.
3. Ask the user: "Would you like light mode, dark mode, or both?"
4. Apply all CSS custom properties (--sui- prefix) and component classes.
5. Follow these design rules:
   - Font: Inter (Google Fonts), fallback system-ui
   - 8px spacing grid (--sui-space-1 through --sui-space-6)
   - Min touch target: 44px, max content width: 1280px
   - Buttons: 44px height, 12px radius | Cards: 16px radius, border separation
   - Shadows: opt-in only (sui-card-shadow) — borders are default
   - WCAG 2.1 AA contrast | Keyboard nav | prefers-reduced-motion support
   - CRITICAL: Never use colour alone for status. Always pair with icon + text.
   - Colour-blind safe: no red/green-only patterns
   - Tabs: role="tablist" on container, role="tab" on buttons, role="tabpanel" on panels
   - Never use aria-selected without role="tab"
   - Avatars: initials-first (optional photo with onerror fallback)
   - Icons: use aria-hidden="true" on decorative icons. Never use an icon alone without a text label.
6. Use SUI component classes: sui-btn (+ sui-btn-primary/secondary/ghost/dashed/danger/success),
   sui-card, sui-badge, sui-alert, sui-avatar, sui-toggle, sui-progress, sui-accordion,
   sui-dropdown, sui-dialog (native modal), sui-modal (legacy), sui-tooltip, sui-breadcrumb,
   sui-pagination, sui-empty, sui-skeleton, sui-table, sui-sheet (bottom sheet),
   sui-segmented (segmented control), sui-chip (tag/chip), sui-card-interactive,
   sui-table-interactive, sui-table-sortable, sui-table-stack (card stacking at tablet),
   sui-table-sticky (sticky thead), sui-table-dense (compact padding),
   sui-input-action (embedded button inside input),
   sui-progress-labeled, sui-dropzone,
   sui-timeline, sui-stepper (multi-step wizard, CSS-only),
   sui-prose (long-form typography), sui-mark (search highlight), sui-meta (metadata line),
   sui-toolbar (action bar), sui-grid-auto, sui-scroll-x, sui-flex-nowrap,
   sui-container (container queries, opt-in), sui-avatar-xl,
   sui-topbar (grid default) or sui-topbar-aligned (flex, brand left, nav+actions right),
   sui-screen/sui-screen-header/sui-screen-body/sui-screen-footer (app shells),
   sui-sidenav + sui-sidenav-group-toggle/links (collapsible groups, SUI.sidenav.collapseAll/expandAll),
   sui-panel (side panel, slides from right, --sui-panel-width, sui-panel-no-backdrop, SUI.panel.open/close/toggle. Desktop: no focus trap. Mobile: focus trap.), etc.
   Themes: light, dark, auto.
7. CRITICAL: Before building custom CSS, check if a recipe exists. SUI uses composition:
   Kanban (flex-nowrap + scroll-x + card), Master-Detail (table-interactive + panel),
   Notification Panel (panel + card + badge), Floating Action Bar (card-shadow + btn + fixed),
   Inline Edit (input + btn-sm), Settings (toggle + input + segmented), Action Sheet (sheet + btn-ghost),
   Push Mode (CSS grid toggle), Split Pane (CSS grid + card), and more.
   Common names: Sidebar = sui-sidenav, Modal = sui-dialog, Drawer = sui-panel/sui-sheet,
   Toast = SUI.toast, Wizard = sui-stepper, Activity feed = sui-timeline,
   Search highlight = sui-mark, Tag = sui-chip, Empty state = sui-empty, File upload = sui-dropzone.
   Full recipe list: https://raw.githubusercontent.com/adrianspeyer/speyer-ui/main/.claude/instructions.md
8. Skip link: add <a href="#main" class="sui-visually-hidden">Skip to main content</a> as first child of <body>. Add id="main" to <main>.
9. If a component isn't covered by SUI, mention it — contributions welcome.
10. Reference: https://github.com/adrianspeyer/speyer-ui

Recipes

SUI ships components. You build patterns. These recipes show common application layouts composed from SUI primitives — with minimal custom CSS clearly documented. Copy the code, adjust to your needs.

Action Sheet

Mobile action menu. Composes from: sui-sheet, sui-btn, sui-btn-ghost, sui-divider. Custom CSS: ~15 lines. Inherits sheet's focus trap, Escape, and backdrop.

Action sheet preview

Mobile App Shell

Complete multi-screen mobile app skeleton with tab navigation. Composes from: sui-screen, sui-screen-header, sui-screen-body, sui-screen-footer, sui-segmented. Custom CSS: 0 lines.

MP
MatchPoint
AI Summit 2026
EV
Elena Vasquez
VP SalesAcme Corp
92%
MJ
Marcus Johnson
CTOGlobex
87%
LW
Lin Wei
DirectorInitech
74%

App Shell Scaffold

Canonical responsive layout combining sui-topbar + sui-sidenav + scrollable main content. Uses app-* classes (not sui-). Composes from existing SUI components. Custom CSS: ~15 lines.

Note: sui-layout, sui-main, and sui-layout-body do not exist in SUI. This recipe provides the documented alternative.

My App

Dashboard

Revenue
$84K
Users
2,847
Tickets
12

Blog Post / Article

Full article layout with metadata, prose content, and find-in-page highlighting. Composes from: sui-prose, sui-meta, sui-mark, sui-avatar. Custom CSS: 0 lines.

AS
Adrian Speyer
Feb 16, 2026 842 words 4 min read
Strategy Leadership

Why Connection Wins When AI Automates Everything Else

In a world where AI can write your emails, generate your reports, and schedule your meetings, what's left that only humans can do? The answer is deceptively simple: build relationships.

The companies that thrive in the next decade won't be the ones with the best algorithms — they'll be the ones with the deepest relationships.

Consider the data: customer retention increases 23% with community investment. NPS scores correlate with depth of connection, not frequency. Enterprise deals close 40% faster when internal champions exist.

Button Group

Single-select option picker. Composes from: sui-grid, sui-btn. Custom CSS: ~10 lines. ARIA radiogroup pattern is the key value here.

Select your plan

Chart.js Integration

SUI-native charts using Chart.js. Token-based colours for light/dark mode, SUI font family, responsive by default. This is an integration recipe — Chart.js is not part of SUI. You bring the library; SUI makes it match.

Live demo — toggle the theme to see dark mode. Charts re-render with SUI token colours.

What this recipe provides: a helper function that reads SUI tokens at runtime and applies them to Chart.js defaults (colours, font, grid lines). Theme-reactive via MutationObserver. What you bring: Chart.js from CDN, your chart configurations.

Integration recipes document how to make third-party widgets SUI-native. SUI provides the token overrides; you bring the library. Chart.js is not bundled, versioned, or maintained as part of SUI. Chart.js is canvas-based — no CSS overrides needed, just token values passed to the JS config.

Command Palette

Ctrl+K dialog with search input and results. Composes from: sui-dialog, sui-input, sui-kbd. Custom CSS: ~10 lines. BYOJS: you provide search logic.

  • New Contact N
  • Search Deals S
  • Settings ,
  • Toggle Theme T

Confirmation Dialog

Accessible destructive-action confirmation using role="alertdialog". Composes from: sui-dialog, sui-btn-danger. Custom CSS: 0 lines.

Delete your account?

This action is permanent. All your data will be removed and cannot be recovered.

Document Library

Searchable file list with toolbar, metadata, and status indicators. Composes from: sui-toolbar, sui-meta, sui-badge, sui-card, sui-input. Custom CSS: ~3 lines.

Q4 Strategy Deck.md
12,340 words Updated 2h ago Adrian
Published
The Human Advantage — Chapter 3.md
4,821 words Updated yesterday Adrian
Draft
COMPONENT-ROADMAP.md
2,100 words Updated 3 days ago Claude
RFC

FilePond Integration

SUI-native file uploads using FilePond. Token-based overrides for light/dark mode, complements sui-dropzone with real upload behaviour. This is an integration recipe — FilePond is not part of SUI. You bring the library; SUI makes it match.

Live demo — drop files or click to browse. Files are not actually uploaded (demo only).

What this recipe provides: token-based colour overrides (light + dark), SUI border-radius, font family, focus ring, and status colours using SUI semantic tokens. Complements sui-dropzone — use dropzone for CSS-only styling, FilePond when you need real upload behaviour. What you bring: FilePond CSS + JS from CDN, your upload endpoint configuration.

Integration recipes document how to make third-party widgets SUI-native. SUI provides the token overrides; you bring the library. FilePond is not bundled, versioned, or maintained as part of SUI. Tested with FilePond v4.32.11.

Flatpickr Integration v2.5.1

SUI-native datepicker using Flatpickr. Token-based overrides for light/dark mode, accessible keyboard nav, zero custom CSS needed. This is an integration recipe — Flatpickr is not part of SUI. You bring the library; SUI makes it match.

Live demo — toggle the theme to see dark mode. Try keyboard navigation (arrow keys, Escape).

What this recipe provides: token-based colour overrides (light + dark), consistent border-radius, SUI font family, focus-visible ring (keyboard nav), shadow depth, z-index stacking. What you bring: Flatpickr CSS + JS from CDN, your init configuration. Use appendTo: document.body if the calendar is inside an overflow: hidden container.

Integration recipes document how to make third-party widgets SUI-native. SUI provides the token overrides; you bring the library. Flatpickr is not bundled, versioned, or maintained as part of SUI. Tested with Flatpickr v4.6.13.

Floating Action Bar

A fixed-position bar that appears when items are selected, showing bulk actions. Composes from: sui-card-shadow, sui-btn, sui-badge, position: fixed. Custom CSS: ~8 lines.

Select items to see the floating bar appear.

Inline Edit

Click-to-edit fields with save/cancel actions. Composes from: sui-input, sui-btn-sm, sui-flex. Custom CSS: ~4 lines.

Display mode
Company
Acme Corporation
Revenue
$120,000
Edit mode

Inline Selection Bar

Selection count + action buttons above content. Not to be confused with the Floating Action Bar (FAB) which is a fixed-position toolbar. Composes from: sui-btn, sui-flex. Custom CSS: ~6 lines.

3 selected
SelectNameStatus
Acme Corp Active
Globex Active
Initech Pending
Umbrella Inactive

Kanban Board

Horizontal scrolling columns with stacked cards. Composes from: sui-flex-nowrap, sui-scroll-x, sui-card-interactive, sui-badge. Custom CSS: ~6 lines.

To Do 3
Update API docs
DKBackend
Design review
SCDesign
Fix login bug
ARBug
In Progress 2
Dashboard redesign
JLFrontend
Email templates
ASMarketing
Review 1
Pricing page copy
RWCopy
Done 2
Onboarding flow
MLShipped
Accessibility audit
ASShipped

Master-Detail (Table + Panel)

CRM / help desk pattern — clickable table row opens sui-panel with detail content. Composes sui-table-interactive + sui-panel.

Click a row to see detail
NameCompanyDeal
Elena VasquezAcme Corp$120K
Marcus JohnsonGlobex$85K
Lin WeiInitech$45K

Notification Centre (Panel + Cards)

Bell icon triggers a panel with a scrollable list of notification cards. Composes sui-panel + sui-card + sui-badge.

Bell with badge count — click to reveal notifications
My App

Main application content. Click the bell icon to open the notification panel.

Notifications
Alice B. commented on your task
2 min ago
Tom K. assigned you a ticket
15 min ago
Sara R. approved your request
1 hour ago

Panel Polish

Canonical patterns for sui-panel internals: header with title + close, sticky footer, sizing, and a CRM-style detail drawer variant. Custom CSS: ~10 lines.

Standard panel layout

Edit Contact

Detail drawer (CRM pattern)
JC
Jane Cooper
VP Sales, Acme Corp
Contact info

jane@acme.com

+1 (555) 123-4567


Recent activity
Opened proposal — 2h ago
Email sent — Yesterday
Panel Polish: Record Detail (Tabs + Table + Sticky Actions)
AC
Acme Corp
Enterprise — $240K ARR
Active
OwnerJC Jane Cooper
Stage Negotiation
Deal Value$240,000
Close DateMar 15, 2026
Probability
75%
Next StepSend SOW
TagsEnterprise Renewal
Jane Cooper sent proposal
Today at 2:15 PM
Marcus Lee scheduled a meeting
Yesterday at 10:30 AM
Jane Cooper updated deal value from $180K to $240K
Feb 18, 2026
System created account
Feb 10, 2026
Jane Cooper Feb 20, 2026

Client wants multi-year pricing. Will send SOW with 3-year option and 15% discount. CFO approval needed on their side before signature.

Marcus Lee Feb 14, 2026

Discovery call went well. They’re migrating from Competitor X. Main concerns: data migration timeline and API compatibility.

Panel Push Mode (Content Resize)

Instead of overlaying, the panel resizes main content. Toggle a CSS class on a wrapper to switch grid-template-columns. Custom CSS: ~8 lines.

Push mode — click toggle to slide panel in
Main Content

This area resizes when the panel opens. Content reflows instead of being covered by an overlay.

Popover

Interactive content region: more than a tooltip, less than a dialog. Light (dropdown-style, click-outside dismissal) and heavy (focus-trap, explicit close) patterns. Custom CSS: ~12 lines.

Light popover
Heavy popover (focus-trapped)

Profile Page

User profile with avatar, metadata, stats, and activity feed. Composes from: sui-avatar-xl, sui-meta, sui-timeline, sui-badge, sui-card. Custom CSS: ~3 lines.

AS
Adrian Speyer
VP Marketing & Technology
Montreal, QC 25+ years experience Joined 2023
SaaS Community AI Events

142
Connections
38
Events
4.9
Rating

Recent Activity

AS
Attended AI Summit 2026
2 days agoMontreal
AS
Published "Why Connection Wins"
1 week ago842 words
EV
Connected with Elena Vasquez
2 weeks agovia SpeedMatch

Quill Integration

SUI-native rich text editing using Quill (Snow theme). Token-based overrides for light/dark mode, focus ring, SUI font family. This is an integration recipe — Quill is not part of SUI. You bring the library; SUI makes it match.

Live demo — toggle the theme to see dark mode. Full toolbar with formatting options.

Start typing here — this is a Quill rich text editor styled with SUI tokens.

What this recipe provides: token-based overrides for toolbar, editor surface, picker dropdowns, active states, and focus ring. Both themes. What you bring: Quill CSS + JS from CDN, your editor configuration.

Integration recipes document how to make third-party widgets SUI-native. SUI provides the token overrides; you bring the library. Quill is not bundled, versioned, or maintained as part of SUI. Tested with Quill v2.0.3. Note: Quill is chosen for CDN-first / zero-build compatibility. If you are in a bundler or React ecosystem, TipTap or Lexical are stronger choices.

Settings / Preferences

Vertical stack of labelled sections with controls. Composes from: sui-card, sui-toggle, sui-segmented, sui-input, sui-divider. Custom CSS: ~4 lines.

Notifications

Email notifications
Receive updates about your account activity.
Marketing emails
Product announcements and feature updates.

Appearance

Theme
Choose your preferred colour scheme.
Language
Select your display language.

Sidenav Context Switching

Auto-collapse inactive groups when switching context. Composes SUI.sidenav.collapseAll() with app routing logic.

Live demo: This page uses this pattern. Click between the Components and Recipes tabs — the sidenav automatically collapses the inactive group and expands the one matching the current tab.

Split Pane / Master-Detail

Two-column list + detail layout. Collapses to stacked on mobile. Composes from: CSS grid, sui-card, sui-avatar, sui-badge. Custom CSS: ~8 lines per variant.

40/60 — CRM reading pane
EV
Elena Vasquez
Acme Corp · $120K
MJ
Marcus Johnson
Globex · $85K
LW
Lin Wei
Initech · $45K
EV
Elena Vasquez
VP Sales · Acme Corp
Closed Won $120,000

Enterprise licence renewal. Multi-year contract signed Q4. Expansion opportunity for Analytics add-on.

Stepper / Wizard

Promoted to component. The stepper pattern has been promoted from recipe to a first-class component in v2.2.0. See sui-stepper in the Components tab above.

Tom Select Integration

SUI-native enhanced selects using Tom Select. Token-based overrides for light/dark mode, tagging, autocomplete. This is an integration recipe — Tom Select is not part of SUI. You bring the library; SUI makes it match.

Live demo — toggle the theme to see dark mode. Try keyboard navigation and typing to filter.

What this recipe provides: token-based overrides for the control, dropdown, tags, active/hover states, option group headers, and focus ring. Both themes. What you bring: Tom Select CSS + JS from CDN, your select configuration.

Integration recipes document how to make third-party widgets SUI-native. SUI provides the token overrides; you bring the library. Tom Select is not bundled, versioned, or maintained as part of SUI. Tested with Tom Select v2.5.1.
Confirm Action

This is a native <dialog> modal. The browser handles focus trapping, scroll lock, Escape key, and backdrop — no custom JavaScript needed for accessibility.

Wide Dialog

Add sui-dialog-wide to a native <dialog class="sui-dialog"> for a 720px-wide surface — useful for record detail, side-by-side content, or wider forms. The legacy overlay pattern has an equivalent sui-modal-wide modifier.