# xBid Design System & Style Guide A reference for the visual language, component patterns, and design principles used in xBid so that future apps can maintain the same look and feel. --- ## 1. Core Principles - **Dark-first**: The app is permanently dark mode (`className="dark"` on ``). There is no light/dark toggle. - **Minimal chrome**: Surfaces are dark zinc grays with amber as the single accent colour. No gradients, no heavy decoration. - **Dense but readable**: Data-heavy UI uses compact sizing (`text-xs`, `text-sm`) with generous whitespace in page-level padding. - **Amber accent, zinc foundation**: Brand colour is amber (`#f59e0b` / `amber-500`). All structural surfaces use the zinc palette. --- ## 2. Typography ### Font Family - **Primary (body & UI)**: **Inter** — loaded via `next/font/google`, subset `latin`. - **Mono**: Geist Mono (via `--font-geist-mono` CSS variable from shadcn). - Applied globally: `font-sans` on ``. ### Scale (Tailwind defaults, used in practice) | Usage | Class(es) | Notes | |---|---|---| | Page title | `text-3xl font-bold text-white` | e.g. Dashboard h1 | | Section title | `text-xl font-semibold text-white` | e.g. "Recent Jobs" h2 | | Detail page title | `text-xl font-bold text-white` | Truncated with `truncate` | | Card title | `text-base font-medium` (via `CardTitle`) | | | Body / default | `text-sm` | | | Captions / meta | `text-sm text-zinc-400` or `text-zinc-500` | | | Table headers | `text-xs uppercase tracking-wider text-zinc-500` | | | Table cells | `text-xs` or `text-sm` | | | Error messages | `text-xs text-red-400` | Form validation | | Stat value | `text-3xl font-bold text-white` | Dashboard stat cards | --- ## 3. Colour Palette The app uses **Tailwind CSS v4 with OKLCH CSS variables**. All semantic tokens map to zinc grays in dark mode. ### Brand / Accent | Token | Tailwind class | Hex approx | Usage | |---|---|---|---| | Brand amber | `amber-500` | `#f59e0b` | Logo bg, icon colour | | Active nav highlight | `amber-500/10` bg + `amber-400` text | — | Active nav item | | Amber text | `text-amber-400` | `#fbbf24` | Active nav, stat icons | | Amber text bold | `text-amber-500` | `#f59e0b` | Logo "Bid" wordmark | ### Surface / Layout | Purpose | Tailwind class | Notes | |---|---|---| | Page background | `bg-zinc-950` | Top bar, outermost bg | | Sidebar & card bg | `bg-zinc-900` | Primary surface | | Hover / secondary surface | `bg-zinc-800` | Hover states, secondary card | | Input fields | `bg-zinc-900 border-zinc-700` | Form inputs override | | Borders | `border-zinc-800` | Dividers, card outlines | | Input borders | `border-zinc-700` | Slightly lighter than surface borders | ### Text | Purpose | Tailwind class | Hex approx | |---|---|---| | Primary / headings | `text-white` | `#ffffff` | | Secondary / labels | `text-zinc-400` | `#a1a1aa` | | Tertiary / placeholders | `text-zinc-500` | `#71717a` | | Disabled / subtle | `text-zinc-600` | `#52525b` | | Bright secondary | `text-zinc-300` | `#d4d4d8` | ### Semantic / Status Badges These appear on `Job` and `Invoice` status badges. Pattern: coloured bg at low opacity + matching light text. | Status | Classes | |---|---| | DRAFT | `bg-zinc-700 text-zinc-300` | | SENT | `bg-blue-900/60 text-blue-300` | | APPROVED / PAID | `bg-green-900/60 text-green-300` | | REJECTED / OVERDUE | `bg-red-900/60 text-red-300` | | ARCHIVED | `bg-yellow-900/60 text-yellow-300` | | VIEWED | `bg-purple-900/60 text-purple-300` | | PARTIALLY_PAID | `bg-orange-900/60 text-orange-300` | | CANCELLED | `bg-zinc-800 text-zinc-500` | ### Icon Colours (Dashboard Stats) | Metric | Icon colour | |---|---| | Jobs / Total | `text-amber-400` | | Clients | `text-blue-400` | | Drafts | `text-zinc-400` | | Sent / Pending | `text-yellow-400` | | Approved | `text-green-400` | --- ## 4. Spacing & Layout ### App Shell ``` ┌─────────────────────────────────────────┐ │ Sidebar (w-60 / w-16 collapsed) │ Main content (flex-1 overflow-y-auto) │ bg-zinc-900 │ p-8 on page content │ border-r border-zinc-800 │ └─────────────────────────────────────────┘ ``` - Root: `flex h-full overflow-hidden` - Sidebar: `flex flex-col bg-zinc-900 border-r border-zinc-800 transition-all duration-200` - Main: `flex-1 overflow-y-auto` - Page padding: `p-8` ### Page Header pattern ```tsx

Page Title

Subtitle / description.

``` ### Detail Page Top Bar ```tsx
{/* back arrow + title + meta + actions */}
``` ### Grid layouts | Pattern | Class | |---|---| | Stat cards | `grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5` | | Form fields | `grid grid-cols-1 sm:grid-cols-2 gap-5` | | Form field spacing | `space-y-1.5` (label + input) | | Form section spacing | `space-y-6` | --- ## 5. Border Radius Defined by CSS variable `--radius: 0.625rem` (10px). | Token | Size | Tailwind class | |---|---|---| | sm | ~6px | `rounded-sm` / `rounded` | | md | ~8px | `rounded-md` | | lg | 10px (base) | `rounded-lg` | | xl | ~14px | `rounded-xl` | | 4xl (badges) | ~26px | `rounded-4xl` | **In practice**: `rounded-lg` is the default for buttons, inputs, cards, nav items. Cards use `rounded-xl`. Badges use `rounded-4xl` (pill shape). --- ## 6. Component Patterns ### Sidebar Navigation - Container: `bg-zinc-900 border-r border-zinc-800` - Logo area: `px-4 py-5 border-b border-zinc-800` - Icon: `w-8 h-8 rounded-lg bg-amber-500 flex items-center justify-center` with black icon inside - Wordmark: `font-bold text-lg tracking-tight text-white` — "x" white, "Bid" amber - Nav item inactive: `text-zinc-400 hover:text-white hover:bg-zinc-800 px-3 py-2.5 rounded-lg text-sm font-medium` - Nav item active: `bg-amber-500/10 text-amber-400` - Icon size: `h-4 w-4` ### Cards ```tsx ``` - Card has `ring-1 ring-foreground/10` and `rounded-xl` by default via shadcn base-nova. - Override bg/border on dark surfaces: `bg-zinc-900 border-zinc-800`. ### Buttons Variants from shadcn `buttonVariants`: | Variant | Appearance | |---|---| | `default` | Dark bg (`primary`), light text — effectively `bg-zinc-900 text-white` in dark mode | | `outline` | Border, transparent bg, hover muted | | `secondary` | Muted bg | | `ghost` | No border, hover muted | | `destructive` | Red tinted bg, red text | | `link` | Underline on hover | Sizes: `xs`, `sm`, `default` (h-8), `lg`, `icon`, `icon-xs`, `icon-sm`, `icon-lg`. ### Badges / Status Pills ```tsx Approved ``` - Custom status colours applied via `className` override (see §3 Semantic/Status Badges). - Default shape: pill (`rounded-4xl`), `h-5`, `text-xs`. ### Form Fields ```tsx
{error &&

{error.message}

}
``` - Input base: `h-8 rounded-lg border border-input bg-transparent` — always override with `bg-zinc-900 border-zinc-700` for dark surface visibility. - Textarea, Select follow the same pattern. ### Tables Line-item tables are custom `` elements styled with: - `text-xs w-full` - Header row: `border-b border-zinc-800 text-zinc-500 uppercase tracking-wider` - Cells: `px-4 py-2 text-left` - Alternating/hover rows: use `hover:bg-zinc-800/50` shadcn `
` component uses `text-sm` and standard `border-b` between rows. ### Tabs ```tsx Label ``` - `TabsList` bg: `bg-muted` (zinc-800 in dark), `rounded-lg`. - `TabsTrigger` active: white text, slight bg lift. ### Dialogs / Sheets Standard shadcn `Dialog` / `Sheet`. Content uses `bg-zinc-900` / card surface. Destructive actions use red confirm buttons. ### Toasts / Notifications - Library: **Sonner** (``) - `toast.success(…)` — green - `toast.error(…)` — red - Always called after async actions complete. ### Dropdown Menus Standard shadcn `DropdownMenu`. Destructive actions get `text-destructive` styling on the `DropdownMenuItem`. ### Collapsible / Expandable Rows Shot and asset cards use a chevron toggle (`ChevronDown` / `ChevronRight`) to expand inline line-item tables. Pattern: ```tsx ``` --- ## 7. Icons Library: **Lucide React** (`lucide-react`) Standard icon size: `h-4 w-4` (16px). Larger decorative: `h-5 w-5`. Common icons used: | Purpose | Icon | |---|---| | Dashboard | `LayoutDashboard` | | Clients | `Users` | | Jobs / Quotes | `Briefcase` | | Invoices | `FileText` | | Rate Cards | `CreditCard` | | Settings | `Settings` | | Back | `ArrowLeft` | | Download PDF | `Download` | | Duplicate | `Copy` | | Delete | `Trash2` | | Edit | `Pencil` | | Add | `Plus` | | More options | `MoreHorizontal` | | Search | `Search` | | Loading | `Loader2` (with `animate-spin`) | | Drag handle | `GripVertical` | | App logo | `Film` | | Send | `Send` | | Approve / Mark paid | `Check` / `CheckCircle` | --- ## 8. Motion & Transitions - Sidebar collapse: `transition-all duration-200` - Nav item colour: `transition-colors` - Buttons: `transition-all` - Drag-and-drop (DnD Kit): opacity `0.5` while dragging. - Animation library: `tw-animate-css` (imported in globals.css). --- ## 9. Tech Stack | Layer | Technology | |---|---| | Framework | Next.js 15 (App Router, React Server Components) | | Styling | Tailwind CSS v4 | | Component system | shadcn/ui (`base-nova` style) + `@base-ui/react` primitives | | Icon library | Lucide React | | Font | Inter (Google Fonts via `next/font`) | | Notifications | Sonner | | Forms | React Hook Form + Zod | | Drag & Drop | `@dnd-kit/core` + `@dnd-kit/sortable` | | ORM | Prisma | | DB | PostgreSQL | | Color space | OKLCH (CSS variables) | --- ## 10. Quick Reference — Recurring Class Combinations ``` # Page wrapper p-8 # Page title text-3xl font-bold text-white # Page subtitle text-zinc-400 mt-1 # Section heading text-xl font-semibold text-white mb-4 # Top bar (detail pages) border-b border-zinc-800 px-8 py-4 flex items-center gap-4 bg-zinc-950 # Card (dark surface) bg-zinc-900 border-zinc-800 # Card text hierarchy text-white (value) | text-zinc-400 (label) | text-zinc-500 (meta) # Form input (dark) bg-zinc-900 border-zinc-700 # Form error text-red-400 text-xs # Table header border-b border-zinc-800 text-zinc-500 uppercase tracking-wider text-xs # Empty state text text-center text-sm text-zinc-500 # Active nav bg-amber-500/10 text-amber-400 # Inactive nav text-zinc-400 hover:text-white hover:bg-zinc-800 ```