Wallflower UI

Typography

A fluid type scale that grows from phone to desktop without breakpoints, and a curated set of free Google Fonts. Fonts come from the active preset.

Type scale

Headings use the preset's display font; text uses its sans. Sizes with clamp() scale smoothly with the viewport.

.wf-text-display
700 · 1.02
clamp(2.75rem, 1.6rem + 4.6vw, 5rem)

Quiet design, loud results

.wf-text-h1
700 · 1.08
clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem)

Every app, one source

.wf-text-h2
650 · 1.15
clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem)

Tokens over magic numbers

.wf-text-h3
600 · 1.25
clamp(1.375rem, 1.2rem + 0.7vw, 1.75rem)

Start with a preset

.wf-text-h4
600 · 1.4
1.125rem

Then make it yours

.wf-text-lead
400 · 1.6
clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem)

A lead paragraph introduces a page and sets its tone in a sentence or two.

.wf-text-body
400 · 1.6
1rem

Body text is set for long reading: 16px with a generous 1.6 line height and balanced measure.

.wf-text-small
400 · 1.5
0.875rem

Small text labels controls and carries secondary details.

.wf-text-caption
500 · 1.4
0.75rem

Captions sit under images and inputs.

.wf-text-overline
500 · 1.3
0.75rem

Section eyebrow

.wf-text-code
400 · 1.5
0.875em

const preset = "wallflower";

usage
<h1 class="wf-text-h1">Title</h1>          <!-- class -->
font: var(--wf-text-h1);                    /* CSS shorthand */
letter-spacing: var(--wf-text-h1-tracking);
<h1 class="font-display">                   <!-- Tailwind: font-sans · font-display · font-serif · font-mono -->

Font catalog

All free on Google Fonts. Presets choose one for each role (sans, display, serif, mono); you can swap any of them by overriding --wf-font-*.

sans

Inter

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Neutral workhorse for product UI.

Geist

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Clean geometric-grotesk built for interfaces.

DM Sans

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Friendly low-contrast geometric.

Manrope

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Modern, open and technical.

Outfit

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Round geometric with warmth.

Plus Jakarta Sans

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Polished startup sans.

Instrument Sans

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Sharp, slightly condensed neo-grotesk.

Space Grotesk

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Quirky grotesk with mono roots.

Figtree

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Friendly geometric, great at small sizes.

Onest

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Crisp modern grotesk with open shapes.

Hanken Grotesk

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Quiet, refined grotesk for premium UIs.

Public Sans

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Neutral government-grade workhorse.

IBM Plex Sans

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Engineered, slightly technical.

Lexend

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Wide and highly readable.

Nunito

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Rounded terminals; soft and playful.

display

Bricolage Grotesque

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Characterful display grotesque for headlines.

Sora

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Wide techy display face.

Syne

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Art-school display face that widens as it gets bolder.

Unbounded

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Wide, bubbly, attention-grabbing.

Archivo

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Grotesk with a huge width range, from condensed to expanded.

Fredoka

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Round, chunky and friendly.

Familjen Grotesk

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Quirky Scandinavian grotesk.

VT323

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Pixel terminal type. Use large.

serif

Fraunces

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Soft "wonky" old-style serif with optical sizes.

Instrument Serif

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Condensed editorial serif for big headlines.

Newsreader

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Readable text serif for long-form.

Playfair Display

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

High-contrast didone for luxury headlines.

DM Serif Display

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Tight, punchy display serif.

Cormorant Garamond

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Elegant classical serif.

Young Serif

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Chunky, warm old-style serif.

Gloock

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Sharp high-contrast serif for statements.

mono

JetBrains Mono

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Developer mono with tall x-height.

Geist Mono

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Companion mono to Geist.

Space Mono

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Retro-futurist fixed width.

IBM Plex Mono

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Classic engineered mono.

Fira Code

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Mono with programming ligatures.

DM Mono

Aa Gg 0123

The quick brown fox jumps over the lazy dog.

Soft, low-contrast mono.

Loading fonts

The preset only names fonts; your app loads them. Use your framework's font loader for self-hosting and no layout shift.

Next.js — app/layout.tsx
import { Inter, Bricolage_Grotesque, JetBrains_Mono } from "next/font/google";

const sans = Inter({ subsets: ["latin"], variable: "--font-wf-sans" });
const display = Bricolage_Grotesque({ subsets: ["latin"], variable: "--font-wf-display" });
const mono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-wf-mono" });

export default function RootLayout({ children }) {
  return (
    <html lang="en" data-preset="wallflower"
      className={`${sans.variable} ${display.variable} ${mono.variable}`}>
      <body>{children}</body>
    </html>
  );
}

/* globals.css: point Wallflower at the self-hosted files */
:root {
  --wf-font-sans: var(--font-wf-sans), ui-sans-serif, system-ui, sans-serif;
  --wf-font-display: var(--font-wf-display), ui-sans-serif, sans-serif;
  --wf-font-mono: var(--font-wf-mono), ui-monospace, monospace;
}
Astro — astro.config.mjs (Fonts API)
import { defineConfig, fontProviders } from "astro/config";

export default defineConfig({
  fonts: [
    { provider: fontProviders.google(), name: "Inter", cssVariable: "--font-wf-sans" },
    { provider: fontProviders.google(), name: "Bricolage Grotesque", cssVariable: "--font-wf-display" },
  ],
});

---
// Layout.astro
import { Font } from "astro:assets";
---
<head>
  <Font cssVariable="--font-wf-sans" preload />
  <Font cssVariable="--font-wf-display" />
</head>

/* Then point --wf-font-* at them, same as Next.js. */
/* Or skip all that: each preset in ds/tokens/presets.json
   has a ready-made googleFontsUrl for a <link> tag. */