# Frontend System Current State ## 1. UI primitive source of truth The current primitive source of truth is the local `components/ui` layer. Current core primitive files: - `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 imports these local primitives rather than importing Radix primitives directly. ## 2. Libraries currently used for UI, motion, icons, and class composition UI primitives and wrappers currently used: - `@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 currently used: - `framer-motion` - `tailwindcss-animate` Icons currently used: - `lucide-react` Class composition currently used: - `class-variance-authority` - `clsx` - `tailwind-merge` Shared helper: - `lib/utils.ts` Current helper function: `cn()` ## 3. Current token system in use The active token system is defined in: - `app/globals.css` - `tailwind.config.ts` Current semantic color tokens 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 shared utility usage is centered on: - `bg-card` - `bg-background` - `bg-surface-2` - `text-card-foreground` - `text-foreground` - `text-muted-foreground` - `border-border/80` - `border-border/70` - `border-input` There are also decorative hero tokens still present in current code: - `--hero-base` - `--hero-ink` - `--hero-left` - `--hero-right` - `--hero-bottom` ## 4. Current radius system in use Current radius tokens in: - `app/globals.css` are: - `--radius-surface: 24px` - `--radius-nested: 16px` - `--radius-pill: 9999px` Current Tailwind mappings in: - `tailwind.config.ts` are: - `rounded-surface` - `rounded-nested` - `rounded-pill` Current usage pattern: - `rounded-surface` - outer surfaces and primitive containers - `components/ui/card.tsx` - `components/ui/app-card.tsx` - `components/ui/dialog.tsx` - `components/ui/select.tsx` - `components/ui/tabs.tsx` - `rounded-nested` - controls and inner blocks - `components/ui/button.tsx` - `components/ui/input.tsx` - `components/ui/textarea.tsx` - `components/ui/select.tsx` - `components/ui/dialog.tsx` - `components/ui/sheet.tsx` - `rounded-pill` - top-level chrome controls - `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 surface rule: `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 feature code now reuses these levels in shared admin surfaces. Examples: - `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` Current base rule: `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` ### Input Source: - `components/ui/input.tsx` Current rule: `flex h-10 w-full rounded-nested border border-input bg-background px-3 py-2 text-base text-foreground shadow-xs ... focus-visible:border-ring ... focus-visible:ring-ring/30` ### Select Source: - `components/ui/select.tsx` Current trigger rule: `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: `rounded-surface border border-input bg-background text-foreground shadow-panel` Current item rule: `rounded-nested ... focus:bg-accent focus:text-accent-foreground` ### Dialog Source: - `components/ui/dialog.tsx` Current overlay rule: `fixed inset-0 z-50 bg-foreground/30 backdrop-blur-sm` Current content rule: `rounded-surface border border-border/80 bg-card p-6 text-card-foreground shadow-panel` Current close button rule: `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`: `fixed inset-0 z-50 bg-foreground/30 backdrop-blur-sm` Current content rule: `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: `inline-flex ... gap-2 rounded-surface border border-border/80 bg-muted/40 p-1.5` Current trigger rule: `rounded-nested px-3 py-2 text-sm font-medium text-muted-foreground` Current active trigger rule: `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 rule: `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` Mapped widths from: - `app/globals.css` are: - `--container-narrow: 48rem` - `--container-default: 72rem` - `--container-wide: 80rem` - `--container-admin: 88rem` ### Shared public top 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 sidebar and header - `p-4 lg:p-6` Source: - `components/dashboard/dashboard-layout.tsx` ## 8. Current spacing rhythm in use Current repeated spacing values: - `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` Current layout spacing is also built around: - `gap-section` - `gap-content` from: - `tailwind.config.ts` ## 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, delay, ease: "easeOut" }}` - shared overlay and disclosure state classes - `components/ui/dialog.tsx` - `components/ui/sheet.tsx` - `components/ui/select.tsx` - `components/ui/dropdown-menu.tsx` - `components/ui/accordion.tsx` - animated navigation chrome - `components/layout/site-header.tsx` ## 10. Current icon rules in use Current icon library: - `lucide-react` Current rule: icons are imported directly from `lucide-react` and used 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 present in: - `package.json` ## 11. Current forbidden drift or remaining transitional areas, if any The shared primitive layer is currently tokenized. Remaining transitional or non-shared drift still present in the codebase: - public atmospheric and hero visuals still use route-specific raw gradients and `rgba(...)` - `components/layout/home-hero.tsx` - `components/layout/site-ambient-backdrop.tsx` - `components/layout/hero-atmosphere.tsx` - `components/layout/site-logo.tsx` - `coming-soon` still uses older translucent raw chrome rules - `app/[locale]/coming-soon/page.tsx` - some public route-level content blocks still use route-local classes instead of shared primitives - `app/[locale]/(site)/portfolio/page.tsx` - `app/[locale]/(site)/portfolio/[slug]/page.tsx` - one custom dark preview surface remains in current admin code - `components/root/site-settings-form.tsx` - `bg-slate-950` - `text-white/55` - `text-white/60` - some admin and public cards still use `Card` with local class overrides instead of `AppCard` - `app/root/page.tsx` - `components/dashboard/dashboard-card.tsx` These are current areas in the repository, but they are not the 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 semantic tokens already defined in `app/globals.css` and mapped in `tailwind.config.ts`. - Use `Card` as the base surface primitive. - 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 rebuilding 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 route-specific hero visuals or transitional raw blocks as shared-system primitives.