Design References — Nothing + Teenage Engineering aesthetic
PHASE 1a of the local AI agent-wiki project. Visual research only: no code, no site files. This document is the brief that PHASE 2 (landing page build) implements.
Method note — what is measured vs. what is inferred. Two tiers of evidence are used throughout, and they are labelled at every claim:
- MEASURED = value read out of the live site's own HTML/CSS or its font metadata
(fetched directly from
cdn.shopify.com/teenage.engineering/google/fonts). Cited with a URL. - THIRD-PARTY = a token or measurement published by an external observer, not
verified by us against the live DOM. Used only for the Teenage Engineering
--te-*token set, because that site's own stylesheet is cross-origin-blocked to us (see §3.1). Always named. - PROPOSED = our design decision for this project. Not a claim about any site.
nothing.tech serves a geolocation interstitial that hides the real landing page from
this machine (Portugal detected, UK store requested). The anatomy in §2 was captured by
fetching the real page HTML, stripping the interstitial and its client-side redirects
locally, and screenshotting the resulting page. Everything in §2 is therefore the site's
own markup — the interstitial was removed, nothing else was styled or altered.
Screenshots backing every claim in this document:
docs/reference-screenshots/01-nothing-hero-nav.png
docs/reference-screenshots/02-nothing-category-stack.png
docs/reference-screenshots/03-nothing-editorial-blocks.png
docs/reference-screenshots/04-teenage-engineering-home.png
docs/reference-screenshots/05-teenage-engineering-products.png
1. Executive summary — the five decisions
- The dot font is Doto, at
ROND(roundness) 100, weight 400–700. It is the only free/OFL dot-matrix face on Google Fonts with a full 100–900 weight axis and a roundness axis, which is what lets it read as Nothing's NDot rather than as an arcade game. Silkscreen and Press Start 2P are too small-x-height to carry headlines; Pixelify Sans is too "soft/indie"; VT323 is a terminal face, not a display face. Doto: OFL-1.1, variable, self-hostable — MEASURED. - The UI sans is Inter. Not Geist, despite nothing.tech shipping Geist: Inter has a
larger default x-height and an
opszaxis that keeps small body copy legible, which matters more here than family loyalty to the reference. Both are OFL-1.1 and on Google Fonts — MEASURED. (§5 has the full rationale.) - The palette is near-monochrome with exactly one functional accent. Nothing's
restrained greyscale ramp does the work; we take its
--accent-blueas our single link/interaction colour. Teenage Engineering's five-colour hardware code is explicitly rejected for us — we are one category, not a hardware catalogue (§6). - The layout is full-bleed stacked editorial blocks, not a card grid. This is the single most load-bearing structural finding: nothing.tech's landing page is a single-column stack of full-width blocks alternating light and dark, with only a 3-column grid deep in the products grid. A landing page built as a card grid will not look like the reference (§2, §4).
- Restraint is the whole aesthetic. Both references derive their cohesion from what they refuse: no gradients, no shadows, no rounded corners, no second accent, no decorative type. Every rule in §7 is a prohibition.
2. Reference A — nothing.tech (primary reference)
2.1 Platform and type stack (MEASURED)
nothing.tech is a Shopify Oxygen (Hydrogen) storefront. Its single bundled
stylesheet declares these @font-face families — read directly from the live CSS asset:
Source: https://cdn.shopify.com/oxygen-v2/43495/38485/80939/4680968/assets/BuU4b1Wn.css
(fetched, 119,915 bytes; family list extracted verbatim)
Family (exact font-family string) |
Role we infer | Evidence |
|---|---|---|
Ndot-Regular / Ndot-Bold |
the dot-matrix display/headline face | declared in CSS; utility classes .font-ndot, .font-ndot-bold present |
NType82-Regular / NType82-Headline |
grotesque UI + heading sans | declared in CSS; utilities .font-ntype82, .font-ntype82-headline |
LatteraMonoLL |
monospace for specs/data | declared in CSS (note the site's own spelling Lattera, not Lettera) |
Geist Variable |
sans fallback / utility | declared in CSS |
Geist Mono Variable |
mono fallback / utility | declared in CSS |
ui-sans-serif, system-ui, … |
Tailwind default fallback chain | declared in CSS |
The utility class declarations, verbatim from the same CSS:
.font-ndot{font-family:Ndot-Bold,sans-serif} <- note: as published, .font-ndot
.font-ndot{font-family:Ndot-Regular,sans-serif} maps to Bold and
.font-ntype82{font-family:NType82-Regular,sans-serif} .font-ndot-bold to Regular;
.font-ntype82-headline{font-family:NType82-Headline,sans-serif}
Licensing consequence (important): Ndot and NType82 are proprietary,
non-redistributable faces — custom cut for Nothing, not published under an open
license and not on Google Fonts. The class names ndot-* / ntype-* are also present in
the page's own markup (ndot-heading-lg, ntype-display-xl, ntype-subheading-md,
ndot-heading-sm, ntype82 — extracted from the fetched HTML), which is useful
vocabulary for naming our type roles, but the font files themselves cannot be used.
This is precisely why §5 exists: we need an OFL stand-in that carries the same job.
Third-party corroboration that Nothing's display face is a dot matrix and its UI face a
grotesque (THIRD-PARTY, not verified by us): a community design-system writeup records
"Display font: NDot 55 / NDot 57 — dot matrix, 24px minimum; UI font: NType 82 — all
labels uppercase, 0.08em+ letter-spacing; Mono font: NType 82 Mono"
(https://github.com/VoltAgent/awesome-design-md/issues/363). We did not verify the
0.08em tracking or the 24px minimum against the live CSS; treat those two numbers as
unverified.
2.2 Colour palette (MEASURED — the real token set)
Nothing runs Tailwind and publishes its palette as space-separated RGB channel
triples (the rgb(var(--token) / alpha) pattern). Extracted verbatim from the same CSS:
--greyscale-white: 255 255 255
--greyscale-black: 4 4 4 <- not #000000. Their "black" is #040404.
--greyscale-100: 244 244 244
--greyscale-200: 216 217 217
--greyscale-300: 203 204 204
--greyscale-400: 190 192 192
--greyscale-600: 155 157 157
--greyscale-700: 133 135 135
--greyscale-800: 111 112 112
--greyscale-900: 89 90 90
--greyscale-1000: 60 60 60
--greyscale-default:177 179 179
--greyscale-dm-dark: 4 4 4 <- dark-mode surface
--greyscale-dm-light:24 24 24 <- dark-mode raised surface
--accent-blue: 0 47 108 -> #002F6C
--accent-red: 200 16 46 -> #C8102E
--accent-yellow:255 199 0 -> #FFC700
Resolved to hex, Nothing's actual palette is:
| Token | Hex | Notes |
|---|---|---|
| white | #FFFFFF |
page canvas, card fill |
| black | #040404 |
primary ink — a 4-level black, deliberately not pure |
| grey 100 | #F4F4F4 |
page canvas on light sections (also seen as an inline #F4F4F4 in the HTML) |
| grey 200 | #D8D9D9 |
hairlines, dividers |
| grey 300 | #CBCCCC |
faint fills |
| grey 400 | #BEC0C0 |
— |
| grey 600 | #9B9D9D |
secondary text |
| grey 700 | #858787 |
— |
| grey 800 | #6F7070 |
— |
| grey 900 | #595A5A |
muted text (also appears as #595a5a at 5% opacity, a tint wash) |
| grey 1000 | #3C3C3C |
near-black surface |
| dm dark | #040404 |
dark-mode ground |
| dm light | #181818 |
dark-mode raised block |
| accent blue | #002F6C |
links, interactive |
| accent red | #C8102E |
the Nothing signature red — product/brand, not chrome |
| accent yellow | #FFC700 |
campaign/alert |
Two things worth stealing and one worth correcting. Steal: the black is #040404,
not #000000 — a single LSB of lift that stops large type from vibrating on screen.
Steal: the accent is a deep navy #002F6C, not a bright web blue; it reads as ink, not
as hyperlink. Correct: the popular perception of Nothing's site as "pure black and white
with red" is only two-thirds right — the measured accent-blue is a navy, and the greyscale
ramp carries eleven distinct steps.
2.3 Layout structure and spacing rhythm (MEASURED from markup + screenshot)
The landing page is a single-column vertical stack of full-bleed blocks. Verified in
the rendered capture (docs/reference-screenshots/01…03):
- Nav — white bar, full width. Left: hamburger. Centre: the
NOTHING (R)wordmark in the dot-matrix face. Right: bag icon. Height is compact; no dropdowns visible. - Announcement strip — a thin secondary bar directly under the nav holding two small
links (
EXPLORE OFFERS,LEARN MORE) and a dismissX. A dismissible promo rail, not a nav item. - Hero — full-bleed, and notably not a centred-headline-over-photo hero. It is a textured field (warm kraft/brown) with white rectangular cards laid at slight organic angles, overlapping rather than gridded. The dot aesthetic appears here as a physical device — patterns of black dots on the white cards — not as type. A blue badge carries the CTA; a red outlined rectangle runs down the right edge.
- Category stack — four consecutive full-width blocks, each a large product
photograph on a uniform light-grey (
~#F4F4F4) ground with a single small category link bottom-left:Earbuds >,Headphones >,Phones >,Watches >. This is the page's primary rhythm: one product, one idea, one link, full width, repeated. - Editorial blocks — the stack then mixes grounds: a watch on light grey, then a
product block on pure black (
Headphone ( 1 ) Profloating in the dark), then a dark cinematic campaign image ("On set with V, our new Global Brand Ambassador…"), then a light "Going pink?" teaser. The alternation of light/dark ground is the section separator — no rules, no cards, no dividers. - Footer — we could not capture it. The geolocation-stripped local render ends after the product blocks; repeated attempts to reach the footer at viewport heights up to 20,000px returned empty bands (the later bands contain only large product art). This is a documented gap, not an oversight — see §9.
Spacing rhythm, described from the capture: generous and uniform. Each full-bleed block owns its vertical space with no visible gutter between blocks — blocks are edge-to-edge and the colour change is the only separation. Interior padding inside text blocks is wide (roughly a 12-column desktop container). Product names sit small and understated relative to their image: the image is the hero, the type is the caption.
2.4 What makes it cohesive
- One dot motif, used three ways. As type (the wordmark), as physical pattern (dots printed on the hero cards), and as product hardware (the Glyph/matrix LED on the phone backs visible in the product shots). The motif is the brand, not decoration.
- Colour is rationed to the product. Red appears on the product (earbud case dot, watch strap, camera module) — never on chrome. Blue appears only on links. The page itself stays achromatic.
- Alternation instead of ornament. Light/dark ground changes do all the sectioning that rules, shadows, or cards would do elsewhere.
- The image always outranks the type. Headlines are small, quiet, sans-serif; only the wordmark gets the dot face. Restraint is what makes the one dot-matrix element land.
3. Reference B — teenage.engineering (secondary inspiration)
3.1 Evidence limitation (stated plainly)
teenage.engineering's own stylesheet is cross-origin and not fetchable by us. What we
verified ourselves is: the served HTML declares
font-family:UniversNextPro-Thin, 'UniversNextPro Thin', and the page markup contains
the tokens te-20, UniversNextPro, UniversNextPro-Thin. (Fetched from
https://teenage.engineering/, 136,641 bytes; and https://teenage.engineering/products,
310,403 bytes.) Hex values present in that HTML: #E5E5E5, #000000, #f1f2f2,
#ed2024, #c5c6cd, #231f20, #121114.
Note the naming drift we observed and are reporting rather than smoothing over: the
served HTML says UniversNextPro, while third-party token captures of the same site
record Univers TE-20 / TE-40. Both cannot be confirmed as current by us. The
--te-* colour token table below is therefore THIRD-PARTY.
The richer --te-* token set below comes from an external observer who captured the live
DOM and published the tokens: https://tastekit.dev/gallery/apps/teenage-engineering
(source line in their writeup: "teenage.engineering (live DOM, computed styles),
2026-07-25"; they also state one stylesheet was cross-origin-blocked to them, so their
breakpoint section is "not captured" — an honest limitation that matches ours).
A second independent observer, https://design.withfudge.com/share/teenage.engineering-design,
independently reports Univers in "extremely light weights", "approximately 94px of
horizontal padding on each side at desktop widths", and accent-blue #0071BB —
the two sources agree on the accent blue, which raises confidence in the token set.
3.2 Colour palette (THIRD-PARTY token capture)
--te-black #0f0e12 primary text / ink
(pure black) #000000 icons, display headlines, thick 4.5px rules
--te-grey-900 #4d4d4d strong secondary text
--te-grey-600 #767676 input borders, muted text
--te-grey-500 #a1a7af tertiary text
--te-grey-300 #b2b2b2 faint / placeholder
--te-grey-200 #cccccc disabled fills
--te-grey-100 #e5e5e5 light dividers, inverse body text <- we saw #E5E5E5 in their HTML
--te-grey-1000 #272727 the thick-rule colour
--white #ffffff page canvas
--te-white #f5f5f5 off-white raised surface
(section fill) #f6f8f7 dominant panel background, a cool off-white
Accent code — "equal-weight, used as full blocks — pick by category, never mix as tint":
--te-blue #0071bb accent / link
--te-green #006837 accent, also success
--te-orange #f05a24 accent / campaign blocks
--te-red #b81d13 accent
--te-yellow #fab413 accent / campaign blocks
--error #c0262c error state
Their own stated rule, quoted: "accents live in full-bleed blocks and product art, not in borders, text or hovers. Chrome stays black-on-white; hover is an opacity change, not a colour."
3.3 Typography (THIRD-PARTY, with our own HTML corroboration)
Two custom Univers cuts: te-20 (narrow neo-grotesque — nav, body, UI) and te-40
(wider open cut — display/headline). Weights run light only: 100 and 300 dominate;
there is no bold or medium in the voice. Their published role table:
| Role | Family | Size/Line | Weight | Tracking |
|---|---|---|---|---|
| Display (hero) | te-40 | ~42px+ / 1.11, fluid | 300 | normal |
| Section link | te-40 | 41.66 / 46.29 | 300 | normal |
| Nav / UI | te-20 | 24.69 / 37.03 | 100 | normal |
| Body | te-20 | 20.06 / 23.14 | 100 | normal |
| Eyebrow / label | te-20 | 24.69 / 37.03 | 300 | lowercase |
Their note on the odd px values is worth repeating because it changes how a spec should be written: "Sizing is fluid (vw/clamp) — the odd computed px values … are viewport-scaled, not a fixed ladder." Case discipline: lowercase throughout, proper nouns included; the fat display headlines are the only UPPERCASE.
3.4 Layout structure (MEASURED from our own captures)
- Nav — horizontal bar, all lowercase, and the distinctive part: a pictographic line-icon nav (fan/asterisk, square, rectangle, magnifier, download tray) paired to text labels, thin hand-drawn geometric outlines rather than a mono font. Far right: a geometric locale/menu mark.
- Products grid — a genuine 3-column grid on a flat light-grey field. Cards are
borderless and image-led: no card border, no shadow, no container. Product name in
uppercase, then a smaller uppercase descriptor beneath (
RIDDIM/ORIGINAL LAYOUTING MACHINE,K.O. II/COMPACT SAMPLER COMPOSER). - Feature sections — full-bleed single-column blocks, alternating pure black and light grey, product dramatically lit out of darkness (turntable, mixer, vinyl).
- Flatness is absolute — "dead flat — no gradients, no shadows"; separation comes from thick 4.5px rules, "the way a panel is silk-screened onto anodised aluminium."
3.5 What makes it cohesive
- Hairline weight as a single voice. One weight family, at 100/300 only, everywhere. The delicacy is the personality.
- Colour as a fixed hardware code. Five named colours, equal weight, used as full blocks. The constraint is what makes it feel industrial rather than playful.
- Lowercase + pictographic icons remove hierarchy noise; nothing shouts.
- One sanctioned moment of play — a fat rounded display face (te-40) for hyphen-joined headlines on a coloured receipt card. The exception proves the rule.
4. Landing page anatomy for PHASE 2 to implement
Structured description of both references' anatomy, plus the merged page we recommend.
Screenshots: docs/reference-screenshots/01…05.
4.1 nothing.tech anatomy (as captured)
[nav] white bar | hamburger | NOTHING(R) dot-matrix wordmark | bag icon
[strip] thin dismissible rail | EXPLORE OFFERS LEARN MORE X
[hero] full-bleed textured field (warm kraft) | white cards at organic
angles, overlapping | black dot patterns on the cards |
blue CTA badge | red outlined rect on right edge
[block 1] light grey ground #F4F4F4 | full-width product photo | "Earbuds >"
[block 2] light grey ground | full-width product photo | "Headphones >"
[block 3] light grey ground | full-width product photo | "Phones >"
[block 4] light grey ground | full-width product photo | "Watches >"
[block 5] light grey | CMF watch, red strap | "CMF >"
[block 6] PURE BLACK | Headphone (1) Pro floating | name + one-line claim
+ blue "Discover >"
[block 7] near-black cinematic campaign image | "On set with V…" | "Discover the
campaign >"
[block 8] light grey | "Going pink?" teaser | colourway hero
[block 9] light grey | "Headphone (a) >"
[block 10] light grey | "Phone (4a) Pro >"
[footer] NOT CAPTURED — see §9
4.2 teenage.engineering anatomy (as captured)
[nav] white bar, ALL LOWERCASE | wordmark | products+icon | store+icon |
latest+icon | finder+icon | download | instagram | locale mark
[label] "EP SERIES" + "UPDATE" tag
[grid] 3 columns, light grey, borderless image-led cards
| RIDDIM / ORIGINAL LAYERING MACHINE
| K.O. II / COMPACT SAMPLER COMPOSER
| (third device)
[feature] PURE BLACK, full-bleed | turntable lit out of darkness | "APC-2"
[feature] BLACK | vinyl sleeve | "SINUS TRANSMISSION COMPLETED"
[feature] light grey | K.O. II rear panel top-down | "EP-133" | "サンプラー"
[feature] BLACK | mixer low-angle | "K.O. SIDEKICK" / "2 CH STEREO MIXER"
[feature] white, scrapbook collage | "RIDDIM" | "SUPERTONE" | "TINGO FM"
[grid] BLACK | row of small hardware units
[overlay] yellow triangle cookie banner, lowercase, "settings" / "accept all"
4.3 The merged anatomy we recommend (PROPOSED)
Take the stack from Nothing (it is the better fit for a wiki's reading rhythm) and the discipline from TE (weights, case, flatness). Our landing page:
[nav] fixed, white, hairline bottom border | wordmark in Doto |
4-5 lowercase nav items in Inter | single accent-blue hover
[hero] full-bleed. Dot-grid field rendered in CSS (radial-gradient dots on
#F4F4F4) with ONE large Doto headline + one Inter subhead.
No photo needed — the grid IS the visual.
[stat strip] thin band, 3-4 facts (page count, source count, last build),
Inter tabular-nums, hairline-separated
[block] dark ground #040404 | "what this is" | Doto section head + Inter body
[grid] 3 columns, light ground, borderless cards = the six categories
| Doto or Inter uppercase category name + count + one-line desc
[block] dark ground | "the agent layer" | llms.txt/llms-full.txt/raw .md
presented as three quiet rows with monospace paths
[grid] light ground | latest entries, single column list, hairline rows
[cta] full-bleed accent-blue #002F6C block | Doto headline + Inter sub
+ one button (white on blue)
[footer] dark or white, hairline top border | 3 link columns + legal row,
Inter at 13-14px, grey-600
Ground discipline: alternate #FFFFFF / #F4F4F4 / #040404. Never a gradient,
never a shadow, never a border-radius above 2px.
5. Dot-matrix font shortlist
All eight faces below are SIL OFL 1.1 and all are on Google Fonts — verified by
fetching each OFL.txt and METADATA.pb from google/fonts. Self-hosting is therefore
permitted for every one; the Google Fonts CSS2 API was confirmed to serve each family.
5.1 Candidate table
| Font | Designer | Licence | Weights / axes | Google Fonts | Best for | Verdict |
|---|---|---|---|---|---|---|
| Doto | Óliver Lalan | OFL-1.1 (Copyright 2024 The Doto Project Authors) | variable, wght 100–900 + ROND 0–100 |
yes (Doto[ROND,wght].ttf) |
headlines, wordmark | WINNER |
| Pixelify Sans | Stefie Justprince | OFL-1.1 (Copyright 2021) | variable, wght 400–700 |
yes (PixelifySans[wght].ttf) |
softer pixel UI | runner-up |
| Silkscreen | Jason Kottke | OFL-1.1 (Copyright 2001) | 2 static: Regular 400, Bold 700 | yes (2 TTFs) | tiny labels, icons | too small-x-height for headlines |
| VT323 | Peter Hull | OFL-1.1 (Copyright 2011) | 1 static: Regular 400 | yes | terminal/console text | wrong category — MONOSPACE, not display |
| Press Start 2P | CodeMan38 | OFL-1.1 (Copyright 2012, Reserved Font Name "Press Start 2P") | 1 static: Regular 400 | yes | arcade/game pastiche | too game-like; RFN constraint |
| DotGothic16 | Fontworks Inc. | OFL-1.1 (Copyright 2020) | 1 static: Regular 400 | yes | Japanese-aware dot gothic | Latin coverage is secondary |
| Inter (UI sans) | Rasmus Andersson et al. | OFL-1.1 (Copyright 2020 The Inter Project Authors) | variable wght 100–900 (+ opsz 14–32) |
yes | body, UI | WINNER for UI |
| Geist (UI sans alt) | Vercel | OFL-1.1 (Copyright 2024 The Geist Project Authors) | variable wght 100–900 |
yes | body, UI | strong alternative |
| IBM Plex Sans (UI sans alt) | Mike Abbink, Bold Monday | OFL-1.1 (Copyright 2017 IBM Corp., Reserved Font Name "Plex") | variable wdth 75–100 + wght 100–700 |
yes | technical body | more character, less neutral |
Metadata citations (all fetched from https://raw.githubusercontent.com/google/fonts/main/ofl/<family>/METADATA.pb
and the matching OFL.txt): Doto date_added: 2024-09-27, category: SANS_SERIF,
classifications: DISPLAY, subsets latin/latin-ext/menu. Pixelify Sans
date_added: 2023-09-13, classifications: DISPLAY, subsets cyrillic/latin/latin-ext.
Silkscreen date_added: 2022-06-23, classifications: DISPLAY, subsets
latin/latin-ext/menu. VT323 date_added: 2011-03-02, category: MONOSPACE, subsets
latin/latin-ext/menu/vietnamese. Press Start 2P date_added: 2012-04-04,
subsets cyrillic/cyrillic-ext/greek/latin/latin-ext/menu.
5.2 Why Doto wins (the argument)
It is the only candidate that can be tuned to look like NDot rather than like a game.
Doto carries two variable axes — wght 100–900 and ROND 0–100 (roundness). The ROND
axis is the decisive one: at ROND=100 the dots are circular and the face reads as an LED
/ dot-matrix display, which is exactly the Nothing look; at ROND=0 the dots become
squares and it reads as a pixel font. No other candidate on this list has that dial. This
is an inference about appearance from the documented axis — we did not render a
side-by-side specimen sheet in this phase; PHASE 2 should print a one-page specimen at
ROND 0/50/100 × wght 400/700 before locking it in.
Second, weight range. Doto's 100–900 axis means one file covers a whisper-thin eyebrow and a heavy hero headline. Silkscreen (400/700 only), VT323 (400 only), Press Start 2P (400 only) and DotGothic16 (400 only) each ship a single useful weight, so any hierarchy must come from size alone — which is precisely the failure mode that makes pixel sites look amateur.
Third, legibility at large sizes. Doto is classified DISPLAY with
category: SANS_SERIF and a proportional (non-mono) advance width, so it sets like a
sans at headline sizes. VT323 is category: MONOSPACE — every glyph occupies the same
advance, which is authentic-terminal but makes headlines ragged and hard to justify;
it is the wrong category for the job Paulo described. Silkscreen was drawn at a 5px
cap height for tiny display text (per https://github.com/amcchord/fonts-for-e-ink, it is
catalogued at 16px) and its x-height is far too small to carry a hero line.
Fourth, connotation. Press Start 2P says arcade cabinet. DotGothic16 says Japanese
terminal. Silkscreen says circuit-board silkscreen. Doto says LED readout — the
closest free analogue to a Glyph matrix / flip-dot display, which is the Nothing
reference's actual source. (Nothing's own Store Soho reportedly uses a large flip-dot
matrix display — https://nothing.wiki/nothing, THIRD-PARTY.)
Rejections, stated: VT323 — wrong category (monospace, not display) and a terminal connotation. Silkscreen — x-height too small for headlines; keep it only for 11–13px eyebrow labels if wanted. Press Start 2P — arcade connotation plus a Reserved Font Name, which restricts modified redistributions under OFL §3. DotGothic16 — Japanese-first design, Latin is a secondary concern. Pixelify Sans — the closest runner-up and the right choice if Paulo wants a softer, friendlier pixel look; it is a "humanist sans rendered on a pixel grid" and reads less like a hardware readout than Doto.
5.3 UI sans: Inter over Geist (PROPOSED, with reasons)
Nothing itself ships Geist Variable + Geist Mono Variable (MEASURED, §2.1), so Geist is the faithful choice. We still recommend Inter:
- Inter has an
opsz(optical size) axis, 14–32, which is the only one of the three designed to keep 14–16px body text legible. Our wiki pages are dense prose for humans; small-text performance outranks family resemblance. - Inter's default x-height is larger than Geist's, so body copy sets comfortably at 16px without a size bump.
- Geist remains the right pick if PHASE 2 wants maximal fidelity to the reference, or wants Vercel-ecosystem consistency. Both are OFL-1.1, both on Google Fonts, both variable 100–900 — switching is a one-line change.
- IBM Plex Sans is the third option and the most characterful: it has a slightly
technical, humanist feel that suits a research wiki, plus a
wdthaxis. It is the pick if the page should feel more "engineering document" and less "consumer hardware".
All three are OFL-1.1 and available via Google Fonts — MEASURED via the CSS2 API, which
returned valid @font-face blocks for Inter:opsz,[email protected],100..900,
Geist:[email protected], and Pixelify+Sans:[email protected].
5.4 Self-host vs. Google Fonts CDN (PROPOSED)
Self-host, subset to latin. Reasons: (a) the project's whole thesis is agent-first
and self-contained — a third-party font CDN is a runtime dependency and a privacy leak on
every page view; (b) PHASE 0 chose MkDocs + Material, a zero-JS-default stack, and a
Google Fonts <link> is a render-blocking third-party request that undercuts that;
(c) OFL-1.1 explicitly permits embedding and self-hosting. Keep only the latin subset
(all candidates list latin; Doto, Silkscreen, VT323, Pixelify Sans and Inter all also
carry latin-ext — include it if Portuguese diacritics matter, which they do for Paulo,
so ship latin + latin-ext). Serve as woff2 with font-display: swap and a
preload on the two families actually used above the fold.
Note: MkDocs Material supports self-hosted fonts via theme.font — but this document
makes no claim about Material's current config surface, since PHASE 0 recorded Material as
being in maintenance mode. PHASE 2 should verify the config key against the installed
version before relying on it.
6. Proposed colour palette for our site (PROPOSED)
Built from Nothing's measured ramp (§2.2), with one accent borrowed from Teenage Engineering's discipline (full blocks only, never as chrome tint) — not their five colours.
Grounds (alternate, never gradient):
| Token | Hex | Use |
|---|---|---|
--bg |
#FFFFFF |
default page ground |
--bg-sunken |
#F4F4F4 |
alternate section ground, card wash, the dot-grid field |
--bg-invert |
#040404 |
dark blocks — note: lifted off pure black, per Nothing |
--bg-invert-raised |
#181818 |
dark-mode raised surface, from Nothing's --greyscale-dm-light |
Ink:
| Token | Hex | Use |
|---|---|---|
--ink |
#040404 |
headings, primary text |
--ink-2 |
#595A5A |
secondary text (Nothing's --greyscale-900) |
--ink-3 |
#9B9D9D |
muted, captions, metadata (--greyscale-600) |
--ink-invert |
#FFFFFF |
text on --bg-invert |
--ink-invert-2 |
#D8D9D9 |
secondary text on dark (--greyscale-200) |
Lines: --rule #D8D9D9 hairlines (1px, the only line weight in normal use);
--rule-strong #3C3C3C for the occasional 2–3px structural rule (a nod to TE's 4.5px
silk-screen rule, dialled back for a text-first site).
Accent — exactly one:
| Token | Hex | Use |
|---|---|---|
--accent |
#002F6C |
links, interactive states, the CTA block. Nothing's measured --accent-blue. |
Reserved, not for chrome: --signal-red #C8102E for genuine alerts/errors only,
and --signal-yellow #FFC700 for warnings. Nothing uses red as product/brand colour;
we have no product, so red would be meaningless decoration — hence it is demoted to
signalling.
Explicitly rejected: TE's five-colour hardware code (blue/green/orange/red/yellow). It works because it maps to physical product categories on a hardware site. We have six knowledge categories and no hardware; five equal-weight accents would read as noise and would break the restraint that makes both references work. One accent, one voice.
Contrast note for PHASE 2 to verify in build: #595A5A on #FFFFFF is roughly 7:1 and
#9B9D9D on #FFFFFF is roughly 2.8:1 — the latter therefore must not carry body text or
meaningful labels, only decorative/muted metadata. These ratios are our arithmetic
inference, not a measured audit; run a real contrast check in PHASE 2 before shipping.
7. Proposed type scale (PROPOSED)
Three roles, three families, deliberately few sizes. Set in rem, 16px base.
Display — Doto, ROND 100. Used ONLY for: the wordmark, hero headline, section
headings, and the CTA. Never for body, never for nav, never below 24px.
| Role | Size / line-height | Weight | Notes |
|---|---|---|---|
| Hero (h1) | clamp(2.75rem, 7vw, 5.5rem) / 1.05 |
700 | the one loud moment on the page |
| Section head (h2) | clamp(1.75rem, 3.5vw, 2.75rem) / 1.1 |
700 | Doto, on dark and light grounds alike |
| Subhead (h3) | 1.375rem / 1.2 |
400 | Doto at lighter weight, or Inter 600 — pick one |
| CTA | 1.5rem / 1.1 |
700 | Doto, white on --accent |
| Eyebrow | 0.8125rem / 1.2 |
400, uppercase, letter-spacing .08em |
Doto; the .08em figure is the third-party-reported Nothing tracking, unverified |
UI + body — Inter.
| Role | Size / line-height | Weight | Notes |
|---|---|---|---|
| Lead paragraph | 1.25rem / 1.55 |
400 | hero subhead, section intro |
| Body | 1rem / 1.65 |
400 | prose, cards, lists |
| Small / meta | 0.875rem / 1.5 |
400 | captions, counts, dates, font-variant-numeric: tabular-nums |
| Nav | 0.9375rem / 1 |
400 | lowercase, per TE discipline |
| Button | 0.9375rem / 1 |
500 | uppercase or lowercase — pick lowercase for consistency |
| Footer | 0.875rem / 1.6 |
400 | --ink-3 |
Mono — for paths, commands, model names, byte counts. One choice, and we recommend
Geist Mono or ui-monospace rather than adding a third family: the wiki body is
agent-facing and full of file paths, so mono appears often and must be quiet. Inter has no
mono companion, which is the one real argument for Geist here — if PHASE 2 wants a
matched sans+mono pair, choose Geist + Geist Mono instead of Inter.
Case discipline (adopted from TE): nav and UI lowercase; section headings and card
titles uppercase or sentence case — decide one and hold it. Tracking: 0.08em on
uppercase eyebrows only; zero tracking on body.
8. Design direction statement
Mood. A instrument panel for a research library. The page should feel like a piece of well-made measurement equipment that happens to be a website: precise, quiet, slightly retro-digital, and completely unbothered about impressing you. It should read as built, not designed — the way a Teenage Engineering device looks machined rather than styled. The one moment of warmth is the dot grid itself: a texture that says this is a machine that talks in discrete units, which is also literally what an agent-facing wiki is.
The feeling to aim for, in one sentence: a flip-dot display in a Swedish lab notebook.
The rules.
We will:
- Use exactly one dot-matrix family (Doto) and exactly one UI sans (Inter), plus one quiet
mono. Three families, no more.
- Alternate three grounds — #FFFFFF, #F4F4F4, #040404 — and let the colour change be
the section separator. No rules between sections, no cards with borders.
- Keep the page achromatic except one accent, #002F6C, used for links and the single CTA
block.
- Set UI text lowercase; reserve uppercase for short eyebrows with 0.08em tracking.
- Use Inter at weight 400 for body and never go above 500 for UI; let Doto be the only
heavy element on the page.
- Keep the image (or the dot grid) larger than the words. Type captions, never type
posters.
- Self-host and subset the fonts to latin + latin-ext.
- Hold a generous, uniform vertical rhythm; full-bleed blocks with no gutters between them.
We will not:
- No gradients. Ever. Both references are dead flat.
- No box-shadows, no drop shadows, no glassmorphism, no blur.
- No border-radius above 2px. Nothing's cards are square; TE's rounding is reserved for
hardware-like controls.
- No second accent colour, and no accent used as a border, hover tint, or text colour on
light ground. Accent = link + CTA block, full stop.
- No dot-matrix type below 24px, and never for body copy or nav.
- No emoji as iconography. TE uses drawn pictographic line icons; if we need icons, draw
or source simple 1.5px-stroke line icons.
- No carousels, no auto-playing anything, no scroll-jacking, no parallax.
- No pure #000000 — our black is #040404, which is measurably what Nothing uses.
- No card grid as the primary page structure. Our stack is editorial; the only grid is the
six-category block.
How the sections should feel.
- Nav — almost invisible. White, hairline underline, lowercase, a Doto wordmark that is the only decorative element above the fold. It should feel like a label silkscreened on a panel.
- Hero — the one loud moment. A dot-grid field on
#F4F4F4with a single large Doto line and one Inter subhead. It should feel like a machine booting and printing its own name. Nothing else competes with it. - Stat strip — quiet, factual,
tabular-nums. Feels like a spec sheet row. - "What this is" — on
#040404. The dot grid inverts to dark; type drops to white. This is the page's first gear-change and it should feel deliberate, like a panel lighting up. - Category grid — back to light, three columns, borderless, image-free (or with a small dot-grid glyph per category). Feels like an index, not a shop.
- Agent layer — dark again. Three rows, monospace paths (
llms.txt,llms-full.txt,/raw/<slug>.md), one line of Inter each. This is the section that makes the project distinct and it should feel like a technical appendix — precise, unglamorous, confident. - Latest entries — light, single column, hairline-separated rows. Reads like a log.
- CTA — the only full accent block on the page:
#002F6Cedge to edge, Doto headline in white, one button. Because it is the only saturated field on the page it will not need to shout to be found. - Footer — quiet, three link columns, legal row in
--ink-3. Feels like the back of a manual.
Open question for Paulo (not blocking PHASE 2). Should the hero carry a real photograph the way nothing.tech does, or should the dot grid alone be the visual? Our recommendation is grid-only: it is cheaper, it ages better, it needs no asset pipeline, and the reference's dot motif is stronger as texture than as photography. But nothing.tech's actual hero is photographic, so this is a deliberate divergence from the primary reference and Paulo should make the call.
9. What we could not determine (documented gaps)
Reported plainly rather than filled in:
- nothing.tech's footer. Not captured. The geolocation interstitial could not be
dismissed in headless Chrome (it is a server-side redirect decision plus a client-side
modal), and the locally-stripped render ends after the product blocks. Viewport heights
up to 20,000px returned empty bands past the product stack. §4.1 marks it
NOT CAPTURED. PHASE 2 should design the footer from §4.3 (our proposal) rather than from the reference. - Nothing's exact type scale in px. Their stylesheet is Tailwind-generated and the utility classes resolve sizes at runtime; we did not extract a full px ladder. The sizes in §7 are our proposal, informed by Nothing's relative hierarchy (image ≫ caption), not by measured values.
- Nothing's spacing rhythm in px. Not extracted as numbers. §2.3 describes it qualitatively (uniform, full-bleed, no inter-block gutters) from the rendered capture.
- The
0.08emuppercase tracking and "24px minimum" for NDot. Third-party reported, not verified against the live CSS. - Teenage Engineering's own
--te-*token values. Third-party (tastekit.dev,design.withfudge.com). Their stylesheet is cross-origin-blocked; we verified onlyUniversNextPro-Thinfrom their HTML and the hexes#E5E5E5 #000000 #f1f2f2 #ed2024 #c5c6cd #231f20 #121114in the served markup. - Which Univers cut is current —
UniversNextPro(their HTML) vsUnivers TE-20/40(third-party captures). Unresolved; it does not affect our recommendations since neither is licensable by us. - Doto's rendered appearance at various
RONDvalues. We verified the axis exists and its range fromMETADATA.pb; we did not render a specimen grid. PHASE 2 should print one before lockingROND. - TE's breakpoints. Their own observer records these as "not captured" because one stylesheet was cross-origin-blocked; we did not measure them either.
- Contrast ratios. §6's ratios are our arithmetic, not an audited measurement.
- Whether Nothing's
.font-ndot/.font-ndot-boldclass mapping is intentional. The published CSS maps.font-ndot→Ndot-Boldand.font-ndot-bold→Ndot-Regular, which looks like an inversion bug in their build. Reported verbatim; not our concern to fix, and it does not affect our type choice.
10. Sources
Primary / measured:
- nothing.tech live HTML —
https://nothing.tech/(fetched, 312,175 bytes) - nothing.tech bundled stylesheet —
https://cdn.shopify.com/oxygen-v2/43495/38485/80939/4680968/assets/BuU4b1Wn.css(fetched, 119,915 bytes; source of §2.1 families and §2.2 tokens) - nothing.tech font assets —
https://cdn.shopify.com/oxygen-v2/43495/38485/80939/4680968/assets/DVQYVosZ.woff2and.../DGPYmcrD.woff2 - teenage.engineering live HTML —
https://teenage.engineering/(fetched, 136,641 bytes) andhttps://teenage.engineering/products(fetched, 310,403 bytes) - Doto licence + metadata —
https://raw.githubusercontent.com/google/fonts/main/ofl/doto/OFL.txt,.../ofl/doto/METADATA.pb - Pixelify Sans licence + metadata —
.../ofl/pixelifysans/OFL.txt,.../ofl/pixelifysans/METADATA.pb - Silkscreen licence + metadata —
.../ofl/silkscreen/OFL.txt,.../ofl/silkscreen/METADATA.pb - VT323 licence + metadata —
.../ofl/vt323/OFL.txt,.../ofl/vt323/METADATA.pb - Press Start 2P licence + metadata —
.../ofl/pressstart2p/OFL.txt,.../ofl/pressstart2p/METADATA.pb - DotGothic16 licence —
.../ofl/dotgothic16/OFL.txt - Inter licence —
.../ofl/inter/OFL.txt - Geist licence —
.../ofl/geist/OFL.txt - IBM Plex Sans licence + metadata —
.../ofl/ibmplexsans/OFL.txt,.../ofl/ibmplexsans/METADATA.pb - Google Fonts CSS2 API (font-serving verification) —
https://fonts.googleapis.com/css2?family=Doto:[email protected]&display=swap,...family=Doto:[email protected],...family=Pixelify+Sans:[email protected],...family=Inter:opsz,[email protected],100..900,...family=Geist:[email protected] - Google Fonts specimen pages —
https://fonts.google.com/specimen/Doto,.../Silkscreen,.../Pixelify+Sans,.../VT323,.../Press+Start+2P,.../DotGothic16
Third-party (labelled as such in-text):
https://github.com/VoltAgent/awesome-design-md/issues/363— Nothing NDot/NType 82 roleshttps://tastekit.dev/gallery/apps/teenage-engineering— TE--te-*token set, Univers TE-20/40, type role tablehttps://design.withfudge.com/share/teenage.engineering-design— corroborates Univers light weights, ~94px side padding, accent#0071BBhttps://github.com/sozanskidan/designing-with-ai/blob/main/design-mds/teenage-engineering-design.md— TE colour/font scrapehttps://github.com/amcchord/fonts-for-e-ink— Silkscreen 16px classification, Doto/Pixelify/ProFont licence tablehttps://github.com/googlefonts/silkscreen— Silkscreen provenance (Jason Kottke, 2001)https://nothing.wiki/nothing— Nothing brand description, dot-matrix typography, flip-dot display in the Soho storehttps://norrly.io/inspiration/nothing-tech— nothing.tech font/colour breakdown (heading NType82, body Arial)
Local captures produced by this task:
docs/reference-screenshots/01-nothing-hero-nav.pngdocs/reference-screenshots/02-nothing-category-stack.pngdocs/reference-screenshots/03-nothing-editorial-blocks.pngdocs/reference-screenshots/04-teenage-engineering-home.pngdocs/reference-screenshots/05-teenage-engineering-products.png