# SDC-Frontend Project Setup Plan ## Context The existing Research Synthesiser at `../SDC-Synthesiser/` is a vanilla HTML/CSS/JS app. This new project creates a React-based design system and component library that will eventually become the full frontend replacement. The design system is driven by Penpot (self-hosted at `192.168.50.211:9001`) via MCP, with Storybook for component development and documentation. The project carries forward the same working principles (plan before building, evaluate before committing, ask don't assume, architecture governance) and the existing design tokens from the synthesiser's CSS. --- ## Tech Stack | Tool | Version | Notes | |---|---|---| | React | 19.x | Function components, hooks only | | Vite | latest | Dev server + build | | TypeScript | strict | All components have typed props | | Tailwind CSS | v4.3+ | CSS-first `@theme` config — no JS config file | | Storybook | 10.x | Component dev, docs, MCP addon | | ESLint + Prettier | latest | With `prettier-plugin-tailwindcss` for class sorting | | clsx + tailwind-merge | latest | Combined as `cn()` utility | --- ## Steps ### 1. Scaffold Vite project ```bash cd /home/richie/Nextcloud/Projects/Coding/ npm create vite@latest SDC-Frontend -- --template react-ts cd SDC-Frontend npm install ``` ### 2. Install Tailwind CSS v4 ```bash npm install tailwindcss @tailwindcss/vite ``` Update `vite.config.ts` to add the Tailwind plugin alongside React. ### 3. Create design tokens and global styles - `src/tokens/tokens.css` — `@theme` block with all design tokens ported from the synthesiser's CSS variables - `src/styles/global.css` — imports Tailwind and tokens, sets base typography - Update `src/main.tsx` to import `global.css` - Delete Vite boilerplate (`App.css`, default `App.tsx` content, `src/assets/react.svg`) ### 4. Install utility dependencies ```bash npm install clsx tailwind-merge ``` Create `src/lib/utils.ts` with `cn()` helper. ### 5. Configure path alias Set up `@/` → `src/` in both `tsconfig.app.json` and `vite.config.ts` for clean imports. ### 6. Install and configure Storybook 10 ```bash npx storybook@latest init npm install @storybook/addon-mcp ``` - Update `.storybook/main.ts` to add MCP addon - Update `.storybook/preview.ts` to import `global.css` (so Tailwind works in stories) ### 7. Install and configure ESLint + Prettier ```bash npm install -D prettier prettier-plugin-tailwindcss eslint-config-prettier ``` - Create `.prettierrc` with Tailwind plugin - Update ESLint config to extend `prettier` ### 8. Create initial Button component Validates the full pipeline: tokens → Tailwind → TypeScript → Storybook. - `src/components/ui/Button/Button.tsx` — primary/secondary/danger variants, sm/md/lg sizes - `src/components/ui/Button/Button.stories.tsx` — stories for each variant + disabled state - `src/components/ui/Button/index.ts` — barrel export ### 9. Write CLAUDE.md Carry over the five working principles from SDC-Synthesiser, adapted for React/TS/Tailwind/Storybook. Add: - Component conventions (folder structure, typed props, forwardRef, stories required) - Design token rules (single source of truth in `tokens.css`, never hardcode) - Styling rules (Tailwind utilities via `cn()`, no inline styles, no CSS modules) - Accessibility requirements (semantic HTML, keyboard nav, ARIA) - MCP integrations (Penpot, Storybook) - Reference to existing synthesiser ### 10. Write initial ARCHITECTURE.md Lightweight living document covering: - Token pipeline (Penpot → tokens.css → Tailwind → components) - Component taxonomy (ui/composite/layout) - Styling approach - Storybook conventions ### 11. Create .claude/settings.json **MCP servers:** - `storybook` — `http://localhost:6006/mcp` (available when Storybook is running) - `penpot` — `http://localhost:4401/mcp` (Penpot MCP server, runs via `npx @penpot/mcp@stable`) Note: The Penpot UI is at `http://192.168.50.211:9001/`. The MCP server runs locally on the dev machine and connects to Penpot via the browser plugin. **Permissions:** Pre-allow npm scripts, TypeScript checks, git operations, WebSearch, and WebFetch for documentation domains. ### 12. Create plans/ directory Add this plan as the first entry. ### 13. Git init + initial commit - `git init` - Verify `.gitignore` covers `node_modules/`, `dist/`, `storybook-static/`, `.claude/settings.local.json` - Stage all files, commit with descriptive message - User provides Gitea remote URL to push ### 14. Verify end-to-end 1. `npm run dev` — Vite serves without errors 2. `npm run storybook` — Storybook loads, Button stories render with correct token colours 3. `npx tsc --noEmit` — TypeScript compiles clean 4. `npm run build` — produces `dist/` output 5. Storybook Controls work interactively on Button 6. Autodocs generate for Button --- ## Files created/modified | File | Purpose | |---|---| | `vite.config.ts` | Add Tailwind plugin + path alias | | `tsconfig.app.json` | Add `@/` path alias | | `src/tokens/tokens.css` | Design tokens as `@theme` block | | `src/styles/global.css` | Tailwind imports + base styles | | `src/main.tsx` | Updated import path | | `src/App.tsx` | Cleaned boilerplate | | `src/lib/utils.ts` | `cn()` utility | | `src/components/ui/Button/Button.tsx` | First component | | `src/components/ui/Button/Button.stories.tsx` | First stories | | `src/components/ui/Button/index.ts` | Barrel export | | `.storybook/main.ts` | MCP addon added | | `.storybook/preview.ts` | Global CSS import | | `.prettierrc` | Tailwind class sorting | | `CLAUDE.md` | Project principles + conventions | | `ARCHITECTURE.md` | Living architecture doc | | `.claude/settings.json` | MCP servers + permissions | | `plans/project-setup.md` | This plan | --- ## Penpot MCP Setup (user action required) After the project is scaffolded, the user needs to: 1. Install the Penpot MCP plugin inside their Penpot instance at `192.168.50.211:9001` 2. Run `npx @penpot/mcp@stable` on their dev machine 3. Open Penpot in the browser with the MCP plugin active 4. Claude Code can then use the `penpot` MCP tools --- ## Open items - **Gitea remote URL** — user will provide when ready to push - **Penpot MCP plugin installation** — user needs to install in their Penpot instance