get-shit-pretty 0.7.1 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +292 -100
- package/bin/install.js +1 -1
- package/gsp/hooks/hooks.json +38 -2
- package/gsp/skills/gsp-brand-identity/SKILL.md +7 -7
- package/gsp/skills/gsp-help/SKILL.md +10 -5
- package/gsp/skills/gsp-project-build/SKILL.md +209 -68
- package/gsp/skills/gsp-project-build/bento-grid.md +114 -0
- package/gsp/skills/gsp-project-build/methodology/gsp-project-builder.md +45 -1
- package/gsp/skills/gsp-project-critique/SKILL.md +8 -4
- package/gsp/skills/gsp-project-design/SKILL.md +0 -1
- package/gsp/skills/gsp-project-design/methodology/gsp-project-designer.md +28 -21
- package/gsp/skills/gsp-scaffold/SKILL.md +19 -0
- package/gsp/skills/gsp-style/styles/INDEX.yml +7 -1
- package/gsp/skills/gsp-style/styles/nothing.md +445 -0
- package/gsp/skills/gsp-style/styles/nothing.yml +146 -0
- package/gsp/templates/branding/config.json +3 -2
- package/gsp/templates/phases/build.md +13 -4
- package/gsp/templates/phases/design.md +0 -8
- package/gsp/templates/projects/config.json +3 -2
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@ You are spawned with an `execution_mode` parameter. Follow the mode strictly:
|
|
|
17
17
|
|
|
18
18
|
### `foundations`
|
|
19
19
|
Build token integration, global styles, and layout primitives ONLY. Stop after foundations.
|
|
20
|
-
- Design tokens → CSS variables / Tailwind config. Write only **global tokens**: brand colors, font families, spacing scale, base radius, base shadows. Do NOT write screen-specific tokens yet.
|
|
20
|
+
- Design tokens → CSS variables / Tailwind config. Use the **token-mapping.md** reference to map `.yml` values to the correct format per target. For shadcn: convert hex to HSL space-separated channels (e.g., `#1E40AF` → `221 72% 40%`), write ALL variables in `:root` and `.dark` scopes (background, foreground, card, popover, primary, secondary, muted, accent, destructive, border, input, ring, sidebar-*, chart-1 through chart-5, --radius). Write only **global tokens**: brand colors, font families, spacing scale, base radius, base shadows. Do NOT write screen-specific tokens yet.
|
|
21
21
|
- Global CSS (resets, base styles, dark mode)
|
|
22
22
|
- Layout components (root layout, nav shell, footer shell)
|
|
23
23
|
- Shared utilities (cn helper, theme provider)
|
|
@@ -31,6 +31,20 @@ Build a single screen. You receive only that screen's design chunk and its refer
|
|
|
31
31
|
- Build the screen's route page and its screen-specific components
|
|
32
32
|
- Wire imports to existing foundation components
|
|
33
33
|
|
|
34
|
+
### `component`
|
|
35
|
+
Install, customize, or create assigned components ONLY. Stop after components.
|
|
36
|
+
- You receive a component partition: a list of components with their classification
|
|
37
|
+
- For **library default**: install via CLI (e.g. `npx shadcn@latest add {name}`) and verify it works
|
|
38
|
+
- For **library + customize**: install via CLI, then apply brand overrides from STYLE.md (radius, shadow, color tokens)
|
|
39
|
+
- For **custom**: create component from scratch following brand patterns, STYLE.md constraints, and token-mapping.md
|
|
40
|
+
- Read foundations from the codebase (tokens, layout, utilities already exist from foundations phase)
|
|
41
|
+
- Follow `implementation_target` rules (shadcn vs rn-reusables vs existing vs code)
|
|
42
|
+
- **Do NOT modify foundation files** (global CSS, layout, tokens, theme provider)
|
|
43
|
+
- **Do NOT build screens or page content**
|
|
44
|
+
- **Do NOT create route pages**
|
|
45
|
+
- Write components to the project's component directory following codebase conventions
|
|
46
|
+
- Leave changes unstaged
|
|
47
|
+
|
|
34
48
|
### `full`
|
|
35
49
|
Legacy mode — build everything in one pass. Used as backward-compatible default.
|
|
36
50
|
|
|
@@ -92,6 +106,36 @@ Check code against these before marking a screen complete — **but STYLE.md tak
|
|
|
92
106
|
- **Components:** customize shadcn radii/colors/shadows, skeleton loaders not spinners, semantic HTML
|
|
93
107
|
- **Code:** no inline styles mixed with utilities, relative units, clean z-index scale, alt text, verify imports exist
|
|
94
108
|
|
|
109
|
+
## shadcn/ui Rules (when target is shadcn)
|
|
110
|
+
|
|
111
|
+
These rules are always enforced for shadcn targets. They reflect the official shadcn/ui composition patterns:
|
|
112
|
+
|
|
113
|
+
**Styling:**
|
|
114
|
+
- Use semantic color tokens (`bg-primary`, `text-muted-foreground`) — never raw values like `bg-blue-500`
|
|
115
|
+
- No manual `dark:` color overrides — use semantic tokens that auto-adapt
|
|
116
|
+
- Use `gap-*` with flex/grid — never `space-x-*` or `space-y-*`
|
|
117
|
+
- Use `size-*` when width and height are equal — `size-10` not `w-10 h-10`
|
|
118
|
+
- Use `cn()` for conditional classes — never manual template literal ternaries
|
|
119
|
+
- No manual `z-index` on overlay components (Dialog, Sheet, Popover handle their own stacking)
|
|
120
|
+
- Use built-in variants before custom styles (`variant="outline"`, `size="sm"`)
|
|
121
|
+
|
|
122
|
+
**Composition:**
|
|
123
|
+
- Items always inside their Group (`SelectItem` → `SelectGroup`, `DropdownMenuItem` → `DropdownMenuGroup`)
|
|
124
|
+
- Dialog, Sheet, and Drawer always need a Title (use `className="sr-only"` if visually hidden)
|
|
125
|
+
- Use full Card composition (`CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`)
|
|
126
|
+
- `TabsTrigger` must be inside `TabsList`
|
|
127
|
+
- `Avatar` always needs `AvatarFallback`
|
|
128
|
+
- Use `Alert` for callouts, `Badge` for status, `Skeleton` for loading, `Separator` for dividers, `sonner` for toast
|
|
129
|
+
|
|
130
|
+
**Icons:**
|
|
131
|
+
- Icons in `Button` use `data-icon` attribute (`data-icon="inline-start"` or `data-icon="inline-end"`)
|
|
132
|
+
- No sizing classes on icons inside components — components handle icon sizing via CSS
|
|
133
|
+
|
|
134
|
+
**CLI awareness:**
|
|
135
|
+
- Install components via `npx shadcn@latest add {name}` — never copy/paste from GitHub
|
|
136
|
+
- Use `npx shadcn@latest search` to find components before building custom ones
|
|
137
|
+
- After installing components from registries, verify imports match the project's alias config
|
|
138
|
+
|
|
95
139
|
Full reference: `references/anti-patterns.md` (available via Read for the complete list with fixes).
|
|
96
140
|
|
|
97
141
|
## Visual Quality Checklist
|
|
@@ -103,6 +103,8 @@ Read `${CLAUDE_SKILL_DIR}/methodology/gsp-project-critic.md`. Include the full c
|
|
|
103
103
|
- `accessibility_level` from config (defaults to "WCAG 2.2 AA")
|
|
104
104
|
- Output path: `{PROJECT_PATH}/critique/`
|
|
105
105
|
|
|
106
|
+
**Model assignment:** Spawn `gsp-accessibility-auditor` with `model: sonnet`. The accessibility audit is checklist-based (WCAG compliance) and works well on Sonnet. This splits rate-limit pressure — the critic runs on the user's current model while the auditor runs on Sonnet.
|
|
107
|
+
|
|
106
108
|
## Step 3: Write critique INDEX.md
|
|
107
109
|
|
|
108
110
|
After both agents complete, write `{PROJECT_PATH}/critique/INDEX.md`:
|
|
@@ -145,11 +147,13 @@ Update `{PROJECT_PATH}/exports/INDEX.md`:
|
|
|
145
147
|
|
|
146
148
|
## Step 4: Assess results
|
|
147
149
|
|
|
148
|
-
Read `critique/critique.md` for the
|
|
150
|
+
Read `critique/critique.md` for the heuristics score (X/50) and brand contract score (X/25, present when STYLE.md was used). Read `critique/prioritized-fixes.md` for critical issues. Determine verdict:
|
|
151
|
+
|
|
152
|
+
**Pass:** Nielsen ≥ 40/50 AND brand contract ≥ 20/25 (when present) AND no critical fixes. Design is solid, proceed to build.
|
|
153
|
+
**Conditional Pass:** Nielsen 30-39/50 OR brand contract 15-19/25 OR critical fixes are minor. Shippable with notes, proceed to build.
|
|
154
|
+
**Fail:** Nielsen < 30/50 OR brand contract < 15/25 OR any brand contract dimension at 1 (constraint violation) OR critical fixes affect layout/navigation/IA. Design needs revision before building.
|
|
149
155
|
|
|
150
|
-
|
|
151
|
-
**Conditional Pass (score 30-39/50 or critical fixes are minor):** Shippable with notes, proceed to build.
|
|
152
|
-
**Fail (score < 30/50 or critical fixes affect layout/navigation/IA):** Design needs revision before building.
|
|
156
|
+
Note: If no STYLE.md was used, the brand contract score is absent — apply Nielsen thresholds only.
|
|
153
157
|
|
|
154
158
|
## Step 5: Update state
|
|
155
159
|
|
|
@@ -146,7 +146,6 @@ Pass in the agent prompt:
|
|
|
146
146
|
The agent writes chunks directly:
|
|
147
147
|
- `design/screen-{NN}-{name}.md` (one per screen)
|
|
148
148
|
- `design/shared/` (personas, IA, navigation, micro-interactions, responsive, component-plan)
|
|
149
|
-
- `design/preview.html` (self-contained wireframe preview)
|
|
150
149
|
- `design/INDEX.md`
|
|
151
150
|
- Updates `{PROJECT_PATH}/exports/INDEX.md` (design section)
|
|
152
151
|
|
|
@@ -13,21 +13,40 @@ When an **Existing Components** inventory is provided (for `shadcn`, `rn-reusabl
|
|
|
13
13
|
<methodology>
|
|
14
14
|
## Design Process
|
|
15
15
|
|
|
16
|
+
### Step 0: Internalize brand DNA (BEFORE designing anything)
|
|
17
|
+
|
|
18
|
+
When `STYLE.md` is provided, read it first and extract a working checklist before designing any screen. STYLE.md is your design law — not a reference to consult later, but the lens through which every decision is made.
|
|
19
|
+
|
|
20
|
+
Extract and hold in working memory:
|
|
21
|
+
- **Constraints** → hard boundaries (never/always lists). Violating these is a Critical error.
|
|
22
|
+
- **Patterns** → component composition rules (how to build cards, buttons, inputs, etc.)
|
|
23
|
+
- **Effects vocabulary** → the ONLY interaction techniques you may use. Anything not listed is off-limits.
|
|
24
|
+
- **Bold bets** → brand-specific techniques you MUST actively implement. These are what prevent generic output. If the brand has "purple atmospheric glow" as a bold bet, every relevant screen must show it.
|
|
25
|
+
- **Intensity dials** → calibrate your creativity (variance drives layout, motion drives animation, density drives spacing)
|
|
26
|
+
|
|
27
|
+
Every screen you design must reference specific techniques by name (e.g., "lift-shadow on feature cards", "press-down on CTA", "purple glow behind glass hero") — never generic terms like "use brand styling."
|
|
28
|
+
|
|
29
|
+
### Steps 1-8: Design with brand DNA active
|
|
30
|
+
|
|
16
31
|
1. **Define personas** — From BRIEF.md audience, create primary persona with goals and pain points
|
|
17
32
|
2. **Map information architecture** — Hierarchy, grouping, navigation structure
|
|
18
33
|
3. **Choose navigation pattern** — Tab bar, sidebar, or custom — justified by use case
|
|
19
|
-
4. **Design
|
|
34
|
+
4. **Design core screens** — Each with wireframe description, component usage, interactions, and all states. Apply brand patterns and effects in every screen — not as a separate pass, but as the default visual language.
|
|
20
35
|
5. **Specify accessibility** — WCAG compliance, VoiceOver order, Dynamic Type behavior
|
|
21
|
-
6. **Define micro-interactions** —
|
|
36
|
+
6. **Define micro-interactions** — Only use techniques from the effects vocabulary. Reference them by name.
|
|
22
37
|
7. **Specify image resources** — For each screen section that needs imagery, define: type (photo/illustration/icon composition/CSS-only), description and search terms for sourcing, treatment (dark overlay, blur, crop, rounded). Match the brand's imagery style from `imagery-style.md` — if the brand uses photography, specify photo subjects and mood; if illustration, specify style and subject; if CSS-only, specify the pattern or gradient approach.
|
|
23
38
|
8. **Build component plan** — When existing components inventory is provided, annotate which components to reuse, refactor, or create new
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
|
|
40
|
+
### Step 9: Brand fidelity self-check
|
|
41
|
+
|
|
42
|
+
Before writing INDEX.md, verify your output against STYLE.md:
|
|
43
|
+
- [ ] Every constraint respected (check the never/always lists)
|
|
44
|
+
- [ ] Every bold bet appears in at least one screen (list which screen for each)
|
|
45
|
+
- [ ] Effects vocabulary is the only source of interaction techniques used
|
|
46
|
+
- [ ] Intensity dials match — variance, motion, density are calibrated correctly
|
|
47
|
+
- [ ] No generic visual treatments — every surface, shadow, glow, gradient references a named brand technique
|
|
48
|
+
|
|
49
|
+
If any bold bet is missing from all screens, go back and add it. Bold bets are the brand's differentiation — skipping them produces generic output.
|
|
31
50
|
|
|
32
51
|
## Style Feedback Detection
|
|
33
52
|
|
|
@@ -111,18 +130,6 @@ Write to `design/shared/` (~50-100 lines each):
|
|
|
111
130
|
|
|
112
131
|
Shared chunks link to related shared chunks and relevant screen chunks.
|
|
113
132
|
|
|
114
|
-
### `design/preview.html`
|
|
115
|
-
|
|
116
|
-
After writing all screen chunks, generate a self-contained HTML preview file:
|
|
117
|
-
- Single HTML file with embedded CSS (no external dependencies)
|
|
118
|
-
- One section per screen showing a wireframe-level layout visualization
|
|
119
|
-
- Use simple boxes, text labels, and semantic structure to represent each screen's layout
|
|
120
|
-
- Include navigation between screens
|
|
121
|
-
- Use the brand's color tokens (from the brand `.yml`) for accents if available, otherwise use neutral grays
|
|
122
|
-
- Responsive — preview itself adapts to viewport width
|
|
123
|
-
- Add a table of contents sidebar listing all screens
|
|
124
|
-
- Keep it minimal — this is a wireframe preview, not a polished mockup
|
|
125
|
-
|
|
126
133
|
### `INDEX.md`
|
|
127
134
|
|
|
128
135
|
After writing all chunks, write `INDEX.md` in the design directory:
|
|
@@ -184,6 +184,21 @@ Clear any build cache first (`rm -rf .next` for Next.js), then run the build com
|
|
|
184
184
|
- After fix attempt, clear cache and re-run build once
|
|
185
185
|
- **Second failure:** Log the error and stop. Do not loop.
|
|
186
186
|
|
|
187
|
+
## Step 5.5: Capture project context (shadcn targets)
|
|
188
|
+
|
|
189
|
+
If `implementation_target` is `shadcn`, run `npx shadcn@latest info --json` and capture the output. This provides:
|
|
190
|
+
- `aliases` — the actual alias prefix for imports (`@/`, `~/`)
|
|
191
|
+
- `tailwindVersion` — `"v4"` (uses `@theme inline`) vs `"v3"` (uses `tailwind.config.js`)
|
|
192
|
+
- `tailwindCssFile` — the global CSS file where custom properties go
|
|
193
|
+
- `style` — component visual treatment (nova, vega, etc.)
|
|
194
|
+
- `base` — primitive library (radix or base)
|
|
195
|
+
- `iconLibrary` — determines icon imports (lucide-react, @tabler/icons-react, etc.)
|
|
196
|
+
- `resolvedPaths` — exact file-system destinations for components, utils, hooks
|
|
197
|
+
- `framework` — routing and file conventions (Next.js App Router, Vite SPA, etc.)
|
|
198
|
+
- `isRSC` — whether "use client" directives are needed
|
|
199
|
+
|
|
200
|
+
Include this JSON in the scaffold log under a `## Project Context` section so the foundations agent can reference it.
|
|
201
|
+
|
|
187
202
|
## Step 6: Write scaffold log
|
|
188
203
|
|
|
189
204
|
Write `{PROJECT_PATH}/build/SCAFFOLD-LOG.md`:
|
|
@@ -225,6 +240,10 @@ Write `{PROJECT_PATH}/build/SCAFFOLD-LOG.md`:
|
|
|
225
240
|
- **Result:** {pass / fail}
|
|
226
241
|
- **Output:** {first/last lines if relevant}
|
|
227
242
|
|
|
243
|
+
## Project Context
|
|
244
|
+
|
|
245
|
+
{If shadcn target: JSON output from `npx shadcn@latest info --json`. Otherwise: "N/A — non-shadcn target"}
|
|
246
|
+
|
|
228
247
|
## Issues
|
|
229
248
|
|
|
230
249
|
{Any problems encountered and how they were resolved, or "None"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# Style Preset Index
|
|
2
|
-
#
|
|
2
|
+
# 35 styles — sourced from designprompts.dev, GSP trend references, and original presets
|
|
3
3
|
# Tags enable fuzzy matching: /gsp-style "something dark and techy" → cyberpunk, terminal, modern-dark
|
|
4
4
|
|
|
5
5
|
styles:
|
|
6
|
+
# ── Industrial ────────────────────────
|
|
7
|
+
- name: nothing
|
|
8
|
+
file: nothing.yml
|
|
9
|
+
tags: [monochrome, industrial, dark, minimal, technical, instrument, mechanical, swiss]
|
|
10
|
+
vibe: "Nothing Phone DNA — OLED black, dot-matrix Doto headlines, red signal accent, zero shadows"
|
|
11
|
+
|
|
6
12
|
# ── Minimal ─────────────────────────
|
|
7
13
|
- name: swiss-minimalist
|
|
8
14
|
file: swiss-minimalist.yml
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
<design-system>
|
|
2
|
+
# Design Style: Nothing
|
|
3
|
+
|
|
4
|
+
## Design Philosophy
|
|
5
|
+
|
|
6
|
+
### Core Principle
|
|
7
|
+
|
|
8
|
+
**Subtract, don't add.** Every element must earn its pixel. Structure is the ornament — expose the grid, the data, the hierarchy itself. Monochrome is the canvas; color is an event, not a default. Typography does the heavy lifting through scale, weight, and spacing — not color, not icons, not borders.
|
|
9
|
+
|
|
10
|
+
### Visual Vibe
|
|
11
|
+
|
|
12
|
+
**Emotional Keywords**: Industrial, Precise, Mechanical, Confident, Sparse, Technical, Warm-through-restraint, Percussive, Honest
|
|
13
|
+
|
|
14
|
+
This is the visual language of:
|
|
15
|
+
|
|
16
|
+
- Nothing Phone's interface — dot-matrix meets Swiss precision
|
|
17
|
+
- Teenage Engineering products — instrument-panel aesthetic
|
|
18
|
+
- Braun industrial design — function expressed through form
|
|
19
|
+
- Technical manuals that are beautiful because they're clear
|
|
20
|
+
- A control room where every indicator serves a purpose
|
|
21
|
+
|
|
22
|
+
The design feels percussive, not fluid. Imagine UI sounds: click not swoosh, tick not chime. Mechanical precision with a human hand felt underneath.
|
|
23
|
+
|
|
24
|
+
### What This Design Is NOT
|
|
25
|
+
|
|
26
|
+
- Not pure darkness for mood (uses OLED black for function)
|
|
27
|
+
- Not atmospheric or ambient (no glows, no blurred orbs)
|
|
28
|
+
- Not cold or sterile (industrial warmth through typography craft)
|
|
29
|
+
- Not colorful (monochrome with red as emergency signal only)
|
|
30
|
+
- Not soft or rounded (flat, sharp, instrument-like)
|
|
31
|
+
- Not similar to Minimal Dark (no amber, no glass, no shadows)
|
|
32
|
+
- Not similar to Modern Dark (no gradients, no ambient lighting)
|
|
33
|
+
- Not similar to Terminal (shares monospace DNA but broader type palette, more compositional ambition)
|
|
34
|
+
|
|
35
|
+
### The DNA of Nothing
|
|
36
|
+
|
|
37
|
+
#### 1. Three-Layer Visual Hierarchy
|
|
38
|
+
|
|
39
|
+
Every screen has exactly three layers of importance — not two, not five. Primary: the ONE thing (Doto or Space Grotesk at display size, #FFFFFF). Secondary: supporting context (Space Grotesk body, #E8E8E8). Tertiary: metadata pushed to edges (Space Mono ALL CAPS, #999999 or #666666).
|
|
40
|
+
|
|
41
|
+
The test: squint at the screen. Can you still tell what's most important? If two things compete, one needs to shrink, fade, or move. Be brave — make the primary absurdly large and the tertiary absurdly small. The contrast IS the hierarchy.
|
|
42
|
+
|
|
43
|
+
#### 2. Monochrome Gray Scale as Hierarchy
|
|
44
|
+
|
|
45
|
+
The gray scale IS the design system. Max four levels per screen:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
#FFFFFF (100%) → Hero numbers. One per screen.
|
|
49
|
+
#E8E8E8 (90%) → Body text, primary content.
|
|
50
|
+
#999999 (60%) → Labels, captions, metadata.
|
|
51
|
+
#666666 (40%) → Disabled, timestamps, hints.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Red (#D71921) is not part of the hierarchy. It's an interrupt — "look HERE, NOW." If nothing is urgent, no red on screen.
|
|
55
|
+
|
|
56
|
+
#### 3. Font Discipline
|
|
57
|
+
|
|
58
|
+
Per screen, maximum: 2 font families (Space Grotesk + Space Mono, Doto only for hero moments), 3 font sizes (one large, one medium, one small), 2 font weights (Regular + one other). Think of it as a budget — every additional size/weight costs visual coherence.
|
|
59
|
+
|
|
60
|
+
**Doto** (variable dot-matrix): 36px+ only, tight tracking, hero numbers and display moments. Never for body text.
|
|
61
|
+
|
|
62
|
+
**Space Grotesk** (geometric sans): Body text, headings, subheadings. Light 300, Regular 400, Medium 500.
|
|
63
|
+
|
|
64
|
+
**Space Mono** (monospace): ALL data, ALL labels (always ALL CAPS with 0.06-0.1em letter-spacing at 11-12px). The instrument panel voice.
|
|
65
|
+
|
|
66
|
+
#### 4. Spacing as Meaning
|
|
67
|
+
|
|
68
|
+
Spacing is the primary tool for communicating relationships:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Tight (4-8px) = "These belong together" (icon + label, number + unit)
|
|
72
|
+
Medium (16px) = "Same group, different items" (list items, form fields)
|
|
73
|
+
Wide (32-48px) = "New group starts here" (section breaks)
|
|
74
|
+
Vast (64-96px) = "This is a new context" (hero to content, major divisions)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If a divider line is needed, the spacing is probably wrong. Dividers are a symptom of insufficient spacing contrast.
|
|
78
|
+
|
|
79
|
+
#### 5. Flat Surfaces, Zero Shadows
|
|
80
|
+
|
|
81
|
+
No shadows anywhere. No blur. No glassmorphism. Flat surfaces separated by borders (#222222 subtle, #333333 intentional). Cards are #111111 on #000000 — elevation through value, not depth illusion.
|
|
82
|
+
|
|
83
|
+
#### 6. Asymmetric Composition
|
|
84
|
+
|
|
85
|
+
Centered layouts feel generic. Favor deliberately unbalanced composition: large left + small right, top-heavy, edge-anchored. Balance heavy elements with more empty space, not with more heavy elements.
|
|
86
|
+
|
|
87
|
+
#### 7. One Moment of Surprise
|
|
88
|
+
|
|
89
|
+
A single break from the pattern per screen IS the design. Without it: sterile grid. With more than one: visual chaos. A dot-matrix headline, a circular widget among rectangles, a red accent among grays, a vast gap where everything else is tight.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Design Token System
|
|
94
|
+
|
|
95
|
+
### Colors (OLED Black + Gray Scale)
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
background: #000000 (OLED pure black)
|
|
99
|
+
surface: #111111 (elevated surfaces, cards)
|
|
100
|
+
surfaceRaised: #1A1A1A (secondary elevation)
|
|
101
|
+
border: #222222 (subtle dividers, decorative only)
|
|
102
|
+
borderVisible: #333333 (intentional borders, wireframe lines)
|
|
103
|
+
textDisabled: #666666 (disabled text, decorative, 4.0:1 contrast)
|
|
104
|
+
textSecondary: #999999 (labels, captions, metadata, 6.3:1 contrast)
|
|
105
|
+
textPrimary: #E8E8E8 (body text, 16.5:1 contrast)
|
|
106
|
+
textDisplay: #FFFFFF (headlines, hero numbers, 21:1 contrast)
|
|
107
|
+
accent: #D71921 (signal red — active states, urgent, destructive)
|
|
108
|
+
accentSubtle: rgba(215,25,33,0.15) (accent tint backgrounds)
|
|
109
|
+
success: #4A9E5C (confirmed, completed, in-range)
|
|
110
|
+
warning: #D4A843 (caution, pending, degraded)
|
|
111
|
+
info: #999999 (uses secondary text color)
|
|
112
|
+
interactive: #5B9BF6 (tappable text: links, picker values — not for buttons)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Light Mode
|
|
116
|
+
|
|
117
|
+
Neither mode is "derived" — both get full design attention.
|
|
118
|
+
|
|
119
|
+
| Token | Dark | Light |
|
|
120
|
+
|-------|------|-------|
|
|
121
|
+
| background | #000000 | #F5F5F5 |
|
|
122
|
+
| surface | #111111 | #FFFFFF |
|
|
123
|
+
| surfaceRaised | #1A1A1A | #F0F0F0 |
|
|
124
|
+
| border | #222222 | #E8E8E8 |
|
|
125
|
+
| borderVisible | #333333 | #CCCCCC |
|
|
126
|
+
| textDisabled | #666666 | #999999 |
|
|
127
|
+
| textSecondary | #999999 | #666666 |
|
|
128
|
+
| textPrimary | #E8E8E8 | #1A1A1A |
|
|
129
|
+
| textDisplay | #FFFFFF | #000000 |
|
|
130
|
+
| interactive | #5B9BF6 | #007AFF |
|
|
131
|
+
|
|
132
|
+
Dark feel: instrument panel in a dark room. OLED black, white data glowing.
|
|
133
|
+
Light feel: printed technical manual. Off-white paper, black ink.
|
|
134
|
+
|
|
135
|
+
### Typography
|
|
136
|
+
|
|
137
|
+
**Font Stack** (all Google Fonts — declare before building):
|
|
138
|
+
|
|
139
|
+
| Role | Font | Fallback | Weight |
|
|
140
|
+
|------|------|----------|--------|
|
|
141
|
+
| Display | Doto | Space Mono, monospace | 400-700 variable |
|
|
142
|
+
| Body/UI | Space Grotesk | DM Sans, system-ui, sans-serif | 300, 400, 500 |
|
|
143
|
+
| Data/Labels | Space Mono | JetBrains Mono, SF Mono, monospace | 400, 700 |
|
|
144
|
+
|
|
145
|
+
**Type Scale**:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
display-xl: 72px / 1.0 / -0.03em (hero numbers, time displays)
|
|
149
|
+
display-lg: 48px / 1.05 / -0.02em (section heroes, percentages)
|
|
150
|
+
display-md: 36px / 1.1 / -0.02em (page titles)
|
|
151
|
+
heading: 24px / 1.2 / -0.01em (section headings)
|
|
152
|
+
subheading: 18px / 1.3 / 0 (subsections)
|
|
153
|
+
body: 16px / 1.5 / 0 (body text)
|
|
154
|
+
body-sm: 14px / 1.5 / 0.01em (secondary body)
|
|
155
|
+
caption: 12px / 1.4 / 0.04em (timestamps, footnotes)
|
|
156
|
+
label: 11px / 1.2 / 0.08em (ALL CAPS monospace labels)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Border Radius
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
technical: 4px (buttons when technical variant, small elements)
|
|
163
|
+
compact: 8px (compact cards, inputs)
|
|
164
|
+
standard: 12px (standard cards)
|
|
165
|
+
large: 16px (max for cards — never larger)
|
|
166
|
+
pill: 999px (primary/secondary buttons, tags)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Spacing (8px base)
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
2xs: 2px (optical adjustments only)
|
|
173
|
+
xs: 4px (icon-to-label gaps)
|
|
174
|
+
sm: 8px (component internal spacing)
|
|
175
|
+
md: 16px (standard padding, element gaps)
|
|
176
|
+
lg: 24px (group separation)
|
|
177
|
+
xl: 32px (section margins)
|
|
178
|
+
2xl: 48px (major section breaks)
|
|
179
|
+
3xl: 64px (page-level vertical rhythm)
|
|
180
|
+
4xl: 96px (hero breathing room)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Component Stylings
|
|
186
|
+
|
|
187
|
+
### Buttons
|
|
188
|
+
|
|
189
|
+
**Primary** (inverted — white on black):
|
|
190
|
+
```
|
|
191
|
+
Background: #FFFFFF
|
|
192
|
+
Text: #000000
|
|
193
|
+
Border: none
|
|
194
|
+
Radius: 999px (pill)
|
|
195
|
+
Font: Space Mono, 13px, ALL CAPS, letter-spacing 0.06em
|
|
196
|
+
Padding: 12px 24px, min-height 44px
|
|
197
|
+
Hover: no glow, no scale — opacity or border state change only
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Secondary** (outlined):
|
|
201
|
+
```
|
|
202
|
+
Background: transparent
|
|
203
|
+
Text: #E8E8E8
|
|
204
|
+
Border: 1px solid #333333
|
|
205
|
+
Radius: 999px (pill)
|
|
206
|
+
Hover: border brightens to #E8E8E8
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Ghost** (text only):
|
|
210
|
+
```
|
|
211
|
+
Background: transparent
|
|
212
|
+
Text: #999999
|
|
213
|
+
Border: none
|
|
214
|
+
Hover: text brightens to #E8E8E8
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Destructive** (red outlined):
|
|
218
|
+
```
|
|
219
|
+
Background: transparent
|
|
220
|
+
Text: #D71921
|
|
221
|
+
Border: 1px solid #D71921
|
|
222
|
+
Radius: 999px (pill)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Cards
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
Background: #111111 (or #1A1A1A for raised)
|
|
229
|
+
Border: 1px solid #222222
|
|
230
|
+
Radius: 12-16px
|
|
231
|
+
Padding: 16-24px
|
|
232
|
+
Shadow: none — never
|
|
233
|
+
Hover (when interactive): border brightens to #333333
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
No glass effects. No transparency. No backdrop-blur. Flat, honest surfaces.
|
|
237
|
+
|
|
238
|
+
### Inputs
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
Style: underline preferred (1px solid #333333 bottom border)
|
|
242
|
+
Alternative: full border with 8px radius
|
|
243
|
+
Label: Space Mono, ALL CAPS, 11px, #999999, positioned above
|
|
244
|
+
Focus: border → #E8E8E8
|
|
245
|
+
Error: border → #D71921, message below in #D71921
|
|
246
|
+
Data entry: Space Mono for input text
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Lists / Data Rows
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
Dividers: 1px solid #222222, full-width
|
|
253
|
+
Row padding: 12-16px vertical
|
|
254
|
+
Label (left): Space Mono ALL CAPS, #999999
|
|
255
|
+
Value (right): #E8E8E8, status color when encoding data
|
|
256
|
+
Never alternating row backgrounds
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Navigation
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Desktop: horizontal text bar
|
|
263
|
+
Labels: Space Mono, ALL CAPS
|
|
264
|
+
Active: #FFFFFF + dot or underline indicator
|
|
265
|
+
Inactive: #666666
|
|
266
|
+
Format: bracket [ HOME ] GALLERY INFO or pipe-delimited
|
|
267
|
+
Back button: circular 40-44px, #111111 bg, thin chevron
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Tags / Chips
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
Border: 1px solid #333333, no fill
|
|
274
|
+
Text: Space Mono, 11-12px, ALL CAPS
|
|
275
|
+
Radius: 999px (pill) or 4px (technical)
|
|
276
|
+
Padding: 4px 12px
|
|
277
|
+
Active: #FFFFFF border + text
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Data Visualization
|
|
283
|
+
|
|
284
|
+
### Segmented Progress Bars (Signature Element)
|
|
285
|
+
|
|
286
|
+
The signature data visualization — discrete rectangular blocks with 2px gaps. Square-ended, no border-radius. Mechanical, instrument-like.
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
Filled: solid status color
|
|
290
|
+
Empty: #222222 (dark) / #E0E0E0 (light)
|
|
291
|
+
Sizes: Hero 16-20px, Standard 8-12px, Compact 4-6px height
|
|
292
|
+
Always pair with numeric readout
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Charts
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
Line: 1.5-2px #FFFFFF
|
|
299
|
+
Average: dashed 1px #999999
|
|
300
|
+
Axis labels: Space Mono, caption size
|
|
301
|
+
Grid: #222222, horizontal only
|
|
302
|
+
No area fill, no legend boxes — label lines directly
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### General Rules
|
|
306
|
+
|
|
307
|
+
- Differentiate with opacity (100%/60%/30%) or pattern (solid/striped/dotted) before introducing color
|
|
308
|
+
- Apply status color to the value itself, not labels or backgrounds
|
|
309
|
+
- Always show numeric value alongside any visual
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Special Elements
|
|
314
|
+
|
|
315
|
+
### Dot-Matrix Motif
|
|
316
|
+
|
|
317
|
+
Use for: hero typography (Doto font), decorative grid backgrounds, loading indicators, empty state illustrations.
|
|
318
|
+
|
|
319
|
+
```css
|
|
320
|
+
/* Standard dot grid */
|
|
321
|
+
background-image: radial-gradient(circle, #333333 1px, transparent 1px);
|
|
322
|
+
background-size: 16px 16px;
|
|
323
|
+
|
|
324
|
+
/* Subtle dot grid */
|
|
325
|
+
background-image: radial-gradient(circle, #222222 0.5px, transparent 0.5px);
|
|
326
|
+
background-size: 12px 12px;
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Dots 1-2px, uniform 12-16px spacing. Opacity 0.1-0.2 for backgrounds, full for data. Never as container border or button style.
|
|
330
|
+
|
|
331
|
+
### State Patterns
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
Error: input border → #D71921 + message below. Inline: [ERROR] prefix
|
|
335
|
+
Empty: centered, 96px+ padding, #999999 headline, dot-matrix illustration, no mascots
|
|
336
|
+
Loading: segmented spinner or [LOADING...] bracket text — never skeleton screens
|
|
337
|
+
Disabled: opacity 0.4 or #666666 text, borders fade to #222222
|
|
338
|
+
Status: inline text — [SAVED], [ERROR: ...], [LOADING...] in Space Mono caption
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Layout Strategy
|
|
344
|
+
|
|
345
|
+
### Composition
|
|
346
|
+
|
|
347
|
+
- Asymmetric over centered — large left + small right, top-heavy, edge-anchored
|
|
348
|
+
- Three layers visible on every screen (primary / secondary / tertiary)
|
|
349
|
+
- One deliberate pattern-break per screen (the surprise IS the design)
|
|
350
|
+
- Generous negative space — resist filling empty areas
|
|
351
|
+
|
|
352
|
+
### Container Strategy (prefer lightest)
|
|
353
|
+
|
|
354
|
+
1. Spacing alone (proximity groups items)
|
|
355
|
+
2. A single divider line
|
|
356
|
+
3. A subtle border outline
|
|
357
|
+
4. A surface card with background change
|
|
358
|
+
|
|
359
|
+
Never box the most important element — let it float on the background.
|
|
360
|
+
|
|
361
|
+
### Visual Variety in Data-Dense Screens
|
|
362
|
+
|
|
363
|
+
When 3+ data sections appear, vary the visual form:
|
|
364
|
+
|
|
365
|
+
| Form | Weight |
|
|
366
|
+
|------|--------|
|
|
367
|
+
| Hero number (large Doto/Space Mono) | Heavy — use once |
|
|
368
|
+
| Segmented progress bar | Medium |
|
|
369
|
+
| Concentric rings / arcs | Medium |
|
|
370
|
+
| Inline compact bar | Light |
|
|
371
|
+
| Number-only with status color | Lightest |
|
|
372
|
+
| Sparkline | Medium |
|
|
373
|
+
| Stat row (label + value) | Light |
|
|
374
|
+
|
|
375
|
+
Lead section → heaviest treatment. The form varies, the voice stays the same.
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Effects & Animation
|
|
380
|
+
|
|
381
|
+
**Motion Philosophy**: Percussive, not fluid. Click not swoosh.
|
|
382
|
+
|
|
383
|
+
- Transitions: 150-250ms, `cubic-bezier(0.25, 0.1, 0.25, 1)` — subtle ease-out
|
|
384
|
+
- Prefer opacity over position — elements fade, don't slide
|
|
385
|
+
- Hover: border/text brightens. No scale, no shadows, no glow
|
|
386
|
+
- No parallax, scroll-jacking, spring/bounce
|
|
387
|
+
- Loading: segmented spinner (hardware-style) or bracket text
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Iconography
|
|
392
|
+
|
|
393
|
+
- Monoline, 1.5px stroke, no fill
|
|
394
|
+
- 24x24 base, 20x20 live area, round caps/joins
|
|
395
|
+
- Color inherits text color, max 5-6 strokes
|
|
396
|
+
- Libraries: Lucide (thin), Phosphor (thin)
|
|
397
|
+
- Never filled, never multi-color
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Accessibility
|
|
402
|
+
|
|
403
|
+
**Contrast Ratios** (dark mode):
|
|
404
|
+
|
|
405
|
+
| Element | Foreground | Background | Ratio |
|
|
406
|
+
|---------|-----------|------------|-------|
|
|
407
|
+
| Display text | #FFFFFF | #000000 | 21:1 (AAA) |
|
|
408
|
+
| Primary text | #E8E8E8 | #000000 | 16.5:1 (AAA) |
|
|
409
|
+
| Secondary text | #999999 | #000000 | 6.3:1 (AA) |
|
|
410
|
+
| Disabled text | #666666 | #000000 | 4.0:1 (AA large) |
|
|
411
|
+
|
|
412
|
+
**Focus States**: border → #E8E8E8 — sharp, visible, mechanical. No decorative rings or glows.
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Bold Choices (Non-Negotiable)
|
|
417
|
+
|
|
418
|
+
1. **OLED pure black** (#000000) — not "rich dark" or slate, actual black
|
|
419
|
+
2. **Zero shadows** — flat surfaces, border separation only
|
|
420
|
+
3. **Red is a signal** (#D71921) — one per screen max, never decorative
|
|
421
|
+
4. **Space Mono ALL CAPS for every label** — the instrument-panel voice
|
|
422
|
+
5. **Three-layer hierarchy on every screen** — primary absurdly large, tertiary absurdly small
|
|
423
|
+
6. **Asymmetric composition** — never default to centered
|
|
424
|
+
7. **Doto for hero moments** — dot-matrix display font, 36px+ only
|
|
425
|
+
8. **Spacing over dividers** — if you need a line, the spacing is wrong
|
|
426
|
+
9. **Data as beauty** — `36GB/s` in Space Mono at 48px IS the visual
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## What Success Looks Like
|
|
431
|
+
|
|
432
|
+
A successfully implemented Nothing design should feel like:
|
|
433
|
+
|
|
434
|
+
- A Nothing Phone's interface — precise, monochromatic, with a dot-matrix surprise
|
|
435
|
+
- A Teenage Engineering product — instrument panel, every control serves a purpose
|
|
436
|
+
- A Braun alarm clock — mechanical honesty, industrial warmth
|
|
437
|
+
- Technical documentation that's beautiful because it's clear
|
|
438
|
+
|
|
439
|
+
It should NOT feel like:
|
|
440
|
+
|
|
441
|
+
- Dark mode with moody atmosphere (no glows, no ambient lighting)
|
|
442
|
+
- Minimalist in a soft, gentle way (this is minimalist in a precise, mechanical way)
|
|
443
|
+
- A terminal emulator (shares DNA but has broader typographic ambition)
|
|
444
|
+
- Generic monochrome (the red signal, Doto display, and asymmetry give it personality)
|
|
445
|
+
</design-system>
|