14 KiB
| phase | slug | status | shadcn_initialized | preset | created |
|---|---|---|---|---|---|
| 41 | diagrams-icons-theme-engine | draft | true | new-york / neutral / cssVariables / lucide | 2026-04-04 |
Phase 41 — UI Design Contract
Visual and interaction contract for Phase 41: Diagrams, Icons & Theme Engine. Generated by gsd-ui-researcher. Verified by gsd-ui-checker.
Design System
| Property | Value | Source |
|---|---|---|
| Tool | shadcn | components.json detected |
| Style | new-york | components.json |
| Preset | neutral base color, cssVariables, radius=0 | ui/src/index.css |
| Component library | Radix UI (via shadcn) | components.json |
| Icon library | lucide-react | components.json |
| Font | System UI (inherited from body; no custom font loaded) | index.css |
Existing components available (no reinstall needed):
button, badge, breadcrumb, card, checkbox, collapsible, command, dialog, dropdown-menu, input, label, popover, scroll-area, select, separator, sheet, skeleton, tabs, textarea, tooltip
New shadcn components needed for Phase 41:
progress— job progress bar (SSE render progress)toggle— dark/light variant switcher in theme previewslider— color seed hue picker (optional; Input[type=color] is acceptable fallback)
Spacing Scale
Declared values (multiples of 4). Source: existing Tailwind scale in project.
| Token | Value | Usage |
|---|---|---|
| xs | 4px | Icon gaps, badge padding, inline chip gaps |
| sm | 8px | Compact element spacing, button icon gap |
| md | 16px | Default card padding, form field spacing |
| lg | 24px | Section padding, panel gaps |
| xl | 32px | Layout column gaps, page section breaks |
| 2xl | 48px | Major section breaks (e.g. diagram panel → source panel) |
| 3xl | 64px | Not used in Phase 41 |
Exceptions (Phase 41 specific):
- Touch targets on coarse-pointer devices:
min-height: 44pxon all interactive controls (already enforced by@media (pointer: coarse)rule in index.css — no new work needed). - Diagram preview container: no fixed height. Use
overflow-x: autowithwidth: max-content; min-width: 100%(matches.paperclip-mermaid svgpattern already in index.css). - Theme swatch grid: 8px gap between swatches, swatches 40×40px minimum.
- Color seed input: 48px height to meet touch targets on mobile.
Typography
Source: index.css .paperclip-markdown, button.tsx, existing component patterns.
| Role | Size | Weight | Line Height | Usage |
|---|---|---|---|---|
| Body | 15px (0.9375rem) | 400 (regular) | 1.6 | Diagram source editor, theme description text |
| Label | 14px (0.875rem) | 400 (regular) | 1.5 | Form labels, badge text, panel section titles |
| Heading | 20px (1.25rem) | 600 (semibold) | 1.3 | Panel titles ("Generate Diagram", "Theme Preview") |
| Display | 28px (1.75rem) | 600 (semibold) | 1.2 | Not used in Phase 41 |
Declared weights: 2 — 400 (regular) and 600 (semibold).
- 400 (regular): body text, labels, badge text, monospace code blocks.
- 600 (semibold): panel headings, dialog headings, section titles.
Monospace (code/source): ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace at 14px, weight 400, line-height 1.6. Used for the Mermaid source collapsible panel and palette export code blocks.
Color
Source: index.css CSS custom properties — Catppuccin Latte (light) + Catppuccin Mocha (dark).
| Role | Light value | Dark value | Usage |
|---|---|---|---|
| Dominant (60%) | #eff1f5 (--background) |
#1e1e2e (--background) |
Page background, diagram canvas background |
| Secondary (30%) | #e6e9ef (--card) |
#181825 (--card) |
Diagram panel card, theme preview panel, icon result card |
| Muted surface | #ccd0da (--secondary) |
#313244 (--secondary) |
Source code panel background, export format tabs, collapsible header |
| Accent (10%) | #bcc0cc (--accent) |
#45475a (--accent) |
Hover states on non-primary interactive elements |
| Primary | #1e66f5 (--primary) |
#89b4fa (--primary) |
See "Accent reserved for" below |
| Destructive | #d20f39 (--destructive) |
#f38ba8 (--destructive) |
Destructive actions only |
| Border | #ccd0da (--border) |
#313244 (--border) |
Panel edges, dividers, input outlines |
| Muted foreground | #9ca0b0 (--muted-foreground) |
#6c7086 (--muted-foreground) |
Helper text, secondary labels, status text |
Accent (--primary) reserved for:
- "Generate" / "Apply Theme" primary CTA buttons
- Job progress bar fill
- Active tab indicator in export format tabs
- Seed color ring/focus ring on color input
- WCAG PASS badges (green: use
--chart-2 #40a02blight /#a6e3a1dark) - WCAG FAIL badges (red: use
--destructive)
Theme Preview special case: The theme preview panel injects CSS custom properties dynamically from the generated palette. It must not inherit --primary from the app shell. Scope theme preview under a .nexus-theme-preview container class so injected tokens do not leak into nav/sidebar.
Component Inventory (Phase 41)
Diagram Panel
- DiagramGeneratePanel — Full-width card. Contains: prompt textarea (4 rows), diagram type selector (Select component, options: Architecture, Flowchart, ERD, Sequence, Mind Map), "Generate Diagram" Button (primary).
- DiagramPreview — Renders SVG output inside
.paperclip-mermaidcontainer (reuse existing CSS class). Shows status line ("Rendering…" / error) using.paperclip-mermaid-status/.paperclip-mermaid-status-errorclasses. Download buttons (SVG, PNG) appear below the preview as ghost buttons. - DiagramSourcePanel — Collapsible (shadcn
collapsible). Shows Mermaid source in monospace Textarea (read/write). "Copy source" IconButton at top-right. IconButton must carryaria-label="Copy source"andtitle="Copy source". - DiagramAttachToChatBadge — After successful render, a badge appears in the conversation thread: "Diagram attached — SVG + PNG". Reuse ChatTaskCreatedBadge visual pattern.
Icon Generation Panel
- IconGeneratePanel — Card with: description textarea (3 rows), style selector (Select, options: Outline, Filled, Rounded), count selector (Select: 1, 4, 8, 16), "Generate Icons" Button (primary).
- IconResultGrid — CSS grid, 4 columns on desktop / 2 on mobile. Each cell: white card, SVG preview centered, icon name label below (text-xs). Hover reveals download row (SVG, PNG 16, PNG 32, PNG 64) as a bottom sheet within the card.
- IconDownloadBar — Appears below grid when any icon is selected (checkbox on card corner). "Download selected (N)" Button (primary), format selector (Select: SVG, PNG 16, PNG 32, PNG 64).
Theme Engine Panel
- ThemeSeedInput — Color picker (
<input type="color">styled with ring) + hex text Input side-by-side. Label: "Seed color". Helper text: "We'll generate a full palette in OKLCH." - ThemeVariantToggle — Toggle group (light / dark), uses shadcn
Toggle. Default: dark. - ThemePaletteGrid — Displays generated swatches. Two rows: Light variant, Dark variant. Columns: Background, Surface, Overlay, Text, Accent-1, Accent-2, Accent-3. Each swatch: 40×40px minimum, hex label below (text-xs, monospace), WCAG badge (AA PASS / FAIL) inline.
- ThemePreviewPanel — Scoped under
.nexus-theme-preview. Renders a mini mock of Nexus UI (sidebar strip + one card) with injected CSS variables. "Apply to Nexus" Button (primary, full-width at panel bottom). - ThemeExportTabs — Tabs component. Tabs: CSS Variables, Tailwind Config, VS Code Theme, JSON. Each tab: pre/code block (monospace 14px), "Copy export" IconButton top-right. IconButton must carry
aria-label="Copy {tab name}"(e.g.aria-label="Copy CSS Variables") and a matchingtitleattribute. - ThemeApplyConfirmDialog — Dialog. Heading: "Apply theme?". Body: "This will update your Nexus color scheme. You can revert from Settings." Confirm: "Apply theme" (primary). Cancel: "Keep current" (ghost).
Interaction Contracts
Job Progress (shared pattern across all three generators)
- User submits prompt → Button shows spinner + label "Generating…" (disabled). Primary CTA label changes in-place; no separate loading overlay.
- SSE events arrive → Progress bar (shadcn
progress, primary fill) animates from 0→100%. Progress bar sits directly below the CTA button, full-width of the panel. - On
ready: progress bar disappears (fade out 200ms), result panel slides down (height animation 300ms ease-out). Button reverts to "Generate again" (secondary variant). - On
error: progress bar fills destructive color, error message appears below bar ("Render failed — {detail}. Try again."), Button reverts to "Generate Diagram" (primary, enabled). - Reconnect on SSE disconnect: silent reconnect, no user-facing error unless render ultimately fails.
Mermaid Source Collapsible
- Default state: collapsed.
- Trigger label: "View Mermaid source" (chevron right). Expanded: "Hide source" (chevron down).
- Height transition: 250ms ease.
- Textarea is editable. "Re-render diagram" Button (secondary, xs size) appears at bottom-right of expanded panel when source is modified.
- Security stripping is server-side. No client-side feedback needed beyond standard error state.
Theme Live Preview
- Preview updates on every palette recalculation (debounced 150ms after seed color change).
- No full-page refresh. CSS variables injected via JS into
.nexus-theme-previewscope only. - "Apply to Nexus" triggers ThemeApplyConfirmDialog before writing to settings.
- After apply: toast notification "Theme applied. Reload to see full effect." (not destructive; use default toast variant).
Icon Selection
- Checkbox appears on card hover (top-left corner, 16px). On coarse pointer: always visible.
- Multi-select: selecting any card shows the DiagramDownloadBar at the bottom of the panel (sticky, z-index above scroll content).
- Deselect all: "Clear selection" link in the sticky bar.
Copywriting Contract
| Element | Copy |
|---|---|
| Diagram CTA | "Generate Diagram" |
| Diagram generating state | "Generating…" |
| Diagram re-render CTA | "Re-render diagram" |
| Diagram download (SVG) | "Download SVG" |
| Diagram download (PNG) | "Download PNG" |
| Diagram source toggle (collapsed) | "View Mermaid source" |
| Diagram source toggle (expanded) | "Hide source" |
| Diagram attach confirmation | "Diagram attached — SVG + PNG" |
| Icon CTA | "Generate Icons" |
| Icon generating state | "Generating…" |
| Icon download (selected) | "Download selected ({N})" |
| Icon empty state heading | "No icons yet" |
| Icon empty state body | "Describe what you need and we'll generate a cohesive set." |
| Theme CTA | "Generate Palette" |
| Theme generating state | "Generating…" |
| Theme apply CTA | "Apply to Nexus" |
| Theme apply dialog heading | "Apply theme?" |
| Theme apply dialog body | "This will update your Nexus color scheme. You can revert from Settings." |
| Theme apply confirm | "Apply theme" |
| Theme apply cancel | "Keep current" |
| Theme applied toast | "Theme applied. Reload to see full effect." |
| WCAG pass badge | "AA" |
| WCAG fail badge | "Fails AA" |
| Export copy button (visible label) | "Copy {tab name}" (e.g. "Copy CSS Variables") |
| Export copy button (aria-label) | aria-label="Copy {tab name}" matching visible label |
| Export copied state | "Copied!" (reverts after 2s) |
| Diagram source copy button (aria-label) | aria-label="Copy source" |
| Generic render error | "Render failed — {detail}. Try again." |
| Mermaid security strip notice | "Unsafe directives were removed before rendering." (shown as muted helper text below diagram, only when stripping occurred) |
| Empty diagram state heading | "No diagram yet" |
| Empty diagram state body | "Describe an architecture, flow, or sequence and we'll render it." |
| Empty theme state heading | "No palette yet" |
| Empty theme state body | "Pick a seed color to generate a full OKLCH palette with dark and light variants." |
Destructive actions in Phase 41: None. "Apply theme" is reversible (can revert from Settings). Confirm dialog is informational, not destructive-red.
Registry Safety
| Registry | Blocks Used | Safety Gate |
|---|---|---|
| shadcn official | progress, toggle, slider (optional) |
not required |
No third-party registries declared for Phase 41.
Accessibility
- All color swatches must render WCAG AA badge computed at runtime — not decorative.
- Diagram SVG output passes DOMPurify before DOM insertion (server responsibility; client renders trusted output only).
- Color seed
<input type="color">must have an associated<label>withforbinding. - Icon grid checkboxes must have
aria-label="Select {icon name}". - Progress bar must use
role="progressbar"witharia-valuenow,aria-valuemin=0,aria-valuemax=100. - Theme preview panel:
aria-label="Theme preview"on the container,aria-live="polite"for palette update announcements. - DiagramSourcePanel "Copy source" IconButton:
aria-label="Copy source"andtitle="Copy source"required (no visible text label on the icon-only button). - ThemeExportTabs copy IconButton per tab:
aria-label="Copy {tab name}"andtitle="Copy {tab name}"required (e.g.aria-label="Copy CSS Variables"). - Keyboard: Tab order in ThemeExportTabs follows tab order; Copy button reachable via keyboard.
prefers-reduced-motion: disable height/slide animations for collapsible and result panel; keep progress bar (functional feedback).
Checker Sign-Off
- Dimension 1 Copywriting: PASS
- Dimension 2 Visuals: PASS
- Dimension 3 Color: PASS
- Dimension 4 Typography: PASS
- Dimension 5 Spacing: PASS
- Dimension 6 Registry Safety: PASS
Approval: pending