Lab

Foundation · styles/nf/

The design system of nfrancois.fr.

The colors, typefaces, and components of the site. Everything on this page is rendered by the site’s real CSS, and the values are read from its files when the site is built.

Principles

01

Four rules hold it all together. They come from my brand guide, the same for the site, talks, and documents.

  • Three colors and some graysPaper, ink, and yellow. Screenshots, photos, and logos bring the rest of the color.
  • Yellow is rareOne use per screen: a highlighted word, the key value in a chart, or a solid block. Never yellow text on a light background.
  • Rules, not shadowsAn ink rule opens each section, a gray rule separates rows. The structure shows, with no depth effects.
  • Light first, dark by choiceThe site always opens in light mode. Dark mode applies when visitors choose it, and the choice is remembered.

What the site guarantees

  • A visible outline on every element reached with the keyboard.
  • Animations turned off when the device asks for reduced motion.
  • Body and secondary text above a 4.5:1 contrast ratio, in both themes (measured below).
  • Animated counters written into the page, readable without JavaScript and by search engines.
  • The theme set before the page shows, with no flash.
  • Cookie-free analytics (Plausible).

Colors

02

Each color is shown in both themes, light on the left and dark on the right. Contrast ratios are measured against the paper of the same theme, with WCAG thresholds: 4.5:1 for text, 3:1 for a rule or a field.

Backgrounds and surfaces

The page paper, the lighter paper of cards, the row hover.

  • --papier
    Light#F6F4EF
    Dark#141413
  • --papier-clair
    Light#FBFAF7
    Dark#1E1E1C
  • --survol
    Light#EDEAE3
    Dark#282825

Text

Ink for text, gray for secondary text and metadata.

  • --encre
    Light#1A1A1A15.8:1 · AA
    Dark#F6F4EF16.8:1 · AA
  • --gris
    Light#6B69645.0:1 · AA
    Dark#A8A59E7.5:1 · AA

Rules and strokes

Light gray for thin rules, mid gray for secondary bars, the stroke of form fields.

  • --gris-clair
    Light#D9D6CE1.3:1 · decorative
    Dark#34332F1.5:1 · decorative
  • --gris-moyen
    Light#8E8A823.1:1 · 3:1
    Dark#74716A3.8:1 · 3:1
  • --trait-champ
    Light#8A87813.3:1 · 3:1
    Dark#807D764.5:1 · 3:1

Yellow

The only bright color, and the ink written on it.

  • --jaune
    Light#FFD84D
    Dark#FFD84D
  • --on-jaune
    Light#1A1A1A12.6:1 · AA
    Dark#1A1A1A12.6:1 · AA

States

For forms only: an error, a successful submission.

  • --erreur
    Light#A3261B6.7:1 · AA
    Dark#E8705F6.1:1 · AA
  • --succes
    Light#2E6B3F5.8:1 · AA
    Dark#6FBF868.3:1 · AA

Typography

03

Hanken Grotesk for headings and numbers, Familjen Grotesk for text, JetBrains Mono for dates, sources, and markers. Three open-source typefaces, served by the site.

  • AaHanken Grotesk--font-display · 800 and 900
  • AaFamiljen Grotesk--font-sans · 400 to 700
  • AaJetBrains Mono--font-mono · 500, uppercase
Home page heading.nf-hero__title · clamp(40px, 7.2vw, 88px) · 800

Make it clear

Page heading.page-title · clamp(36px, 5.2vw, 56px) · 800

What I build

Lead.page-lead · 22px · 400

An introduction in one or two sentences.

Textbody · 18px · 400

Body text, at most 680 px wide, to keep lines easy to read.

Label.nf-label · 14px · 500

My approach

Marker.nf-fiche__date · 12px · 500

October 13, 2026

Number.nf-chiffre · clamp(48px, 6vw, 72px) · 900

3,000+

Shapes and motion

04

A single subtle radius, pills for what you click, a fixed column, and two curves for everything that moves.

  • --rayon 6pxPhotos, cards, screenshots, code blocks.
  • --radius-full 999pxButtons, filters, labels: fully rounded.
  • --container 1200pxColumn width.
  • --measure 680pxBody text width.
  • --rule-strong 2pxInk rule that opens a section.
  • --rule-thin 1pxGray rule between rows.

Spacing

  • --space-14px
  • --space-28px
  • --space-312px
  • --space-416px
  • --space-624px
  • --space-832px
  • --space-1248px
  • --space-1664px
  • --space-2496px
  • --space-32128px
  • --sortie-douce cubic-bezier(.2, .7, .2, 1)Starts fast, lands softly: hovers, highlights, menus.
  • --entree-sortie cubic-bezier(.65, 0, .35, 1)For what crosses: the yellow fill of the primary button.
  • --duree-courte 160msHovers and state changes.
  • --duree-moyenne 320msUnderlines and highlights that draw themselves.
  • --duree-longue 640msChart bars and reveals.

Icons and logos

05

The site’s icons come from Phosphor, Bold weight, in a single color and always next to text. The logos of the Lab’s tools are single-color too, to stay on brand in light and dark modes.

Site icons

  • Moon
  • Sun
  • Menu
  • Close
  • External link

Tool logos

  • Vercel
  • Supabase
  • Neon
  • Cloudflare
  • Claude
  • Claude Code
  • Google Cloud
  • Google Search Console
  • Plausible
  • Hostinger
  • GitHub
  • Gemini
  • Mistral
  • Mistral Vibe

Paths from Simple Icons (CC0 license). No open logo for ChatGPT, Google AI Studio, or Wispr Flow.

Components

06

The site’s classes, for real. Each snippet can be pasted as is into a page of the site.

Buttons

.nf-btn --primaire --secondaire --petit

On hover, a yellow fill rises in the primary button.

HTML
<a class="nf-btn nf-btn--primaire" href="…"><span class="nf-btn__lbl">Primary action</span></a>
<a class="nf-btn nf-btn--secondaire" href="…">Secondary action</a>
<a class="nf-btn nf-btn--primaire nf-btn--petit" href="…"><span class="nf-btn__lbl">Small</span></a>

Link

.nf-link

On hover, the underline redraws itself in yellow.

HTML
<a class="nf-link" href="…">Read the lab note</a>

Highlight

.nf-hl

1 to 4 words, on text at least 24 px, once per screen. In dark mode, the words turn yellow.

What I test with AI

HTML
<h1>What I <span class="nf-hl">test with AI</span></h1>

Labels

.nf-label .lab-etiquette .article__etiquette
My approachAI · Data · Prototypes
HTML
<p class="nf-label">My approach</p>
<p class="lab-etiquette">AI · Data · Prototypes</p>
<span class="article__etiquette">Behind the scenes</span>

Numbers

.nf-preuve

20 yearsin digital

3,000+newsletter subscribers

HTML
<div class="nf-preuve">
  <p><span class="nf-preuve__n">3,000+</span><span class="nf-preuve__l">newsletter subscribers</span></p>
</div>

Bar chart

.nf-bars .nf-bar--cle

A single key value in yellow, the others in mid gray.

Writing64%
Research41%
Translation23%
HTML
<div class="nf-bars">
  <div class="nf-bar nf-bar--cle">
    <span class="nf-bar__label">Writing</span><span class="nf-bar__val">64%</span>
    <span class="nf-bar__track"><span class="nf-bar__fill" style="width: 64%"></span></span>
  </div>
</div>

List row

.nf-fiches .nf-fiche

Talks, lab notes: date and type, title and summary, arrow.

HTML
<ul class="nf-fiches"><li><a class="nf-fiche" href="…">
  <span class="fiche__quand"><span class="nf-fiche__date">October 13, 2026</span><span class="fiche__type">Behind the scenes</span></span>
  <span><h3 class="nf-fiche__title">Turning an Excel spreadsheet into a web calculator</h3><p class="nf-fiche__meta">The summary, in one or two lines.</p></span>
</a></li></ul>

Light / dark toggle

[data-theme-bouton]

Try it: it switches the whole page.

Logo

07

The NF stamp: the N and the bar of the F drawn as a single line of ink, then the dot. In the top bar, it animates by drawing itself.