---
description: Frontend conventions -- React, routing, state, styling, testing, pages
paths:
  - ui/src/**
---
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
<!-- Regenerate: pnpm scaffold:sync -->


# Frontend

## Safety Invariants

- `ElevasisUIProvider` in `ui/src/main.tsx` auto-composes shared UI, auth, and API surface -- route files do not wire providers manually
- `useApiClient()` from `@/lib/hooks/useApiClient` for authenticated API calls -- never raw `fetch` with auth headers
- `routeTree.gen.ts` is auto-generated on `pnpm dev` -- never edit manually
- Auth protection: wrap page content with `ProtectedRoute` from `@elevasis/ui/auth`. Admin pages nest `AdminGuard` inside `ProtectedRoute`
- Never fork `@elevasis/ui` components -- if a published component needs a tweak, that missing capability is a bug in `@elevasis/ui`

## Silent-Break Gotchas

- Route files vs layout files: `operations.tsx` is a layout (renders `<Outlet />`), `operations/my-page.index.tsx` is a page. Confusing the two breaks routing silently
- `core/` cannot import React or `@elevasis/sdk/worker` -- it is runtime-agnostic shared types and organization configuration only
- `@/*` resolves to `ui/src/*`, `@core/*` resolves to `core/*` -- never import from `operations/` (separate runtime)

## Stack Constraints

- Mantine 8.2.7 for all UI components -- no Radix UI, no Tailwind CSS, no shadcn
- `@tabler/icons-react` for icons -- never Lucide
- Server state: TanStack Query. Client state: Zustand + Immer. Never mix the two
- Glass background is the primary surface treatment: `var(--glass-background)` with `backdrop-filter: var(--glass-blur)`
- Import shared components from `@elevasis/ui/components`, `@elevasis/ui/layout`, `@elevasis/ui/charts`
- Import charts from `@elevasis/ui/charts`, not directly from `@mantine/charts`

## Integration UI Surfaces

When building pages that display external data, use published `@elevasis/ui` components before building custom UI. Use Mantine components and CSS variables exclusively -- no inline hex colors, no custom design tokens. Match existing page density and spacing.

## Detailed Reference

- `node_modules/@elevasis/sdk/reference/scaffold/ui/recipes.md` -- add a page, add a nav item, theme tokens, feature-scoped components, route patterns (static, nested, dynamic)
- `node_modules/@elevasis/sdk/reference/scaffold/ui/feature-flags-and-gating.md` -- `systemKey` / `SystemGuard` / `AdminGuard` model
- `node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md` -- sidebar composition via manifest overrides
- `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md` -- TypeScript shapes (`SystemModule`, `NavItem`, `OrganizationModel`)
- `ui/src/config/theme.ts` -- theme configuration and CSS variable definitions
- `ui/src/config/nav-items.ts` -- sidebar navigation entries
