diff --git a/CHANGES b/CHANGES index a08c2fb5..dd6cd65e 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,17 @@ $ uv add gp-sphinx --prerelease allow +### What's new + +#### `gp-sphinx`: Default font-preload list now covers heading, italic, and bold-code FOUT + +`DEFAULT_SPHINX_FONT_PRELOAD` adds IBM Plex Sans 500 / 600 normal +(`h1`–`h6` and `blockquote.epigraph`), Sans 400 italic (`` body +text and announcement bars), and Mono 700 normal (bold inline code). +Downstream consumers that render those surfaces no longer need a +local `sphinx_font_preload` override to avoid first-paint FOUT. +(#34) + ### Bug fixes #### `gp-sphinx`: MystLexer highlights `:::{directive}` colon-fences diff --git a/docs/configuration.md b/docs/configuration.md index 3c204c5b..697b901c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -130,7 +130,7 @@ These are injected even though they are not exposed as `DEFAULT_*` constants: | Constant | Value | | --- | --- | | `DEFAULT_SPHINX_FONTS` | IBM Plex Sans (400/500/600/700, normal+italic) and IBM Plex Mono (400, normal+italic) Fontsource definitions | -| `DEFAULT_SPHINX_FONT_PRELOAD` | `("IBM Plex Sans", 400, "normal")`, `("IBM Plex Sans", 700, "normal")`, `("IBM Plex Mono", 400, "normal")` | +| `DEFAULT_SPHINX_FONT_PRELOAD` | IBM Plex Sans 400 / 500 / 600 / 700 normal + 400 italic, IBM Plex Mono 400 / 700 normal | | `DEFAULT_SPHINX_FONT_FALLBACKS` | Metric-adjusted Arial and Courier fallback declarations | | `DEFAULT_SPHINX_FONT_CSS_VARIABLES` | `--font-stack`, `--font-stack--monospace`, `--font-stack--headings` | diff --git a/packages/gp-sphinx/src/gp_sphinx/defaults.py b/packages/gp-sphinx/src/gp_sphinx/defaults.py index 39310b1f..b6375b1c 100644 --- a/packages/gp-sphinx/src/gp_sphinx/defaults.py +++ b/packages/gp-sphinx/src/gp_sphinx/defaults.py @@ -232,15 +232,32 @@ class FontConfig(_FontConfigRequired, total=False): DEFAULT_SPHINX_FONT_PRELOAD: list[tuple[str, int, str]] = [ ("IBM Plex Sans", 400, "normal"), + ("IBM Plex Sans", 500, "normal"), + ("IBM Plex Sans", 600, "normal"), ("IBM Plex Sans", 700, "normal"), + ("IBM Plex Sans", 400, "italic"), ("IBM Plex Mono", 400, "normal"), + ("IBM Plex Mono", 700, "normal"), ] """Font preload hints for critical rendering path. +Each entry is ``(family, weight, style)``. Faces in this list are +emitted as ```` tags so the browser +fetches them in parallel with the critical CSS/HTML, before +``font-display: block`` would otherwise hide text waiting on a +lazy ``@font-face`` request. + +The list covers every face Furo / ``furo-tw.css`` is observed to +demand above the fold: body (Sans 400), headings + sidebar labels +(Sans 500), epigraph blockquotes (Sans 600), strong / current +sidebar (Sans 700), inline ```` and announcement-bar emphasis +(Sans 400 italic), code blocks (Mono 400), and bold inline code +```` (Mono 700). + Examples -------- >>> len(DEFAULT_SPHINX_FONT_PRELOAD) -3 +7 """ DEFAULT_SPHINX_FONT_FALLBACKS: list[dict[str, str]] = [ diff --git a/tests/test_config.py b/tests/test_config.py index c4301d35..ac89dd1a 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -218,7 +218,7 @@ def test_merge_sphinx_config_default_fonts() -> None: ) assert len(result["sphinx_fonts"]) == 2 assert result["sphinx_fonts"][0]["family"] == "IBM Plex Sans" - assert len(result["sphinx_font_preload"]) == 3 + assert len(result["sphinx_font_preload"]) == 7 assert len(result["sphinx_font_fallbacks"]) == 2 assert "--font-stack" in result["sphinx_font_css_variables"]