DDS — The dani design system
One monochrome foundation. Eighteen product accents. A single rectangular, monospace-data design language that scales across every dani app on every platform.
DDS (dani design system) is the visual language shared by every dani product — from dani.subs to dani.zone, dani.bot to dani.pet. It is deliberately narrow: one typographic scale, one spacing grid, one set of components, one monochrome base. The only thing that changes between products is the accent color — and even that is chosen from a single curated 18-hue palette spanning the color wheel.
This document is the complete specification. It defines the foundations, components, accent system, usage rules, accessibility floors, and per-platform implementations. Anything not documented here should not ship.
01 · Philosophy
DDS draws from four schools — Dieter Rams' functional discipline, the Swiss International Typographic style, Nothing OS's industrial monochrome, and Apple's platform polish. From each we took one thing:
- 01Less, but better.Every element earns its place. No decoration, no gradients, no shadows. Only functional surface, text, and border.
- 02Typography is the interface.Clear hierarchy beats ornament. A grid, a monospace, weight, and whitespace do the work of a hundred icons.
- 03Rectangular, not round.Sharp 4px radii and hairline 1px borders. Circles and pills are out; rectangles are honest about what they are.
- 04Monochrome speaks, accent shouts.Black, white, and one saturated accent. Accent is reserved for action — never decoration.
- 05Hue is identity.Each product gets one hue on the wheel. A user recognizes the app from its accent alone.
02 · Color
The DDS color system has two layers. The monochrome base is shared across every product, dark mode and light mode. The accent is per-product and appears only on action surfaces.
Monochrome base
Nine tokens per mode. Memorize them. Never deviate.
Dark mode is matte black (#000000), not charcoal. This gives DDS its electronic/industrial character — closer to a piece of consumer hardware than a typical software UI. Light mode uses warm off-white (#F7F7F7) with pure-white surfaces stacked on top.
The 18 product accents
Each dani product is assigned a single hue from the color wheel. Every accent ships as a pair — a dark variant tuned for #000 surfaces (brighter, more saturated) and a light variant tuned for #F7F7F7 (deeper, denser). Never cross-use.
| Product | Name | Dark | Light |
|---|---|---|---|
| dani.subs | Alert Red | #FF2D2D | #E80000 |
| dani.news | Scarlet | #FF4518 | #D11500 |
| dani.penny | Copper | #FF6B1A | #C4470A |
| dani.park | Signal Orange | #FF8A00 | #B26500 |
| dani.tos | Amber | #FFB300 | #8F5C00 |
| dani.money | Gold | #FFD400 | #8C7000 |
| dani.snap | Flash Yellow | #E8FF1A | #5C7A00 |
| dani.go | Lime | #8AFF1A | #3D7A00 |
| dani.plant | Green | #3AFF7D | #0A8F3D |
| dani.budget | Mint | #00FFB0 | #008F5E |
| dani.clean | Teal | #00E0C4 | #00806F |
| dani.zone | Electric Cyan | #00F0FF | #008A94 |
| dani.track | Sky | #00B8FF | #0070B2 |
| dani.web | Blue | #3D7AFF | #0047D6 |
| dani.bot | Violet | #8F5CFF | #4B1FBF |
| dani.photo | Purple | #C14DFF | #7A14B5 |
| dani.design | Magenta | #FF4DD4 | #B51495 |
| dani.pet | Pink | #FF4D8F | #C4144F |
All 18 accents are pre-verified for ≥4.5:1 contrastagainst their mode's surface (WCAG AA). White text on an accent button hits the same floor. If you need a new hue, don't invent one — pick the closest existing accent, or propose the addition in a design review.
03 · Typography
Two families. Space Grotesk is the voice of the UI. Space Mono is the voice of data — every number, date, code, label, and timestamp uses mono. This split is the system's signature.
Labels are always uppercase with 0.08–0.12emletter-spacing, weight 700, 8–10px size. This is the "small tag" style that appears throughout — above section headers, inside pills, as hex-code labels, and in the bottom tab bar.
04 · Spacing
DDS is built on a 4px grid. Every padding, margin, gap, and dimension snaps to a multiple of 4. This is non-negotiable.
Screen padding is 16px horizontal. Card internal padding is 18px. Card-to-card gap is 14px. Section gap (between logical groupings on a screen) is 24px.
05 · Radii
DDS is rectangular. Three radii exist. There are no pills and no circles (except the small decorative dot indicators — the system's one exception to its own rule).
06 · Borders & depth
DDS uses borders instead of shadows. Two widths exist: 1px hairline for standard dividers and card boundaries, and 2px strong for emphasis and selected states. No drop shadows. Ever. Depth comes from surface stacking (surface over surface_2) and borders, never from blur.
07 · Motion
Motion is functional, not expressive. Two durations exist: 100ms for instant feedback (button press, tab switch) and 200ms for default state transitions (reveal, dismiss, route change). Easing is always ease-out. Haptic feedback is light.
There are no physics-based animations, no parallax, no particle effects, no easter egg flourishes. If a user can't explain what an animation is for, it shouldn't be there.
08 · Components
Every DDS component is built from the same primitives. A button is a rectangle with a 4px radius, a 1px border, a 14px padding, and uppercase semibold text. A card is a rectangle with a 1px border and 18px padding. The system is combinatorial — there are no special-case components.
Buttons
List items
Data card / totals
Chips & tags
Gauge / progress
Inputs
09 · Usage rules
These are the enforcement rules. Every design and code review applies them.
- · Primary button fill
- · Key numeric values (amounts, counts)
- · Active tab / selected state
- · Alert badges and status pills
- · Tag indicators (small dots)
- · Section bullets
- · Body text
- · Borders or dividers
- · Page or card backgrounds
- · Disabled / muted states
- · Standard icons
- · Section headers
10 · Accessibility
- All accent/surface text pairs hit ≥4.5:1 (WCAG AA). Pre-verified per accent.
- All interactive elements have a minimum 44×44pt hit area, even when the visual element is smaller.
- Every interactive element has a semantic label.
- Focus rings use a
2pxaccent outline with2pxoffset. - Dynamic type (iOS) / font scale (Android) is respected — the scale up to 130% without breaking layout.
- Reduced-motion users get motion disabled, not "shortened" — zero animation.
11 · Platform implementations
DDS tokens live in shared/design/dot-tokens.yaml as the single source of truth. Each platform mirrors them into native code. There is no auto-generation — the yaml is the contract, each project owns its translation.
Flutter (Dart)
// lib/core/theme/dds_tokens.dart
class DdsBase {
// Dark
static const darkBg = Color(0xFF000000);
static const darkSurface = Color(0xFF0B0B0B);
static const darkSurface2 = Color(0xFF141414);
static const darkBorder = Color(0xFF1F1F1F);
static const darkText = Color(0xFFFFFFFF);
static const darkText2 = Color(0xFF777777);
// Light
static const lightBg = Color(0xFFF7F7F7);
static const lightSurface = Color(0xFFFFFFFF);
static const lightBorder = Color(0xFFE0E0E0);
static const lightText = Color(0xFF111111);
static const lightText2 = Color(0xFF666666);
}
class DdsAccent {
// dani.subs
static const dark = Color(0xFFFF2D2D);
static const light = Color(0xFFE80000);
}
class DdsRadii {
static const xs = 2.0; // phone screens
static const sm = 4.0; // all controls
static const md = 8.0; // phone frame
}Next.js / Web
/* globals.css */
:root {
/* Light mode (default) */
--bg: #F7F7F7;
--surface: #FFFFFF;
--border: #E0E0E0;
--text: #111111;
--text-2: #666666;
--accent: #E80000; /* dani.subs light */
}
[data-theme="dark"] {
--bg: #000000;
--surface: #0B0B0B;
--border: #1F1F1F;
--text: #FFFFFF;
--text-2: #777777;
--accent: #FF2D2D; /* dani.subs dark */
}
.btn-primary {
background: var(--accent);
color: #FFFFFF;
border-radius: 4px;
padding: 14px 16px;
font: 600 12px 'Space Grotesk';
}SwiftUI
// DdsTokens.swift
enum DdsBase {
static let darkBg = Color(hex: 0x000000)
static let darkSurface = Color(hex: 0x0B0B0B)
static let darkBorder = Color(hex: 0x1F1F1F)
static let darkText = Color(hex: 0xFFFFFF)
static let lightBg = Color(hex: 0xF7F7F7)
static let lightSurface = Color(hex: 0xFFFFFF)
static let lightBorder = Color(hex: 0xE0E0E0)
static let lightText = Color(hex: 0x111111)
}
enum DdsAccent {
static let dark = Color(hex: 0xFF2D2D)
static let light = Color(hex: 0xE80000)
}12 · Governance & versioning
DDS is versioned semantically. The current version is 1.0.0.
- Patch (1.0.x) — accent contrast tweaks, typo fixes in docs.
- Minor (1.x.0) — new component, new accent, new token. Backwards compatible.
- Major (x.0.0) — breaking changes: removed tokens, changed monochrome base, new type family.
Any change to the yaml must be mirrored in every consuming project's local token file before the next release of that project. The yaml is the contract.
DDS is not a design system you customize. It's a design system you live inside. The constraints are the feature.
shared/design/dot-tokens.yaml