nexus/.planning/phases/41-diagrams-icons-theme-engine/41-UI-SPEC.md

14 KiB
Raw Blame History

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 preview
  • slider — 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: 44px on 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: auto with width: max-content; min-width: 100% (matches .paperclip-mermaid svg pattern 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:

  1. "Generate" / "Apply Theme" primary CTA buttons
  2. Job progress bar fill
  3. Active tab indicator in export format tabs
  4. Seed color ring/focus ring on color input
  5. WCAG PASS badges (green: use --chart-2 #40a02b light / #a6e3a1 dark)
  6. 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-mermaid container (reuse existing CSS class). Shows status line ("Rendering…" / error) using .paperclip-mermaid-status / .paperclip-mermaid-status-error classes. 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 carry aria-label="Copy source" and title="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 matching title attribute.
  • 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)

  1. User submits prompt → Button shows spinner + label "Generating…" (disabled). Primary CTA label changes in-place; no separate loading overlay.
  2. 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.
  3. On ready: progress bar disappears (fade out 200ms), result panel slides down (height animation 300ms ease-out). Button reverts to "Generate again" (secondary variant).
  4. On error: progress bar fills destructive color, error message appears below bar ("Render failed — {detail}. Try again."), Button reverts to "Generate Diagram" (primary, enabled).
  5. 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-preview scope 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> with for binding.
  • Icon grid checkboxes must have aria-label="Select {icon name}".
  • Progress bar must use role="progressbar" with aria-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" and title="Copy source" required (no visible text label on the icon-only button).
  • ThemeExportTabs copy IconButton per tab: aria-label="Copy {tab name}" and title="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