DDS — The dani design system
One monochrome foundation. One red accent. 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. Every product uses the same Dot Red accent for UI. Product-specific colors exist only for app icons and brand assets — never in-app.
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 red. Accent is reserved for action — never decoration.
- 05One accent, every app.All dani products share the same Dot Red UI accent. Product identity comes from the app icon and brand assets, not from in-app colors.
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 Dot Red — the same across all products — 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.
UI accent — Dot Red
Every dani product uses the same accent for UI: Dot Red. It ships as a pair — #FF2D2D tuned for #000 surfaces (dark mode) and #E80000 tuned for #F7F7F7 (light mode). Never cross-use.
Dot Red is pre-verified for ≥4.5:1 contrast against both mode surfaces (WCAG AA). White text on a Dot Red button hits the same floor.
Brand colors (icons & assets only)
Each dani product has a unique hue for its app icon and marketing assets. These are never used as the in-app accent — all UI uses Dot Red above.
| 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 | Alert Red | #FF2D2D | #E80000 |
| 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 |
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 DdsUiAccent {
// Dot Red — same for all products
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; /* Dot Red light */
}
[data-theme="dark"] {
--bg: #000000;
--surface: #0B0B0B;
--border: #1F1F1F;
--text: #FFFFFF;
--text-2: #777777;
--accent: #FF2D2D; /* Dot Red 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 DdsUiAccent {
// Dot Red — same for all products
static let dark = Color(hex: 0xFF2D2D)
static let light = Color(hex: 0xE80000)
}12 · Governance & versioning
DDS is versioned semantically. The current version is 1.1.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