Changelog
- 1.0.0, 22 October 2026: first release
kits / brand-starter
A fill-in brand guide, contrast-checked design tokens and a logo usage sheet to make a brand consistent from day one.
MIT License
Copyright (c) 2026 Snowkit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.Version 1.0.0
A brand is the set of decisions that make your business look and sound like itself every time: what you say, how you say it, which logo goes where, which colours and fonts you use. This kit gives a small team a fill-in brand guide, ready-to-use design tokens with checked contrast, a logo usage sheet you can print or share, and the checklists and size tables you need when you export everything.
You don't need a designer to use it, although a designer will get more out of it.
brand-guide-template.md and fill in section 1, purpose and positioning. Everything else follows from it.tokens/ folder into your project and link colors.css and typography.css before your own stylesheet.tokens/README.md.logo-usage.html in a browser, replace the placeholder mark with your logo, and save it as a PDF for your team.brand-checklist.md before you announce the brand, using social-sizes.md for exports.If you are still choosing a name, start with naming-worksheet.md.
| File | What it is |
|---|---|
README.md | This file |
brand-guide-template.md | A complete fill-in brand guide: positioning, voice and tone, logo, colour, type, imagery, layout, accessibility, applications, contacts and approvals |
naming-worksheet.md | A step-by-step worksheet to generate, score and check names |
logo-usage.md | Logo rules in plain text: versions, clear space, minimum size, colour versions, backgrounds, don'ts, formats |
logo-usage.html | A standalone one-page logo do and don't sheet with a placeholder logo, built on the tokens and ready to print |
tokens/README.md | How the tokens work, dark mode, measured contrast ratios, and how to use them with Tailwind CSS and design tools |
tokens/colors.css | Colour custom properties: neutral scale, brand colours, semantic tokens, light and dark themes |
tokens/typography.css | Font stacks, fluid type scale, line heights, weights, spacing, radius and shadows |
tokens/tokens.json | The same tokens in the Design Tokens Community Group format |
tokens/tailwind-theme.js | A Tailwind CSS theme mapped to the custom properties |
social-sizes.md | Profile, banner, share image, favicon and app icon sizes, with HTML and manifest snippets |
brand-checklist.md | A launch checklist: decisions, legal, domains, logo exports, website, email, social, templates and handover |
CHANGELOG.md | Version history |
LICENSE.txt | Licence |
The example palette passes WCAG AA for the pairs listed in tokens/README.md. Once you change a colour, those numbers no longer apply, so check again. Platform image sizes change often; confirm them before a launch. The naming worksheet and checklist mention trademarks, but they are not legal advice, and a professional search is the only reliable check.
MIT License. See LICENSE.txt.
Use this when you launch a new brand or refresh an old one. It lists what to decide, what to export and where the brand has to show up before you announce it. Strike out items that don't apply so you know you looked.
Brand: ______________________ Owner: ______________ Launch date: ____________
---
naming-worksheet.md).brand-guide-template.md, section 1).Export every version in every colour from the master. Suggested naming: [brand]-logo-[version]-[colour].[ext].
| Version | Full colour | Reversed | One colour dark | One colour light |
|---|---|---|---|---|
| Primary | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF |
| Stacked | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF |
| Symbol | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF | [ ] SVG [ ] PNG [ ] PDF |
logo-usage.html updated with the real logo and sizes, and saved as PDF for sharing.tokens/colors.css and tokens/tokens.json.tokens/typography.css, with system fallbacks kept.font-display: swap.favicon.ico, favicon.svg, apple-touch-icon.png, manifest icons at 192 and 512 (see social-sizes.md).theme_color in the manifest set to the brand colour.logos/, fonts/, colours/, templates/, photography/, guide/, with a short read-me.Version [1.0] - [Month year] - Owner: [Name, role]
This guide explains how [Brand name] looks, sounds and behaves, so anyone making something for us can get it right without asking. Fill in every [bracketed field]. Delete any section that truly doesn't apply, rather than leaving it empty. A short guide people read beats a long one nobody opens.
How to fill this in: work top to bottom. Sections 1 and 2 decide everything after them, so don't skip to colours. Where you're unsure, write your best answer and mark it "draft". Review the drafts together once the whole guide exists.
---
[Brand name] helps [who] [do what] so they can [outcome].
Example: Example Co helps independent bakeries take online orders so they can sell out before noon.
[Two or three sentences on the problem you saw and why you care about it. Write it so a new hire could repeat it.]
| Audience | What they need from us | What they worry about |
|---|---|---|
| [Primary audience] | [Need] | [Worry] |
| [Secondary audience] | [Need] | [Worry] |
| [Who we are not for] | [Why we say no] | - |
For [target audience] who [need or problem], [Brand name] is the [category] that [key benefit]. Unlike [main alternative], we [main difference].
The facts that back up the positioning. Only list things you can show.
Pick three to five. For each, say what it means in practice, so it can guide a real decision.
| Value | What it means | What it rules out |
|---|---|---|
| [Value, e.g. Plain] | [We explain things without jargon] | [Buzzwords, vague claims] |
| [Value] | [Meaning] | [What we won't do] |
| [Value] | [Meaning] | [What we won't do] |
If [Brand name] were a person, they would be:
---
Voice is who we are, and it stays the same everywhere. Tone is how that voice adjusts to the moment: lighter in a launch post, calmer in an outage notice.
| Situation | Tone | Example line |
|---|---|---|
| Homepage and ads | [e.g. Confident, direct] | [Example line] |
| Onboarding and help docs | [e.g. Patient, step by step] | [Example line] |
| Error messages | [e.g. Calm, specific, no blame] | [Example line] |
| Outage or incident | [e.g. Factual, frequent, no jokes] | [Example line] |
| Social media | [e.g. Relaxed, human] | [Example line] |
| Billing and legal | [e.g. Clear, precise] | [Example line] |
| Do | Don't |
|---|---|
| "Your order is confirmed. We'll email you when it ships." | "Woohoo! Your awesome order is officially confirmed!!!" |
| "We couldn't save your changes. Check your connection and try again." | "Oops! Something went wrong." |
| "Most teams finish setup in about an hour." | "Setup takes seconds!" (unless it truly does) |
| "Cancel any time from Settings > Billing." | "Contact us to discuss your cancellation options." |
| "This feature is in beta. Expect some rough edges." | "Revolutionary next-generation experience." |
| "You" and "we" | "The user" and "the company" |
| Short sentences. One idea each. | Long sentences that try to cover every case at once, with several clauses and qualifiers. |
Replace these with lines in your own voice. Keep at least five pairs.
| We say | We don't say | Why |
|---|---|---|
| [e.g. customers] | [e.g. users] | [We sell to people, not accounts] |
| [Term] | [Term] | [Reason] |
| [Term] | [Term] | [Reason] |
---
Full rules and a printable sheet are in logo-usage.md and logo-usage.html. Summarise the essentials here.
| Version | When to use | File names |
|---|---|---|
| Primary (horizontal) | Default for websites, documents, most uses | [brand-logo-primary.svg] |
| Stacked | Square or narrow spaces | [brand-logo-stacked.svg] |
| Symbol only | Favicons, app icons, profile images, small spaces where the name appears nearby | [brand-symbol.svg] |
| Wordmark only | Where the symbol would be too small to read | [brand-wordmark.svg] |
---
The values below should match tokens/colors.css. If they ever disagree, the token file wins, because that is what ships.
| Name | Role | HEX | RGB | CMYK (print) | Pantone (if used) |
|---|---|---|---|---|---|
| [Primary] | Main brand colour, primary buttons, links | [#2453d6] | [36, 83, 214] | [Get from your printer] | [Code] |
| [Secondary] | Supporting colour, highlights | [#0f766e] | [15, 118, 110] | [ ] | [ ] |
| [Accent] | Small amounts only: badges, key callouts | [#c2410c] | [194, 65, 12] | [ ] | [ ] |
Convert to CMYK and Pantone with your printer or designer, using a proof. Automatic conversions often shift colours, especially bright blues and greens.
| Name | HEX | Typical use |
|---|---|---|
| [Neutral 900] | [#16191e] | Body text |
| [Neutral 600] | [#4f5662] | Secondary text |
| [Neutral 300] | [#c3c9d2] | Dividers |
| [Neutral 50] | [#f7f8fa] | Alternate backgrounds |
| [White] | [#ffffff] | Main background |
A rough guide to how much of each colour appears in a typical layout: [e.g. 60% neutrals and white, 25% primary, 10% secondary, 5% accent].
| Purpose | Light theme | Dark theme |
|---|---|---|
| Success | [#15803d] | [#4ade80] |
| Warning | [#b45309] | [#fbbf24] |
| Danger | [#b91c1c] | [#f87171] |
| Info | [#0369a1] | [#38bdf8] |
Never use colour alone to carry meaning. Pair it with an icon, a word or both.
List only pairs that meet WCAG AA (4.5:1 for normal text). See tokens/README.md for the measured ratios of the example palette.
| Text | Background | Ratio | Use |
|---|---|---|---|
| [Neutral 900] | [White] | [17.62:1] | Body text |
| [White] | [Primary] | [6.40:1] | Primary buttons |
| [ ] | [ ] | [ ] | [ ] |
---
| Role | Typeface | Weights | Fallback | Licence |
|---|---|---|---|---|
| Headings | [Typeface] | [600, 700] | [System sans-serif] | [Licence and where it is stored] |
| Body | [Typeface] | [400, 500] | [System sans-serif] | [Licence] |
| Code or data | [Typeface] | [400] | [System monospace] | [Licence] |
| Office documents | [e.g. Arial or Calibri, if brand fonts aren't installed] | - | - | - |
Check each font licence covers web, app, print and email use, and how many people may install it.
| Style | Size (mobile to desktop) | Weight | Line height | Use |
|---|---|---|---|---|
| Display | [44 to 68 px] | [700] | [1.15] | Hero headlines only |
| H1 | [36 to 52 px] | [700] | [1.15] | Page titles |
| H2 | [30 to 40 px] | [700] | [1.15] | Section titles |
| H3 | [24 to 30 px] | [600] | [1.3] | Sub-sections |
| Body | [16 to 17 px] | [400] | [1.5] | Paragraphs |
| Small | [14 to 15 px] | [400] | [1.5] | Captions, labels |
The matching CSS is in tokens/typography.css.
---
---
tokens/typography.css.| Component | Rule |
|---|---|
| Primary button | [Primary fill, white text, one per view] |
| Secondary button | [Outline in border-strong, text colour] |
| Links | [Link colour, underlined in body text] |
| Form fields | [Border-strong outline, visible label above, error text below] |
| Cards | [Surface-alt background, border, radius-lg] |
---
Our minimum standard is [WCAG 2.2 level AA]. In practice:
prefers-reduced-motion. Nothing flashes more than three times a second.Accessibility contact: [Name, email].
---
Show one approved example of each and link to the master file.
| Item | Template location | Notes |
|---|---|---|
| Website | [Link] | [Uses tokens from tokens/] |
| Email signature | [Link] | [Logo as hosted PNG, no images-only signatures] |
| Slide deck | [Link] | [Title, section, content and closing layouts] |
| Letterhead and documents | [Link] | [Office fonts listed in section 5] |
| Invoice | [Link] | [Legal company name and registration details] |
| Social profile and cover images | [Link] | [See social-sizes.md] |
| Business cards | [Link] | [Print specs: size, bleed, stock] |
| Merchandise | [Link] | [Approved colours on fabric] |
| Signage | [Link] | [Minimum viewing sizes] |
---
| Area | Owner | Contact |
|---|---|---|
| Brand guide overall | [Name, role] | [email] |
| Logo and visual identity | [Name] | [email] |
| Copy and voice | [Name] | [email] |
| Website | [Name] | [email] |
| Social channels | [Name] | [email] |
| Type of work | Needs approval? | Approver | Turnaround |
|---|---|---|---|
| Uses approved templates unchanged | No | - | - |
| New marketing asset using the guide | [Yes / No] | [Name] | [2 working days] |
| Logo used by a partner or press | Yes | [Name] | [2 working days] |
| Anything that changes the logo, colours or tagline | Yes | [Name, plus leadership] | [Agreed case by case] |
| Version | Date | Change | By |
|---|---|---|---|
| 1.0 | [Date] | First version | [Name] |
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Logo usage - [Brand name]</title>
<style>
:root {
--neutral-0: #ffffff;
--neutral-50: #f7f8fa;
--neutral-100: #eef0f3;
--neutral-200: #dde1e7;
--neutral-300: #c3c9d2;
--neutral-400: #868e9b;
--neutral-500: #6b7380;
--neutral-600: #4f5662;
--neutral-800: #262a31;
--neutral-900: #16191e;
--neutral-950: #0c0e11;
--brand-primary-300: #8aaaff;
--brand-primary-500: #2453d6;
--brand-primary-700: #1b3fa8;
--brand-secondary-500: #0f766e;
--brand-accent-500: #c2410c;
--green-600: #15803d;
--red-600: #b91c1c;
--color-surface: var(--neutral-0);
--color-surface-alt: var(--neutral-50);
--color-surface-sunken: var(--neutral-100);
--color-text: var(--neutral-900);
--color-text-muted: var(--neutral-600);
--color-border: var(--neutral-300);
--color-border-strong: var(--neutral-400);
--color-primary: var(--brand-primary-500);
--color-success: var(--green-600);
--color-danger: var(--red-600);
--font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-12: 3rem;
--space-16: 4rem;
--logo-mark: var(--brand-primary-500);
--logo-mark-in: var(--neutral-0);
--logo-word: var(--neutral-900);
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--color-surface: var(--neutral-900);
--color-surface-alt: var(--neutral-800);
--color-surface-sunken: var(--neutral-950);
--color-text: var(--neutral-50);
--color-text-muted: var(--neutral-300);
--color-border: var(--neutral-600);
--color-border-strong: var(--neutral-500);
--color-success: #4ade80;
--color-danger: #f87171;
color-scheme: dark;
}
}
:root[data-theme="dark"] {
--color-surface: var(--neutral-900);
--color-surface-alt: var(--neutral-800);
--color-surface-sunken: var(--neutral-950);
--color-text: var(--neutral-50);
--color-text-muted: var(--neutral-300);
--color-border: var(--neutral-600);
--color-border-strong: var(--neutral-500);
--color-success: #4ade80;
--color-danger: #f87171;
color-scheme: dark;
}
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
font-family: var(--font-sans);
font-size: 1rem;
line-height: 1.5;
color: var(--color-text);
background: var(--color-surface);
}
.page {
max-width: 72rem;
margin: 0 auto;
padding: var(--space-12) var(--space-4) var(--space-16);
}
header.top {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-end;
gap: var(--space-4);
padding-bottom: var(--space-8);
border-bottom: 1px solid var(--color-border);
}
h1 {
margin: 0;
font-size: clamp(2rem, 1.6rem + 2vw, 3rem);
line-height: 1.1;
letter-spacing: -0.02em;
}
h2 {
margin: 0 0 var(--space-2);
font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
line-height: 1.2;
letter-spacing: -0.01em;
}
h3 {
margin: var(--space-3) 0 0;
font-size: 1rem;
}
p { margin: 0 0 var(--space-4); max-width: 66ch; }
.meta { color: var(--color-text-muted); font-size: 0.875rem; margin: 0; }
.lead { color: var(--color-text-muted); font-size: 1.125rem; margin-top: var(--space-3); }
section {
padding: var(--space-12) 0;
border-bottom: 1px solid var(--color-border);
}
section:last-of-type { border-bottom: 0; }
.eyebrow {
display: inline-block;
margin-bottom: var(--space-2);
font-size: 0.75rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-text-muted);
}
.grid {
display: grid;
gap: var(--space-6);
margin-top: var(--space-6);
}
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.card {
margin: 0;
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
overflow: hidden;
background: var(--color-surface);
}
.card .stage {
display: flex;
align-items: center;
justify-content: center;
min-height: 11rem;
padding: var(--space-6);
background: var(--neutral-0);
overflow: hidden;
}
.card .caption {
padding: var(--space-3) var(--space-4) var(--space-4);
border-top: 1px solid var(--color-border);
}
.card .caption p {
margin: var(--space-2) 0 0;
font-size: 0.875rem;
color: var(--color-text-muted);
}
.logo { display: block; width: 12.5rem; height: auto; overflow: visible; }
.logo .mk { fill: var(--logo-mark); }
.logo .mk-in { fill: var(--logo-mark-in); }
.logo .wm {
fill: var(--logo-word);
font-family: var(--font-sans);
font-size: 22px;
font-weight: 700;
letter-spacing: -0.01em;
}
.symbol { display: block; width: 3rem; height: auto; }
.symbol .mk { fill: var(--logo-mark); }
.symbol .mk-in { fill: var(--logo-mark-in); }
.clear-wrap {
display: flex;
justify-content: center;
padding: var(--space-8) var(--space-4);
margin-top: var(--space-6);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--neutral-0);
}
.clear-zone {
position: relative;
padding: 2.5rem;
border: 2px dashed var(--brand-primary-300);
background: repeating-linear-gradient(45deg, rgba(36, 83, 214, 0.06) 0, rgba(36, 83, 214, 0.06) 6px, transparent 6px, transparent 12px);
}
.clear-zone .logo {
outline: 1px solid var(--brand-primary-500);
background: var(--neutral-0);
}
.x {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
font-size: 0.8125rem;
font-weight: 700;
font-style: italic;
color: var(--brand-primary-700);
}
.x-top { top: 0; left: 50%; transform: translateX(-50%); }
.x-bottom { bottom: 0; left: 50%; transform: translateX(-50%); }
.x-left { left: 0; top: 50%; transform: translateY(-50%); }
.x-right { right: 0; top: 50%; transform: translateY(-50%); }
.sizes {
display: flex;
flex-wrap: wrap;
align-items: flex-end;
gap: var(--space-8);
margin-top: var(--space-6);
padding: var(--space-8);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
background: var(--neutral-0);
}
.size { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }
.size span { font-size: 0.8125rem; color: var(--neutral-600); }
.size-200 .logo { width: 12.5rem; }
.size-120 .logo { width: 7.5rem; }
.size-min .logo { width: 6.25rem; }
.size-48 .symbol { width: 3rem; }
.size-24 .symbol { width: 1.5rem; }
.size-16 .symbol { width: 1rem; }
.v-full { --logo-mark: var(--brand-primary-500); --logo-mark-in: var(--neutral-0); --logo-word: var(--neutral-900); }
.v-reversed { --logo-mark: var(--neutral-0); --logo-mark-in: var(--brand-primary-500); --logo-word: var(--neutral-0); }
.v-dark { --logo-mark: var(--neutral-900); --logo-mark-in: var(--neutral-0); --logo-word: var(--neutral-900); }
.v-light { --logo-mark: var(--neutral-0); --logo-mark-in: var(--neutral-900); --logo-word: var(--neutral-0); }
.card .stage.bg-white { background: var(--neutral-0); }
.card .stage.bg-light { background: var(--neutral-100); }
.card .stage.bg-primary { background: var(--brand-primary-500); }
.card .stage.bg-dark { background: var(--neutral-900); }
.card .stage.bg-photo-dark {
background:
radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.08), transparent 40%),
linear-gradient(135deg, #1f2a38 0%, #12161c 100%);
}
.card .stage.bg-mid { background: #7b8494; }
.tag {
display: inline-flex;
align-items: center;
gap: 0.375rem;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.tag-do { color: var(--color-success); }
.tag-dont { color: var(--color-danger); }
.tag::before {
content: "";
display: inline-block;
width: 1rem;
height: 1rem;
border-radius: 50%;
background-color: currentColor;
background-repeat: no-repeat;
background-position: center;
}
.tag-do::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.5 8.5l2.2 2.2 4.8-5' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.tag-dont::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M5.2 5.2l5.6 5.6M10.8 5.2l-5.6 5.6' fill='none' stroke='white' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
.dont .stage { position: relative; }
.d-stretch .logo { transform: scale(1.35, 0.7); }
.d-recolour { --logo-mark: #c026d3; --logo-mark-in: #facc15; --logo-word: #65a30d; }
.d-rotate .logo { transform: rotate(-14deg); }
.d-effects .logo {
filter: drop-shadow(3px 4px 0 rgba(12, 14, 17, 0.35)) drop-shadow(0 0 6px rgba(194, 65, 12, 0.7));
}
.card .stage.d-busy {
background:
repeating-linear-gradient(60deg, rgba(194, 65, 12, 0.55) 0 10px, transparent 10px 22px),
repeating-linear-gradient(-30deg, rgba(15, 118, 110, 0.55) 0 8px, transparent 8px 18px),
repeating-radial-gradient(circle at 30% 40%, #f5d0a9 0 6px, #8aaaff 6px 12px);
}
.d-outline .logo .mk,
.d-outline .logo .mk-in,
.d-outline .logo .wm {
fill: none;
stroke: var(--brand-primary-500);
stroke-width: 1.5;
}
.d-contrast { --logo-mark: #c9d6f5; --logo-mark-in: var(--neutral-0); --logo-word: var(--neutral-200); }
.d-crowd {
flex-direction: column;
gap: 0;
}
.d-crowd .crowd-text {
margin: 0;
font-size: 1.375rem;
font-weight: 800;
line-height: 1;
color: var(--neutral-900);
text-transform: uppercase;
}
.d-crowd .logo { width: 11rem; }
.rules {
margin: var(--space-6) 0 0;
padding: 0;
list-style: none;
display: grid;
gap: var(--space-3);
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
.rules li {
max-width: none;
padding: var(--space-4);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: var(--color-surface-alt);
font-size: 0.9375rem;
}
.rules strong { display: block; margin-bottom: 0.25rem; }
footer {
padding-top: var(--space-8);
color: var(--color-text-muted);
font-size: 0.875rem;
}
.fill { background: var(--color-surface-sunken); border-radius: 0.25rem; padding: 0 0.25rem; }
.sizes .fill { background: var(--neutral-100); color: var(--neutral-900); }
@media print {
body { background: #ffffff; color: #000000; }
.page { padding: 0; max-width: none; }
section { break-inside: avoid; padding: var(--space-8) 0; }
.card { break-inside: avoid; }
}
</style>
</head>
<body>
<div class="page">
<header class="top">
<div>
<span class="eyebrow">Brand guidelines</span>
<h1>Logo usage</h1>
<p class="lead">How to use the <span class="fill">[Brand name]</span> logo so it reads clearly everywhere it appears.</p>
</div>
<p class="meta">Version <span class="fill">[1.0]</span> · <span class="fill">[Month year]</span><br>Questions: <span class="fill">[[email protected]]</span></p>
</header>
<section aria-labelledby="clear-space">
<span class="eyebrow">01</span>
<h2 id="clear-space">Clear space</h2>
<p>Keep a margin around the logo that is free of text, images and edges. The margin equals <strong>x</strong>, the height of the symbol. More space is always fine. Less is not.</p>
<div class="clear-wrap">
<div class="clear-zone">
<span class="x x-top">x</span>
<span class="x x-bottom">x</span>
<span class="x x-left">x</span>
<span class="x x-right">x</span>
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="[Your logo] placeholder">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
</div>
</section>
<section aria-labelledby="min-size">
<span class="eyebrow">02</span>
<h2 id="min-size">Minimum size</h2>
<p>Below these sizes the name stops being readable. Use the symbol on its own when space is tighter than the primary logo's minimum, as long as the brand name appears nearby.</p>
<div class="sizes">
<div class="size size-200">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="[Your logo] at 200 pixels wide">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
<span>Preferred: 200 px wide</span>
</div>
<div class="size size-120">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="[Your logo] at 120 pixels wide">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
<span>Small: 120 px</span>
</div>
<div class="size size-min">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="[Your logo] at minimum size">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
<span>Minimum: <span class="fill">[100 px / 25 mm]</span></span>
</div>
<div class="size size-48">
<svg class="symbol v-full" viewBox="0 0 48 48" role="img" aria-label="Symbol at 48 pixels">
<rect class="mk" x="4" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="24" cy="24" r="8"/>
</svg>
<span>Symbol: 48 px</span>
</div>
<div class="size size-24">
<svg class="symbol v-full" viewBox="0 0 48 48" role="img" aria-label="Symbol at 24 pixels">
<rect class="mk" x="4" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="24" cy="24" r="8"/>
</svg>
<span>24 px</span>
</div>
<div class="size size-16">
<svg class="symbol v-full" viewBox="0 0 48 48" role="img" aria-label="Symbol at 16 pixels">
<rect class="mk" x="4" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="24" cy="24" r="8"/>
</svg>
<span>Minimum: <span class="fill">[16 px]</span></span>
</div>
</div>
</section>
<section aria-labelledby="colour-versions">
<span class="eyebrow">03</span>
<h2 id="colour-versions">Colour versions</h2>
<p>Use full colour wherever you can. Switch to a one-colour version only when the background or the printing method calls for it.</p>
<div class="grid grid-4">
<figure class="card">
<div class="stage bg-white">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Full colour logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-do">Default</span>
<h3>Full colour</h3>
<p>On white and light neutral backgrounds.</p>
</figcaption>
</figure>
<figure class="card">
<div class="stage bg-primary">
<svg class="logo v-reversed" viewBox="0 0 200 48" role="img" aria-label="Reversed logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-do">Approved</span>
<h3>Reversed</h3>
<p>On the primary brand colour.</p>
</figcaption>
</figure>
<figure class="card">
<div class="stage bg-light">
<svg class="logo v-dark" viewBox="0 0 200 48" role="img" aria-label="One colour dark logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-do">Approved</span>
<h3>One colour, dark</h3>
<p>Single-colour print, stamps, engraving and fax-quality documents.</p>
</figcaption>
</figure>
<figure class="card">
<div class="stage bg-dark">
<svg class="logo v-light" viewBox="0 0 200 48" role="img" aria-label="One colour light logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-do">Approved</span>
<h3>One colour, light</h3>
<p>On dark surfaces, dark mode and dark photography.</p>
</figcaption>
</figure>
</div>
</section>
<section aria-labelledby="backgrounds">
<span class="eyebrow">04</span>
<h2 id="backgrounds">Backgrounds</h2>
<p>The logo needs a calm, even area behind it with strong contrast. Pick the version that contrasts most with the background. If none does, change the background, not the logo.</p>
<div class="grid grid-4">
<figure class="card">
<div class="stage bg-light">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Logo on light neutral">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-do">Do</span>
<h3>Light neutral</h3>
<p>Full colour on white or neutral 100.</p>
</figcaption>
</figure>
<figure class="card">
<div class="stage bg-photo-dark">
<svg class="logo v-light" viewBox="0 0 200 48" role="img" aria-label="Logo on dark photo area">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-do">Do</span>
<h3>Dark, even photo area</h3>
<p>Light version over a dark, low-detail part of the image.</p>
</figcaption>
</figure>
<figure class="card">
<div class="stage bg-mid">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Logo on mid grey">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Avoid</span>
<h3>Mid-tone colour</h3>
<p>Neither the dark nor the light version contrasts enough.</p>
</figcaption>
</figure>
<figure class="card">
<div class="stage bg-primary">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Full colour logo on primary colour">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Avoid</span>
<h3>Full colour on brand colour</h3>
<p>The symbol disappears. Use the reversed version.</p>
</figcaption>
</figure>
</div>
</section>
<section aria-labelledby="donts">
<span class="eyebrow">05</span>
<h2 id="donts">Don't</h2>
<p>Always use the master files. Never redraw, edit or decorate the logo. If a layout seems to need one of these changes, ask <span class="fill">[[email protected]]</span> for an alternative.</p>
<div class="grid grid-4">
<figure class="card dont">
<div class="stage d-stretch">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Incorrect: stretched logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Stretch or squash</h3>
<p>Scale in proportion only. Hold Shift when resizing.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-recolour">
<svg class="logo" viewBox="0 0 200 48" role="img" aria-label="Incorrect: recoloured logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Recolour</h3>
<p>Use only the four approved colour versions.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-rotate">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Incorrect: rotated logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Rotate or tilt</h3>
<p>The logo always sits level.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-effects">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Incorrect: logo with effects">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Add effects</h3>
<p>No shadows, glows, bevels, gradients or textures.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-busy">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Incorrect: logo on busy background">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Busy background</h3>
<p>Patterns and detailed photos fight the logo.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-outline">
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Incorrect: outlined logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Outline</h3>
<p>Never convert the logo to strokes or a keyline version.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-contrast">
<svg class="logo" viewBox="0 0 200 48" role="img" aria-label="Incorrect: low contrast logo">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Fade or tint</h3>
<p>No transparency or pale tints that lower contrast.</p>
</figcaption>
</figure>
<figure class="card dont">
<div class="stage d-crowd">
<p class="crowd-text">Big sale</p>
<svg class="logo v-full" viewBox="0 0 200 48" role="img" aria-label="Incorrect: logo crowded by text">
<rect class="mk" x="0" y="4" width="40" height="40" rx="10"/>
<circle class="mk-in" cx="20" cy="24" r="8"/>
<text class="wm" x="52" y="32">[Your logo]</text>
</svg>
<p class="crowd-text">Today only</p>
</div>
<figcaption class="caption">
<span class="tag tag-dont">Don't</span>
<h3>Crowd it</h3>
<p>Respect the clear space from section 01.</p>
</figcaption>
</figure>
</div>
</section>
<section aria-labelledby="files">
<span class="eyebrow">06</span>
<h2 id="files">Files and formats</h2>
<ul class="rules">
<li><strong>SVG</strong>Websites, apps and anything that scales. First choice on screen.</li>
<li><strong>PNG with transparency</strong>Office documents, email signatures and tools that don't accept SVG. Export at 2x the display size.</li>
<li><strong>PDF or EPS</strong>Professional print. Ask your printer which they prefer.</li>
<li><strong>Master files</strong><span class="fill">[Link to the brand folder]</span></li>
</ul>
</section>
<footer>
<p>Replace the placeholder mark with your own logo files, update the sizes in brackets, then save or print this page for your team and partners.</p>
</footer>
</div>
</body>
</html>Version [1.0] - [Month year] - Questions: [[email protected]]
These rules keep the logo readable and recognisable everywhere it appears. A visual version of the same rules is in logo-usage.html. Open it in a browser, replace the placeholder mark, and print or share it.
Fill in the [bracketed values] once your logo files are final.
| Version | Use it for | Master file |
|---|---|---|
| Primary (horizontal) | The default for almost everything | [brand-logo-primary.svg] |
| Stacked | Square and narrow spaces | [brand-logo-stacked.svg] |
| Symbol | Favicons, app icons, profile pictures, very small spaces | [brand-symbol.svg] |
| Wordmark | Where the symbol would be too small to read | [brand-wordmark.svg] |
Use the symbol on its own only where the brand name appears nearby, or where the symbol is already well known to your audience.
Keep an empty margin around the logo, free of text, images, other logos and the edge of the page or screen.
More space is always fine.
| Version | Screen | |
|---|---|---|
| Primary logo | [100 px wide] | [25 mm wide] |
| Stacked logo | [64 px wide] | [18 mm wide] |
| Symbol | [16 px] | [6 mm] |
Below these sizes, switch to a simpler version. If even the symbol is unreadable, leave the logo out and write the brand name in text.
For very small sizes such as a 16 px favicon, a hand-tuned simplified symbol often reads better than a scaled-down master. If you have one, list it here: [brand-symbol-small.svg].
| Version | Colours | Use on |
|---|---|---|
| Full colour | [Primary mark, neutral 900 wordmark] | White and light neutral backgrounds |
| Reversed | [White mark with primary inner shape, white wordmark] | The primary brand colour |
| One colour, dark | [Neutral 900] | Light backgrounds where full colour isn't possible, single-colour print, engraving |
| One colour, light | [White] | Dark backgrounds, dark mode, dark photography |
Don't create other colour versions. If a project needs one, ask [Name] first.
Use this list as a review checklist before anything with the logo goes out.
| Format | Use for | Notes |
|---|---|---|
| SVG | Websites, apps, presentations that support it | First choice on screen. Outline all text before export so fonts aren't needed. |
| PNG (transparent) | Office documents, email signatures, tools without SVG support | Export at 2x the display size. Keep a version at 1000 px wide. |
| Print and sharing with designers | Vector, fonts outlined. | |
| EPS | Older print workflows | Only if a printer asks for it. |
| ICO and PNG | Favicons | See social-sizes.md for the size set. |
Name files consistently, for example [brand]-logo-[version]-[colour].[ext], such as exampleco-logo-primary-reversed.svg.
| Version | Date | Change |
|---|---|---|
| 1.0 | [Date] | First version |
A structured way to find and test a name for a company, product or feature. Work through it with two or three people. It takes about two hours spread over a few days, because names often look different the morning after.
This worksheet helps you think. It is not a trademark search. Before you commit to a name, have a qualified professional check it in the countries where you will trade.
---
Answer these before anyone suggests a name. They become the test every candidate has to pass.
| Question | Answer |
|---|---|
| What are we naming? (company, product, feature, plan) | [Answer] |
| Who has to remember and say this name? | [Answer] |
| In which countries and languages will it be used? | [Answer] |
| What should people feel when they hear it? Pick three words. | [Answer] |
| What must it never suggest? | [Answer] |
| Does it need to describe what we do, or can it be abstract? | [Answer] |
| Will it sit under a parent brand? If so, how does it relate? | [Answer] |
| Must the .com or another domain be available? | [Answer] |
| Names of competitors and close alternatives | [Answer] |
| Who makes the final decision? By when? | [Answer] |
Most names fall into one of these groups. Knowing which you want narrows the search.
| Type | How it works | Strengths | Risks |
|---|---|---|---|
| Descriptive | Says what it does, such as "Example Payroll" | Instantly clear | Hard to trademark, easy to confuse with competitors |
| Suggestive | Hints at a benefit or feeling | Memorable and often protectable | Can be too vague |
| Compound | Two real words joined | Often available, easy to say | Can feel generic |
| Invented | A new word | Usually available, very protectable | Needs time and money to give it meaning |
| Founder or place | A person's or place's name | Personal, local trust | Hard to sell the business later, may limit growth |
| Acronym | Initials | Short | Forgettable unless already famous |
Our preferred types: [Type, type].
Aim for quantity first. Write down at least 50 candidates before judging any.
Sources to mine:
| Candidate | Type | Source or idea behind it |
|---|---|---|
| [Name] | [Type] | [Idea] |
| [Name] | [Type] | [Idea] |
| [Name] | [Type] | [Idea] |
Remove any candidate that fails one of these. Be strict.
Keep the best 10.
Score each from 1 (poor) to 5 (strong). Have each person score alone first, then compare.
| Name | Fits the brief | Memorable | Easy to say and spell | Distinctive | Room to grow | Total |
|---|---|---|---|---|---|---|
| [Name] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
| [Name] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
| [Name] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
| [Name] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
| [Name] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
Keep the top three to five for checks.
| Check | [Name 1] | [Name 2] | [Name 3] |
|---|---|---|---|
| Preliminary trademark search in your national register | [ ] | [ ] | [ ] |
| Search in the registers of other target markets (for example EUIPO, USPTO, UKIPO, WIPO Global Brand Database) | [ ] | [ ] | [ ] |
| Company or business name registry | [ ] | [ ] | [ ] |
| Main domain | [ ] | [ ] | [ ] |
| Social handles on the networks you need | [ ] | [ ] | [ ] |
| App store search | [ ] | [ ] | [ ] |
| Web search: what already ranks for this name? | [ ] | [ ] | [ ] |
| Professional clearance search (before final decision) | [ ] | [ ] | [ ] |
A quick search in an online register only shows obvious conflicts. Similar names in related classes can still block you. That is why the professional check matters.
For each finalist:
| Question | Answer |
|---|---|
| Chosen name | [Name] |
| Backup name | [Name] |
| Why this one, in two sentences | [Reason] |
| How to write it (capitals, spacing) | [e.g. Example Co, never EXAMPLECO or Example co] |
| Pronunciation, if not obvious | [e.g. EX-am-pull] |
| Professional clearance done by | [Firm or person, date] |
| Trademark filing planned for | [Date, countries, classes] |
| Domain and handles secured on | [Date] |
| Approved by | [Name, date] |
Next, add the name and how to write it to brand-guide-template.md, section 2, and work through brand-checklist.md.
A reference for exporting profile pictures, banners, share images and icons. Sizes are in pixels, width x height.
Platforms change these often. The values below were a reasonable reference when this kit was written, but networks redesign profiles, change crops and switch between desktop and mobile layouts without notice. Before a launch, check each platform's own help page or upload a test image and look at it on desktop and on a phone.
| Platform | Profile picture | Banner or cover | Notes |
|---|---|---|---|
| X (Twitter) | 400 x 400 | 1500 x 500 | Banner crops top and bottom on some screens. Profile overlaps the banner's lower left. |
| Facebook Page | 320 x 320 or larger | 1640 x 624 recommended upload | Shown around 820 x 312 on desktop and taller and narrower on mobile. Keep content central. |
| 320 x 320 | No banner | Shown as a small circle. | |
| LinkedIn personal | 400 x 400 | 1584 x 396 | Profile overlaps the banner's lower left. |
| LinkedIn company page | 400 x 400 | 1128 x 191 | Logo is shown square with rounded corners. |
| YouTube | 800 x 800 | 2560 x 1440 | Banner safe area for text and logos is about 1546 x 423, centred. |
| TikTok | 200 x 200 minimum, larger is better | No banner | Shown as a circle. |
| 280 x 280 or larger | Optional cover, 16:9 works well | Shown as a circle. | |
| Threads | Uses your Instagram picture | No banner | Change it in Instagram. |
| Bluesky | 1000 x 1000 | 3000 x 1000 | Banner is 3:1. |
| Discord server | 512 x 512 or larger | 960 x 540 | Banner availability depends on server features. |
| WhatsApp Business | 640 x 640 | No banner | Shown as a circle. |
| GitHub organisation | 500 x 500 or larger | No banner | Square, shown with rounded corners in places. |
| Use | Size | Ratio |
|---|---|---|
| Open Graph share image (link previews on most networks and chat apps) | 1200 x 630 | 1.91:1 |
| X single image post | 1600 x 900 | 16:9 |
| Instagram portrait post | 1080 x 1350 | 4:5 |
| Instagram square post | 1080 x 1080 | 1:1 |
| Stories, Reels, TikTok, Shorts (vertical video and images) | 1080 x 1920 | 9:16 |
| LinkedIn shared image | 1200 x 627 | 1.91:1 |
| Pinterest standard pin | 1000 x 1500 | 2:3 |
| YouTube thumbnail | 1280 x 720 | 16:9 |
For vertical video, keep text and logos away from the top and bottom 15 percent and the right edge. Captions, buttons and profile details sit there on most apps.
Instagram has changed how the profile grid crops posts more than once. Check how your posts look in the grid, not only in the feed.
A minimal, modern set that covers current browsers:
| File | Size | Used by |
|---|---|---|
favicon.ico | 32 x 32 (can also hold 16 x 16 and 48 x 48) | Older browsers, tools that request /favicon.ico directly |
favicon.svg | Scalable | Current browsers. Can include a dark mode version with a CSS media query inside the SVG. |
apple-touch-icon.png | 180 x 180 | iPhone and iPad home screen. Use a solid background; transparent areas show as black. |
icon-192.png | 192 x 192 | Android home screen, web app manifest |
icon-512.png | 512 x 512 | Web app manifest, install and splash screens |
icon-maskable-512.png | 512 x 512 | Android adaptive icons. Keep the symbol inside the central circle, about 80 percent of the width. |
HTML for the head of every page:
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">
Matching site.webmanifest:
{
"name": "[Brand name]",
"short_name": "[Short name]",
"icons": [
{ "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
{ "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" },
{ "src": "/icon-maskable-512.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" }
],
"theme_color": "#2453d6",
"background_color": "#ffffff",
"display": "standalone"
}
Test at 16 px. If the symbol turns into a smudge, make a simplified version for the smallest sizes.
| Store or platform | Size | Notes |
|---|---|---|
| Apple App Store | 1024 x 1024 | PNG, no transparency, no rounded corners. The system applies the mask. |
| Google Play listing | 512 x 512 | 32-bit PNG. Google applies the rounded mask and shadow. |
| Android adaptive icon (in the app) | 108 x 108 dp per layer | Keep the symbol inside the central 72 x 72 dp. The device chooses the mask shape. |
| Windows and Microsoft Store | Several sizes from 44 x 44 up | Generate them from a square master of 1024 x 1024 or larger. |
Apple and Google publish their current icon rules in the Human Interface Guidelines and the Android developer documentation. Check them before you submit.
| Use | Size | Notes |
|---|---|---|
| Email signature logo | Display at about 200 x 50, export at 400 x 100 | PNG, hosted on your own domain over HTTPS. Many email apps block images by default, so the signature must make sense without it. |
| Email newsletter header | 600 wide, any height | 600 px is the common safe width. Export at 1200 px for sharp screens. |
| Slide deck | 1920 x 1080 | 16:9 |
| Document letterhead logo | Vector PDF or SVG, or PNG at 300 dpi for the printed size |
[brand]-social-x-banner-1500x500.png.Tokens are the named values behind your brand: colours, type, spacing and corner radius. Keep them in one place and every website, app, slide template and email can use the same values. When the brand changes, you change a token, not a hundred files.
This folder holds one example set in four formats. The values are a neutral starting palette. Replace the brand colours with your own, then re-check contrast (see below).
| File | Use it for |
|---|---|
colors.css | CSS custom properties for colour, with light and dark themes |
typography.css | Font stacks, fluid type scale, line heights, weights, spacing, radius and shadows, plus base body and heading rules |
tokens.json | The same values in the Design Tokens Community Group format ($value and $type), for design tools and build pipelines |
tailwind-theme.js | A Tailwind CSS theme that points at the CSS custom properties |
colors.css and typography.css into your site.<link rel="stylesheet" href="/css/colors.css">
<link rel="stylesheet" href="/css/typography.css">
<link rel="stylesheet" href="/css/site.css">
.card {
background: var(--color-surface-alt);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-6);
}
.button-primary {
background: var(--color-primary);
color: var(--color-on-primary);
border-radius: var(--radius-md);
padding: var(--space-3) var(--space-5);
font-weight: var(--weight-semibold);
}
.button-primary:hover {
background: var(--color-primary-hover);
}
:focus-visible {
outline: 2px solid var(--color-focus-ring);
outline-offset: 2px;
}
--neutral-600 and --brand-primary-500 are raw values. They never change between themes.--color-text, --color-surface and --color-danger describe a job. Dark mode swaps what they point to.If you find yourself writing var(--neutral-600) inside a component, add or reuse a semantic token instead.
colors.css handles three cases:
prefers-color-scheme.<html data-theme="dark">: dark theme, whatever the system says.<html data-theme="light">: light theme, whatever the system says.To offer a theme switch, set or remove the data-theme attribute on the html element and store the choice. Without a switch, nothing extra is needed.
Checked with the WCAG 2.x relative luminance formula. AA needs 4.5:1 for normal text, 3:1 for large text (24px, or 18.66px bold) and 3:1 for UI component boundaries such as input borders.
| Pair | Ratio | Result |
|---|---|---|
--color-text on --color-surface (#16191e on #ffffff) | 17.62:1 | AA and AAA |
--color-text on --color-surface-alt (#16191e on #f7f8fa) | 16.58:1 | AA and AAA |
--color-text on --color-surface-sunken (#16191e on #eef0f3) | 15.43:1 | AA and AAA |
--color-text-muted on --color-surface (#4f5662 on #ffffff) | 7.39:1 | AA and AAA |
--color-text-muted on --color-surface-alt (#4f5662 on #f7f8fa) | 6.96:1 | AA |
--color-text-muted on --color-surface-sunken (#4f5662 on #eef0f3) | 6.48:1 | AA |
--color-text-subtle on --color-surface (#6b7380 on #ffffff) | 4.78:1 | AA |
--color-primary and --color-link on --color-surface (#2453d6 on #ffffff) | 6.40:1 | AA |
--color-on-primary on --color-primary (#ffffff on #2453d6) | 6.40:1 | AA |
--color-on-primary on --color-primary-hover (#ffffff on #1b3fa8) | 9.04:1 | AA and AAA |
--color-secondary on --color-surface (#0f766e on #ffffff) | 5.47:1 | AA |
--color-on-secondary on --color-secondary (#ffffff on #0f766e) | 5.47:1 | AA |
--color-accent on --color-surface (#c2410c on #ffffff) | 5.18:1 | AA |
--color-on-accent on --color-accent (#ffffff on #c2410c) | 5.18:1 | AA |
--color-success on --color-surface (#15803d on #ffffff) | 5.02:1 | AA |
--color-warning on --color-surface (#b45309 on #ffffff) | 5.02:1 | AA |
--color-danger on --color-surface (#b91c1c on #ffffff) | 6.47:1 | AA |
--color-info on --color-surface (#0369a1 on #ffffff) | 5.93:1 | AA |
--color-border-strong on --color-surface (#868e9b on #ffffff) | 3.30:1 | Passes 3:1 for UI boundaries |
--color-border on --color-surface (#c3c9d2 on #ffffff) | 1.67:1 | Decorative only, not for input borders |
| Pair | Ratio | Result |
|---|---|---|
--color-text on --color-surface (#f7f8fa on #16191e) | 16.58:1 | AA and AAA |
--color-text on --color-surface-alt (#f7f8fa on #262a31) | 13.55:1 | AA and AAA |
--color-text-muted on --color-surface (#c3c9d2 on #16191e) | 10.58:1 | AA and AAA |
--color-text-muted on --color-surface-alt (#c3c9d2 on #262a31) | 8.65:1 | AA and AAA |
--color-text-subtle on --color-surface (#868e9b on #16191e) | 5.33:1 | AA |
--color-primary and --color-link on --color-surface (#8aaaff on #16191e) | 7.78:1 | AA and AAA |
--color-on-primary on --color-primary (#0c0e11 on #8aaaff) | 8.54:1 | AA and AAA |
--color-secondary on --color-surface (#5eead4 on #16191e) | 11.91:1 | AA and AAA |
--color-on-secondary on --color-secondary (#0c0e11 on #5eead4) | 13.07:1 | AA and AAA |
--color-accent on --color-surface (#fb923c on #16191e) | 7.78:1 | AA and AAA |
--color-on-accent on --color-accent (#0c0e11 on #fb923c) | 8.54:1 | AA and AAA |
--color-success on --color-surface (#4ade80 on #16191e) | 10.11:1 | AA and AAA |
--color-warning on --color-surface (#fbbf24 on #16191e) | 10.55:1 | AA and AAA |
--color-danger on --color-surface (#f87171 on #16191e) | 6.37:1 | AA |
--color-info on --color-surface (#38bdf8 on #16191e) | 8.22:1 | AA and AAA |
--color-border-strong on --color-surface (#6b7380 on #16191e) | 3.68:1 | Passes 3:1 for UI boundaries |
--color-border on --color-surface (#4f5662 on #16191e) | 2.38:1 | Decorative only, not for input borders |
Use --color-border-strong for form fields, checkboxes and anything a user has to find to operate. Use --color-border for dividers and card edges.
Every row above stops being true the moment you edit a value. Re-check each pair with a contrast checker before you ship. Brand blues, oranges and greens often fail on white at their "logo" shade. The usual fix is a darker text shade of the same hue for text and links, and keeping the bright logo shade for large shapes.
The file follows the Design Tokens Community Group format:
$value. Groups set a $type that their children inherit.{color.neutral.900}."1rem". Some tools expect the newer object form ({ "value": 1, "unit": "rem" }). If yours does, convert them when you import.$value. The fluid maximum and the full CSS clamp() sit in $extensions.fluid.semantic.light and semantic.dark.Tools that read this format include Style Dictionary, Tokens Studio and several design tool plugins. Check your tool's documentation for the exact version of the format it supports.
tailwind-theme.js is written for Tailwind CSS v3 config files. To use it:
colors.css and typography.css globally, before Tailwind's output.tailwind.config.js:const brand = require("./tokens/tailwind-theme.js");
module.exports = {
content: ["./src/**/*.{html,js,jsx,ts,tsx}"],
darkMode: brand.darkMode,
theme: brand.theme
};
bg-surface, bg-surface-alt, text-ink, text-ink-muted, border-border-strong, bg-primary text-primary-on hover:bg-primary-hover, text-danger, rounded-lg, p-6.Because the colours are CSS custom properties, dark mode switches without any dark: classes. The darkMode setting is there for the rare case where you want a different layout or image in dark mode.
Tailwind CSS v4 is configured in CSS rather than a JavaScript file. Its theme variables also use the --color- prefix, so a line such as --color-surface: var(--color-surface); would point at itself. Map the tokens under new utility names in an @theme inline block instead:
@import "tailwindcss";
@theme inline {
--color-canvas: var(--color-surface);
--color-canvas-alt: var(--color-surface-alt);
--color-ink: var(--color-text);
--color-ink-muted: var(--color-text-muted);
--color-line: var(--color-border);
--color-line-strong: var(--color-border-strong);
--color-brand: var(--color-primary);
--color-brand-hover: var(--color-primary-hover);
--color-on-brand: var(--color-on-primary);
}
That gives you bg-canvas, text-ink, border-line-strong, bg-brand text-on-brand and so on.
The font stacks start with Inter, Source Serif 4 and JetBrains Mono, which are open-source fonts. If you don't load those files, each stack falls back to the visitor's system fonts, which look clean on every platform. To use your brand fonts, put their names first in --font-sans, --font-serif or --font-mono and keep the fallbacks.
If you self-host fonts, use font-display: swap in your @font-face rules and check the font licence covers web use.
:root {
--neutral-0: #ffffff;
--neutral-50: #f7f8fa;
--neutral-100: #eef0f3;
--neutral-200: #dde1e7;
--neutral-300: #c3c9d2;
--neutral-400: #868e9b;
--neutral-500: #6b7380;
--neutral-600: #4f5662;
--neutral-700: #3a404a;
--neutral-800: #262a31;
--neutral-900: #16191e;
--neutral-950: #0c0e11;
--brand-primary-300: #8aaaff;
--brand-primary-500: #2453d6;
--brand-primary-700: #1b3fa8;
--brand-secondary-300: #5eead4;
--brand-secondary-500: #0f766e;
--brand-secondary-700: #115e59;
--brand-accent-300: #fb923c;
--brand-accent-500: #c2410c;
--brand-accent-700: #9a3412;
--green-300: #4ade80;
--green-600: #15803d;
--amber-300: #fbbf24;
--amber-600: #b45309;
--red-300: #f87171;
--red-600: #b91c1c;
--sky-300: #38bdf8;
--sky-600: #0369a1;
--color-surface: var(--neutral-0);
--color-surface-alt: var(--neutral-50);
--color-surface-sunken: var(--neutral-100);
--color-surface-inverse: var(--neutral-900);
--color-text: var(--neutral-900);
--color-text-muted: var(--neutral-600);
--color-text-subtle: var(--neutral-500);
--color-text-inverse: var(--neutral-50);
--color-border: var(--neutral-300);
--color-border-strong: var(--neutral-400);
--color-primary: var(--brand-primary-500);
--color-primary-hover: var(--brand-primary-700);
--color-on-primary: var(--neutral-0);
--color-secondary: var(--brand-secondary-500);
--color-secondary-hover: var(--brand-secondary-700);
--color-on-secondary: var(--neutral-0);
--color-accent: var(--brand-accent-500);
--color-accent-hover: var(--brand-accent-700);
--color-on-accent: var(--neutral-0);
--color-link: var(--brand-primary-500);
--color-link-hover: var(--brand-primary-700);
--color-focus-ring: var(--brand-primary-500);
--color-success: var(--green-600);
--color-warning: var(--amber-600);
--color-danger: var(--red-600);
--color-info: var(--sky-600);
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--color-surface: var(--neutral-900);
--color-surface-alt: var(--neutral-800);
--color-surface-sunken: var(--neutral-950);
--color-surface-inverse: var(--neutral-50);
--color-text: var(--neutral-50);
--color-text-muted: var(--neutral-300);
--color-text-subtle: var(--neutral-400);
--color-text-inverse: var(--neutral-900);
--color-border: var(--neutral-600);
--color-border-strong: var(--neutral-500);
--color-primary: var(--brand-primary-300);
--color-primary-hover: var(--neutral-0);
--color-on-primary: var(--neutral-950);
--color-secondary: var(--brand-secondary-300);
--color-secondary-hover: var(--neutral-0);
--color-on-secondary: var(--neutral-950);
--color-accent: var(--brand-accent-300);
--color-accent-hover: var(--neutral-0);
--color-on-accent: var(--neutral-950);
--color-link: var(--brand-primary-300);
--color-link-hover: var(--neutral-0);
--color-focus-ring: var(--brand-primary-300);
--color-success: var(--green-300);
--color-warning: var(--amber-300);
--color-danger: var(--red-300);
--color-info: var(--sky-300);
color-scheme: dark;
}
}
:root[data-theme="dark"] {
--color-surface: var(--neutral-900);
--color-surface-alt: var(--neutral-800);
--color-surface-sunken: var(--neutral-950);
--color-surface-inverse: var(--neutral-50);
--color-text: var(--neutral-50);
--color-text-muted: var(--neutral-300);
--color-text-subtle: var(--neutral-400);
--color-text-inverse: var(--neutral-900);
--color-border: var(--neutral-600);
--color-border-strong: var(--neutral-500);
--color-primary: var(--brand-primary-300);
--color-primary-hover: var(--neutral-0);
--color-on-primary: var(--neutral-950);
--color-secondary: var(--brand-secondary-300);
--color-secondary-hover: var(--neutral-0);
--color-on-secondary: var(--neutral-950);
--color-accent: var(--brand-accent-300);
--color-accent-hover: var(--neutral-0);
--color-on-accent: var(--neutral-950);
--color-link: var(--brand-primary-300);
--color-link-hover: var(--neutral-0);
--color-focus-ring: var(--brand-primary-300);
--color-success: var(--green-300);
--color-warning: var(--amber-300);
--color-danger: var(--red-300);
--color-info: var(--sky-300);
color-scheme: dark;
}module.exports = {
darkMode: ["variant", ["@media (prefers-color-scheme: dark) { &:not([data-theme=\"light\"] *) }", "&:is([data-theme=\"dark\"] *)"]],
theme: {
extend: {
colors: {
neutral: {
0: "var(--neutral-0)",
50: "var(--neutral-50)",
100: "var(--neutral-100)",
200: "var(--neutral-200)",
300: "var(--neutral-300)",
400: "var(--neutral-400)",
500: "var(--neutral-500)",
600: "var(--neutral-600)",
700: "var(--neutral-700)",
800: "var(--neutral-800)",
900: "var(--neutral-900)",
950: "var(--neutral-950)"
},
surface: {
DEFAULT: "var(--color-surface)",
alt: "var(--color-surface-alt)",
sunken: "var(--color-surface-sunken)",
inverse: "var(--color-surface-inverse)"
},
ink: {
DEFAULT: "var(--color-text)",
muted: "var(--color-text-muted)",
subtle: "var(--color-text-subtle)",
inverse: "var(--color-text-inverse)"
},
border: {
DEFAULT: "var(--color-border)",
strong: "var(--color-border-strong)"
},
primary: {
DEFAULT: "var(--color-primary)",
hover: "var(--color-primary-hover)",
on: "var(--color-on-primary)"
},
secondary: {
DEFAULT: "var(--color-secondary)",
hover: "var(--color-secondary-hover)",
on: "var(--color-on-secondary)"
},
accent: {
DEFAULT: "var(--color-accent)",
hover: "var(--color-accent-hover)",
on: "var(--color-on-accent)"
},
link: {
DEFAULT: "var(--color-link)",
hover: "var(--color-link-hover)"
},
success: "var(--color-success)",
warning: "var(--color-warning)",
danger: "var(--color-danger)",
info: "var(--color-info)"
},
ringColor: {
focus: "var(--color-focus-ring)"
},
fontFamily: {
sans: "var(--font-sans)",
serif: "var(--font-serif)",
mono: "var(--font-mono)",
body: "var(--font-body)",
heading: "var(--font-heading)"
},
fontSize: {
xs: ["var(--text-xs)", { lineHeight: "var(--leading-normal)" }],
sm: ["var(--text-sm)", { lineHeight: "var(--leading-normal)" }],
base: ["var(--text-base)", { lineHeight: "var(--leading-normal)" }],
lg: ["var(--text-lg)", { lineHeight: "var(--leading-snug)" }],
xl: ["var(--text-xl)", { lineHeight: "var(--leading-snug)" }],
"2xl": ["var(--text-2xl)", { lineHeight: "var(--leading-snug)" }],
"3xl": ["var(--text-3xl)", { lineHeight: "var(--leading-tight)" }],
"4xl": ["var(--text-4xl)", { lineHeight: "var(--leading-tight)" }],
"5xl": ["var(--text-5xl)", { lineHeight: "var(--leading-tight)" }]
},
fontWeight: {
regular: "var(--weight-regular)",
medium: "var(--weight-medium)",
semibold: "var(--weight-semibold)",
bold: "var(--weight-bold)"
},
lineHeight: {
tight: "var(--leading-tight)",
snug: "var(--leading-snug)",
normal: "var(--leading-normal)",
relaxed: "var(--leading-relaxed)"
},
spacing: {
1: "var(--space-1)",
2: "var(--space-2)",
3: "var(--space-3)",
4: "var(--space-4)",
5: "var(--space-5)",
6: "var(--space-6)",
8: "var(--space-8)",
10: "var(--space-10)",
12: "var(--space-12)",
16: "var(--space-16)",
20: "var(--space-20)",
24: "var(--space-24)"
},
borderRadius: {
none: "var(--radius-none)",
sm: "var(--radius-sm)",
DEFAULT: "var(--radius-md)",
md: "var(--radius-md)",
lg: "var(--radius-lg)",
xl: "var(--radius-xl)",
full: "var(--radius-full)"
},
boxShadow: {
sm: "var(--shadow-sm)",
DEFAULT: "var(--shadow-md)",
md: "var(--shadow-md)",
lg: "var(--shadow-lg)"
},
maxWidth: {
measure: "var(--measure)"
}
}
}
};{
"color": {
"$type": "color",
"neutral": {
"0": { "$value": "#ffffff" },
"50": { "$value": "#f7f8fa" },
"100": { "$value": "#eef0f3" },
"200": { "$value": "#dde1e7" },
"300": { "$value": "#c3c9d2" },
"400": { "$value": "#868e9b" },
"500": { "$value": "#6b7380" },
"600": { "$value": "#4f5662" },
"700": { "$value": "#3a404a" },
"800": { "$value": "#262a31" },
"900": { "$value": "#16191e" },
"950": { "$value": "#0c0e11" }
},
"brand": {
"primary": {
"300": { "$value": "#8aaaff" },
"500": { "$value": "#2453d6" },
"700": { "$value": "#1b3fa8" }
},
"secondary": {
"300": { "$value": "#5eead4" },
"500": { "$value": "#0f766e" },
"700": { "$value": "#115e59" }
},
"accent": {
"300": { "$value": "#fb923c" },
"500": { "$value": "#c2410c" },
"700": { "$value": "#9a3412" }
}
},
"status": {
"green": {
"300": { "$value": "#4ade80" },
"600": { "$value": "#15803d" }
},
"amber": {
"300": { "$value": "#fbbf24" },
"600": { "$value": "#b45309" }
},
"red": {
"300": { "$value": "#f87171" },
"600": { "$value": "#b91c1c" }
},
"sky": {
"300": { "$value": "#38bdf8" },
"600": { "$value": "#0369a1" }
}
}
},
"semantic": {
"$type": "color",
"light": {
"surface": { "$value": "{color.neutral.0}" },
"surface-alt": { "$value": "{color.neutral.50}" },
"surface-sunken": { "$value": "{color.neutral.100}" },
"surface-inverse": { "$value": "{color.neutral.900}" },
"text": { "$value": "{color.neutral.900}" },
"text-muted": { "$value": "{color.neutral.600}" },
"text-subtle": { "$value": "{color.neutral.500}" },
"text-inverse": { "$value": "{color.neutral.50}" },
"border": { "$value": "{color.neutral.300}" },
"border-strong": { "$value": "{color.neutral.400}" },
"primary": { "$value": "{color.brand.primary.500}" },
"primary-hover": { "$value": "{color.brand.primary.700}" },
"on-primary": { "$value": "{color.neutral.0}" },
"secondary": { "$value": "{color.brand.secondary.500}" },
"secondary-hover": { "$value": "{color.brand.secondary.700}" },
"on-secondary": { "$value": "{color.neutral.0}" },
"accent": { "$value": "{color.brand.accent.500}" },
"accent-hover": { "$value": "{color.brand.accent.700}" },
"on-accent": { "$value": "{color.neutral.0}" },
"link": { "$value": "{color.brand.primary.500}" },
"link-hover": { "$value": "{color.brand.primary.700}" },
"focus-ring": { "$value": "{color.brand.primary.500}" },
"success": { "$value": "{color.status.green.600}" },
"warning": { "$value": "{color.status.amber.600}" },
"danger": { "$value": "{color.status.red.600}" },
"info": { "$value": "{color.status.sky.600}" }
},
"dark": {
"surface": { "$value": "{color.neutral.900}" },
"surface-alt": { "$value": "{color.neutral.800}" },
"surface-sunken": { "$value": "{color.neutral.950}" },
"surface-inverse": { "$value": "{color.neutral.50}" },
"text": { "$value": "{color.neutral.50}" },
"text-muted": { "$value": "{color.neutral.300}" },
"text-subtle": { "$value": "{color.neutral.400}" },
"text-inverse": { "$value": "{color.neutral.900}" },
"border": { "$value": "{color.neutral.600}" },
"border-strong": { "$value": "{color.neutral.500}" },
"primary": { "$value": "{color.brand.primary.300}" },
"primary-hover": { "$value": "{color.neutral.0}" },
"on-primary": { "$value": "{color.neutral.950}" },
"secondary": { "$value": "{color.brand.secondary.300}" },
"secondary-hover": { "$value": "{color.neutral.0}" },
"on-secondary": { "$value": "{color.neutral.950}" },
"accent": { "$value": "{color.brand.accent.300}" },
"accent-hover": { "$value": "{color.neutral.0}" },
"on-accent": { "$value": "{color.neutral.950}" },
"link": { "$value": "{color.brand.primary.300}" },
"link-hover": { "$value": "{color.neutral.0}" },
"focus-ring": { "$value": "{color.brand.primary.300}" },
"success": { "$value": "{color.status.green.300}" },
"warning": { "$value": "{color.status.amber.300}" },
"danger": { "$value": "{color.status.red.300}" },
"info": { "$value": "{color.status.sky.300}" }
}
},
"font": {
"family": {
"$type": "fontFamily",
"sans": { "$value": ["Inter", "ui-sans-serif", "system-ui", "-apple-system", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans", "sans-serif"] },
"serif": { "$value": ["Source Serif 4", "ui-serif", "Georgia", "Cambria", "Times New Roman", "Times", "serif"] },
"mono": { "$value": ["JetBrains Mono", "ui-monospace", "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", "monospace"] }
},
"weight": {
"$type": "fontWeight",
"regular": { "$value": 400 },
"medium": { "$value": 500 },
"semibold": { "$value": 600 },
"bold": { "$value": 700 }
},
"size": {
"$type": "dimension",
"xs": { "$value": "0.75rem", "$extensions": { "fluid": { "max": "0.8125rem", "css": "clamp(0.75rem, 0.73rem + 0.1vw, 0.8125rem)" } } },
"sm": { "$value": "0.875rem", "$extensions": { "fluid": { "max": "0.9375rem", "css": "clamp(0.875rem, 0.85rem + 0.12vw, 0.9375rem)" } } },
"base": { "$value": "1rem", "$extensions": { "fluid": { "max": "1.0625rem", "css": "clamp(1rem, 0.97rem + 0.15vw, 1.0625rem)" } } },
"lg": { "$value": "1.125rem", "$extensions": { "fluid": { "max": "1.25rem", "css": "clamp(1.125rem, 1.08rem + 0.22vw, 1.25rem)" } } },
"xl": { "$value": "1.25rem", "$extensions": { "fluid": { "max": "1.5rem", "css": "clamp(1.25rem, 1.18rem + 0.36vw, 1.5rem)" } } },
"2xl": { "$value": "1.5rem", "$extensions": { "fluid": { "max": "1.875rem", "css": "clamp(1.5rem, 1.38rem + 0.6vw, 1.875rem)" } } },
"3xl": { "$value": "1.875rem", "$extensions": { "fluid": { "max": "2.5rem", "css": "clamp(1.875rem, 1.68rem + 0.98vw, 2.5rem)" } } },
"4xl": { "$value": "2.25rem", "$extensions": { "fluid": { "max": "3.25rem", "css": "clamp(2.25rem, 1.95rem + 1.5vw, 3.25rem)" } } },
"5xl": { "$value": "2.75rem", "$extensions": { "fluid": { "max": "4.25rem", "css": "clamp(2.75rem, 2.3rem + 2.25vw, 4.25rem)" } } }
},
"line-height": {
"$type": "number",
"tight": { "$value": 1.15 },
"snug": { "$value": 1.3 },
"normal": { "$value": 1.5 },
"relaxed": { "$value": 1.65 }
}
},
"space": {
"$type": "dimension",
"0": { "$value": "0rem" },
"1": { "$value": "0.25rem" },
"2": { "$value": "0.5rem" },
"3": { "$value": "0.75rem" },
"4": { "$value": "1rem" },
"5": { "$value": "1.25rem" },
"6": { "$value": "1.5rem" },
"8": { "$value": "2rem" },
"10": { "$value": "2.5rem" },
"12": { "$value": "3rem" },
"16": { "$value": "4rem" },
"20": { "$value": "5rem" },
"24": { "$value": "6rem" }
},
"radius": {
"$type": "dimension",
"none": { "$value": "0rem" },
"sm": { "$value": "0.25rem" },
"md": { "$value": "0.5rem" },
"lg": { "$value": "0.75rem" },
"xl": { "$value": "1rem" },
"full": { "$value": "9999px" }
}
}:root {
--font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
--font-serif: "Source Serif 4", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
--font-body: var(--font-sans);
--font-heading: var(--font-sans);
--text-xs: clamp(0.75rem, 0.73rem + 0.1vw, 0.8125rem);
--text-sm: clamp(0.875rem, 0.85rem + 0.12vw, 0.9375rem);
--text-base: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
--text-lg: clamp(1.125rem, 1.08rem + 0.22vw, 1.25rem);
--text-xl: clamp(1.25rem, 1.18rem + 0.36vw, 1.5rem);
--text-2xl: clamp(1.5rem, 1.38rem + 0.6vw, 1.875rem);
--text-3xl: clamp(1.875rem, 1.68rem + 0.98vw, 2.5rem);
--text-4xl: clamp(2.25rem, 1.95rem + 1.5vw, 3.25rem);
--text-5xl: clamp(2.75rem, 2.3rem + 2.25vw, 4.25rem);
--leading-tight: 1.15;
--leading-snug: 1.3;
--leading-normal: 1.5;
--leading-relaxed: 1.65;
--tracking-tight: -0.02em;
--tracking-normal: 0;
--tracking-wide: 0.04em;
--weight-regular: 400;
--weight-medium: 500;
--weight-semibold: 600;
--weight-bold: 700;
--measure: 66ch;
--space-0: 0;
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-5: 1.25rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-10: 2.5rem;
--space-12: 3rem;
--space-16: 4rem;
--space-20: 5rem;
--space-24: 6rem;
--radius-none: 0;
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
--radius-full: 9999px;
--shadow-sm: 0 1px 2px rgba(12, 14, 17, 0.06);
--shadow-md: 0 4px 12px rgba(12, 14, 17, 0.08);
--shadow-lg: 0 12px 32px rgba(12, 14, 17, 0.12);
}
body {
font-family: var(--font-body);
font-size: var(--text-base);
line-height: var(--leading-normal);
font-weight: var(--weight-regular);
color: var(--color-text);
background: var(--color-surface);
}
h1, h2, h3, h4 {
font-family: var(--font-heading);
line-height: var(--leading-tight);
letter-spacing: var(--tracking-tight);
font-weight: var(--weight-bold);
}
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); line-height: var(--leading-snug); }
h4 { font-size: var(--text-xl); line-height: var(--leading-snug); }
p, li { max-width: var(--measure); }
small { font-size: var(--text-sm); }
code, kbd, pre { font-family: var(--font-mono); font-size: 0.925em; }