feat(type): self-host Manrope and DM Mono so they actually render

`styles.css` line 1 carried a malformed rule for the life of the site:

  @font-face{font-family:Manrope;src:url('https://fonts.googleapis.com/css2?...')}

`src:` in an @font-face must point at a font binary. That URL returns a CSS
stylesheet, so no browser could ever load a face from it. Every
`font-family:Manrope,Arial,sans-serif` fell through to Arial, and 'DM Mono' was
never declared as a family at all, so it fell through to generic monospace. The
intended typography has never once been seen.

Task 02 spotted this and was told to default to deleting the dead rule and
declaring the stacks that actually render. It recorded that decision, deferred
the deletion to "future component tasks", and nothing picked it up. The human
has now chosen the other branch: the real fonts.

Self-hosted rather than linked from fonts.googleapis.com because
scripts/audit-ui.mjs rejects any external <link>/<script>, and because the site
is presented in workshop rooms with unreliable networks. Latin and latin-ext
subsets only — the site is EN and PT-BR, so the cyrillic, greek and vietnamese
subsets Google also serves are dropped. Manrope ships as one variable file
covering 400-800. 89 KB total across six faces, all SIL OFL.

One public/fonts/fonts.css serves both trees, with relative url()s that each
consumer resolves against that file's own location: BaseLayout.astro links it
for Astro pages, the legacy root styles.css @imports it.

This changes how every page renders. That is the point, and it is the one
sanctioned visual change in the migration — screenshots taken before today show
Arial and are no longer a valid baseline. The three governing documents that
said "do not add a webfont" are updated so the next design-system-keeper does
not undo this.

Adds .stylelintignore, mirroring .prettierignore's legacy list for the same
reason: staging the minified styles.css to change one declaration produced ~180
declaration-block-single-line-max-declarations errors and blocked the commit.
public/fonts/fonts.css is deliberately excluded from that ignore list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Marcos Paulo
2026-09-05 19:07:55 +00:00
parent 421c84ff92
commit 7f11b6e88e
14 changed files with 211 additions and 56 deletions
+14
View File
@@ -0,0 +1,14 @@
# Font licences
Both families here are licensed under the SIL Open Font License, Version 1.1,
which permits redistribution and self-hosting.
| Family | Designer | Source |
| ------- | ---------------------------- | -------------------------------------- |
| Manrope | Mikhail Sharanda | https://github.com/sharanda/manrope |
| DM Mono | Colophon Foundry for Deja Vu | https://github.com/googlefonts/dm-mono |
Full licence text: https://openfontlicense.org/open-font-license-official-text/
The `.woff2` files are the latin and latin-ext subsets as served by Google
Fonts. They are unmodified.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+100
View File
@@ -0,0 +1,100 @@
/* Manrope and DM Mono, self-hosted.
*
* `styles.css` line 1 used to carry this:
*
* @font-face{font-family:Manrope;src:url('https://fonts.googleapis.com/css2?...')}
*
* `src:` in an @font-face must point at a font binary. That URL returns a CSS
* stylesheet, so no browser could ever load a face from it: every
* `font-family:Manrope,Arial,sans-serif` fell through to Arial, and 'DM Mono'
* was never declared at all, so it fell through to the generic monospace face.
* The intended typography has never rendered. This file is the fix.
*
* Self-hosted rather than linked from fonts.googleapis.com because
* `scripts/audit-ui.mjs` rejects any external <link>/<script>, and because the
* site is shown in workshop rooms with unreliable networks.
*
* Both families are SIL Open Font License 1.1 — see OFL.md in this directory.
* Subsets are latin and latin-ext only: the site is EN and PT-BR, so the
* cyrillic, greek and vietnamese subsets Google also serves are dropped.
*
* The url()s are relative on purpose. Both consumers resolve them against this
* file's own location:
* - Astro pages: <link> in BaseLayout.astro, served from `${base}fonts/`
* - legacy pages: @import at the top of the root `styles.css`
*/
/* DM Mono 400 — latin */
@font-face {
font-family: 'DM Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('dm-mono-400-latin.woff2') format('woff2');
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* DM Mono 400 — latin-ext */
@font-face {
font-family: 'DM Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('dm-mono-400-latin-ext.woff2') format('woff2');
unicode-range:
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
U+A720-A7FF;
}
/* DM Mono 500 — latin */
@font-face {
font-family: 'DM Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('dm-mono-500-latin.woff2') format('woff2');
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* DM Mono 500 — latin-ext */
@font-face {
font-family: 'DM Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('dm-mono-500-latin-ext.woff2') format('woff2');
unicode-range:
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
U+A720-A7FF;
}
/* Manrope 400 800 — latin */
@font-face {
font-family: Manrope;
font-style: normal;
font-weight: 400 800;
font-display: swap;
src: url('manrope-var-latin.woff2') format('woff2');
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Manrope 400 800 — latin-ext */
@font-face {
font-family: Manrope;
font-style: normal;
font-weight: 400 800;
font-display: swap;
src: url('manrope-var-latin-ext.woff2') format('woff2');
unicode-range:
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
U+A720-A7FF;
}
Binary file not shown.
Binary file not shown.