@teller/brand · @teller/ui
Receipt
Everything itemized. Deb shows the work like a good receipt: every line labelled, every number aligned, nothing hidden at the bottom. Warm paper, black ink, and one marker colour reserved for what you’re overpaying.
Logo
The wordmark is the logo: lowercase “deb”, outlined from Geist SemiBold, closed by a marker-orange full stop, the total line on a receipt. The mark is the same d with the same stop, for the app icon, the Messages contact photo, and the favicon. Under 32 px, use the small cut, whose stop is larger so it still reads as orange at 16 px.
- Clear space: the height of the slot on every side.
- Minimum size: 16 px (small cut), 32 px (full mark), 56 px wide (wordmark).
- Ink on paper or paper on ink. The full stop is always marker orange, and the logo never sits on photos.
Color
Neutral ink and paper do the work. Marker orange appears only on overpayment figures and the single most important action. Green means confirmed, never estimated.
light
- background#FAF9F6
- foreground#0C0C0D
- surface#FFFFFF
- receipt#F2F0EA
- muted-foreground#5C5B62
- border#E2E0D9
- border-strong#C9C6BC
- primary#0C0C0D
- primary-foreground#FAF9F6
- marker#F2471B
- marker-foreground#0C0C0D
- marker-text#B8320C
- marker-tint#FCEBE4
- positive#146C43
- positive-tint#E3F1E8
- destructive#B42318
- ring#0C0C0D
dark
- background#0C0C0D
- foreground#F4F3EF
- surface#161618
- receipt#1E1E21
- muted-foreground#A1A1A8
- border#2A2A2E
- border-strong#3E3E44
- primary#F4F3EF
- primary-foreground#0C0C0D
- marker#FF6A3D
- marker-foreground#0C0C0D
- marker-text#FF8A66
- marker-tint#2A1810
- positive#5CCB93
- positive-tint#12261B
- destructive#F97066
- ring#F4F3EF
| Text on surface | Light | Dark | Minimum |
|---|---|---|---|
| foreground / background | 18.57:1 | 17.61:1 | 7:1 |
| foreground / surface | 19.55:1 | 16.28:1 | 7:1 |
| foreground / receipt | 17.16:1 | 14.98:1 | 7:1 |
| muted-foreground / background | 6.38:1 | 7.62:1 | 4.5:1 |
| muted-foreground / surface | 6.71:1 | 7.04:1 | 4.5:1 |
| muted-foreground / receipt | 5.89:1 | 6.48:1 | 4.5:1 |
| primary-foreground / primary | 18.57:1 | 17.61:1 | 7:1 |
| marker-foreground / marker | 5.30:1 | 6.87:1 | 4.5:1 |
| marker-text / background | 5.70:1 | 8.45:1 | 4.5:1 |
| marker-text / surface | 6.00:1 | 7.81:1 | 4.5:1 |
| marker-text / marker-tint | 5.18:1 | 7.34:1 | 4.5:1 |
| positive / background | 6.13:1 | 9.70:1 | 4.5:1 |
| positive / positive-tint | 5.53:1 | 7.90:1 | 4.5:1 |
| destructive / background | 6.24:1 | 7.02:1 | 4.5:1 |
Type
Geist for words, Geist Mono for every figure so digits line up like a receipt. Tight tracking on display sizes, none on body.
- text-6xl · 76/76Overpaying $2,140
- text-5xl · 60/62Overpaying $2,140
- text-4xl · 44/48Overpaying $2,140
- text-3xl · 32/38Overpaying $2,140
- text-2xl · 24/32Overpaying $2,140
- text-xl · 20/28Overpaying $2,140
- text-lg · 18/28Overpaying $2,140
- text-base · 16/24Overpaying $2,140
- text-sm · 14/20Overpaying $2,140
- text-xs · 12/16Overpaying $2,140
Sans · Geist 400/500/600
The honest counterparty.
Mono · Geist Mono 500, tabular
$1,310.00 · 27.99% → 21.99%
Space, radius, elevation
A 4 px grid. Radii stay small: receipts have corners. Elevation is a hairline first and a shadow only for overlays.
Motion: print
Lines print in, left to right, in steps, the way a receipt comes out. Figures never count up. Durations stay at or under 240 ms, and everything is off under reduced motion.
Icons
Base library: Lucide. It’s ISC-licensed, tree-shakes to inline SVG with zero runtime, has the broadest set, ships for React and React Native, and its 24 px grid with 2 px padding matches our geometry. We draw it at 1.5 px with square caps and miter joins so it feels printed, not rounded.
Custom finance glyphs
@teller/brand/icons (React) and svg/icons (native)
Lucide, Deb stroke
<Icon {...iconStroke} />
Components
@teller/ui: shadcn-style primitives built only from semantic tokens. Shown in light and dark.
SavingsFigure estimates always carry “up to”, a dotted marker underline, and a footnote. Only statement-backed savings render as confirmed.
Voice and tone
Deb sounds like a sharp friend who works at the bank and is on your side: direct, calm, specific. Deb never hypes, never scolds, and never pretends to be you.
Short
Under 160 characters when you can. One idea per text.
Plain
Words a ninth grader uses. “Interest rate”, not “APR optimization”.
One ask
Every message asks for at most one thing, answerable with one word.
Never sensitive
No balances, account numbers, card digits, or credit details. Put them behind a secure link.
Honest numbers
Estimates say “about” or “up to”. Only statement-backed savings are “saved”.
Always exit
STOP and HELP always work. Don’t argue with STOP.
DoYou’re overpaying about $2,140 a year (estimate). Want the breakdown? Reply YES.
Don’tYour Chase card ending 4417 has a $6,212 balance at 27.99% APR. We can save you $2,140!
DoConfirmed: your new rate shows on your statement. You saved $388. Deb’s share is $97.
Don’tGreat news!!! 🎉 We crushed it and saved you a TON on interest!
DoCan I call your issuer and add you to the call? Reply YES or NO.
Don’tReply YES to call, 2 to see options, or tell us a time and which card first.