doc: collect Banatie Lab documentation in docs/labs
- extract Lab design system from feature/lab-frontend branch - move legacy workbench and expanded-image-view docs from apps/landing - add overview README with planned pages, API scope, and design direction Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
369a306324
commit
00ef8b969d
|
|
@ -0,0 +1,48 @@
|
|||
# Banatie Lab
|
||||
|
||||
Banatie Lab is the browser UI for working with the Banatie API: generating images, browsing the gallery of created images, managing prompts, aliases, and flows. It is referenced on the landing page as "Web Lab".
|
||||
|
||||
The Lab will be built **from scratch**. This folder collects everything that was previously designed or documented, so the ideas are not lost.
|
||||
|
||||
## Documents in this folder
|
||||
|
||||
| Document | Origin | Purpose |
|
||||
|----------|--------|---------|
|
||||
| [design-system.md](design-system.md) | `feature/lab-design` / `feature/lab-frontend` branches (`apps/landing/src/app/(lab)/CLAUDE.md`) | Full design system and layout architecture for the Lab UI |
|
||||
| [legacy-workbench.md](legacy-workbench.md) | `apps/landing/WORKBENCH_DOCUMENTATION.md` (main) | Text-to-Image workbench — predecessor of the Generate page (MinimizedApiKey badge, PromptReuseButton) |
|
||||
| [legacy-expanded-image-view.md](legacy-expanded-image-view.md) | `apps/landing/src/components/shared/EXPANDED_IMAGE_VIEW.md` (main) | Full-size image modal with metadata — building block for the gallery |
|
||||
|
||||
## Planned feature set (from design-system.md)
|
||||
|
||||
Pages that were planned in the abandoned `feature/lab-*` branches:
|
||||
|
||||
- `/lab/generate` — generation workbench (prompt, references, parameters)
|
||||
- `/lab/images` — gallery of generated images with filters
|
||||
- `/lab/live` — live URL / prompt-URL testing
|
||||
- `/lab/upload` — file upload interface
|
||||
|
||||
Additional concepts mentioned in the design doc: alias management and flow control.
|
||||
|
||||
## API capabilities the UI must expose
|
||||
|
||||
The functional scope is defined by the existing API documentation:
|
||||
|
||||
- [../api/image-generation.md](../api/image-generation.md) — basic generation
|
||||
- [../api/image-generation-advanced.md](../api/image-generation-advanced.md) — reference images, aliases (`@hero`), flows, flow-scoped aliases (`@best`), dynamic aliases (`@last`, `@first`, `@upload`), regeneration
|
||||
- [../api/live-url.md](../api/live-url.md) — CDN architecture, live URLs (`/live/{scope}?prompt=...`), prompt-based caching
|
||||
- [../api/images-upload.md](../api/images-upload.md) — uploads
|
||||
- [../api/admin.md](../api/admin.md) — API key management
|
||||
|
||||
## Design direction (summary)
|
||||
|
||||
- Work-focused tool, not marketing — compact typography, tight spacing, like Google AI Studio
|
||||
- Dual color system: zinc for layout chrome, slate for forms/cards; purple→cyan accent gradient
|
||||
- Lucide React icons only, no emojis
|
||||
- Scroll-aware collapsing header, left filter sidebar, contextual footer
|
||||
- Responsive 768px–1920px+
|
||||
|
||||
See [design-system.md](design-system.md) for the complete spec.
|
||||
|
||||
## What does NOT exist
|
||||
|
||||
There is no PRD with a detailed feature list (gallery filters, prompt list, flow list behavior). The pages above plus the API docs are the only recorded ideas. A proper PRD should be written here before implementation starts.
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
# 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
|
||||
```
|
||||
Loading…
Reference in New Issue