Skip to content
Join the waitlist

@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.

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
Contrast ratios for text pairs
Text on surfaceLightDarkMinimum
foreground / background18.57:117.61:17:1
foreground / surface19.55:116.28:17:1
foreground / receipt17.16:114.98:17:1
muted-foreground / background6.38:17.62:14.5:1
muted-foreground / surface6.71:17.04:14.5:1
muted-foreground / receipt5.89:16.48:14.5:1
primary-foreground / primary18.57:117.61:17:1
marker-foreground / marker5.30:16.87:14.5:1
marker-text / background5.70:18.45:14.5:1
marker-text / surface6.00:17.81:14.5:1
marker-text / marker-tint5.18:17.34:14.5:1
positive / background6.13:19.70:14.5:1
positive / positive-tint5.53:17.90:14.5:1
destructive / background6.24:17.02:14.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.

4px
8px
12px
16px
24px
32px
48px
64px
xs · 4px
sm · 6px
md · 8px
lg · 12px
xl · 16px
pill · pill
xs · hairline edge
sm · cards on paper
lg · menus, sheets

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.

duration-instant80ms
duration-fast120ms
duration-base160ms
duration-slow240ms
ease-standardcubic-bezier(0.2, 0, 0, 1)
ease-exitcubic-bezier(0.4, 0, 1, 1)
ease-printsteps(6, end)

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)

Card
APR down
Fee reversed
Refinance
Insurance
Secure link
Approval

Lucide, Deb stroke

<Icon {...iconStroke} />

Components

@teller/ui: shadcn-style primitives built only from semantic tokens. Shown in light and dark.

EstimateConfirmedCalling nowOverpayingPhase 2Declined
You could saveUp to $2,140 a year, illustrative estimate
You saved$388, confirmed on a statement
Late fee reversed$40.00
Annual fee waived$95.00
EstimateConfirmedCalling nowOverpayingPhase 2Declined
You could saveUp to $2,140 a year, illustrative estimate
You saved$388, confirmed on a statement
Late fee reversed$40.00
Annual fee waived$95.00

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.