The text scale as sixteen components, every style bound to font-size and font-weight because a typography token breaks line-height in Penpot.
Sixteen components, twenty variants
The scale - one component each: H1 (Breakpoint: Mobile 36/40 · Desktop 48/48) · H2 30/36 with a base.border rule under it · H3 24/32 · H4 20/28 · Lead 20/28 · Large 18/28 · P 16/28 · Small 14/20 · Muted 14/20
Typography / Rich Text - none: 636 × 788 - eleven nested instances of the other fifteen
Using the Typography
Why is every style bound to two tokens instead of one?
Because a typography token applied in Penpot takes the line-height with it and breaks it. So each style binds font-size and font-weight separately - text.3xl.font-size and font-weight.semibold - and sets its line-height as a plain number. It is the one compromise on this page, and it belongs to the medium rather than to the kit.
What are the line-heights?
40 on H1 mobile and 48 on desktop, then 36, 32, 28 down the headings, 28 on Lead and Large, 28 on P - the source's leading-7 - 24 on Blockquote and List, 20 on Small and Muted, and 24 on the code block, which is the loosest of the lot at 1.71 and right for text a reader scans by column as much as by line. They are correct values held as numbers, so a change to the scale has to be made in two places.
Why is H1 the only responsive one?
Because it is the only one that needs to be. 36 on mobile and 48 on desktop is the source's text-4xl with lg:text-5xl. A 30px H2 works at every width, and giving every heading a Breakpoint axis would double the component count without changing a single page.
When do I use Lead rather than P?
Lead is the one sentence under a page title that says what the page is about - 20/28 in base.muted-foreground, one per page, directly under the H1. P is everything else. A docs page without a Lead makes every reader scan the first paragraph to work out whether they are in the right place, which is exactly the job Lead does at a glance.
What is the difference between Small, Muted and P?
Weight and colour, and what they are for. Small is 14 at medium in base.foreground - a label, something you want read. Muted is 14 at normal in base.muted-foreground - metadata, something available but not competing. P is 16 for prose. Body copy at 16 inside a card is almost always too big; that is what Small and Muted exist for.
Why does H2 carry a rule?
Because the source does - h2 is the only heading with border-b and pb-2, which puts a 1px base.border 8 under the text and takes the component to 45 tall. It is what separates a section from a subsection at a glance in a long article, and it is the reason H2 and H3 are not interchangeable even though their sizes are only six apart.
Why is the blockquote not italic?
Because Geist ships no italic cut. The source writes the blockquote in italic, and a browser will fake one by slanting the roman - Penpot will not, and a synthetic oblique is not a thing to bake into a component. The 2px rule and the 24 inset are doing the work instead, which are the parts a reader actually notices.
Why is the list bullet a character?
Because Penpot has no list primitive, so the marker is typed into the line rather than generated. It works, and under dir=rtl it follows the text like any other glyph - but it does not hang outside the text block the way list-disc does, so a wrapped line starts under the bullet rather than beside it. Rebuild it as a real list in code.
Which table is this?
The article one. Typography / Table is a 314 × 160 block of four rows built from Typography / Table / Item, whose axes are Variant - Head or Cell - and Even, which fills the row with base.muted for zebra striping. The Table page's component is the data one, with sortable heads and eleven cell types. They look similar and are not interchangeable.
What is Rich Text for?
Showing the scale doing its job. It is the sixteenth component and the only one made entirely of the other fifteen - eleven nested instances at 636 wide, in the order a real article uses them. Change H2 and the article follows without anyone opening it, which is the whole argument for building it as instances rather than as text.
How wide should a column of text be?
About 672, which is roughly 75 characters at 16px and what the usage frame uses. Narrower than 480 and the eye jumps back too often; past 900 it loses the start of the next line. The same paragraph at three widths reads three ways with no change to the type at all, which is worth seeing once.
Does it work right to left?
The scale does, entirely - a font-size, a font-weight and a fill have no direction, so dir on an ancestor is the whole job. The blocks are where the work is: the blockquote rule is drawn as a rectangle before the text rather than as border-left, so it moves on its own, and in code it wants border-inline-start with padding-inline-start. The table's first column and the list's bullets follow the text the same way.