Fuelr — Design System
Foundations for the responsive web app · v0.2
What this document does

It fixes the decisions that are no longer up for debate: colour, type, space, grid, shape, motion, accessibility. Every value exists in dark and light — flip the theme and everything you see re-renders from the real tokens.

Three principles

Dark by default. The near-black ground lets the lime carry the action; light is a mirror, not a second system.

Food first. The UI stays neutral so the dish photos are the only uncontrolled colour.

One accent per view. Lime = action, mint = progress, coral = alert. Never two roles for one colour.

What changes for the web

The original system is mobile. The web adds a 4/8/12-column grid with a 1240px container, two extra type steps for large screens, hover and keyboard focus states, and an elevation scale.

Nothing is removed from the existing mobile system.

01

Colour ramps — 100 to 1000

Step 500 is the flat brand colour, identical in both themes. The dark steps carry text on light grounds (the *-ink tokens); the light steps are used as grounds.

Lime--lime
100#FAFCE6
200#F2F8C4
300#E4F294
400#D2EB5D
500base
600#A6CB1B
700#85A414
800#65800F
900ink · light
1000#2E3A08

500 is the flat brand colour in both themes (CTA, active tab, progress ring). 900 is --lime-ink: lime text and borders in light mode (6.9:1).

Mint--mint
100#E3FBF7
200#C4F5EC
300#97ECDD
400#5FE0CB
500base
600#1DB3A0
700#158F80
800ink · light
900#0A4C43
1000#062E28

500 is progress, links and the focus ring. 800 is --mint-ink (6.1:1). 100–200 are positive alert grounds.

Coral--coral
100#FFEDE7
200#FFD3C4
300#FFAD8C
400#FF8A66
500base
600#E8532F
700#C43F22
800ink · light
900#742513
1000#4D1A0D

500 is alerts, badges and notifications. 800 is --coral-ink (6.9:1). Never used for body text.

Neutral--gray
100#F3F4F6
200#E5E7EB
300#D1D5DB
400#9CA3AF
500base
600#4B5563
700#374151
800#1F2937
900#111827
1000#030712

500 is secondary text, field borders and inactive states. Steps 700–1000 are dark-mode surfaces, 100–200 light-mode ones.

02

Semantic tokens

A component never hardcodes a hex — it uses the token. That is what lets the light theme exist without duplicating a single component.

TokenDarkLightUsage
--bg#121212#F7F5EFPage ground
--bg-raised#191919#FFFFFFCards, panels, nav bar
--bg-raised-2#212121#ECE9DFFields, inactive chips, tracks
--text#F5F5F0#15150FPrimary text
--text-dim#B9B9B4#5B5A50Descriptions, metadata
--gray#6B7280#64635ALabels, inactive icons, borders
--linergba(…,.08)rgba(…,.12)Separators and card outlines
--lime#C4F135#C4F135Primary action (flat)
--lime-ink#C4F135#4B5E12Lime as text or border
--mint#2DD4BF#2DD4BFProgress, focus (flat)
--mint-ink#2DD4BF#0E6B5FMint as text or link
--coral#FF6B4A#FF6B4AAlert, badge (flat)
--coral-ink#FF6B4A#9C321BCoral as text or border
03

Typography

Poppins ExtraBold for the brand voice and headings, Manrope for everything else, JetBrains Mono for quantities and units — tabular figures stop the text jumping when a value changes.

Display
44 / 40 · 800
Fuelr.
H1
32 / 28 · 800
Planning de la semaine
H2
22 / 20 · 800
Liste de courses
H3
16 · 700
Poulet basquaise
Body
15 · 500 · 1.5
Planifie tes repas, atteins tes objectifs.
Meta
13 · 600
4 personnes · 25 min
Label
11 · 700 · .02em
Petit-déjeuner
Data
13 · mono
420 kcal · 600 g
Rules
  • Max body line length — 68ch
  • Heading leading — 1.1 to 1.2
  • Smallest on-screen size — 11px (labels)
  • Poppins allowed from — 14px
  • Uppercase — labels only
Avoid

Manrope in a heading with Poppins in the body: the hierarchy flattens. Titles in Poppins, descriptions in Manrope, quantities in mono.

04

Spacing — 4px base

No value off the scale. If a spacing 'doesn't quite land', it's the composition to revisit, not the scale.

--sp-14pxicon micro-offset
--sp-28pxlabel ↔ field
--sp-312pxgap between chips
--sp-416pxcard padding (mobile)
--sp-520pxmobile screen margin
--sp-624pxgrid gutter
--sp-832pxpanel padding
--sp-1040pxdesktop screen margin
--sp-1248pxclickable row height
--sp-1664pxgap between sections
--sp-2080pxpage top margin
--sp-2496pxbottom safe area
05

Shape, elevation, motion

Radii
--r-sm 8px
fields, tags
--r-md 14px
cards
--r-lg 20px
panels
--r-full 999px
buttons, chips

A card never mixes two surface radii.

Elevation
e0
border only · in-flow cards
e1
card hover
e2
menus, toasts
e3
modals, sheets

In dark, elevation reads through the surface; in light, through the shadow.

Motion
  • Hover, colour, theme — 120–180ms
  • Check, chip, switch — 160ms
  • Sheet, modal — 240ms
  • cubic-bezier(.2,.8,.2,1)
  • Reduced motion — honoured, everything becomes 0ms

Nothing lasts longer than 240ms: a cooking app gets read with dirty hands.

06

Buttons

Six variants, one role each. Only one primary per view. Hover, focus, pressed, loading and disabled are shown for every variant.

primary
one action per view · 46px
secondary
1.5px gray border
tertiary
raised-2 ground, no border
text
no surface · underline on hover
danger
coral outline → filled on hover
soft
accent 14% ground · dense lists
dangerText
destructive, no surface · inside a row
Icon buttons & full width
07

Fields

Seven states. The focus ring is mint and appears instantly; error and success carry both a border and a hint, never colour alone.

Empty state uses the placeholder in gray

Adresse incomplète

Foyer rejoint

Géré par l'admin du foyer

08

Selection controls

Checkbox
Radio
Switch
09

Chips, tabs & badges

Filter chips
Tabs
Badges
PopulaireNouveauPlanifiéPériméGratuit
10

Cards

Recipe cards lift 3px and zoom the photo 1.04 on hover. Selected carries an accent border and a check; unavailable drops to 55% and stops responding.

Végé

Bowl quinoa & légumes rôtis

4 personnes · 25 min

520 kcal · 600 g

Saumon grillé, riz citronné

2 personnes · 30 min

640 kcal · 450 g

Curry de lentilles corail

6 personnes · 40 min

480 kcal · 900 g

Wrap poulet & avocat

1 personne · 10 min

510 kcal · 320 g

Interactive card

The generic card takes the same hover elevation when it is clickable. It uses the medium radius; panels use the large one.

Panel

Panels carry more padding and the 20px radius. They group cards and controls rather than content of their own.

11

Banners

Three tones, because the system gives one meaning per colour. Errors take role=alert and interrupt; the rest wait their turn. `position="fixed"` pins one to the bottom of the viewport for something wrong with the page as a whole.

Mot de passe modifié.
Confirme ton adresse pour que Fuelr puisse te joindre.
12

Data & system states

Ta liste de courses est vide

Ajoute des recettes au planning et les ingrédients arriveront ici automatiquement.

Chargement impossible

La connexion a été interrompue. Tes recettes enregistrées restent disponibles hors ligne.