---
name: style-system
description: 'Use the style-system CLI for frontend or design work that needs approved Tailwind classes, theme tokens, shared UI components, app-specific components, Storybook component visuals, or design-system-aware component polish. Trigger before writing UI styles or creating UI components.'
metadata:
  paths:
    - 'apps/*-app/src/**/*.tsx'
    - 'apps/*-mcp-app/src/**/*.tsx'
    - 'packages/frontend/**/src/**/*.tsx'
    - 'packages/mcp/style-system/**'
---

# Style System

Use `pnpm exec style-system`, not MCP tools, for UI token, theme, component, and visual discovery. Run the relevant discovery command before creating new UI components or writing Tailwind classes.

## Commands

```bash
pnpm exec style-system get-css-classes --app-path apps/{product}-app --category all
pnpm exec style-system get-css-classes --theme-path ./packages/frontend/web-theme/dist/agiflow-theme.css --category colors

pnpm exec style-system list-shared-components
pnpm exec style-system list-shared-components --cursor <cursor>

pnpm exec style-system list-app-components --app-path apps/{product}-app
pnpm exec style-system list-app-components --app-path apps/{product}-app --cursor <cursor>

pnpm exec style-system list-themes --app-path apps/{product}-app

pnpm exec style-system get-ui-component --component-name Button --app-path apps/{product}-app --story-name Playground
pnpm exec style-system get-ui-component --component-name Button --app-path apps/{product}-app --story-name Default --dark-mode
```

## Workflow

- Before writing styles, run `get-css-classes` for the target app and use only supported token classes.
- Before creating a component, run `list-shared-components` and `list-app-components --app-path <app>` and reuse existing components when possible.
- Before visual design or Storybook work, run `list-themes --app-path <app>` and `get-ui-component` for the closest existing component.
- For component polish during implementation, `polish-component <file> --instructions "<text>"` is available, but it edits files and must not be used for read-only planning or review.

## React Native Story Composition

- Target presentational `View` components in stories. Do not render smart screens that call Expo Router, generated API hooks, stores, or native SDKs.
- Extract screen state into serializable View props and callbacks. Keep router calls in the smart wrapper and pass callbacks such as `onBack`, `onOpenTask`, or `onSignIn` to the View.
- Compose native-only content through props such as `renderHeader`, `renderLink`, `renderWidget`, or `renderEmptyState`. Stories provide deterministic web-safe React Native elements for those slots.
- Prefer callback composition over importing `Link`, `Redirect`, `Stack`, `Tabs`, or router hooks into a story target.

## Data-Heavy Surface Composition

Apply this pattern to every data-heavy frontend surface, including native screens, web pages, route content, dashboards, settings pages, detail pages, and feature panels.

- Split a monolithic surface into a **Container** and a presentational **View** before adding or repairing its story.
- Keep API hooks, query or store access, mutations, router calls, SDK calls, derived domain state, and side effects in the Container.
- Give the View serializable display props, event callbacks, and render slots for nested or platform-specific content. The View must be able to render from deterministic fixture data alone.
- Stories target the View and compose it with representative fixture data and web-safe slots. They never render Containers or mock the router, API client, store, or SDK.
- Preserve the production route/page as the Container boundary, or delegate it to a colocated Container. Do not duplicate business logic in stories or create a catalog-only approximation of the surface.
- For a large surface, first extract its meaningful sections into presentational components, then compose those sections in the View. Do not replace a data-heavy page with one giant `children` slot.
- Verify each new `Playground` story with `get-ui-component`, then inspect the returned image for visual hierarchy, empty and loading states, overflow, and action placement.

### Expo Router web support

When a presentation component must retain an Expo Router component, add a web implementation with the same exported component and props:

```text
Component/
├── View.tsx
├── View.web.tsx
└── View.stories.tsx
```

- Keep `View.tsx` as the native implementation.
- In `View.web.tsx`, replace Expo Router navigation elements with web-safe React Native composition, normally `Pressable`, `Text`, and injected navigation callbacks.
- Keep props identical across native and web files so Metro and the style-system Vite renderer select the platform implementation without story-specific branching.
- Never mock `expo-router` inside a story file. Use composition or a `.web.tsx` adapter.
- Apply the same platform adapter pattern to native-only SDK components that cannot be bundled for web.
- Run `get-ui-component` for every added `Playground` story. A typecheck-only result is insufficient for router or native SDK composition.

## Rules

- Prefer `--app-path` so the CLI reads the project's `style-system.config.yaml`.
- Use `--theme-path` only when there is no target app path or the app config does not define a theme path.
- Treat CLI output as the allowed design surface: do not invent Tailwind token classes when the CLI can list them.
- If `pnpm exec style-system` is unavailable after dependency changes, run `pnpm install` and `pnpm nx build style-system`.
