A frontend implementation skill that enforces modularity, testability, and Storybook-first development for the Ambasdr React application. Every UI component must be renderable in isolation before it's wired to real data.
The /frontend-ui skill guides Claude through implementing frontend features using the Ambasdr architecture patterns. It enforces a strict separation between presentational components (pure UI) and container/page components (data + routing), ensuring every visual element can render in Storybook without backend dependencies.
Presentational components accept only props. Page/container components own all orchestration: API calls, navigation, toasts, validation.
Every component gets a story file immediately. Auth0 is globally mocked. Context-dependent components use mock providers.
Directory conventions, type splitting, service layer patterns, and context provider patterns are all codified.
Type /frontend-ui in Claude Code when starting frontend work, or ask Claude to "implement a new component" or "build the UI for this feature." The skill activates automatically when the task involves React component development.
Every UI feature has two layers that must be kept separate.
Pure UI that accepts props, renders markup, and calls callbacks. Zero knowledge of APIs, Auth0, routing, or context. This is what Storybook renders.
Orchestrates data fetching, context, routing, and wires presentational components together via props. Lives in pages/.
A component is "Storybook-ready" when it can render in complete isolation with only props and static mock data. No useApiClient(), useAuth0(), useNavigate(), or feature-specific context hooks in presentational components.
| Directory | Purpose |
|---|---|
components/ |
Presentational components organized by feature: ui/ (atoms), home/, onboarding/, dashboard/. |
pages/ |
Page-level containers (route entry points). The only place where context, routing, API calls, and business logic converge. |
context/ |
React Context providers. Export both the Context object and Provider component. Always export a guarded useXyz() hook. |
services/ |
API client functions. Pure functions that accept apiFetch as the first argument. Never import Auth0. |
types/ |
TypeScript interfaces split by concern: <feature>.ts for API types, <feature>-ui.ts for UI state types. |
stories/ |
Storybook stories mirroring components/ structure. Mock providers prefixed with _. |
__tests__/ |
Vitest test files for components, hooks, services, and context. |
The skill guides implementation in a specific order to ensure Storybook always works.
API types in types/<feature>.ts, UI-specific types in types/<feature>-ui.ts.
Small, reusable components in components/ui/ or components/<feature>/. All accept props only.
Shell and layout components that accept children/slots. Still presentational.
Every component gets a story file immediately. Include Default, Filled, and Interactive variants.
Connect to context, API, and routing in pages/. Pages are NOT rendered in Storybook.
API calls in services/ accepting apiFetch as the first parameter.
New feature context in context/, with a matching mock provider in stories/.
Auth0 is globally mocked via Vite alias in .storybook/main.ts. Do not add Auth0 mocking in individual stories.
Stories use satisfies Meta<typeof Component>. Use fn() from storybook/test for callback props.
Context-dependent components get a _Mock<Feature>Provider.tsx in the stories folder that wraps the real Context object.
Every story includes at minimum: Default (empty state), Filled (realistic data), and Interactive (with useState).
Story titles follow a strict convention:
Feature/Category/ComponentName
Home/Atoms/ChatInput
Onboarding/Page/NameStep
Dashboard/Tabs/ProfileTab
Dashboard/Page/DashboardPage
When given tightly-coupled UI code, the skill follows this process.
Look for useApiClient(), useAuth0(), useNavigate(), feature context hooks, and inline business logic in component files.
API data becomes data props. Mutations become callback props. Navigation becomes callback props. Loading/error state becomes boolean/string props.
Presentational component in components/ receives props. Page/container in pages/ provides data and handles side effects.
Story file in stories/. If the component uses context, create a mock provider. Add Default, Filled, and Interactive variants.
| Concern | Approach |
|---|---|
| CSS Framework | Tailwind CSS with custom design tokens defined in index.css. |
| Class Merging | Always use cn() from @/lib/utils (wraps clsx + tailwind-merge). |
| Typography | font-serif-headline for headings, font-body for body text, font-label for UI labels. |
| Colors | Use design token classes: text-primary, bg-surface, border-outline-variant. |
| Responsive | Tailwind breakpoints: sm:, md:. |
| Animations | Framer Motion for page transitions and micro-interactions. |
The skill lives at .claude/skills/frontend-ui/SKILL.md in the repository root. It is a single-file skill with no reference documents — the full architecture, patterns, and examples are contained in the SKILL.md itself.