# Frontend System Audit

## 1. UI libraries actually used

- `next` App Router is the app shell and routing layer.
- `tailwindcss` is the styling system.
- `@radix-ui/react-*` primitives are used through local wrappers in:
  - `components/ui/accordion.tsx`
  - `components/ui/checkbox.tsx`
  - `components/ui/dialog.tsx`
  - `components/ui/dropdown-menu.tsx`
  - `components/ui/select.tsx`
  - `components/ui/sheet.tsx`
- `class-variance-authority` is used for variants in:
  - `components/ui/button.tsx`
  - `components/ui/badge.tsx`
  - `components/ui/app-card.tsx`
  - `components/layout/container.tsx`
- `clsx` + `tailwind-merge` are used through `cn()` in `lib/utils.ts`.
- `next-themes` is used for theme switching in:
  - `components/theme-provider.tsx`
  - `components/theme-toggle.tsx`
- `framer-motion` is used for custom motion in:
  - `components/motion-fade.tsx`
  - `components/layout/site-header.tsx`
  - `components/layout/site-logo.tsx`
  - `components/layout/hero-motion-backdrop.tsx`
  - `components/layout/hero-atmosphere.tsx`
  - `components/layout/site-ambient-backdrop.tsx`
  - `components/layout/ascii-water-ripple.tsx`
  - `components/layout/animated-logo.tsx`
  - `components/layout/stacked-marquee-section.tsx`
- `tailwindcss-animate` is enabled in `tailwind.config.ts` and is used by state classes in `dialog`, `dropdown-menu`, `select`, `sheet`, and `accordion`.

## 2. Which library is the primary source of UI primitives

The primary primitive source is the local
`components/ui`
layer.

That layer is mostly built on top of
`@radix-ui/react-*`
plus Tailwind classes.

The app code imports local primitives like:

- `@/components/ui/button`
- `@/components/ui/card`
- `@/components/ui/input`
- `@/components/ui/dialog`
- `@/components/ui/select`

It does not import Radix primitives directly from route files and feature components.

## 3. Whether shadcn/ui is really used or only partially used

`shadcn/ui`
is present, but partially.

Evidence that it is present:

- `components.json` exists and points to `app/globals.css`, `tailwind.config.ts`, and `@/components/ui`.
- The local primitive structure matches the common shadcn pattern:
  - `components/ui/button.tsx`
  - `components/ui/card.tsx`
  - `components/ui/dialog.tsx`
  - `components/ui/dropdown-menu.tsx`
  - `components/ui/select.tsx`
  - `components/ui/sheet.tsx`
- `lib/utils.ts` exposes the standard `cn()` helper.

Evidence that it is partial/customized rather than stock:

- There is no runtime `shadcn-ui` package in `package.json`.
- Several components are customized to project tokens:
  - `rounded-surface`
  - `rounded-nested`
  - `shadow-card`
  - `shadow-panel`
- `components/ui/app-card.tsx` is a project-specific wrapper over `Card`.
- `components/ui/tabs.tsx` is a custom React context implementation, not a Radix wrapper.
- Usage is selective. Import counts in the current codebase show:
  - `app-card`: `23`
  - `card`: `26`
  - `button`: `19`
  - `dialog`: `1`
  - `dropdown-menu`: `1`
  - `sheet`: `1`
  - `table`: `1`
  - `tabs`: `1`

## 4. Repeated layout/container patterns found in code

### Global container pattern

The main reusable container is `components/layout/container.tsx`:

```tsx
mx-auto w-full px-4 sm:px-6 lg:px-8
```

Container sizes come from Tailwind extensions:

- `max-w-layout`
- `max-w-narrow`
- `max-w-wide`
- `max-w-admin`

These map to CSS vars in `app/globals.css`:

- `--container-narrow: 48rem`
- `--container-default: 72rem`
- `--container-wide: 80rem`
- `--container-admin: 88rem`

### Public site shell pattern

Repeated in:

- `app/[locale]/(site)/layout.tsx`
- `components/layout/site-header.tsx`
- `components/layout/home-hero.tsx`
- `components/layout/page-hero.tsx`
- `app/[locale]/(site)/contact/page.tsx`

Patterns:

- `relative flex min-h-screen flex-col overflow-hidden`
- `max-w-[72rem] px-4 sm:px-6 lg:px-8`
- hero sections with:
  - `pt-24`
  - `sm:pt-28`
  - `lg:pt-28`
  - `pb-10`
  - `lg:pb-12`
  - `lg:pb-16`

### Admin layout pattern

Repeated in:

- `components/dashboard/dashboard-layout.tsx`
- `components/root/root-dashboard-shell.tsx`
- many `app/root/*/page.tsx`

Patterns:

- `min-h-screen bg-muted/30`
- `grid min-h-screen lg:grid-cols-[280px_minmax(0,1fr)]`
- sticky sidebar:
  - `lg:sticky lg:top-0 lg:h-screen`
- sticky header:
  - `sticky top-0 z-30 ... bg-background/95 ... backdrop-blur`
- main content spacing:
  - `p-4 lg:p-6`
- page stack wrapper:
  - `space-y-6`

### Editor / split workspace pattern

Repeated in:

- `components/root/site-settings-form.tsx`
- `components/root/portfolio-project-form.tsx`
- `app/root/page.tsx`

Patterns:

- `grid gap-6 xl:grid-cols-[minmax(0,3fr)_minmax(320px,1fr)]`
- `grid gap-6 xl:grid-cols-[280px_minmax(0,1fr)]`
- sticky side panel:
  - `xl:sticky xl:top-6 xl:self-start`

## 5. Repeated radius values found in code

### Tokenized radius values

Defined in `app/globals.css`:

- `--radius-surface: 24px`
- `--radius-nested: 16px`
- `--radius-pill: 9999px`

Mapped in `tailwind.config.ts`:

- `rounded-surface`
- `rounded-nested`
- `rounded-pill`

### Repeated radius class patterns

Most repeated token usage:

- `rounded-surface`
  - `components/ui/card.tsx`
  - `components/ui/app-card.tsx`
  - `components/ui/accordion.tsx`
  - `components/ui/dropdown-menu.tsx`
  - `components/ui/select.tsx`
  - `components/ui/tabs.tsx`
- `rounded-nested`
  - `components/ui/button.tsx`
  - `components/ui/input.tsx`
  - `components/ui/textarea.tsx`
  - `components/ui/select.tsx`
  - `components/dashboard/sidebar.tsx`
  - `components/root/contact-protection-form.tsx`
- `rounded-[var(--radius-pill)]`
  - `components/layout/site-header.tsx`
  - `components/layout/floating-preferences.tsx`
- `rounded-full`
  - used heavily for decorative circles and icon pills in site chrome:
    - `components/layout/site-ambient-backdrop.tsx`
    - `components/layout/hero-atmosphere.tsx`
    - `components/layout/ascii-water-ripple.tsx`

### Non-token radius values also present

- `rounded-md`
  - several content blocks and previews
  - examples:
    - `app/root/page.tsx`
    - `components/root/site-settings-form.tsx`
    - `components/root/media-field-picker.tsx`
- `rounded-lg`
  - examples:
    - `components/ui/dialog.tsx`
    - `components/dashboard/dashboard-layout.tsx`
    - `components/root/portfolio-project-form.tsx`

## 6. Repeated spacing patterns found in code

### Global repeated spacing

Most repeated stack and gap patterns:

- `space-y-6`
- `gap-6`
- `space-y-2`
- `space-y-3`
- `p-6`
- `p-4`
- `px-4 py-3`
- `px-4 py-4`
- `px-3 py-2`

### Core primitive spacing

- `CardHeader`: `flex flex-col gap-1.5 p-6`
  - `components/ui/card.tsx`
- `CardContent`: `p-6 pt-0`
  - `components/ui/card.tsx`
- `Button` sizes:
  - `default`: `h-10 px-4 py-2`
  - `sm`: `h-9 px-3`
  - `lg`: `h-11 px-6`
  - `icon`: `h-10 w-10`
  - `components/ui/button.tsx`
- `Input` and `Textarea`:
  - `px-3 py-2`
  - `components/ui/input.tsx`
  - `components/ui/textarea.tsx`
- `SelectTrigger`:
  - `px-3 py-2`
  - `components/ui/select.tsx`

### Layout spacing

- container padding:
  - `px-4 sm:px-6 lg:px-8`
- admin page wrapper:
  - `p-4 lg:p-6`
- admin section wrapper:
  - `py-6 lg:py-8`
  - `components/layout/app-shell.tsx`
- hero wrappers:
  - `pt-24`
  - `sm:pt-28`
  - `lg:pt-28`

## 7. Repeated color/token usage found in code

### Semantic tokens defined

Defined in `app/globals.css` and exposed in `tailwind.config.ts`:

- base semantic:
  - `background`
  - `foreground`
  - `card`
  - `popover`
  - `primary`
  - `secondary`
  - `muted`
  - `accent`
  - `destructive`
  - `border`
  - `border-strong`
  - `input`
  - `ring`
- custom semantic:
  - `surface-1`
  - `surface-2`
  - `surface-3`
  - `surface-inverse`
  - `brand-primary`
  - `brand-secondary`
  - `status-success`
  - `status-success-soft`
  - `status-warning`
  - `status-warning-soft`
  - `sidebar-*`
  - `hero-*`

### Repeated utility combinations

Very common combinations:

- `border border-border/80 bg-card text-card-foreground shadow-card`
  - `components/ui/card.tsx`
- `border border-input bg-background`
  - `components/ui/input.tsx`
  - `components/ui/select.tsx`
  - `components/root/portfolio-categories-manager.tsx`
  - `components/root/portfolio-projects-overview.tsx`
- `bg-primary text-primary-foreground`
  - active nav and badges/buttons:
    - `components/ui/button.tsx`
    - `components/ui/badge.tsx`
    - `components/dashboard/sidebar.tsx`
    - `components/root/portfolio-subnav.tsx`
    - `app/[locale]/(site)/portfolio/page.tsx`
- `text-muted-foreground`
  - repeated throughout forms, cards, table headers, descriptions
- `hover:bg-accent`
  - repeated in `button`, `dropdown-menu`, select items, and selection cards
- `bg-muted/40` and `bg-muted/50`
  - repeated in admin surfaces and tables

### Site-specific color usage outside semantic surface tokens

Public-facing chrome also uses many arbitrary values:

- `border-black/6`
- `bg-white/24`
- `bg-white/32`
- `text-[hsl(var(--hero-ink)/0.76)]`
- custom shadow values with raw `rgba(...)`

Examples:

- `components/layout/site-header.tsx`
- `components/layout/floating-preferences.tsx`
- `app/[locale]/(site)/page.tsx`

## 8. Motion/animation approach actually used

There are two real motion layers.

### `framer-motion`

Used for custom movement and page chrome:

- reveal-on-scroll wrapper:
  - `components/motion-fade.tsx`
- header nav active pill and mobile menu:
  - `components/layout/site-header.tsx`
- logo animation:
  - `components/layout/site-logo.tsx`
  - `components/layout/animated-logo.tsx`
- ambient / backdrop motion:
  - `components/layout/hero-motion-backdrop.tsx`
  - `components/layout/hero-atmosphere.tsx`
  - `components/layout/site-ambient-backdrop.tsx`
  - `components/layout/ascii-water-ripple.tsx`
  - `components/layout/stacked-marquee-section.tsx`

### `tailwindcss-animate`

Used through state classes for Radix-style overlays and disclosures:

- `data-[state=open]:animate-in`
- `data-[state=closed]:animate-out`
- `fade-in-0`
- `zoom-in-95`
- `slide-in-from-top-2`
- `animate-accordion-down`
- `animate-accordion-up`

Files:

- `components/ui/dialog.tsx`
- `components/ui/dropdown-menu.tsx`
- `components/ui/select.tsx`
- `components/ui/sheet.tsx`
- `components/ui/accordion.tsx`

## 9. Icon system actually used

The icon system is
`lucide-react`
.

Evidence:

- dependency in `package.json`
- broad usage across app and components
- examples:
  - `components/root/root-dashboard-shell.tsx`
  - `components/layout/site-header.tsx`
  - `components/theme-toggle.tsx`
  - `app/root/page.tsx`
  - `app/[locale]/(site)/page.tsx`

No second React icon library is present in `package.json`.

## 10. Component architecture currently used

### Routing structure

- `app` is the real route layer.
- public site routes live under:
  - `app/[locale]/(site)/*`
- admin routes live under:
  - `app/root/*`
- `src` exists but is empty in the current codebase.

### Component folders

- `components/ui`
  - primitive and near-primitive reusable controls
- `components/layout`
  - site shell, hero, header, footer, container, backdrops
- `components/root`
  - admin feature components and forms
- `components/dashboard`
  - admin navigation and dashboard layout shell
- `components/site`
  - site feature forms such as contact form

### Helper layer

- `lib/utils.ts`
  - `cn()`
- `lib/root-navigation.ts`
  - navigation config for admin shell
- other `lib/*`
  - app settings, metadata, locale, media, portfolio, auth

### Wrappers around primitives

Confirmed custom wrappers around local primitive layer:

- `components/ui/app-card.tsx`
  - wraps `Card`
- `components/theme-toggle.tsx`
  - wraps `Button`
- `components/layout/locale-toggle.tsx`
  - uses `Button` and `DropdownMenu`
- `components/root/form-save-button.tsx`
  - uses `Button`

## 11. Violations or inconsistencies found in the current codebase

These are current inconsistencies visible in the implementation.

### Token system is mixed with raw one-off styling

Admin and primitive components strongly use semantic tokens:

- `bg-card`
- `bg-background`
- `border-input`
- `shadow-card`
- `rounded-surface`

But public chrome often bypasses them with raw arbitrary values:

- `components/layout/site-header.tsx`
- `components/layout/floating-preferences.tsx`
- `app/[locale]/(site)/page.tsx`

Examples:

- `bg-white/24`
- `border-black/6`
- `shadow-[0_14px_34px_-24px_rgba(15,23,42,0.18)]`

### Radius usage is not fully normalized

Tokenized radius classes exist, but these also appear:

- `rounded-md`
- `rounded-lg`
- `rounded-full`

Examples:

- `components/ui/dialog.tsx`
- `components/dashboard/dashboard-layout.tsx`
- `components/root/site-settings-form.tsx`
- `components/root/portfolio-project-form.tsx`

### Some primitives follow the local system, some keep stock shadcn-style values

- tokenized:
  - `components/ui/card.tsx`
  - `components/ui/button.tsx`
  - `components/ui/input.tsx`
  - `components/ui/select.tsx`
- less tokenized:
  - `components/ui/dialog.tsx`
    - `sm:rounded-lg`
    - `shadow-lg`
- less tokenized:
  - `components/ui/sheet.tsx`
    - `shadow-lg`

### `AppCard` surface levels are not all visually distinct

In `components/ui/app-card.tsx`:

- `level: 1` and `level: 2` both use:
  - `border border-border/80 bg-card text-card-foreground shadow-card`

So the file defines multiple levels, but two of them are currently identical.

### Primitive implementation style is not uniform

Most interactive primitives use Radix wrappers, but `components/ui/tabs.tsx` is a custom React context implementation instead.

### Tailwind scans `src`, but `src` is empty

`tailwind.config.ts`
includes:

- `./src/**/*.{js,ts,jsx,tsx,mdx}`

Current project state:

- `src` contains no files.

## 12. Codex rules derived from the existing system

These rules are derived from what the codebase already does.

- Use local primitives from `components/ui` before introducing direct Radix usage.
- Use `cn()` from `lib/utils.ts` for class composition.
- Use `cva()` for reusable variant APIs where the project already does that:
  - `Button`
  - `Badge`
  - `AppCard`
  - `Container`
- For shared admin surfaces, prefer tokenized classes already present:
  - `rounded-surface`
  - `rounded-nested`
  - `bg-card`
  - `bg-background`
  - `border-input`
  - `border-border/80`
  - `shadow-card`
  - `shadow-panel`
- For main width constraints, follow the existing container system:
  - `Container`
  - `max-w-layout`
  - `max-w-admin`
  - `px-4 sm:px-6 lg:px-8`
- For admin pages and forms, the repeated layout rhythm is:
  - `space-y-6`
  - `gap-6`
  - `space-y-2`
  - `p-6`
  - `p-4`
- For public site hero/layout sections, the repeated shell is:
  - `hero-surface`
  - `max-w-[72rem]`
  - `px-4 sm:px-6 lg:px-8`
  - `pt-24 sm:pt-28`
- Use `lucide-react` for icons.
- Use `framer-motion` for custom motion and `tailwindcss-animate` for Radix state transitions.
- Treat `shadcn/ui` in this repo as a local customized base, not as a stock untouched library.
