diff --git a/.claude/skills/sidebar-nav-redesign/SKILL.md b/.claude/skills/sidebar-nav-redesign/SKILL.md new file mode 100644 index 000000000..9cf9aa588 --- /dev/null +++ b/.claude/skills/sidebar-nav-redesign/SKILL.md @@ -0,0 +1,57 @@ +--- +name: sidebar-nav-redesign +description: Use this skill when redesigning a Vue 3 app's navigation into a modern SaaS-style left sidebar layout, replacing a top nav bar, introducing CSS design tokens, or making an app's chrome (nav, header, sticky bars, profile menu) more consistent and professional-looking. +--- + +# Sidebar Nav Redesign + +Turns a Vue 3 app's top-nav chrome into a modern SaaS-style left sidebar: collapsible, icon-led, with consistent spacing via extracted design tokens. This skill is a **procedure**, not a code generator — it never edits `.vue` files itself. It discovers the app's current chrome, designs the token/sidebar spec, then hands the actual file writes off to a Vue-capable agent (this repo's `vue-expert` subagent, if invoked from here; otherwise whatever frontend-editing agent/tool the host project designates). + +Read the reference files as you reach each phase — don't front-load all of them. + +## Phase 0 — Scope check + +Confirm the target is a Vue 3 SPA: find `package.json` with a `vue` dependency, and a router (`vue-router` or a hand-rolled route table). If it isn't Vue 3, stop and say so — this skill assumes Single File Components and doesn't care whether they use the Options or Composition API. + +## Phase 1 — Discover current chrome architecture + +Read `references/discovery.md` and apply its heuristics to find: the shell/root component, the nav markup inside it, any companion pieces coupled to nav height/position (sticky bars, dropdowns), and the authoritative route list — then cross-check that list against existing nav links and i18n keys to catch gaps (a view that exists but has no nav entry, a nav label with no translation key, etc.). + +## Phase 2 — Design tokens + +Read `references/design-tokens.md`. **Extract, don't invent**: pull the app's existing hardcoded colors/spacing/radii into a `:root` CSS custom-property block so the redesign preserves the app's brand feel instead of replacing it wholesale. + +## Phase 3 — Sidebar anatomy + +Read `references/sidebar-anatomy.md`. Fixed structural slots: brand/logo top, nav item list (icon + label + active-state, icon-only when collapsed), a collapse/expand toggle, and a footer slot for the profile/account menu. Reuse whatever icon approach the app already has; never add a new icon dependency without asking the user first. + +## Phase 4 — Responsive / mobile spec + +Also in `references/sidebar-anatomy.md`. Desktop keeps the sidebar always visible (collapsible to an icon-only rail); below ~768px (or the app's existing breakpoint) it becomes an off-canvas drawer triggered by a slim top bar with a hamburger toggle. + +## Phase 5 — Migrate companion pieces + +Using Phase 1's findings: recalculate or remove any sticky/fixed offset that was hardcoded against the old nav's height; flip any dropdown that assumed a top-right, downward-opening position (a footer-anchored menu opens upward instead); fix the nav-link/i18n gaps found in Phase 1 in this same pass, not later. + +## Phase 6 — Handoff + +Do not write `.vue`, `.js`, or CSS files yourself. Compose one scoped delegation prompt containing: +- The concrete file list from Phase 1 +- The exact token names/values from Phase 2 +- The anatomy + responsive acceptance criteria from Phases 3–4 +- The specific gaps to fix from Phase 5 +- An explicit instruction: presentation-layer only, no changes to API calls, data logic, or business logic + +Then delegate to the project's designated Vue-editing agent (in this repo, that's `vue-expert` — mandatory per this repo's root `CLAUDE.md`). + +## Phase 7 — Verify + +Start the dev server and drive the app in a browser (Playwright MCP in this repo, against `localhost:3000`): confirm the sidebar renders, active-route highlighting works, the collapse toggle works, the profile menu opens without clipping off-screen, the mobile drawer opens/closes at the breakpoint, and there are no new console errors. + +## Common pitfalls + +Read `references/pitfalls.md` before finishing — it's a short generalized do/don't list (sticky-offset coupling, dropdown-direction assumptions, nav/i18n parity drift, inventing tokens instead of extracting them) worth checking your output against regardless of which app you're redesigning. + +## Templates + +`templates/sidebar.vue.template` and `templates/tokens.css.template` are annotated skeletons, not copy-paste-ready components — adapt class names, exact values, and slot content to the target app before handing them to the editing agent. diff --git a/.claude/skills/sidebar-nav-redesign/references/design-tokens.md b/.claude/skills/sidebar-nav-redesign/references/design-tokens.md new file mode 100644 index 000000000..3b31f0173 --- /dev/null +++ b/.claude/skills/sidebar-nav-redesign/references/design-tokens.md @@ -0,0 +1,61 @@ +# Design tokens: extract, don't invent + +The fastest way to make a redesign feel disconnected from the app it came from is to replace its existing colors and spacing with a generic new palette. Instead, mine the app's current hardcoded values and formalize them into CSS custom properties. The redesign should feel like the same app, tidied up — not a different app wearing the old app's logo. + +## Method + +1. Grep the shell component and 2–3 representative components/views for hex colors, `rem`/`px`/`em` spacing values, and `border-radius` values: + ``` + grep -rno "#[0-9a-fA-F]\{3,6\}" src/ | sort | uniq -c | sort -rn + grep -rno "[0-9.]\+rem\|[0-9]\+px" src/ | sort | uniq -c | sort -rn + ``` +2. Cluster near-duplicates (`#2563eb` and `#2563EB` are the same color; `1.5rem` appearing 40 times is a real spacing unit, `1.37rem` appearing once probably isn't). +3. Name the survivors as tokens by **role**, not by raw value — a future edit to "the primary color" shouldn't require renaming a variable called `--blue-600`. + +## Minimal token set to always produce + +**Spacing scale** — a 4px or 8px multiple ladder, however many steps the app's actual usage supports (don't invent 10 steps if the app only really uses 4 distinct spacing values): +```css +--space-1: 0.25rem; +--space-2: 0.5rem; +--space-3: 0.75rem; +--space-4: 1rem; +--space-5: 1.5rem; +--space-6: 2rem; +``` + +**Color roles:** +```css +--color-bg: ...; /* page background */ +--color-surface: ...; /* card/panel background */ +--color-border: ...; /* dividers, card borders */ +--color-text: ...; /* primary text */ +--color-text-muted: ...; /* secondary/caption text */ +--color-primary: ...; /* brand/action color */ +--color-primary-hover: ...; +--color-accent: ...; /* if the app has a secondary brand color */ +``` +If the app has status colors (success/warning/danger badges, etc.), extract those too as `--color-success`, `--color-warning`, `--color-danger` — don't leave them as scattered literals. + +**Radius scale:** +```css +--radius-sm: ...; +--radius-md: ...; +--radius-lg: ...; +``` + +**Shadow tokens** (only if the app already uses box-shadow anywhere): +```css +--shadow-sm: ...; +--shadow-md: ...; +``` + +## Where to put the block + +Put the `:root { }` block in whichever file already holds global unscoped styles — usually the shell component's ` diff --git a/.claude/skills/sidebar-nav-redesign/templates/tokens.css.template b/.claude/skills/sidebar-nav-redesign/templates/tokens.css.template new file mode 100644 index 000000000..c5b940bf1 --- /dev/null +++ b/.claude/skills/sidebar-nav-redesign/templates/tokens.css.template @@ -0,0 +1,45 @@ +/* + Skeleton design-token block. Not copy-paste-ready. + Replace every placeholder with a value EXTRACTED from the target app + (see references/design-tokens.md) — don't invent new brand colors. + Delete any category the app doesn't use (e.g. no shadows if it never + uses box-shadow today). +*/ + +:root { + /* Spacing scale — only as many steps as the app's real usage supports */ + --space-1: 0.25rem; + --space-2: 0.5rem; + --space-3: 0.75rem; + --space-4: 1rem; + --space-5: 1.5rem; + --space-6: 2rem; + + /* Color roles — replace with extracted hex values */ + --color-bg: #REPLACE; + --color-surface: #REPLACE; + --color-border: #REPLACE; + --color-text: #REPLACE; + --color-text-muted: #REPLACE; + --color-primary: #REPLACE; + --color-primary-hover: #REPLACE; + + /* Status colors — only if the app has badges/alerts today */ + --color-success: #REPLACE; + --color-warning: #REPLACE; + --color-danger: #REPLACE; + + /* Radius scale */ + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + + /* Shadows — only if the app already uses box-shadow */ + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08); + + /* Sidebar-specific dimensions */ + --sidebar-width-expanded: 240px; + --sidebar-width-collapsed: 72px; + --sidebar-breakpoint: 768px; /* match app's existing breakpoint if one exists */ +} diff --git a/CLAUDE.md b/CLAUDE.md index 89c307d15..a2336bd0d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,7 @@ # CLAUDE.md +# Always document non-obvious logic changes with comments + Factory Inventory Management System Demo with GitHub integration - Full-stack application with Vue 3 frontend, Python FastAPI backend, and in-memory mock data (no database). > ⚠️ **This repository and any fork you create are PUBLIC.** Do not commit credentials, internal hostnames, or private registry URLs. `client/.npmrc` pins the public npm registry and `client/package-lock.json` is gitignored to prevent locally-configured registries from leaking into commits — leave both in place. @@ -18,6 +20,7 @@ Use the Task tool with these specialized subagents for appropriate tasks: ### Skills - **backend-api-test** skill: Use when writing or modifying tests in `tests/backend` directory with pytest and FastAPI TestClient +- **sidebar-nav-redesign** skill: Use when redesigning app navigation into a left sidebar layout, introducing CSS design tokens, or modernizing the UI chrome (nav, header, profile menu) ### MCP Tools - **ALWAYS use GitHub MCP tools** (`mcp__github__*`) for ALL GitHub operations diff --git a/client/src/App.vue b/client/src/App.vue index c2da05a5c..ed7b54ce1 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,42 +1,113 @@