Wisteria Craft Design Language¶
The unified visual language for the Loryth platform across three surfaces: the cross-platform app (React web + React Native), the marketing website, and the documentation site (MkDocs Material).
Philosophy¶
Craft over convenience. Wisteria Craft embraces the ethos of self-hosting: deliberate choices, artisanal attention to detail, and pride in building something that's truly yours. The palette draws from natural dye traditions — deep wisteria purples that feel hand-mixed, warm amber tones that evoke beeswax and candlelight. Typography balances character (serif headings) with clarity (humanist sans body text). The system feels handcrafted without sacrificing professionalism.
Color Palette¶
Primary: Wisteria Purple¶
A rich, Tailwind-standard purple scale used as the primary brand color across all surfaces.
| Token | Hex | Usage |
|---|---|---|
purple-50 | #f5f3ff | Subtle backgrounds, hover tints |
purple-100 | #ede9fe | Light highlights, selected states |
purple-200 | #ddd6fe | Soft accents, borders (light mode) |
purple-300 | #c4b5fd | Muted interactive states |
purple-400 | #a78bfa | Dark mode primary (links, buttons, active states) |
purple-500 | #8b5cf6 | Brand color reference point |
purple-600 | #7c3aed | Light mode primary (links, buttons, active states) |
purple-700 | #6d28d9 | Hover states (light mode) |
purple-800 | #5b21b6 | Active/pressed states, dark mode surfaces |
purple-900 | #4c1d95 | Deep accents, dark mode borders |
purple-950 | #2e1065 | Darkest shade |
Secondary: Artisan Amber¶
Warm gold/amber for accents, calls-to-action, and warmth. Think aged brass, honey, handmade candles.
| Token | Hex | Usage |
|---|---|---|
amber-50 | #fffbeb | Subtle warm backgrounds |
amber-100 | #fef3c7 | Inline code backgrounds (light mode) |
amber-200 | #fde68a | Highlights |
amber-300 | #fcd34d | Accent borders |
amber-400 | #fbbf24 | Dark mode secondary (CTAs, highlights) |
amber-500 | #f59e0b | Light mode secondary (CTAs, highlights) |
amber-600 | #d97706 | Hover states |
amber-700 | #b45309 | Active/pressed states |
amber-800 | #92400e | Deep accents |
amber-900 | #78350f | Dark tones |
amber-950 | #451a03 | Inline code backgrounds (dark mode) |
Semantic Colors¶
Desaturated to avoid competing with the brand palette.
| Semantic | Light Mode | Dark Mode | Usage |
|---|---|---|---|
| Success | #22c55e (green-500) | #86efac (green-300) | Confirmations, completed states |
| Warning | #f59e0b (amber-500) | #fcd34d (amber-300) | Caution, in-progress states |
| Error | #ef4444 (red-500) | #fca5a5 (red-300) | Errors, destructive actions |
| Info | #3b82f6 (blue-500) | #93c5fd (blue-300) | Informational highlights |
Neutrals: Slate¶
Cool-toned neutrals for backgrounds, text, and structural elements.
| Token | Hex | Role |
|---|---|---|
slate-50 | #f8fafc | Light mode background |
slate-100 | #f1f5f9 | Light mode secondary surface |
slate-200 | #e2e8f0 | Borders (light mode) |
slate-300 | #cbd5e1 | Strong borders (light mode) |
slate-400 | #94a3b8 | Disabled text, placeholders |
slate-500 | #64748b | Tertiary text (dark mode) |
slate-600 | #475569 | Secondary text (light mode), disabled (dark mode) |
slate-700 | #334155 | Borders (dark mode) |
slate-800 | #1e293b | Secondary surface (dark mode) |
slate-900 | #0f172a | Dark mode background |
slate-950 | #020617 | Deepest dark |
Surface Tokens¶
Light Mode¶
| Token | Value | Usage |
|---|---|---|
bg-primary | #ffffff | Main canvas |
bg-secondary | slate-50 | Cards, panels |
bg-tertiary | slate-100 | Hover states, input backgrounds |
fg-primary | slate-900 | Body text |
fg-secondary | slate-600 | Secondary text |
fg-tertiary | slate-400 | Placeholders, disabled |
border-subtle | slate-200 | Dividers |
border-strong | slate-300 | Emphasis borders |
accent-primary | purple-600 | Interactive elements |
accent-secondary | amber-500 | CTAs, highlights |
Dark Mode¶
| Token | Value | Usage |
|---|---|---|
bg-primary | slate-900 | Main canvas |
bg-secondary | slate-800 | Cards, panels |
bg-tertiary | slate-700 | Hover states, input backgrounds |
fg-primary | slate-100 | Body text |
fg-secondary | slate-300 | Secondary text |
fg-tertiary | slate-500 | Placeholders, disabled |
border-subtle | slate-700 | Dividers |
border-strong | slate-600 | Emphasis borders |
accent-primary | purple-400 | Interactive elements |
accent-secondary | amber-400 | CTAs, highlights |
Typography¶
Font Families¶
| Role | Font | Fallback Stack | Rationale |
|---|---|---|---|
| Headings | Fraunces (variable) | Georgia, serif | Warm, slightly organic serif with soft curves. Communicates craft and care without pretension. Variable axes: wght 300-900, opsz 9-144. |
| Body | Inter (variable) | system-ui, -apple-system, sans-serif | Clean, humanist sans-serif optimized for screens. Familiar, highly readable. Variable axes: wght 300-700. |
| Code | JetBrains Mono | "Fira Code", Consolas, monospace | Excellent code readability with ligature support. Slightly rounded terminals for warmth. |
Type Scale¶
Based on a major third ratio (1.250). All values in rem (1rem = 16px).
| Token | Size | Typical Usage |
|---|---|---|
xs | 0.75rem (12px) | Fine print, captions, metadata |
sm | 0.875rem (14px) | Labels, secondary text, code blocks |
base | 1rem (16px) | Body text |
lg | 1.125rem (18px) | Lead paragraphs, emphasis |
xl | 1.25rem (20px) | h5, subheadings |
2xl | 1.5rem (24px) | h4 |
3xl | 1.875rem (30px) | h3 |
4xl | 2.25rem (36px) | h2, page headings |
5xl | 3rem (48px) | h1, marketing section headings |
6xl | 3.75rem (60px) | Marketing hero (desktop) |
7xl | 4.5rem (72px) | Marketing hero (large desktop) |
Font Weights¶
| Token | Value | Usage |
|---|---|---|
regular | 400 | Body text, descriptions |
medium | 500 | Emphasis, button labels, UI text |
semibold | 600 | Headings (Fraunces), strong emphasis |
bold | 700 | Major headings, strong emphasis |
Line Heights¶
| Token | Value | Usage |
|---|---|---|
tight | 1.25 | Large headings (4xl-7xl) |
snug | 1.375 | Small headings (xl-3xl), subheadings |
normal | 1.5 | Body text |
relaxed | 1.625 | Long-form content, documentation body |
loose | 2 | Code blocks, spacious layouts |
Spacing¶
Base unit: 4px (0.25rem). All spacing values are multiples of 4px.
| Token | Value | Common Usage |
|---|---|---|
0 | 0px | — |
1 | 4px | Tight padding, icon gaps |
2 | 8px | Default gap between related elements |
3 | 12px | Button vertical padding, comfortable spacing |
4 | 16px | Base rhythm — paragraph margins, card padding |
5 | 20px | — |
6 | 24px | Section spacing, card padding (generous) |
8 | 32px | Large component gaps |
10 | 40px | — |
12 | 48px | Hero padding |
16 | 64px | Major layout sections |
20 | 80px | Generous whitespace |
24 | 96px | Marketing hero spacing |
32 | 128px | Marketing page sections |
Component Spacing Defaults¶
| Component | Padding |
|---|---|
| Button | spacing-3 vertical, spacing-4 horizontal |
| Card | spacing-6 (24px) |
| Form input | spacing-2 vertical, spacing-3 horizontal |
| Page margins | spacing-4 to spacing-8 (responsive) |
| Stack gap (vertical rhythm) | spacing-4 (16px) |
Border Radii¶
Soft and organic, but not overly rounded. No hard edges.
| Token | Value | Usage |
|---|---|---|
none | 0px | — |
sm | 4px | Tags, badges, pills |
md | 8px | Default — buttons, inputs, cards |
lg | 12px | Modals, panels, large cards |
xl | 16px | Hero cards, feature blocks |
2xl | 24px | Marketing sections, image containers |
full | 9999px | Avatars, icon buttons |
Shadows¶
Soft, warm shadows. Elevation conveys depth without harshness.
Light Mode¶
Uses slate-900 (rgba(15, 23, 42, ...)) as shadow color for natural, warm shadows.
| Token | Value |
|---|---|
sm | 0 1px 2px 0 rgba(15, 23, 42, 0.05) |
md | 0 4px 6px -1px rgba(15, 23, 42, 0.08), 0 2px 4px -1px rgba(15, 23, 42, 0.04) |
lg | 0 10px 15px -3px rgba(15, 23, 42, 0.10), 0 4px 6px -2px rgba(15, 23, 42, 0.05) |
xl | 0 20px 25px -5px rgba(15, 23, 42, 0.12), 0 10px 10px -5px rgba(15, 23, 42, 0.04) |
inner | inset 0 2px 4px 0 rgba(15, 23, 42, 0.06) |
Dark Mode¶
Shadows become wisteria-tinted glows for a warm, dimensional feel.
| Token | Value |
|---|---|
sm | 0 1px 2px 0 rgba(139, 92, 246, 0.1) |
md | 0 4px 6px -1px rgba(139, 92, 246, 0.15), 0 2px 4px -1px rgba(0, 0, 0, 0.3) |
lg | 0 10px 15px -3px rgba(139, 92, 246, 0.2), 0 4px 6px -2px rgba(0, 0, 0, 0.4) |
xl | 0 20px 25px -5px rgba(139, 92, 246, 0.25), 0 10px 10px -5px rgba(0, 0, 0, 0.5) |
inner | inset 0 2px 4px 0 rgba(0, 0, 0, 0.3) |
Interactive Glows (Dark Mode)¶
For buttons, focus states, and interactive elements:
| Token | Value |
|---|---|
glow-wisteria | 0 0 0 3px rgba(139, 92, 246, 0.3) |
glow-amber | 0 0 0 3px rgba(245, 158, 11, 0.3) |
Special Touches¶
These signature elements create visual cohesion across all three surfaces.
Grain Texture¶
A barely-visible noise texture applied to large background areas (hero sections, dark mode backgrounds) to add warmth and break up flatness.
- Light mode hero sections:
opacity: 0.03 - Dark mode backgrounds:
opacity: 0.05
Iconography¶
Rounded, friendly, slightly organic stroke icons. Use Lucide as the base icon set with a stroke width of 1.75px for a softer feel. For accent icons on the marketing site, pair amber icons with wisteria text.
Interactive States¶
All clickable elements follow a consistent state progression:
| State | Visual Treatment |
|---|---|
| Rest | accent-primary, shadow-sm |
| Hover | Darken one shade, shadow-md, translateY(-1px) |
| Active | Darken two shades, shadow-inner, translateY(0) |
| Focus | 2px outline at accent-primary with 3px offset |
Transition: 150ms cubic-bezier(0.4, 0, 0.2, 1) (ease-out).
Inline Code Styling¶
Inline code uses amber-tinted backgrounds for a warm, distinctive look:
- Light mode:
background: amber-100(#fef3c7),color: amber-800(#92400e) - Dark mode:
background: amber-950(#451a03),color: amber-200(#fde68a)
Surface: App (React Web + React Native)¶
The app is the primary product surface — functional, calm, and optimized for daily use.
Characteristics¶
| Aspect | Value |
|---|---|
| Default mode | Dark mode preferred |
| Max heading size | 3xl (30px) — no marketing-scale headings |
| Default card padding | spacing-6 (24px) |
| Default border radius | md (8px) |
| Shadows | Mostly sm and md, reserve lg for modals |
| Fraunces usage | Page titles and empty states only; body headings use Inter semibold |
| Amber usage | Destructive actions, alerts, and highlights only |
Navigation¶
- Sidebar:
slate-100(light) /slate-900(dark) background - Active state:
purple-600/purple-400indicator - Icons: Lucide at
1.75pxstroke
Data Display¶
- Tables: zebra striping with
slate-100/slate-200(light) orslate-900/slate-800(dark) - Form inputs:
slate-200(light) /slate-800(dark) background,shadow-inneron focus
Surface: Marketing Website¶
The website needs to inspire, communicate values, and convert visitors.
Characteristics¶
| Aspect | Value |
|---|---|
| Default mode | Light mode preferred |
| Hero heading size | 5xl-7xl (48-72px), Fraunces bold (700) |
| Section heading size | 3xl-4xl, Fraunces semibold (600) |
| Body text size | lg (18px) for readability |
| Section padding | spacing-16 to spacing-24 (64-96px vertical) |
| Card border radius | xl (16px) to 2xl (24px) |
| Shadows | Liberal use of lg and xl |
| Content max-width | 1280px |
CTA Buttons¶
- Primary:
amber-500background withpurple-600text/border - Hover:
amber-600with wisteria glow (dark mode) - The amber CTAs paired with wisteria headings create a distinctive pairing
Hero Section¶
- Grain texture on background (
opacity: 0.05) - Fraunces headings at large sizes
- Generous whitespace above and below
Illustrations¶
Duotone illustrations using purple-600 + amber-400. Hand-drawn aesthetic — artisanal tools, servers in a workshop, cables as vines.
Surface: Documentation (MkDocs Material)¶
Documentation prioritizes readability, scannability, and focus.
Characteristics¶
| Aspect | Value |
|---|---|
| Default mode | Both equally supported |
| Body text size | base (16px) or 1.0625rem (17px) for readability |
| Body line height | relaxed (1.625) |
| Code font size | sm (14px) for inline, base (16px) for blocks |
| Section padding | spacing-6 to spacing-8 |
| Card border radius | sm (4px) for code blocks, md (8px) for admonitions |
| Shadows | Minimal — sm on code blocks and sticky elements only |
Fraunces Usage¶
Only for the site title and major section dividers. All content headings use Inter to maintain focus on readability.
Admonitions¶
| Type | Border Color | Background |
|---|---|---|
| Note / Tip | purple-600 / purple-400 | purple-50 / purple-950 |
| Warning | amber-500 / amber-400 | amber-50 / amber-950 |
| Danger | red-500 / red-400 | red-50 / red-950 |
| Info | blue-500 / blue-400 | blue-50 / blue-950 |
Style: 4px left border with tinted background.
Code Blocks¶
- Background:
slate-900(light mode, dark block) /slate-950(dark mode) - Syntax highlighting with purple and amber accents
- JetBrains Mono at
sm(14px) for inline code,base(16px) for blocks
Sidebar¶
- Active item:
purple-600/purple-400left border (3px) with subtle background tint - Hover: lighter purple background tint
MkDocs Material Theme Configuration¶
theme:
name: material
palette:
- scheme: default
primary: custom
accent: custom
toggle:
icon: material/brightness-7
name: Switch to dark mode
- scheme: slate
primary: custom
accent: custom
toggle:
icon: material/brightness-4
name: Switch to light mode
font:
text: Inter
code: JetBrains Mono
Custom CSS overrides (stylesheets/wisteria-craft.css):
[data-md-color-scheme="default"] {
--md-primary-fg-color: #7c3aed; /* purple-600 */
--md-accent-fg-color: #f59e0b; /* amber-500 */
--md-default-bg-color: #ffffff;
--md-default-fg-color: #0f172a; /* slate-900 */
}
[data-md-color-scheme="slate"] {
--md-primary-fg-color: #a78bfa; /* purple-400 */
--md-accent-fg-color: #fbbf24; /* amber-400 */
--md-default-bg-color: #0f172a; /* slate-900 */
--md-default-fg-color: #f1f5f9; /* slate-100 */
}
h1, h2, h3, h4, h5, h6 {
font-family: "Inter", sans-serif;
font-weight: 600;
}
/* Inline code: amber-tinted */
code {
background-color: #fef3c7; /* amber-100 */
color: #92400e; /* amber-800 */
border-radius: 4px;
padding: 2px 6px;
}
[data-md-color-scheme="slate"] code {
background-color: #451a03; /* amber-950 */
color: #fde68a; /* amber-200 */
}
Diagram Colors¶
For Mermaid diagrams, use the following standardized palette (compatible with dark mode styling):
| Name | Hex | Usage |
|---|---|---|
| Wisteria | #7c3aed | Primary components, current context |
| Amber | #f59e0b | Highlights, active processing |
| Success Green | #22c55e | Completed operations |
| Info Blue | #3b82f6 | Information flow, data |
| Error Red | #ef4444 | Errors, critical states |
| Infrastructure Teal | #0d9488 | Infrastructure components |
| Data Cyan | #06b6d4 | Data storage, persistence |
Dark mode diagram styling:
classDef wisteria fill:none,stroke:#a78bfa,stroke-width:2px,color:#a78bfa
classDef amber fill:none,stroke:#fbbf24,stroke-width:2px,color:#fbbf24
classDef success fill:none,stroke:#86efac,stroke-width:2px,color:#86efac
classDef info fill:none,stroke:#93c5fd,stroke-width:2px,color:#93c5fd
classDef error fill:none,stroke:#fca5a5,stroke-width:2px,color:#fca5a5
Cross-Surface Cohesion Summary¶
What stays consistent across all three surfaces:
- Wisteria purple + artisan amber as the two brand colors
- Fraunces serif for display headings (adapted per surface)
- Inter for body text everywhere
- JetBrains Mono for all code
- 4px base spacing unit with the same scale
- Craft ethos: grain textures, rounded Lucide icons, warm shadows
- Amber inline code styling — a distinctive signature
- Purple-tinted glows in dark mode instead of harsh drop shadows
- Consistent interactive states (hover, active, focus progression)
What varies per surface:
| Element | App | Website | Docs |
|---|---|---|---|
| Spacing | Tight (4-16px) | Generous (16-128px) | Balanced (6-32px) |
| Max heading size | 3xl (30px) | 7xl (72px) | 3xl (30px) |
| Border radius | md (8px) | xl-2xl (16-24px) | sm-md (4-8px) |
| Shadows | Minimal (sm/md) | Bold (lg/xl) | Subtle (sm) |
| Primary CTA color | Purple-600 | Amber-500 | Purple-600 |
| Default mode | Dark | Light | Both equally |
| Fraunces usage | Titles only | All headings | Site title only |
| Grain texture | Dark bg (0.03) | Hero bg (0.05) | Dark bg (0.03) |