Card
Move the pointer here
The rim follows your pointer; the inside picks up a faint wash of gold.
Brand · v2.0
One gold ribbon, folded into an M. The logo and how to use it, the colour and type around it, and the tokens and components we build with.
01 · Logo
A single gold stroke rises over two peaks and dips into a V. Its outer feet are cut by an even gap and tuck beneath it as two wings. The wordmark is drawn, not typeset.
Every product is the same mark and the same lettering, with its name set straight after master in gold. No space, no other typeface.
For large moments only: app icons, social images, hero art. A band of light follows the outline, brightest where an edge faces the upper left and fading as the edge turns away. The mark must be at least 64px tall; below that, use the flat logo.
02 · Construction
Every edge is a 1:2 diagonal or a circular arc. With the stroke width W as the unit, the mark can be redrawn exactly.
| Stroke | W (the unit) |
| Height | 2.5W |
| Width | 4.51W |
| Diagonals | 1 : 2 (26.57°) |
| Peaks, valley, cut | radius ½W |
| Wing apex | radius 0.3W, concentric with the cut |
| Wing base | radius W, centred on the outer edge line, tangent to the baseline |
| Gap | ⅕W (0.3W in the small-size cut) |
Measured in x-heights of the wordmark: the mark is 1.3x tall and sits on the baseline, the t rises to 1.2x, and the gap between mark and word is one mark stroke W.
03 · Usage
Keep at least x, one x-height of the wordmark, free on every side. For the mark on its own, keep half its height.
| Version | Screen | |
|---|---|---|
| Horizontal lockup | 16px tall | 25mm wide |
| Mark | 24px wide | 8mm wide |
| Mark, small-size cut | 16px wide | 5mm wide |
| Dimensional mark | 64px tall | 40mm wide |
The files already carry the right proportions, colours and spacing. Use them as they are.
04 · Colour
Graphite carries the page, white supports it, and gold is kept for the mark, product names and the one thing that matters most. Click a swatch to copy it.
Defined in OKLCH: light steps lean yellow, dark steps lean warm, so deep golds never turn olive. Gold 400 on dark, Gold 600 for large gold on light, Gold 700 for gold text on light.
Graphite 900 #151517 is the brand ground. A touch warm, so gold sits on it more calmly than on pure black.
Light comes from the upper left. Each arm of the M carries a gradient that runs along the stroke, from champagne at the peak to soft amber in the V; the wings are deepest where they tuck under. The range is narrow on purpose.
#FBE9B3 → #E6AD63#F8E1A4 → #E6AD63#E4AE65 → #FAE7AF#E0A862 → #F8E0A1#F2D48B → #DB9848#EFCD7F → #DB9848#D9994A → #F0D085#D69347 → #EEC97BGradients belong to the mark. Interface elements use flat gold.
| Pair | Ratio | Grade | Use | |
|---|---|---|---|---|
| Aa | Graphite 900 on white | 18.24:1 | AA | Body text |
| Aa | Graphite 50 on Graphite 900 | 17.03:1 | AA | Body text |
| Aa | Gold 300 on Graphite 900 | 12.92:1 | AA | Product names, emphasis |
| Aa | Gold 400 on Graphite 900 | 11.15:1 | AA | Mark, buttons |
| Aa | Gold 700 on white | 4.75:1 | AA | Gold text on light |
| Aa | Gold 600 on white | 3.17:1 | Large / graphics | Product names on light (large) |
| Aa | Previous #ECBB40 on white | 1.79:1 | Fails | Retired |
05 · Typography
master, css and UI are custom lettering; no font reproduces them, so always use the logo files. Everything else is set in two families.
DISPLAY & UI · GEIST
Headings, interface and marketing copy. Precise, neutral geometry with careful numerals and punctuation, in tune with the wordmark. OFL.
CODE · JETBRAINS MONO
Code, tokens, specs and numbers. OFL.
Ten roles, each a size, line height, tracking and weight. Sizes scale fluidly between a 375px and a 1440px screen. Geist has no optical sizes, so tracking tightens as type grows, the way display cuts do. Use the role, never a raw size.
06 · Design tokens
Our sites are built on CSS custom properties. Palette tokens never change; semantic tokens point at them and switch between dark (the default) and light. Get them as CSS, JSON or a Master CSS config.
| Token | Dark | Light | Use |
|---|---|---|---|
| --bg | graphite-950 | #FBFBFB | Page background |
| --surface | graphite-900 | #FFFFFF | Cards, panels |
| --surface-2 | graphite-800 | graphite-100 | Raised controls, code |
| --line | white 8% | graphite-900 9% | Hairlines, borders |
| --text | graphite-50 | graphite-900 | Primary text |
| --text-2 | graphite-300 | graphite-600 | Secondary text |
| --text-3 | graphite-400 | graphite-500 | Captions, meta |
| --accent | gold-400 | gold-400 | Primary buttons, highlights |
| --accent-text | gold-300 | gold-700 | Gold text |
| --focus | gold-300 | gold-600 | Focus ring |
| --space-1 | 4px | |
| --space-2 | 8px | |
| --space-3 | 12px | |
| --space-4 | 16px | |
| --space-6 | 24px | |
| --space-8 | 32px | |
| --space-12 | 48px | |
| --space-16 | 64px | |
| --space-24 | 96px | |
| --space-32 | 128px | |
| --space-40 | 160px |
| --radius-xs | 6px | |
| --radius-sm | 8px | |
| --radius-md | 12px | |
| --radius-lg | 16px | |
| --radius-xl | 22px | |
| --radius-2xl | 28px | |
| --radius-3xl | 36px | |
| --radius-full | 999px |
Surfaces use continuous corners (corner-shape: superellipse(1.4)) where the browser can draw them, so curves flow into straight edges without a visible joint.
| --shadow-1 | Resting surfaces | |
| --shadow-2 | Hovered cards, menus | |
| --shadow-3 | Dialogs, hero art | |
| --hairline | 1px, or one device pixel on 2x screens |
| --ease-out cubic-bezier(.16, 1, .3, 1) Entrances, hovers | |
| --ease-in-out cubic-bezier(.65, 0, .35, 1) Moves on screen | |
| --ease-spring linear(…), 44 samples Presses, toggles, things that land | |
| --dur-fast 150ms | Press, toggle |
| --dur 250ms | Hover, colour |
| --dur-slow 500ms | Glow, reveal |
| --dur-slower 900ms | Hero entrance |
| --dur-spring 700ms | One spring, start to rest |
The spring is a real damped spring (damping ratio 0.72), sampled into linear(). It overshoots by about 4% and settles. Motion turns off for people who ask for reduced motion.
:root {
/* dark: the default */
--bg: var(--graphite-950);
--surface: var(--graphite-900);
--surface-2: var(--graphite-800);
--fill: rgb(255 255 255 / .06);
--fill-strong: rgb(255 255 255 / .1);
--line: rgb(255 255 255 / .09);
--line-strong: rgb(255 255 255 / .16);
--highlight: rgb(255 255 255 / .07);
--text: var(--graphite-50);
--text-2: var(--graphite-300);
--text-3: var(--graphite-400);
--accent: var(--gold-400);
--accent-text: var(--gold-300);
--accent-ink: var(--graphite-900);
--accent-glow: rgb(238 197 107 / .14);
--focus: var(--gold-300);
--success: #7FD3A6;
--danger: #FF8A7A;
--glass: rgb(13 13 14 / .72);
}
@media (prefers-color-scheme: light) {
:root {
--bg: #FBFBFC; --surface: #FFFFFF; --surface-2: var(--graphite-100);
--fill: rgb(21 21 23 / .045); --fill-strong: rgb(21 21 23 / .08);
--line: rgb(21 21 23 / .1); --line-strong: rgb(21 21 23 / .18); --highlight: rgb(255 255 255 / .9);
--text: var(--graphite-900); --text-2: var(--graphite-600); --text-3: var(--graphite-500);
--accent-text: var(--gold-700); --accent-glow: rgb(193 132 53 / .1); --focus: var(--gold-600);
--success: #1F7A4D; --danger: #C2412D; --glass: rgb(251 251 252 / .74);
color-scheme: light;
}
}// Master brand palette for Master CSS v2 (`master.css.ts`).
import type { Config } from '@master/css'
export default {
variables: {
gold: {
50: '#FEFAED',
100: '#FCF2D5',
200: '#FAE8B3',
300: '#F5D68B',
400: '#EEC56B',
500: '#DFA54B',
600: '#C18435',
700: '#A06625',
800: '#804D19',
900: '#613811',
950: '#3B2008',
},
graphite: {
50: '#F7F7F8',
100: '#EDEDEF',
200: '#D9D9DD',
300: '#B4B4BA',
400: '#86868D',
500: '#5C5C63',
600: '#3A3A3F',
700: '#2A2A2E',
800: '#1E1E21',
900: '#151517',
950: '#0D0D0E',
},
}
} as Config
Full files: master.css · tokens.json · master-brand.css · master.css.ts
07 · Components
The pieces this site is made of. They take colour, radius and motion from the tokens, follow the theme and respect reduced motion.
Primary is gold and appears once per view. Secondary and ghost for everything else. Press one.
<a class="btn btn-primary">Get started</a> <a class="btn btn-secondary">Documentation</a> <a class="btn btn-ghost btn-sm">Changelog</a>
A chevron that grows into an arrow.
<a>Learn more <svg class="arrow">…</svg></a>
Status in a word. Gold with a pulse marks something on the way.
<span class="badge badge-gold badge-dot">…</span>
With card-glow, the border lights up where the pointer is, the same edge light as the mark.
Card
The rim follows your pointer; the inside picks up a faint wash of gold.
<article class="card card-glow">…</article> // set --px / --py on pointermove; see /assets/brand.js
Underlines warm to gold on hover.
Read the documentation, run npm i @master/css or press ⌘ K.
<a class="link">…</a> <code>…</code> <kbd>K</kbd>
Glass, springs in, confirms one thing.
<div class="toast" role="status">…</div>
08 · Brand kit
Logos in every colour and size, app icons, favicons, social images and tokens. Every file is generated from one source, so they always match this page.
SVG and PNG logos, icons, social images, tokens · ZIP · 2.6 MB
| logo/mark/ | The mark: on dark, on light, gold, black, white, small-size cut and dimensional. |
| logo/master/ | Master: horizontal, stacked and wordmark, each on dark, on light, black and white. dimensional/ for large use. |
| logo/master-css/ | Master CSS, same set. |
| logo/master-ui/ | Master UI, same set. |
| logo/png/ | Horizontal lockups as PNG, 1024px dimensional marks. |
| icon/ | App icons (dark, light, gold), favicon.svg that follows light and dark, favicon.ico, PNG sizes. |
| social/png/ | Open Graph 1200×630 and GitHub social previews 1280×640. |
| tokens/ | tokens.json, CSS variables and a Master CSS config. |


