The Problem
Every new externally-facing project required the same design tokens, component atoms, and aesthetic decisions to be re-implemented from scratch or manually copied from motivka. This caused drift between projects over time and meant design changes had to be applied in multiple places. There was no single source of truth that agents and developers could reference when building new interfaces.
I noticed this most acutely when thinking about the encyclopedia-brown and vibration projects. Both would need the same colour palette, typography scale, and basic components. Copying from motivka would create three diverging copies within months.
What I Built
Motif is a standalone design library at ~/Code/motif, published as @motif/design. It extracts the canonical design tokens and atomic components from motivka into a reusable package that any SvelteKit project can install.
Phase 0: Repository foundation. I initialised the repo with Bun, configured Vite in library mode with vite-plugin-dts for TypeScript declarations, set up Tailwind CSS 4 as a utility layer (tokens handle colours and spacing, not Tailwind), and configured Storybook 10 with Svelte CSF. The package.json exports three CSS entry points and two component entry points.
Phase 1: CSS tokens. I extracted all CSS custom properties from motivka's app.css into three separate files. public.css contains the full OKLCH colour palette, typography, spacing, shadows, animations, gradients, and grid pattern tokens. admin.css contains all --admin-* tokens pinned to dark palette values. base.css contains global styles like the typography scale, body defaults, scrollbar styling, focus states, and utility classes. All colour tokens use OKLCH format for perceptual uniformity, with intentional exceptions for --*-rgb tuple tokens and --hex-* SVG tokens.
Phase 2: Svelte 5 atoms. I ported 12 components from motivka: Button, Input, Select, Textarea, Label, Toggle, TagPill, Tooltip, Portrait (public atoms) and StatusBadge, BulkActionModal, DeleteConfirmModal (admin atoms). Each component follows the four-block structure (module script, instance script, markup, style) with Svelte 5 runes only. I created a shared form-states.css with a .motif-form-control class for consistent focus ring and validation styling across all form atoms. Variable fonts replaced 13 individual weight file imports, reducing font imports from 13 to 7.
Phase 3: Storybook catalogue. I ported all token visualisation stories (Colours, Typography, Spacing, Shadows) and wrote component stories for every public and admin atom. The Storybook catalogue serves as both visual documentation and a proof that the components render correctly outside of motivka.
Phase 4: Motivka migration. This was the most delicate phase. I replaced motivka's inline token definitions in app.css with three imports from @motif/design (public, admin, base), maintaining a documented import order dependency. I replaced all direct atom imports throughout the codebase with imports from @motif/design, keeping a deprecated compatibility shim at $lib/ui/atoms/index.ts. The admin design system gallery was updated to show import paths from @motif/design rather than local file paths.
Phase 5: Global design-system skill. I created a comprehensive global Claude skill at ~/.claude/skills/design-system/ covering the full design language: brand identity, layout philosophy, widget and component patterns, and multi-medium guidance. The skill reads ~/Code/motif/src/ directly for Svelte-specific token and component details, ensuring it never goes stale. Motivka's old project-level design-system skill was deleted entirely.
Key Decisions
- Standalone repo -- not co-located inside motivka. Enables any project outside the monorepo to reference and install it.
- Motivka becomes a consumer -- eliminates the duplicated source of truth. Motivka is the first proof-of-concept and validates the library API.
- Atoms only, no composites -- section-level and form composites are too motivka-specific to generalise safely.
- CSS custom properties, not JS objects -- framework-agnostic, readable directly by agents, works in any consumer.
- Three CSS entry points -- prevents admin tokens polluting public pages and vice versa.
- Local path for dev, git URL for CI -- avoids npm registry overhead.
github:knedliky/motifwithbun.lockcommit hash for reproducibility. - Alfons is Motif -- the planned
alfons/project was always the same concept under a different name. No separate Alfons project will be built. - Global skill reads source directly -- static token summaries go stale. Reading
~/Code/motif/src/is always accurate.
What is Next
The motif dependency strategy has been resolved: github:knedliky/motif in package.json with bun link for local dev hot reload. The Docker integration tasks (dev volume mount and production build) are queued. The design system cleanup phase was the immediate follow-up to fix inconsistencies surfaced during the motif migration.