# OW Animation Arts Vault - UI Design System & Layout Guide This document outlines the complete UI/style and layout architecture used in this codebase. Use this guide to create additional applications for the same client with consistent design and user experience. --- ## Table of Contents 1. [Technology Stack](#technology-stack) 2. [Project Architecture](#project-architecture) 3. [Color System & Theming](#color-system--theming) 4. [Layout System](#layout-system) 5. [Navigation & Sidebar](#navigation--sidebar) 6. [Page Layouts](#page-layouts) 7. [Component Library](#component-library) 8. [Typography & Spacing](#typography--spacing) 9. [Form Patterns](#form-patterns) 10. [Responsive Design](#responsive-design) 11. [Dark Mode Implementation](#dark-mode-implementation) 12. [Reusable Patterns](#reusable-patterns) 13. [Asset Guidelines](#asset-guidelines) --- ## 1. Technology Stack ### Core Framework - **Next.js 16.0.3** - React framework with App Router - **React 18+** - UI library - **TypeScript** - Type safety - **Tailwind CSS 3.4+** - Utility-first CSS framework ### UI Component Library - **shadcn/ui** - Pre-built, composable React components - **@radix-ui/** - Unstyled, accessible component primitives - **Lucide React** - Beautiful, consistent icon library - **Tabler Icons** - Alternative icon set ### State Management & Data - **NextAuth.js** - Authentication - **Next-Themes** - Theme management (dark/light mode) - **Prisma ORM** - Database abstraction - **TanStack React Table** - Advanced table data management - **Sonner** - Toast notifications ### Additional Libraries - **@dnd-kit** - Drag and drop functionality - **Embla Carousel** - Carousel/slider component - **Recharts** - Data visualization charts - **HLS.js** - Video streaming (HLS protocol) - **date-fns** - Date utilities - **class-variance-authority (CVA)** - Component variant management - **clsx** - Conditional className merging --- ## 2. Project Architecture ### Directory Structure ``` app/ ├── layout.tsx # Root layout (server component) ├── page.tsx # Landing/home page ├── providers.tsx # Client-side providers (SessionProvider, ThemeProvider) ├── globals.css # Global styles & CSS variables ├── login/ │ ├── page.tsx # Login page │ └── unauthorized/ ├── dashboard/ │ ├── page.tsx # Protected dashboard │ ├── dashboard-client.tsx # Client component with content │ ├── liked-videos/ │ └── watch-history/ ├── admin/ │ ├── page.tsx # Admin gate (server component) │ ├── admin-client.tsx # Admin UI (client component) │ ├── users/ │ ├── courses/ │ ├── playlists/ │ ├── videos/ │ ├── enrollments/ │ └── stats/ ├── api/ # API routes for server operations └── videoplayer/ # Video player page components/ ├── app-sidebar.tsx # Main navigation sidebar ├── site-header.tsx # Top header with breadcrumbs ├── nav-main.tsx # Primary navigation menu ├── nav-secondary.tsx # Secondary navigation items ├── nav-user.tsx # User profile dropdown ├── login-form.tsx # Google OAuth login form ├── data-table.tsx # Advanced data table component ├── hls.tsx # Video player (HLS streaming) ├── chart-area-interactive.tsx # Interactive chart component ├── comments-section.tsx # Comments/discussion area ├── admin-notifications.tsx # Admin notifications ├── ui/ # shadcn/ui components │ ├── button.tsx │ ├── card.tsx │ ├── sidebar.tsx │ ├── input.tsx │ ├── label.tsx │ ├── badge.tsx │ ├── dropdown-menu.tsx │ ├── dialog.tsx │ ├── drawer.tsx │ ├── table.tsx │ ├── tabs.tsx │ ├── carousel.tsx │ ├── chart.tsx │ ├── select.tsx │ ├── checkbox.tsx │ ├── field.tsx │ ├── collapsible.tsx │ └── ... (27+ components) lib/ ├── utils.ts # Utility functions (cn for className merging) ├── auth-options.ts # NextAuth configuration ├── auth-check.ts # Authentication helpers ├── prisma.ts # Prisma client └── video-urls.ts # Video URL generation hooks/ ├── use-mobile.ts # Mobile breakpoint hook ├── useVideo.ts # Video data hooks ├── usePlaylists.ts # Playlist data hooks └── usePlaylist.ts # Single playlist hook public/ ├── icon.svg # App icon ├── vault.png # Vault image (login page) └── vault.exr # Vault image (high-res) ``` ### Component Structure Pattern **Server Component (pages):** ```tsx // app/dashboard/page.tsx import { requireUser } from '@/lib/auth-check'; import DashboardClient from './dashboard-client'; export default async function DashboardPage() { const session = await requireUser('/login'); return ; } ``` **Client Component (content):** ```tsx // app/dashboard/dashboard-client.tsx 'use client'; import React from 'react'; import { AppSidebar } from '@/components/app-sidebar'; import { SiteHeader } from '@/components/site-header'; import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'; export default function DashboardClient() { return (
{/* Page content */}
); } ``` --- ## 3. Color System & Theming ### CSS Variables (OKLch Color Space) The design system uses **OKLch color space** for perceptually uniform colors across light and dark modes. **Light Mode (`:root`):** ```css --background: oklch(1 0 0); /* White */ --foreground: oklch(0.141 0.005 285.823); /* Near Black */ --card: oklch(1 0 0); /* White */ --card-foreground: oklch(0.141 0.005 285.823); /* Near Black */ --primary: oklch(0.646 0.222 41.116); /* Warm Yellow/Orange */ --primary-foreground: oklch(0.98 0.016 73.684); /* Light cream */ --secondary: oklch(0.967 0.001 286.375); /* Light gray */ --secondary-foreground: oklch(0.21 0.006 285.885); --muted: oklch(0.967 0.001 286.375); /* Light gray (buttons, etc) */ --muted-foreground: oklch(0.552 0.016 285.938); /* Medium gray (text) */ --accent: oklch(0.967 0.001 286.375); /* Light gray */ --accent-foreground: oklch(0.21 0.006 285.885); --destructive: oklch(0.577 0.245 27.325); /* Red */ --border: oklch(0.92 0.004 286.32); /* Light gray */ --input: oklch(0.92 0.004 286.32); /* Light gray */ --ring: oklch(0.75 0.183 55.934); /* Orange/Gold for focus */ ``` **Dark Mode (`.dark`):** ```css .dark { --background: oklch(0.141 0.005 285.823); /* Near Black */ --foreground: oklch(0.985 0 0); /* White */ --card: oklch(0.21 0.006 285.885); /* Dark gray */ --card-foreground: oklch(0.985 0 0); /* White */ --primary: oklch(0.705 0.213 47.604); /* Lighter Orange */ --secondary: oklch(0.274 0.006 286.033); /* Dark gray */ --muted: oklch(0.274 0.006 286.033); /* Dark gray */ --muted-foreground: oklch(0.705 0.015 286.067); --border: oklch(1 0 0 / 10%); /* White with 10% opacity */ --input: oklch(1 0 0 / 15%); /* White with 15% opacity */ --ring: oklch(0.408 0.123 38.172); /* Red-orange for focus */ } ``` ### Chart Colors ```css --chart-1: oklch(0.837 0.128 66.29); /* Warm yellow */ --chart-2: oklch(0.705 0.213 47.604); /* Orange */ --chart-3: oklch(0.646 0.222 41.116); /* Dark orange */ --chart-4: oklch(0.553 0.195 38.402); /* Red-orange */ --chart-5: oklch(0.47 0.157 37.304); /* Deep red-orange */ ``` ### Sidebar Colors ```css --sidebar: oklch(0.985 0 0); --sidebar-foreground: oklch(0.141 0.005 285.823); --sidebar-primary: oklch(0.646 0.222 41.116); --sidebar-primary-foreground: oklch(0.98 0.016 73.684); --sidebar-accent: oklch(0.967 0.001 286.375); --sidebar-accent-foreground: oklch(0.21 0.006 285.885); --sidebar-border: oklch(0.92 0.004 286.32); --sidebar-ring: oklch(0.75 0.183 55.934); ``` ### Color Usage | Color | Usage | |-------|-------| | **Primary** | Main CTA buttons, active links, selected items | | **Secondary** | Secondary buttons, badges | | **Muted** | Disabled states, placeholder text, subtle backgrounds | | **Accent** | Hover states, subtle highlights | | **Destructive** | Delete buttons, error states | | **Ring** | Focus indicators, form input focus | --- ## 4. Layout System ### Main Layout Structure The application uses a **sidebar + content** layout pattern: ``` ┌─────────────────────────────┐ │ SidebarProvider │ ├──────────┬──────────────────┤ │ │ │ │AppSidebar│ SidebarInset │ │ ├──────────────────┤ │ │ SiteHeader │ │ Logo │ (breadcrumbs) │ │ Nav ├──────────────────┤ │ Items │ │ │ │ Main Content │ │ Footer │ │ │ (User) │ │ │ │ │ └──────────┴──────────────────┘ ``` ### Layout Implementation ```tsx // Standard page layout export default function DashboardClient() { return (
{/* Page content */}
); } ``` ### Content Container Sizing ```tsx // Wide content area with centered max-width
{/* Content */}
// Grid layout patterns
{/* Columns adjust: 1 on mobile, 3 on desktop */}
{/* Responsive grid: 1 → 2 → 3 columns */}
``` --- ## 5. Navigation & Sidebar ### AppSidebar Component Located in `components/app-sidebar.tsx` **Features:** - Collapsible sidebar (offcanvas mode on mobile) - Uses `next-auth` for user session and roles - Dynamic navigation based on user role (admin/superadmin/user) - Logo and brand in header - User profile footer with avatar **Navigation Items:** **For Regular Users:** - Library → `/dashboard` - Liked Videos → `/dashboard/liked-videos` - History → `/dashboard/watch-history` - Search → `#` (secondary item) **For Admins/Superadmins (Additional):** - Admin (collapsible parent with submenu): - Manage Users → `/admin/users` - Manage Enrollments → `/admin/enrollments` - Manage Courses → `/admin/courses` - Manage Playlists → `/admin/playlists` - Manage Videos → `/admin/videos` ### SiteHeader Component Located in `components/site-header.tsx` **Features:** - Responsive breadcrumb navigation - Sidebar toggle trigger button - Dynamic breadcrumbs based on current route - Breadcrumb mapping for all main routes **Breadcrumb Pattern:** ``` Dashboard Dashboard > Liked Videos Dashboard > Watch History Admin Panel Admin Panel > Users > User Details Admin Panel > Videos > Edit Video ``` ### NavMain Component Located in `components/nav-main.tsx` **Features:** - Collapsible menu items with expandable submenus - Icon support (Tabler icons) - Smooth transitions with chevron rotation - Accessible keyboard navigation ```tsx // Usage ``` ### NavSecondary Component Located in `components/nav-secondary.tsx` For secondary navigation items (Search, Help, etc.) ### NavUser Component Located in `components/nav-user.tsx` **Features:** - User avatar display - User name and email - Dropdown menu with user actions - Sign out button - Accessible user menu --- ## 6. Page Layouts ### Login Page **Location:** `app/login/page.tsx` **Layout Structure:** ``` Centered Container (min-h-screen, flex-col) ├── Brand Logo + Text (top) ├── Vault Image └── Login Form (Card with Google OAuth button) ``` **Styling:** ```tsx
{/* Content */}
``` **Key Features:** - Centered, max-width container (sm = 448px) - Muted background color - Responsive padding (6 on mobile, 10 on desktop) - Logo + app name at top - Vault imagery - Google OAuth login form in card ### Dashboard Page **Location:** `app/dashboard/page.tsx` (server) → `dashboard-client.tsx` (client) **Layout Structure:** ``` Sidebar + Content Layout ├── AppSidebar └── SidebarInset ├── SiteHeader (breadcrumbs) └── Main Content ├── Hero Section (Welcome) ├── Video Carousels (by course/playlist) ├── Segmented Progress Bars └── Lock indicators for restricted content ``` **Content Structure:** ```tsx
{/* Section: Welcome/Title */}

Welcome back, {userName}

Continue your learning

{/* Section: Courses/Playlists with Video Carousels */} {playlists.map(playlist => (

{playlist.title}

{/* Video cards with progress bars */}
))}
``` ### Admin Page **Location:** `app/admin/page.tsx` (server) → `admin-client.tsx` (client) **Layout Structure:** ``` Sidebar + Content Layout ├── AppSidebar (with Admin menu) └── SidebarInset ├── SiteHeader (breadcrumbs) └── Main Content ├── Page Title & Description ├── Grid of Management Cards (2-3 columns) │ ├── Video Statistics Card │ ├── Manage Users Card │ ├── Manage Courses Card │ ├── Manage Playlists Card │ ├── Manage Videos Card │ └── Manage Enrollments Card └── Admin Notifications (right sidebar) ``` **Admin Grid Layout:** ```tsx
{/* Admin cards */}
``` --- ## 7. Component Library ### shadcn/ui Components The following pre-built components are used throughout the application: | Component | Used For | |-----------|----------| | **Button** | CTAs, form submissions, interactive elements | | **Card** | Container for content sections | | **Input** | Text input fields | | **Label** | Form labels | | **Badge** | Tags, status indicators, trending indicators | | **Sidebar** | Main navigation (with collapsible support) | | **Dropdown Menu** | User menus, action menus | | **Dialog** | Modal dialogs | | **Drawer** | Mobile-friendly off-canvas menus | | **Table** | Data tables with sorting, filtering, pagination | | **Tabs** | Tab navigation | | **Carousel** | Image/video sliders | | **Chart** | Data visualization (AreaChart, BarChart, etc.) | | **Select** | Dropdown select fields | | **Checkbox** | Multi-select checkboxes | | **Form/Field** | Form field containers and validation | | **Collapsible** | Expandable/collapsible sections | | **Progress** | Progress bars | | **Avatar** | User profile pictures | | **Separator** | Visual dividers | | **Toast/Sonner** | Toast notifications | | **Tooltip** | Info tooltips | ### Custom Components **HlsPlayer** (`components/hls.tsx`) - HLS video streaming with fallback to MP4 - Subtitle/caption support - Controls with no-download protection - Used in: Video player pages **DataTable** (`components/data-table.tsx`) - Advanced table with sorting, filtering, pagination - Column visibility toggle - Drag-and-drop row reordering (via dnd-kit) - Export functionality - Used in: Admin management pages (Users, Videos, Courses, etc.) **SegmentedProgressBar** (`components/segmented-progress-bar.tsx`) - Shows watched segments of video - Visual indication of progress across duration - Used in: Dashboard video carousels **VideoCarousel** (`components/VideoCarousel.tsx`) - Embla carousel-based video slider - Responsive grid layout - Lock indicators for restricted content - Used in: Dashboard, video listings **CommentsSection** (`components/comments-section.tsx`) - Comments display and threading - Used in: Video player pages **LoginForm** (`components/login-form.tsx`) - Google OAuth integration - Card-based layout - Terms and privacy links - Used in: Login page --- ## 8. Typography & Spacing ### Font Families The project uses **Geist** font family (Next.js default): - `--font-sans: var(--font-geist-sans)` - Primary (body text, UI) - `--font-mono: var(--font-geist-mono)` - Monospace (code, technical text) Imported in `layout.tsx`: ```tsx import { Geist, Geist_Mono } from "next/font/google"; ``` ### Typography Scale | Element | Class | Size | Weight | Usage | |---------|-------|------|--------|-------| | H1 | `.text-3xl` | 30px | bold (700) | Page titles | | H2 | `.text-2xl` | 24px | bold (700) | Section titles | | H3 | `.text-xl` | 20px | semibold (600) | Subsection titles | | H4 | `.text-lg` | 18px | semibold (600) | Card titles | | Body | `.text-base` | 16px | normal (400) | Body text | | Small | `.text-sm` | 14px | normal (400) | Labels, captions, secondary text | | Extra Small | `.text-xs` | 12px | normal (400) | Tiny labels | ### Spacing Scale Tailwind default spacing (4px base): | Class | Size | |-------|------| | `gap-1` | 4px | | `gap-2` | 8px | | `gap-3` | 12px | | `gap-4` | 16px | | `gap-6` | 24px | | `gap-8` | 32px | | `p-4` | 16px padding | | `p-6` | 24px padding | | `py-4` | 16px vertical padding | | `px-4` | 16px horizontal padding | ### Text Opacity/Color Hierarchy ```tsx // Primary text

Main content

// Secondary text

Secondary info

// Subtle text Caption ``` --- ## 9. Form Patterns ### Login Form Pattern Located in `components/login-form.tsx` ```tsx
Welcome Please login with your account
By continuing, you agree to our Terms of Service and Privacy Policy
``` ### Admin Form Patterns Located in `app/admin/*/` directories **Data Table Integration:** ```tsx ``` **Modal Form Pattern:** ```tsx Create New Item
{/* Form fields */}
``` --- ## 10. Responsive Design ### Tailwind Breakpoints ``` sm: 640px md: 768px lg: 1024px xl: 1280px 2xl: 1536px ``` ### Mobile-First Approach All responsive classes use mobile-first convention: ```tsx // Mobile: 1 column, Tablet: 2 columns, Desktop: 3 columns
{/* Content */}
// Mobile: padding-4, Desktop: padding-6
{/* Content */}
// Mobile: hidden, Desktop: visible ``` ### Mobile-Specific Components - **Drawer** - Off-canvas menus on mobile (instead of Dialog) - **Sidebar Collapsible** - Sidebar collapses to mobile menu on small screens - **useMobile Hook** - `hooks/use-mobile.ts` for React-based breakpoint logic ```tsx const isMobile = useIsMobile(); return isMobile ? : ; ``` ### Container Queries Used for responsive component sizing: ```tsx

Responsive heading

``` --- ## 11. Dark Mode Implementation ### Theme Provider Setup Located in `app/providers.tsx`: ```tsx defaultTheme="dark" // Dark by default enableSystem={false} // Don't auto-detect system preference > {children} ``` ### Dark Mode Styling CSS variables automatically switch in `.dark` class: ```tsx // Light mode (automatic) :root { --background: oklch(1 0 0); /* White */ --foreground: oklch(0.141 0.005 285.823); /* Dark gray */ } // Dark mode (when .dark is on ) .dark { --background: oklch(0.141 0.005 285.823); /* Dark gray */ --foreground: oklch(0.985 0 0); /* White */ } ``` ### Toggle Theme Button Pattern ```tsx // In component const { theme, setTheme } = useTheme(); ``` --- ## 12. Reusable Patterns ### Protected Page Pattern **Server Component (checks auth):** ```tsx // app/dashboard/page.tsx import { requireUser } from '@/lib/auth-check'; import DashboardClient from './dashboard-client'; export default async function DashboardPage() { const session = await requireUser('/login'); return ; } ``` **Client Component (renders content):** ```tsx // app/dashboard/dashboard-client.tsx 'use client'; import React from 'react'; import { AppSidebar } from '@/components/app-sidebar'; import { SiteHeader } from '@/components/site-header'; export default function DashboardClient() { return (
); } ``` ### Role-Based Navigation Located in `components/app-sidebar.tsx`: ```tsx const { data: session } = useSession(); const role = session?.user?.role ?? 'user'; const navMain = React.useMemo(() => { const base = [...navMainBase]; if (role === 'admin' || role === 'superadmin') { base.unshift({ title: 'Admin', url: '/admin', icon: IconShieldCheck, items: [/*submenu items*/] }); } return base; }, [role]); ``` ### Session Initialization Located in `app/layout.tsx`: ```tsx export default async function RootLayout({ children }) { // Get server session once, pass to client providers const session = await getServerSession(authOptions); return ( {children} ); } ``` ### Data Fetching Pattern Using `useFetch`/SWR for client-side data: ```tsx // hooks/usePlaylists.ts export function usePlaylists() { const [subjects, setSubjects] = React.useState([]); const [isLoading, setIsLoading] = React.useState(true); React.useEffect(() => { fetchPlaylists().then(data => { setSubjects(data); setIsLoading(false); }); }, []); return { subjects, isLoading }; } // Usage in component export default function DashboardClient() { const { subjects, isLoading } = usePlaylists(); if (isLoading) return ; return <>{/* Content */}; } ``` ### Carousel Pattern ```tsx // Embla-based carousel {videos.map(video => ( ))} ``` ### Badge & Status Pattern ```tsx // Icon + Badge combination
+12.5%
// Status badge {status} ``` --- ## 13. Asset Guidelines ### Logo & Branding - **Icon**: `/public/icon.svg` - Small 5x5 size in sidebar header - **Vault Image**: `/public/vault.png` - 1:1 aspect ratio for login page - **High-Res Alternative**: `/public/vault.exr` - For promotional use ### Image Optimization ```tsx // Use Next.js Image for optimization import Image from 'next/image'; Description // Regular images Icon ``` ### Approved Icon Sets 1. **Tabler Icons** (`@tabler/icons-react`) - Primary - Large collection (4000+) - Consistent stroke weight - Import: `import { IconHome, IconUsers } from '@tabler/icons-react';` 2. **Lucide React** (`lucide-react`) - Secondary - Modern, clean icons - Import: `import { Home, Users } from 'lucide-react';` 3. **SVG Files** - Custom branding - Small icons in public/ - Optimized for performance ### Sizing Conventions ```tsx // Icon sizes /* 12px */ /* 16px */ /* 20px */ /* 24px */ /* 32px */ // Image sizes /* Full width */ /* Max 448px */ /* Max 512px */ ``` --- ## Quick Reference - Common Patterns ### Button Variants ```tsx ``` ### Card Layout ```tsx Title Subtitle {/* Content */} {/* Footer */} ``` ### Container Classes ```tsx // Full width className="w-full" // Max width containers className="w-full max-w-sm" /* 448px */ className="w-full max-w-md" /* 512px */ className="w-full max-w-lg" /* 576px */ className="w-full max-w-2xl" /* 672px */ // Flex containers className="flex flex-col gap-4" className="flex items-center justify-between" // Grid containers className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" ``` ### Responsive Padding ```tsx className="p-4 md:p-6 lg:p-8" /* All sides */ className="px-4 py-6" /* Horizontal & vertical */ className="p-4 md:py-6 md:px-8" /* Different per breakpoint */ ``` ### Text & Styling ```tsx className="text-foreground" /* Main text */ className="text-muted-foreground" /* Secondary text */ className="text-sm text-muted-foreground" /* Label text */ className="font-semibold" /* Bold text */ className="line-clamp-1" /* Truncate to 1 line */ className="text-center" /* Centered text */ ``` --- ## Migration Checklist for New Projects When creating a new app with this design system: - [ ] Copy `globals.css` (CSS variables) - [ ] Copy `tailwind.config.cjs` - [ ] Copy `components/ui/` directory (all base components) - [ ] Copy `components/app-sidebar.tsx`, `site-header.tsx`, `nav-*.tsx` - [ ] Copy `app/providers.tsx` (SessionProvider, ThemeProvider) - [ ] Copy `lib/utils.ts` (utility functions) - [ ] Copy `lib/auth-options.ts` and auth-related files - [ ] Install dependencies from `package.json` - [ ] Update branding assets (/public icons, logos) - [ ] Customize navigation items in `app-sidebar.tsx` - [ ] Update theme colors in `globals.css` if needed - [ ] Test responsive design on mobile/tablet/desktop --- ## Key Takeaways 1. **Framework**: Next.js 16 with shadcn/ui component library 2. **Styling**: Tailwind CSS with OKLch color variables 3. **Layout**: Sidebar + content pattern with collapsible nav 4. **Dark Mode**: CSS class-based switching with automatic variable updates 5. **Components**: Pre-built shadcn/ui components + custom components (HLS, DataTable, etc.) 6. **Responsiveness**: Mobile-first, Tailwind breakpoints (sm/md/lg/xl) 7. **Navigation**: Role-based dynamic nav, breadcrumb system 8. **Auth**: NextAuth.js with Google OAuth integration 9. **Icons**: Tabler Icons (primary), Lucide (secondary) 10. **Consistency**: Use className patterns, spacing scale, and color variables throughout --- **Last Updated**: February 2026 **Version**: 1.0 For questions or updates to this design system guide, refer to the component files and config files referenced throughout.