Font Sizes, per role, per width

A fifth section between Fonts and Spacing. The same four roles the families use,
so a template asks for a role and gets both — and a role used at two sizes on
purpose collapses to one, which was the trade taken over a separate list of text
roles.

The live preview builds the same stylesheet the site renders, because a size is
three values and an inline style cannot carry a media query.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-01 08:03:21 +01:00
co-authored by Claude Opus 5
parent 8f26d0d3b6
commit 5f7e4d7d61
3 changed files with 188 additions and 3 deletions
+30
View File
@@ -655,3 +655,33 @@ export function applySpacing(document: Document, spacing: SpacingDraft): () => v
}
};
}
/**
* The chosen type sizes, applied to a rendered page before they are saved.
*
* ── A stylesheet, not classes and not properties ──
*
* Colours and families are custom properties on `<html>`, which the panel can set directly. A size is
* three values, one per breakpoint, so it has to carry media queries — and only a stylesheet can. The
* site renders exactly this element, marked `data-font-sizes`; this finds it or makes one.
*
* The cleanup restores what was there, including removing an element the site had not rendered — which
* is the ordinary case, since it renders none until something is chosen.
*/
export function applyFontSizes(document: Document, css: string): () => void {
const existing = document.querySelector<HTMLStyleElement>('style[data-font-sizes]');
const element = existing ?? document.createElement('style');
const before = existing?.textContent ?? null;
if (!existing) {
element.setAttribute('data-font-sizes', '');
document.head.append(element);
}
element.textContent = css;
return () => {
if (before === null) element.remove();
else element.textContent = before;
};
}