HypeTheType fluid typography tool

01 / 04

01
Type ScaleSystem Foundation
Viewport simulation960px
display47.78px -> 100.98px--type-display

Build the scale.

lh 0.898 / tracking -0.056em
heading-xl39.81px -> 75.76px--type-heading-xl

Set the rhythm.

lh 0.898 / tracking -0.056em
heading-l33.18px -> 56.83px--type-heading-l

Fluid type, built properly.

lh 1.012 / tracking -0.03em
heading-m27.65px -> 42.63px--type-heading-m

Responsive typography without arbitrary values.

lh 1.06 / tracking -0.0282em
heading-s23.04px -> 31.98px--type-heading-s

Hierarchy remains separate from semantics.

lh 1.096 / tracking -0.0256em
body-l19.2px -> 23.99px--type-body-l

A system for scale, spacing, and long-form content.

lh 1.58 / tracking 0em
body16px -> 18px--type-body

The selected type scale adapts fluidly between the chosen minimum and maximum viewport while preserving readable relationships.

lh 1.58 / tracking 0em
body-s13.33px -> 13.5px--type-body-s

Secondary text stays legible without competing with the main reading voice.

lh 1.64 / tracking 0.006em
caption11.11px -> 10.13px--type-caption

Type token / min value / max value / line-height / tracking

lh 1.64 / tracking 0.006em
01

Fluid values combine rem endpoints with a modest vi component rather than pure viewport units.

02

Spacing is derived from base size and body line-height, so rhythm changes with the type system.

03

Heading semantics remain independent from visual tokens; the default h1-h6 mapping is editable in production.

04

Large type receives tighter leading and tracking, while smaller supporting text keeps more line separation.

05

Rich-text spacing uses contextual selectors so headings, lists, media, captions, and prose do not share one generic margin.

Export workspace

Choose a format, inspect the output, then open the full code stage when needed.

The export UI now keeps the format picker separate from the code so long token files do not collapse into a cramped sidebar card.

CSS export334 lines10946 chars

Raw custom properties and prose tokens for direct use in apps or prototypes.

:root {
  --font-body: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-heading: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --body-weight: 400;
  --heading-weight: 600;
  --type-display: clamp(2.986rem, calc(2.0358rem + 4.7508vi), 6.3115rem);
  --type-heading-xl: clamp(2.4883rem, calc(1.8465rem + 3.2093vi), 4.7348rem);
  --type-heading-l: clamp(2.0736rem, calc(1.6512rem + 2.112vi), 3.552rem);
  --type-heading-m: clamp(1.728rem, calc(1.4604rem + 1.3381vi), 2.6647rem);
  --type-heading-s: clamp(1.44rem, calc(1.2803rem + 0.7986vi), 1.999rem);
  --type-body-l: clamp(1.2rem, calc(1.1144rem + 0.428vi), 1.4996rem);
  --type-body: clamp(1rem, calc(0.9643rem + 0.1786vi), 1.125rem);
  --type-body-s: clamp(0.8333rem, calc(0.8303rem + 0.0152vi), 0.844rem);
  --type-caption: clamp(0.6944rem, calc(0.712rem - 0.0876vi), 0.6331rem);
  --leading-display: 0.898;
  --leading-heading-xl: 0.898;
  --leading-heading-l: 1.012;
  --leading-heading-m: 1.06;
  --leading-heading-s: 1.096;
  --leading-body-l: 1.58;
  --leading-body: 1.58;
  --leading-body-s: 1.64;
  --leading-caption: 1.64;
  --tracking-display: -0.056em;
  --tracking-heading-xl: -0.056em;
  --tracking-heading-l: -0.03em;
  --tracking-heading-m: -0.0282em;
  --tracking-heading-s: -0.0256em;
  --tracking-body-l: 0em;
  --tracking-body: 0em;
  --tracking-body-s: 0.006em;
  --tracking-caption: 0.006em;
  --space-3xs: clamp(0.3865rem, calc(0.3664rem + 0.1005vi), 0.4568rem);
  --space-2xs: clamp(0.5797rem, calc(0.5496rem + 0.1507vi), 0.6852rem);
  --space-xs: clamp(0.7729rem, calc(0.7327rem + 0.201vi), 0.9136rem);
  --space-s: clamp(1.1594rem, calc(1.0991rem + 0.3015vi), 1.3705rem);
  --space-m: clamp(1.5459rem, calc(1.4655rem + 0.402vi), 1.8273rem);
  --space-l: clamp(2.3188rem, calc(2.1982rem + 0.603vi), 2.7409rem);
  --space-xl: clamp(3.0917rem, calc(2.9309rem + 0.804vi), 3.6545rem);
  --space-2xl: clamp(4.6376rem, calc(4.3964rem + 1.206vi), 5.4818rem);
  --space-3xl: clamp(6.9564rem, calc(6.5946rem + 1.809vi), 8.2227rem);
  --space-inline: clamp(1.1802rem, calc(1.1188rem + 0.3072vi), 1.3953rem);
  --space-stack: clamp(1.5734rem, calc(1.4915rem + 0.4099vi), 1.8604rem);
  --space-paragraph: clamp(1.0699rem, calc(1.0142rem + 0.2788vi), 1.2651rem);
  --space-heading-before: clamp(3.6511rem, calc(3.4613rem + 0.9489vi), 4.3154rem);
  --space-heading-after: clamp(0.9678rem, calc(0.9174rem + 0.2519vi), 1.1441rem);
  --space-list: clamp(1.4161rem, calc(1.3423rem + 0.3689vi), 1.6744rem);
  --space-media: clamp(3.3049rem, calc(3.1331rem + 0.8589vi), 3.9062rem);
  --space-component: clamp(2.3605rem, calc(2.2378rem + 0.6135vi), 2.79rem);
  --space-section-s: clamp(3.3049rem, calc(3.1331rem + 0.8589vi), 3.9062rem);
  --space-section-m: clamp(5.0987rem, calc(4.8334rem + 1.3262vi), 6.027rem);
  --space-section-l: clamp(7.3647rem, calc(6.9817rem + 1.9151vi), 8.7053rem);
  --measure-narrow: 50ch;
  --measure-reading: 66ch;
  --measure-wide: 76ch;
  --prose-measure: 66ch;
  --prose-body-leading: 1.651;
  --prose-body-tracking: 0em;
  --prose-flow: clamp(1.5851rem, calc(1.5025rem + 0.4128vi), 1.874rem);
  --prose-paragraph-gap: clamp(1.1376rem, calc(1.0784rem + 0.2962vi), 1.3449rem);
  --prose-heading-1-scale: 1.146;
  --prose-heading-2-scale: 1.095;
  --prose-heading-3-scale: 1.067;
  --prose-heading-1-before: clamp(6.043rem, calc(5.7287rem + 1.5714vi), 7.1431rem);
  --prose-heading-1-after: clamp(1.0145rem, calc(0.9615rem + 0.265vi), 1.2rem);
  --prose-heading-2-before: clamp(4.2515rem, calc(4.0305rem + 1.1051vi), 5.0251rem);
  --prose-heading-2-after: clamp(1.0165rem, calc(0.9634rem + 0.2655vi), 1.2023rem);
  --prose-list-gap: clamp(1.3879rem, calc(1.3157rem + 0.3614vi), 1.6409rem);
  --prose-list-item-gap: 0.52em;
  --prose-list-indent: 1.25em;
  --prose-heading-measure: 24ch;
  --prose-heading-leading-scale: 1;
  --prose-lead-scale: 1;
  --prose-quote-gap: clamp(4.0792rem, calc(3.8671rem + 1.0603vi), 4.8214rem);
  --prose-quote-padding: 1.44rem;
  --prose-quote-border: 0.25rem;
  --prose-quote-scale: 1.118;
  --prose-pullquote-measure: 20ch;
  --prose-media-gap: clamp(3.5284rem, calc(3.345rem + 0.917vi), 4.1703rem);
  --prose-caption-gap: clamp(0.3792rem, calc(0.3595rem + 0.0987vi), 0.4483rem);
  --prose-section-gap: clamp(5.8452rem, calc(5.5412rem + 1.52vi), 6.9092rem);
  --prose-code-leading: 1.398;
  --prose-code-padding: 1rem;
  --prose-inline-code-pad-y: 0.07em;
  --prose-inline-code-pad-x: 0.32em;
  --prose-code-font-size: 0.907em;
  --prose-table-cell-pad: 0.63em;
}

/* Progressive enhancements: balance headings, pretty-wrap paragraphs, use tabular numbers for tables and metadata. */
.hype-prose {
  --flow-space: var(--prose-flow);
  max-inline-size: var(--prose-measure);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--type-body);
  font-weight: var(--body-weight);
  line-height: var(--prose-body-leading);
  letter-spacing: var(--prose-body-tracking);
  font-optical-sizing: auto;
  hyphens: auto;
  text-wrap: pretty;
}

.hype-prose > * {
  margin-block: 0;
}

.hype-prose > * + * {
  margin-block-start: var(--flow-space);
}

.hype-prose :where(h1, h2, h3, h4) {
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  text-wrap: balance;
}

.hype-prose h1 {
  font-size: clamp(2.8514rem, calc(2.1157rem + 3.6785vi), 5.4263rem);
  line-height: 0.898;
  letter-spacing: var(--tracking-heading-xl);
  margin-block-start: var(--prose-heading-1-before);
  max-inline-size: calc(var(--prose-heading-measure) * 0.86);
}

.hype-prose h2 {
  font-size: clamp(2.2708rem, calc(1.8083rem + 2.3122vi), 3.8893rem);
  line-height: 1.012;
  letter-spacing: var(--tracking-heading-l);
  margin-block-start: var(--prose-heading-2-before);
  max-inline-size: var(--prose-heading-measure);
}

.hype-prose h3 {
  font-size: clamp(1.8439rem, calc(1.5585rem + 1.4271vi), 2.8429rem);
  line-height: 1.06;
  letter-spacing: var(--tracking-heading-m);
  margin-block-start: calc(var(--prose-heading-2-before) * 0.78);
}

.hype-prose h4 {
  font-size: var(--type-heading-s);
  line-height: 1.096;
  letter-spacing: var(--tracking-heading-s);
  margin-block-start: calc(var(--prose-heading-2-before) * 0.64);
}

.hype-prose h1 + :where(p, ul, ol, figure, blockquote, pre, table) {
  margin-block-start: var(--prose-heading-1-after);
}

.hype-prose :where(h2, h3, h4) + :where(p, ul, ol, figure, blockquote, pre, table) {
  margin-block-start: var(--prose-heading-2-after);
}

.hype-prose > :where(h2, h3):has(+ :where(h3, h4)) {
  margin-block-end: calc(var(--prose-heading-2-after) * 0.45);
}

.hype-prose p + p {
  margin-block-start: var(--prose-paragraph-gap);
}

.hype-prose p + :where(ul, ol),
.hype-prose :where(ul, ol) + p {
  margin-block-start: var(--prose-list-gap);
}

.hype-prose :where(ul, ol) + :where(ul, ol) {
  margin-block-start: var(--prose-list-gap);
}

.hype-prose p,
.hype-prose li {
  max-inline-size: var(--prose-measure);
}

.hype-prose .lead {
  font-size: clamp(1.2rem, calc(1.1145rem + 0.4277vi), 1.4994rem);
  line-height: 1.585;
  letter-spacing: var(--tracking-body-l);
  max-inline-size: calc(var(--prose-measure) * 0.92);
}

.hype-prose a {
  color: inherit;
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.18em;
}

.hype-prose :where(strong, b) { font-weight: 720; }
.hype-prose :where(em, i) { font-style: italic; }
.hype-prose mark { background: var(--spot-soft); color: inherit; padding-inline: 0.15em; }
.hype-prose small { font-size: var(--type-caption); line-height: var(--leading-caption); }
.hype-prose sup, .hype-prose sub { font-size: 0.68em; line-height: 0; }

.hype-prose :where(ul, ol) {
  padding-inline-start: var(--prose-list-indent);
}

.hype-prose li + li {
  margin-block-start: var(--prose-list-item-gap);
}

.hype-prose :where(ul, ol) :where(ul, ol) {
  margin-block-start: var(--prose-list-item-gap);
  padding-inline-start: 1.05em;
}

.hype-prose blockquote,
.hype-prose .pullquote {
  border-inline-start: var(--prose-quote-border) solid var(--ink);
  font-size: clamp(1.3416rem, calc(1.246rem + 0.4781vi), 1.6763rem);
  line-height: 1.618;
  padding-inline-start: var(--prose-quote-padding);
  margin-block-start: var(--prose-quote-gap);
}

.hype-prose blockquote {
  color: var(--ink-soft);
}

.hype-prose .pullquote {
  max-inline-size: var(--prose-pullquote-measure);
  font-size: clamp(1.8923rem, calc(1.5994rem + 1.4646vi), 2.9175rem);
  line-height: var(--leading-heading-m);
  letter-spacing: var(--tracking-heading-m);
}

.hype-prose figure,
.hype-prose pre,
.hype-prose table {
  margin-block-start: var(--prose-media-gap);
}

.hype-prose figure + :where(p, h2, h3) {
  margin-block-start: var(--prose-section-gap);
}

.hype-prose :where(blockquote, pre, table, hr) + :where(p, h2, h3, h4, ul, ol) {
  margin-block-start: var(--prose-section-gap);
}

.hype-prose img,
.hype-prose video {
  display: block;
  inline-size: 100%;
  block-size: auto;
  border: 1px solid var(--rule);
}

.hype-prose figcaption {
  margin-block-start: var(--prose-caption-gap);
  font-size: var(--type-caption);
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
}

.hype-prose hr {
  border: 0;
  border-block-start: 1px solid var(--rule-strong);
  margin-block-start: var(--prose-section-gap);
}

.hype-prose table {
  border-collapse: collapse;
  inline-size: 100%;
  font-size: var(--type-body-s);
  font-variant-numeric: tabular-nums;
}

.hype-prose th,
.hype-prose td {
  border-block: 1px solid var(--rule);
  padding: var(--prose-table-cell-pad) 0.65em;
  text-align: start;
}

.hype-prose pre {
  overflow: auto;
  padding: var(--prose-code-padding);
  border: 1px solid var(--rule);
  background: var(--paper-muted);
  font-size: var(--prose-code-font-size);
  line-height: var(--prose-code-leading);
}

.hype-prose :where(code, kbd) {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  font-size: var(--prose-code-font-size);
}

.hype-prose :not(pre) > code,
.hype-prose kbd {
  background: var(--paper-muted);
  border: 1px solid var(--rule);
  padding: var(--prose-inline-code-pad-y) var(--prose-inline-code-pad-x);
}

.hype-prose details {
  border-block: 1px solid var(--rule);
  padding-block: var(--space-s);
}

.hype-prose summary {
  cursor: pointer;
  font-weight: 700;
}

.hype-prose .footnotes {
  font-size: var(--type-body-s);
  line-height: var(--leading-body-s);
  border-block-start: 1px solid var(--rule-strong);
  padding-block-start: var(--space-s);
}

/* Optional CMS compatibility */
.hype-prose :where(.wp-block-image, .wp-block-table, .wp-caption) {
  margin-block-start: var(--prose-media-gap);
}

.hype-prose :where(.wp-block-quote) {
  border-inline-start: 0.18rem solid currentColor;
  padding-inline-start: var(--space-s);
}

.hype-prose .alignwide {
  max-inline-size: var(--measure-wide);
}

.hype-prose .alignfull {
  max-inline-size: none;
}