02 · GALTON AI Assets
Foundations
Colour, type, shape and elevation — the tokens everything is built from.
01 — Overview
Overview
GALTON Brands is a dark-first, editorial, high-contrast brand system. The page floor is a near-black canvas (#1A1A1A — #1A1A1A), text is white (#FFFFFF), and a single signature primary yellow (#FFD700 — #FFD700) carries every accent — CTAs, highlights, focus rings, the hero word. Yellow is never a large fill; on a yellow surface text is always black (#1A1A1A).
Everything is set in one typeface — Galton — at Light (300) in Sentence case. Weight steps up to Medium (500) / Bold (700) only for emphasis. Uppercase is reserved for the H1 / display headline and three small utilities (eyebrow label, button labels, badge); everything else is Sentence case. Where Galton can't be embedded (email, Google Docs/Slides, system contexts), Montserrat is the official substitute — it is last in every font stack. Hierarchy is created by size and a leading ratio (Headline ×1.1, Subhead ×1.2, Body ×1.5), not by heavy weights.
The component language is pill-and-flat: buttons are full pills (100px), uppercase, Galton Bold; inputs are flat (0px), transparent, bottom-border only, with a primary-yellow focus. The palette is fixed — no invented shades; raised surfaces are built from white at low opacity (rgba(255,255,255,0.04)), never a new hex.
If this system doesn't define something, do not invent it. Derive it from the primitives in the Fallbacks & unknown elements section (the
fallbackblock): monochrome surfaces and text, hairline lines, and a single yellow accent — never a red/blue/green you reached for by default. This one rule prevents most off-brand output.
02 — Colors
Colors
Primary palette
Secondary palette
Semantic tokens
How the palette is applied across the UI. Reference these as {colors.name} — they resolve to the brand colours above (or a grey derived from black/white at opacity).
Brand palette
The brand has three colours, in two groups:
- Primary palette — White (#FFFFFF) and Black (#1A1A1A). The base of the system: black is the dark-first canvas, white is the ink.
- Secondary palette — Yellow (#FFD700). The single accent: CTAs, highlights, focus rings, the hero word. Used sparingly, never a large fill; on a yellow surface, foreground is always black (#1A1A1A).
Text is always pure — white (#FFFFFF) on dark, near-black (#1A1A1A) on light, with no opacity and no grey text (body, body-soft and muted all resolve to pure white on the dark canvas). Only non-text structure — rgba(255,255,255,0.12) dividers and rgba(255,255,255,0.04) panels — is derived from white at low opacity, never a new brand colour.
Surface
- Canvas (
#1A1A1A— #1A1A1A): The default page floor on every dark surface. The brand is dark-first. - Surface Raised (
rgba(255,255,255,0.04)— white @4%): Cards, modals, raised panels. Built from white at low opacity over the canvas — never a new hex. Pair with argba(255,255,255,0.12)border. - Hairline (
rgba(255,255,255,0.12)— white @12%): 1px dividers, table rows, card outlines, the top/bottom bars. - Light Canvas (
#FFFFFF— #FFFFFF): The floor for light surfaces (cards on light, print, email).
Text
- Ink / On Dark (
#FFFFFF— #FFFFFF): Headlines and primary text on the dark canvas. - Body (
#FFFFFF— #FFFFFF): Running body text — pure white, no opacity. - Body Soft (
#FFFFFF— #FFFFFF): Secondary paragraphs and section leads — also pure white. - Muted (
#FFFFFF— #FFFFFF): Captions, metadata, placeholders, disabled labels — pure white (no grey text). Dividers and borders usergba(255,255,255,0.12), not a grey text colour. - On Light (
#1A1A1A— #1A1A1A): Text and marks on a white/light surface.
Usage Rules
- Default page =
#1A1A1Abackground,#FFFFFFtext. #FFD700is for emphasis only — never a large fill. On a primary surface, text is always black.- Keep the secondary yellow to accents only — never a large fill.
- Need a raised surface? Build it from white/grey at low opacity (
rgba(255,255,255,0.04)) — do not introduce a new hex. - Selection highlight is primary-on-black.
03 — Combinations
Combinations
04 — Typography
Typography
- Family
- Galton
- Default
- 300 · Sentence case
- Weights
- 100 Thin · 300 Light (default) · 400 Regular · 500 Medium · 600 Bold · 700 Extrabold · 800 Black
- Fallback
- Montserrat
- · 100–900· the single web font — variable, covers every weight
@font-face {
font-family: "Galton";
src: url("https://galton-ai-assets.vercel.app/brand/fonts/GaltonVariable.woff2") format("woff2-variations");
font-weight: 100 900;
font-style: normal;
font-display: swap;
/* Vertical-metric correction — KEEP these three lines. The variable woff2
sets USE_TYPO_METRICS with an asymmetric 750/-250 typo ascent/descent,
which floats UPPERCASE labels ~0.1em high in tight (line-height:1) boxes
like buttons and badges. These overrides pin the webfont to the desktop
masters' metrics (ascent−descent ≈ the cap height) so text centres
correctly everywhere — no per-button padding hacks needed. */
ascent-override: 96%;
descent-override: 24%;
line-gap-override: 0%;
}Type scale & hierarchy
Size, scale and position all play a factor in how information is read. Always ensure there is a purposeful difference between type sizes. Type sizes are examples only.
Confident headlines, set in Galton Light.
Leading = size × 1.1 → 80/88pt
Subheads carry a clear, secondary voice beneath the headline.
Leading = size × 1.2 → 30/36pt
Body copy holds the detail at a comfortable measure, with a leading ratio that keeps long passages easy to read across the page.
Leading = size × 1.5 → 18/27pt
All type styles
The quick brown fox
The quick brown fox
The quick brown fox
The quick brown fox
The quick brown fox
The quick brown fox
Section label
Button label
The quick brown fox
Section label
Font Family
The system runs one typeface — Galton — for both headings and body, from a single variable woff2 that covers every weight 100–900 (the only web font). The default is Light (300), set in Sentence case at normal tracking.
Montserrat is the official substitute: use it wherever Galton can't be embedded (email, Google Docs/Slides, system contexts). It is last in every font stack: Galton, Montserrat, ui-sans-serif, system-ui, sans-serif. There is no second brand face — Galton does everything.
Weights — the Galton named cuts: 100 Thin · 300 Light (default) · 400 Regular · 500 Medium · 600 Bold · 700 Extrabold · 800 Black. The single variable woff2 covers 100–900 continuously, so any in-between weight is available. Buttons use Bold (600) — the same Galton-Bold weight the live site renders its .btn at.
Font source & embedding
The Galton typeface ships with this package — don't substitute a lookalike. Load the variable woff2 (one file, weights 100–900):
- File:
https://galton-ai-assets.vercel.app/brand/fonts/GaltonVariable.woff2— the single web font (variable, weights 100–900). Embed this and nothing else. - Base URL:
https://galton-ai-assets.vercel.app/brand/(resolved to wherever this is deployed) - Hotlink these absolute URLs exactly as given — the files are served with permissive CORS (
Access-Control-Allow-Origin: *), so a cross-origin@font-faceworks. Do not relativise them to/brand/fonts/…(that resolves against your host and 404s, silently falling back to Montserrat) and don't copy the file locally.
@font-face {
font-family: "Galton";
src: url("https://galton-ai-assets.vercel.app/brand/fonts/GaltonVariable.woff2") format("woff2-variations");
font-weight: 100 900;
font-style: normal;
font-display: swap;
/* Vertical-metric correction — KEEP these. The variable woff2 ships with
USE_TYPO_METRICS and an asymmetric 750/-250 typo ascent/descent, so the glyphs
sit ~0.1em high in tight (line-height:1) boxes — UPPERCASE buttons and badges
look floated up and off-centre. These overrides pin the webfont to the desktop
masters' metrics (ascent−descent ≈ cap height) so labels centre correctly. */
ascent-override: 96%;
descent-override: 24%;
line-gap-override: 0%;
}Why the three
*-overridelines matter. Without them, Galton's UPPERCASE labels float ~0.1em above the optical centre of any pill/badge (the font reserves empty descender space it never uses). The overrides re-declare the metrics the browser lays text out with — so you center buttons and badges with plain symmetric padding, never an asymmetric "push the text down" hack. Embed the@font-faceexactly as given, descriptors included.
Then use the stack Galton, Montserrat, ui-sans-serif, system-ui, sans-serif. Montserrat is the substitute and loads from Google Fonts (https://fonts.google.com/specimen/Montserrat) — it is last in the stack and only kicks in where Galton can't be embedded. The full fonts block in the frontmatter lists every file, format and the ready-to-paste @font-face.
Hierarchy
All Galton Light (300). Display headlines — the page H1 and every section title (H2) — are set UPPERCASE (matching the slide system); every other level — subheads, sub-section headings (H3+), body, labels — stays Sentence case. Leading (line-height) is a ratio of the type size. Display sizes are responsive; the token value is the desktop maximum.
| Token | Size (responsive) | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
{typography.display-lg} | 56 → 88 → 136 → 180px | 300 | 1.05 | 0 | Jumbotron / extreme display |
{typography.display} | 48 → 72 → 96 → 120px | 300 | 1.1 | 0 | Large hero headline |
{typography.headline} | 40 → 52 → 64 → 80px | 300 | 1.1 | 0 | Headline (size ×1.1) |
{typography.subhead} | 22 → 24 → 30px | 300 | 1.2 | 0 | Subhead (size ×1.2) |
{typography.body} | 18px | 300 | 1.5 | 0 | Body — the web/body minimum (never below 18px) |
{typography.body-strong} | 18px | 500 | 1.4 | 0 | Emphasis inside body |
{typography.eyebrow} | 15px | 500 | 1.4 | 0.22em | Section label — uppercase overline above headlines, primary color |
{typography.button} | 18px | 600 | 1.0 | 0 | Uppercase button labels (Galton Bold = 600, the live .btn weight) |
{typography.label} | 18 → 24px | 300 | 1.4 | 0 | Form labels |
{typography.badge} | 15px | 400 | 1.0 | 0.08em | Uppercase pill chip (the global 15px minimum) |
Principles
Emphasis comes from size and leading, then a small step in weight (300 → 500/700) — never from uppercase body copy. The rule of thumb for any new size: Headline ×1.1, Subhead ×1.2, Body ×1.5 leading, with a purposeful jump between levels.
Uppercase appears for the H1 / display headline and in three small utilities — the eyebrow label, button labels, and the badge. Everything else (subheads, body, links, form labels, captions) is Sentence case. Never uppercase body copy.
Note on Font Substitutes
If Galton is unavailable, fall back to Montserrat (Google Fonts) — the official substitute, already last in every stack. Montserrat is a geometric sans close to Galton in proportion; keep the Light (300) default and Sentence case. Do not substitute a serif or a condensed face.
05 — Data visualization
Data visualization
12345Read chart via get_chart_palette. One highlight per chart, never a library-default rainbow, and red/green only for genuine good-vs-bad deltas.
Charts are dark-first and monochrome-led, exactly like the rest of the system: a near-black plot floor, hairline gridlines, muted labels, and one yellow accent carrying the series you want read first. The full palette is the chart block in the frontmatter (read it via get_chart_palette or list_tokens → chart).
Colour rules
- Categorical series use the ramp in order: the signature yellow first (the highlight), then white, then white at 62% / 40% / 24%. Five distinguishable categories is the practical ceiling — beyond that, prefer small multiples over more colours.
- Never reach for a chart library's default palette (the rainbow), and never use red / blue / green as a decorative series colour. This is the most common way a generated chart goes off-brand.
- The plot background is
#1A1A1A, gridlines arergba(255,255,255,0.12), axis ticks and labels are#FFFFFF, data labels#FFFFFF. - Semantic good/bad colouring (
#5FB87A/#E0664E) is used only when the chart literally encodes positive vs negative — a delta, a target met/missed. Otherwise stay in the yellow-and-neutral ramp. - One highlight per chart. Put the series that matters in yellow and keep the rest neutral; that single accent does the work a rainbow only pretends to.
Sequential / intensity
For a heat ramp or single-measure intensity, go white @10% → white @40% → yellow (low → high). Keep the steps few and legible.
06 — Status & feedback colours
Status & feedback colours
#5FB87AConfirmation, valid input
#FFD700Caution (the brand yellow)
#E0664EError, failed validation
#7FB2D4Neutral, informational
Functional, not brand, colours — semantic feedback only. They are never the accent (that's always yellow) and never a large fill: a 3px rule, an icon, a 1px error border.
The brand palette is fixed — black, white, yellow. But real products must signal success, warning, error and information, and an agent with no sanctioned status colour will invent a garish one (the red sliders and green box that prompted this work). So the system defines four functional status hues, muted for the dark canvas:
| Role | Token | Hex | Use |
|---|---|---|---|
| Success | #5FB87A | #5FB87A | Confirmation, valid input, positive delta |
| Warning | #FFD700 | #FFD700 | Caution / attention (this is the brand yellow) |
| Error | #E0664E | #E0664E | Error, destructive action, failed validation |
| Info | #7FB2D4 | #7FB2D4 | Neutral, informational |
These are functional, not brand, colours. Hard rules:
- They signal status only — form validation, alerts/notifications, semantic chart deltas. Never decoration, never a heading colour, never a button fill.
- They are never the accent. The accent is always
#FFD700(yellow). An active tab, a selected chip, a slider fill, a focus ring — all yellow, neversuccess/error. - They appear minimally: a 3px rule on an alert, an icon, a 1px error border on an input — never a large coloured panel.
07 — Elevation & Depth
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| Flat | No shadow, no border | Body, top nav, footer, most sections |
| Hairline | 1px rgba(255,255,255,0.12) border | Section dividers, table rows, card outlines |
| Raised surface | rgba(255,255,255,0.04) (white @4%) + hairline border | Cards, modals, panels — no drop shadow |
| Accent glow | Radial primary tint at very low opacity | Optional hover halo on a feature panel only |
The system avoids drop shadows and gradients. Depth comes from the contrast between the near-black canvas and a barely-raised white-at-opacity surface, plus the hairline. Do not add material-style elevation shadows.
08 — Shapes
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
0px | 0px | Inputs, textareas, selects, checkboxes — always flat |
10px | 10px | Small UI elements |
20px | 20px | Standard card / media container — the signature radius (galton.sk uses 20px on nearly every card, image and media block) |
28px | 28px | Large panel / floating select dropdown (galton.sk .nice-select-dropdown) |
100px | 100px | Buttons, tags, chips, the badge |
50% (not a token) | 50% | True circles only — avatars, status dots, the custom cursor (galton.sk) |
The radius language is intentional and matches the live site: form controls are flat (0px); interactive pills are fully round (100px); content containers and media are softly rounded (20px), with large floating panels at 28px; true circles use 50%. Avoid arbitrary in-between radii — galton.sk's one-off 5/12/15/25/30px values are page-specific and not part of the system.
