Adam Foster · Design System

Style guide for adm.io.

The tokens, type and components behind adm.io — the portfolio site you're looking at. Everything is driven by a single set of CSS variables that swap between light and dark — toggle the theme (top right) to see this page respond live, while the colour table below always shows both values side by side.

01Colour

Every token carries two values — one for dark mode, one for light. They're referenced as var(--hk-*) and swap automatically with the theme, so each row below shows both side by side.

Surfaces & lines

--hk-bg

Page background

Dark#090d15
Light#f3efe7

--hk-cta

CTA / lifted surface

Dark#0f1420
Light#e1dacf

--hk-panel

Panel surface (chat, tooltips)

Dark#0f1420
Light#faf8f3

--hk-head

Header / input bars

Dark#0c111b
Light#efe9df

--hk-bubble

Bubble / chip / tile surface

Dark#141a27
Light#fbf8f2

--hk-line

Hairlines & borders

Dark#222a3a
Light#dcd6c9

Text

--hk-ink

Primary text & headings

Dark#ece7dd
Light#1c1a15

--hk-body

Body copy

Dark#969cab
Light#4f4a42

--hk-muted

Muted labels / meta

Dark#626a7a
Light#9a9488

--hk-faint

Faint captions / coordinates

Dark#8b92a2
Light#6f6a5f

--hk-onimg

Text set over imagery

Dark#f3eee4
Light#f5f0e7

Accent & state

--hk-blue

Accent — electric blue

Dark#5b6ef5
Light#2f40c8

--hk-photo-tint

Photography duotone tint

Dark#5b6ef5
Light#97784c

--hk-error

Error / alert

Dark#ff7a80
Light#b4232a
02Typography

Three families: Fraunces for editorial display, Hanken Grotesk for interface and body, IBM Plex Mono for eyebrows, numerals and coordinates. Samples render in the active theme — toggle (top right) to see them in the other.

Display · FrauncesBuilding digital products
Display italic · accenttaste, speed, and ambition.
Heading · FrauncesOff the screen, behind the lens.
Body · Hanken GroteskI build at the intersection of engineering, design and product — from early ideas to launch and beyond.
Eyebrow · Plex MonoWhat I do
Mono · coordinates27.4698° S 153.0251° E
03Components

The recurring building blocks — labels, buttons, dividers, bullets, cards and tags — all theme-aware, shown here in the active theme.

Section label
Selected work
Buttons
Connect Send
Inline link
Explore work
Divider & bullet
Diamond bullet — used in lists
Card / surface

Ask about Adam

Grounded surface for bubbles, tooltips and chips.

Tags
Next.jsTypeScriptAgentic AIAWS
04Imagery

Cinematic, architectural photography carries the mood. Every story image has a paired light and dark frame that crossfades when the theme switches; work covers and the fine-art grid are tinted to the active theme instead.

Hero — DarkDark
Hero — LightLight

Hero

Full-bleed image behind the headline — the first impression and the loudest mood-setter.

About — DarkDark
About — LightLight

About

An editorial band paired with the about statement.

Contact CTA — DarkDark
Contact CTA — LightLight

Contact CTA

Dissolves into the “Let’s build” panel along its left edge.

How I work — DarkDark
How I work — LightLight

How I work

A quiet accent beside the four working principles.

work-lumenwork-northlinework-atlaswork-obsidian

Work covers

Square covers for the Selected Work carousel — one per live product.

single-finlighthousevenice-street-lightsrock-pool

Photography

Fine-art grid — desaturated with a theme tint, colourises on hover; sourced from buddsbeachhouse.com.

05Layout & viewports

A single 1240px content column on a 12-ish step rhythm, reflowing at three Tailwind breakpoints. The schematics below show how the shell rearranges as the viewport grows.

Mobile≤ 640px

Hamburger opens a full-screen menu. Hero text sits over a darkened image; grids drop to 1–2 columns.

Tablet640 – 1024px

Inline nav links appear; work and photography grids go to 3 across; the hero still stacks.

Desktop≥ 1024px

Full nav, a side-by-side hero, 4-column grids, and the assistant can expand full-screen.

06Assistant UX

“Ask about Adam” is a streaming, CV-grounded assistant. It lives in three escalating states and uses the accent blue to mark anything the visitor said.

Ask about Adam Grounded in his CV
Adam's assistant
Hi — I'm Adam's assistant, grounded in his CV. Ask me what he does, his projects, or the way he works.
You
What's his experience with AI?
Adam's assistant
Adam ships production agentic AI — RAG pipelines, vector storage and agent orchestration — with the LLMOps to keep it measurable and safe.
Ask about Adam…Send
Three states
  1. 01Pulse A blue gradient launcher with a ping dot, bottom-right.
  2. 02Floating A 380px popover anchored to the launcher.
  3. 03Expanded Desktop only — a full-screen frosted takeover that keeps the page visible behind it. State is shareable via ?chat=open|expanded.
Interaction colour

Visitor turns use a translucent accent-blue bubble — the one moment the accent fills a surface.

Assistant turns sit on the neutral bubble surface; answers stream token-by-token with a pulsing caret.

07AI scope & safety

The assistant is deliberately narrow. Its strongest safeguard isn't a filter — it's scope: the model is only ever handed a public CV, has no tools, and can reach no data or secrets, so there is nothing sensitive for a jailbreak to surface.

Limited — in scope
  • A static, public CV / profile string
  • Public project names & what Adam does
  • The current conversation (max 12 turns)
Locked — never in scope
  • The OpenAI key (server-only, never shipped)
  • Databases, analytics, admin or visitor data
  • The internet, files or any tool calls
  • Other pages' data or environment variables
Defending against jailbreaks
  • Scope first Even a successful jailbreak reaches only a public CV — there is nothing private to extract.
  • Server-owned framing The system prompt is built and prepended on the server; the client can only send user / assistant turns.
  • Input sanitised Roles are whitelisted and content is length- and turn-capped before it ever reaches the model.
  • Grounded + steered The prompt forbids inventing facts and steers off-topic or adversarial questions back to Adam's work.

Honest note: there is no dedicated jailbreak classifier or output filter — the design leans on minimal scope and server-controlled framing rather than trying to out-prompt every adversarial input.