[00]STYLEGUIDE> man design-systemnoindex

The parts WESLI.DEV is built from, with their states and real content. Page builders work from this page and COMPONENTS.md; nothing here is invented for the demo.

evolution
0034
last commit
05 OCT 2026 22:01 · #5f67501
built
05 OCT 2026 22:01 (git)
tokens
17 colours · 10 type sizes · 9 spaces

[01]> cat tokens.css | grep color

Near-black screen, off-white text, greys for hierarchy. Green means live or active, nothing else; amber is for alerts, red for errors. Contrast is measured against the background.

  • --color-bg#060908the screen1.0:1
  • --color-surface#0b0f0dpanels, inputs1.0:1
  • --color-raised#111714hover planes1.1:1
  • --color-fg-strong#f2f5f3emphasis, selection18.2:1
  • --color-fg#d8dddabody text14.5:1
  • --color-muted#8d9691secondary text6.6:1
  • --color-subtle#7e8782metadata (min. text)5.4:1
  • --color-dim#56605bdecoration only3.1:1
  • --color-line-faint#121916grid guides1.1:1
  • --color-line#1f2824hairlines1.3:1
  • --color-line-strong#34403aframes, inputs1.8:1
  • --color-accent#50d890live / active ONLY11.0:1
  • --color-accent-dim#2b7a52live, quiet3.8:1
  • --color-accent-ghostrgb(80 216 144 / 0.1)live wash—
  • --color-alert#f0b44calerts10.8:1
  • --color-error#ff8a7aerrors8.7:1
  • --color-scrimrgb(6 9 8 / 0.86)dialog / nav scrim—

[02]> fc-list | grep JetBrains

One mono voice, JetBrains Mono, with a real hierarchy: every size tracks the viewport's system scale and is clamped to stay legible.

mega · page headers

EVOLUTION

headline · statements

I BUILD SYSTEMS

title · section titles

Built to learn

lead · intros

I build software that can think, act and improve.

reading · long text

A lot of my code is now written by coding agents that I direct and check. The work moved from typing every line to deciding what to build, setting the constraints and verifying what comes back.

body · UI text

Systems I designed, built and still run.

label · caps metadata

[02] WORK · RECENT ACTIVITY · SYSTEM STATUS

micro · fine print

fig.02 · build #5f67501 · EVOLUTION 0034

Type tokens
tokenvalue
--text-microclamp(10px, calc(10px * var(--system-scale)), 13px)
--text-labelclamp(10px, calc(11.5px * var(--system-scale)), 15px)
--text-bodyclamp(11px, calc(13.5px * var(--system-scale)), 18px)
--text-readingclamp(15px, calc(16.5px * var(--system-scale)), 20px)
--text-leadclamp(12.5px, calc(17px * var(--system-scale)), 23px)
--text-roleclamp(12px, calc(17px * var(--system-scale)), 24px)
--text-titleclamp(22px, calc(32px * var(--system-scale)), 52px)
--text-headlineclamp(32px, calc(60px * var(--system-scale)), 104px)
--text-displayclamp(40px, calc(var(--display-base) * var(--system-scale)), 176px)
--text-megaclamp(46px, calc(9.2vw * var(--mega-factor)), 216px)

[03]> ls -la ./grid

Twelve columns inside the gutters, hairlines with + ticks where they meet. Spacing is a fluid scale; radii are zero.

.grid-12 + .grid-lines

010203040506070809101112span 4span 8

Rule

[02]SELECTED WORK03 CASES
DRAWS ON VIEW

.hairline · .frame


A hairline box with two + ticks: the light version of a Panel. Use it for figures, inputs and quotes.

spacing scale

  • --space-3xsclamp(2px, calc(4px * var(--system-scale)), 6px)
  • --space-2xsclamp(4px, calc(8px * var(--system-scale)), 12px)
  • --space-xsclamp(6px, calc(12px * var(--system-scale)), 18px)
  • --space-sclamp(10px, calc(16px * var(--system-scale)), 24px)
  • --space-mclamp(14px, calc(24px * var(--system-scale)), 36px)
  • --space-lclamp(20px, calc(36px * var(--system-scale)), 56px)
  • --space-xlclamp(28px, calc(56px * var(--system-scale)), 88px)
  • --space-2xlclamp(40px, calc(88px * var(--system-scale)), 136px)
  • --space-3xlclamp(56px, calc(136px * var(--system-scale)), 208px)

[04]> grep -n '## ' case.md

SectionHeader introduces every section: index, command, title, intro. The title scrambles in the first time it scrolls into view.

[02]> tail career.log

From web design to agents, as a system log.

[03]> ls ~/products, 03 ITEMS

[05]> ./controls --states

Buttons are commands: [ LABEL ] at rest, the shell command typed out on hover or focus, executing... when pressed (the one moment a button turns green). Hover and tab through these.

CommandLink

CommandButton · states

Disabled shows a dashed frame and never its command (the email channel is a placeholder, so the composer's send looks like this).

Tag

SvelteKitAstro + SanityCloudflare WorkersSupabaseStripeMCP / LLM agentslive, in active developmentexperimentalneeds reviewfwrd.digital

Hover only brightens a chip. Pressed is a state: green brackets, a ghost fill and an underline, so it never depends on colour alone. Filter chips need JS and are not rendered without it.

Kbd · Tooltip · Glyph

control plus kcommand or control plus kg then w?escEVOLUTION 0034 · launch SEO: let Google/Bing see the experience noindex, noindex pages.dev hosts
  • arrow-right
  • arrow-left
  • arrow-up
  • arrow-down
  • arrow-up-right
  • arrow-down-left
  • plus
  • close
  • search
  • command
  • enter
  • chevron-right
  • expand
  • copy
  • check

[06]> systemctl status wesli

Status dots say what is live. The clock, caffeinate level and weather are real and update in the browser; evolution comes from git at build time.

active / live idle muted alert
local timeNL
caffeinatecaffeinate: --
weatherUtrecht--°Csky pendingasking the window
FWRD releasev2.73.5 · 05 OCT 2026(live)

ProgressBar

Metric (real numbers only)

0034

evolutions

commits to this site

3

changes today

05 OCT 2026

03

case studies

07

routes

excluding shielded pages

Marquee

  • directing coding agents (Claude Code, headless)
  • LLM pipelines with structured output
  • model routing + fallback
  • MCP servers
  • embeddings + retrieval (pgvector)
  • prompt-injection guards
  • TypeScript
  • SvelteKit
  • Astro + Sanity
  • Expo / React Native

[07]> cat /proc/panels

Panels frame live readouts. On content pages they construct when they scroll into view; their [data-seq] rows populate one by one.

SYSTEM SPEC

FWRD Studio
role
founder / product & AI systems engineering
year
2026 — now
status
live, in active development
stack
SvelteKitAstro + SanityCloudflare WorkersSupabaseStripeMCP / LLM agents

PRINCIPLES

  1. Brief first, then code// three WebGL concepts for this site, dropped in one day: two for poor contrast and an invisible swarm, one for about 336 KB of JS against a 300 KB budget
  2. Verified, not claimed// Atlas reviews its own failures every night and adds guards
  3. Model output is data// Sponsorboard match pipeline, with a prompt-injection test

KeyValue

species
human (apparently)
origin
pencils and paint, then code
uptime
goes to the gym; Atlas watches the deploys
languages
Dutch, English, TypeScript
coffee
sufficient; see the home page

[08]> git log --oneline -n 12

LogList renders evolution entries, activity and releases on a git-graph rail, grouped by day. Rows can be linked and filtered by area.

05 OCT 2026 · MON3 changes

  1. 0034launch SEO: let Google/Bing see the experience noindex, noindex pages.dev hostswork
  2. 0033FWRD case images recaptured in Englishwork
  3. 0032case covers from real product captures instead of the ASCII art inputswork

04 OCT 2026 · SUN6 changes

  1. 0031atlas: live-tested prompt fixes, intent protocol and consented handoff to Wesliwork
  2. 0030contact form sends through Resend via a Pages Functioncontact
  3. 0029v2 QA: shared fixes, audits, per-area fixes, final verificationbuild
  4. 0028v2 pages: home, work, cases, experience, about, contact, now, evolution, colophon, 404system
  5. 0027v2 foundation: design system, page shell, command palette, footer, live datasystem
  6. 0026v2 groundwork: BRIEF, QA tooling, media helperbuild

03 OCT 2026 · SAT17 changes

  1. 0025updated the experience pageswork
  2. 0024updated the experience pageswork
  3. 0023experience: uncropped screenshots, four projects marked as updateswork
  4. 0022home: drop the left rail and the boot log framehome
  5. 0021updated the experience pageswork
  6. 0020sticky nav with CTAs, announcement bar, comment-free build, Talk to Atlassystem

Subjects that name shielded work are replaced at build time ("updated the experience pages").

[09]> open fig.01

Figures are framed, numbered and zoomable: click or press enter for the lightbox, arrow keys to browse every image on the page, esc to close.

Two browser windows on a dark backdrop: the fwrd.digital homepage hero, 'Describe your business. Get a website that maintains itself.' above a prompt box, and in front of it the FWRD Studio start screen at app.fwrd.digital/start, with a prompt box under 'Your site should be working as hard as you. Let's fix that.'
fig.01Two browser windows on a dark backdrop: the fwrd.digital homepage hero, 'Describe your business. Get a website that maintains itself.' above a prompt box, and in front of it the FWRD Studio start screen at app.fwrd.digital/start, with a prompt box under 'Your site should be working as hard as you. Let's fix that.'
Two browser windows on a dark backdrop: the getsponsorboard.com hero, 'Stop chasing sponsors, start choosing them.', and in front of it the how-it-works scan, a list of brands with match percentages where G FUEL (89%) and SteelSeries (88%) are locked as the strongest fits
fig.02Sponsorboard
The Atlas Hub in a browser window on a dark backdrop: the empty conversation with 'Atlas is listening.', a message composer and four starter questions, and on the right the golden point-cloud orb above a list of three live sessions
fig.03Atlas

[10]> cat case.md

Long-form text for case bodies and the colophon: headings read as system labels, lists as terminal output, figures with fig.0N captions.

FWRD is my Dutch web company, and FWRD Studio is its product. It treats a website as something that keeps being worked on after launch.

How it works

A visitor describes their business in a chat box. An LLM pipeline turns that description into a structured site config, and the config renders into a client template that is then provisioned on Cloudflare. Building is free. You pay when the site goes live.

  • The marketing site, fwrd.digital. Astro on Cloudflare Pages, with Sanity as a block-based page builder.
  • The hub, app.fwrd.digital. A SvelteKit app plus a separate Cloudflare Worker for generation, chat, Stripe webhooks and crons.
  • Client sites. Each site is built from one template, driven by tokens.

Every site has an MCP endpoint

Four tools: generate_page, edit_page, publish_site and run_report. The owner connects it to Claude and asks for changes in plain Dutch. Nothing goes live until it has been approved.

  1. Claude writes a schema-exact Sanity document.
  2. The server saves it as a draft.
  3. It scaffolds the Astro page.
Two browser windows on a dark backdrop: the fwrd.digital homepage hero, 'Describe your business. Get a website that maintains itself.' above a prompt box, and in front of it the FWRD Studio start screen at app.fwrd.digital/start, with a prompt box under 'Your site should be working as hard as you. Let's fix that.'
fig.02A Markdown figure: the image, then "*fig.0N — caption*" on the next line.

Receipts over model claims.

// FWRD Studio, decisions worth explaining
$ npm run build
> astro build && node scripts/pagefind.mjs
[pagefind] indexed 11 pages
routecommandgroup
/cd ~primary
/work/cd /workprimary
/about/cat about.mdprimary
/contact/ping wesliprimary
/now/cat now.mdsecondary
/evolution/git log --onelinesecondary
/colophon/man wesli.devsecondary

Press ctrl k anywhere to search.

[12]> cat fx.ts

Declarative reveals: add data-fx to an element and it plays once when it scrolls into view. Under reduced motion and in automated browsers everything renders in its final state.

SCRAMBLE

> typed in, left to right, one step per character

Blocks type in from top to bottom. Nothing reflows: the text is laid out before the clip opens, and screen readers always get the final content.

0034

timing tokens

Motion tokens
tokenvalue
--dur-instant80ms
--dur-fast160ms
--dur-base240ms
--dur-slow480ms
--dur-slower800ms
--ease-systemcubic-bezier(0.22, 1, 0.36, 1)
--ease-out-expocubic-bezier(0.16, 1, 0.3, 1)
--ease-in-outcubic-bezier(0.65, 0, 0.35, 1)
--ease-stepsteps(6, end)

AsciiWordmark

EVOLUTION 0034