Files
vfxreview/STYLEGUIDE.md
T
twotalesanimation 0fbe856dce Initial commit
2026-05-19 22:20:29 +02:00

11 KiB

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 <html>). 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 <html>.

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

<div className="mb-8">
  <h1 className="text-3xl font-bold text-white">Page Title</h1>
  <p className="text-zinc-400 mt-1">Subtitle / description.</p>
</div>

Detail Page Top Bar

<div className="border-b border-zinc-800 px-8 py-4 flex items-center gap-4 bg-zinc-950">
  {/* back arrow + title + meta + actions */}
</div>

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

<Card className="bg-zinc-900 border-zinc-800">
  <CardHeader>
    <CardTitle></CardTitle>
    <CardDescription></CardDescription>
  </CardHeader>
  <CardContent></CardContent>
</Card>
  • 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

<Badge className="bg-green-900/60 text-green-300">Approved</Badge>
  • Custom status colours applied via className override (see §3 Semantic/Status Badges).
  • Default shape: pill (rounded-4xl), h-5, text-xs.

Form Fields

<div className="space-y-1.5">
  <Label>Field Label *</Label>
  <Input className="bg-zinc-900 border-zinc-700" placeholder="…" />
  {error && <p className="text-red-400 text-xs">{error.message}</p>}
</div>
  • 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 <table> 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 <Table> component uses text-sm and standard border-b between rows.

Tabs

<Tabs defaultValue="…">
  <TabsList>
    <TabsTrigger value="…">Label</TabsTrigger>
  </TabsList>
  <TabsContent value="…"></TabsContent>
</Tabs>
  • 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 (<Toaster richColors position="top-right" />)
  • 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:

<button onClick={() => setExpanded(!expanded)}>
  {expanded ? <ChevronDown /> : <ChevronRight />}
</button>

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