wedo

Design System

14 colours. 10 tokens. One font. Generated from token_data.dart. If it is not here, it does not exist, and adding one is a decision.

Specimens render in dark, the only theme the app ships. Light is defined in the tokens and listed below, but no screen reads it yet.

Foundations

Color

Semantic

The ten tokens screens read. Never a raw hex, never a primitive. Every one resolves in both themes, so a screen written once works in both.

TokenLightDark
surfaceBase#F7F3EC#17111F
surfaceRaised#FFFDF8#211829
surfaceSunken#EFE9DE#0F0A15
textPrimary#2E0249#F7F3EC
textSecondary#7B7286#7B7286
border#2E02491F#FFFFFF1F
brand#2E0249#9B5FC9
accent#F47C7C#F47C7C
success#22C55E#22C55E
danger#EF4444#EF4444

Color

Palette

All 14 primitives, the whole set. Screens never touch these. They exist only so the semantic layer has somewhere to point.

brand

violet700

#2E0249

violet300

#9B5FC9

pink400

#F47C7C

neutral

0

#FFFDF8

50

#F7F3EC

100

#EFE9DE

500

#7B7286

800

#211829

900

#17111F

950

#0F0A15

feedback

green

#22C55E

red

#EF4444

premium

gold400

#FFD700

gold600

#FFA000

Brand

Mark

Wordmark on the brand gradient. Violet to pink, top to bottom, never reversed. Text on the gradient is always white.

WeDo
WeDo

Type

DM Sans

One family, six sizes. Weight does the work, not a second typeface. Display and body are the same font at different weights.

display . 32px . 700

Never be bored again.

h1 . 24px . 700

Never be bored again.

h2 . 18px . 600

Never be bored again.

body . 16px . 400

Never be bored again.

bodySm . 14px . 400

Never be bored again.

caption . 12px . 500

Never be bored again.

Space + radius

Rhythm

4pt base, seven steps. Four radii, closed set: sm for inputs, md for containers, lg for the date card, full for pills. Do not invent an eighth.

spacing

x14
x28
x312
x416
x624
x832
x1248

radius

8

sm

16

md

28

lg

999

full

Surface + elevation

Depth

Three surfaces: sunken for inputs, base for the page, raised for anything that lifts. Shadow is for lift, not decoration. On dark the border carries the edge, because shadow does not read.

surfaceSunken
surfaceBase
surfaceRaised

Motion

Timing

Three durations. Fast for state flips, base for most transitions, slow for a card leaving the deck. Nothing custom, ever.

fast 120msbase 200msslow 320ms
Components

Web replicas of the Flutter widgets, driven by the same generated tokens. Change a token, these change with it.

Buttons

Actions

Primary is the brand gradient, pill shaped, white text. One primary per screen. Ghost is the secondary. Never two primaries side by side.

primary

ghost

primary . disabled

Cards

Containers

Raised lifts off the base and takes a shadow. Flat is for static rows inside a list. Radius md for containers, lg is reserved for the date card alone.

Raised

Lifts off the base. Sheets, dialogs.

Flat

Static rows inside a list.

Signature

Date card

The one component WeDo is recognised by. The photo IS the card: full bleed, scrim into the surface, meta line, title, one text action. Largest radius in the system and nothing else may use it. The block below stands in for the photo.

RELAX . FREE

Sketching Each Other

Sit across from each other. Set a 10 min timer.

Read more

Status

Markers

Success and danger, tinted at 12 percent over the surface. These two are the only status colours. No warning, no info, no third state.

MatchedPassed

Forms

Inputs

Fields sit on the sunken surface so they read as recessed. Chips are the quiz control, single select, brand fill when active.

text field

chips . single select

Lists

Rows

Matches and Memories are hairline separated rows, never cards. One row, one action. A card here would make every row shout equally.

Living Room FortmatchedPlan it

Paywall

Plan card

Selection is a 1.5px accent border plus a 10 percent tint and a filled radio. The saving badge overlaps the top edge. The struck price is twelve months at the monthly rate, never an invented number.

Annual14 days free, EUR 0.96 a weekEUR 119.88EUR 49.99
SAVE 58%
MonthlyEUR 9.99

Paywall

Benefits and locks

Gold appears here and nowhere else. A gold check means Pro includes it, a gold lock means Pro opens it. Never use gold for emphasis in the core loop.

benefit rows

New packs monthly60 ideas today, more every month
MemoryEvery date you have been on, kept
No adsEver

locked panel

3 more kept

Free keeps the last 5 readable. Pro opens all of them.

Unlock with Pro

Paywall

Timeline

Used to show what a trial actually costs and when. The live step glows gold, past and future steps sit quiet. Three steps maximum.

TodayEverything unlocks. Pay nothing.
Day 14Your year starts, EUR 49.99.

Sheets

Sheet header

The drag handle sits on the photo, so a sheet never opens with a strip of chrome above the content. Title, then a meta line in caps.

Living Room Fort

FREE . AT HOME

States

Empty

A sentence that says what will fill this screen, and how. Left aligned, no illustration, no icon. The screen is empty, so the copy carries it.

No memories yet

Finish a date and it is kept here, with whatever you wrote about it.

Navigation

Tab bar

Icon over label, each in its own pill. The active tab takes an accent tint and a filled icon. Labels are sentence case and never truncate.

Home
Matches
Memories
Rules
  • Gold is paywall only

    Badges, benefit checks, locks. Never in the core loop.

  • Hairlines, not cards

    A list of cards makes every row shout. Rules separate, cards contain.

  • One font

    DM Sans, weight does the work. A second family was tried and dropped.

  • Gradient on the CTA

    One primary per screen. Nothing else gets the brand gradient.

  • No emoji, anywhere

    Not in copy, not as an icon, not as an image fallback.

  • Never a raw hex

    Screens read the ten semantic tokens. Adding a token is a decision.