
Dust Design System โ Sparkle
Source: Open source ยท [github.com/dust-tt/dust](http://github.com/dust-tt/dust) ยท /sparkle package
UI Stack \- Framework: Next.js (App Router + Pages Router) \- Styling: Tailwind CSS via @dust-tt/sparkle preset \- Component library: Sparkle (internal, open source) \- Dark mode: class-based (darkMode: "class"), every token has a -night variant
Typography \- Sans font: Geist (variable font) \- Mono font: Geist Mono \- Scale: xs 12px โ 9xl 80px, with negative letter-spacing at larger sizes \- Font weights: copy 400 ยท label 500 ยท heading-smโ3xl 550 ยท heading-4xl+ 450 \- Three type styles: copy-, label-, heading- (+ heading-mono-)
Color Philosophy \- Fully custom palette: gray, stone, blue, green, rose, golden, violet, red, orange, lime, emerald, pink \- Every shade has a mirrored -night sibling (light โ dark inversion) \- Semantic aliases: foreground, background, primary, highlight (blue), warning (rose), success (green), info (golden), border, muted, faint, hover, separator, ring \- Brand tokens: hunter-green, electric-blue, red-rose, orange-golden mapped to palette
Spacing & Layout \- Default Tailwind spacing scale \- Sidebar spacing: 0.75rem \- Conversation max-width: 48rem \- Breakpoints: xxs 384px ยท xs 512px ยท sm 640px ยท md 768px ยท lg 1024px ยท xl 1280px ยท 2xl 1536px \- Size scale additions: 100โ400px, 125โ500px, 150โ600px
Border Radius \- Tailwind defaults + 4xl: 2rem
Shadows \- Box shadows use gray-950 base with low opacity \- Scale: sm, DEFAULT, md, lg, xl, 2xl
Transitions \- Named durations: enter 200ms ยท exit 160ms ยท modal-enter 300ms ยท modal-exit 240ms \- Rich easing library: out-quad, out-expo, emphasized (cubic-bezier(0.23,1,0.32,1)), enter, move
:root { / TYPOGRAPHY / --font-family-base: 'Geist', sans-serif; --font-family-mono: 'Geist Mono', monospace; --font-weight-copy: 400; --font-weight-label: 500; --font-weight-heading: 550; --font-weight-heading-large: 450;
/ FONT SIZES / --text-xs: 12px; --leading-xs: 16px; --tracking-xs: normal; --text-sm: 14px; --leading-sm: 20px; --tracking-sm: -0.28px; --text-base: 16px; --leading-base: 24px; --tracking-base: -0.32px; --text-lg: 18px; --leading-lg: 26px; --tracking-lg: -0.36px; --text-xl: 20px; --leading-xl: 28px; --tracking-xl: -0.4px; --text-2xl: 24px; --leading-2xl: 30px; --tracking-2xl: -0.96px; --text-3xl: 32px; --leading-3xl: 36px; --tracking-3xl: -1.28px; --text-4xl: 40px; --leading-4xl: 42px; --tracking-4xl: -2.4px; --text-5xl: 48px; --leading-5xl: 52px; --tracking-5xl: -2.88px;
/ SPACING / --space-xs: 0.25rem; / 4px / --space-sm: 0.5rem; / 8px / --space-md: 1rem; / 16px / --space-lg: 1.5rem; / 24px / --space-xl: 2rem; / 32px / --space-2xl: 3rem; / 48px / --space-sidebar: 0.75rem;
/ COLORS โ Light mode / --color-background: #ffffff; --color-app-background: #FBFAF9; --color-foreground: #111418; --color-foreground-muted: #596170; --color-foreground-faint: #969CA5;
/ Primary (gray scale) / --color-primary: #2A3241; --color-primary-light: #596170; --color-primary-dark: #111418; --color-primary-muted: #7B818D;
/ Highlight (blue) / --color-highlight: #1C91FF; --color-highlight-light: #4BABFF; --color-highlight-dark: #137FE3;
/ Warning (rose) / --color-warning: #E14322; --color-warning-light: #ED756C; --color-warning-dark: #C93913;
/ Success (green) / --color-success: #6AA668; --color-success-light: #91C174; --color-success-dark: #418B5C;
/ Info (golden) / --color-info: #FFAA0D; --color-info-light: #FFBE2C; --color-info-dark: #FE9C1A;
/ Brand / --color-brand: #418B5C; --color-brand-electric-blue: #1C91FF; --color-brand-red-rose: #E14322; --color-brand-golden: #FE9C1A;
/ Borders & UI chrome / --color-border: #EEEEEF; --color-border-dark: #DFE0E2; --color-border-focus: #4BABFF; --color-separator: #EEEEEF; --color-hover: #EEEEEF; --color-muted-background: #F7F7F7; --color-ring: #9FDBFF;
/ BORDER RADIUS / --radius-sm: 0.125rem; / 2px / --radius-md: 0.375rem; / 6px / --radius-lg: 0.5rem; / 8px / --radius-xl: 0.75rem; / 12px / --radius-2xl: 1rem; / 16px / --radius-3xl: 1.5rem; / 24px / --radius-4xl: 2rem; / 32px / --radius-full: 9999px;
/ SHADOWS / --shadow-sm: 0 1px 2px rgba(17,20,24,0.05); --shadow-md: 0 2px 6px rgba(17,20,24,0.10); --shadow-lg: 0 4px 12px rgba(17,20,24,0.12); --shadow-xl: 0 10px 20px rgba(17,20,24,0.12); --shadow-2xl: 0 25px 50px rgba(17,20,24,0.12);
/ TRANSITIONS / --transition-default: all 200ms cubic-bezier(0.215, 0.61, 0.355, 1); --transition-enter: 200ms cubic-bezier(0.215, 0.61, 0.355, 1); --transition-exit: 160ms cubic-bezier(0.25, 0.46, 0.45, 0.94); --transition-modal-enter: 300ms cubic-bezier(0.23, 1, 0.32, 1); --transition-modal-exit: 240ms cubic-bezier(0.455, 0.03, 0.515, 0.955); --transition-emphasized: cubic-bezier(0.23, 1, 0.32, 1);
/ LAYOUT / --max-w-conversation: 48rem; --panel-height: var(--panel-height); }
/ Dark mode overrides / .dark { --color-background: #111418; --color-app-background: #1C222D; --color-foreground: #D3D5D9; --color-foreground-muted: #969CA5; --color-foreground-faint: #596170; --color-primary: #D3D5D9; --color-primary-light: #B2B6BD; --color-primary-dark: #EEEEEF; --color-border: #2A3241; --color-border-dark: #364153; --color-border-focus: #137FE3; --color-hover: #2A3241; --color-muted-background: #111418; --color-ring: #364153; }
Dust / Sparkle โ Design Tokens Reference
Color Tokens
| Token | Light | Dark (night) | Usage |
|---|---|---|---|
| background | #ffffff | #111418 | Page background |
| app-background | #FBFAF9 | #1C222D | App shell background |
| foreground | #111418 | #D3D5D9 | Primary text |
| muted.foreground | #596170 | #969CA5 | Secondary text |
| faint | #969CA5 | #596170 | Placeholder / disabled text |
| primary | #2A3241 | #D3D5D9 | Default UI color |
| primary.dark | #111418 | #EEEEEF | Emphasis |
| highlight | #1C91FF | #1C91FF | Interactive / links |
| highlight.dark | #137FE3 | #4BABFF | Hover state |
| warning | #E14322 | #E14322 | Errors / destructive |
| success | #6AA668 | #6AA668 | Positive states |
| info | #FFAA0D | #FFAA0D | Informational / golden |
| brand | #418B5C | #418B5C | Brand hunter-green |
| border | #EEEEEF | #2A3241 | Default border |
| border.dark | #DFE0E2 | #364153 | Prominent border |
| border.focus | #4BABFF | #137FE3 | Focus ring color |
| hover | #EEEEEF | #2A3241 | Hover background |
| separator | #EEEEEF | #2A3241 | Dividers |
| ring | #9FDBFF | #364153 | Focus ring |
| sidebar.primary | #292524 | #D6D3D1 | Sidebar text |
Palette Reference
| Name | 50 | 200 | 500 | 800 | 950 |
|---|---|---|---|---|---|
| gray | #F7F7F7 | #D3D5D9 | #7B818D | #2A3241 | #111418 |
| stone | #FBFAF9 | #E7E5E4 | #79716B | #292524 | #0C0A09 |
| blue | #E9F7FF | #9FDBFF | #1C91FF | #085092 | #041728 |
| green | #FEFFF0 | #E2F78C | #6AA668 | #105B2B | #04140A |
| rose | #FFF1F7 | #FFC3DF | #E14322 | #8C230D | #220A04 |
| golden | #FFFAE0 | #FFE262 | #FFAA0D | #AF5511 | #331606 |
| violet | #F5F3FF | #DDD6FE | #8B5CF6 | #5B21B6 | #2E1065 |
Typography Tokens
| Class | Size | Line Height | Letter Spacing | Weight |
|---|---|---|---|---|
| copy-xs | 12px | 16px | normal | 400 |
| copy-sm | 14px | 20px | -0.28px | 400 |
| copy-base | 16px | 24px | -0.32px | 400 |
| copy-lg | 18px | 26px | -0.36px | 400 |
| label-xs | 12px | 16px | normal | 500 |
| label-sm | 14px | 20px | -0.28px | 500 |
| label-base | 16px | 24px | -0.32px | 500 |
| heading-sm | 14px | 20px | -0.28px | 550 |
| heading-base | 16px | 24px | -0.32px | 550 |
| heading-xl | 20px | 28px | -0.4px | 550 |
| heading-3xl | 32px | 36px | -1.28px | 550 |
| heading-4xl | 40px | 42px | -2.4px | 450 |
| heading-6xl | 56px | 60px | -3.36px | 450 |
| heading-mono-2xl | 24px | 30px | -0.96px | 400 mono |
Spacing Tokens
| Token | Value | px equiv |
|---|---|---|
| space-1 | 0.25rem | 4px |
| space-2 | 0.5rem | 8px |
| space-3 | 0.75rem | 12px |
| space-4 | 1rem | 16px |
| space-6 | 1.5rem | 24px |
| space-8 | 2rem | 32px |
| space-12 | 3rem | 48px |
| space-16 | 4rem | 64px |
| sidebar-side-spacing | 0.75rem | 12px |
Border Radius
| Token | Value |
|---|---|
| rounded-sm | 2px |
| rounded | 4px |
| rounded-md | 6px |
| rounded-lg | 8px |
| rounded-xl | 12px |
| rounded-2xl | 16px |
| rounded-3xl | 24px |
| rounded-4xl | 32px |
| rounded-full | 9999px |
Shadows
| Token | Value |
|---|---|
| shadow-sm | 0 1px 2px gray-950/5% |
| shadow | 0 2px 6px gray-950/10% |
| shadow-md | 0 4px 12px gray-950/12% |
| shadow-lg | 0 10px 20px gray-950/12% |
| shadow-xl | 0 20px 25px gray-950/12% |
| shadow-2xl | 0 25px 50px gray-950/12% |
Breakpoints
| Name | Width |
|---|---|
| xxs | 384px |
| xs | 512px |
| sm | 640px |
| md | 768px |
| lg | 1024px |
| xl | 1280px |
| 2xl | 1536px |
Implementation Notes โ Dust Design System
Source \- Repository: [github.com/dust-tt/dust](http://github.com/dust-tt/dust) (fully open source, MIT) \- Design system package: /sparkle โ published as @dust-tt/sparkle on npm \- Data provenance: Extracted directly from sparkle/tailwind-preset.js and front/tailwind.config.js โ these are the ground-truth token files, not approximations
UI Framework \- Next.js (both App Router and Pages Router in use across the monorepo) \- Tailwind CSS via a custom preset (@dust-tt/sparkle/tailwind-preset) \- Component system: Sparkle (internal design system, open source) \- Tailwind plugins in use: @tailwindcss/forms, @tailwindcss/container-queries, tailwind-scrollbar-hide, tailwindcss-animate
Theme / Dark Mode \- Dark mode via darkMode: "class" โ a .dark class on or a parent element \- Every semantic color token has a paired -night value baked into the Tailwind config \- The color inversion strategy is explicit: light shade 100 โ dark shade 900, etc. \- No CSS custom property swap at runtime โ Tailwind generates both light and dark utility classes statically
Notable Patterns \- Typography classes are Tailwind components (addComponents), not utilities โ e.g. .heading-3xl, .copy-base, .label-sm \- Custom easing curves named out-expo, emphasized, enter, move โ richer than standard Tailwind \- Negative letter-spacing scales with size: all headings above sm use negative tracking for a premium editorial feel \- Geist font family (Vercel's open source font) used for both sans and mono \- Golden color replaces amber/yellow โ a warm amber with custom 12-stop scale (50โ950) \- Sidebar uses stone palette (warm gray) rather than cool gray, for visual differentiation \- Conversation max-width is hardcoded at 48rem โ a key layout constraint for the chat UI \- Animation conventions: spring-like cubic-bezier (0.34, 1.56, 0.64, 1) for entry animations, standard ease-out for exits \- Container queries are used (@tailwindcss/container-queries) with named sizes from xxs: 24rem to xl: 80rem


.webp)


.webp)













SaaSFrame subscriptions are sold on Lemon Squeezy, a secured online selling platform for creators.
SaaSFrame gets updated all the time! Every new update and version will immediately be made available to all SaaSFrame users.
You can generate an invoice on your Lemon Squeezy portal once you purchased SaaSFrame. You will find the link in the order confirmation email.
You can cancel your membership subscription at any moment on your profile page.โ
If you're not satisfied, you can ask for a refund within 7 days. Just send me an email at antoine[at]unmake[dot]io
You can send me an email at antoine[at]unmake[dot]io, I'll be happy to help with any questions.