algorithmic-color-pale…
Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building…
Ratio-based type scale where every size relates to the others. Use when defining font sizes or type tokens, or when typography feels arbitrary.
Claude Code
$ npx -y skills add dembrandt/dembrandt-skills --skill modular-scale-typography --agent claude-code
Codex
$ npx skills add dembrandt/dembrandt-skills --skill modular-scale-typography -a codex -y
Cursor
$ npx skills add dembrandt/dembrandt-skills --skill modular-scale-typography -a cursor -y
Gemini CLI
$ npx skills add dembrandt/dembrandt-skills --skill modular-scale-typography -a gemini-cli -y
GitHub Copilot
$ npx skills add dembrandt/dembrandt-skills --skill modular-scale-typography -a github-copilot -y
OpenCode
$ npx skills add dembrandt/dembrandt-skills --skill modular-scale-typography -a opencode -y
Windsurf
$ npx skills add dembrandt/dembrandt-skills --skill modular-scale-typography -a windsurf -y
name: modular-scale-typography
description: Ratio-based type scale where every size relates to the others. Use when defining font sizes or type tokens, or when typography feels arbitrary.
metadata:
priority: 7
docs:
- "https://typescale.com"
- "https://www.modularscale.com"
pathPatterns:
- "**/*.css"
- "**/*.scss"
- "**/*.tokens.json"
- "**/tokens/**"
- "**/typography/**"
- "**/theme/**"
- "tailwind.config.*"
- "design-system/**"
promptSignals:
phrases:
- "modular scale"
- "type scale"
- "font sizes"
- "typography tokens"
- "heading sizes"
- "typographic hierarchy"
- "text feels inconsistent"
retrieval:
aliases:
- modular scale
- type scale
- typographic rhythm
- font size tokens
- visual harmony typography
intents:
- define font sizes
- make typography feel cohesive
- set up type tokens
- fix inconsistent font sizes
- create typographic hierarchy
examples:
- my font sizes feel random, fix them
- set up a modular scale for this design system
- which ratio should I use for my type scaleTypography feels cohesive when all font sizes are related to each other through a single mathematical ratio. Without a scale, sizes get picked arbitrarily and the result feels visually noisy — headings that don't contrast enough, body text too close in size to captions, labels that blend into content.
A modular scale starts from a **base size** and multiplies or divides by a **ratio** to generate every size in the system.
size(n) = base × ratio^n
Every size is thus a deliberate step away from the base — not a guess.
| Ratio | Name | Feel | Good for | |---|---|---|---| | 1.067 | Minor Second | Very tight | Dense data UIs, dashboards | | 1.125 | Major Second | Subtle | Long-form reading, editorial | | 1.200 | Minor Third | Balanced | Most UI applications | | 1.250 | Major Third | Clear hierarchy | Marketing, landing pages | | 1.333 | Perfect Fourth | Strong contrast | Display, hero sections | | 1.414 | Augmented Fourth | Dramatic | Portfolios, branding | | 1.500 | Perfect Fifth | Very dramatic | Use sparingly |
**Default recommendation:** `1.25` (Major Third) — enough contrast between steps to feel intentional without being theatrical.
> **Recover an existing scale, don't reverse-engineer it by hand (dembrandt engine, optional).** If a brand already has type on the web, `get_typography` returns the real font sizes, weights, and line-heights computed off the live DOM — infer the underlying ratio from those, then regularise it with the method below, instead of guessing which sizes were intended. See [`extract-design`](../extract-design/SKILL.md).
Starting from `base = 16px`, ratio `1.25`:
| Step | Formula | Value | Rounded | Role | |---|---|---|---|---| | -2 | 16 ÷ 1.25² | 10.24px | 10px | Caption, label-xs | | -1 | 16 ÷ 1.25 | 12.80px | 13px | Label, small | | 0 | 16 | 16px | 16px | Body (base) | | +1 | 16 × 1.25 | 20px | 20px | Body-lg, lead | | +2 | 16 × 1.25² | 25px | 25px | H4 | | +3 | 16 × 1.25³ | 31.25px | 31px | H3 | | +4 | 16 × 1.25⁴ | 39.06px | 39px | H2 | | +5 | 16 × 1.25⁵ | 48.83px | 49px | H1 | | +6 | 16 × 1.25⁶ | 61.04px | 61px | Display |
Round to whole pixels or rem — the ratio provides the intent, exact pixel rounding is fine.
:root {
--text-xs: 0.625rem; /* 10px — caption */
--text-sm: 0.813rem; /* 13px — label */
--text-base: 1rem; /* 16px — body */
--text-lg: 1.25rem; /* 20px — lead */
--text-xl: 1.563rem; /* 25px — h4 */
--text-2xl: 1.938rem; /* 31px — h3 */
--text-3xl: 2.438rem; /* 39px — h2 */
--text-4xl: 3.063rem; /* 49px — h1 */
--text-5xl: 3.813rem; /* 61px — display */
}// tailwind.config.js
fontSize: {
'xs': ['0.625rem', { lineHeight: '1rem' }],
'sm': ['0.813rem', { lineHeight: '1.25rem' }],
'base': ['1rem', { lineHeight: '1.5rem' }],
'lg': ['1.25rem', { lineHeight: '1.75rem' }],
'xl': ['1.563rem', { lineHeight: '2rem' }],
'2xl': ['1.938rem', { lineHeight: '2.25rem' }],
'3xl': ['2.438rem', { lineHeight: '2.5rem' }],
'4xl': ['3.063rem', { lineHeight: '1.1' }],
'5xl': ['3.813rem', { lineHeight: '1' }],
}Without a scale, designers and developers pick sizes by eye or habit (`14px`, `16px`, `18px`, `24px`, `32px`, `48px`). These feel subtly wrong because the intervals are uneven — the jump from 14→16 is small, 32→48 is large, and there is no underlying logic tying them together. The eye senses the inconsistency even when the viewer cannot name it.
With a modular scale, every size step carries the same visual weight of change. Hierarchy reads clearly because each level is a proportional step away from the next, not an arbitrary gap.
**Body text base: 16px minimum.** This is the browser default for good reason — it is the threshold below which reading comfort drops significantly, especially on screens.
In the modular scale, this means the base (`step 0`) should be 16px, and negative steps (step -1, step -2) should be used only for genuinely secondary content — never for body copy or primary labels.
**The 1% heuristic.** Sub-16px text is the rare exception (target: under ~1% of a page, never below 14px). Nobody counts characters, so apply it as a role test:
Enterprise UX secrets, now built into your AI agent. Your agent writes the component in seconds. It does not know the modal should be a drawer, or that the grey it picked fails contrast. These skills carry that judgment: what to do, and what breaks otherwise.
Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building…
Top bar, sidebar rail, app launcher, tenant and environment cue, status bar. Use when designing the persistent shell, a…
Product visuals must show the real product with real data. Use when building landing pages, hero sections, screenshots or demo…
Shape language across type, radius and icons carries brand personality. Use when starting a design system, picking icons or…
Rest, hover, active, focus, disabled and loading states, derived from the base colour. Use when designing buttons, links, inputs…
Rebuild a live web page 1:1 from measurement into Figma, Penpot or code, then verify it. Use when reproducing a page or checking…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.