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