UI Components
Design system overview -- shadcn/ui component library, design tokens, theming, and component patterns.
Trovella's UI layer combines shadcn/ui (generated components), a custom design token system (@repo/design-tokens), and Tailwind CSS v4 with CSS-first configuration. The design system enforces semantic color tokens, brand typography, and a hierarchical border radius scale across both light and dark modes.
Architecture
@repo/design-tokens (tokens.css) -- HSL color tokens, shadows, radii
|
v
apps/web/src/app/globals.css -- imports tokens, maps to Tailwind v4 @theme
|
v
apps/web/src/components/ui/ -- shadcn/ui generated components (24 components)
|
v
apps/web/src/components/dashboard/ -- dashboard shell, sidebar, top bar
apps/web/src/components/landing/ -- landing page sections
apps/web/src/components/admin/ -- admin dashboard panels
apps/web/src/components/brand/ -- logo, brand mark
apps/web/src/components/auth/ -- sign-in button
apps/web/src/components/theme/ -- theme provider, toggle
apps/web/src/components/settings/ -- settings UI
The design token package is a leaf-layer package that exports only CSS and SVG assets -- no TypeScript, no runtime code. Components in @repo/web consume tokens indirectly through Tailwind utility classes that resolve to CSS custom properties.
Key Design Decisions
shadcn/ui over a pre-built library. Components are generated into the project (not installed as a dependency), giving full ownership of the source code. This means components can be customized without fighting library abstractions, and AI agents can read and modify them directly. The trade-off is that upstream updates require manual re-generation. See shadcn/ui Component Library.
Semantic tokens only. All color usage goes through semantic token names (bg-primary, text-muted-foreground, border-border) rather than Tailwind's default palette (bg-indigo-500, text-blue-600). This enforces brand consistency and makes dark mode automatic -- the same class names resolve to different HSL values under the .dark class. See Design Tokens.
Tailwind v4 CSS-first configuration. There is no tailwind.config.ts file. All theme mapping happens in globals.css using the @theme inline directive. Fonts, colors, and spacing are defined as CSS custom properties and mapped to Tailwind utilities in the @theme block. See Theming.
Class strategy for dark mode. Dark mode uses the .dark class on the root element (set by next-themes), not @media (prefers-color-scheme). This allows user override via the three-way theme toggle (light / dark / system).
Component Categories
| Category | Location | Count | Description |
|---|---|---|---|
| UI primitives | src/components/ui/ | 24 | shadcn/ui generated components (Button, Card, Dialog, etc.) |
| Dashboard | src/components/dashboard/ | 6 | Shell, sidebar, top bar, content, coming-soon placeholder |
| Landing | src/components/landing/ | 11 | Hero, bento, CTA, FAQ, pricing, and other marketing sections |
| Admin | src/components/admin/ | 20+ | AI logs, research plans, search admin, skill executions |
| Brand | src/components/brand/ | 1 | TrovellaLogo with diamond icon and wordmark |
| Auth | src/components/auth/ | 1 | Google OAuth sign-in button |
| Theme | src/components/theme/ | 2 | Theme provider and toggle |
| Settings | src/components/settings/ | 2 | PAT manager and settings content |
Key Utilities
cn() function (src/lib/utils.ts): Merges Tailwind class names using clsx + tailwind-merge. Every component uses this for conditional class composition:
import { cn } from "@/lib/utils";
<div className={cn("bg-card rounded-lg", isActive && "border-primary", className)} />
class-variance-authority (CVA): Used by shadcn/ui components to define variant styles. Button, Badge, Alert, Tabs, and Sidebar all use CVA for type-safe variant props:
const buttonVariants = cva("inline-flex items-center ...", {
variants: {
variant: { default: "bg-primary ...", destructive: "bg-destructive ..." },
size: { default: "h-9 px-4", sm: "h-8 px-3", lg: "h-10 px-6" },
},
});
ESLint Exemptions
The apps/web ESLint config relaxes max-lines and complexity rules for src/components/ui/**. These are shadcn/ui generated files -- they are vendor code that should not be manually refactored. See ESLint Configuration for the full rule set and all relaxed file patterns.
Related Pages
- Design Tokens -- HSL color system, typography, shadows, radii, icon rules
- shadcn/ui Component Library -- component inventory, generation workflow, customization rules
- Theming -- dark mode, theme provider, Tailwind v4 CSS-first setup, font loading
- Component Patterns -- dashboard shell, custom components, composition patterns
Cross-Domain References
- ESLint Configuration -- UI component exemptions from complexity rules
- Routing & Pages -- Component Boundaries -- server vs. client component split