@ai-created/ui
Design-system overview

Component specifications

Build from documented contracts.

Every public primitive is documented as a visual system, an interaction contract, and a production implementation. Search the library or browse by responsibility.

22 entries

Actions & feedback

5 documented contracts

Layout & content

2 documented contracts

Fields & selection

7 documented contracts

Overlays

4 documented contracts

Theme & media

2 documented contracts

Utilities & motion

2 documented contracts

Components

These are the shared production patterns exported from @ai-created/ui.

Component Rules

  • -Start with shared primitives: Button, Surface, TextInput, and TextArea carry the interaction contract.
  • -Prefer existing shells before inventing a new card style.
  • -Do not add checklist components for completeness. A new shared component should answer a real product need, not a hypothetical one.
  • -Keep metadata systems compact and mono-driven: status, platform, date, category, read time.
  • -For multi-tool product surfaces, prefer overview cards plus one active workspace instead of stacking every tool vertically.
  • -If an action has nowhere useful to go yet, disable it or replace it with explanatory copy. Do not ship dead-end clicks.
  • -Dense toolbars should use same-height controls and shared alignment before introducing custom flourishes.
  • -Use the accent token for emphasis and state. Use the action token for filled controls with the on-action foreground.
  • -Route-level composition counts as a component decision. Shared shells are part of the system, not implementation trivia.
  • -Interactive components need visible focus, explicit naming, and correct HTML semantics before they are considered done.
  • -If a component only appears on one route, question whether it should be part of the design system at all.

Shared UI Primitives

The reusable building blocks exported from @ai-created/ui.

Button

Handles primary, secondary, ghost, filter, and icon styles with consistent sizing and disabled states.

Surface

Encodes the shared shell language for cards, panels, notices, and accent modules instead of repeating border and background recipes inline.

default
muted
accent
info

When to Add a Component

This system grows by product pressure, not by checklist completeness. New components should be promoted when the pattern is real, repeated, or clearly cross-route.

Component admission rule

  • -First use: solve the product problem with existing primitives and route-level composition.
  • -Second similar use: identify the repeated interaction, content shape, and accessibility contract.
  • -Shared or repeated use: promote it into a canonical component, then document it here and in DESIGN-SYSTEM.md in the same pass.
  • -Patterns learned from shipped product flows belong here once they repeat: capacity states, status-first settings cards, overview-plus-workspace, and honest empty states.
  • -Badges, dropdowns, radio groups, sliders, toggles, dialogs, and tooltips are shared primitives. Tooltip + Badge is the standard composition for interactive status pills.
Promotion checklist

Use the real product need first.

Add the shared primitive or variant.

Ship the full accessibility and state contract.

Document it in the playground and in DESIGN-SYSTEM.md.

Status & Loading

Async feedback uses a shared notice primitive and a small skeleton primitive instead of ad hoc status markup.

Saved changes

A small semantic surface for confirmations and success states.

Sync in progress

Informational updates stay distinct from brand actions and error states.
Use skeletons for content that is genuinely loading. Keep them quiet, structural, and motion-light.

ThemedHeroImage

Shared hero media wrapper. Every route-level hero uses this single primitive. It handles dark/light image swapping, overlay strength, edge fade gradients, and transparent-PNG blending, all backed by design system tokens.

darkSrc / lightSrc
overlay: default | strong | soft | none
fadeTop: gradient from bg to transparent
fadeBottom: gradient from bg to transparent
blendLight: multiply blend for transparent PNGs in light mode
theme-aware image swap + hero text colors

default is the standard overlay for most browse pages.

strong is heavier, used for high-contrast moments.

soft is 20% more transparent than strong, for subtler image presence.

fadeBottom blends the hero edge into the page background.

fadeTop same effect at the top.

blendLight uses mix-blend-multiply on images in light mode so transparent PNGs blend into the warm beige background.

Form Controls

FieldGroup owns one vertical spacing rhythm so text controls, hints, and adjacent Dropdown triggers stay aligned across content and states.

Results update as you type.

Release status

Keep the rationale concise and actionable.

Approval owner for proposed changes requiring security and accessibility review

Browse Controls

Search plus low-friction filters are the preferred pattern when a route needs more than a simple grid.

Type

Tabs

Horizontal tab bar for switching between related views. Uses roving tabindex with arrow-key navigation, Home/End support, and proper ARIA tab pattern.

Overview panel content.
KeyboardArrow Left/Right moves focus and selection. Home/End jump to first/last tab.
ARIArole="tablist", role="tab", aria-selected, aria-controls, roving tabindex

Checkbox

Binary toggle with a visually hidden native input and a styled indicator. Focus-visible outlines appear on the visual box. Labels are always required for accessibility.

FocusNative input is sr-only; focus-visible outline renders on the visual box via peer selector.
StatesUnchecked, checked (action fill), hover (border brightens), disabled (opacity 50%).
SemanticsNative <input type="checkbox"> with <label> linked by generated id.

Dropdown

Single-select dropdown built on Headless UI Listbox. Full keyboard navigation with Arrow Up/Down, Enter/Space to select, Escape to close, and type-ahead search.

Framework
KeyboardArrow Up/Down navigates, Enter/Space selects, Escape closes, type-ahead jumps.
ARIAHeadless UI Listbox provides role, aria-selected, aria-activedescendant automatically.
StatesClosed, open, active option (bg-surface2), selected (check icon), disabled (opacity 50%).

Radio Group

Single-select group using native radio inputs in a fieldset. Arrow keys move selection. Styled indicators follow the checkbox visual pattern with a centered dot.

Category
Horizontal
KeyboardArrow keys move selection within the group. Tab moves focus out of the group.
SemanticsNative <fieldset> with <legend>, native <input type="radio"> with shared name.
StatesUnselected, selected (action fill + on-action dot), hover (border brightens), disabled (opacity 50%).

Slider

Range input with a styled track and thumb. The filled portion uses the accent action color. Includes an output element for the current value with aria-valuetext for screen readers.

65%
$250
50
TrackFilled portion uses the action color, unfilled uses surface2. Border matches input fields.
ThumbRed-solid fill, bg border for contrast. Scales up on hover for better grab target.
ARIAaria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext with formatted display value.

Toggle

On/off switch visually distinct from checkboxes. Uses role='switch' with aria-checked. Sliding track animation with the accent action color for the on state.

Semanticsrole="switch" with aria-checked. Native <button> for keyboard activation.
StatesOff (surface2 track), on (action track + translated knob), hover (border brightens), disabled (opacity 50%).
FocusFocus-visible outline on the track, not a wrapper. 2px outline, 3px offset.

Badge

Pill-shaped semantic label for status indicators, counters, and metadata tags. Six variants map to the semantic color system.

Variants
DefaultMutedSuccessWarningErrorInfo
Status row
completedextractingpartial successfailedqueued
Shaperounded-full with border, px-2 py-0.5, 11px font. Compact enough for inline use.
ColorsMaps to semantic color triplets: border, surface, and text for each variant.
ComposableWrap in Tooltip for hover detail. Override rounded-full with className for square badges.

Dialog

Modal dialog built on Headless UI with automatic focus trap, Escape to close, backdrop click to close, and transition animations. Size variants from sm to xl.

FocusHeadless UI traps focus inside the dialog. Focus restores to the trigger on close.
KeyboardEscape closes, Tab/Shift+Tab cycles focusable elements.
ARIArole="dialog", aria-modal, aria-labelledby from DialogTitle, aria-describedby optional.
Sizessm (max-w-sm), md (max-w-lg), lg (max-w-2xl), xl (max-w-4xl).

Modal composition

The composable Modal family keeps flexible header, body, and footer layouts while owning portal, focus, Escape, backdrop, and restoration behavior.

ConfirmDialog

Use the pre-composed alert dialog when an action needs an explicit confirm or cancel decision.

No action selected.

Semantic feedback

Notice variants communicate system state through text, role, icon, border, surface, and color together.

Draft saved

Neutral progress that does not need urgency.

Import running

We will keep this page updated.

Changes published

The new version is now live.

Review required

Two fields still need attention.

EmptyState

The shared empty-state primitive pairs direct explanation with one useful next action.

No projects yet

Create a project when you are ready to collect sources and notes.

ErrorReport

An actionable error surface with optional progressive disclosure and copyable debug context.

ThemedHeroImage live state

This constrained preview uses the same decorative, theme-aware media primitive as the page hero.

Decorative media

One composition, both themes.

Images stay outside the reading order while overlays preserve readable foreground content.

Tooltip

Contextual hint that appears on hover and focus. Configurable position and delay. Uses role='tooltip' with aria-describedby for screen reader support.

TriggerShows on hover and focus. Configurable delay (default 300ms). Hides on mouse leave and blur.
ARIArole="tooltip" on the popup, aria-describedby on the trigger when visible.
PositionTop, bottom, left, or right. Centered on the trigger axis.

Tooltip + Badge

Badges wrapped in Tooltip create interactive status pills with explanatory hover text. Use cursor-help to signal the tooltip is available. This composition is the standard pattern for audit metadata and status indicators.

Status with detail
completedextractingpartial successfailed
Fit assessment
strong fitpartial fitno evidence
PatternTooltip wraps Badge. Add cursor-help to signal interactivity.
When to useStatus labels, fit assessments, and audit metadata where a one-word label needs supporting context.
OverridesUse className to swap rounded-full for rounded, adjust text size, or change padding for compact rows.

Card Hover System

Cards follow a consistent hover progression: border brightens, text lifts in contrast, and images scale subtly. Use the group selector for coordinated effects.

Defaultborder-border
Hoverborder-border-strong
Featured Hoverborder-accent-muted
Border: border-border → border-border-strong
Text: text-text2 → text-text
Image: group-hover:scale-[1.02] duration-500
Lift: whileHover={{ y: -2 }} (Framer Motion)
Featured: border-accent-border → border-accent-muted

Dividers

Three divider weights for different contexts. Structural for lists, decorative for subtle breaks, accent for emphasis.

Structural
border-t border-border
Decorative
h-px bg-highlight
Accent
h-px w-20 bg-accent

Empty States

When filters or search return nothing, show a direct, non-cute message. Always provide context or a way forward.

No articles found.

Try adjusting your search or clearing filters.

Breadcrumbs

Used on detail pages to show route context. Mono font, slash separators, current page is not linked.

Icon Sizing

Icons follow three size tiers. Small for inline metadata, medium for interactive controls, large for decorative or standalone use.

w-4 h-4inline
w-5 h-5controls
w-8 h-8decorative

Accessibility By Component

  • -Buttons and links must keep visible focus and communicate destination or action clearly.
  • -Buttons ship with default, hover, focus-visible, loading, and disabled states. The design system should show those states, not imply them.
  • -Disabled actions should communicate why they are unavailable when the user needs more context. Do not force navigation into empty destinations.
  • -Cards that act as links should expose one clear accessible name and treat supporting imagery as decorative.
  • -Forms require labels, helper copy when needed, autocomplete where appropriate, and success/error announcements.
  • -Browse controls should use real fieldsets, legends, pressed states, and live feedback when results change.
  • -Workflow tabs and utility actions should not share the same semantic tablist unless they represent the same kind of destination.
  • -Mixed toolbars still need consistent hit targets and alignment. Buttons, dropdowns, and icon actions should share height when they occupy one control row.
  • -Modals must trap focus, restore focus on close, support Escape to dismiss, and use role="dialog" with aria-modal and aria-labelledby.
  • -Tabs use role="tablist" with arrow-key navigation, Home/End support, and roving tabindex. Each tab has role="tab", aria-selected, and aria-controls linking to its panel.
  • -Checkboxes pair a visually hidden native input with a styled indicator. Focus-visible outlines render on the visual box via peer selectors. Labels are always required.
  • -Empty states must communicate clearly to screen readers. Avoid placeholder SVGs without alt text.
  • -Breadcrumbs use nav with aria-label="Breadcrumb" and plain text for the current page.
  • -Dropdowns use Headless UI Listbox with full keyboard navigation (Arrow Up/Down, Enter, Escape, type-ahead). Selected option shows a check icon.
  • -Radio groups use native radio inputs in a fieldset with legend. Arrow keys move selection. Styled indicators mirror the checkbox pattern with a centered dot.
  • -Sliders use native range input with a styled track and thumb. The filled portion uses the accent action color. aria-valuemin, aria-valuemax, aria-valuenow, and aria-valuetext are set.
  • -Toggles use role="switch" with aria-checked. Visually distinct from checkboxes with a sliding track. Focus-visible outline on the track.
  • -Dialogs use Headless UI Dialog with automatic focus trap, Escape to close, backdrop click to close, and transition animations. Close button has an aria-label.
  • -Tooltips appear on hover and focus with a configurable delay. Use role="tooltip" with aria-describedby on the trigger. Positioned top/bottom/left/right.
  • -Badges are inline semantic labels. When wrapped in Tooltip, add cursor-help so users know hover detail is available. The Tooltip provides aria-describedby on the Badge automatically.