# Frontend System Current State ## 1. UI primitive source of truth The current primitive source of truth is: - `components/ui/button.tsx` - `components/ui/card.tsx` - `components/ui/app-card.tsx` - `components/ui/input.tsx` - `components/ui/textarea.tsx` - `components/ui/select.tsx` - `components/ui/dialog.tsx` - `components/ui/sheet.tsx` - `components/ui/tabs.tsx` - `components/ui/dropdown-menu.tsx` - `components/ui/accordion.tsx` - `components/ui/badge.tsx` - `components/ui/checkbox.tsx` - `components/ui/table.tsx` - `components/ui/label.tsx` - `components/ui/separator.tsx` Feature code currently reuses these primitives directly. ## 2. Libraries currently used for UI, motion, icons, and class composition UI primitives and wrappers: - `@radix-ui/react-accordion` - `@radix-ui/react-checkbox` - `@radix-ui/react-dialog` - `@radix-ui/react-dropdown-menu` - `@radix-ui/react-select` - `@radix-ui/react-slot` Motion: - `framer-motion` - `tailwindcss-animate` Icons: - `lucide-react` Class composition: - `class-variance-authority` - `clsx` - `tailwind-merge` Shared helper: - `lib/utils.ts` - `cn(...inputs)` Source files: - `package.json` - `lib/utils.ts` ## 3. Current token system in use The active semantic token layer is defined in: - `app/globals.css` - `tailwind.config.ts` Current color token groups exposed in Tailwind: - `background` - `foreground` - `card` - `card-foreground` - `popover` - `popover-foreground` - `primary` - `primary-foreground` - `secondary` - `secondary-foreground` - `muted` - `muted-foreground` - `accent` - `accent-foreground` - `destructive` - `destructive-foreground` - `border` - `border-strong` - `input` - `ring` - `surface.1` - `surface.2` - `surface.3` - `surface.inverse` - `brand.primary` - `brand.secondary` - `status.success` - `status.success-soft` - `status.warning` - `status.warning-soft` - `sidebar.*` Current tokenized utility usage in shared UI is based on: - `bg-card` - `bg-background` - `bg-surface-2` - `text-card-foreground` - `text-foreground` - `text-muted-foreground` - `border-border/80` - `border-border/70` - `border-input` - `hover:bg-accent` ## 4. Current radius system in use Defined in: - `app/globals.css` - `tailwind.config.ts` Current radius tokens: - `--radius-surface: 24px` - `--radius-nested: 16px` - `--radius-pill: 9999px` Current mapped utilities: - `rounded-surface` - `rounded-nested` - `rounded-pill` Current shared primitive usage: - surface containers: - `rounded-surface` - `components/ui/card.tsx` - `components/ui/app-card.tsx` - `components/ui/dialog.tsx` - `components/ui/select.tsx` - `components/ui/tabs.tsx` - controls and nested blocks: - `rounded-nested` - `components/ui/button.tsx` - `components/ui/input.tsx` - `components/ui/textarea.tsx` - `components/ui/select.tsx` - `components/ui/dialog.tsx` - `components/ui/sheet.tsx` - pill controls: - `rounded-pill` - `components/layout/site-header.tsx` - `components/layout/floating-preferences.tsx` ## 5. Current surface/card/panel rules in use ### Base `Card` Source: - `components/ui/card.tsx` Current base rule: ```tsx rounded-surface border border-border/80 bg-card text-card-foreground shadow-card ``` ### `AppCard` Source: - `components/ui/app-card.tsx` Current visual levels: - `level={1}` - `border border-border/80 bg-card text-card-foreground shadow-card` - `level={2}` - `border border-input bg-background text-foreground shadow-xs` - `level={3}` - `border border-border/80 bg-surface-2 text-foreground shadow-panel` - `level="inverse"` - `border-transparent bg-foreground text-background shadow-card` Current padding variants: - `none` - `sm` - `p-4` - `md` - `p-6` - `lg` - `p-8` Current interactive rule: - `hover:bg-accent/30 hover:text-accent-foreground` ### Current surface usage in feature code Nested surface blocks currently reuse `AppCard` directly in: - `components/root/media-field-picker.tsx` - `components/root/portfolio-projects-overview.tsx` - `components/root/portfolio-project-form.tsx` - `components/root/portfolio-categories-manager.tsx` - `components/root/site-settings-form.tsx` ## 6. Current input/button/select/dialog/sheet rules in use ### Button Source: - `components/ui/button.tsx` Base: ```tsx inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-nested text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 ``` Current variants: - `default` - `bg-primary text-primary-foreground shadow-sm hover:bg-primary/92` - `secondary` - `bg-secondary text-secondary-foreground hover:bg-secondary/90` - `outline` - `border border-input bg-background hover:border-border-strong hover:bg-accent hover:text-accent-foreground` - `ghost` - `text-muted-foreground hover:bg-muted hover:text-foreground` - `link` - `rounded-none text-primary underline-offset-4 hover:underline` - `destructive` - `bg-destructive text-destructive-foreground hover:bg-destructive/90` Current sizes: - `default` - `h-10 px-4 py-2` - `sm` - `h-9 px-3` - `lg` - `h-11 px-6` - `icon` - `h-10 w-10` ### Input Source: - `components/ui/input.tsx` Current rule: ```tsx flex h-10 w-full rounded-nested border border-input bg-background px-3 py-2 text-base text-foreground shadow-xs ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-0 ``` ### Select Source: - `components/ui/select.tsx` Current trigger rule: ```tsx flex h-10 w-full items-center justify-between rounded-nested border border-input bg-background px-3 py-2 text-sm shadow-xs ``` Current content rule: ```tsx rounded-surface border border-input bg-background text-foreground shadow-panel ``` Current item rule: ```tsx rounded-nested ... focus:bg-accent focus:text-accent-foreground ``` ### Dialog Source: - `components/ui/dialog.tsx` Current overlay rule: ```tsx fixed inset-0 z-50 bg-foreground/30 backdrop-blur-sm ``` Current content rule: ```tsx rounded-surface border border-border/80 bg-card p-6 text-card-foreground shadow-panel ``` Current close button rule: ```tsx inline-flex h-8 w-8 items-center justify-center rounded-nested text-muted-foreground hover:bg-accent hover:text-foreground ``` ### Sheet Source: - `components/ui/sheet.tsx` Current overlay rule matches `Dialog`: ```tsx fixed inset-0 z-50 bg-foreground/30 backdrop-blur-sm ``` Current content rule: ```tsx border-border/80 bg-card p-6 text-card-foreground shadow-panel ``` Current side radius rules: - `sm:rounded-l-surface` - `sm:rounded-r-surface` - `rounded-b-surface` - `rounded-t-surface` ### Tabs Source: - `components/ui/tabs.tsx` Current list rule: ```tsx inline-flex ... gap-2 rounded-surface border border-border/80 bg-muted/40 p-1.5 ``` Current trigger rule: ```tsx rounded-nested px-3 py-2 text-sm font-medium text-muted-foreground ``` Current active rule: ```tsx border border-border/80 bg-background text-foreground shadow-xs ``` ## 7. Current layout/container rules in use ### Container Source: - `components/layout/container.tsx` Current base container rule: ```tsx mx-auto w-full px-4 sm:px-6 lg:px-8 ``` Current size variants: - `default` - `max-w-layout` - `narrow` - `max-w-narrow` - `wide` - `max-w-wide` - `admin` - `max-w-admin` ### Shared public chrome Current shared top controls use: - `rounded-pill` - `border-border/70` - `bg-background/80` - `shadow-panel` - `backdrop-blur-chrome` Files: - `components/layout/site-header.tsx` - `components/layout/floating-preferences.tsx` ### Admin shell Current admin layout still uses: - `min-h-screen bg-muted/30` - `grid min-h-screen lg:grid-cols-[280px_minmax(0,1fr)]` - `sticky top-0` - `p-4 lg:p-6` Source: - `components/dashboard/dashboard-layout.tsx` ## 8. Current spacing rhythm in use Current repeated spacing values across primitives and layout: - `p-4` - `p-6` - `p-8` - `px-3 py-2` - `px-4 py-2` - `px-4 py-3` - `px-4 py-4` - `gap-2` - `gap-3` - `gap-4` - `gap-6` - `space-y-2` - `space-y-3` - `space-y-4` - `space-y-6` Current primitive spacing sources: - `CardHeader` - `gap-1.5 p-6` - `CardContent` - `p-6 pt-0` - `AppCard padding="sm"` - `p-4` - `AppCard padding="md"` - `p-6` - `AppCard padding="lg"` - `p-8` - `Container` - `px-4 sm:px-6 lg:px-8` ## 9. Current motion rules in use Primary motion library: - `framer-motion` State animation utility layer: - `tailwindcss-animate` Current motion patterns: - reveal-on-scroll wrapper - `components/motion-fade.tsx` - `initial: { opacity: 0, y: 20 }` - `whileInView: { opacity: 1, y: 0 }` - `transition: { duration: 0.45, ease: "easeOut" }` - shared overlay open/close classes - `dialog` - `sheet` - `select` - `dropdown-menu` - `accordion` - animated nav active pill and mobile menu - `components/layout/site-header.tsx` ## 10. Current icon rules in use Current icon library: - `lucide-react` Current shared rule: Icons are imported directly from `lucide-react` and passed through local primitives or feature components. Examples: - `components/ui/dialog.tsx` - `components/ui/select.tsx` - `components/layout/site-header.tsx` - `components/theme-toggle.tsx` - `components/root/portfolio-project-form.tsx` No second React icon library is currently present in `package.json`. ## 11. Current forbidden drift or remaining transitional areas, if any The shared primitive system is currently tokenized. Remaining transitional areas still present in the codebase: - public hero / atmospheric visuals still use raw gradients and `rgba(...)` decorative backgrounds - `components/layout/home-hero.tsx` - `components/layout/site-ambient-backdrop.tsx` - `components/layout/hero-atmosphere.tsx` - `components/layout/site-logo.tsx` - `coming-soon` page still uses older raw translucent chrome styles - `app/[locale]/coming-soon/page.tsx` - some public route-level content blocks still use direct local classes instead of shared primitive wrappers - `app/[locale]/(site)/portfolio/page.tsx` - `app/[locale]/(site)/portfolio/[slug]/page.tsx` - one preview block in site settings still uses a custom dark preview surface - `components/root/site-settings-form.tsx` - `bg-slate-950` - `text-white/55` - `text-white/60` These files exist in the current codebase and should be treated as remaining transitional areas, not as shared-system rules. ## 12. Codex rules derived from the current system - Use `components/ui` as the primitive source of truth. - Use `cn()` from `lib/utils.ts` for class composition. - Use `cva()` where the primitive already exposes variants. - Use semantic tokens already defined in `app/globals.css` and mapped in `tailwind.config.ts`. - Use `Card` for the base surface: - `rounded-surface border border-border/80 bg-card text-card-foreground shadow-card` - Use `AppCard` when feature code needs explicit shared surface levels. - Use `AppCard level={1}` for primary card surfaces. - Use `AppCard level={2}` for nested panels and inner blocks. - Use `AppCard level={3}` for elevated grouped panels. - Use `rounded-surface`, `rounded-nested`, and `rounded-pill` as the shared radius system. - Use `Input`, `Textarea`, `Select`, `Dialog`, `Sheet`, and `Tabs` from `components/ui` instead of re-creating those patterns in feature code. - Use `Container` for width and horizontal padding rules. - Use `lucide-react` for icons. - Use `framer-motion` for custom motion and `tailwindcss-animate` for primitive state transitions. - Do not treat transitional decorative hero files or remaining route-local raw blocks as shared-system primitives.