565 lines
13 KiB
Markdown
565 lines
13 KiB
Markdown
# Keep Design System
|
|
|
|
**Version:** 1.0
|
|
**Created:** 2026-01-17
|
|
**Status:** Active
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
This design system defines the visual language for Keep application. It ensures consistency across all components and screens while supporting multiple themes (light, dark, midnight, sepia).
|
|
|
|
**Key Principles:**
|
|
- Consistent spacing using 4px base unit
|
|
- Clear visual hierarchy
|
|
- Accessible color contrast (WCAG 2.1 AA)
|
|
- Theme-agnostic design
|
|
- Responsive breakpoints
|
|
- 44x44px minimum touch targets
|
|
|
|
---
|
|
|
|
## Design Tokens
|
|
|
|
### Spacing Scale (4px Base Unit)
|
|
|
|
All spacing uses the standard Tailwind spacing scale:
|
|
|
|
| Token | Value | Pixels | Usage |
|
|
|-------|-------|---------|-------|
|
|
| `p-1` / `gap-1` | 0.25rem | 4px | Tiny gaps, icon padding |
|
|
| `p-2` / `gap-2` | 0.5rem | 8px | Small padding, badges |
|
|
| `p-3` / `gap-3` | 0.75rem | 12px | Button padding, small inputs |
|
|
| `p-4` / `gap-4` | 1rem | 16px | Card padding, standard gap |
|
|
| `p-6` / `gap-6` | 1.5rem | 24px | Section padding |
|
|
| `p-8` | 2rem | 32px | Large containers |
|
|
|
|
**Standards:**
|
|
- Cards: `p-4` (16px)
|
|
- Buttons: `px-4 py-2` (16px/8px)
|
|
- Inputs: `px-3 py-2` (12px/8px)
|
|
- Badges: `px-2 py-0.5` (8px/2px)
|
|
- Form sections: `gap-4` (16px)
|
|
|
|
---
|
|
|
|
### Border Radius
|
|
|
|
Consistent corner rounding across all components:
|
|
|
|
| Token | Value | Pixels | Usage |
|
|
|-------|-------|---------|-------|
|
|
| `rounded` | 0.25rem | 4px | Small elements, icon buttons |
|
|
| `rounded-md` | 0.375rem | 6px | Inputs, small buttons |
|
|
| `rounded-lg` | 0.5rem | 8px | Cards, buttons (default) |
|
|
| `rounded-xl` | 0.75rem | 12px | Modals, large containers |
|
|
| `rounded-2xl` | 1rem | 16px | Hero elements, search bars |
|
|
| `rounded-full` | 9999px | Circular | Avatars, pill badges |
|
|
|
|
**Standards:**
|
|
- Cards/NoteCards: `rounded-lg` (8px)
|
|
- Buttons: `rounded-md` (6px)
|
|
- Inputs: `rounded-md` (6px)
|
|
- Badges (text): `rounded-full` (pills)
|
|
- Search bars: `rounded-lg` (8px)
|
|
- Icons: `rounded-full` (circular)
|
|
- Modals/Dialogs: `rounded-xl` (12px)
|
|
|
|
---
|
|
|
|
### Shadow/Elevation
|
|
|
|
Clear elevation hierarchy for depth perception:
|
|
|
|
| Token | Value | Usage |
|
|
|-------|-------|-------|
|
|
| `shadow-sm` | 0 1px 2px | Cards (base), buttons (hover) |
|
|
| `shadow` | 0 1px 3px | Default elevation |
|
|
| `shadow-md` | 0 4px 6px | Cards (hover), dropdowns |
|
|
| `shadow-lg` | 0 10px 15px | Modals, elevated content |
|
|
|
|
**Standards:**
|
|
- Cards: `shadow-sm` (base), `hover:shadow-md` (interactive)
|
|
- Buttons: No shadow (flat), `hover:shadow-sm` (optional)
|
|
- Modals: `shadow-lg` (elevated)
|
|
- Dropdowns: `shadow-lg` (elevated)
|
|
|
|
---
|
|
|
|
### Typography Scale
|
|
|
|
Consistent font sizes and weights using Tailwind defaults:
|
|
|
|
#### Font Sizes
|
|
|
|
| Token | Value | Pixels | Usage |
|
|
|-------|-------|---------|-------|
|
|
| `text-xs` | 0.75rem | 12px | Labels, small text, badges, metadata |
|
|
| `text-sm` | 0.875rem | 14px | Body text, buttons, inputs |
|
|
| `text-base` | 1rem | 16px | Card titles, emphasized text |
|
|
| `text-lg` | 1.125rem | 18px | Section headers |
|
|
| `text-xl` | 1.25rem | 20px | Page titles |
|
|
| `text-2xl` | 1.5rem | 24px | Large headings |
|
|
|
|
#### Font Weights
|
|
|
|
| Token | Value | Usage |
|
|
|-------|-------|-------|
|
|
| `font-normal` | 400 | Body text |
|
|
| `font-medium` | 500 | Emphasized text, button labels |
|
|
| `font-semibold` | 600 | Section titles |
|
|
| `font-bold` | 700 | Major headings |
|
|
|
|
#### Typography Hierarchy
|
|
|
|
```
|
|
H1: text-2xl font-bold (24px) - Page titles
|
|
H2: text-xl font-semibold (20px) - Section headers
|
|
H3: text-lg font-medium (18px) - Card titles
|
|
Body: text-sm text-gray-700 (14px) - Body text
|
|
Button: text-sm font-medium (14px) - Button labels
|
|
Label: text-xs font-medium (12px) - Labels/badges
|
|
Metadata: text-xs text-gray-500 (12px) - Metadata, dates
|
|
```
|
|
|
|
---
|
|
|
|
### Color System
|
|
|
|
The design uses CSS custom properties defined in `globals.css` for theme support.
|
|
|
|
#### Semantic Colors (CSS Variables)
|
|
|
|
```css
|
|
/* Primary Actions */
|
|
--primary: oklch(0.205 0 0)
|
|
--primary-foreground: oklch(0.985 0 0)
|
|
|
|
/* Secondary Elements */
|
|
--secondary: oklch(0.97 0 0)
|
|
--secondary-foreground: oklch(0.205 0 0)
|
|
|
|
/* Accent/Highlight */
|
|
--accent: oklch(0.97 0 0)
|
|
--accent-foreground: oklch(0.205 0 0)
|
|
|
|
/* Destructive Actions */
|
|
--destructive: oklch(0.577 0.245 27.325)
|
|
|
|
/* Foreground/Background */
|
|
--background: oklch(1 0 0)
|
|
--foreground: oklch(0.145 0 0)
|
|
|
|
/* Card Background */
|
|
--card: oklch(1 0 0)
|
|
--card-foreground: oklch(0.145 0 0)
|
|
|
|
/* Muted Text */
|
|
--muted: oklch(0.97 0 0)
|
|
--muted-foreground: oklch(0.556 0 0)
|
|
|
|
/* Borders & Inputs */
|
|
--border: oklch(0.922 0 0)
|
|
--input: oklch(0.922 0 0)
|
|
|
|
/* Focus Ring */
|
|
--ring: oklch(0.708 0 0)
|
|
```
|
|
|
|
#### Functional Color Patterns
|
|
|
|
```css
|
|
/* Text Colors */
|
|
text-foreground - Primary text
|
|
text-muted-foreground - Secondary text, metadata
|
|
text-destructive - Error messages, delete actions
|
|
text-primary - Primary action text
|
|
|
|
/* Background Colors */
|
|
bg-background - Main background
|
|
bg-card - Card background
|
|
bg-secondary - Secondary elements
|
|
bg-accent - Highlight/active states
|
|
bg-destructive - Error backgrounds
|
|
|
|
/* Border Colors */
|
|
border-border - Default borders
|
|
border-input - Input fields
|
|
```
|
|
|
|
**Rule:** Always use semantic color classes (e.g., `bg-primary`, `text-foreground`) instead of hardcoded colors (e.g., `bg-blue-500`) to support theming.
|
|
|
|
---
|
|
|
|
### Transitions
|
|
|
|
Consistent transition values for smooth interactions:
|
|
|
|
| Token | Value | Usage |
|
|
|-------|-------|-------|
|
|
| `transition-colors duration-200` | 200ms | Color changes (hover states) |
|
|
| `transition-all duration-200` | 200ms | Multiple property changes |
|
|
| `transition-opacity duration-150` | 150ms | Fade in/out |
|
|
| `transition-transform duration-200` | 200ms | Movement/position |
|
|
|
|
**Standards:**
|
|
- Buttons/hover states: `transition-colors duration-200`
|
|
- Cards: `transition-all duration-200`
|
|
- Modals/overlays: `transition-opacity duration-150`
|
|
|
|
---
|
|
|
|
### Focus States
|
|
|
|
All interactive elements must have visible focus indicators:
|
|
|
|
```css
|
|
/* Focus Ring Pattern */
|
|
focus-visible:border-ring
|
|
focus-visible:ring-ring/50
|
|
focus-visible:ring-[3px]
|
|
```
|
|
|
|
**Rule:** Use `focus-visible:` instead of `focus:` to only show focus when navigating with keyboard.
|
|
|
|
---
|
|
|
|
## Component Standards
|
|
|
|
### Button
|
|
|
|
**Default Size:**
|
|
```tsx
|
|
<Button className="h-9 px-4 py-2 text-sm font-medium rounded-md transition-colors duration-200">
|
|
Button Label
|
|
</Button>
|
|
```
|
|
|
|
**Small Size:**
|
|
```tsx
|
|
<Button size="sm" className="h-8 px-3 text-sm rounded-md">
|
|
Small Button
|
|
</Button>
|
|
```
|
|
|
|
**Variants:**
|
|
- `default`: Primary action (`bg-primary text-primary-foreground`)
|
|
- `secondary`: Secondary action (`bg-secondary text-secondary-foreground`)
|
|
- `outline`: Outlined button (`border bg-background`)
|
|
- `ghost`: Transparent button (`hover:bg-accent`)
|
|
- `destructive`: Delete/danger action (`bg-destructive text-white`)
|
|
|
|
### Input
|
|
|
|
**Standard Input:**
|
|
```tsx
|
|
<Input className="h-9 px-3 py-2 text-sm rounded-md border border-input focus-visible:ring-2 focus-visible:ring-ring/50" />
|
|
```
|
|
|
|
**With Error State:**
|
|
```tsx
|
|
<Input className="border-destructive focus-visible:ring-destructive/50" />
|
|
```
|
|
|
|
### Card
|
|
|
|
**Standard Card:**
|
|
```tsx
|
|
<Card className="rounded-xl border p-4 shadow-sm hover:shadow-md transition-all duration-200">
|
|
<CardHeader>
|
|
<CardTitle className="text-lg font-medium">Card Title</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
Card content
|
|
</CardContent>
|
|
</Card>
|
|
```
|
|
|
|
### Badge
|
|
|
|
**Standard Badge:**
|
|
```tsx
|
|
<Badge variant="default" className="rounded-full px-2 py-0.5 text-xs font-medium">
|
|
Badge Label
|
|
</Badge>
|
|
```
|
|
|
|
**Variants:**
|
|
- `default`: Primary badge
|
|
- `secondary`: Secondary badge
|
|
- `outline`: Outlined badge
|
|
- `destructive`: Error badge
|
|
|
|
### NoteCard
|
|
|
|
**Standard NoteCard:**
|
|
```tsx
|
|
<Card className="note-card group rounded-lg border p-4 shadow-sm hover:shadow-md transition-all duration-200">
|
|
{/* Note content */}
|
|
</Card>
|
|
```
|
|
|
|
---
|
|
|
|
## Accessibility Standards
|
|
|
|
### Touch Targets
|
|
|
|
**Minimum Size:** 44x44px (WCAG 2.1 AA)
|
|
|
|
```tsx
|
|
/* Icon Buttons - Ensure 44x44px on mobile */
|
|
<Button className="min-h-[44px] min-w-[44px] md:h-8 md:w-8">
|
|
<Icon className="h-5 w-5" />
|
|
</Button>
|
|
```
|
|
|
|
### Color Contrast
|
|
|
|
**Minimum Ratios:**
|
|
- Normal text: 4.5:1 (WCAG AA)
|
|
- Large text (18px+): 3:1 (WCAG AA)
|
|
- UI components: 3:1 (WCAG AA)
|
|
|
|
**Validation:** Use WAVE browser extension or axe DevTools
|
|
|
|
### Focus Indicators
|
|
|
|
All interactive elements must have visible focus states:
|
|
|
|
```tsx
|
|
<button className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2">
|
|
Button
|
|
</button>
|
|
```
|
|
|
|
### Keyboard Navigation
|
|
|
|
- All interactive elements must be keyboard accessible
|
|
- Tab order must be logical
|
|
- Escape key should close modals/dropdowns
|
|
- Enter/Space should activate buttons
|
|
|
|
---
|
|
|
|
## Responsive Breakpoints
|
|
|
|
Tailwind default breakpoints:
|
|
|
|
| Breakpoint | Minimum Width | Usage |
|
|
|------------|---------------|-------|
|
|
| `sm` | 640px | Small tablets |
|
|
| `md` | 768px | Tablets |
|
|
| `lg` | 1024px | Desktops |
|
|
| `xl` | 1280px | Large desktops |
|
|
| `2xl` | 1536px | Extra large screens |
|
|
|
|
**Pattern:** Mobile-first, use `md:`, `lg:`, etc. to override for larger screens.
|
|
|
|
---
|
|
|
|
## Theme Support
|
|
|
|
The design system supports multiple themes:
|
|
|
|
### Available Themes
|
|
|
|
1. **Light** (default) - Clean, bright interface
|
|
2. **Dark** - Dark mode for low-light environments
|
|
3. **Midnight** - Custom dark theme with blue tint
|
|
4. **Sepia** - Warm, book-like reading experience
|
|
|
|
### Theme Implementation
|
|
|
|
Themes use CSS custom properties in `globals.css`:
|
|
|
|
```css
|
|
[data-theme='midnight'] {
|
|
--background: oklch(0.18 0.04 260);
|
|
--foreground: oklch(0.985 0 0);
|
|
/* ... */
|
|
}
|
|
```
|
|
|
|
**Rule:** Use semantic color variables (`--primary`, `--foreground`) instead of hardcoded colors to support all themes.
|
|
|
|
---
|
|
|
|
## Anti-Patterns
|
|
|
|
### ❌ Don't Do
|
|
|
|
```tsx
|
|
/* Hardcoded colors - breaks theming */
|
|
<div className="bg-blue-500 text-white">
|
|
Blue background
|
|
</div>
|
|
|
|
/* Custom font sizes - breaks typography scale */
|
|
<p className="text-[10px]">
|
|
Tiny text
|
|
</p>
|
|
|
|
/* Inconsistent spacing */
|
|
<div className="p-2.5">
|
|
Odd padding
|
|
</div>
|
|
|
|
/* No focus state */
|
|
<button className="hover:bg-gray-100">
|
|
Button
|
|
</button>
|
|
|
|
/* Touch target too small */
|
|
<button className="h-6 w-6">
|
|
<Icon className="h-4 w-4" />
|
|
</button>
|
|
```
|
|
|
|
### ✅ Do Instead
|
|
|
|
```tsx
|
|
/* Semantic colors - supports theming */
|
|
<div className="bg-primary text-primary-foreground">
|
|
Primary background
|
|
</div>
|
|
|
|
/* Standard font sizes */
|
|
<p className="text-xs">
|
|
Small text
|
|
</p>
|
|
|
|
/* Consistent spacing (4px base unit) */
|
|
<div className="p-2">
|
|
Standard padding
|
|
</div>
|
|
|
|
/* Visible focus state */
|
|
<button className="hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring/50">
|
|
Button
|
|
</button>
|
|
|
|
/* Minimum 44x44px touch target */
|
|
<button className="min-h-[44px] min-w-[44px]">
|
|
<Icon className="h-5 w-5" />
|
|
</button>
|
|
```
|
|
|
|
---
|
|
|
|
## Component Checklist
|
|
|
|
When creating or updating components, ensure:
|
|
|
|
- [ ] Spacing uses 4px base unit (`p-2`, `gap-4`, etc.)
|
|
- [ ] Border radius follows standard (`rounded-md`, `rounded-lg`, etc.)
|
|
- [ ] Typography follows hierarchy (`text-sm`, `text-lg`, etc.)
|
|
- [ ] Colors use semantic variables (`bg-primary`, `text-foreground`)
|
|
- [ ] Transitions use standard durations (`duration-200`, `duration-150`)
|
|
- [ ] Focus states are visible (`focus-visible:ring-2`)
|
|
- [ ] Touch targets are minimum 44x44px on mobile
|
|
- [ ] Color contrast meets WCAG 2.1 AA standards
|
|
- [ ] Dark mode works correctly (no hardcoded colors)
|
|
- [ ] All themes work (light, dark, midnight, sepia)
|
|
|
|
---
|
|
|
|
## Migration Guide
|
|
|
|
### Converting Existing Components
|
|
|
|
1. **Identify hardcoded colors:**
|
|
```tsx
|
|
// Before
|
|
className="bg-blue-100 text-blue-600"
|
|
|
|
// After
|
|
className="bg-accent text-primary"
|
|
```
|
|
|
|
2. **Standardize spacing:**
|
|
```tsx
|
|
// Before
|
|
className="p-2.5 mb-3"
|
|
|
|
// After
|
|
className="p-3 mb-4"
|
|
```
|
|
|
|
3. **Use standard border radius:**
|
|
```tsx
|
|
// Before
|
|
className="rounded-[10px]"
|
|
|
|
// After
|
|
className="rounded-lg"
|
|
```
|
|
|
|
4. **Update typography:**
|
|
```tsx
|
|
// Before
|
|
className="text-[10px] font-bold"
|
|
|
|
// After
|
|
className="text-xs font-semibold"
|
|
```
|
|
|
|
5. **Add focus states:**
|
|
```tsx
|
|
// Before
|
|
<button className="hover:bg-gray-100">Click</button>
|
|
|
|
// After
|
|
<button className="hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring/50">Click</button>
|
|
```
|
|
|
|
---
|
|
|
|
## Testing
|
|
|
|
### Visual Regression Testing
|
|
|
|
1. Take screenshots of all major screens
|
|
2. Compare before/after changes
|
|
3. Verify no broken layouts
|
|
4. Check responsive breakpoints
|
|
|
|
### Cross-Browser Testing
|
|
|
|
Test in:
|
|
- Chrome (latest)
|
|
- Firefox (latest)
|
|
- Safari (latest)
|
|
- Edge (latest)
|
|
|
|
### Accessibility Testing
|
|
|
|
Use tools:
|
|
- WAVE browser extension
|
|
- axe DevTools
|
|
- Screen reader testing (NVDA, VoiceOver)
|
|
- Keyboard navigation testing
|
|
|
|
### Mobile Testing
|
|
|
|
Test on:
|
|
- iOS Safari
|
|
- Chrome Android
|
|
- Responsive breakpoints (sm, md, lg, xl)
|
|
|
|
---
|
|
|
|
## Resources
|
|
|
|
- **Tailwind CSS Documentation:** https://tailwindcss.com/docs
|
|
- **WCAG 2.1 Guidelines:** https://www.w3.org/WAI/WCAG21/quickref/
|
|
- **Design Systems Best Practices:** https://www.designsystems.com/
|
|
- **Accessibility Testing:** https://www.deque.com/axe/
|
|
|
|
---
|
|
|
|
**Last Updated:** 2026-01-17
|
|
**Maintained By:** Development Team
|
|
**Status:** Active
|