Paper, ink and one red pencil.
Three layers, all CSS custom properties. Components only read semantic tokens, so a theme or preset can swap the whole palette without touching a component.
Raw values with neutral names. Never used by components directly.
- --paper-100: #F5F2EB
- --graphite-950: #141414
- --graphite-600: #5B554D
- --red-600: #D7261E
- --safelight-400: #FF5A4E
Roles. Themes and presets override these, and only these.
- --canvas → paper-100
- --ink → graphite-950
- --muted → graphite-600
- --accent → red-600
- --accent-text → red-700
Scoped to one component, always pointing at a semantic token.
- --button-bg → accent
- --button-ink → on-accent
- --card-meta → muted
- --sheet-edge → edge
- --stamp-ink → accent-text
:root { --canvas: var(--paper-100); --accent: var(--red-600); }
[data-theme="darkroom"] { --canvas: var(--graphite-990); --accent: var(--safelight-400); }
[data-preset="gallery"] { --f-display: "Jost"; --frame-pad: 14px; --dur: 700ms; }
.button { background: var(--button-bg); color: var(--button-ink); }
Studio is warm paper with a faint grain, the default. Darkroom is for photography, film and night viewing: deep warm blacks, and red turns to safelight.
Studio
data-theme="studio"
Canvas--canvas
#F5F2EB
Surface--surface
#FFFFFF
Ink--ink
#141414
Muted--muted
#5B554D
Hairline--line
#D9D3C7
Grease Red--accent
#D7261E
Red text--accent-text
#C21F18
Darkroom
data-theme="darkroom"
Canvas--canvas
#0D0C0B
Surface--surface
#161412
Raised--surface-2
#201D1A
Text--ink
#EEE9E1
Muted--muted
#A59D92
Hairline--line
#2E2A26
Safelight--accent
#FF5A4E
On a contact sheet, the red circle marks the chosen frame. In PROOF it marks the chosen next step. Grease Red carries white text in Studio; a deeper red is used when red itself is the text. In Darkroom it becomes Safelight with ink text.
Use for
- Primary CTA per view
- Selected frame, active state
- Grease-pencil annotations
- Approval stamps
Never for
- Headings or body copy
- Icons and dividers
- Errors (use plum)
- Decoration
Studio · Grease Red
Start a project →
Book a 20-min call →
From €9k
Fill #D7261E · text #FFFFFF
Red text #C21F18
Darkroom · Safelight
Start a project →
Book a 20-min call →
From €9k
Fill #FF5A4E · text #141414
Red text #FF5A4E
Status always pairs an icon, a plain message and its own treatment. Error is plum, not red, and gets a hatched ground and dashed rule so it can never be read as the accent.
✓
Brief sent
Mara will reply within two working days.
--success · #2E6B3A
!
Limited availability
Booking from November 2026. Smaller jobs may fit sooner.
--warning · #7A5200
i
Prices exclude VAT
Ranges are starting points. The brief sets the final quote.
--info · #1D4C89
✕
Budget is missing
Pick a range so Mara can tell you what fits. “Not sure yet” is fine.
--error · #9A1747
Computed from the token values. AA (4.5:1) is the floor for all text; body pairs target AAA (7:1). Large-only pairs are limited to 24 px+ display type.
Sample
Pair
Use
Ratio
WCAG
Aa
Studio · ink on canvas
#141414 on #F5F2EB
Body, headings
16.48:1
AAA
Aa
Studio · ink on surface
#141414 on #FFFFFF
Cards, forms
18.42:1
AAA
Aa
Studio · muted on canvas
#5B554D on #F5F2EB
Metadata, captions
6.59:1
AA
Aa
Studio · red text on canvas
#C21F18 on #F5F2EB
Text links, CTAs
5.36:1
AA
Aa
Studio · white on Grease Red
#FFFFFF on #D7261E
Primary button
5.02:1
AA
Aa
Darkroom · text on canvas
#EEE9E1 on #0D0C0B
Body, headings
16.17:1
AAA
Aa
Darkroom · text on raised
#EEE9E1 on #201D1A
Menus, dialogs
13.88:1
AAA
Aa
Darkroom · muted on canvas
#A59D92 on #0D0C0B
Metadata, captions
7.29:1
AAA
Aa
Darkroom · Safelight on canvas
#FF5A4E on #0D0C0B
Text links, CTAs
6.35:1
AA
Aa
Darkroom · ink on Safelight
#141414 on #FF5A4E
Primary button
5.99:1
AA
Aa
Status · success
#2E6B3A on #E3EFE3
Confirmations
5.40:1
AA
Aa
Status · warning
#7A5200 on #F8EBCF
Heads-up
5.86:1
AA
Aa
Status · info
#1D4C89 on #E1E9F4
Neutral notices
7.01:1
AAA
Aa
Status · error
#9A1747 on #F7E1E8
Form errors
6.53:1
AA
The same project card and case-study section, rendered in all five presets. Only the documented semantic tokens change; the markup is identical.
Editorialstudio
No. 07A2025
Brühl Coffee
Brühl · Identity & web · 2025 · 12 wks
+38% online orders
View case →
Chapter 02 — The decision
A label that reads from the shelf.
Three directions went to tasting. The quietest one sold the most.
v3 — client picked this one
Final
- --f-display
- Newsreader
- --f-body
- Albert Sans
- --radius
- 0
- --dur
- 400ms
- --frame-ratio
- 3/2
Gallerystudio
No. 07A2025
Brühl Coffee
Brühl · Identity & web · 2025 · 12 wks
+38% online orders
View case →
Chapter 02 — The decision
A label that reads from the shelf.
Three directions went to tasting. The quietest one sold the most.
v3 — client picked this one
Final
- --f-display
- Jost 300
- --f-body
- Jost
- --frame-pad
- 14px mat
- --dur
- 700ms
- --img-filter
- grayscale
Rawstudio
No. 07A2025
Brühl Coffee
Brühl · Identity & web · 2025 · 12 wks
+38% online orders
View case →
Chapter 02 — The decision
A label that reads from the shelf.
Three directions went to tasting. The quietest one sold the most.
v3 — client picked this one
Final
- --f-display
- Anybody 800
- --f-body
- Space Mono
- --sheet-gap
- 0
- --dur
- 120ms steps
- --frame-ratio
- 1/1
Playfulstudio
No. 07A2025
Brühl Coffee
Brühl · Identity & web · 2025 · 12 wks
+38% online orders
View case →
Chapter 02 — The decision
A label that reads from the shelf.
Three directions went to tasting. The quietest one sold the most.
v3 — client picked this one
Final
- --f-display
- Young Serif
- --f-body
- Rubik
- --radius
- 14px
- --ease
- overshoot
- --frame-ratio
- 4/5
Cinematicdarkroom
No. 07A2025
Brühl Coffee
Brühl · Identity & web · 2025 · 12 wks
+38% online orders
View case →
Chapter 02 — The decision
A label that reads from the shelf.
Three directions went to tasting. The quietest one sold the most.
v3 — client picked this one
Final
- --f-display
- Bodoni Moda
- --f-body
- Manrope
- theme
- Darkroom
- --dur
- 1000ms
- --frame-ratio
- 2.39/1
Computed from each preset’s token values. Every text pair clears AA; body pairs reach AAA in all five presets.
editorial · Studio
Aa
Ink on canvas#141414 / #F5F2EB
16.48AAA
Aa
Ink on surface#141414 / #FFFFFF
18.42AAA
Aa
Muted on canvas#5B554D / #F5F2EB
6.59AA
Aa
Red text on canvas#C21F18 / #F5F2EB
5.36AA
Aa
Button label#FFFFFF / #D7261E
5.02AA
Aa
Sheet text#EEE9E1 / #1B1917
14.51AAA
Aa
Sheet muted#B8B0A4 / #1B1917
8.17AAA
Aa
Placeholder label#4A453E / #E9E4D9
7.49AAA
gallery · Studio
Aa
Ink on canvas#121212 / #F3F3F1
16.86AAA
Aa
Ink on surface#121212 / #FFFFFF
18.73AAA
Aa
Muted on canvas#565654 / #F3F3F1
6.62AA
Aa
Red text on canvas#C21F18 / #F3F3F1
5.40AA
Aa
Button label#FFFFFF / #D7261E
5.02AA
Aa
Sheet text#121212 / #E7E7E4
15.12AAA
Aa
Sheet muted#4E4E4B / #E7E7E4
6.74AA
Aa
Placeholder label#3A3A37 / #E0E0DC
8.62AAA
raw · Studio
Aa
Ink on canvas#000000 / #FFFFFF
21.00AAA
Aa
Ink on surface#000000 / #FFFFFF
21.00AAA
Aa
Muted on canvas#2B2B2B / #FFFFFF
14.16AAA
Aa
Red text on canvas#C21F18 / #FFFFFF
5.99AA
Aa
Button label#FFFFFF / #D7261E
5.02AA
Aa
Sheet text#FFFFFF / #000000
21.00AAA
Aa
Sheet muted#CFCFCF / #000000
13.48AAA
Aa
Placeholder label#000000 / #EDEDED
17.94AAA
playful · Studio
Aa
Ink on canvas#1F1B3F / #FFF3E2
14.90AAA
Aa
Ink on surface#1F1B3F / #FFFFFF
16.32AAA
Aa
Muted on canvas#4E4A6B / #FFF3E2
7.62AAA
Aa
Red text on canvas#C21F18 / #FFF3E2
5.47AA
Aa
Button label#FFFFFF / #D7261E
5.02AA
Aa
Sheet text#FFF3E2 / #2C2566
12.26AAA
Aa
Sheet muted#D9D2F2 / #2C2566
9.24AAA
Aa
Placeholder label#3A2A55 / #FFD9C7
9.74AAA
cinematic · Darkroom-first
Aa
Ink on canvas#EEE9E1 / #0D0C0B
16.17AAA
Aa
Ink on surface#EEE9E1 / #161412
15.21AAA
Aa
Muted on canvas#A59D92 / #0D0C0B
7.29AAA
Aa
Red text on canvas#FF5A4E / #0D0C0B
6.35AA
Aa
Button label#141414 / #FF5A4E
5.99AA
Aa
Sheet text#EEE9E1 / #000000
17.38AAA
Aa
Sheet muted#A59D92 / #000000
7.84AAA
Aa
Placeholder label#CFC8BD / #201D1A
10.10AAA