Colors

Brand primitives
brand.100
offwhite
#FFF8FA
brand.200
xxlight
#FFEBF2
brand.300
xlight
#FFBDD3
brand.400
light
#F782AA
brand.500
DEFAULT
#DA4570
brand.600
medium
#B3304B
brand.700
dark
#5E1B27
brand.800
xdark
#2D070D
Gray primitives
gray.100
#F9FAFB
gray.200
#F3F4F6
gray.300
#E5E7EB
gray.400
#D1D5DB
gray.500
#9CA3AF
gray.600
#6B7280
gray.700
#4B5563
gray.800
#374151
gray.900
#1F2937
Semantic tokens
text.primary
#1E1E1E
text.secondary
#757575
border.default
#D9D9D9
bg
#F3F3F3
white
#FFFFFF
icon.onAccent
#F3F3F3
Status
red.100
#FEF2F2
red.600
#EF4444
red.700
#DC2626
green.100
#F0FDF4
green.600
#22C55E
yellow.100
#FEFCE8
yellow.500
#FACC15

Typography

titleHero
Inter 700 · 72px · 1.2lh · Noto Serif for quotes
Proof
titlePage / sm
Inter 700 · 40px · 1.2lh
My Profile
heading / sm
Inter 600 · 20px · 1.2lh
Account Settings
subheading
Inter 400 · 16px · 1.2lh
Section label
body
Inter 400 · 16px · 1.4lh
The quick brown fox jumps over the lazy dog.
bodyStrong
Inter 600 · 16px · 1.4lh
The quick brown fox jumps over the lazy dog.
bodySmall
Inter 400 · 14px · 1.4lh
The quick brown fox jumps over the lazy dog.
bodySmallStrong
Inter 600 · 14px · 1.4lh
The quick brown fox jumps over the lazy dog.
code
Roboto Mono · 16px · 1.3lh
const x = "hello";
titlePage · serif quote
Noto Serif · decorative
"

Gradients

Brand gradient stops (from colors.ts)
primary
vertical
gradient.from #C94F7C
→ gradient.to #3C0D0E
secondary
vertical
gradient.from2 #C94F7C
→ gradient.to2 #7C1553
primary
diagonal
diagonal (default)
primary
horizontal
horizontal
Overlay gradients (for text legibility over photos)
LinearBottom
gradientOverlays
.linearBottom
→ rgba(0,0,0,0.72)
LinearBottom 2
gradientOverlays
.linearBottom2
→ rgba(0,0,0,0.50)

Button

Variants · size md
primary
primary
secondary
secondary
outline
outline
ghost
ghost
destructive
destructive
dangerPrimary
dangerPrimary
dangerSecondary
dangerSecondary
link
neutralFilled
neutralFilled
On dark backgrounds
primaryOnDark
primaryOnDark
white
white
linkOnDark
linkOnDark
Sizes
small
sm · 8/16
medium
md · 12/12
large
lg · 16/32
States
default
default
disabled
disabled
⟳ loading
loading

Input

Empty (italic placeholder, gray[500])
With value (normal style, main.xdark #2D070D)
Invalid (border #DC2626)
Please enter a valid email address
InputField · label + description
Email address
We'll never share your email.
secureToggle (Show/Hide · main.medium #B3304B Inter500)
Show
onDark (no border, white bg)

Textarea

Empty (italic, 4 lines = minHeight 96px)
With value (normal style)
Invalid (border #DC2626)
Caption must be at least 20 characters
TextareaField · label + description
Photo caption
Help matches understand this photo.

DateInput

Empty (placeholder=main.light #F782AA italic)
Birthday
With value (main.xdark #2D070D, normal style)
Error state
Please enter a valid date

Switch

States
Off
On
Disabled
With label + description (SwitchGroup)
New matches
Notify when you get a new match
New messages
Notify on incoming messages
Likes received
Notify when someone likes you
Super likes (disabled)

Checkbox

States
Unchecked
Checked
Indeterminate
Disabled
CheckboxGroup
Hiking
Outdoor activities
Photography
Food & Cooking

Radio

RadioGroup
Long-term
Looking for something serious
Short-term
Just friends
Disabled option

RangeSlider

Age range · 22–38 (20–60 scale = 13%–38%)
22 38
Distance · 5–50 mi (0–100 scale = 5%–50%)
5 mi 50 mi
Disabled (opacity:0.4)
20 60
labels float above thumbs · rail=#D9D9D9 · active=#B3304B (main.medium) · thumbs 20×20 solid circles · touch target height 44px

Tags

Tag — all schemes × variants
brand primary brand secondary
danger primary danger secondary
positive primary positive secondary
warning primary warning secondary
neutral primary neutral secondary
with remove ×
TagToggle
Hiking
Photography
Food & Cooking
Travel
Disabled
TagGhost (on dark background)
Kindness
Ambition
Humor
Loyalty
Disabled

Avatar

Sizes · with image
xs · 28
sm · 36
md · 48
lg · 72
xl · 96
Initials fallback
JT
md
JT
lg

Notification

message · variant="message" (bg=#FFEBF2 · border=#FFBDD3 · text=#5E1B27)
Your profile is live and visible to other users.
alert · variant="alert" (bg=#FEF2F2 · border=#FECACA · text=#DC2626)
Your account has been flagged for review.
dismissible
Complete your profile to get better matches.

InfoCard

With title + description + dismiss
Start with candid photos
Most of our users enjoy candid photos of you rather than group photos
Title only (no dismiss)
Your feedback is anonymous
bg #FFF8FA · radius 8 · padding 16 · zap SVG fill/stroke #B3304B · title=bodyStrong(16) #B3304B · desc=bodySmall(14) #4B5563 · dismiss=SVG X #757575

Accordion

How does matching work?
When two users both like each other, it becomes a match and a chat opens automatically.
Is my feedback anonymous?
Disabled item

Dialog

Card type (centered modal)
Log out
Are you sure you want to log out of your account?
Log out
Cancel
Sheet type (bottom sheet)
Delete account
This will permanently delete your profile, photos, matches, and messages. This cannot be undone.
Delete my account
Cancel

PageControl

1 of 3
2 of 4
5 of 5

ActionIconButton

dismiss
like
disabled
dismiss: 56×56 r=30.55 rgba(44,44,44,0.85) · like: 66×66 r=36 rgba(255,255,255,0.8) shadow(#632142)

ChatThumbnail

Sophia
Hey! I loved your photos 😊
Your turn
Marcus
That sounds like a great idea!
Your turn
Jordan
You matched with Jordan!
Your turn
Alex
Sounds fun, let's do it!
Taylor
This person is blocked
Riley
You have been unmatched
new_unread · read · new_match · message_sent · blocked · unmatched

Card

Default (padding:20)
Ratings
Your personalized information will be shown to matches here.
Elevated (shadow: main.dark #5E1B27 @ 8% · offset 0,4 · radius 12)
Elevated Card
bg=#FFF8FA · radius=20 · border=#FFEBF2

BottomToolbar

App content
Background #202020 · height 56px · gap 59px · center = ProofIcon (double-figure-8 logo) · active=brand-500, inactive=#F3F3F3

Icon / IconButton

Icon container — sized wrapper (14 / 16 / 20 / 24 / 32 / 40 / 48)
14
20
24
32
IconButton — medium (36px) · 3 variants
primary
neutral
subtle
IconButton — small (28px) · disabled
sm · primary
sm · neutral
disabled
DestructiveIconButton — red-100 bg
md
sm
Icon: sized flex container · IconButton: border-radius 50% · primary=brand-500 · neutral=gray-100 · subtle=transparent · sm=28px · md=36px · DestructiveIconButton: red-100 bg

Select

Placeholder state
Select gender…
With value
Man
Invalid state
Choose…
Disabled
Select…
Sheet picker (opens on press)
Done
Man
Woman
Non-binary
Prefer not to say
border-radius 14 · 1.5px brand-300 border · padding 16 · sheet picker on mobile

Slider

Slider (single thumb, 60%)
SliderField with label + value output
Maximum Distance 25
Disabled
height 40 · thumb 20×20 white + 2px brand-500 border · fill = brand-500

Fieldset / Form / Field

Form with fields, labels, description, error
First name *
Email
We'll send a confirmation to this address.
Phone number
Please enter a valid phone number
Fieldset with legend
Notifications
New matches
Get notified when you match with someone
Messages
Get notified when you receive a message
Fieldset (legend + gap:16) · Field (gap:4) · Label (Inter 500) · FieldError (red-600)

Tabs

TabList + Tab (underline indicator)
About
Photos
Prompts
Premium ✦
Tab panel content is rendered here for the active tab.
Tab: padding 12v/16h · selected: border-bottom 2px brand-500 + brand-500 text 600 · unselected: gray-600

Pagination

Page 3 of 10
1
2
3
4
10
Page 1 of 5 (prev disabled)
1
2
3
5
Item: 36×36 · border-radius 8 · current=brand-500 bg white text · arrows=brand-500

SendLikeSheet

Empty (heart + "like" label)
Send a like
like
With message (arrow + "send" label)
Send a like
send
bg #1E1E1E · border-radius 16 top · padding 24 · empty=heart icon + "like" · message=arrow icon + "send"

MatchSheetV2

It's a match!
It's a match!
send
Message Later
Same dark sheet · no X button · send arrow always shown (dimmed until message typed) · "Message Later" link below
Settings Sheets
Settings
Settings
Match Preferences
Notifications
Account
Privacy Policy
Delete Account
Log out
Notifications Sheet
Notifications
New matches
When someone you liked also likes you back
New messages
When a match sends you a message
Account Sheet
Account
Kiki Vega November 6, 1998
Email
kvega@gmail.com
Phone number
123-456-7890
Reset password
Delete Account
Log out