veza/apps/web/docs/DESIGN_DIRECTION.md

282 lines
12 KiB
Markdown
Raw Normal View History

# Design Direction: SUMI — « Encre, pas néon »
**Last Updated**: 2026-02-12
**Status**: Active Design Direction
**Purpose**: Define the SUMI design philosophy for the Veza application
## Overview
SUMI is a design philosophy rooted in the **sumi-e** (墨絵) ink wash painting tradition. The guiding motto is:
> **« Encre, pas néon »** — Ink, not neon.
Three pillars:
1. **Surgical Minimalism** — Every visual element serves a function. If it doesn't inform, guide, or delight purposefully, it doesn't belong.
2. **Purposeful Design** — Color, motion, and spacing are intentional tools, never decoration.
3. **Texture over effect** — Depth comes from paper grain, ink wash gradients, and warm neutrals — not from glows, neon pulses, or flashy transforms.
## Core Principles
### 1. Sumi-e Metaphor
The UI draws from ink wash painting:
- **Paper grain**: subtle texture through warm neutral backgrounds (`--sumi-bg-base`, `--sumi-bg-raised`, `--sumi-bg-wash`). Light theme evokes washi paper (`--sumi-bg-void: #f0ece4`).
- **Ink wash gradients**: depth built with opacity layers and glass effects (`--sumi-glass-bg`), not solid neon colors.
- **Pigments, not neon**: four earth-toned accent pigments — **Accent** (slate blue `#7c9dd6`), **Vermillion** (brick red `#d4634a`), **Sage** (muted green `#7a9e6c`), **Gold** (warm ochre `#c9a84c`). Each used sparingly and intentionally.
### 2. Color: Warm Neutrals, Muted Pigments
**Principle**: Warm neutral surfaces, muted earth-toned pigments for accents, high contrast text.
- **Backgrounds**: Warm dark neutrals with subtle blue-violet undertones (`#0c0c0f` → `#1a1a1f``#222228`), not pure black.
- **Text**: Warm off-white (`--sumi-text-primary: #f0ede8`) for primary, stone gray (`--sumi-text-secondary: #a8a4a0`) for secondary. High contrast, WCAG AA compliant.
- **Accents**: Used only for primary actions, active states, semantic status. Never decorative fills.
**Implementation**:
- Primary actions: `--sumi-accent` (buttons, active states, focus rings)
- Secondary actions: `--sumi-bg-hover` / `--sumi-border-default`
- Semantic: `--sumi-success` (sage), `--sumi-warning` (gold), `--sumi-error` (vermillion)
- Decorative elements: neutral backgrounds only
### 3. Typography: Inter + Space Grotesk
| Role | Font | Token |
|------|------|-------|
| Body text | Inter | `--sumi-font-body` |
| Headings | Space Grotesk | `--sumi-font-heading` |
| Code / mono | JetBrains Mono | `--sumi-font-mono` |
| Serif accents | Noto Serif JP | `--sumi-font-serif` |
**Text sizes** follow SUMI scale: `--sumi-text-xs` (0.75rem) through `--sumi-text-4xl` (2.25rem), with `--sumi-text-base` at 0.875rem.
**Hierarchy**:
- Headings: `--sumi-text-primary` + `--sumi-font-heading` + `--sumi-weight-semibold`
- Body: `--sumi-text-primary` + `--sumi-font-body` + `--sumi-weight-regular`
- Secondary/metadata: `--sumi-text-secondary` or `--sumi-text-tertiary`, sparingly
### 4. Whitespace & Readability
**Principle**: Generous whitespace improves visual hierarchy and reduces cognitive load.
**Spacing tokens** (SUMI scale in [index.css](../src/index.css)):
- `--sumi-space-2` (8px) — base unit
- `--sumi-space-4` (16px) — standard gap
- `--sumi-space-6` (24px) — section gap
- `--sumi-space-8` (32px) — card padding, large section spacing
- `--sumi-space-12` (48px) — page-level spacing
- `--sumi-space-16` (64px) — major separations
**Layout gaps**:
- `--layout-gap` (1rem), `--layout-gap-sm` (0.75rem), `--layout-gap-lg` (1.5rem)
### 5. Subtle, Purposeful Interactions
**Principle**: Hover effects and animations should be functional, not decorative.
**Keep** (functional):
- Background color changes: `hover:bg-[var(--sumi-bg-hover)]` for interactive feedback
- Opacity changes: `group-hover:opacity-100` for functional overlays (play buttons)
- Border color changes: `hover:border-[var(--sumi-border-strong)]`
- Text color changes: `hover:text-[var(--sumi-text-primary)]`
- Transition timing: `--sumi-duration-fast` (150ms) for colors, `--sumi-duration-normal` (200ms) for transforms
- Easing: `--sumi-ease-default` or `--sumi-ease-out`
**Anti-patterns** (NEVER do):
- ❌ Scale transforms on hover: no `hover:scale-[1.02]`, `hover:scale-105`, `hover:scale-110`
- ❌ Neon glows: no `shadow-[0_0_15px_rgba(0,255,255,...)]`, no `shadow-neon-*`
- ❌ Decorative animations: no pulsing, no bouncing, no breathing effects for aesthetics
- ❌ Multiple simultaneous effects: no scale + shadow + border combos
- ❌ Image zoom on hover: no `group-hover:scale-110` on decorative images
### 6. Surfaces & Elevation
Depth is conveyed through **background layers** and **shadows**, not glows:
| Level | Token | Usage |
|-------|-------|-------|
| Void | `--sumi-bg-void` | Page background |
| Base | `--sumi-bg-base` | Main content area |
| Raised | `--sumi-bg-raised` | Sidebar, cards |
| Overlay | `--sumi-bg-overlay` | Dropdowns, popovers |
| Glass | `--sumi-glass-bg` + blur | Header, player bar |
**Shadows** (SUMI scale): `--sumi-shadow-xs` through `--sumi-shadow-2xl`. Use sparingly — one shadow level per element. `--sumi-shadow-glow` reserved for focus rings only.
### 7. Gradients: Functional Only
**Keep**:
- Functional overlays for text readability: `bg-gradient-to-t from-black/80`
- Hero sections (featured content, landing)
- Glass effects (via `--sumi-glass-bg` + backdrop-blur)
**Remove**:
- Card backgrounds: use solid `--sumi-surface-card`
- Decorative section backgrounds
- Hover overlays: use solid colors with opacity
## Sub-Themes: Contextual Accents
Sub-themes are **contextual accent overrides**, not global theme replacements. They provide feature-specific color accents while the core SUMI palette stays constant.
| Sub-theme | Accent | Token | Context |
|-----------|--------|-------|---------|
| Nature | Sakura pink | `--sakura: #e0a0b8` | Nature/ambient content |
| Graffiti | Magenta | `--graffiti-magenta: #c840a0` | Urban/graffiti features |
| Gaming | Gold | `--gaming-gold: #d4b040` | Gaming-related features |
| Terminal | Green | `--terminal-green: #3eaa5e` | Developer/terminal features |
| Music | Default accent | `--sumi-accent` | Core music experience |
**Rules**:
- Sub-themes affect only their feature area, not the global shell
- Core backgrounds, text colors, and border tokens remain SUMI
- A sub-theme overrides `--sumi-accent` locally, nothing else
## Anti-Patterns Reference
These patterns contradict SUMI and must be avoided:
| Anti-pattern | Why | Alternative |
|--------------|-----|-------------|
| `hover:scale-[1.02]` | Decorative, not functional | `hover:bg-[var(--sumi-bg-hover)]` |
| `shadow-neon-cyan/20` | Neon aesthetic, not ink | `--sumi-shadow-sm` |
| `bg-gradient-to-r from-cyan to-blue` | Neon gradient | Solid `--sumi-surface-card` |
| `animate-pulse` on decorative elements | Distracting | Static or `--sumi-transition-opacity` |
| `text-cyan-400` / `text-kodo-cyan` | Old Kodo neon palette | `--sumi-accent` or `--sumi-text-link` |
| `bg-kodo-void` / `bg-kodo-ink` | Old Kodo tokens | `--sumi-bg-void` / `--sumi-bg-base` |
| Class-based theme toggle (`dark:`) | Stale pattern | `[data-theme]` attribute |
## Implementation Checklist
When applying SUMI to a component or page:
### Color & Surface
- [ ] Backgrounds use SUMI tokens (`--sumi-bg-*`, `--sumi-surface-*`)
- [ ] Text uses `--sumi-text-primary` (not `text-white` or `text-kodo-*`)
- [ ] Accents use `--sumi-accent` family (not `kodo-cyan`)
- [ ] Semantic colors use `--sumi-success`, `--sumi-warning`, `--sumi-error`
- [ ] No neon colors, no `kodo-*` tokens
- [ ] Cards use `--sumi-surface-card` (solid, no gradient)
### Spacing & Layout
- [ ] Spacing uses SUMI scale (`--sumi-space-*`) or Tailwind equivalents
- [ ] Layout uses SUMI layout tokens (`--sumi-max-width`, `--sumi-header-height`, etc.)
- [ ] Generous whitespace between sections
### Interactions
- [ ] Hover effects are subtle: background/opacity/border color only
- [ ] No scale transforms on interactive elements
- [ ] No decorative shadows or glows on hover
- [ ] Transitions use `--sumi-duration-fast` / `--sumi-ease-default`
### Typography
- [ ] Body text uses `--sumi-font-body` (Inter)
- [ ] Headings use `--sumi-font-heading` (Space Grotesk)
- [ ] Text sizes follow SUMI scale (`--sumi-text-*`)
- [ ] Text contrast meets WCAG AA
### Glass & Elevation
- [ ] Glass surfaces use `--sumi-glass-bg` + `backdrop-blur`
- [ ] Shadows use SUMI scale (`--sumi-shadow-*`)
- [ ] Focus rings use `--sumi-shadow-glow`
### Theme Compatibility
- [ ] Component works with `[data-theme="dark"]` and `[data-theme="light"]`
- [ ] No hardcoded colors that break in light theme
- [ ] Borders use `--sumi-border-*` tokens
## Examples
### ✅ Good: SUMI Applied
```tsx
// Card with SUMI tokens
<Card className="bg-[var(--sumi-surface-card)] border border-[var(--sumi-border-faint)] p-8
hover:bg-[var(--sumi-bg-hover)] transition-colors duration-[var(--sumi-duration-fast)]">
<CardHeader>
<CardTitle className="text-[var(--sumi-text-primary)] font-heading">Title</CardTitle>
</CardHeader>
<CardContent>
<p className="text-[var(--sumi-text-secondary)]">Content</p>
</CardContent>
</Card>
// Button with SUMI accent
<Button className="bg-[var(--sumi-accent)] text-[var(--sumi-text-inverse)]">
Primary Action
</Button>
<Button variant="outline" className="border-[var(--sumi-border-default)]
hover:border-[var(--sumi-border-strong)]">
Secondary Action
</Button>
```
### ❌ Avoid: Anti-SUMI Patterns
```tsx
// Neon glow + scale transform + gradient
<Card className="bg-gradient-to-r from-kodo-ink to-kodo-graphite
hover:scale-[1.02] hover:shadow-neon-cyan/20">
{/* ❌ Gradient bg, scale, neon glow */}
</Card>
// Kodo tokens (deprecated)
<Button className="bg-kodo-cyan text-black">
{/* ❌ Use --sumi-accent instead */}
</Button>
// Decorative animation
<div className="animate-pulse bg-cyan-500/20">
{/* ❌ Neon color + decorative animation */}
</div>
```
## Migration Path
### Completed
1. ✅ SUMI token system defined in `index.css` (`:root` + `[data-theme="light"]`)
2. ✅ Theme switching migrated from class to `[data-theme]` attribute
3. ✅ Typography tokens: Inter (body) + Space Grotesk (headings) + JetBrains Mono (code)
4. ✅ Glass effects on header and player bar
5. ✅ Shadow and z-index scales defined
6. ✅ Contextual accent tokens (graffiti, gaming, terminal, sakura)
### In Progress
- Component migration from `kodo-*` tokens to `--sumi-*` tokens
- Audit and removal of remaining neon glows and scale transforms
- Light theme (Washi Paper) refinement
### Future Work
- Enforce SUMI tokens via linting rules
- Paper grain texture as optional background layer
- Ink wash gradient presets for hero/feature sections
- Sub-theme contextual scoping
## References
- **SUMI tokens source**: `apps/web/src/index.css``:root` and `[data-theme="light"]`
- **App Shell layout**: `apps/web/docs/APP_SHELL.md`
- **Design Tokens doc**: `apps/web/docs/DESIGN_TOKENS.md`
- **Storybook contract**: `apps/web/docs/STORYBOOK_CONTRACT.md`
## Benefits
**User Experience**:
- Reduced cognitive load — warm neutrals are easier on the eyes
- Improved readability — high contrast text, generous whitespace
- Better visual hierarchy — depth through layers, not decoration
- Professional, distinctive aesthetic — ink wash, not neon
**Developer Experience**:
- Single token system (`--sumi-*`) — no ambiguity between old/new tokens
- Clear anti-patterns — easy to audit and enforce
- Consistent patterns across dark and light themes
- Meaningful names tied to the sumi-e metaphor
**Accessibility**:
- WCAG AA compliant contrast ratios
- Clear focus states (`--sumi-shadow-glow`)
- Reduced visual noise and motion
- Functional-only interactions