Leon Matheus

Brand

The design system of this site: what it looks like, the rules it keeps, and the lessons the rules came from. Everything shown here is read from the site's own stylesheet when the site is built.

Written in English by Saci, from the sessions in which Leon and Saci designed the site.

Palette

Ten named colors. Components never use them directly (C1); they use roles.

  • --sun#f7b00aSun yellow, from Leon's first site (hsl 42 95% 50%, 2022). Light, not ink.
  • --sun-soft#fbd46aA paler sun, kept for soft fills.
  • --ochre#b8761aLarge marks: numerals, list markers, headings on hover.
  • --ochre-deep#8a5410Ochre for seeds and marks on light.
  • --brown#2a1c12Dark brown: the ink, the footer, the brand pair with sun.
  • --brown-2#4a3322A lighter brown: muted ink on the yellow band.
  • --moss#4f6b38Moss green: the draft badge, the organization topic.
  • --sage#a3b273Sage: the careers topic, loose seeds in the dark.
  • --cream#fff6dcWarm cream: text on dark brown.
  • --white#fffbf2Warm white: the light background. Never pure white.

Roles

What components use. A theme changes only these (C1, C9).

RoleLightDarkUsed for
--bg#fffbf2--white#1c140dPage background
--ink#2a1c12--brown#f6ebd5Body text
--muted#6f5945#b9a68cSecondary text, labels, dates
--rule#eadfc8#3a2b1eHairlines between items
--hero-bg#f7b00a--sun#24180fHeader band and hero
--hero-ink#2a1c12--brown#f7b00a--sunText and the name on the band
--hero-muted#4a3322--brown-2#e8d6b4Lede and kicker on the band
--markrgb(247 176 10 / 0.55)rgb(247 176 10 / 0.32)The highlighter under links
--chip-bg#f6ead0#2e2117Chips, cards, inline code
--code-bg#2a1c12--brown#120c07Code blocks
--footer-bg#2a1c12--brown#120c07Footer band
--dot-1#2a1c12--brown#b8761a--ochreSunflower: the core
--dot-2#8a5410--ochre-deep#f7b00a--sunSunflower: the inner ring, spiral lines
--dot-3#4f6b38--moss#a3b273--sageSunflower: loose data
--dot-4#fffbf2--white#fff6dc--creamSunflower: the brightest loose seeds
--topic-meaning#f7b00a--sun#f7b00a--sunTopic dot: meaning & AI
--topic-modeling#b8761a--ochre#b8761a--ochreTopic dot: modeling & architecture
--topic-organization#4f6b38--moss#4f6b38--mossTopic dot: data as organization
--topic-fundamentals#4a3322--brown-2#b9a68cTopic dot: fundamentals
--topic-career#a3b273--sage#a3b273--sageTopic dot: careers

Contrast

Every pair the site uses, computed from the stylesheet (C7). Text needs 4.5:1, large marks 3:1, topic dots 1.5:1; decorative pairs carry no text.

PairUsed forLightDarkNeeds
AaAaink / bgBody text16.015.44.5:1
AaAamuted / bgDates, labels, ledes6.47.74.5:1
AaAamuted / chip-bgText on cards5.56.64.5:1
AaAahero-ink / hero-bgThe name, the menu8.89.24.5:1
AaAahero-muted / hero-bgLede on the band6.212.14.5:1
AaAacream / footer-bgFooter text15.318.04.5:1
AaAasun / footer-bgThe motto (large)8.810.33.0:1
AaAabrown / sunThe brand pair: hover, essay badge8.88.84.5:1
AaAawhite / mossDraft badge5.85.84.5:1
AaAaochre / bgLarge marks only3.64.93.0:1
AaAaochre / chip-bgCard numerals3.14.23.0:1
AaAasun / bg§ and rules: decorative1.89.7deco
AaAatopic-meaning / chip-bgTopic dot beside its label1.68.31.5:1
AaAatopic-modeling / chip-bgTopic dot beside its label3.14.21.5:1
AaAatopic-organization / chip-bgTopic dot beside its label5.02.61.5:1
AaAatopic-fundamentals / chip-bgTopic dot beside its label9.86.61.5:1
AaAatopic-career / chip-bgTopic dot beside its label1.96.81.5:1

Type

Two voices (T1): Jost for people, Fira Code for data.

Jost · the human voice

Data is shared meaning.

Regular 400Medium 500Semibold 600Bold 700Italic

Fira Code · the data voice

2026-11-02 · essay · pt → en

0123456789 { } => != <=

  • --step--1
    0.875rem
    Leon Matheus
  • --step-0
    1.1875rem
    Leon Matheus
  • --step-1
    1.5rem
    Leon Matheus
  • --step-2
    2rem
    Leon Matheus
  • --step-3
    clamp(2.75rem, 8vw, 5rem)
    Leon Matheus

Components

The real classes, as the site uses them.

The favicon
K1 · The mark and the favicon
A link is a highlighter, filled with sun on hover.
K2 · Links
Essay Note Draft
K4 · Badges
  • Meaning & AI
  • Data modeling & architecture
  • Data as organization
  • Fundamentals over hype
  • Careers in data
K5, C6 · Topic chips

What I keep coming back to

T2 · Label
K7 · Language pill

A section in prose

Running text in Jost, with inline code in the data voice.

A quote stays short and names its author.

T5, K9 · Prose: §, code, quote, rule
  1. A card

    On the chip background, numbered in mono ochre.

K6 · Pebble

The sunflower

Bring the pointer to its center: the data falls into order (S1). It follows the theme (C8).

Specification

0. About this specification

This page is the specification and a specimen of it at once. The colors, type and components in the first half are read from the site’s own stylesheet when the site is built, so they cannot drift from the code: if the page names a token the stylesheet no longer has, the build fails.

The rules below are the lessons from designing the site, written down so the next change starts from them instead of rediscovering them.

  • Must is a rule the site keeps today. A change that breaks one changes the rule first, here.
  • Should is the default. Leaving it needs a reason.
  • Gap marks a place where the site doesn’t keep its own rule yet.

How it improves. Every rule has an id (P1, C2…) and, where it came from a mistake or a decision, an origin. A rule enters when a pattern repeats or a mistake teaches one, and leaves when it stops earning its place. Each revision raises the version and adds a line to the changelog (§ 12). The known gaps (§ 11) are where the next revision starts.

1. Principles

  • P1. Found before invented. An identity must be looked for in what already exists before one is proposed. The sun yellow (hsl(42 95% 50%)), Jost and Fira Code all came from Leon’s first site, from 2022. Origin: a first proposal, typographic and terracotta, was made without looking, and replaced the same day.
  • P2. One idea, carried everywhere. The site has one image: a sunflower made of data, with order at the center and entropy at the edge, information organized against noise. Every motif is a smaller form of it: the mark, the favicon, the topic dots, the yellow under the links. A new motif must read as part of that idea, or it isn’t added.
  • P3. A simple concept, done with care. Depth goes into behavior, not into more elements. Leon, on the first sunflower: “looking nice for a simple concept.”
  • P4. Every reader gets a whole site. Without JavaScript, without motion, without the web fonts, the site must still be complete. Enhancement only adds.
  • P5. Nothing leaves the domain. No third-party fonts, scripts or analytics. Fonts are bundled from Fontsource at build time.
  • P6. The content outlives the design. Texts are plain Markdown in content/, outside the code. The design must never need markup inside a text; the site has already been Gatsby and Next.js, and the texts must survive the next change of tool.
  • P7. Provenance is part of the design. Every text says which language Leon wrote it in and where it came from. The translation note is a designed element, not small print.
  • P8. Proved, not judged. A design claim is checked with something that can fail: contrast is computed (the table above), animation is measured (S7), links are counted after each build.

2. Color

The palette is ten named colors; the components use roles. A theme is only a change of roles.

  • C1. Roles, not colors. Components must use role tokens (--bg, --ink, --muted…). Palette names appear only inside role definitions and in the brand pair (C3).
  • C2. Sun yellow is light, not ink. On a light background the yellow must never carry text: it reaches 1.8:1 there. It is a surface: the header band, the highlighter under links, the focus ring, markers. In the dark theme, where it reaches 9.7:1, it becomes the color of the name.
  • C3. The brand pair is fixed. Brown on sun (8.8:1) is the same in both themes: link hover, the skip link, the essay badge.
  • C4. Ochre is for large things. Ochre reaches 3.6:1 on the light background: it may color numerals, list markers, headings on hover and other large or decorative marks, never running text.
  • C5. Dark is warm. The dark theme is brown, never neutral grey or black, and its text is cream, never pure white. The light background is warm white for the same reason.
  • C6. Topics keep their color. Meaning is sun, modeling is ochre, organization is moss, fundamentals is the second brown (light brown in the dark), careers is sage, each a --topic-* token. A topic has the same dot everywhere. A dot always sits beside its label, so it needs no 3:1, but it must stay visible: at least 1.5:1 on its surface, measured in the contrast table. Origin: the fundamentals dot was 1.3:1 on the dark chips, and dead CSS hid the ring meant to save it.
  • C7. Contrast is computed. Text pairs must reach WCAG AA (4.5:1) in both themes; large text and marks, 3:1. The table above is calculated from the stylesheet on every build.
  • C8. The sunflower follows the theme. Its colors come from --dot-1 to --dot-4, resolved live through a hidden probe element (a canvas can’t read light-dark()), so switching theme recolors it without a reload.
  • C9. One line per role. Each role is defined once, as light-dark(<light>, <dark>); a theme is nothing but color-scheme. Origin: v0.1 wrote every dark value twice, once for the system and once for the toggle. Cost: light-dark() needs a browser from 2024 or later; an older one falls back to its default colors, plain but readable (P4).

3. Type

  • T1. Two voices. Jost is the human voice: reading, headings, the name. Fira Code is the data voice: dates, labels, badges, metadata, code. What describes a text (its date, kind, language) is set in mono; the text itself is in Jost.
  • T2. Labels are mono, weight 500, uppercase, letter-spacing 0.06em, at --step--1, in --muted.
  • T3. The scale. Body is --step-0 (1.1875rem) at line-height 1.65. Headings sit at line-height 1.1 with -0.02em tracking. The fluid display size, --step-3, belongs to the name on the home page; page titles use --step-2.
  • T4. Measure. Running text must stay within --measure (40rem). Index pages use 48rem; only the home page uses --wide (68rem).
  • T5. Sections in prose begin with a sun §. A text has no H1 in its body: the page shows the title.

4. Layout and space

  • L1. One wrapper. .wrap, up to --wide, with --gutter (1.25rem) on each side.
  • L2. Three breakpoints, in rem so they follow the reader’s font size: 34rem (phone: lists become one column, the header stacks), 44rem (the hero becomes one column, the sun above the text), 52rem (the home page’s two columns become one).
  • L3. Rhythm. Margins, padding and gaps should come from the scale --space-1 to --space-6 (0.5, 1, 1.5, 2.5, 3.5, 5rem). Sections sit --space-5 apart; items in a group, --space-2 to --space-3. A value off the scale needs a reason; the ones left from before the scale move onto it when their rule is touched.
  • L4. Bands. The header is the hero surface (yellow in light, brown in dark). The footer is dark brown in both themes and carries the motto in sun.

5. Motifs and components

  • K1. The mark is a sun disc with a dark core: the sunflower at sixteen pixels. The favicon is the same disc on brown.
  • K2. Links are a highlighter: a band of --mark under the lower third of the text. On hover it fills with sun and the text turns brown (C3). Navigation and headings drop the band: navigation underlines, headings change color.
  • K3. Focus is a 3px sun ring, 3px away, on everything focusable.
  • K4. Badges (kind, draft) are mono, 0.68rem, uppercase, with a 4px radius. Essay is the brand pair; note is quiet (chip fill, hairline); draft is moss with white.
  • K5. Chips (topics, the concept index) are pills on --chip-bg, with the topic’s dot when they stand for a topic.
  • K6. Pebbles (the three beliefs on the home page, the community card) are --chip-bg with an uneven radius, a pebble and not a box, numbered in mono ochre. On hover a pebble lifts 4px and tilts by less than a degree. Origin: 0.4; until then a card with a 12px radius.
  • K7. The language pill shows the languages a page exists in, the current one inverted. It never offers a language the page doesn’t have.
  • K8. The theme toggle is three icons (system, light, dark) with aria-pressed on the current one.
  • K9. Dividers. A 1px --rule between list items. In prose, a short 4px sun bar.
  • K10. The character is Leon as a soft 3D cartoon (generated with Gemini from his photos, cut out to WebP with transparency by scripts/cutout.py). One scene per idea of the site, never decoration alone: the hero stands before the sunflower, each belief has its scene on a soft blob (sun, sage, sun). Every scene has a real alternative text, in each language. Scenes float slowly (6 to 7 s, 6px) and stand still under reduced motion. Origin: 0.4, when Leon published his likeness (2026-11-03).
  • K11. Hills close a section: one soft curve, drawn once, in the color of what comes after it (the hero into --bg, the page into --footer-bg). Decorative, aria-hidden.

6. The sunflower

Gravity as consciousness, gathering data (Leon). About 900 seeds on a Fibonacci sphere, seen from a pole that leans toward the reader, turning slowly. At rest the core is dense and the edge scatters as loose data that floats under the title. When the pointer nears the center the seeds fall into place with mass: they accelerate, overshoot a little, spiral and settle, and the Fibonacci spirals (21 and 34) appear as thin lines. It breathes, and a wave of light runs from the pole to the edge every few seconds.

  • S1. Motion means something. Order follows attention: only the pointer near the center orders the data. Motion must not be decoration alone.
  • S2. Time, not frames. Smoothing and physics must be functions of elapsed time (1 − e^(−k·dt)), and physics runs in steps of at most 1/120 s, so the sun behaves the same at 30, 60 or 120 Hz. Origin: smoothing per frame was a bug; the sun ran faster on faster screens.
  • S3. Pause when unseen. The loop stops while the canvas is off screen.
  • S4. Three levels. Without JavaScript: a flat SVG of 560 points, generated at build time, in the same place. With reduced motion: one still frame of the 3D version. Otherwise the live canvas, fading in over the SVG.
  • S5. Placed by CSS. Position and size come from --sun-x, --sun-y and --sun-d on the container; the script reads them through the flat SVG, so layout stays in the stylesheet.
  • S6. Tuned in one place. The parameters (N, CAP, TILT, SPIN, NEAR, FAR, BREATH, WAVE) sit at the top of the script, named and commented.
  • S7. Measured, not watched. Animation is tested by simulating the pointer and counting frames. Origin: the app’s browser pane sometimes reports reduced motion, and stops animating when its window is off screen; looking at it proved nothing.

7. Theme

  • M1. Three states: system (the default), light, dark. The choice lives in the reader’s browser (localStorage, key theme) and becomes data-theme on <html>, which only sets color-scheme (C9).
  • M2. No flash. An inline script in <head> restores the choice before the first paint.
  • M3. Everything themes through roles, the sunflower and the browser’s theme-color included; the meta tags read --hero-bg from the stylesheet at build time.

8. Language and voice

  • V1. Three languages: English at /, Portuguese at /pt/, Spanish at /es/. Interface words live in src/i18n.ts; everything else is content.
  • V2. Leon’s voice is never invented. Saci organizes, cuts, links and translates. Ideas Saci adds are marked and told to Leon. First person that isn’t Leon’s stays a draft.
  • V3. Every text shows its origin: “Written in …” or “Translated from … with Saci”, and the source.
  • V4. Quotes from others stay under fifteen words, with the author’s name.
  • V5. The frame speaks plainly: short sentences, no hype. The site argues for fundamentals over hype; its own words must not sell.
  • V6. Accessible names speak the page’s language, like every other word of the frame: they live in src/i18n.ts.
  • V7. Translations keep up. This specification is written in English and translated with Saci into Portuguese and Spanish, one file per language in src/brand/spec/. Each file declares the version it says; a translation behind the original fails the build, so no reader gets older rules than another.

9. Accessibility

  • A1. A skip link is the first thing to focus.
  • A2. Landmarks and groups of controls have names.
  • A3. Contrast follows C7; focus follows K3; motion follows S4.
  • A4. Decorative graphics (the sunflower, the mark, the topic dots) are hidden from assistive technology.
  • A5. Forced colors (Windows high contrast) replace backgrounds, so links get their underline back and badges and chips a border; the mark and the topic dots keep their colors.
  • A6. Print is the text in ink on paper: no bands, no sun, no controls; code turns to ink and wraps.

10. How design decisions are made here

  • D1. “No preference” is not carte blanche. Before choosing for Leon, look at what Leon already made. Origin: the stack was chosen before reading the history of the site; the history changed the question.
  • D2. Carte blanche is still a proposal. “Be creative” (Leon) meant: propose, show, refine together in small steps, and record who decided what.
  • D3. Decisions live where they last: the why in the project’s note in the Mind, the how in the repository, the rules on this page.
  • D4. Structure comes from use. No new token, component or rule until a pattern repeats.

11. Known gaps

Where v0.5 starts.

  • Forced colors are written, not proved (A5): the browsers at hand can’t emulate them. They need a look on Windows with a contrast theme.
  • Two navigations share one name: the language pill and the footer’s language list are both “Language”.
  • Spacing literals off the scale (3rem, 2rem, 0.75rem and others) remain from before L3.
  • Two topic dots pass narrowly on light chips: meaning at 1.6:1 and careers at 1.9:1, against a floor of 1.5.
  • The scenes are 800px captures of the Gemini window, not full-size downloads: fine at the sizes used, soft on large screens. Full size comes from Chrome (K10).
  • K10 and K11 have no specimen on this page yet, only on the home.

12. Changelog

  • 0.4 · 2026-11-03. The home with the character goes live: Leon’s likeness, his choice. New rules K10 (the character) and K11 (hills); K6 cards become pebbles. The scenes are built by Astro’s <Image> (sizes and srcset).
  • 0.3 · 2026-11-02. The page in three languages: the rules in src/brand/spec/<lang>.md, the page’s words in src/brand/ui.ts, and a build check that keeps translations at the original’s version (V7).
  • 0.2 · 2026-11-02. Closed the gaps of 0.1. Every role is one light-dark() line (C9). Topic colors became tokens; the fundamentals dot is visible in the dark again (C6), and the dead CSS around it is gone. Accessible names are translated (V6). theme-color reads the tokens (M3). A spacing scale (L3, proved to change no value). Rules for forced colors and print (A5, A6); print checked by printing to PDF.
  • 0.1 · 2026-11-02. First version, extracted from the sessions that built the site: the identity, the sunflower, the theme toggle.