Save the Dogs Design System
A living reference for the Save the Dogs skin — the design tokens and the shared UI primitives built on them. Flip the theme in the top bar to preview light and dark.
Save the Dogs is a teal / beryl skin set in Mulish for body and Fraunces for display. It is dark by default: every color is a CSS variable, and the theme is decided entirely in globals.css — :root holds the light values and .dark overrides them for the (default) dark skin.
- Token layers
- Raw palette ramps (--p-beryl-*, --p-neutral-*) feed semantic tokens (--color-accent, --color-surface, --color-text…) which feed the Tailwind utilities.
- Theme-aware
- Components read semantic tokens only, so flipping :root ↔ .dark re-skins the entire library with no per-component edits.
- Primitives
- The shared components live in src/components/ui (barrel: @/components/ui). Every section below exercises them across their variants.
Sections
Beryl + neutral ramps and the theme-aware semantic palette.
The Mulish body / Fraunces display type scale.
The structural tokens: radius scale, shadows, focus ring, motion.
Governance for the lucide-react icon system: sizes, stroke, the decorative-vs-meaningful a11y rule, semantic naming + a catalog.
The composable Surface primitive + the full surface taxonomy registry (11 categories).
Every basic primitive on one page — one anchor per component, live demo + source path. The issue-scoping surface.
Variants, sizes, loading & disabled states, icons.
Modal, Drawer, Popover, Tooltip, Menu, ConfirmDialog, Toaster, Tabs, Accordion.
The rule for picking a transient/floating surface: tooltip vs popover vs menu vs confirm vs modal vs drawer vs floating panel — a decision tree + use-which-when table.
Badges, status pills, notification counts and icon chips.
Field, Input, Select, Textarea, Label and Toggle.
Combobox, Checkbox/Radio groups, Switch, Slider, NumberInput, SearchInput, Select, DatePicker & FileUpload.
Avatar, AvatarGroup (overflow +N) and the STD PersonCard.
The STD RichTextEditor (Tiptap): formatting toolbar + markdown/HTML output.
The STD events kit: event cards & lists, type/status/recurrence chips + viewer-tz date formatters, RSVP & attendance, the two-column detail layout + calendar/share actions, the event-form building blocks and the door check-in kiosk.
TitleBar, a11y Breadcrumbs and a dirty-state SaveBar (+ the useUnsavedChanges guard) for record edit pages.
DateTimePicker, DateTimeRangePicker and the SchedulerStrip — date + time entry over DatePicker + TimeInput.
TreeView (WAI-ARIA hierarchy, keyboard nav) and a composed FileBrowser over the @phauna/ds Tree.
A draggable, resizable SplitView and the static multi-region PaneLayout skeleton.
TeachingPopover coachmarks, a sequenced Tour and the SetupGuide checklist.
The “explain this page” family: a collapsible ExplainerPanel (Callout + DescriptionList + Steps) and its AuthExplainer auth-ceremony variant.
EntityPicker (typed multi-select tokens) and a free-entry TagPicker.
Whole-page templates — ResourceIndexPage, ResourceDetailPage, ResourceEditPage and SettingsPage — composing the TablePage/RecordPage recipes with the workflow TitleBar/SaveBar.
The resource lifecycle pages: ResourceIndexPage (list), ResourceDetailPage (read), ResourceEditPage (create/update) and the delete-confirm flow.
Overview pages: DashboardPage — a summary band over a widget grid and stacked sections, composing the DashboardLayout.
Multi-pane shells: TabbedPage, SplitViewPage (master/detail) and SideTabPage (vertical tab rail + optional inspector).
Collection-heavy templates: tables, faceted filters, boards and card grids composed into whole-page recipes.
Multi-step flows: the WizardSheet stepped sheet plus the dirty-aware edit/settings shells armed with the route-leave guard.
Messaging + assistant surfaces: conversation panes, the AI assistant panel and notification/activity feeds as page templates.
Whole-screen lifecycle states: AuthPage (login / step-up / invite / setup) plus the splash, lock, maintenance and error screens.
Transient page companions: OverlaySurface, InspectorDrawer, WizardSheet and LauncherMenu — responsive dialogs/sheets a page opens by hand.
Account & admin templates: BillingPage, IntegrationsPage, PermissionsPage and TeamManagementPage — the settings surfaces an org administrator lives in.
Authoring templates: RichEditorPage — a rich-text authoring surface with a metadata / outline aside, over the DocumentLayout.
On-the-go templates: ScanPage (camera/barcode), OfflineSyncPage (queue + connectivity) and QuickCapturePage (a focused capture form) — the field-work surfaces.
Card padding/accent variants, ActionCard and lockable tools.
Alerts, empty / error states and loading skeletons.
CompactCard, ListRow, CompactListItem and lockable rows.
Region surfaces composed from Surface: Panel, Well, Tile, Sheet and GroupBox.
Bars and rails that move you around: Toolbar, CommandBar, NavigationRail and BottomBar.
Docked + floating panels: Inspector, Properties, History, Activity, Settings, AI assistant, Flyout, HoverCard and FloatingPanel.
Multi-item layouts: Kanban board, Masonry, Gallery, Feed and Timeline.
Transient surfaces summoned on demand: BottomSheet, ActionSheet, FabMenu and PeekPreview.
The @phauna/ds/command surfaces: CommandPalette (⌘K), GlobalSearch and NotificationCenter.
Whole-screen lifecycle states: Splash, Lock, Permission, Maintenance, Auth and Error.
The @phauna/ds document module: a pdf.js DocumentViewer (page nav, zoom, search) and PdfThumbnail — mounted SSR-safe via next/dynamic({ ssr: false }) with a self-hosted worker.
PageHeader, PageTabs, ProgressSteps and SectionHeader.
Tabular layouts, stats and data-density patterns.
DataGrid: sortable columns, selection, sticky header, density, CSV export, virtualization.
The grants-style FilterBar + SavedViewBar + filterRows → DataGrid, with URL state.
StatTile, Sparkline, Gauge / Meter / ProgressRing / StatusMeter, TrendDelta and the Line / Area / Bar / Donut charts.
DatePicker / DateRangePicker / RelativeTime, the DateInput type + fmt helpers, and the app's month calendar (EventsCalendar). Week/agenda views are future work.
STD maplibre wrappers: MapView, markers, territory/district polygons, member clusters, location & district chips.
The page container, sidebars and overall app frame.