banatie-service/docs/labs/design-system.md

365 lines
9.3 KiB
Markdown

# Lab Section Design System
The Lab section is a production-ready UI interface for interacting with the Banatie API service. It provides a clean, work-focused experience for image generation, gallery browsing, alias management, and flow control.
## File Structure
```
apps/landing/src/
├── app/(lab)/
│ ├── CLAUDE.md # This design documentation
│ ├── layout.tsx # Root lab layout with scroll context
│ └── lab/
│ ├── layout.tsx # Sub-layout with PageProvider
│ ├── page.tsx # Redirect to /lab/generate
│ ├── generate/page.tsx # Generation workbench
│ ├── images/page.tsx # Image gallery browser
│ ├── live/page.tsx # Live generation testing
│ └── upload/page.tsx # File upload interface
├── components/layout/lab/
│ ├── LabLayout.tsx # Main layout (sidebar + content + footer)
│ ├── LabSidebar.tsx # Left filter panel
│ └── LabFooter.tsx # Contextual footer with links
├── components/lab/
│ ├── GenerateFormPlaceholder.tsx # Generation form component
│ └── FilterPlaceholder.tsx # Reusable filter checkbox/radio
└── contexts/
└── lab-scroll-context.tsx # Scroll state for header collapse
```
## Design Principles
1. **Work-focused, not marketing** - Small typography, efficient spacing
2. **Clean and functional** - Like Google AI Studio
3. **Dual color system** - Zinc for layout, Slate for forms
4. **Consistent icons** - Lucide React only, no emojis
5. **Responsive** - Works on 768px to 1920px+ screens
---
## Color System
### Layout/Chrome → Zinc (Neutral Gray)
Used for sidebar, footer, and layout borders:
```css
bg-zinc-950 /* Sidebar background */
bg-zinc-950/50 /* Footer background, layout wrappers */
border-zinc-800 /* Layout borders, dividers */
text-zinc-400 /* Sidebar text */
text-zinc-500 /* Footer text, muted */
```
### Forms/Cards → Slate (Original Style)
Used for cards, inputs, and interactive UI elements:
```css
bg-slate-900/80 /* Card backgrounds */
bg-slate-900/50 /* Empty states, lighter cards */
bg-slate-800 /* Input backgrounds, secondary surfaces */
border-slate-700 /* Card borders, input borders */
text-gray-400 /* Labels, secondary text */
text-gray-500 /* Placeholders, hints */
```
### Accent Colors (Purple/Cyan)
```css
/* Primary gradient */
bg-gradient-to-r from-purple-600 to-cyan-600
hover:from-purple-500 hover:to-cyan-500
shadow-lg shadow-purple-900/30
focus:ring-2 focus:ring-purple-500
/* Single-color accents */
text-purple-400 /* Links, interactive text */
/* Info banners */
bg-purple-900/10 border-purple-700/50
```
### Status Colors
```css
/* Success */ bg-emerald-500/10 border-emerald-500/30 text-emerald-400
/* Warning */ bg-amber-500/10 border-amber-500/30 text-amber-400
/* Error */ bg-red-500/10 border-red-500/30 text-red-400
/* Info */ bg-purple-900/10 border-purple-700/50 text-purple-400
```
---
## Typography Scale
### Headings (Practical Sizes)
```tsx
// Page Title (only on main pages)
text-lg font-semibold text-white
// Section Title
text-base font-semibold text-white
// Card Title
text-sm font-medium text-white
```
### Body Text
```tsx
// Primary body
text-sm text-gray-300
// Secondary/descriptions
text-sm text-gray-400
// Small text (hints, metadata)
text-xs text-gray-500
// Labels (form fields)
text-xs font-medium text-gray-400
```
### Interactive
```tsx
// Button text
text-sm font-semibold
// Links
text-sm text-purple-400 hover:text-purple-300
// Badge/count
text-xs text-gray-600
```
---
## Spacing System
### Padding
```tsx
// Cards
p-4 md:p-5
// Compact cards
p-3
// Form inputs
px-3 py-2
// Buttons (primary)
px-4 py-2.5
// Buttons (secondary)
px-3 py-2
```
### Section Spacing
```tsx
// Page padding
p-4 md:p-6
// Between sections
space-y-4
// Between cards in grid
gap-3 md:gap-4
// Between form fields
gap-2
// Label to input
mb-1.5
```
### Border Radius
```tsx
rounded-lg /* Standard (inputs, small cards) */
rounded-xl /* Medium (cards) */
```
---
## Component Patterns
### Page Header
```tsx
<header className="pb-3 border-b border-zinc-800">
<div className="flex items-center gap-2">
<Sparkles className="w-5 h-5 text-purple-400" />
<div>
<h1 className="text-lg font-semibold text-white">Generate</h1>
<p className="text-xs text-gray-400">Create AI images from text prompts</p>
</div>
</div>
</header>
```
### Form Card (Slate)
```tsx
<section className="p-4 bg-slate-900/80 backdrop-blur-sm border border-slate-700 rounded-xl">
{/* content */}
</section>
```
### Form Input (Slate)
```tsx
<div className="space-y-1.5">
<label className="block text-xs font-medium text-gray-400">Field Label</label>
<input
className="w-full px-3 py-2 text-sm bg-slate-800 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
placeholder="Enter value..."
/>
</div>
```
### Textarea (Slate)
```tsx
<textarea
className="w-full px-3 py-2.5 text-sm bg-slate-800 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent resize-none"
rows={4}
/>
```
### Primary Button
```tsx
<button className="px-4 py-2 text-sm rounded-lg bg-gradient-to-r from-purple-600 to-cyan-600 text-white font-semibold hover:from-purple-500 hover:to-cyan-500 transition-all shadow-lg shadow-purple-900/30 focus:ring-2 focus:ring-purple-500 flex items-center gap-1.5">
<Sparkles className="w-4 h-4" />
Generate
</button>
```
### Secondary Button (Slate)
```tsx
<button className="w-full px-3 py-2 text-sm bg-slate-800 border border-slate-700 rounded-lg text-gray-400 hover:text-white hover:bg-slate-700 transition-colors flex items-center justify-center gap-1.5 focus:ring-2 focus:ring-purple-500">
<Settings className="w-4 h-4" />
Configure
</button>
```
### Empty State (Slate)
```tsx
<div className="p-6 bg-slate-900/50 backdrop-blur-sm border border-slate-700 rounded-lg text-center">
<div className="w-12 h-12 mx-auto mb-3 flex items-center justify-center bg-slate-800 rounded-lg">
<ImageOff className="w-6 h-6 text-gray-500" />
</div>
<h3 className="text-sm font-medium text-white mb-1">No results yet</h3>
<p className="text-xs text-gray-400">Generated images will appear here</p>
</div>
```
### Info Banner
```tsx
<div className="p-3 bg-purple-900/10 border border-purple-700/50 rounded-lg">
<div className="flex items-start gap-2">
<Info className="w-4 h-4 text-purple-400 mt-0.5 shrink-0" />
<p className="text-xs text-gray-300">
<span className="font-medium text-white">Lab Mode:</span> Experimental features enabled.
</p>
</div>
</div>
```
---
## Icon System (Lucide React)
### Standard Sizes
```tsx
// Inline with text
<Icon className="w-4 h-4" />
// Small (badges)
<Icon className="w-3 h-3" />
// Medium (empty states)
<Icon className="w-6 h-6" />
// With margin (before text)
<Icon className="w-4 h-4 mr-1.5" />
```
### Recommended Icons
```tsx
// Navigation
import { Home, Image, Upload, Zap, Settings } from 'lucide-react';
// Actions
import { Plus, X, Download, Share2, Copy, Trash2, Edit3, MoreVertical } from 'lucide-react';
// Filters
import { Activity, Calendar, Palette, ChevronRight, ChevronDown } from 'lucide-react';
// Status
import { CheckCircle2, AlertCircle, XCircle, Info, Loader2 } from 'lucide-react';
// Media
import { ImageOff, FileImage, Sparkles } from 'lucide-react';
// Form
import { Search, Filter, SlidersHorizontal } from 'lucide-react';
```
---
## Responsive Breakpoints
```tsx
// Base: < 768px (mobile) - single column, no sidebar
// md: >= 768px (tablet) - 2 columns, no sidebar
// lg: >= 1024px (desktop) - sidebar visible, 2-3 columns
// xl: >= 1280px (large desktop) - optimal spacing, 3 columns
```
### Sidebar Behavior
```tsx
// Hidden on mobile/tablet, visible lg+
hidden lg:block w-64
```
### Content Grid
```tsx
// Images: 1 col mobile, 2 col tablet, 3 col desktop
grid-cols-1 md:grid-cols-2 xl:grid-cols-3
// Form fields
grid-cols-1 md:grid-cols-3
```
---
## Do's and Don'ts
### DO
- Use **zinc** for layout (sidebar, footer, layout borders)
- Use **slate** for forms (cards, inputs, empty states)
- Use text-sm/text-xs for most text
- Use Lucide icons exclusively
- Keep spacing tight (p-3 to p-5)
- Add focus:ring-2 focus:ring-purple-500 to all interactive elements
- Use transitions (transition-colors, transition-all)
### DON'T
- Use emojis anywhere in the UI
- Use marketing-size headings (text-3xl+)
- Use generous spacing (p-8+, py-12+)
- Mix zinc and slate inconsistently
- Forget aria-label on icon-only buttons
---
## Layout Architecture
The Lab uses a scroll-aware header system:
1. **LabScrollProvider** wraps the entire section
2. **LabLayout** detects scroll > 50px in content area
3. When scrolled, header collapses (h-16 → h-0)
4. SubsectionNav becomes the top element
5. Content height adjusts: `h-[calc(100vh-7rem)]``h-[calc(100vh-3rem)]`
```tsx
// Layout hierarchy
(lab)/layout.tsx LabScrollProvider + LabHeader
└── lab/layout.tsx PageProvider (SubsectionNav)
└── LabLayout.tsx ThreeColumnLayout (sidebar + content + footer)
└── page.tsx Actual page content
```