Skip to content

Typography System

The theme uses a token-driven typography system built with SCSS maps and CSS variables. You define a token once — size, line-height, breakpoints — and the system generates the utility class, the CSS variable, and all responsive overrides from that single definition.

The typography setup has three parts:

  1. Typography tokens — define font sizes, line-heights, letter-spacing
  2. CSS variables & classes — generated from the tokens
  3. Mixins — for custom applications

The base font family is defined in assets/src/scss/abstracts/variables/_typography.scss. By default it’s a native system stack — add your own fonts here:

$base-font-family:
-apple-system, blinkmacsystemfont, "Segoe UI", roboto, helvetica, arial,
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
$type-tokens: (
display: (
lg: (
size: rem(48px),
line-height: 1.1,
letter-spacing: -0.001em,
breakpoint: (
tablet: (
size: rem(28px),
),
mobile: (
size: rem(24px),
),
),
),
md: (
size: rem(40px),
line-height: 1.1,
),
),
heading: (
// …
),
body: (
// …
),
);

$type-tokens is the single source of truth for all typography in the theme. Every utility class, CSS variable, and responsive override is generated from this map — you never write the same font size in two places.

group:
size:
size: font-size (required)
line-height: line-height (optional)
letter-spacing: letter-spacing (optional)
breakpoint: (optional)
breakpoint-name:
size: override font-size

Top-level keys are semantic groups:

  • display — Hero titles, very large text
  • heading — Page and section headings
  • body — Body text, paragraphs

Classes are generated as .text-{group}-{size} for every token defined:

.text-display-lg // Hero titles
.text-display-md // Section headers
.text-heading-lg // Page headings
.text-heading-md // Section headings
.text-heading-sm // Subsection headings
.text-body-lg // Large body text
.text-body-md // Standard body text
.text-body-sm // Small text, captions
<h1 class="text-display-lg">Page Title</h1>
<p class="text-body-md">Body text here</p>
.card__title {
@include typography(heading, lg);
}

Mixin options:

@include typography(heading, lg); // Base styles only
@include typography(heading, lg, mobile); // Specific breakpoint
@include typography-with-breakpoints(heading, lg); // All breakpoints

Breakpoints are defined in the token and automatically applied. They reference the named breakpoints in abstracts/variables/_media-queries.scss (mobile, tablet, …) and are max-width, so scale down for smaller screens:

display: (
lg: (
size: rem(48px),
breakpoint: (
tablet: (
size: rem(28px),
),
mobile: (
size: rem(24px),
),
),
)
);

This generates responsive CSS variables and utility classes automatically.

Defined separately in $font-weights:

$font-weights: (
light: 300,
normal: 400,
medium: 500,
bold: 700,
);

Each weight generates a .font-{name} utility class:

<p class="text-body-md font-medium">Medium text</p>
:root {
--instance-display-lg-font-size: 3rem;
--instance-display-lg-line-height: 1.1;
--instance-display-lg-tablet-font-size: 1.75rem;
--instance-display-lg-mobile-font-size: 1.5rem;
}

All tokens generate CSS variables on :root automatically (from assets/src/scss/generate/_typography.scss) — you never write these by hand. The naming pattern is --instance-{group}-{size}-{property}.

.custom-heading {
--instance-heading-lg-font-size: 2.25rem;
}

Override a token locally by redefining its CSS variable on a specific selector. The utility class picks up the new value without needing a new token or a specificity battle.

  1. Open the token file

    Edit assets/src/scss/abstracts/variables/_typography.scss.

  2. Add your token

    $type-tokens: (
    display: (
    xl: (
    size: rem(64px),
    line-height: 1.1,
    letter-spacing: -0.002em,
    breakpoint: (
    tablet: (
    size: rem(48px),
    ),
    mobile: (
    size: rem(36px),
    ),
    ),
    ),
    ),
    );
  3. Use the generated class or mixin

    <h1 class="text-display-xl">Hero Title</h1>

    or via SCSS:

    .hero__title {
    @include typography-with-breakpoints(display, xl);
    }
  1. Open the Typography / Type Scale board in Figma
  2. Copy font sizes, line heights, letter spacing, and weights
  3. Map into $type-tokens using semantic naming (display, heading, body + lg/md/sm)
  1. Go page by page and collect typography styles
  2. Identify repeating patterns
  3. Map into $type-tokens semantically
  4. Add even one-off sizes as tokens for consistency

Enable debug output to see generated classes:

$font-output-generated-class-names: true;

This prints generated class names to the SCSS output during compilation.