Internal · Vera UI
Design system
Vera, in pieces.
Every component, every state.
The whole design system on one page so the warm-fintech voice stays honest as the dashboard grows. Tokens, typography, primitives, charts, overlays — all live.
Foundations
Tokens, palette, typography, spacing
Color palette
Surfaces
bg-base
#f5efe6
Page background
bg-card
#fffcf7
Card surface
bg-elevated
#ffffff
Modal / popover
bg-subtle
#ece4d3
Hover / chrome
Text
text-primary
#1f1b16
Headlines, body
text-secondary
#6e6258
Supporting copy
text-muted
#9c8e80
Labels, hints
Lines & accents
border
#e8decf
Dividers, outlines
accent
#c8854e
Primary action
accent-soft
#e8c5a0
Accent on tint
success
#7a8f6f
Positive states
Heat bands
heat-cool
#7a8f6f
0–25 · Cool
heat-warm
#c9a05f
26–50 · Warm
heat-hot
#c8714c
51–75 · Hot
heat-critical
#a14535
76–100 · Critical
Typography
Display · 5xl
Where each install actually stands
Display · 4xl
Who I'd nudge today
Display · 2xl
606 McMackin Street
Body · lg
A thoughtful companion for accounts receivable in the roofing business.
Body · base
Insurance final check still missing — I'd nudge Brandon today.
Body · sm
Brandon Roberts · Dallas · Insurance · 47 days post-install
Caption · xs
Vera will draft a follow-up; nothing autosends.
Eyebrow · 0.65rem
Daily · job milestone tracking
Radii & shadows
0.75rem
radius-input
1.25rem
radius-card · soft shadow
9999px
pill / chip
Vera's voice
A thoughtful narrator, not a dashboard widget
Good morning. I'm watching three jobs more closely than usual today — Mike Ahrend's McMackin install crossed into the Hot band overnight.
Metric tiles
Headline numbers in three emphasis levels
Emphasis variants — default, accent, critical
Total AR
$1.42M
Across 130 installs
Critical
36
Need executive eyes
Hot
28
Vera will draft
Fell through
27
Weekly sweep
Tiles in the same row stretch to a uniform height. hint always reserves space (renders an invisible spacer when omitted).
Value type variants
Currency
$1,278,629
Total outstanding
Integer
130
Jobs in AR
Compact
$496K
Commissions YTD
Empty
—
No data yet
value accepts any ReactNode: strings, numbers, or inline elements (badges, icons, em-dashes for empty states).
Heat — meters & badges
Two presentations of the composite score
HeatMeter · default
HeatMeter · compact (table-row variant)
HeatScoreBadge · two sizes
Charts
Pure SVG, no Recharts dep
BarChart · horizontal
DonutChart
- Cool22 jobs17%
- Warm44 jobs34%
- Hot28 jobs22%
- Critical36 jobs28%
Cards
Plain, with header, and richly composed
Plain card
A plain Card just gives content the warm cream surface, the soft border, and the generous padding.
Card with header
Heat distribution
How the 130 active AR jobs split across the four heat bands today.
Cool 22 · Warm 44 · Hot 28 · Critical 36. Critical accounts for $711K of the $1.42M outstanding.
Job card · rich composition
606 McMackin Street
Brandon Roberts · Dallas · Insurance
$14,995 outstanding · install was 47 days ago. Insurance final check still missing — I'd nudge Brandon today.
Tables
TableShell, sticky head, footer slot
| Job | Rep | Balance | Aging | Heat |
|---|---|---|---|---|
606 McMackin Street Dallas · Insurance | Brandon Roberts | $14,995 | 31–60d | 72Hot |
224 Roy Rogers Lane Shreveport · Insurance | Clemente Mandujano | $5,333 | 60–120d | 88Critical |
1487 Streamside Drive Dallas · Retail | Hernan Cubillos | $6,201 | 1–30d | 42Warm |
Pagination
TablePagination — rows-per-page dropdown, ellipsis, prev/next
Standalone — short list (≤5 pages)
With 5 or fewer pages, every page number renders. No ellipsis.
Standalone — long list (ellipsis kicks in)
Past 5 pages: 1 … (n−1) n (n+1) … last. The rows-per-page dropdown opens upward and supports 10 / 25 / 50 / 100.
Integrated — TableShell footer slot
| Job | Rep | Balance | Aging | Heat |
|---|---|---|---|---|
606 McMackin Street Dallas · Insurance | Brandon Roberts | $14,995 | 31–60d | 72Hot |
224 Roy Rogers Lane Shreveport · Insurance | Clemente Mandujano | $5,333 | 60–120d | 88Critical |
1487 Streamside Drive Dallas · Retail | Hernan Cubillos | $6,201 | 1–30d | 42Warm |
1320 Raleigh Path Dallas · Insurance | Brent Crutchfield | $4,302 | 1–30d | 58Hot |
1011 Thomas Ave Shreveport · Insurance | Fushia McFashion | $3,710 | 60–120d | 81Critical |
Pass a TablePagination into TableShell.footer to get the unified card chrome. Used on Aging, Milestones, Reconciliation, and Rep Leaderboard.
Filter menu
FilterMenu + TableToolbar — chip groups and searchable dropdowns
Live — open and try it
By job — 130 rows
Click Filter to try it
No filters applied.
Both the popover and the inner Rep dropdown render to document.body so they escape every overflow / stacking trap. Marked with data-filter-popover so the click-outside handler keeps them grouped.
Trigger states
Default · with active filter count.
Tabs
Shared underline-style tabs · used on Scheduler + Follow-ups
Hot-band jobs Vera will draft for today (51–75).
Use Tabs / TabsList / Tab / TabsContent from @vera/ui. Controlled (pass value + onValueChange — e.g. wired to a useQueryState) or uncontrolled (just defaultValue). Underline is border-accent with primary text on the active tab; idle tabs are secondary. ARIA roles wired correctly — keyboard navigation works.
Toasts & confirm modals
Transient feedback + replacement for window.confirm()
toast() and useConfirm() from @vera/ui. Sonner-backed, themed in globals.css under [data-sonner-toaster] with Vera tokens. Five toast states share the modal chrome but use distinct silhouettes (filled circle / octagon / triangle / rounded square / arc) so users tell info vs error apart by shape, not just color. Info is the one cool tone in the palette — slate blue --color-info.
Two modal flavors share visual chrome (centered, bg-card, rounded card radius, p-7, shadow) but differ in layout:
- <Modal> — content surface, no icon. Big
font-displaytitle, body owns the layout. Use for chat (Ask Vera), info dialogs, custom forms. See Modals & sheets below for the canonical example. - <ConfirmDialog> — action confirmation, with icon. Same display-serif title as
<Modal>; what signals "confirmation" is the tinted icon blockto the left (accent or heat-critical). Title is imperative, not a question — "Cancel this run", not "Cancel this run?". Description as the body, left-aligned. Close X hidden — user must pick a button. Use viauseConfirm().
Infinite scroll
Card-list pagination via IntersectionObserver
606 McMackin Street
Brandon Roberts · Dallas · Insurance
224 Roy Rogers Lane
Clemente Mandujano · Shreveport · Insurance
1487 Streamside Drive
Hernan Cubillos · Dallas · Retail
1320 Raleigh Path
Brent Crutchfield · Dallas · Insurance
1011 Thomas Ave
Fushia McFashion · Shreveport · Insurance
7101 GR 571
David Jones · Dallas · Retail
Showing 6 of 28 · scroll to load more
Sentinel below the list with IntersectionObserver(rootMargin: 320px) bumps a local visibleCountby chunk size as it scrolls into view. Footer reads "Showing X of Y · scroll to load more" while loading, "All N loaded" once done.
Empty states
What we show when filters or queries return nothing
No filter matches
No jobs match the current filters.
Queue is clear
Executive queue is clear in this view. Nothing has crossed the Critical threshold. Try clearing filters.
Reconciliation — clean board
Nothing fell through this week. Every completed install has at least one fresh signal — paperwork, an endorsed check, a commission request, or a recent edit.
Tooltips
Portaled — escape every overflow / stacking trap
Modals & sheets
Right-side sheet and centered modal
Both overlays render via createPortal to document.body so they escape any ancestor overflow/z-index trap.
Iconography
lucide-react · sized at h-4 / h-3.5
Conventions: h-4 w-4 in nav and tile chrome, h-3.5 w-3.5 for inline button icons, h-3 w-3 for tiny chip glyphs. Icon color usually inherits from the surrounding text color.
Animations
Entrance and attention utilities
Entrance
vera-rise
Fade + 8px translateY on load. The default for hero, headers, sections.
vera-rise-delay-1 / -2 / -3
Same as vera-rise with 80 / 160 / 240ms stagger.
vera-modal-in
translateY 8px + scale 0.96 → 1, 220ms. Used by the centered modal.
vera-sheet-in / vera-backdrop-in
Slide-from-right + cross-fade for right-side sheets and the backdrop.
Attention
vera-fab-pulse
Continuous box-shadow pulse on the Ask Vera FAB.
vera-callout-in
Tooltip-callout for the FAB on first appearance.
All animations honor prefers-reduced-motion — if the user has reduced motion enabled, entrance and attention animations are suppressed.
That's every public component. Add new ones to shared/ui/src/components and surface a section here.