Configuration

Every key in emily.config.json: type, default, and what it generates.

name & description

Optional strings. Written into generated CSS comments. No effect on output utilities.

{
  "name": "My Brand Design System",
  "description": "A complete design system for our products"
}

baseUnit & baseFontSize

baseUnit sets the base multiplier for spacing utilities (default "8px"). baseFontSize sets the root font-size on html (default "16px").

{
  "baseUnit": "8px",
  "baseFontSize": "16px"
}

fontFamily

Pick from the bundled options or leave blank to use system defaults. Supported values: inter, lexend, system, georgia, mono.

"fontFamily": {
  "heading": "lexend",
  "body": "inter"
}

Generates font-lexend and font-inter utility classes, plus sets CSS custom properties for --emily-font-heading and --emily-font-body.

colours

Provide one hex value per colour role. emilyCSS generates a full 10-shade scale (10–100) automatically using OKLCH interpolation, balancing lightness and chroma to produce visually consistent steps.

"colours": {
  "brand":         "#DB2777",
  "accent":        "#2563EB",
  "btn-primary":   "#DB2777",
  "btn-secondary": "#2563EB",
  "success":       "#017F65",
  "warning":       "#FFC107",
  "error":         "#B20000",
  "neutral":       "#57534E"
},
"semanticColours": {
  "dark":  "#1A1A1A",
  "light": "#FAFAFA"
}

Each colour in colours generates text, background, and border utilities across the full 10-shade scale. semanticColours generates single-value utilities with no shade suffix.

/* Palette colours — full shade scale */
text-brand-10  text-brand-20  ...  text-brand-100
bg-brand-10   bg-brand-20   ...  bg-brand-100
border-brand-10  ...  border-brand-100

/* Semantic colours — single value */
bg-dark   text-dark   border-dark
bg-light  text-light  border-light

Naming note: 10 is lightest (near white), 100 is darkest (near black). Your input colour lands roughly at 80 on the scale. Use it as bg-brand-80 or text-brand-80.

semanticColours

Single-value colour tokens, no shade scale. Use these for theme-level values like dark and light where a full gradient doesn't make sense.

"semanticColours": {
  "dark":  "#1A1A1A",
  "light": "#FAFAFA"
}

Generates bg-dark, text-dark, border-dark and the light equivalents. All support state and responsive variants: hover:bg-dark, md:text-light.

breakpoints

Defines the responsive prefix values. All utilities support responsive variants. Prefix any class with a breakpoint name to apply it from that width up.

"breakpoints": {
  "sm": "640px",
  "md": "768px",
  "lg": "1024px",
  "xl": "1280px",
  "2xl": "1536px"
}
<div class="text-sm md:text-base lg:text-lg">Responsive text</div>

spacing

Controls three related areas: the spacing scale (used for padding, margin, gap, width, height), border widths, and border radius.

"spacing": {
  "scale": {
    "0": "0px",
    "1": "0.25rem",
    "2": "0.5rem",
    "4": "1rem",
    "8": "2rem"
    ...
  },
  "borderWidths": [0, 2, 4, 8],
  "borderRadius": {
    "none": "0",
    "sm": "4px",
    "base": "8px",
    "md": "12px",
    "lg": "16px",
    "full": "9999px"
  }
}

Scale values generate p-*, m-*, gap-*, w-*, h-* and others. Border widths generate border-2, border-4, border-8. Border radius generates rounded-sm, rounded-lg, rounded-full etc.

typography

Controls font size steps, weights, and line heights. Font sizes generate both utility classes and CSS custom properties.

"typography": {
  "lineHeightRatio": 1.5,
  "fontWeights": {
    "light": 300,
    "normal": 400,
    "medium": 500,
    "semibold": 600,
    "bold": 700
  },
  "fontSizes": [
    { "name": "xs",   "value": "12px", "lineHeight": 1.5 },
    { "name": "sm",   "value": "14px", "lineHeight": 1.5 },
    { "name": "base", "value": "16px", "lineHeight": 1.6 },
    { "name": "lg",   "value": "18px", "lineHeight": 1.6 },
    { "name": "xl",   "value": "20px", "lineHeight": 1.6 },
    { "name": "2xl",  "value": "24px", "lineHeight": 1.4 },
    { "name": "3xl",  "value": "30px", "lineHeight": 1.4 },
    { "name": "4xl",  "value": "36px", "lineHeight": 1.3 },
    { "name": "5xl",  "value": "48px", "lineHeight": 1.1 },
    { "name": "6xl",  "value": "60px", "lineHeight": 1.0 },
    { "name": "7xl",  "value": "72px", "lineHeight": 1.0 }
  ]
}

Generates text-xs through text-7xl and font-light through font-bold.

shadows

Named shadow values. Generates shadow-sm, shadow-base, shadow-md, shadow-lg, and shadow-none.

"shadows": {
  "sm": "0 1px 2px rgba(0, 0, 0, 0.05)",
  "base": "0 4px 6px rgba(0, 0, 0, 0.1)",
  "md": "0 10px 15px rgba(0, 0, 0, 0.1)",
  "lg": "0 20px 25px rgba(0, 0, 0, 0.15)",
  "none": "none"
}

transitions

Named durations and a shared timing function. Generates transition utility classes such as transition, transition-none, transition-colors, transition-opacity, transition-transform, and duration utilities such as duration-100, duration-200, and duration-300.

"transitions": {
  "fast": "100ms",
  "base": "200ms",
  "slow": "300ms",
  "timing": "cubic-bezier(0.4, 0, 0.2, 1)"
}

zIndex

Named z-index values. Semantic names (dropdown, modal, tooltip) alongside numeric steps. Generates z-0, z-10, z-dropdown, z-modal etc.

"zIndex": {
  "auto": "auto",
  "0": "0",
  "10": "10",
  "50": "50",
  "dropdown": "1000",
  "modal": "1040",
  "tooltip": "1070"
}

opacity

An array of opacity steps (0–100). Generates opacity-0, opacity-25, opacity-50, opacity-100 etc.

"opacity": [0, 5, 10, 25, 50, 75, 90, 95, 100]

purge

Source globs and file extensions scanned during npx emily-css build. Any class not found in matching files is removed from production output.

"purge": {
  "extensions": [
    ".html", ".vue", ".jsx", ".tsx",
    ".twig", ".liquid", ".njk", ".php"
  ]
}

formBase

Bare element form styles for input, select, textarea, and fieldset are opt-in as of v2.0.0. Set "formBase": true to apply them.

This default changed to prevent EmilyCSS from overwriting form styles already applied by a CMS — particularly Drupal, Power Pages, and WordPress themes where bare element styles cause visual regressions.

"formBase": true

If you are upgrading from v1.x and your forms have lost styling, add this key and rebuild.

cornerStyle

Sets the --radius-base CSS custom property used by all component patterns — buttons, inputs, cards, and anything else that inherits border radius from tokens. Set during emily-css init or add it manually.

"cornerStyle": "rounded"

Accepted values and the --radius-base they produce:

"square"  → --radius-base: 0
"subtle"  → --radius-base: 4px
"rounded" → --radius-base: 8px  (default)

extend.utilities

Custom utility escape hatch. Define your own one-off utility classes in config and EmilyCSS generates them into @layer utilities — the same layer as all other utilities — with full responsive and state variant support.

"extend": {
  "utilities": {
    "w-hero":       { "property": "width",      "value": "720px" },
    "min-h-screen": { "property": "min-height", "value": "100svh" },
    "text-balance": { "property": "text-wrap",  "value": "balance" }
  }
}
/* From the above config */
.w-hero       { width: 720px }
.min-h-screen { min-height: 100svh }
.text-balance { text-wrap: balance }

/* Responsive variants generated automatically */
.md\:w-hero { ... }
.lg\:w-hero { ... }

/* State variants too */
.hover\:text-balance { ... }

Config validation will error if an entry is missing property or value, or if the key conflicts with a built-in utility name.

Next step

Read Utilities to see every class emilyCSS generates from your config.