Component Library · Brand Guide

The Hodget design system

Our internal component library — colors, type, buttons, badges and forms — built on shadcn and Base UI with our own tokens. Every example is live; hover a code chip to copy the class.

Geist / Inter / Geist MonoTailwind CSS v4OKLCH tokens
01 · Foundations

Color tokens

Semantic tokens are OKLCH CSS variables consumed through Tailwind utilities like bg-muted or text-muted-foreground. They flip automatically in dark mode.

Surfaces
bg-background
--background
bg-card
--card
bg-muted
--muted
bg-secondary
--secondary
bg-accent
--accent
bg-primary
--primary
Content (text)
Ag
text-foreground
--foreground
Ag
text-muted-foreground
--muted-foreground
Ag
text-secondary-foreground
--secondary-foreground
Ag
text-primary-foreground
--primary-foreground
Borders
border-border
--border
border-input
--input
border-ring
--ring
Accent & charts
bg-destructive
--destructive
bg-chart-1
--chart-1
bg-chart-2
--chart-2
bg-chart-3
--chart-3
bg-chart-4
--chart-4
bg-chart-5
--chart-5
02 · Foundations

Typography

Three families. Geist for display headings (font-heading), Inter for UI & body (font-sans), and Geist Mono for code and numerals (font-mono).

Geistfont-heading
Ag
Compounding, on autopilot
400 · 500 · 700 · 900
Interfont-sans
Ag
The quick brown fox
400 · 500 · 600 · 700
Geist Monofont-mono
Ag
run_9f2a10
400 · 500 · 600
Type scale
Compounding, on autopilot
text-4xl
36 / 40
Compounding, on autopilot
text-3xl
30 / 36
Compounding, on autopilot
text-2xl
24 / 32
Compounding, on autopilot
text-xl
20 / 28
Compounding, on autopilot
text-lg
18 / 28
Compounding, on autopilot
text-base
16 / 24
Compounding, on autopilot
text-sm
14 / 20
Compounding, on autopilot
text-xs
12 / 16
03 · Foundations

Radii, shadows & spacing

Radii derive from --radius (0.625rem). Spacing is a 4px base scale. Shadows stay soft and functional.

Border radius
rounded-sm
radius · 0.6
rounded-md
radius · 0.8
rounded-lg
radius · 1.0
rounded-xl
radius · 1.4
rounded-2xl
radius · 1.8
rounded-full
pills · avatars
Shadows
shadow-sm
cards
shadow-md
dropdowns
shadow-lg
popovers, dialogs
Spacing · 4px base
w-1
4px
w-2
8px
w-3
12px
w-4
16px
w-6
24px
w-10
40px
w-14
56px
04 · Components

Buttons

The shadcn Button — six variants and five sizes. Sharp corners, h-8 default, text-xs. Hover any button; copy the variant below.

default
secondary
outline
ghost
destructive
link
Sizes & states
05 · Components

Badges

The shadcn Badge — the standard variants, plus a set of named color variants layered on top. Click a card to copy its variant.

Standard
defaultsecondarydestructiveoutlineghost
Run status · with icons
QueuedRunningCompletedFailed
Color variants
Default
neutral
New
black
Pro
blue
Beta
violet
Active
green
Error
red
Trial
amber
Info
sky
Draft
gray
Upgrade
blueGradient
AI
rainbow
06 · Components

Inputs & forms

Text inputs are h-8, sharp, with a border-input resting border that gains a ring on focus. Checkbox and switch use --primary when active. Everything here is live.

default · focus:ring
type=password · reveal toggle
read-only · font-mono

Please enter a valid email address.

error · aria-invalid
Selection controls
Public analytics
Anyone with the link can view this run’s stats
checkbox · size-4 · checked bg-primary
switch · h-5 w-9 · checked bg-primary
07 · Components

Alerts

The shadcn Alert with AlertTitle / AlertDescription and an optional leading icon. Standard default and destructive, extended with info / success / warning.

08 · Components

Data table

A data table on @tanstack/react-table — sortable headers, row selection with a bulk-action bar, a filter menu + pills, and pagination. This demo runs in memory over a static set of engine runs; the live, session-guarded version is wired through the runs API.

ModeStatus
run_9f2a10Momentum · Large CapBacktest1.82CompletedJun 30, 14:20
run_9f2a11Mean Reversion · ETFPaperRunningJun 30, 13:05
run_9f2a12Value + Quality BlendBacktest2.14CompletedJun 30, 11:47
run_9f2a13Trend Following · FuturesPaperFailedJun 30, 09:12
run_9f2a14Low Volatility · GlobalBacktest0.96CompletedJun 29, 18:40
run_9f2a15Pairs · Sector NeutralBacktestQueuedJun 29, 16:31
12 results · page 1 / 2
09 · Foundations

Animations & motion

Motion is built on Emil Kowalski’s easing blueprint and a five-step duration scale. Entrances favor ease-out-quart; feedback loops stay subtle. Every demo honors prefers-reduced-motion.

Easing · the curve is the feel
ease-out-quart
entrances (default)
ease-out-expo
long, dramatic
ease-in-out-cubic
moves & returns
ease-ios-sheet
sheets & drawers
Duration · 100 → 400ms
--duration-instant
100ms
--duration-fast
150ms
--duration-base
200ms
--duration-slow
300ms
--duration-page
400ms
Entrances · replay on loop
fade-in0.2s · base
scale-in0.2s · base
fade-in-blur0.3s · slow
slide-up-fade0.4s · page
slide-right-fade0.4s · page
Feedback · continuous
wiggle0.75s loop
pulse2s loop
blink1.4s loop
spinner1s loop
10 · Components

Overlays

Floating surfaces that open over the page — modals, side panels, popovers, tooltips, and a command palette.

Dialog
AlertDialog
Sheet
Drawer
Popover
Tooltip
Command
12 · Components

Form controls

The inputs a dashboard actually needs — with Input Group front and center for prefixed URLs, numeric amounts, and inline search.

hodget.dev/
InputGroup — URL
$
USD
InputGroup — amount
InputGroup — search
Select — currency
Combobox
Date Picker
RadioGroup

Visible to your team only.

Field — Textarea
Field — error
K
Kbd
13 · Components

Feedback & status

Loading, progress, notifications, and identity — the small signals that tell people what just happened and who is here.

toast()
<Skeleton />
<Spinner />
x
<Progress />
CH
ABCDEF
+5
<Avatar />
Above
OverviewActivity
<Separator />
<ScrollArea />
14 · Components

Empty states & items

Empty states for zero-data views, and Item rows for lists of content — the building blocks for results, settings, and member lists.

Empty states
No runs
You have not started any runs yet.
Empty — default
All caught up
You have no new notifications.
Empty — outline
No results
Try a different search term.
Empty — input group
CH
Invite your team
No members yet — invite someone to collaborate.
Empty — avatar media
Items
Dashboard

Overview of your workspace.

AB
Alex Brown

alex@acme.com

Strategies

Rendered as a link.

default

variant

outline

variant

muted

variant

15 · Templates

Page templates

Full-page layouts inside the app shell — reuse these as starting points when building a new page. Each pairs a PageHeader with library components inside a shell frame.

List page

Runs

Search, filter, and sort a data table.

RunStrategyModeStatus
run_9f2a12Value + Quality BlendBacktestCompleted
run_9f2a11Mean Reversion · ETFPaperRunning
run_9f2a13Trend Following · FuturesPaperFailed
Detail page

Value + Quality Blend

Backtest · Jun 30, 2026 · 14:20 UTC

Mode

Backtest

Positions

31

Status

Completed · Sharpe 2.14

Empty page

Reports

Export and scheduled reports.

No reports yet
Create your first report to see it here.
Settings page

Settings

Workspace and account.

Shown across the app.

Email notifications
Run summaries and alerts.
16 · Components

File upload

A drag-and-drop surface built on native drag events and a hidden file input — no extra dependencies. The whole surface is clickable and keyboard accessible (Enter/Space opens the file picker), and files over the size limit are rejected via onRejected.

Drag files here or click to choose
CSV, Parquet and JSON
<Dropzone /> + <DropzoneEmpty />
Drag files here or click to choose
Max 5 MB per file
prices.csv
x
0 %
universe.parquet
x
0 %
<Dropzone /> + file list (Item + Progress)
17 · Components

One-time code

Code input for two-factor and verification — one character per slot, with paste support, keyboard navigation, and a clearly marked active slot. The confirm button stays disabled until every digit is filled in.

We sent a 6-digit code to you@example.com.

<InputOTP maxLength={6} /> · 3 + 3 with separator

Enter the 4-digit code from SMS.

<InputOTP maxLength={4} /> · one group
18 · Components

Tree & folders

A composable tree for folder and file navigation. Arrow keys move focus between visible rows, right/left open and close folders, and a single row can be selected. Expand and selected state can be controlled or uncontrolled.

<Tree defaultExpanded selected />
TreeItemTrigger trailing={<Badge />}
19 · Components

Timeline

Activity and audit log — who did what, when. Each event has an icon, an actor, a description, and a timestamp, and the line between the icons hides automatically on the last row.

  1. Committee approved 3 positions

    Portfolio construction passed all risk gates.

  2. Backtest completed

    Momentum · Large Cap finished in 4 minutes.

  3. Risk engine blocked a position

    Exposure limit exceeded for a single name.

  4. Scheduler queued a run

    Momentum · Large Cap, backtest mode.

<Timeline /> — activity log
  1. Backtest completed
  2. Run queued
  3. Position blocked
compact — time right-aligned
20 · Components

Score

Reusable score primitives for conviction and other scoring surfaces. Numbers use font-mono tabular-nums; colors draw only on the existing --chart-* tokens.

Conviction score
78/100
High78
x
<ScoreMeter score={78} />
High86Medium54Low21
<ScoreBadge /> — score band
Momentum
12-month trend positive
22/22
x
Value
P/E below sector median
17/22
x
Quality
ROIC 14%
6/10
x
<SignalBar /> — generic signal list
Sharpe
2.14
backtest
Max DD
8.4%
peak-to-trough
KpiTile pattern — Card + tabular numerals
21 · Components

Charts

Built on recharts via ChartContainer. The color tokens --chart-1--chart-5 are a sequential cyan ramp (light → dark), not a categorical palette — use at most two series per chart (--chart-2 primary, --chart-5 secondary), or--chart-3 alone for a single series. Never five separate categories on five different tokens without direct labels. One y-axis per chart, tooltip always on, legend from two series and up.

Two series max — primary --chart-2, secondary --chart-5. Days are zero-filled, no gaps in the run.

Area chart · 2 series · chart-2 + chart-5

A single series in a light context uses --chart-3 — mid-ramp, neither the lightest nor the darkest.

Bar chart · 1 series, horizontal · chart-3

Four categories with a direct name on each segment (chart-1/chart-3/chart-5 + muted-foregroundfor "other") — never five+ tokens without labels.

Donut · max 4 segments · direct labels
No data yet
Charts appear here as soon as there is activity to show.
Empty dataset — show <Empty />, never a blank chart