The pain this chapter solves

You pick spacing values by gut feel, copy pixel numbers from Figma, and end up with 47 different padding values across your app. Nothing feels intentional. The layout has no rhythm.

Chapter 5

Design Scale Presets

What scales are

Scales are the non-color dimension of your design system. While colors define identity, scales define feel — how tight or spacious the layout breathes, how sharp or soft the edges are, how large or small the text reads.

salt-theme-gen provides three independent scales, each with preset options:

generateTheme({
  preset: 'ocean',
  spacing: 'default',   // 'compact' | 'default' | 'spacious'
  radius:  'default',   // 'none' | 'sm' | 'default' | 'lg' | 'pill'
  fontSize: 'default',  // 'small' | 'default' | 'large'
})

They are completely independent. You can combine any spacing with any radius and any font size.


Spacing scale

Spacing controls all gap, padding, and margin values in your system. Six named steps cover the full range from tight component internals to section-level breathing room.

Spacing preset values (in px)

Tokencompactdefaultspacious
xs246
sm4812
md81220
lg121628
xl162440
xxl244064

Reading the table

  • md is the base unit — button padding, card internal spacing, form field padding.
  • sm is for tight internals — icon gaps, badge padding, list item gaps.
  • lg is for component separation — space between a label and its input, between a heading and a paragraph.
  • xl is for section internals — card padding, sidebar padding.
  • xxl is for section separation — vertical rhythm between major page sections.

compact — dense, information-rich layouts

Use when you need to show maximum content per screen. Common in:

  • Admin dashboards and data tables
  • Developer tools and terminals
  • IDE sidebars and toolbars
  • Financial applications with many numbers per row
/* compact: button padding */
padding: var(--space-sm) var(--space-md); /* 4px 8px */

default — balanced, general-purpose

The safe starting point for any product. Works for:

  • SaaS applications
  • Documentation sites
  • Most consumer web apps
  • E-commerce
/* default: button padding */
padding: var(--space-sm) var(--space-lg); /* 8px 16px */

spacious — generous, editorial layouts

Use when you want the layout to breathe and content to feel premium. Common in:

  • Marketing and landing pages
  • Editorial and content-first sites
  • Luxury or premium product pages
  • Mobile-first apps where touch targets need extra room
/* spacious: button padding */
padding: var(--space-sm) var(--space-lg); /* 12px 28px */

Spacing in practice

/* The same CSS works across all spacing presets */
.card {
  padding: var(--space-xl);
  gap: var(--space-md);
}

.form-field {
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-lg);
}

.page-section {
  padding: var(--space-xxl) 0;
}

Change spacing: 'compact' to spacing: 'spacious' in your generateTheme() call, regenerate your CSS variables, and every one of these values updates automatically. Your component CSS never changes.


Radius scale

Radius controls border rounding across your entire interface. Seven steps from perfectly sharp to fully pill-shaped.

Radius preset values (in px)

Tokennonesmdefaultlgpill
none00000
sm02464
md048129999
lg0614209999
xl0820289999
xxl01028369999
pill09999999999999999

The pill preset sets most sizes to 9999px — anything short enough becomes fully rounded. Only the none column is always 0.

none — sharp edges, zero rounding

Every element is rectangular. Reads as technical, precise, rigorous. Common in:

  • Terminal and CLI interfaces
  • Code editors and developer tools
  • Financial data products
  • Brutalist or editorial design aesthetics
/* Borders are always rectangular */
.btn { border-radius: var(--radius-md); } /* → 0px */
.card { border-radius: var(--radius-lg); } /* → 0px */

sm — subtle rounding, mostly sharp

Very light rounding on smaller elements. Large elements remain near-rectangular. Reads as professional with a slight softness. Common in:

  • Enterprise SaaS
  • Productivity software
  • B2B tools

default — balanced, broadly appropriate

The most versatile choice. Small elements (inputs, tags) get subtle rounding. Large elements (cards, modals) get noticeable but not exaggerated rounding. Common in:

  • Most web applications
  • Documentation
  • Component libraries
.tag    { border-radius: var(--radius-sm); }  /* 4px */
.btn    { border-radius: var(--radius-md); }  /* 8px */
.card   { border-radius: var(--radius-lg); }  /* 14px */
.modal  { border-radius: var(--radius-xl); }  /* 20px */

lg — confident, modern rounding

Noticeably rounded at all sizes. Reads as contemporary and friendly. Common in:

  • Consumer mobile apps
  • Startup landing pages
  • Modern SaaS products targeting non-technical users

pill — soft, fully rounded

Buttons, inputs, and chips become stadium-shaped. Cards and modals have significant rounding. Reads as playful, friendly, consumer-oriented. Common in:

  • Social apps
  • Health and wellness
  • Fintech consumer apps (Revolut-style)
  • Mobile-first experiences
.btn    { border-radius: var(--radius-md); }  /* 9999px → stadium */
.tag    { border-radius: var(--radius-sm); }  /* 9999px → fully rounded */
.card   { border-radius: var(--radius-xl); }  /* 9999px → large rounded */

Mixing radius with element size

The pill token (9999px) creates a stadium shape on any element. Use it for:

  • Pill buttons
  • Rounded badges
  • Tag chips
  • Avatar crops
.avatar {
  border-radius: var(--radius-pill); /* always fully circular for square elements */
}

Font size scale

Font sizes follow a modular scale based on a ~1.25 ratio. Seven named steps from caption to hero heading.

Font size preset values (in px)

Tokensmalldefaultlarge
xs101112
sm111314
md131517
lg151821
xl182226
xxl222834
3xl303848

small — compact, dense text

Appropriate for:

  • Admin interfaces with dense data
  • Developer tools (IDE-like UIs)
  • Secondary content in information-rich UIs
  • Mobile-first apps where screen real estate is limited
body { font-size: var(--text-md); } /* → 13px */
h1   { font-size: var(--text-3xl); } /* → 30px */

default — universal baseline

Readable for most users on most screens. Suitable for:

  • Any web application without a strong reason to go larger or smaller
  • Documentation and instructional content
  • Marketing sites
body { font-size: var(--text-md); } /* → 15px */
h1   { font-size: var(--text-3xl); } /* → 38px */

large — accessible, editorial

Generous text sizes for:

  • Accessibility-focused products (older audiences, vision accessibility)
  • Marketing sites where text is hero content
  • Long-form editorial and blog content
  • TV/large-screen interfaces
body { font-size: var(--text-md); } /* → 17px */
h1   { font-size: var(--text-3xl); } /* → 48px */

A practical type scale

Apply the scale to semantic HTML elements once in your global styles:

h1, .text-3xl { font-size: var(--text-3xl); line-height: 1.1; }
h2, .text-xxl { font-size: var(--text-xxl); line-height: 1.2; }
h3, .text-xl  { font-size: var(--text-xl);  line-height: 1.3; }
h4, .text-lg  { font-size: var(--text-lg);  line-height: 1.4; }
p,  .text-md  { font-size: var(--text-md);  line-height: 1.75; }
small, .text-sm { font-size: var(--text-sm); line-height: 1.6; }
.text-xs      { font-size: var(--text-xs);  line-height: 1.5; }

Every font-size in your UI now comes from the same seven steps. No more rogue 14px or 17px values scattered across components.


Combining scales — personality matrix

The real power of independent scales is the personality you create by combining them. Here are common combinations:

Corporate / enterprise B2B

generateTheme({ preset: 'sapphire', spacing: 'compact', radius: 'none', fontSize: 'small' })

Sharp edges, dense information, small text. Reads as serious and data-focused.


Modern SaaS (Linear, Vercel-style)

generateTheme({ preset: 'ocean', spacing: 'default', radius: 'default', fontSize: 'default' })

Balanced in every dimension. Professional but not stiff. The most common combination.


Consumer mobile app

generateTheme({ preset: 'aurora', spacing: 'spacious', radius: 'pill', fontSize: 'large' })

Generous spacing, full rounding, large touch-friendly text. Every element feels approachable.


Editorial / content-first

generateTheme({ preset: 'desert', spacing: 'spacious', radius: 'sm', fontSize: 'large' })

Lots of breathing room, minimal rounding, generous text. The layout gets out of the way of the content.


Developer tool / terminal-adjacent

generateTheme({ preset: 'midnight', spacing: 'compact', radius: 'none', fontSize: 'small' })

Dark, dense, sharp. Everything signals precision and control.


Startup landing page

generateTheme({ preset: 'sunset', spacing: 'spacious', radius: 'lg', fontSize: 'default' })

Energetic color, generous layout, noticeable rounding. Designed to impress at first scroll.


Switching scales at runtime

Scales are defined once at theme generation time — they are not dynamic. If you want runtime scale switching (for example, a user-controlled density preference), generate multiple themes and swap the CSS variable block:

const compact  = generateTheme({ preset: 'ocean', spacing: 'compact' });
const spacious = generateTheme({ preset: 'ocean', spacing: 'spacious' });

// Swap on user preference change
function applyDensity(dense: boolean) {
  const vars = dense
    ? compactSpacingVars(compact.light)
    : spaciousSpacingVars(spacious.light);
  document.documentElement.style.cssText += vars;
}

For most products this is unnecessary — pick a scale at build time and commit to it. But the option exists.


What scales do not control

Scales control spacing, radius, and font size steps. They do not control:

  • Line height — set this in your global CSS (line-height: 1.75 for body text is a safe default)
  • Font weight — choose weights for headings and body text in your CSS
  • Font family — bring your own typeface; salt-theme-gen is font-agnostic
  • Shadow — elevation depth is expressed through surfaceElevation colors, not shadow values. Add your own box-shadow as needed.
  • Transition duration — define motion in your CSS

The design scales give you the geometry of your system. You own the typography and motion.

Tip: When in doubt, start with spacing: ‘default’, radius: ‘default’, and fontSize: ‘default’. These are calibrated to feel balanced on most screens. Move away from the defaults only when you have a specific product reason.