Start here
How a page is built
The rules each designed page has settled, and the page each came from. Every new page starts from these and adds what it learns, so the system gets better with each one.
Edit · components/hub/StyleguideViewer/PageRecipe.tsx · shared classes in styles/app.css
The pattern
A section and a card, built only from the shared classes. Start every new page here.
Your account
The line under a heading says what the card is for.
Maya Chen
maya.chen@example.com
One card for one job, with a main action if it has one.
Surfaces
What the page is made of.
The page is stone. Content sits on white cards with a soft stone edge and no shadow.
Clean, not playful: one quiet edge separates a card from the page without stacking tints.
Never a card inside a card, and never a stack of boxes for a list. One card holds the list; a hairline splits each item.
Nested or stacked rounded boxes read as bubbly; hairlines and type read as considered. Navigation's suggested questions were four boxes; now they are one card.
At most one dark block on a screen, and only for the one thing to do next, or where she is.
Navy is the anchor. Two anchors compete; a settings page like Profile needs none. In the advisor panel the only navy is the destination she is on, so her own messages are light blue.
Colour
Few colour areas, each with one job.
One accent per screen. Before adding a colour, say which colour it replaces.
Several colour areas at once (header tint, card fill, gold, glows, lime) tipped Home towards playful.
Colour is never the only cue. The words carry the meaning; the page must still read in greyscale.
Accessibility, and the greyscale switch reviewers use. Outcome dots are hidden from screen readers for this reason.
Red is only for destroying something: deleting the account, removing a connection.
Kept rare, so it always means the same thing.
Type
Kulim Park for headings only; Inter for everything she reads or presses.
Only paragraphs get the airy 1.7 line spacing. A one-line label, date or note uses tight spacing (1.3), so a card that ends in one doesn't look heavier at the bottom than at the top.
Line spacing adds invisible space above and below each line. On a single line it pads the card's edge, so 20px of padding looks like 25.
No text anywhere in the product is cut off with an ellipsis. Titles, headers, previews and placeholders wrap and show every word. An ellipsis written into the words stays: something in progress (Writing your first draft…) and a prompt to type (Ask or go…). One exception: a tool's pinned draft preview stops after two lines, because the card sits over the page and Show draft opens the whole draft.
Cut-off words hide what she needs to read. Keep a navy header short so it rarely needs a second line, but when it does, it wraps (designer, 2026-10-13).
Whatever is chosen or current steps up a weight: its label turns bold. Each label holds its bold width, so nothing shifts when the choice moves.
The choice is said by the type as well as by colour, which helps when colour alone is hard to see. Rings, chips, the nav, steps, filters.
Kulim Park is for display, title and heading. Labels, eyebrows, subheadings, body and captions are Inter.
Kulim gives the page its voice in a few places; Inter keeps everything else calm and easy to read. This covers the advisor's name, the where-you-are chip and chat replies too.
A section is a heading on the page, an optional line under it, then the card. The heading never goes inside the card.
Every page scans the same way: Home's Progress Tracker and Signal Picture, Profile's Account and Notifications.
A labelled read inside a card is a grey eyebrow, then the words. Blue eyebrows introduce a heading; grey ones label a read.
Why this / Why now / Why you on Home; Name and Email on Profile; Go to and Ask me in the advisor panel. One look for one job.
A label that names a group on the page (a list, a set of links, Why this matters) is a group title: the eyebrow's small capitals, a size up at 14px, in the copy's dark ink. The eyebrow itself stays for a single read or the line above a heading.
A label over a whole group needs a little more weight than one over a single read, without becoming a heading. Titles matter as much as the copy, so none is greyed out.
The title inside a list card (What to do next, What next?) is a card title: sentence case, Inter semibold, 16px, dark, 20px above the list.
It is the title for every item in the card, not the first, so it sits further from the list than an item's title does from its own line.
A group title sits 12px above its group, more than a line of body copy leaves; a card title 20px. A form field's label, and a question over its answers, sit 12px above them too. Bullets sit 16px apart, a step more than paragraphs. Items split by hairlines get 20px either side of the line.
Each kind of gap is said once and kept: a title belongs to its group, a bullet is its own item, a divider needs room to read as a divider.
Lists are indented: numbers or bullets sit inside the text's margin and the lines indent after them. Nothing hangs past the padding.
Hanging numbers in the advisor's answers ran out past the edge every other line respects.
Libre Baskerville italic is only for words that are said: a welcome line, ExecHQ speaking, her own words quoted back, a publication's name. Never a title, a label or interface text, and always clearly smaller than the screen's title.
One clear job keeps the serif meaning the same thing wherever it shows. At 22px under a 28px title it competed with the title on Reflection.
The editorial role has four sizes, each with one job. 28px: the web welcome's statement on its dark panel. 18px: ExecHQ speaking on a guided step. 16px: her words quoted back, and the chat's welcome line. 14px, at the 500 weight: a short line under a heading, a quote inside the chat, a publication's name.
The sizes had grown one per screen (14, 16, 22, 28). Four, each named for its job, make the choice obvious, and 14px italic needs the heavier weight to read.
Numbers in circles are one style everywhere: a 16px numeral in a 28px navy circle, the copy starting 16px past it, and 16px between items.
The smallest circle that still holds the numeral comfortably. Larger circles outweighed the copy beside them; smaller numerals were hard to read.
No line of copy leaves one word alone on its last line, and no line ends on a single word after a comma: that word drops to the next line.
A lone word reads as a mistake and makes a short paragraph look unfinished; "a result, so" at a line's end hangs the same way. Both are set as the copy renders, never by editing it.
A set of choices on the page is one card like a numbered list, without the numbers: each choice a title and a line, a hairline between them, a chevron at the right.
Stacked outlined boxes read as a pile of buttons; one card with rows reads as a considered set, and the chevron says each row can be pressed.
Body copy at 1.7 leading with a 12px gap between paragraphs. Captions are 13px regular.
Text-heavy screens get lighter through rhythm, never by cutting the copy.
Controls
Only buttons are pills, so the shape means "press me".
Only a card with a chevron is tappable. A card or chip without one is a reference, and its action sits on a button beside it.
The same look must always do the same thing, or people tap what does nothing.
Every prompt the advisor offers is one button style: the raised surface, a thin edge, 20px corners, sized to its words and wrapping so all show.
Suggested questions and reply buttons are the same job, so they look the same. Fixed corners keep a two-line prompt a rounded box, not a stretched pill.
In a stack of controls about 44px tall (prompts, a shortcut, the message box), every one takes the same 20px corners.
Mixed corners stacked on top of each other read as clutter.
What she said or made always sits in a white card, one line or many. Its action sits at the card's top right, centred on the eyebrow's line, in grey so it stays behind her words, with 8px under the line before her words. Change is a 12px underlined link; Edit is the edit icon alone.
Her input looks the same wherever it is shown, and the way to redo it is always in the same place. A pill there would be one more button competing with the yellow one.
Change when she picks again from choices; Edit when she types again.
The word says what will happen: Change reopens the question, Edit opens the words or fields.
Yellow is the one main action on a screen. Light blue is everything secondary, including the advisor's reply buttons. No white outlined buttons.
One clear next move, and a button looks the same wherever it appears. Still open: whether light blue and yellow are distinct enough side by side.
Hover never carries meaning. Every tap target is at least 44px.
ExecHQ is used on a phone first.
Chat
The advisor should feel like a chat app on a phone: the conversation, and little else.
No rules, boxes or outlined chips around the conversation. The header is just New chat and close, with no mark or name; on the phone they sit in the top corners, level with the grab bar.
Layers of chrome above the first message made the panel feel clunky next to Claude or ChatGPT on mobile.
One even gap between every message, 28px, the same above and below each of hers. Answers are set like Claude's chat: 1.55 leading, paragraphs and cards 12px apart; numbered steps keep their numbers.
16px and then 24px between turns felt tight, and uneven gaps around her messages made a card look attached to the wrong turn; no gaps inside an answer made it one block.
The product's places are one row of icon tiles, all six in view, the one she is on in navy. While she chats the row stays put above the conversation.
Destinations stay in reach while chatting. Kate's icon row was kept over text tabs (designer, 2026-10-09).
Spacing
Gaps are named for their job.
Cards run 16px from the phone's edge, 12px apart when one sits straight under another (half the 24px between sections; text without a card keeps the full gap), with 16px inside (20px in a feature card).
Wider cards, steady rhythm.
A card's last thing, a button or a flat link, sits 20px from its bottom edge, the same as its first thing sits from the top.
Every card ends the same way, so a link never looks squeezed against the edge. A tall tap target whose words sit high is the one allowance.
Inside a card, three steps of space, each wider than the last: eyebrow to title 4px, title to copy 8px, copy to button 20px.
The eyebrow and title read as one label, the copy belongs to them, and the button stands apart as the thing to do. Most cards take this; a card that needs otherwise is adjusted on its own.
Sections sit 32px apart; inside a section, heading, line and card sit 12px apart.
The gap between groups must be clearly bigger than the gaps inside them, or the page reads as one long list.
Pages that shaped it
Each page designed refines the rules above. Add a line when one does.
Home 6 October 2026
- Clean direction: stone page, white outlined cards, one navy anchor.
- Inter for every type role below heading.
- Grey eyebrow reads split by hairlines (the next-step card).
- 13px regular captions; outcome dots as a second cue.
Profile 6 October 2026
- Home's card and read lifted into shared classes: .card, .card--reads, .read.
- The section rule: heading on the page, line, then the card.
- Section rhythm: 32px between sections, 12px inside.
Navigation 7 October 2026
- A list of choices is one card with hairlines, not a stack of boxes.
- Grey eyebrows label groups inside a panel (Go to, Ask me).
- Kulim Park out of the chat: advisor name, reply chips and the where-you-are chip are Inter.
- Reply buttons are the light-blue secondary; her messages are light blue, not navy.
- Chat streamlined: slim header, 28px between messages, full-pill field, replies at the left.
- On the phone, New chat and close sit in the sheet's top corners with no header row.
- Say a thing once: a label is dropped when something above already says it (the advisor's name above each of his messages, under the panel's header).
- The places stay Kate's row of icon tiles, pinned above the chat (2026-10-09); text tabs were tried and set aside.
Onboarding 13 October 2026
- One numbered circle: 16px numeral, 28px navy circle, copy 16px past it, as tokens.
- Her answers in a guided step are her side of a conversation: the raised surface with a thin edge, the one she picks navy and bold, 12px apart.
- Step labels are the blue eyebrow; Why this matters is a grey-eyebrow read with no rule beside it.
- The welcome is navy edge to edge with the light logo at 48px.
- No lone word on a last line.
- A group title role (dark small capitals at 14px) and a card title role (sentence case, 16px, 20px above its list), with their own spacing: 16px between bullets, 20px either side of a divider.
- What next is one card of rows with chevrons, like Done's list without numbers.
- No single word left after a comma at a line's end.
- Form labels and questions sit 12px above their field or answers. The Google and Apple sign-in buttons follow their makers' guidelines exactly: Google's dark theme in Google Sans with the four-colour G, Apple's black.
- Libre italic only for words that are said, in four sizes with one job each.
- Her input always in a card, its action grey at the top right, centred on the label: Change as a 12px link, Edit as the new edit icon (pencil and square). Change to pick again, Edit to type again.
- Flat links sit at the left, 32px apart; Edit carries a pencil.
- An answer drawer's main action is full width, and any second action (Skip, Back, Later) is a secondary button the same size under it, a peer and never a smaller link. Onboarding and the Plan's check-ins share it.
- An example to follow (What good looks like) is the system's card with a grey eyebrow, like First draft.
- Kulim's letters close up: headings keep Kulim's own spacing (0), its text opens 0.01em and its labels 0.02em. The tighter word spacing stays.
Brand
Logo
Two versions of one logo. The dark logo sits on stone and blue 100; the light logo sits on any dark color.
Edit · components/primitives/Logo
Dark logo
Gold and navy. Sits on stone and blue 100. Not on light blue (blue 200): the gold falls to 4.2:1 there.
- ExecHQOn stone
--brand-stone - ExecHQOn blue 100
--brand-blue-100
Light logo
Bright yellow and light blue. Sits on a dark color, and in most cases on navy or the darkest navy: the logo stays in some form of navy. Dark green is the secondary choice; stone 900 is kept but largely unused for now.
- ExecHQPrimaryOn navy
--brand-navy - ExecHQPrimaryOn darkest navy
--brand-blue-900 - ExecHQSecondaryOn dark green
--brand-dark-green - ExecHQTertiaryOn stone 900
--brand-stone-900
Color
Brand colors
The main colors, by role. Each sits on one of the scales below at its exact palette value.
Edit · styles/tokens.css
Primary
The colors that make a screen ExecHQ.
- Navy
#002945Blue 800--brand-navy - Bright yellow
#f7d500Yellow 400--brand-bright-yellow
Secondary
Supporting colors, used in smaller amounts.
- Gold yellow
#856300Yellow 700--brand-gold-yellow - Light green
#d3f36aGreen 300--brand-light-green - Dark green
#014b42Green 800--brand-dark-green - Light blue
#d4e0ffBlue 200--brand-light-blue - Orange
#fd8143Orange 400--brand-orange
Neutral
One neutral: stone. Its 100 is the page, its 900 the near-black used in place of black.
- LightsStone
#f7f6f1Stone 100--brand-stone - DarksStone 900
#0e0c0aStone 900--brand-stone-900 - Cards and fieldsWhite
#ffffff--brand-white
Color
Color scales
Five scales, 100 to 900, with the palette colors named. Everything else is built from them.
Edit · styles/tokens.css
Blue
Navy (800) carries links, focus rings, dark panels and the approved badge. Blue 900, the darkest navy, is its deep end: pressed navy and deep backgrounds. Light blue (200) is the soft secondary. Tokens --brand-blue-100 to -900.
- Blue 100
#eff3ff--color-surface-sunken--color-surface-hover--color-surface-feature--color-glow-fade--color-text-inverse--color-wash-mid--color-status-draft-surface--color-status-approved-text--color-feedback-info-surface--color-text-on-selected--color-segmented-track
- Blue 200
#d4e0ffpalette: light blue--color-surface-active--color-surface-selected--color-surface-for-her--color-chart-glow-bottom--color-eyebrow-on-inverse--color-section-title-on-inverse--color-glow--color-action-secondary--color-wash-start--color-ring-progress-end--color-ring-complete-edge--color-sky-dawn--color-secondary-soft--color-surface-check-in-band--color-logo-hq-on-inverse--color-status-review-surface
- Blue 300
#a6beef--color-border-on-for-her--color-action-on-for-her-hover--color-text-inverse-muted--color-action-secondary-hover--color-ring-lift--color-ring-complete-deep--color-sky-day--color-sky-dusk--color-status-draft-border--color-pill-edge-on-inverse
- Blue 400
#789fe0--color-action-on-for-her-active--color-divider-on-inverse--color-action-secondary-active
- Blue 500
#497fc3--color-sky-dusk-edge-top--color-sky-night-spark--color-sky-night-edge--color-feedback-info-dot
- Blue 600
#22609c--color-eyebrow-on-for-her--color-stage-4--color-sky-dusk-outer--color-sky-night-glow--color-sky-panel-dusk-mid--color-secondary--color-eyebrow--color-edge-on-inverse--color-feedback-info-border
- Blue 700
#014472--color-surface-inverse-hover--color-text-on-for-her-muted--color-stage-3--color-border-inverse--color-sky-night-low--color-sky-panel-dusk--color-selected-hover
- Blue 800
#002945palette: navy--color-surface-inverse--color-text-on-for-her--color-action-on-for-her--color-chart-bar-base--color-stage-2--color-text-link--color-text-link-hover--color-text-on-action-secondary--color-nav-current-icon--color-text-on-wash--color-ring-done--color-ring-progress-start--color-sky-night-top-ring--color-sky-night--color-sky-panel-dusk-deep--color-icon-default--color-here-text--color-text-on-check-in-band--color-logo-hq--color-code-digit--color-focus--color-field-focus--color-status-approved-surface--color-status-approved-border--color-selected--color-outline-ink--color-text-on-selected-inverse
- Blue 900
#03151fdarkest navy — pressed navy, deep backgrounds--color-surface-inverse-active--color-surface-inverse-deep--color-stage-1--color-sky-night-top-core--color-sky-night-top--color-surface-quiet-on-inverse
Green
Success. Dark green (800) is its text and border, green 100 its surface. Tokens --brand-green-100 to -900.
- Green 100
#f1fdd8--color-wash-end--color-sky-night-fade-end--color-feedback-success-surface
- Green 200
#e3faa6--color-text-on-progress-muted--color-surface-note--color-surface-her-band--color-tag-surface--color-icon-surface--color-headline-on-navy-quiet
- Green 300
#d3f36apalette: light green--color-eyebrow-on-progress--color-chart-glow-top--color-sky-day-top-ring--color-sky-night-horizon
- Green 400
#a7db58--color-chart-bar-tip
- Green 500
#6ebb5d--color-outcome-positive
- Green 600
#389560--color-sky-panel-night-horizon--color-feedback-success-dot
- Green 700
#087158--color-border-progress
- Green 800
#014b42palette: dark green--color-surface-progress--color-text-on-her-band--color-surface-briefing-cover--color-tag-text--color-icon--color-feedback-success-text--color-feedback-success-border
- Green 900
#02302b
Yellow
Bright yellow (400) is the primary button, 500 on hover and 600 pressed. Gold yellow (700) is for small accents on light, and is the warning color. Tokens --brand-yellow-100 to -900.
- Yellow 100
#fdf8da--color-accent-soft--color-feedback-warning-surface
- Yellow 200
#fdf0aa--color-sky-heart-light
- Yellow 300
#fce46e--color-ring-complete-core--color-sky-day-ring--color-sky-day-top-core
- Yellow 400
#f7d500palette: bright yellow--color-headline-on-inverse--color-action--color-nav-current--color-sky-day-heart--color-accent-on-inverse--color-here-surface--color-logo-exec-on-inverse
- Yellow 500
#d3ad04--color-action-hover--color-action-edge--color-outcome-neutral--color-feedback-warning-dot
- Yellow 600
#ac8704--color-action-active
- Yellow 700
#856300palette: gold yellow--color-accent--color-logo-exec--color-feedback-warning-border
- Yellow 800
#644803--color-accent-hover
- Yellow 900
#432f07
Orange
Orange into red. From 600 the scale turns red for danger (border 600, text 700). The palette orange (400) is too light for text on white. Tokens --brand-orange-100 to -900.
- Orange 100
#fff0e8--color-feedback-danger-surface
- Orange 200
#ffdac8--color-sky-dusk-top-core--color-sky-panel-dusk-heart
- Orange 300
#ffb38f--color-ring-complete-mid--color-sky-heart-warm--color-sky-dusk-ring--color-sky-dusk-top-ring--color-sky-panel-dusk-ring
- Orange 400
#fd8143palette: orange--color-sky-dusk-heart
- Orange 500
#eb5520--color-nav-dot--color-outcome-negative--color-feedback-danger-border--color-feedback-danger-dot
- Orange 600
#d72212 - Orange 700
#b30614--color-danger--color-feedback-danger-text
- Orange 800
#8a0e15--color-danger-hover
- Orange 900
#5f0c10--color-danger-active
Stone
The one neutral. 100 is the platform's page; 200 and 300 are quiet, hover and pressed surfaces; 400 to 600 are borders and secondary text; 900 is the near-black used in place of black. Tokens --brand-stone-100 to -900.
- Stone 100
#f7f6f1palette: stone--color-card-on-inverse--color-drawer-on-inverse
- Stone 200
#e7e4de--color-surface-disabled--color-surface-quiet--color-surface-reference--color-ring-track--color-surface-logged--color-drawer-on-inverse-hover
- Stone 300
#c7c4bd - Stone 400
#8e8a83--color-text-disabled--color-border-strong--color-status-review-border
- Stone 500
#68645e--color-text-muted
- Stone 600
#55504b--color-text-secondary--color-status-draft-text--color-device-edge--color-device-hardware
- Stone 700
#3e3a36--color-text-on-logged
- Stone 800
#24211e--color-status-review-text
- Stone 900
#0e0c0anear-black: the ink--color-text-on-cover--color-text-primary--color-text-on-action--color-feedback-info-text--color-feedback-warning-text--color-device-bezel
Color
Color roles
220 tokens the interface actually uses, grouped by job. Each shows the scale step it lands on.
Edit · styles/tokens.css
Brand slots
What the semantic tokens reach for. Swap a slot and every role built on it follows.
Surfaces
What a screen is built on, from the canvas up, and how surfaces respond to the pointer.
Action and accent
The primary button, gold accents and the soft secondary.
Text
Primary for reading, secondary for support, muted for metadata. Inverse sits on navy.
Borders
Subtle and default are decorative; strong is the one controls use.
Focus, overlay and masks
Focus rings, the scrim behind dialogs, the mic's listening pulse, and the mask that fades scrolling content at an edge.
Feedback
Each tone is a halo dot (a mid-tone centre in a bright ring), drawn here with the real notice and tag. Border and text are the field error; surface is the catalogue's problem box.
- Info tag
Info
An example info notice.--color-feedback-info-dotBlue 500 · #497fc3--color-feedback-info-haloBlue 200 at 75%, softened with white--color-feedback-info-borderBlue 600 · #22609c--color-feedback-info-textStone 900 · #0e0c0a--color-feedback-info-surfaceBlue 100 · #eff3ff
- Success tag
Success
An example success notice.--color-feedback-success-dotGreen 600 · #389560--color-feedback-success-haloGreen 300 at 75%, softened with white--color-feedback-success-borderGreen 800 · #014b42--color-feedback-success-textGreen 800 · #014b42--color-feedback-success-surfaceGreen 100 · #f1fdd8
- Warning tag
Warning
An example warning notice.--color-feedback-warning-dotYellow 500 · #d3ad04--color-feedback-warning-haloYellow 400 at 75%, softened with white--color-feedback-warning-borderYellow 700 · #856300--color-feedback-warning-textStone 900 · #0e0c0a--color-feedback-warning-surfaceYellow 100 · #fdf8da
- Danger tag
Danger
An example danger notice.--color-feedback-danger-dotOrange 500 · #eb5520--color-feedback-danger-haloOrange 300 at 75%, softened with white--color-feedback-danger-borderOrange 500 · #eb5520--color-feedback-danger-textOrange 700 · #b30614--color-feedback-danger-surfaceOrange 100 · #fff0e8
Status badges
The draft, in-review and approved badges on the hub and in the catalogue.
- Draft
--color-status-draft-surfaceBlue 100 · #eff3ff--color-status-draft-textStone 600 · #55504b--color-status-draft-borderBlue 300 · #a6beef
- In review
--color-status-review-surfaceBlue 200 · #d4e0ff--color-status-review-textStone 800 · #24211e--color-status-review-borderStone 400 · #8e8a83
- Approved
--color-status-approved-surfaceBlue 800 · #002945--color-status-approved-textBlue 100 · #eff3ff--color-status-approved-borderBlue 800 · #002945
Device frame
The phone and tablet drawn around the canvas. Prototype chrome, not product.
Other
Color tokens no group above claims.
Type
Typefaces
Three faces, three jobs. The scale below is rendered in each of them so the roles can be compared directly.
Edit · styles/tokens.css
Kulim Park --font-display
Headings and UI labels. The primary face.
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
Libre Baskerville --font-serif
Pull quotes and editorial moments. Used sparingly.
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
Inter --font-body
Body copy and interface text.
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
- Your career doesn't pause
Type
Type roles
Every piece of text is one of eleven roles. Change a role here to try it on real components at phone size; nothing is saved until it goes into styles/tokens.css.
Edit · styles/tokens.css
| Role | Face | Size | Weight | Line height | Letters | Words |
|---|---|---|---|---|---|---|
| DisplayWelcome, privacy | ||||||
| TitleOne per screen | ||||||
| HeadingSections, card titles | ||||||
| SubheadingRows, links, reads | ||||||
| BodyReading text | ||||||
| Body smallSupporting text | ||||||
| LabelButtons, field labels | ||||||
| CaptionDates, hints, status | ||||||
| EyebrowCapitals above a heading | ||||||
| FigureNumbers shown as data | ||||||
| EditorialQuotes, welcome lines |
No changes. Pick a setting to try it on every component at once.
WelcomeSplit
ExecHQ
Somewhere to work on what comes next.
Welcome to ExecHQ
A private career advisor that takes you from “I’d like to be” to “I’m going to be”. It doesn’t just show you the way. It works for you to get you there.
StepHeader
Your direction
What would you like to move toward?
A role, a scope, an aspiration or a challenge. A precise title is optional.
NextStepCard
Your next step
Brief your manager before Thursday’s check-in
- Why this
- A one-page brief turns a check-in into a conversation about scope.
- Why now
- The check-in is on Thursday.
- Why you
- You’re in the Show the proof stage of your plan.
EntryLink
Today’s Briefing · 3 readsHow planning season decides who gets new workRelevant to your Q1 planning review.EntryLink
Pick up where you left offBrief for your manager check-inEdited 19 OctProfileHeader
SettingsGroup
Settings
Notice
Saved
Input
Button
Icons
Icons
One hand-drawn library of 76 icons: the standard set most platforms need, drawn before a screen asks for them. One line, three sizes. Every icon here is the real Icon component, so this is the set as it ships.
Edit · components/primitives/Icon
The line
- Hand-drawn on a 20 × 20 grid, scaled to size.
- One 1.5 line, round ends and corners, no fills except where a fill carries meaning (the dock's color switch).
- Stroked in
currentColor: an icon takes the color of what it sits in. - Never on its own: every icon has a visible label, or a hidden one that screen readers read. The icon itself is hidden from them.
- No icon libraries. The library below is drawn ahead of need; a new icon is added here first, drawn to match, before any screen uses it.
- Names say what an icon is, not what it is for (
trash, notdelete-draft), lowercase with hyphens, direction last (arrow-left).
Navigation
Getting around, opening and closing.
homeIn usemenuIn usecloseIn usechevronIn usechevron-leftLibrarychevron-upLibrarychevron-downLibraryarrow-rightLibraryarrow-leftLibraryarrow-upLibraryarrow-downLibraryexternal-linkLibrarymore-horizontalLibrarymore-verticalLibrarysearchLibraryfilterLibrary
Actions
Doing something to the user's own work.
plusLibraryminusLibrarycheckIn useeditIn usepencilIn usetrashIn usecopyLibraryshareLibrarydownloadIn useuploadLibraryrefreshLibraryundoLibrarysendIn useattachIn uselinkIn usebookmarkLibrarystarLibrarysettingsLibraryslidersLibraryeyeLibraryeye-offLibrarysign-inLibrarysign-outIn use
Communication
Messages, calls and alerts.
mailIn usemessageLibrarybellIn usephoneLibrarymicIn usevideoLibrary
People and places
Who and where.
personIn usepeopleLibraryperson-addLibrarybriefcaseLibrarybuildingLibrarypinLibraryglobeIn usecompassLibrary
Time and content
What a row or card is about.
calendarIn useclockLibrarydocumentIn usefolderLibraryimageLibrarybriefingIn usebookLibraryflagIn usetargetLibrarychart-barLibrarytrend-upLibrarylightbulbLibrary
Status
Feedback. Always with words beside it: an icon alone never carries the message.
infoLibrarywarningLibraryerrorLibrarysuccessLibraryhelpLibrary
Security
Privacy and access.
lockIn useunlockLibraryshieldLibrarykeyLibrary
Brand
LinkedIn, and ExecHQ's own marks: the advisor's spark and the open draft (the pencil, writing a line).
linkedinIn usesparkIn usedraftIn use
Sizes
Three sizes, and nothing between them.
- 16pxInside buttons and links, and beside small text.
- 20pxIn rows, cards, icon chips and navigation.
- 24pxStanding alone: the tab bar and header controls.
Color
Where an icon sits decides its color. In a button it takes the label's color.
- On its own
--color-icon-default - In an icon chip
--color-icon on --color-icon-surface - On navy
--color-text-inverse
Prototype only
The review dock and hub. Not part of the product, so not for dev.
mobiletabletwebhubcontrastresetsidebar
Layout
Spacing
A 4px base. Every gap, padding and margin in the prototype comes from this scale.
Edit · styles/tokens.css
Layout
Surfaces
What a screen is built on, from the canvas up. Text on each is the color that belongs there.
Edit · styles/tokens.css
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
- Your next role, planned
Layout
Radii
Corner rounding, from small controls up to the device frame.
Edit · styles/tokens.css
Layout
Shadows
Depth, tinted with the darkest navy so it reads as depth rather than dirt.
Edit · styles/tokens.css
Layout
Borders
Three widths, and the composed border shorthands the stylesheet uses most.
Edit · styles/tokens.css
Components
Form fields
Text fields, choice chips and toggles, in each of their states.
Edit · components/form
Input
Text field. The label is a required prop, so an unlabelled field cannot be built by accident. Errors are wired to the field with aria-describedby and never rely on color alone.
Default
Hover
Focus
With hint
A personal address, not a work one. Your employer never sees this account.
Filled
Required
Error
Error: Use a personal email address, not a work one.
Disabled
Empty state — placeholder
Multiline
A role, a scope, an aspiration or a challenge. A precise title is optional.
Statement
Statement — empty
Pill
Pill — filled
Pill — focus
Pill — error
Error: That doesn’t look like an email address. Check it and try again.
Label hidden
ChipGroup
Pressable chips for picking one, or up to a set number. Toggle buttons, so single and multiple choice look and behave the same and no arrow key ever chooses. At the limit, the other chips disable and the legend's note says why.
Single — empty
Single — chosen
Equal width
With a line under each
Multiple — at the limit
ToggleGroup
Single-select segmented control built on native radio inputs, so arrow-key navigation and screen-reader semantics come from the platform. Used by the viewport toggle.
Chips
Default
Second option selected
With a disabled option
Label hidden
Small