Frontend Design System
Visual patterns and UI conventions for fe/ components.
Tech Stack
- •React SPA (Vite)
- •Tailwind CSS +
dark:variants - •SuperTokens (auth)
- •TanStack Query (server state)
- •Redux (global UI state)
- •Lucide React (icons)
Design Philosophy
- •Rounded, soft surfaces with subtle shadows (
rounded-xl/2xl,shadow-md/2xl) - •Clear hierarchy: bold titles, muted supporting text, roomy spacing
- •Primary actions are indigo; destructive actions are red
- •Minimal borders, light separators, and consistent padding
- •Use
font-sansand consistent text sizes across screens
Dark Mode
Class-based dark mode via ThemeToggle → dark class on <html>.
Rule: All components must use dark:* counterparts for every color.
Color System
Surfaces
| Element | Light | Dark |
|---|---|---|
| App canvas | bg-gray-50 | bg-gray-950 |
| Cards/modals | bg-white | bg-slate-900 |
| Text | text-gray-900 | text-gray-50 |
| Muted text | text-gray-500 | text-gray-400 |
| Borders | border-gray-200 | border-slate-700 |
Semantic Colors
| Purpose | Light | Dark |
|---|---|---|
| Primary | indigo-600 | indigo-500 |
| Primary hover | indigo-700 | indigo-400 |
| Info/loading | blue-* | blue-* |
| Danger | red-* | red-* |
Layout Rules
- •Pages are thin:
page/*composes feature components - •Spacing: Use Tailwind scale (
p-4,gap-2,space-y-6) - •Rounded: Prefer
rounded-xl/rounded-2xl - •Max widths: Modals use
max-w-*sizes (defaultmax-w-lg) - •Panels: Use
bg-white+dark:bg-slate-900andborder-gray-100+dark:border-slate-800
Component Structure
core-design/ (Reusable)
Generic UI blocks without feature knowledge:
- •Inputs:
CommonInput,CommonButton,Select - •Modals:
ModalBase,ConfirmModal - •Cards:
ActiveMenu
Rules:
- •No feature-specific data fetching
- •No feature-specific Redux slices
- •Props are generic and typed
components/<feature>/ (Feature Modules)
UI + behavior for a domain:
code
components/<feature>/ ├── components/ # Pure subcomponents ├── hooks/ # Feature hooks ├── utils.ts # Feature utilities ├── types.ts # Feature types └── store.ts # Zustand store
Service Layer
code
services/<module>/ ├── api.ts # Low-level fetch calls └── useQuery.ts # TanStack Query hooks
Rule: UI components never call fetch directly—use hooks from useQuery.ts.
Modal System
Use ModalBase + useModal for all dialogs:
- •Open/close via
useModal(backed bystore/modal.store.ts) - •Stacked modals are supported; top layer handles ESC
- •Backdrop click closes unless blocked by custom logic
- •Use
ConfirmModalorWarningModalfor destructive actions - •Use
maxWidthClassto size modals (e.g.,max-w-sm,max-w-lg)
Modal attributes for testing:
- •
data-modal,data-modal-panel,data-modal-confirm,data-modal-close
Form Controls
- •Use
CommonInputfor text fields (floating labels supported) - •Use
CurrencyInputfor money and numeric inputs - •Use
Select/SelectSearchfor dropdowns - •Use
CommonButtonfor primary actions (supportsloading)
Forms & Validation
- •Use
react-hook-formfor form state and submission - •Prefer
zodschemas withzodResolverfor validation - •Keep form schema in the same feature folder (e.g.,
components/<feature>/schema.ts) - •Map server errors to field errors when possible
Loading & Empty States
- •Use
Spinnerfor inline loading - •Prefer skeletons (
ProductCardSkeleton,CategoryListSkeleton) for list screens - •Disable submit buttons while loading
Naming Conventions
- •Components:
PascalCase.tsx - •Hooks:
useXxx.ts - •Utilities:
utils.ts
Checklist (Before Merge)
- • Works in both light and dark mode
- • Uses consistent text colors (gray/slate)
- • Interactive elements have hover states
- • API logic in
services/, primitives incore-design/