Internal reference

A system for evidence-first software.

Sober monochrome chrome. Color reserved for data. One family, one focus ring, one radius. Every component below mounts the real primitive from @evalgist/design-system — if the package drifts from the spec, this page breaks.

Evalgist·Design system·v0·Geist Sans · Geist Mono
02Principles

The system agrees on these before anything else.

Principle 01
Evidence, not verdicts

Every AI judgment is anchored to a literal quote or reference from the source. The product surfaces evidence so the human can defend the decision to a candidate, a student, or an auditor.

Principle 02
Privacy is a claim with a receipt

External surfaces name concrete data handling: EU storage, no AI-provider retention, public service-provider lists, and deletion rules for extracted document text. Avoid “privacy by design” unless the page also shows what that means.

Principle 03
Monochrome chrome

Chrome is slate-and-white. Color is semantic and used only on data — confidence bands, status, score. Decoration stays monochrome.

Principle 04
Bands, not scores

Percentages are deliberately not shown. Candidates fall into Likely match, Uncertain, or Unlikely match — a shape a reviewer can argue about, not a decimal that pretends to be truth.

Principle 05
One family, one focus ring

Geist Sans for everything UI. Focus is a neutral 2px ring at 30% opacity — never chromatic. Radius is 10px for cards, inputs, buttons; 9999px for pills and dots. No exceptions without a reason.

Principle 06
Quiet motion

Short, mechanical, monochrome. 150–200ms transitions on hover. No bounces, no springs, no fade-ins on page load. Accent animation is reserved for state: the footer live dot, the “Processing” chip.

Principle 07
Text is the hard floor

Ambient decoration — the hero grid, background patterns — declares the text region as an exclude zone. Inside that rectangle, nothing animates. Around it, a feather band scatters the boundary so decoration dissolves into the copy instead of butting against a straight edge. The text region is authoritative; ornament is probabilistic outside it. On phones, decoration is cut entirely — the text takes the full width and reads without peripheral motion.

03Color

Slate is the product. Color is the data.

Chrome is fully monochrome. The moment color appears, it means something — a band, a status, a verdict. Always paired with a label; never the only indicator.

Neutral rail — chrome, surfaces & type

Slate 50 → 900
slate-50#f8fafc
Page bg
slate-100#f1f5f9
Muted
slate-200#e2e8f0
Border
slate-300#cbd5e1
Hairline
slate-400#94a3b8
Placeholder
slate-500#64748b
Muted text
slate-600#475569
Body
slate-700#334155
Emphasis
slate-800#1e293b
Deep
slate-900#0f172a
Titles

Primary — near-black

Actions, focus anchor
--eg-primary
oklch(0.205 0 0)

Semantic — color on data only

100 fill · 200 border · 800 text
Emerald
Likely match · shortlisted · complete
Amber
Uncertain · partial · warning
Red
Unlikely match · rejected · error
Sky
Processing · analyzing

Abandoned directions

Do not reintroduce
Violet accent · retired
Indigo-600 · retired
04Type

One family. A deliberate scale. Tabular numbers everywhere that counts.

Geist Sans for UI, Geist Mono for tabular and code-ish content. The scale is Tailwind-aligned and used sparingly — three sizes per screen is enough almost always.

The scale

Geist Sans
Hero (clamp)
clamp 56 → 84px
Evalgist
H1
24px
Review results
Lede
17px
A shortlist backed by evidence — per qualification, per candidate.
Body
14px
Per candidate, per qualification. Evidence anchored to the source document.
Muted
14px
10 of 32 reviewed
Mono
13px
bg-primary text-primary-foreground
Caption
10px
CRITERIA · NOTES · GIST

Tabular numbers

Stats, progress, counts
147
Resumes analyzed
12
Likely match
2.4 s
Median per CV
05Shape

Ten-pixel corners. Shadows so light they almost aren't there.

Shape is quiet — the point is content, not chrome. Shadows are hover-reveal only; nothing glows, nothing floats at rest.

Radii

--eg-radius family
sm
6px
menu item
md
8px
dropdown
lg
10px
card · input · button
xl
14px
large card
full
9999px
pill · dot · avatar

Shadows

Hover-reveal only
xs
--eg-shadow-xs
outline button
sm
--eg-shadow-sm
card on hover
md
--eg-shadow-md
auth card · dialog
06Space

A 4-pixel grid. A six-pixel gutter. A page that breathes.

Card padding is p-6 (24px). Section stack is space-y-6. Page max is 72rem (max-w-6xl). Everything else falls out of the 4-pixel grid.

Spacing scale

Tailwind-aligned
1
0.25rem
4px
2
0.5rem
8px
3
0.75rem
12px
4
1rem
16px
5
1.25rem
20px
6
1.5rem
24px
8
2rem
32px
12
3rem
48px

Two surface modes

Pages vs. workspaces
Page mode

Dashboard, settings, credits, new position. max-w-6xl mx-auto px-6 py-6. Card-based, page-level scrolling. Users pass through quickly.

Workspace mode

Candidate review. Full-width master-detail with independent panel scrolling. Users spend time here.

07Icons

Lucide. 1.5px stroke. Sixteen pixels unless there's a reason otherwise.

One icon set, stroke-based, neutral weight. Always paired with a label or used in a known slot. No sparkle, no emoji, no unicode as icon (except → and · as glyphs).

The working set

lucide-react · 16 px
LayoutDashboard
Sidebar
PlusCircle
New position
Coins
Credits
Settings
Settings
FileText
Resume · document
ChevronLeft
Prev candidate
ChevronRight
Next candidate
ChevronsUpDown
Expand all
Download
Export
AlertTriangle
Parse warning
Menu
Mobile nav
08Voice

Write like someone who knows they're right and doesn't need to raise their voice.

Sober, self-assured, lightly dry. Short sentences. Closer to The Economist than to TechCrunch. No superlatives, no startup language, no emoji, no exclamation marks.

Same meaning, two voices

Real strings from the product
Hero
Wrong
Revolutionize hiring with AI-powered candidate screening!
Right
From applications to shortlist. Fast and fair.
Empty state
Wrong
Oops! No positions found. Get started by creating one now! 🚀
Right
No positions yet. Create your first position to start screening resumes.
Status
Wrong
AI analysis is happening — hold tight, we are working some magic for you...
Right
Analyzing · 22 of 147
Button
Wrong
Unleash the Power →
Right
Start for free

Vocabulary

The list we actually ship from
Use
evidenceevaluateshortlistgradeconsistentfairfasterper criterionper candidateper answerreviewdecideverifyprofessional
Avoid
revolutionarygame-changingunleashsuperchargeseamlesslyeffortlessly10xcutting-edgenext-generationdisruptiveAI sparklemagical
09Don'ts

The shortest route to getting the system wrong.

A short list of the mistakes we keep catching in review. Each one looks small; together they are what separates 'looks like Evalgist' from 'looks like a dashboard'.

Color on data only

Never use an accent color on chrome — no colored nav, no colored cards, no colored borders. When in doubt, use slate.

Bands, not scores

Don't show 87%. Show Likely match. A reviewer can argue about a band; a decimal pretends to be truth.

Active state: weight, not pill

The active sidebar item gets font-medium + text-foreground. No pill background, no left bar, no rounded highlight. The absence of decoration is the decoration.

Empty states earn their keep

Every empty state tells the reader what's there and what to do next. Two short sentences. No mascot, no “Oops!”, no exclamation.

10Buttons

Four variants. One size by default. The primary is near-black.

Every button below is the real <Button> from @evalgist/design-system. If a variant gets renamed or removed, this page will stop compiling.

Variants

primary · outline · ghost · destructive

Sizes & states

sm · default · lg · icon · disabled

With glyph

Gap is 8px; icons are 16 px
11Badges

Four jobs. Four palettes. Always paired with a glyph or a label.

Every badge below is the real <Badge> from the package — if the cva config drifts, these chips will look wrong or the build will fail.

Job status

Lifecycle of a position
DraftAnalyzingCompleteError

Confidence bands

Replaces a numeric score
Likely matchUncertainUnlikely match

Qualification verdict

Per criterion, per candidate
MetPartialMissedUnknown

Candidate status

Reviewer's verdict
ShortlistedRejectedUndecided

Generic shadcn variants

DefaultSecondaryDestructiveOutline
12Inputs

Slate border, white fill, near-black text, neutral focus ring.

Real <Input>, <Label>, and <Select> from the package. The focus ring is the canonical neutral 2px at 30% — never chromatic.

Form fields

Select

13Cards

White fill. Slate-200 border. Ten-pixel corners. Lifts only on hover.

All real <Card*> primitives from the package. Padding is p-6 (roomy) or p-4 (dense).

Dense — job card

dashboard
Senior data engineer · Ghent
Opened 2 days ago · 147 resumes analyzed
Complete
12 Likely match48 Uncertain87 Unlikely
Reviewed: 10 of 147

Roomy — auth card

standalone
Welcome back
Sign in to continue reviewing.
14Primitives

Shared primitives for dense product surfaces.

Batch A and B primitives cover status, menus, tables, confirmations, forms, and notifications. Product-specific rows, filters, and panels stay in the app.

Alert and tooltip

status · explanation

Dropdown menu

actions
Senior data engineer
147 candidates · last analyzed today

Table

candidate list
CandidateBandEvidenceStatus
Anika VerbruggenLikely match4 quotesReviewed
Milan PeetersUncertain3 quotesNeeds check
Sara BenaliUnlikely match2 quotesQueued

Skeleton

loading state
Analyzing uploaded resumes

Confirmations

alert dialog
Archive position
Confirmation is explicit when the action changes evidence state.

Confirm dialog

destructive · async pending
Neutral confirmation
Default variant. The confirm button uses the primary action style.
Destructive confirmation
Async confirm. The dialog shows a pending state and stays open if the action throws.

Form primitives

checkbox · textarea · message

Keep notes factual and anchored to evidence.

The human decision remains separate from the AI band.

Review workspace

tabs · sheet · popover · toggles
Four quotes support the current band. One quote needs reviewer confirmation.
Resume
Document excerpt and highlighted quote.
Evidence
Band rationale and reviewer controls.
15Chrome

Navigation that disappears once you know where you are.

Sidebar and topbar are Shortlist-specific, so they don't live in the shared package. They're shown here as a reference for how the tokens and primitives compose.

Sidebar — expanded

Active state is weight, not pill
Dashboard
Open positions
Dashboard content lives in apps/shortlist.
16Confidence

Three bands. Four qualification verdicts. One progress bar that tells the story.

Confidence is a band, not a percentage — shown in English, backed by evidence. Progress is the <Progress> primitive; the band is a <Badge>.

Match bands

Per candidate · always with a label
Anna De Smet
Likely match
5/6 met
Pieter Vermeulen
Uncertain
3/6 met
Laila El-Khatib
Likely match
5/6 met
Yves Maes
Unlikely match
1/6 met

Qualification verdicts

Per criterion
5+ years SQLData warehousingCloud certificationBelgian driver's license