Overview
Learn about Plainform's UI system built with Tailwind CSS 4 and shadcn/ui components
Plainform uses a modern UI system combining Tailwind CSS 4 with shadcn/ui-inspired components built on Radix UI primitives. This approach provides a flexible, accessible, and customizable design system.
What's Included
Tailwind CSS 4
Tailwind CSS 4 is the latest version featuring:
- Native CSS imports with
@import 'tailwindcss' - CSS-first configuration using
@themedirective - Improved performance and smaller bundle sizes
- Enhanced dark mode support with custom variants
UI Components
Plainform includes 25+ pre-built components in components/ui/:
- Form Elements: Button, Input, Label, InputOTP
- Layout: Card, Separator, Sheet, ScrollArea
- Overlays: Dialog, Popover, DropdownMenu
- Navigation: Tabs, TableOfContents, BackButton
- Feedback: Skeleton, ProgressBar, Avatar
- Advanced: Accordion, BentoGrid, Marquee, AnimatedShinyText
All components are built with:
- Radix UI primitives for accessibility
- TypeScript for type safety
- forwardRef for ref forwarding
- Tailwind CSS for styling
Design System
The design system uses CSS variables for theming:
:root {
--color-surface: #fafafa;
--color-foreground: #171717;
--color-brand: #4153ff;
--color-neutral: #e7e6e6;
}
.dark {
--color-surface: #171717;
--color-foreground: #fafafa;
--color-brand: #4153ff;
--color-neutral: #262626;
}Component Architecture
Base Pattern
UI components follow standard React patterns with TypeScript:
import * as React from 'react';
import { cn } from '@/lib/utils';
function Card({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
className={cn(
'bg-neutral/40 text-foreground flex flex-col gap-6 rounded-md border border-neutral py-6 shadow-sm',
className
)}
{...props}
/>
);
}
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
className={cn('grid auto-rows-min items-start gap-1.5 px-6', className)}
{...props}
/>
);
}
export { Card, CardHeader };Key Features
- Composition: Components can be composed together
- Customization: Override styles via className prop
- Accessibility: Built-in ARIA attributes and keyboard navigation
- Type Safety: Full TypeScript support with proper types
Styling Utilities
cn() Helper
The cn() utility merges Tailwind classes intelligently:
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}Usage:
<div className={cn(
'base-classes',
variant === 'primary' && 'bg-brand',
className
)} />Typography System
Global typography styles are defined in globals.css:
@layer base {
h1 {
@apply text-5xl font-bold leading-normal max-md:text-[36px] font-poppins;
}
h2 {
@apply text-[2.5rem] font-semibold leading-normal max-md:text-[32px] font-poppins;
}
p {
@apply text-base font-normal leading-normal max-md:text-[15px];
}
}Responsive Design
All components are mobile-first and responsive:
<div className="w-full md:w-1/2 lg:w-1/3">
<p className="text-sm md:text-base lg:text-lg">
Responsive text
</p>
</div>Custom breakpoints:
<div className="max-[1000px]:hidden">
Desktop only content
</div>Dark Mode
Dark mode is handled automatically using CSS variables:
<div className="bg-card text-card-foreground border-border">
<h2 className="text-foreground">Title</h2>
<p className="text-muted-foreground">Description</p>
</div>The theme provider handles mode switching:
import { ThemeProvider } from 'next-themes';
<ThemeProvider attribute="class" defaultTheme="system">
{children}
</ThemeProvider>Next Steps
- Setup and Configuration - Add new components
- Theming - Customize colors and styles
- Troubleshooting - Common issues and solutions
How is this guide ?
Last updated on