# Brand Layer — GALTON Brands, for AI agents > A confident, editorial, dark-first brand house. Near-black canvas, white type, one signature yellow used sparingly, and a single typeface — Galton. > Brand Layer is a brand knowledge service by GALTON Brands. This file is the AI entry point. The full, machine-readable spec is in the open DESIGN.md format. Connect over MCP for live token/component queries, or read the surfaces below. ## Critical rule for agents (read first) Never invent a colour, font, radius or component. The accent is ALWAYS the yellow primary — never red, blue or green as an accent, selected state, slider fill, link or focus ring. For anything this system does not define, read the fallback contract (get_fallback) and derive from the primitives, or ask. Charts use the chart palette (get_chart_palette), never a library-default rainbow. Status hues (success/warning/error/info) are functional-only — never decoration or an accent. H1/display is UPPERCASE; everything else is Sentence case. ## Read the spec - [DESIGN.md](https://galton-ai-assets.vercel.app/design.md): complete token frontmatter + rules (apply this directly). - [skill.md](https://galton-ai-assets.vercel.app/skill.md): the versioned agent orchestrator skill — how to route any task to the right tools. Save it (optional) or keep it in context; re-fetch when the brand version changes. - [brand.json](https://galton-ai-assets.vercel.app/brand.json): identity, tokens, components and assets as JSON. - [llms-full.txt](https://galton-ai-assets.vercel.app/llms-full.txt): the whole brand in ONE file (this entry point + full design spec + brand guide + verbal identity + LinkedIn playbook + layouts) — for single-file context uploads. - [brand.css](https://galton-ai-assets.vercel.app/brand.css): hotlinkable stylesheet — @font-face, every token as a CSS variable, and a .bl-{component} class per component. One makes a page on-brand. - [snippets.json](https://galton-ai-assets.vercel.app/snippets.json): ready-to-paste HTML markup per component, styled by brand.css. - [layouts.json](https://galton-ai-assets.vercel.app/layouts.json): the slide canvas + layout slot schemas, with absolute example-image URLs. - [icons.json](https://galton-ai-assets.vercel.app/icons.json): the icon library (line / 3d) with absolute hotlinkable URLs (line icons also carry lightUrl). - MCP endpoint: https://galton-ai-assets.vercel.app/api/mcp (Streamable HTTP, stateless — the recommended transport). Read-only knowledge tools: get_skill, get_brand_overview, get_design_spec, get_brand_guide, list_tokens, resolve_token, list_components, get_component, get_agent_prompts, get_fallback, get_chart_palette, get_agent_rules, list_assets, get_section, search_design, get_voice_guide, get_linkedin_playbook, get_slide_canvas, list_layouts, get_layout, list_carousel_recipes, get_carousel_recipe, list_icons, get_icon. ## Brand palette Primary: `White` #FFFFFF · RGB 255/255/255 · CMYK 0/0/0/0 · PMS Not specified C; `Black` #1A1A1A · RGB 26/26/26 · CMYK 0/0/0/95 · PMS Not specified C Secondary: `Yellow` #FFD700 · RGB 255/215/0 · CMYK 0/10/100/0 · PMS Not specified C ## Approved combinations > Some colors are not suitable to be used in combination with others. The following diagram demonstrates approved color combinations. - Black on white (fg #1A1A1A / bg #FFFFFF) - White on black (fg #FFFFFF / bg #1A1A1A) - Yellow on white — large graphic marks only, never text (fails contrast) (fg #FFD700 / bg #FFFFFF) - Yellow on black (fg #FFD700 / bg #1A1A1A) ## Semantic colour tokens - `primary` #FFD700 - `on-primary` #1A1A1A - `ink` #FFFFFF - `on-dark` #FFFFFF - `body` #FFFFFF - `body-soft` #FFFFFF - `muted` #FFFFFF - `canvas` #1A1A1A - `surface-raised` rgba(255,255,255,0.04) - `hairline` rgba(255,255,255,0.12) - `on-light` #1A1A1A - `light-canvas` #FFFFFF - `link` #FFD700 - `success` #5FB87A - `warning` #FFD700 - `error` #E0664E - `info` #7FB2D4 > `success` / `warning` / `error` / `info` are FUNCTIONAL status colours, not brand colours — semantic feedback only, never an accent or a fill. The accent is always `primary`. ## Typeface - Font: **Galton** (default weight 300, Sentence case) - Stack: `Galton, Montserrat, ui-sans-serif, system-ui, sans-serif` - File: https://galton-ai-assets.vercel.app/brand/fonts/GaltonVariable.woff2 (woff2-variations) - @font-face: @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%; } - Fallback: Montserrat (https://fonts.google.com/specimen/Montserrat) ## Type styles - `display-lg` 136px w300 lh1.05 - `display` 96px w300 lh1.1 - `headline` 64px w300 lh1.1 - `subhead` 30px w300 lh1.2 - `body` 18px w300 lh1.5 - `body-strong` 18px w500 lh1.4 - `eyebrow` 15px w500 lh1.4 - `button` 18px w600 lh1 - `label` 18px w300 lh1.4 - `badge` 15px w400 lh1 ## Components `button-yellow`, `button-primary`, `button-secondary`, `button-yellow-hover`, `button-primary-hover`, `button-secondary-hover`, `text-input`, `textarea`, `select`, `checkbox`, `text-link`, `eyebrow`, `badge`, `card`, `top-nav`, `footer`, `radio`, `toggle`, `toggle-on`, `slider-track`, `slider-fill`, `slider-thumb`, `stepper`, `stepper-button`, `search`, `tag`, `tag-active`, `tab`, `tab-active`, `breadcrumb`, `breadcrumb-current`, `pagination-item`, `pagination-item-active`, `menu`, `menu-item`, `modal`, `tooltip`, `accordion`, `accordion-content`, `alert`, `alert-success`, `alert-warning`, `alert-error`, `alert-info`, `progress-track`, `progress-fill`, `table`, `table-header`, `table-cell`, `side-nav`, `side-nav-item`, `side-nav-item-active`, `index-row`, `index-row-hover` ## Data visualization (read via get_chart_palette) Categorical series (in order): {colors.primary}, {colors.ink}, rgba(255,255,255,0.62), rgba(255,255,255,0.40), rgba(255,255,255,0.24) Sequential ramp: rgba(255,255,255,0.10) → rgba(255,255,255,0.40) → {colors.primary} Background {colors.canvas}; gridlines {colors.hairline}; axis {colors.muted}. - The default series colour is the single yellow accent; add white, then greys at opacity, for more series. - Never use a chart-library default palette (the rainbow), and never red/blue/green as decorative series colours. - Use `semantic` hues ONLY when the chart encodes good/bad (deltas, pass/fail) — otherwise stay in the categorical ramp. - Plot background is {colors.canvas}; gridlines are {colors.hairline}; axis ticks and labels are {colors.muted}. - One highlight per chart — set the series you want read first in yellow and keep the rest neutral. ## Fallback contract (read via get_fallback) > When something isn't defined here, resolve it from these primitives — never invent a colour, font, radius or shape. The brand accent is ALWAYS the yellow primary. Restraint — ink + greys + a single yellow accent — is always on-brand. - surface → {colors.canvas} - surfaceRaised → {colors.surface-raised} - ink → {colors.ink} - body → {colors.body} - muted → {colors.muted} - border → {colors.hairline} - accent → {colors.primary} - onAccent → {colors.on-primary} - focus → {colors.primary} - Accent: every highlighted / active / selected state, slider fill, toggle-on, link, focus ring and progress fill is {colors.primary} (yellow). NEVER red, blue, green or any other hue as an accent. - Surfaces: build any new panel from {colors.surface-raised} (white at low opacity) over {colors.canvas}. Never introduce a new hex. - Lines: borders, dividers, slider/track rules and table rules are {colors.hairline}. - Text: {colors.ink} for headings/strong, {colors.body} for running text, {colors.muted} for captions / placeholders / disabled. - Form controls: flat ({rounded.none}), transparent, bottom-border only; focus turns the border {colors.primary} — exactly like text-input. - Pills & buttons: {rounded.pill}, uppercase, Galton Bold. Content containers: {rounded.card}. - Status hues: success / warning / error / info come ONLY from `colors` and ONLY for genuine semantic feedback (validation, alerts, deltas) — never decoration, never an accent, never a fill. - Charts: use the `chart` palette (yellow + neutrals), never a chart-library default rainbow. - Type: one typeface (Galton Light, Sentence case); H1 / display headlines are UPPERCASE; uppercase elsewhere only for eyebrow, button and badge. - When in doubt, go monochrome with one yellow accent. If you still cannot resolve it on-brand, ASK THE HUMAN — do not guess. ## Rules (sections in the spec) - Overview - Colors - Typography - Elevation & Depth - Shapes - Components - Data visualization - Status & feedback colours - Fallbacks & unknown elements - Logo & Iconography - Do's and Don'ts - Responsive Behavior ## Assets - [Galton Variable](https://galton-ai-assets.vercel.app/brand/fonts/GaltonVariable.woff2): The web font — variable, covers every weight. Embed this and nothing else. - [Favicon 32](https://galton-ai-assets.vercel.app/brand/icons/galton-favicon-32x32.png): Browser-tab favicon. - [Favicon 192](https://galton-ai-assets.vercel.app/brand/icons/galton-favicon-192x192.png): Android / high-DPI. - [Apple touch](https://galton-ai-assets.vercel.app/brand/icons/galton-favicon-180x180.png): Apple touch icon (iOS home screen). ## Logo policy The logo is white or black ONLY — never the primary yellow or any other color. White on dark, black on light or on a yellow surface. Never recolor, rotate, stretch, add shadows/gradients, or re-typeset the wordmark. ## Verbal identity (brand voice) > Sebavedomý stratég s dušou tvorcu, ktorý hovorí veci na rovinu a baví ho to. **Stratég-Challenger** — Vedie, pýta sa „prečo“, reframuje problém, argumentuje dátami a skúsenosťou. Nerobí mechanicky to, čo klient povie, ak to nedáva zmysel.; **Partner pre vizionárov** — Hovorí s lídrami (C-level) ako rovný s rovným. Nikdy nie servisný dodávateľ čakajúci na zadanie.; **Sebavedomý, no bez ega** — Istota stojí na dátach a faktoch, nie na pozérstve. Dovolí si povedať „toto nevieme, zistíme to“.; **Odvážny tvorca** — Mení pravidlá hry, hľadá inakosť, dovolí si vtip a prekvapenie tam, kde to funguje.; **Ľudský a zodpovedný** — „Na konci dňa ide o ľudí.“ Hrdý na tím, empatický ku klientovi pod tlakom, zodpovedný za dlhodobý dopad. Do: Hovoríme na rovinu, krátko, bez prázdnych fráz. · Každé tvrdenie podložíme „prečo“ — dátami alebo skúsenosťou. · Oslovujeme priamo; klient je hrdina, my sme sprievodca. · Myslíme dlhodobo — budovanie, konzistencia, progres. · Dovolíme si vtip tam, kde funguje. · Priznáme, čo nevieme. · Sme partneri — povieme aj nepríjemnú pravdu. Don't: Žiadny hype a sľuby zázrakov („revolučný“, „zaručene“, „number one“). · Buzzwordy bez obsahu ani žargón bez vysvetlenia. · Neosobný, korporátne chladný tón. · Nesľubujeme rýchle zázraky ani jednorazové „opravy“. · Vtip v citlivých či krízových témach. · Nehráme sa na vševedúcich. · Nie sme servilní ani apologetickí. ### AI brief (paste into your AI tool before writing copy) Píš ako GALTON Brands — strategická brandingová agentúra. Hlas: sebavedomý stratég s dušou tvorcu, ktorý hovorí na rovinu. Si partner pre vizionárskych lídrov (C-level), nie dodávateľ. Veď, pýtaj sa „prečo“, argumentuj dátami; buď sebavedomý, ale priznaj, čo nevieš (bez ega). Píš krátko a jasne, striedaj úderné a vysvetľujúce vety, oslovuj priamo (vykanie). Najprv emócia a zmysel, potom dôkaz a fakty. Rámcuj: investícia (nie náklad), partnerstvo (nie projekt), dopad (nie výstup). Stoj na pilieroch: brand as business, budovanie zvnútra von, konzistencia v jadre + flexibilita v prejave, emócia pred racionalitou, dlhodobé partnerstvo, jedinečnosť a odvaha. Centrálna idea je jedinečnosť — výstup musí byť odvážny, unikátny a jasne rozpoznateľný. Registre podľa kontextu: konzultatívny (web/sales), edukačný/mentor (blog — mýtus→reframe, rečnícke otázky, listicles, svetové príklady, mäkké CTA), case-study (klient ako hrdina, dopad nie výstup), claimy/kampane (hravé, na antitéze či pun-e). Vyhýbaj sa: hype („zaručene/revolučné/number one“), buzzwordom, lacným urgenciám/FOMO vo vlastnom hlase, apologetickému aj arogantnému tónu, woke washingu. Nikdy neuvádzaj nepodložené čísla; externé štatistiky cituj so zdrojom. Origin story rámcuj okolo myšlienky odtlačku prsta a jedinečnosti, nie osoby Francisa Galtona. Píš primárne po slovensky; angličtinu používaj zámerne v claimoch, názvoch a odborných termínoch. Tón vždy partnerský, nikdy apologetický. Nepoužívaj „em dash“. Nepoužívaj vetnú konštrukciu „Nie X, ale Y“. Full verbal identity: https://galton-ai-assets.vercel.app/verbal-identity.md (alias: https://galton-ai-assets.vercel.app/voice.md) ## LinkedIn playbook - **Educational carousel** (`educational`) → recipe `educational-carousel` - **Single insight** (`insight`) → recipe `single-insight` - **Announcement** (`announcement`) → recipe `announcement` - **Event / speaker** (`event`) → recipe `event-post` - **Naming showcase** (`naming`) → recipe `naming-carousel` Full playbook: https://galton-ai-assets.vercel.app/linkedin.md ## Layout archetypes (reference for on-brand slides / carousels) Shared slide canvas (get_slide_canvas): 1080x1350, 64px padding, vertical-central Top/Bottom-block composition, Galton Light UPPERCASE headlines. - `cover` — Cover / title (1080x1350, 1080x1080) - `profile` — Profile / speaker card (1080x1350) - `concept` — Concept + supporting graphic (1080x1350, 1080x1080) - `statement` — Statement + centred graphic + CTA (1080x1350, 1080x1080) Carousel recipes (ordered layout sequences): `educational-carousel`=[cover → statement → concept → concept → statement]; `single-insight`=[statement]; `announcement`=[cover → statement]; `event-post`=[profile]; `naming-carousel`=[cover → statement → concept] These are reference knowledge, not a generator. Use list_layouts / get_layout (or the catalog above) to read each archetype's slot schema + example image, then recreate the slide on-brand in your own tool. The framework does not render or generate slides. ## Icons (optional, for layouts) - Line icons: tvorba-loga-identity-farby-typo, tvorba-loga-identity-vizualita, tvorba-loga-identity-logo, tvorba-loga-identity-sound, tvorba-webstranok-animacie, tvorba-webstranok-bezpecnost, tvorba-webstranok-dizajn, tvorba-webstranok-skalovatelnost, employer-branding-atraktivna-firemna-kultura, employer-branding-znizenie-nakladov, employer-branding-zvysenie-lojality, employer-branding-rychlejsi-hiring, employer-branding-zvysenie-brand-awareness, employer-branding-podpora-angazovanosti-timu, employer-branding-efektivnejsi-proces-hiringu, employer-branding-efektivnejsi-proces-hiringu-2, interna-komunikacia-zvysenie-angazovanosti, interna-komunikacia-znizenie-fluktuacie, interna-komunikacia-zvysenie-produktivity, interna-komunikacia-narast-inovacneho-potencialu, socialne-siete-report, socialne-siete-komunikacia, socialne-siete-komunita, socialne-siete-obsah, foto-video-produkcia-live-action-videa, foto-video-produkcia-postprodukcia, foto-video-produkcia-fotografie, foto-video-produkcia-animacie, content-marketing-podpora-predaja, content-marketing-zvysenie-konverzii, content-marketing-narast-zakaznikov, content-marketing-budovanie-dovery, marketing-advertising-report, marketing-advertising-media, marketing-advertising-meranie-efektivity, marketing-advertising-tvorba-strategie - 3D icons: magnifier, strategy, magnet, thumb-up, camera, bubbles, user-heart, pencil, vr, hand, thunder, tag, register, house, graph, horse-shoe ====================================================================== === DESIGN SPEC — design.md (tokens + rules, DESIGN.md format) ====================================================================== --- version: "1.7" name: galton-design-system description: >- A confident, editorial, high-contrast brand interface built dark-first on a near-black canvas (#1A1A1A) with white text and a single signature primary-yellow (#FFD700) used sparingly for emphasis. Everything is set in one typeface — Galton — at Light (300) weight in Sentence case, with Montserrat as the official substitute. Hierarchy comes from size and generous leading, not weight or uppercase shouting. The logo is white or black only — never colored. Components (buttons, forms, links, eyebrow, badge) are pill-and-flat, pill-shaped uppercase Bold buttons, flat bottom-border-only inputs with a yellow focus, and a strict palette with no invented shades. colors: primary: "#FFD700" # signature yellow — CTAs, highlights, focus, hero accent. Never a large fill. on-primary: "#1A1A1A" # text/icons on a yellow surface (always black) ink: "#FFFFFF" # primary text + headlines on dark on-dark: "#FFFFFF" # anything sitting on the dark canvas body: "#FFFFFF" # running body text — pure white, NO opacity body-soft: "#FFFFFF" # secondary paragraphs / leads — pure white muted: "#FFFFFF" # captions, labels, placeholders — pure white (no grey text) canvas: "#1A1A1A" # dark-first page floor (the brand default) surface-raised: "rgba(255,255,255,0.04)" # cards / raised panels — built from white at low opacity, never a new hex hairline: "rgba(255,255,255,0.12)" # 1px borders, dividers, table rows on-light: "#1A1A1A" # text/marks on a white/light surface light-canvas: "#FFFFFF" # light-surface floor (cards on light, print) link: "#FFD700" # hover/focus link color (signature yellow) # ── Functional UI colours — NOT brand colours ────────────────────────── # Status/feedback only: form validation, alerts, semantic chart deltas. These # are utilitarian, never expressive: never an accent, never decoration, never a # large fill. The brand accent is ALWAYS `primary` (yellow). They exist so an # agent has an on-brand status hue to reach for instead of inventing a garish # red/green (see the `fallback` contract). Tuned muted for the dark canvas. success: "#5FB87A" # muted green — positive / confirmation status only warning: "#FFD700" # = primary; caution / attention (the accent doubles here) error: "#E0664E" # muted clay-red — error / destructive status only info: "#7FB2D4" # muted slate-blue — neutral informational status only # Brand palette (per the official manual) — the actual brand colors, grouped. # `colors` above are the SEMANTIC ROLES that apply these; `palette` is the source. palette: primary: - { name: White, hex: "#FFFFFF", rgb: "255/255/255", cmyk: "0/0/0/0", pms: "Not specified C" } - { name: Black, hex: "#1A1A1A", rgb: "26/26/26", cmyk: "0/0/0/95", pms: "Not specified C" } secondary: - { name: Yellow, hex: "#FFD700", rgb: "255/215/0", cmyk: "0/10/100/0", pms: "Not specified C" } # Approved colour combinations — foreground on background. combinations: note: >- Some colors are not suitable to be used in combination with others. The following diagram demonstrates approved color combinations. approved: - { fg: "#1A1A1A", bg: "#FFFFFF", label: "Black on white" } - { fg: "#FFFFFF", bg: "#1A1A1A", label: "White on black" } - { fg: "#FFD700", bg: "#FFFFFF", label: "Yellow on white — large graphic marks only, never text (fails contrast)" } - { fg: "#FFD700", bg: "#1A1A1A", label: "Yellow on black" } # Data-visualization palette. Charts are dark-first: a `{colors.canvas}` plot # floor, `{colors.hairline}` gridlines, `{colors.muted}` axis labels. The # CATEGORICAL series ramp leads with the single yellow accent (the series you want # read first), then white and greys at descending opacity — it is NEVER a rainbow # or a chart-library default palette. Use the functional `semantic` hues ONLY when # the chart encodes good/bad (deltas, pass/fail). This block is the answer to # "what colours do I use in a chart" so an agent never invents red/blue/green. chart: background: "{colors.canvas}" grid: "{colors.hairline}" axis: "{colors.muted}" label: "{colors.body}" # Categorical series, in order. Cap meaningful categories at ~5; beyond that use # small multiples rather than more colours. categorical: - "{colors.primary}" # 1 — primary / highlight series (the signature accent) - "{colors.ink}" # 2 — white - "rgba(255,255,255,0.62)" # 3 - "rgba(255,255,255,0.40)" # 4 - "rgba(255,255,255,0.24)" # 5 # Sequential / intensity ramp (low → high). sequential: ["rgba(255,255,255,0.10)", "rgba(255,255,255,0.40)", "{colors.primary}"] # Semantic deltas — only when the chart literally means good vs bad. semantic: positive: "{colors.success}" negative: "{colors.error}" neutral: "{colors.muted}" rules: - The default series colour is the single yellow accent; add white, then greys at opacity, for more series. - Never use a chart-library default palette (the rainbow), and never red/blue/green as decorative series colours. - Use `semantic` hues ONLY when the chart encodes good/bad (deltas, pass/fail) — otherwise stay in the categorical ramp. - Plot background is {colors.canvas}; gridlines are {colors.hairline}; axis ticks and labels are {colors.muted}. - One highlight per chart — set the series you want read first in yellow and keep the rest neutral. # Typeface source — WHICH font to use and WHERE to load it from. The `typography` # tokens below carry the font stack; this block carries the files, the @font-face # and the fallback so an agent can actually embed the brand typeface. fonts: brand: family: Galton stack: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" defaultWeight: 300 case: Sentence case weights: "100 Thin · 300 Light (default) · 400 Regular · 500 Medium · 600 Bold · 700 Extrabold · 800 Black" baseUrl: "https://galton-ai-assets.vercel.app/brand/" files: - { weight: "100–900", file: "fonts/GaltonVariable.woff2", format: "woff2-variations", note: "the single web font — variable, covers every weight" } fontFace: |- @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%; } fallback: family: Montserrat source: Google Fonts url: "https://fonts.google.com/specimen/Montserrat" note: "Official substitute wherever Galton can't be embedded; last in the stack." # Leading + hierarchy reference. The RATIO is the rule (leading = size × ratio); # the point sizes are examples only. Keep leading consistent across applications. typeScale: note: >- When setting type, the leading should be consistent across applications. Leading refers to the space between lines of text. Leading = type size × ratio. hierarchyNote: >- 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. levels: - { name: Headline, plural: Headlines, font: "Galton Light", case: "UPPERCASE", size: 80, leading: 88, ratio: 1.1 } - { name: Subhead, plural: Subheads, font: "Galton Light", case: "Sentence case", size: 30, leading: 36, ratio: 1.2 } - { name: Body, plural: "Body copy", font: "Galton Light", case: "Sentence case", size: 18, leading: 27, ratio: 1.5 } typography: display-lg: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 136px # responsive 56 -> 88 -> 136 -> 180 fontWeight: 300 lineHeight: 1.05 letterSpacing: 0 display: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 96px # responsive 48 -> 72 -> 96 -> 120 fontWeight: 300 lineHeight: 1.1 letterSpacing: 0 headline: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 64px # responsive 40 -> 52 -> 64 -> 80 fontWeight: 300 lineHeight: 1.1 letterSpacing: 0 subhead: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 30px # responsive 22 -> 24 -> 30 fontWeight: 300 lineHeight: 1.2 letterSpacing: 0 body: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 18px # web/body minimum — reading text is never below 18px fontWeight: 300 lineHeight: 1.5 letterSpacing: 0 body-strong: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 18px fontWeight: 500 lineHeight: 1.4 letterSpacing: 0 eyebrow: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 15px # section label — the uppercase overline above headlines fontWeight: 500 lineHeight: 1.4 letterSpacing: 3.3px # 0.22em — uppercase button: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 18px # web/body minimum — button labels are never below 18px fontWeight: 600 # Galton Bold (the live site's `.btn` weight — Galton-Bold = 600) lineHeight: 1 letterSpacing: 0 # uppercase, no extra tracking label: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 18px # form labels (1.125rem -> 1.5rem) fontWeight: 300 lineHeight: 1.4 letterSpacing: 0 badge: fontFamily: "Galton, Montserrat, ui-sans-serif, system-ui, sans-serif" fontSize: 15px # the global minimum size — nothing renders below 15px fontWeight: 400 lineHeight: 1 letterSpacing: 1.2px # 0.08em — uppercase rounded: none: 0px # inputs, selects — always flat component: 10px # small UI elements card: 20px # standard card / media container card-lg: 28px # large panel / select dropdown (galton.sk) pill: 100px # buttons, tags, chips # ── THE FALLBACK CONTRACT ────────────────────────────────────────────── # Read this whenever you meet an element, component, state or colour this system # does not explicitly define. Do NOT invent values — DERIVE them from these # primitives. This is the single rule that stops off-brand output: an undefined # slider must not become a red slider, an unknown chip must not become a red chip. # `colors`/`radius` are the primitives to fall back to; `protocol` is the order of # operations. Exposed to agents via the get_fallback MCP tool and /brand.json. fallback: note: >- When something isn't defined here, resolve it from these primitives — never invent a colour, font, radius or shape. The brand accent is ALWAYS the yellow primary. Restraint — ink + greys + a single yellow accent — is always on-brand. colors: surface: "{colors.canvas}" surfaceRaised: "{colors.surface-raised}" ink: "{colors.ink}" body: "{colors.body}" muted: "{colors.muted}" border: "{colors.hairline}" accent: "{colors.primary}" onAccent: "{colors.on-primary}" focus: "{colors.primary}" radius: control: "{rounded.none}" pill: "{rounded.pill}" container: "{rounded.card}" protocol: - "Accent: every highlighted / active / selected state, slider fill, toggle-on, link, focus ring and progress fill is {colors.primary} (yellow). NEVER red, blue, green or any other hue as an accent." - "Surfaces: build any new panel from {colors.surface-raised} (white at low opacity) over {colors.canvas}. Never introduce a new hex." - "Lines: borders, dividers, slider/track rules and table rules are {colors.hairline}." - "Text: {colors.ink} for headings/strong, {colors.body} for running text, {colors.muted} for captions / placeholders / disabled." - "Form controls: flat ({rounded.none}), transparent, bottom-border only; focus turns the border {colors.primary} — exactly like text-input." - "Pills & buttons: {rounded.pill}, uppercase, Galton Bold. Content containers: {rounded.card}." - "Status hues: success / warning / error / info come ONLY from `colors` and ONLY for genuine semantic feedback (validation, alerts, deltas) — never decoration, never an accent, never a fill." - "Charts: use the `chart` palette (yellow + neutrals), never a chart-library default rainbow." - "Type: one typeface (Galton Light, Sentence case); H1 / display headlines are UPPERCASE; uppercase elsewhere only for eyebrow, button and badge." - "When in doubt, go monochrome with one yellow accent. If you still cannot resolve it on-brand, ASK THE HUMAN — do not guess." components: button-yellow: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" typography: "{typography.button}" rounded: "{rounded.pill}" padding: "15px 30px" border: "1px solid {colors.canvas}" button-primary: backgroundColor: "{colors.ink}" textColor: "{colors.on-primary}" typography: "{typography.button}" rounded: "{rounded.pill}" padding: "15px 30px" border: "1px solid {colors.canvas}" button-secondary: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.button}" rounded: "{rounded.pill}" padding: "15px 30px" border: "1px solid {colors.ink}" # Hover states (the spec pairs `-hover` with its base). button-yellow-hover: backgroundColor: "{colors.canvas}" textColor: "{colors.ink}" border: "1px solid {colors.ink}" button-primary-hover: backgroundColor: "{colors.canvas}" textColor: "{colors.ink}" border: "1px solid {colors.ink}" button-secondary-hover: backgroundColor: "{colors.ink}" textColor: "{colors.on-primary}" border: "1px solid {colors.ink}" text-input: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.body}" rounded: "{rounded.none}" padding: "0" height: 53px border: "0 0 1px 0 solid {colors.ink}" textarea: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.body}" rounded: "{rounded.none}" padding: "12px 0" height: 120px border: "0 0 1px 0 solid {colors.hairline}" select: backgroundColor: transparent textColor: "{colors.muted}" typography: "{typography.label}" rounded: "{rounded.none}" padding: "0 30px 0 0" height: 53px border: "0 0 1px 0 solid {colors.ink}" checkbox: backgroundColor: transparent textColor: "{colors.ink}" rounded: "{rounded.none}" size: 30px border: "1px solid {colors.ink}" text-link: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.body}" eyebrow: backgroundColor: transparent textColor: "{colors.primary}" typography: "{typography.eyebrow}" badge: backgroundColor: transparent textColor: "{colors.muted}" typography: "{typography.badge}" rounded: "{rounded.pill}" padding: "5.6px 13.6px" border: "1px solid {colors.hairline}" card: backgroundColor: "{colors.surface-raised}" textColor: "{colors.ink}" rounded: "{rounded.card}" padding: "28px" border: "1px solid {colors.hairline}" top-nav: backgroundColor: "{colors.canvas}" textColor: "{colors.ink}" typography: "{typography.body}" height: 56px border: "none" footer: backgroundColor: "{colors.canvas}" textColor: "{colors.muted}" typography: "{typography.body}" padding: "72px" border: "none" # ── Selection controls ──────────────────────────────────────────────── # radio is the round sibling of `checkbox`; both fill with a white mark on select. radio: backgroundColor: transparent textColor: "{colors.ink}" rounded: "{rounded.pill}" size: 30px border: "1px solid {colors.ink}" toggle: backgroundColor: "{colors.hairline}" # OFF track textColor: "{colors.ink}" rounded: "{rounded.pill}" width: 52px height: 30px border: "1px solid {colors.hairline}" toggle-on: backgroundColor: "{colors.primary}" # ON track — small accent fill (allowed) border: "1px solid {colors.primary}" # Slider / range — the FILLED portion is the yellow accent; never red. slider-track: backgroundColor: "{colors.hairline}" rounded: "{rounded.pill}" height: 4px slider-fill: backgroundColor: "{colors.primary}" rounded: "{rounded.pill}" height: 4px slider-thumb: backgroundColor: "{colors.ink}" rounded: "{rounded.pill}" size: 18px border: "1px solid {colors.canvas}" # ── Text entry (beyond the base form set) ───────────────────────────── # stepper = numeric input with −/+ controls; field stays flat like text-input. stepper: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.body}" rounded: "{rounded.none}" height: 53px border: "0 0 1px 0 solid {colors.ink}" stepper-button: backgroundColor: transparent textColor: "{colors.muted}" rounded: "{rounded.component}" size: 30px border: "1px solid {colors.hairline}" search: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.body}" rounded: "{rounded.none}" height: 53px padding: "0 0 0 32px" # room for the leading search icon border: "0 0 1px 0 solid {colors.ink}" # ── Tags / chips (interactive, removable) ───────────────────────────── # Distinct from `badge` (badge is static meta). A selected filter chip goes # ink-filled — NOT yellow, NOT red (yellow stays the single CTA accent). tag: backgroundColor: "{colors.surface-raised}" textColor: "{colors.ink}" typography: "{typography.badge}" rounded: "{rounded.pill}" padding: "6px 12px" border: "1px solid {colors.hairline}" tag-active: backgroundColor: "{colors.ink}" textColor: "{colors.on-light}" border: "1px solid {colors.ink}" # ── Tabs ────────────────────────────────────────────────────────────── tab: backgroundColor: transparent textColor: "{colors.muted}" typography: "{typography.body}" rounded: "{rounded.none}" padding: "0 0 12px" border: "0 0 1px 0 solid {colors.hairline}" tab-active: textColor: "{colors.ink}" border: "0 0 2px 0 solid {colors.primary}" # active underline = accent # ── Breadcrumbs ─────────────────────────────────────────────────────── breadcrumb: backgroundColor: transparent textColor: "{colors.muted}" typography: "{typography.body}" breadcrumb-current: textColor: "{colors.ink}" # ── Pagination ──────────────────────────────────────────────────────── pagination-item: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.body}" rounded: "{rounded.pill}" size: 44px border: "1px solid {colors.hairline}" pagination-item-active: backgroundColor: "{colors.ink}" textColor: "{colors.on-light}" border: "1px solid {colors.ink}" # ── Menus / dropdowns (popover; distinct from the native `select`) ───── menu: backgroundColor: "{colors.surface-raised}" textColor: "{colors.ink}" rounded: "{rounded.component}" padding: "8px" border: "1px solid {colors.hairline}" menu-item: backgroundColor: transparent textColor: "{colors.body}" typography: "{typography.body}" rounded: "{rounded.component}" padding: "10px 14px" # ── Modal / dialog (sits on a {colors.canvas} @ ~70% scrim) ──────────── modal: backgroundColor: "{colors.surface-raised}" textColor: "{colors.ink}" rounded: "{rounded.card}" padding: "32px" border: "1px solid {colors.hairline}" # ── Tooltip — inverted for high contrast over the dark canvas ────────── tooltip: backgroundColor: "{colors.ink}" textColor: "{colors.on-light}" typography: "{typography.badge}" rounded: "{rounded.component}" padding: "6px 10px" # ── Accordion / FAQ (replicated from galton.sk) ─────────────────────── # A stack of rows divided by hairlines; each header is a question with a chevron # that rotates 180° on open. Single-open by default. The token carries the row # (header divider + title type); the open/closed animation + chevron live in CSS. accordion: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.subhead}" # the question title — Galton Light rounded: "{rounded.none}" padding: "24px 0" # vertical rhythm of the header row border: "0 0 1px 0 solid {colors.hairline}" # divider between items accordion-content: backgroundColor: transparent textColor: "{colors.body}" typography: "{typography.body}" padding: "0 0 24px" # ── Alerts / notifications ──────────────────────────────────────────── # Neutral surface + hairline; the status colour appears ONLY as a 3px left rule # and the icon — never as a fill. Variants override that left border. alert: backgroundColor: "{colors.surface-raised}" textColor: "{colors.body}" rounded: "{rounded.card}" padding: "16px 20px" border: "1px solid {colors.hairline}" alert-success: border: "0 0 0 3px solid {colors.success}" alert-warning: border: "0 0 0 3px solid {colors.warning}" alert-error: border: "0 0 0 3px solid {colors.error}" alert-info: border: "0 0 0 3px solid {colors.info}" # ── Progress ────────────────────────────────────────────────────────── progress-track: backgroundColor: "{colors.hairline}" rounded: "{rounded.pill}" height: 6px progress-fill: backgroundColor: "{colors.primary}" # the fill is the accent — never red rounded: "{rounded.pill}" height: 6px # ── Tables ──────────────────────────────────────────────────────────── table: backgroundColor: transparent textColor: "{colors.body}" rounded: "{rounded.card}" border: "1px solid {colors.hairline}" table-header: backgroundColor: "{colors.surface-raised}" textColor: "{colors.muted}" typography: "{typography.badge}" border: "0 0 1px 0 solid {colors.hairline}" table-cell: backgroundColor: transparent textColor: "{colors.body}" typography: "{typography.body}" border: "0 0 1px 0 solid {colors.hairline}" # ── Side navigation (vertical nav / app shell) ──────────────────────── side-nav: backgroundColor: transparent textColor: "{colors.body}" rounded: "{rounded.none}" border: "0 1px 0 0 solid {colors.hairline}" side-nav-item: backgroundColor: transparent textColor: "{colors.muted}" typography: "{typography.body}" rounded: "{rounded.component}" padding: "10px 14px" side-nav-item-active: backgroundColor: "{colors.surface-raised}" textColor: "{colors.ink}" border: "0 0 0 2px solid {colors.primary}" # active marker = accent rule # ── Index row ───────────────────────────────────────────────────────── # A large editorial line-item for indexes, menus and directories (optional # oversized number + uppercase title + optional blurb + trailing icon). On # hover the WHOLE row fills with the accent and inverts to black — the brand's # one-accent-per-view rule applied to a list. Drives the homepage index. index-row: backgroundColor: transparent textColor: "{colors.ink}" typography: "{typography.display}" padding: "32px 28px" border: "0 0 1px 0 solid {colors.hairline}" index-row-hover: backgroundColor: "{colors.primary}" textColor: "{colors.on-primary}" # How the component library is presented & exercised on the front end. The token # values live in `components` above; this groups them into sub-sections and adds # rendering hints (labels, placeholders, options) so the showcase can render real, # interactive examples. `-hover` token entries drive the live hover states. componentGroups: - id: buttons title: Buttons description: >- Pill, UPPERCASE, Galton Bold (600), symmetric padding. Three variants; hover inverts toward the canvas. Use for submit / save / buy / continue / cancel. Labels centre correctly because the @font-face pins Galton's vertical metrics (no per-button padding nudge needed). kind: button items: [button-yellow, button-primary, button-secondary] - id: inputs title: Text fields & inputs description: >- Dark-first: transparent, flat (radius 0), bottom-border only; focus turns the border the signature yellow. For names, emails, passwords, search and numbers. items: - { name: text-input, kind: input, label: Email, placeholder: "you@brand.com", inputType: email } - { name: textarea, kind: textarea, label: Message, placeholder: "Tell us about the project…" } - { name: select, kind: select, label: Service, options: [Branding, Marketing, Web design, Other] } - { name: search, kind: search, label: Search, placeholder: "Search…" } - { name: stepper, kind: stepper, label: Quantity, value: 25 } - id: selection title: Selection controls description: >- Checkbox (square) and radio (round) fill with a white mark on select; the toggle's ON track and the slider's filled range are the yellow accent — never red or green. Single-choice, multi-choice, on/off, and ranges. items: - { name: checkbox, kind: checkbox, label: "I agree to the privacy policy" } - { name: radio, kind: radio, label: Billing, options: [Monthly, Yearly] } - { name: toggle, kind: toggle, label: "Email notifications" } - { name: slider, kind: slider, label: Budget, value: 60 } - id: tags title: Tags, chips & multi-select description: >- Interactive filter chips — distinct from the static badge. A selected chip goes ink-filled (white on black); the brand never tints a chip red. The × removes it. items: - { name: tag, kind: tag, options: [Bratislava, Žilina, Nitra, Trnava, Košice] } - id: navigation title: Tabs, breadcrumbs & pagination description: >- In-page navigation. The active tab carries a yellow underline; the current breadcrumb segment and the current page are ink, everything else muted. items: - { name: tab, kind: tabs, options: [Overview, Activity, Settings] } - { name: breadcrumb, kind: breadcrumb, options: [Home, Services, Branding] } - { name: pagination-item, kind: pagination } - id: header-footer title: Header & footer description: >- The two persistent pieces of the page chrome. The header is a sticky bar with a blurred canvas backdrop and no border: the white wordmark lockup (with the ® + BRANDS tagline) at left, the nav links at right, no button. The footer is the canvas with a hairline top border: the big lockup centered over the copy lines. Both use the lockup white-on-dark, and neither ever inverts. items: - { name: top-nav, kind: nav, options: [Foundations, Components, Verbal identity, Layouts] } - { name: footer, kind: nav } - id: side-nav title: Side navigation description: >- A vertical in-app nav with a hairline right edge. Items are muted, brightening to ink on hover; the active item carries a 2px yellow left rule on a raised row. Pair it with the header for an app shell; collapse to a hamburger on mobile. items: - { name: side-nav, kind: sidenav, options: [Dashboard, Projects, Reports, Settings] } - id: overlays title: Menus, modals & tooltips description: >- Raised surfaces over the canvas — a dropdown menu, a dialog on a dimmed scrim, and the inverted (black-on-white) tooltip for high contrast on dark content. items: - { name: menu, kind: menu, options: [Edit, Duplicate, Archive] } - { name: modal, kind: modal } - { name: tooltip, kind: tooltip } - id: disclosure title: Accordion & FAQ description: >- Replicated from galton.sk: a stack of rows divided by hairlines, each a question with a chevron that rotates 180° on open. Single-open — opening one closes the rest. For FAQs, long-form Q&A and progressive disclosure of dense content. kind: accordion items: - { name: accordion, kind: accordion } - id: feedback title: Alerts, progress & badges description: >- System feedback: success / info / warning / error. Alerts are neutral surfaces with a 3px status rule + icon — the status hue is never a fill. Progress fills in the yellow accent. items: - { name: alert, kind: alert } - { name: progress-track, kind: progress, value: 64 } - { name: badge, kind: badge } - id: data title: Tables description: "Structured data, admin panels and reports: a muted uppercase header on a raised row, hairline row rules, body at 18px." items: - { name: table, kind: table } - id: cards title: Cards & surfaces description: >- Raised from white at low opacity over the canvas, hairline border, 20px radius — no drop shadows. Depth comes from contrast, not material elevation. items: - { name: card, kind: card } - id: labels title: Links & eyebrow description: "Small text utilities. Links hover to yellow; the eyebrow is the uppercase overline above headlines." items: - { name: text-link, kind: link } - { name: eyebrow, kind: eyebrow } - id: index-rows title: Index rows description: >- A large editorial line-item for indexes, section menus and directories: an optional oversized number, an uppercase title, an optional blurb and a trailing icon. On hover the whole row fills with the yellow accent in a single left-to-right wipe and the content inverts to black — the brand's one-accent-per-view rule applied to a list. This is the homepage "Explore the system" pattern, reusable anywhere a prominent list of destinations is needed. kind: index-row items: - { name: index-row, kind: index-row } # Ready-to-use agent prompts. Deliberately value-free — they describe intent and # reference roles ("the signature accent", "the display headline") so the agent # resolves exact colours, type and components from this spec. `{{brand}}` is filled # with the brand name at render time, so this stays universal across brands. agentPrompts: prompts: - title: Landing hero prompt: >- Build an on-brand {{brand}} hero. Dark-first canvas; a large display headline in Sentence case with the final word in the signature accent; a short body lead beneath; and the primary call-to-action button. Place the wordmark top-left. Pull every colour, type size and component from the design system — don't invent values. - title: Contact form prompt: >- Create an on-brand contact form. Stack labelled fields — a text input, a select and a textarea — then a consent checkbox and the primary CTA. Use the form component tokens: flat fields, bottom-border only, focus in the accent. Keep it dark-first. - title: Full landing page prompt: >- Compose a full {{brand}} landing page: a hero, two or three content sections and a footer. Use the design system's type scale, spacing rhythm and components throughout; keep the dark-first canvas and reserve the accent for emphasis. Pull every value from the spec — don't invent any. - title: Rebrand a page prompt: >- Restyle this page to match {{brand}}. Map every colour, font and component to the design system's tokens and replace ad-hoc values with the brand's. Keep the logo white or black only. - title: Dashboard / data UI prompt: >- Build an on-brand {{brand}} dashboard. Dark-first canvas; a side-nav, cards, a data table, and form controls (sliders, toggles, steppers, multi-select chips). Every interactive/selected state — slider fill, toggle-on, active chip, focus ring — is the single yellow accent; never red, blue or green. Pull every value from the design system; for anything undefined, follow the fallback contract. - title: Chart / data visualization prompt: >- Build an on-brand chart. Use the `chart` palette: a {{brand}} canvas plot floor, hairline gridlines, muted axis labels, and the categorical series ramp (yellow highlight first, then white and greys at opacity). Never use a chart library's default rainbow; use the semantic good/bad hues only for real deltas. rules: - Describe intent and structure; let the agent resolve exact values from the spec. - Reference roles — "primary CTA", "the accent", "display headline" — not hex codes. - Keep the logo white or black only; never recolour it. - Don't use the accent as a large fill, and never uppercase body copy (H1/display is the only uppercase headline). - The accent is ALWAYS the yellow primary. Never introduce red, blue or green as an accent, selected state, slider fill, link or focus ring. - Never invent a colour, font, radius or component. If it isn't defined, read the `fallback` contract and derive it from the primitives — or ask the human. - Status hues (success/warning/error/info) are functional only — semantic feedback, never decoration or a brand accent. - In charts, use the `chart` palette (yellow + neutrals), not a library-default rainbow. --- ## Overview GALTON Brands is a **dark-first**, editorial, high-contrast brand system. The page floor is a near-black canvas (`{colors.canvas}` — #1A1A1A), text is white (`{colors.ink}`), and a single signature **primary yellow** (`{colors.primary}` — #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 (`{colors.on-primary}`). Everything is set in **one typeface — Galton** — at **Light (300)** in **Sentence case**. Weight steps up to Medium (500) / Bold (600) 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 (`{rounded.pill}`), uppercase, Galton Bold; inputs are **flat** (`{rounded.none}`), 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 (`{colors.surface-raised}`), 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 `fallback` block): > 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. ## Colors ### 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 (`{colors.ink}`) on dark, near-black (`{colors.on-light}`) 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 — `{colors.hairline}` dividers and `{colors.surface-raised}` panels — is derived from white at low opacity, never a new brand colour. ### Surface - **Canvas** (`{colors.canvas}` — #1A1A1A): The default page floor on every dark surface. The brand is dark-first. - **Surface Raised** (`{colors.surface-raised}` — white @4%): Cards, modals, raised panels. Built from white at low opacity over the canvas — never a new hex. Pair with a `{colors.hairline}` border. - **Hairline** (`{colors.hairline}` — white @12%): 1px dividers, table rows, card outlines, the top/bottom bars. - **Light Canvas** (`{colors.light-canvas}` — #FFFFFF): The floor for light surfaces (cards on light, print, email). ### Text - **Ink / On Dark** (`{colors.ink}` — #FFFFFF): Headlines and primary text on the dark canvas. - **Body** (`{colors.body}` — #FFFFFF): Running body text — pure white, no opacity. - **Body Soft** (`{colors.body-soft}` — #FFFFFF): Secondary paragraphs and section leads — also pure white. - **Muted** (`{colors.muted}` — #FFFFFF): Captions, metadata, placeholders, disabled labels — pure white (no grey text). Dividers and borders use `{colors.hairline}`, not a grey text colour. - **On Light** (`{colors.on-light}` — #1A1A1A): Text and marks on a white/light surface. ### Usage Rules - Default page = `{colors.canvas}` background, `{colors.ink}` text. - `{colors.primary}` is 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 (`{colors.surface-raised}`) — do not introduce a new hex. - Selection highlight is primary-on-black. ## Typography ### 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-face` works. 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. ```css @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 `*-override` lines 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-face` > exactly 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/600) — 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. ## Elevation & Depth | Level | Treatment | Use | |---|---|---| | Flat | No shadow, no border | Body, top nav, footer, most sections | | Hairline | 1px `{colors.hairline}` border | Section dividers, table rows, card outlines | | Raised surface | `{colors.surface-raised}` (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. ## Shapes ### Border Radius Scale | Token | Value | Use | |---|---|---| | `{rounded.none}` | 0px | Inputs, textareas, selects, checkboxes — always flat | | `{rounded.component}` | 10px | Small UI elements | | `{rounded.card}` | 20px | Standard card / media container — the signature radius (galton.sk uses 20px on nearly every card, image and media block) | | `{rounded.card-lg}` | 28px | Large panel / floating select dropdown (galton.sk `.nice-select-dropdown`) | | `{rounded.pill}` | 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. ## Components > Interaction note: buttons and inputs use a standard `ease` over ~300–600ms. Hover states are described in prose; default (and focus) states are the source of truth in the YAML. ### Top Navigation **`top-nav`** — A sticky bar on `{colors.canvas}` with a blurred backdrop and **no border** (galton.sk's header separates by the blur alone — no rule): the canvas at ~70% opacity behind a `blur(16px)`, with **35px** vertical padding (15px on mobile). Carries the **white wordmark lockup** — the full mark with the ® and the letter-spaced BRANDS tagline (`galton-wordmark-white-tagline-tight.png`, ~46px tall) — at left, and the nav links at right. **No button lives in the persistent nav** — keep `{component.button-yellow}` (and any outline CTA) for the in-page calls to action (hero, forms). Links are **22px, weight 300, `{colors.ink}`** with a **45px** gap, brightening to `{colors.primary}` (the accent) on hover; the lockup never recolours (white or black only). Below ~1400px the links collapse to a hamburger that opens a full-screen overlay. ### Logo lockup The **GALTON wordmark** with a superscript ® and a letter-spaced "BRANDS" tagline beneath — this is the lockup the header and footer carry (`galton-wordmark-white-tagline-tight.png`, white-on-dark; a black-on-light twin exists for inverted surfaces). The wordmark on its own ships as a `fill="currentColor"` SVG. **White or black only** — the lockup never turns yellow, even on hover. See "Logo & Iconography". ### Buttons All buttons: pill (`{rounded.pill}`), UPPERCASE, Galton Bold (`{typography.button}`), `inline-flex` centered, **symmetric** padding (`15px 30px` desktop), border `1px solid`, transition `all 0.5s ease`. Labels sit dead-centre because the `@font-face` pins Galton's vertical metrics (see Typography → "Why the three `*-override` lines matter") — **do not** re-introduce an asymmetric "less padding at the bottom" hack; that was a workaround for the un-corrected webfont and is no longer needed. Responsive padding follows the live site: mobile `10px 25px` · ≤991px `12px 20px` · desktop `15px 30px`. - **`button-yellow`** — The signature CTA (galton.sk `.btn-yellow`). `{colors.primary}` background, `{colors.on-primary}` text, `{colors.canvas}` border. Hover → `{colors.canvas}` background, `{colors.ink}` text, `{colors.ink}` border. - **`button-primary`** — A solid light button (galton.sk `.btn-primary`). `{colors.ink}` background, `{colors.on-primary}` text, `{colors.canvas}` border. Hover → `{colors.canvas}` background, `{colors.ink}` text, `{colors.ink}` border. - **`button-secondary`** — The outline/ghost pill on dark (galton.sk `.btn-transparent-white`): transparent with a `{colors.ink}` border and text. Hover → `{colors.ink}` background, `{colors.on-primary}` text. On a dark canvas this is also how the source's solid `.btn-secondary` (dark fill + white border) reads, so the two collapse into this one token. > **Source mapping (galton.sk).** The WordPress theme defines five pill variants on a *light* page; this dark-first system realises the same set with three tokens. `btn-yellow → button-yellow`, `btn-primary → button-primary`, and both `btn-secondary` (solid dark) and `btn-transparent-white` (transparent) → `button-secondary` (they're visually identical on the `{colors.canvas}` floor). The fifth, `btn-transparent` (black border + text, hover → yellow text), is a **light-surface-only** outline — on light, override `button-secondary`'s white border/text to `{colors.on-light}`, exactly as the form note describes. ### Inputs & Forms Dark-first: transparent background, bottom-border only, primary-yellow focus. On light surfaces, override the white border/text to black. - **`text-input`** — Flat (`{rounded.none}`), transparent, `{colors.ink}` bottom border, height 53px, `{typography.body}`/300, placeholder `{colors.muted}`. Focus → border `{colors.primary}`. - **`textarea`** — Flat, hairline (`{colors.hairline}`) bottom border, min-height 120px, vertically resizable. Focus → `{colors.primary}`. - **`select`** — Flat, `{colors.ink}` bottom border, height 53px, `appearance: none`. The native arrow is replaced by the brand chevron (grey "V") at the right, padding-right 30px, weight 300, `{colors.muted}` text. Focus → `{colors.primary}`. (Sourced from the galton.sk contact form.) - **`checkbox`** — Flat square (`{rounded.none}`), `{colors.ink}` border, 30px → 45px@1024, fills with a white square on `:checked`, focus → `{colors.primary}`. Pair with a label in `{typography.body}`/300 inside a flex `form-check` row. - **`label`** — `{typography.label}` (Galton Light), `{colors.ink}`, block, 8px bottom margin. ### Links, Eyebrow & Badge - **`text-link`** — `color: inherit`, no underline, hover/focus → `{colors.link}` (primary). Transition `color 0.3s ease`. - **`eyebrow`** — Small uppercase label above headlines: `{typography.eyebrow}`, `{colors.primary}`. - **`badge`** — Neutral pill chip for meta/status/version on dark: `{typography.badge}`, `{colors.muted}`, `{colors.hairline}` border, `{rounded.pill}`. ### Cards & Containers **`card`** — `{colors.surface-raised}` background, `{colors.hairline}` border, `{rounded.card}` (20px), ~28px padding, no drop shadow. (Detailed card patterns are not yet fully specified — see Known Gaps.) ### Footer **`footer`** — `{colors.canvas}` with a `{colors.hairline}` top border, everything centered: the **white wordmark lockup big** (~80px tall) above two copy lines in **`{colors.ink}` at 18px** — the © line and the brand/website line. ~80px vertical padding. The footer never inverts. ### Selection controls The choice family shares the flat, dark-first language. The accent (`{colors.primary}`) marks the *chosen* state — never red or green. - **`checkbox`** — Flat square (`{rounded.none}`), `{colors.ink}` border, 30px; fills with a white square on `:checked`. Multi-choice, consent, filters. - **`radio`** — The round sibling: a circle (`{rounded.pill}`), `{colors.ink}` border, 30px; fills with a white dot on select. Single-choice from a set. - **`toggle`** / **`toggle-on`** — A 52×30 pill switch. OFF = `{colors.hairline}` track; ON = `{colors.primary}` track (`toggle-on`) with a white knob. On/off preferences and settings. - **`slider-track`** / **`slider-fill`** / **`slider-thumb`** — A 4px `{colors.hairline}` track; the **filled portion is `{colors.primary}`** (yellow, never red); a 18px white thumb. Ranges, budgets, percentages. ### Steppers & search - **`stepper`** — A numeric input with `−`/`+` controls (`stepper-button`: ghost, `{colors.hairline}` border, `{rounded.component}`). The field stays flat (bottom-border only) like `text-input`. Quantities, counts. - **`search`** — A flat bottom-border input with a leading search icon (32px left padding). Focus → `{colors.primary}`. In content-heavy chrome a `{rounded.pill}` contained variant is allowed. ### Tags, chips & multi-select - **`tag`** — An interactive, removable filter chip: `{rounded.pill}`, `{colors.surface-raised}` background, `{colors.hairline}` border, `{colors.ink}` text, a muted `×`. Distinct from the static `badge`. - **`tag-active`** — The selected state goes **ink-filled** (white background, black text) — **never tinted red/green**. A multi-select is a row of tags plus the input. ### Tabs, breadcrumbs & pagination - **`tab`** / **`tab-active`** — Underline tabs. Inactive = `{colors.muted}` with a `{colors.hairline}` rule; **active = `{colors.ink}` text with a 2px `{colors.primary}` underline**. Switch sections without leaving the page. - **`breadcrumb`** / **`breadcrumb-current`** — Muted segments separated by a chevron; the current page is `{colors.ink}`. Shows position in a hierarchy. - **`pagination-item`** / **`pagination-item-active`** — 44px pill buttons, `{colors.hairline}` border; the current page is **ink-filled** (not yellow — yellow stays the single CTA). For lists, search results and feeds. ### Menus, modals & tooltips - **`menu`** / **`menu-item`** — A dropdown/popover panel: `{colors.surface-raised}`, `{colors.hairline}` border, `{rounded.component}`; items hover to a raised row. An *actions* menu, distinct from the native `select`. - **`modal`** — A dialog panel: `{colors.surface-raised}`, `{colors.hairline}` border, `{rounded.card}`, 32px padding, over a `{colors.canvas}`-at-~70% scrim. Confirmations, forms, prompts. No drop shadow. - **`tooltip`** — **Inverted** for contrast over dark content: `{colors.ink}` (white) background, `{colors.on-light}` (black) text, `{rounded.component}`, badge-size text. Short hover/tap explanations. ### Accordion & FAQ **`accordion`** / **`accordion-content`** — Replicated from galton.sk. A vertical stack of rows divided by `{colors.hairline}` rules (no card, no fill); each header is a question in `{typography.subhead}` (Galton Light) with a **chevron that rotates 180°** when open, tinting to `{colors.primary}`. **Single-open** by default — opening one row closes the rest (match the source). The body (`accordion-content`) is `{typography.body}`. Height animates open/closed (~0.3s); the header is a real `