Typography Cleanup
Fix font chaos in a vibecoded website — too many font sizes, inconsistent weights, broken heading hierarchy, mismatched line heights, and mixed font families. Establish a clean type scale and apply it everywhere. Trigger when fonts "look off," headings are inconsistent, or there are too many text sizes.
Typography is the single most visible design property on any website, and font inconsistency is the fastest way to make a site feel unprofessional. When fifteen different font sizes appear across a site instead of seven, when headings do not follow a clear hierarchy, and when line heights vary randomly, users feel the disorder immediately even if they cannot name what is wrong. Cleaning up typography has a disproportionate impact on perceived quality relative to the effort required. ## Key Points - Text that's now too big or too small (wrong mapping) - Headings that don't follow h1 > h2 > h3 visual hierarchy - Body text that feels too tight or too loose (line-height issue) - Labels that no longer look like labels (weight issue) - Don't use more than 2 font families. If you need emphasis, use weight and size, not a new font. - Don't use font-weight 300 (light) for body text — it's hard to read on most screens. - Don't set line-height as a fixed pixel value — use unitless ratios so they scale with font size. - Don't skip sizes in the heading hierarchy. If you use h1 and h3, the missing h2 is confusing. - Don't use `text-transform: uppercase` on long text. It kills readability. Only on short labels. - Don't mix rem and px. Pick one (rem preferred) and use it everywhere.
skilldb get web-polish-skills/typography-cleanupFull skill: 255 linesTypography Cleanup Specialist
Core Philosophy
Typography is the single most visible design property on any website, and font inconsistency is the fastest way to make a site feel unprofessional. When fifteen different font sizes appear across a site instead of seven, when headings do not follow a clear hierarchy, and when line heights vary randomly, users feel the disorder immediately even if they cannot name what is wrong. Cleaning up typography has a disproportionate impact on perceived quality relative to the effort required.
A clean type scale is a set of 6-8 sizes on a mathematical ratio, three font weights, and paired line heights. This is the entire system. Every text element on the site maps to one of these predefined styles. The cleanup process is not about choosing beautiful fonts -- it is about reducing the 17 arbitrary sizes found in a vibecoded codebase to 8 intentional ones and applying them consistently.
The migration from arbitrary values to a clean scale must be mechanical, not creative. Each found value maps to its nearest scale value (13px becomes 14px, 22px becomes 20px), and the replacement is executed file by file. The site should look virtually identical after the migration -- just more consistent. If the typography looks noticeably different, a mapping was wrong and should be corrected.
You are a typographer who fixes the single most visible design problem in vibecoded websites: font inconsistency. When 15 different font sizes appear across a site instead of 7, when headings don't follow a clear hierarchy, when line heights vary randomly — users feel it immediately even if they can't name it. You make text feel intentional.
The Typical Mess
A vibecoded site's typography audit usually reveals:
Font sizes found: 11px, 12px, 13px, 14px, 15px, 16px, 17px, 18px, 20px, 22px, 24px,
28px, 30px, 32px, 36px, 40px, 48px
Font weights found: 300, 400, 500, 600, 700, 800
Line heights found: 1, 1.2, 1.25, 1.3, 1.4, 1.5, 1.6, 1.75, 2, normal, 20px, 24px, 28px
Font families found: 'Inter', 'Helvetica', system-ui, -apple-system, sans-serif,
'Roboto', 'Open Sans', inherit
The fix: reduce to a clean scale and apply it consistently.
The Clean Type Scale
Choosing a Scale
Pick a type scale based on the site's personality:
Perfect Fourth (1.333) — Compact, good for data-dense dashboards:
12 → 14 → 16 → 18 → 21 → 24 → 28 → 32
Major Third (1.250) — Balanced, good for most sites:
12 → 14 → 16 → 18 → 20 → 24 → 30 → 36
Perfect Fifth (1.500) — Dramatic, good for marketing sites:
12 → 14 → 16 → 18 → 24 → 30 → 36 → 48
The Recommended Scale (Major Third)
:root {
/* Font families — TWO max */
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
/* Type scale — 8 sizes, clean ratios */
--text-xs: 0.75rem; /* 12px — captions, fine print */
--text-sm: 0.875rem; /* 14px — secondary text, labels */
--text-base: 1rem; /* 16px — body text, default */
--text-lg: 1.125rem; /* 18px — large body, intro text */
--text-xl: 1.25rem; /* 20px — small headings */
--text-2xl: 1.5rem; /* 24px — section headings */
--text-3xl: 1.875rem; /* 30px — page headings */
--text-4xl: 2.25rem; /* 36px — hero headings */
/* Font weights — 3 max */
--font-normal: 400; /* Body text */
--font-medium: 500; /* Labels, emphasis */
--font-semibold: 600; /* Headings, buttons */
/* Reserve 700 (bold) for rare emphasis only */
/* Line heights — paired with sizes */
--leading-tight: 1.25; /* Headings (text-xl and above) */
--leading-snug: 1.375; /* Large body text */
--leading-normal: 1.5; /* Body text (text-base and below) */
--leading-relaxed: 1.625; /* Long-form reading */
/* Letter spacing */
--tracking-tight: -0.025em; /* Large headings */
--tracking-normal: 0; /* Body text */
--tracking-wide: 0.05em; /* Uppercase labels, captions */
}
Semantic Type Styles
Define named styles so components reference roles, not raw values:
/* Display — hero headlines */
.text-display {
font-size: var(--text-4xl);
font-weight: var(--font-semibold);
line-height: var(--leading-tight);
letter-spacing: var(--tracking-tight);
}
/* Heading — page titles */
.text-heading {
font-size: var(--text-3xl);
font-weight: var(--font-semibold);
line-height: var(--leading-tight);
letter-spacing: var(--tracking-tight);
}
/* Subheading — section titles */
.text-subheading {
font-size: var(--text-2xl);
font-weight: var(--font-semibold);
line-height: var(--leading-tight);
}
/* Title — card titles, list headers */
.text-title {
font-size: var(--text-xl);
font-weight: var(--font-medium);
line-height: var(--leading-snug);
}
/* Body — default text */
.text-body {
font-size: var(--text-base);
font-weight: var(--font-normal);
line-height: var(--leading-normal);
}
/* Body small — secondary content */
.text-body-sm {
font-size: var(--text-sm);
font-weight: var(--font-normal);
line-height: var(--leading-normal);
}
/* Caption — metadata, timestamps, fine print */
.text-caption {
font-size: var(--text-xs);
font-weight: var(--font-normal);
line-height: var(--leading-normal);
color: var(--color-text-secondary);
}
/* Label — form labels, button text, badges */
.text-label {
font-size: var(--text-sm);
font-weight: var(--font-medium);
line-height: 1;
}
/* Overline — section labels, category markers */
.text-overline {
font-size: var(--text-xs);
font-weight: var(--font-semibold);
line-height: 1;
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
}
The Cleanup Process
Step 1: Audit
Extract every unique typography value from the codebase:
# Font sizes
grep -roh 'font-size:\s*[^;]*' src/ | sort | uniq -c | sort -rn
grep -roh 'text-\(xs\|sm\|base\|lg\|xl\|2xl\|3xl\|4xl\|5xl\|6xl\|\[.*\]\)' src/ | sort | uniq -c
# Font weights
grep -roh 'font-weight:\s*[^;]*' src/ | sort | uniq -c | sort -rn
grep -roh 'font-\(thin\|light\|normal\|medium\|semibold\|bold\|extrabold\|black\)' src/ | sort | uniq -c
# Line heights
grep -roh 'line-height:\s*[^;]*' src/ | sort | uniq -c | sort -rn
grep -roh 'leading-\(none\|tight\|snug\|normal\|relaxed\|loose\)' src/ | sort | uniq -c
# Font families
grep -roh "font-family:\s*[^;]*" src/ | sort | uniq -c | sort -rn
Step 2: Build a Migration Map
Map every found value to its nearest scale value:
FOUND → REPLACE WITH → REASON
11px → var(--text-xs) → Round to 12px
13px → var(--text-sm) → Round to 14px
15px → var(--text-base) → Round to 16px
17px → var(--text-lg) → Round to 18px
22px → var(--text-xl) → Round to 20px
28px → var(--text-2xl) → Round to 24px
32px → var(--text-3xl) → Round to 30px
40px, 48px → var(--text-4xl) → Round to 36px
font-weight:300 → var(--font-normal) → Drop light weight
font-weight:800 → var(--font-semibold) → Drop extra-bold
'Roboto' → DROP → Consolidate to Inter
'Open Sans' → DROP → Consolidate to Inter
'Helvetica' → DROP → Consolidate to Inter
Step 3: Apply File by File
Replace values mechanically, one file at a time. Don't redesign — just map to the nearest clean scale value. The site should look virtually identical after, just more consistent.
Step 4: Visual Review
After migration, scan every page looking for:
- Text that's now too big or too small (wrong mapping)
- Headings that don't follow h1 > h2 > h3 visual hierarchy
- Body text that feels too tight or too loose (line-height issue)
- Labels that no longer look like labels (weight issue)
Responsive Typography
For marketing/content sites, use fluid typography that scales with viewport:
:root {
--text-base: clamp(0.9375rem, 0.9rem + 0.2vw, 1.0625rem); /* 15-17px */
--text-lg: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem); /* 17-19px */
--text-xl: clamp(1.1875rem, 1rem + 0.9vw, 1.5rem); /* 19-24px */
--text-2xl: clamp(1.4375rem, 1rem + 2.2vw, 2rem); /* 23-32px */
--text-3xl: clamp(1.75rem, 1rem + 3.8vw, 2.75rem); /* 28-44px */
--text-4xl: clamp(2.1875rem, 1rem + 6vw, 3.75rem); /* 35-60px */
}
For dashboards and apps, use fixed sizes — fluid type in data-dense UI is disorienting.
Anti-Patterns
- Don't use more than 2 font families. If you need emphasis, use weight and size, not a new font.
- Don't use font-weight 300 (light) for body text — it's hard to read on most screens.
- Don't set line-height as a fixed pixel value — use unitless ratios so they scale with font size.
- Don't skip sizes in the heading hierarchy. If you use h1 and h3, the missing h2 is confusing.
- Don't use
text-transform: uppercaseon long text. It kills readability. Only on short labels. - Don't mix rem and px. Pick one (rem preferred) and use it everywhere.
Install this skill directly: skilldb add web-polish-skills
Related Skills
UI Audit
Audit a vibecoded or inconsistent website for visual and structural problems — mismatched components, font chaos, color drift, spacing irregularities, broken states, and missing interactions. Produces a prioritized fix list. Trigger when users say "this looks off," "make it consistent," "audit the UI," "fix the design," or "polish this site."
Vibecode Upgrade
The comprehensive playbook for upgrading a vibecoded website from "it works" to "it feels premium." Combines all other web-polish skills into a prioritized workflow — audit, extract tokens, unify components, fix responsiveness, add polish. Trigger when users want to "upgrade the whole site," "make it look professional," "polish everything," or "it was vibecoded and needs to be cleaned up."
Visual Polish
Apply the final layer of visual polish to a website — hover states, transitions, micro- interactions, loading states, empty states, scroll behavior, and the small details that make a site feel premium. Trigger when a site "works but feels cheap," needs "polish," or the user says "make it feel premium/professional/finished."
Web Design Fundamentals
Use this skill when designing a web page or interface from scratch rather than repairing one. Activate when users mention web design, web-design, visual design, layout design, typography choices, color palette selection, spacing systems, visual hierarchy, landing page design, or "make this look professional / less like a bootstrap template".
Color System Repair
Fix color chaos in a vibecoded website — too many near-duplicate colors, inconsistent semantic usage, broken dark mode, contrast failures, and colors without purpose. Establish a minimal palette with clear roles. Trigger when colors "don't match," there are too many shades of gray, or the palette feels random.
Component Unification
Take scattered, inconsistent UI components from a vibecoded website and unify them into a shared component library where every button, input, card, badge, and modal uses the same design language. Trigger when users want to "make components match," "create a component library," "unify the UI," or "build shared components."