docs(product): commit design references under docs/product/reference/

Copy the founder's design handoff bundle (.proto/design/) into
docs/product/reference/ byte-for-byte so dispatch agents running in git
worktrees can read the HTML prototypes, veect-codebase/ prototype,
upload PNGs, and remaining bundle files (ADR-029: reference only, never
vendored into packages/). Ignore-list entries so whole-codebase auditors
and formatters skip reference material: .prettierignore (byte
preservation through lint-staged), .fallowrc.json ignorePatterns, root
ESLint ignores, and the coverage:diff allowlist in
scripts/coverage/diff.mjs (+ unit test). .DS_Store files skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 14:09:30 +02:00
parent c80e09e732
commit 1483a45406
97 changed files with 15685 additions and 1 deletions

View File

@@ -0,0 +1,87 @@
# Veect — design-system-native canvas
> Full product & design specification: [`SPEC.md`](./SPEC.md)
A React 18 + TypeScript (strict) + Tailwind + shadcn-style codebase for the Veect MVP:
a canvas where a designer composes screens from **their own** tokens and components and
gets **real React** out — constrained AI, a Polish (Impeccable) craft pass, and honest code.
## Run
```bash
npm i
npm run dev # vite
npm run typecheck # tsc --noEmit
npm run lint # eslint
```
## Architecture — atomic design
```
src/
types/ Domain types (VeectNode, DesignSystem, Proposal, PolishIssue…)
config/ Library manifest + node glyphs + demo fiction (customer identity, imports, team)
engine/ Pure logic, no React: color math, tree ops, views (responsive variants),
codegen, parser (code→tree), tw utilities, polish rules, isolation specs,
upload intake, constrained-AI prompt + sanitizer
store/ zustand store (navigation, document + labelled restorable history, panels + tabs, chat)
hooks/ usePanelResize, useAiCompose (AI orchestration)
lib/ cn(), clamp(), truncate()
components/
ui/ shadcn-style primitives (Button, Input, Badge, Select, Panel) — cva + tailwind-merge
atoms/ Logo, MonoLabel, Swatch
molecules/ SegmentedControl, Stepper, ChatBubble, ChatComposer, LayerTree, LibraryList,
TokenEditor, PolishIssueCard, CollapseButton, ZoomControls
organisms/ ActivityBar, NodeRenderer, BoardCanvas, FrameNode, ChatPanel, BoardSidebar,
Inspector, PolishTab, IsolationView, CodePanel, ExportDialog, TopBar
templates/ EditorLayout (activity bar + resizable columns), PageShell
pages/ SignIn, Home, Onboarding, Editor, Settings, Profile, SystemUpdate
```
**Rules of the split**
- *Atoms* render one thing, take no store access.
- *Molecules* compose atoms, still store-free (props in, events out).
- *Organisms* own a slice of store state and one product concern.
- *Templates* own layout only. *Pages* wire organisms to a screen.
- `engine/` is framework-free and unit-testable; nothing in it imports React.
## Product invariants encoded here
- **One runtime** — `NodeRenderer` backs canvas *and* preview; codegen walks the same tree
(`engine/codegen.ts` is deterministic: same tree → same code).
- **The board is React Flow** (`@xyflow/react`, MIT) — frames are custom nodes with
`.frame-drag-handle` name tabs, so the DOM inside stays fully interactive. Scroll pans,
⌘/pinch zooms at the cursor, pane click deselects; the zustand tree remains the single
source of truth (React Flow carries only positions + viewport).
- **0 unregistered elements** — `engine/ai.ts` whitelist-sanitizes model output and refuses
anything outside the registry rather than failing open to generic markup.
- **Green is reserved** — the `LiveDot` atom is the only green in the chrome; success states
use neutral surfaces + accent check.
- **Craft is a pass, not a vibe** — `engine/polish.ts` holds the Impeccable-derived rules;
every issue carries a *why* and a one-click fix expressed in the user's tokens.
## Wiring the model
`engine/ai.ts#complete` expects a host-provided client (the prototype used one); point it
at your `/api/compose` endpoint in production. Everything else runs fully offline.
## Handoff notes — deliberate seams
- **Model bridge** — `engine/ai.ts#complete` throws without a host client; swap in your API.
- **Export zip** — `ExportDialog`'s "Download .zip" is presentational; wire it to a bundler
endpoint (the code it shows is real — `engine/codegen.ts`).
- **Placeholder projects** — `HomePage` lists two static placeholder cards; back with real data.
- **Auth** — `SignInPage` continues straight through; SSO buttons are visual.
- **Persistence** — the zustand store is in-memory; add storage middleware for real sessions.
- Theme default is dark (`index.html` `data-theme` + store); light is one toggle away.
## Prototype parity roadmap
Ported for parity with the prototype: **activity bar** (`ActivityBar` — toggleable icon
groups drive every panel; tabs live in the store), **responsive variants**
(`engine/views.ts` — one tree rendered at 13 widths per frame, view chips in Layers with
eye toggles, Desktop/Tablet/Mobile/All switcher in the top bar, cluster-shift on resize),
and the **ultra-minimal flat restyle** (paper/ink light default + carbon dark, 2px radii,
hairline borders instead of shadows — `index.css` + `tailwind.config.ts`).