Design System

A brand book covering logo, color, typography, layout, iconography, and application — the source of truth for every interface decision on this site.

Designed by AI agents — Codex and Claude wrote the Next.js, ChatGPT generated the imagery, and QuiverAI built the vector marks. An agent-authored system, documented inside the product it powers.

Felipe Chaves logo

Brand book

Design System

April, 2026

Authors: Me, Codex and Claude

01

Logo

The portrait mark and the FC monogram. Where they live, how they scale, and the palette expressions that extend them.

Brand · Logo

Portrait mark

A hand-drawn portrait in clean line-art — head, shoulders, hoodie. Doubles as an avatar and a logo: a signature on writing, a founder's mark on projects, and a face beside the name in the nav.

  • Always square. ~10% radius at hero, ~22% at nav scale.
  • Hero 160–240px · Card 40–64px · Nav 20–24px.
  • Pair with the name in primary contexts; mark stands alone only as an avatar.

Light · Large

Logo large

Dark · Large

Logo large

Brand · Monogram

FC monogram

Where the portrait is too detailed — favicons, single-colour surfaces, letterpress — the FC monogram takes over. A neutral charcoal chip with a mono 'FC' lockup, built to hold its weight at 16 px.

  • Use when the portrait would not survive the surface.
  • Never recolour the monogram — swap to a light chip only.
  • Pair with the wordmark; never the portrait.

Light surface

16
16
24
32
72

Dark surface

16
16
24
32
72

Brand · Logo

Palette expressions

Twenty-eight approved tints. Use the base portrait by default; reach for a palette variant only when the surface needs a warmer or cooler mood.

Saturated

Portrait · Saturated · AmberPortrait · Saturated · BluePortrait · Saturated · BrownPortrait · Saturated · CyanPortrait · Saturated · GrayPortrait · Saturated · GreenPortrait · Saturated · IndigoPortrait · Saturated · LimePortrait · Saturated · OrangePortrait · Saturated · PinkPortrait · Saturated · PurplePortrait · Saturated · RedPortrait · Saturated · RosePortrait · Saturated · TealPortrait · Saturated · Yellow

Earth

Portrait · Earth · OlivePortrait · Earth · SagePortrait · Earth · SandPortrait · Earth · Terracotta

Pastel

Portrait · Pastel · ButterPortrait · Pastel · LilacPortrait · Pastel · MintPortrait · Pastel · Peach

Neon

Portrait · Neon · CyanPortrait · Neon · LimePortrait · Neon · OrangePortrait · Neon · Pink

02

Color

Pure black, pure white, and the semantic signals that carry weight. Chromatic restraint by default — every hue has to earn its place.

Color · Light mode

Pure white. Pure black.

#fff ground, #000 ink. Zero chroma — pure greyscale. Depth from borders at 12% black.

background--backgroundoklch(1 0 0) · #ffffff
foreground--foregroundoklch(0 0 0) · #000000
card--cardoklch(1 0 0) · borders define elevation
popover--popoveroklch(1 0 0)
primary--primaryoklch(0 0 0) · CTAs, primary ink
secondary--secondaryoklch(0.96 0 0)
muted--mutedoklch(0.96 0 0)
muted-foreground--muted-foregroundoklch(0.45 0 0)
accent--accentoklch(0.93 0 0)
border--borderoklch(0 0 0 / 12%)
input--inputoklch(0 0 0 / 10%)
ring--ringoklch(0 0 0 / 40%)

Color · Dark mode

Pure black. Pure white.

#000 ground, #fff ink. Depth from translucent white borders at 14% and stepped neutral greys.

background--backgroundoklch(0 0 0) · #000000
foreground--foregroundoklch(1 0 0) · #ffffff
card--cardoklch(0 0 0) · borders define elevation
popover--popoveroklch(0.14 0 0) · lifted neutral grey
primary--primaryoklch(1 0 0) · inverted for CTAs
secondary--secondaryoklch(0.22 0 0)
muted--mutedoklch(0.18 0 0)
muted-foreground--muted-foregroundoklch(0.72 0 0)
accent--accentoklch(0.28 0 0)
border--borderoklch(1 0 0 / 14%)
input--inputoklch(1 0 0 / 10%)
ring--ringoklch(1 0 0 / 60%)

Color · Semantic

Signals, sparingly.

Chromatic signals are rare and load-bearing. Success green marks a live project. Destructive red is reserved for error states. Shimmer gradients mark "in flight" content — nothing is decorative.

success--success
oklch(0.6 0.2 145)live project
destructive--destructive
oklch(0.577 0.245 27.325)error states

In the wild

Live project

Dot pulses green while a project is live. Translation banners and audio narration use shimmer.

Shimmer · base · purple · red · blue

4s sweep · prefers-reduced-motion

Loading content · generic TTS / asyncGenerating audio narration… · AudioNative widgetThis content was automatically translatedDownload PDF · file links

Color · Accessibility

Accessibility & contrast

Primary · light

The quick brown fox jumps over the lazy dog.

21.0 : 1

Primary · dark

The quick brown fox jumps over the lazy dog.

21.0 : 1

Muted · light

The quick brown fox jumps over the lazy dog.

4.74 : 1

03

Typography

Five cuts, five jobs. Display headlines, body serifs, UI sans, and a mono companion — each with a voice the others cannot borrow.

Headline · --font-dm-serif-display

DM Serif Display

High-contrast display serif · Google Fonts · 400 · Roman + Italic

Reserved for moments that need to sing — section openers, cover titles, the one word that has to land.

Weights in use

400 · RegularCover titles · section openers
400 · ItalicEditorial flourish
Use sparinglyOne-word headlines only
NeverBody copy · UI text · buttons

Letterforms

Aa

Character set

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz · 0123456789& @ # $ % * + = — . , ; : ' " ? !

Serif · --font-lora

Lora

Contemporary serif · Google Fonts · 400 · 500 · 600 · 700 · Roman + Italic

Long-form reading deserves a serif that can carry rhythm without losing its footing on screen.

Weights in use

400 · RegularBody copy, essays, long reads
400 · ItalicEmphasis, asides, callouts
500 · MediumSection dek, pull quotes
700 · BoldInline emphasis, run-in headers

Letterforms

Aa

Character set

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz · 0123456789& @ # $ % * + = — . , ; : ' " ? !

Sans · --font-sans

Geist

Neo-grotesque sans · Vercel · variable 100–900 · in use 400 · 500

A marketer who builds — production software, not just strategy decks. When a tool doesn't exist, I build it.

Weights in use

400 · RegularRunning copy, nav links, captions
500 · MediumWordmark, titles, active states
600 · SemiboldReserved for interactive emphasis
UPPER · tracking 0.22BRAND · WRITING · PROJECTS

Letterforms

Aa

Character set

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz · 0123456789& @ # $ % * + = — . , ; : ' " ? !

Display · --font-display

Cormorant Garamond

Transitional serif · Google Fonts · 400 · 500 · 600 · Roman + Italic

The best interfaces feel inevitable — like they were discovered, not drawn.

Weights in use

400 · RegularFelipe Chaves · Writing
400 · ItalicNotes from the workshop
500 · MediumOn calm design
600 · SemiboldThe long version

Letterforms

Aa

Character set

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz · 0123456789& @ # $ % * + = — . , ; : ' " ? !

Mono · --font-mono

Geist Mono

Monospaced companion to Geist · 400 · 500 · set at 0.875em inline

$ pnpm dev
> ftchvs_26 dev
> next dev --turbopack
▲ Next.js 16.0.1 ✓ Ready in 1.2s

Weights in use

400 · Regular2025 — Dec '25 — Nov '25
500 · MediumLIVE · ALPHA · PUBLIC
Symbols{ } [ ] => -> != == </ >
Tabular2,480 · 12,607 · 99,914

Letterforms

Aa

Character set

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz · 0123456789& @ # $ % * + = — . , ; : ' " ? !

Typography · Scale

Scale & hierarchy

Four steps, one voice. Display serif for headlines, Geist for running copy, Geist Mono for meta and code. Every size snaps to the 8-point rhythm.

H1 · Display

Lorem ipsum dolor sit

7cqh · Cormorant

H2 · Section

Lorem ipsum dolor sit amet

5cqh · Cormorant

Body · Geist

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt.

2.4cqh · 1.7 lh

Meta · Geist Mono

BRAND · TYPOGRAPHY · SCALE

1.4cqh · uppercase

Typography · Summary

The family at a glance.

Five cuts, five jobs. Pick by role, not by taste — the family is built so that reaching for the right voice is the default.

Family

Role

Weights

Use for

DM Serif Display--font-dm-serif-display
Headline serif400
Every slide title · cover · section openersAvoid · Anything under 32px · body · UI
Lora--font-lora
Body serif400 · 500 · 600 · 700
Long-form essays · articles · reading blocksAvoid · UI chrome · dense tables
Geist--font-preview-sans
UI sans400 · 500 · 600
Running copy · nav · buttons · form fieldsAvoid · Editorial titles (reach for a serif)
Cormorant Garamond--font-cormorant
Editorial serif400 · 500 · 600
Pull quotes · editorial flourishes · in-slide typographic featuresAvoid · Body copy · slide headlines (reach for DM Serif Display)
Geist Mono--font-preview-mono
Data mono400 · 500
Code blocks · tabular numbers · meta labels · tokensAvoid · Running body copy

04

Layout & grid

An editorial column, an 8-point rhythm, and a grid that collapses gracefully from desktop to phone. The frame is always the point.

Layout · Intent

Narrow by design.

This site reads like a magazine column — 896px (56rem) at its widest, centred with calibrated side margins. Reach never wins against reading. The grid earns its keep by staying out of the way.

  • Default max-width --content-narrow · 56rem
  • Wide max-width --content-wide · 80rem · archive pages
  • 8-point rhythm drives every padding, gap, margin

Reading column · 896px

A narrow column forces clarity. You can't hide behind width.

marginmargin

Layout · Spacing

The 8-point rhythm.

Eight is the metronome. Every padding, gap, and margin snaps to a multiple of 8 — with 4 reserved only for hairline alignment nudges. Predictability is the point.

0px
4px
hairline nudge8px
base unit12px
16px
mobile gutter20px
tablet gutter24px
desktop gutter32px
tablet margin48px
64px
desktop margin96px
section break

Layout · Anatomy

Margins · columns · gutters.

Three parts build every page. Margins frame the reading field. Columns hold the content. Gutters breathe between columns so the eye never collides with neighbours.

Margin
64 · outer frame at desktop
Gutter
24 · between every column
Columns
8 · at desktop, equal minmax(0, 1fr)
margin 64margin 64
gutter 24 · column (8×)

Layout · Viewports

Desktop · tablet · mobile.

Three viewports, three grid densities. Eight columns on desktop, six on tablet, four on mobile. Margins tighten with the canvas, gutters stay proportional.

Desktop · 1280

8 col · 64 margin · 24 gutter

Tablet · 768

6 col · 32 margin · 20 gutter

Mobile · 390

4 col · 16 margin · 16 gutter

Layout · Breakpoints

How content shifts.

Five breakpoints. The grid collapses from 8 to 6 to 4. Margins tighten as the canvas narrows. Content max-width clamps at --content-narrow · 896px.

1280xl
cols
8
margin
64
gutter
24

full editorial

1024lg
cols
8
margin
48
gutter
24

narrows margin

768md
cols
6
margin
32
gutter
20

grid drops to 6

480sm
cols
4
margin
16
gutter
16

single-handed

390xs
cols
4
margin
16
gutter
16

iPhone baseline

05

Iconography

A tight Radix set at 15×15, pressed into service sparingly. Tiny labels replace decorative emoji. A green dot carries every live signal.

Iconography · Style

Icon style

Menu
Moon
Sun
Globe
Search
Home
Profile
Article
Doc
Image
Code
Mail
Chat
Share
Copy
Download
Upload
Link
Save
Like
Star
Notify
View
Locked
Audio
Play
Pause
Date
Time
Archive
Settings
Edit
Delete
Add
Remove
Info
Help
Alert
Check
Close
Arrow
Next
Down
GitHub
LinkedIn
Twitter
Instagram
Discord

Radix Icons · 15 × 15 baseline · 16–24px

Iconography · Usage

Usage examples

01 · Live project

Live projectw-2 h-2 rounded-full bg-green-500 animate-pulse

02 · Label badges

[NEW]CONTACTLIVEALPHADRAFTMono · uppercase · bracketed when stating a noun

03 · Editorial punctuation

Middle dot

LinkedIn · GitHub · Substack

Em-dash

Body copy — like this

Arrow suffix

View all →

Braille divider

⠀⠁⠈⠘⠰⠠⠄⠆

Tiny marks, not decorative — every one earns its keep.

06

Application

The system in place — nav, lists, shimmer, and the favicon. Where every earlier slide earns its keep.

Application · Nav

The nav bar.

Three-zone grid — brand left, menu centered on the page axis, utilities right. Collapses to logo + menu button at mobile.

Desktop
W896pxH56pxPad28px
Felipe Chaves
ProjectsWritingResumeAboutContact
Felipe Chaves
ProjectsWritingResumeAboutContact
896px
Tablet
W640pxH56pxPad24px
Felipe Chaves
ProjectsWritingResumeAboutContact
Felipe Chaves
ProjectsWritingResumeAboutContact
640px
Mobile
W360pxH56pxPad20px
Felipe Chaves
Felipe Chaves
360px

Application · Selected work

Selected work · ledger.

Tabular, scannable, dense. Year · Project · Role · Status. Reads like a filmography — the whole practice visible at a glance.

2025

2025 →ftchvs.comDesign, build, write · Next.js · MDX · i18nLive
Dec '25Meal Prep agentAgent design, tool authoring · ClaudeAlpha
Nov '25Movie MagicPrototyping, prompt craft · GeminiPublic
Oct '25Speed ReadResearch, build · RSVP readerPublic

Earlier

2024Field notes, vol. IWriting collection · 14 essaysDraft
2023Weeknotes (52 issues)Newsletter · Friday cadenceArchived

Homepage · /projects · dense · scannable

Application · Translated

Translation disclaimer.

Shown above MDX posts on non-English locales. A red shimmer sweep, dismissible. The only chromatic signal on a reading page.

Disclaimer: This content was automatically translated.

Notas do ateliê

Construir com calma

Há algo particular em fazer uma coisa sem pressa — em deixar que a forma encontre o seu próprio ritmo, sem forçar uma data de entrega que não ajuda ninguém.

shimmer-text-red · 4s sweep · prefers-reduced-motion · dismissible

Application · Writing

The writing page.

Body lives in a 42rem reading column — roughly 65 characters per line. DM Serif sets the title, Lora carries the prose, Geist Mono holds the meta.

Writing · essays

The patience tax on product design.

Jan 2026·8 min read·Audio available

There is a particular kind of shipping — the kind you do because the calendar says to — that never once asks whether the thing is ready. It ships because the slot is open, because the dashboard has a hole.

“The patience tax is what you pay to skip the thinking. Every shortcut is a loan against the next release.”

The alternative is slower, but it compounds. You only notice the tax three or four releases on, when the thing you shipped last quarter has to be unshipped and re-done.

42rem column · 65ch · DM Serif title · Lora body · Geist Mono meta · Cormorant pull quote

Application · Outline

Outline · marginalia.

On long reads the article column holds at 42rem, but the outline breaks out into the right margin — a quiet way to let readers jump sections without leaving the page.

Writing · essays

The patience tax on product design.

Jan 2026·8 min read

There is a particular kind of shipping — the kind you do because the calendar says to — that never once asks whether the thing is ready.

It ships because the slot is open, because the dashboard has a hole, because someone's quarter is ending. None of those are reasons. They are circumstances.

Body stays at 42rem · outline breaks out · Tufte / Gwern marginalia pattern

Application · Voice

Audio narration.

Every post reads itself aloud. While ElevenLabs warms up the voice model, the title shimmers purple. Once the file is ready, the widget snaps to a standard transport and breaks out into the right margin.

State · generating

Generating audio narration…

First play primes the ElevenLabs AudioNative widget. Subsequent visits stream instantly.

shimmer-text-purple · 4s sweep · respects prefers-reduced-motion

State · ready

The patience tax on product design

07:42 · Narrated by Rachel · EN

02:37−05:05

Sits under the article title, can bleed right of the 42rem column on wider viewports.

ElevenLabs AudioNative · shimmer purple while generating · breaks right margin when ready

Application · Favicon

The favicon in the wild.

Same portrait mark in two tints — black for logos, blue for the favicon. One source SVG, recolored at export. Rounded in CSS at 22%.

Favicon · blue

Favicon · blue96
Favicon · blue64
Favicon · blue32
Favicon · blue16

/public/portrait-mark-blue.svg

Logo · black

Logo · black96
Logo · black64
Logo · black32
Logo · black16

/public/portrait-mark.svg

In browser chrome

FaviconFelipe Chaves · ftchvs.com×
FaviconFelipe Chaves · ftchvs.com×
<link rel="icon" href="/portrait-mark-blue.svg" />
<meta name="theme-color" content="#2563eb" />

One mark · two tints · black for logos · blue for favicon

1 / 34
Design system | Felipe Chaves