Commit deab3fd
feat(brand): add _brand.yml support across the render pipeline
New `quarto-brand` crate owns the typed `_brand.yml` data model (color
palette + named theme colors, typography slots, logo, defaults) with
serde-driven validation via `deny_unknown_fields`. Ports Q1's
`Brand.getColor` palette/named-color resolution (with cycle detection),
monospace inline/block merging, and logo path resolution.
`quarto-sass::brand_layer` ports Q1's `brandColorLayer` /
`brandDefaultsBootstrapLayer` / `brandTypographyLayer` to produce
`SassLayer`s. Font-family values are quoted (one intentional Q2
improvement over Q1's bare emission, which is fragile for multi-word
names).
`ThemeSpec::Brand` is a new position marker for the literal token
`brand` in the `theme:` array — same semantics as Q1's
`format-html-scss.ts:216`. `ThemeConfig` grows an unresolved
`brand_ref: Option<BrandRef>` (path or inline block) populated by
`from_config_value` (pure, no I/O); a sync `ThemeConfig::resolve(&dyn
SystemRuntime, base_dir)` reads the file and produces a
`ResolvedThemeConfig` with a typed `Brand`. The split keeps the parsing
pure and routes all brand I/O through one site
(`CompileThemeCssStage::run`), so native CLI and WASM hub-client share
the code path via `SystemRuntime`.
`ThemeContext::with_brand` carries the resolved `Brand` into
`process_theme_specs`, which expands `ThemeSpec::Brand` into the
brand-derived layers. Cache key in `CompileThemeCssStage` hashes the
brand's YAML serialization so brand edits invalidate.
Coverage:
- 31 unit tests in `quarto-brand` (parse, color, typography, logo)
- 14 string-search + 6 grass-compile parity tests for brand_layer
- 12 ThemeConfig integration tests
- 2 end-to-end tests in `quarto-core/tests/brand_render.rs` that drive
the real `render_to_file` API against project + brand and brand-only
fixtures
- Manual smoke: `q2 render` against project+theme+brand, brand-only,
and explicit-position fixtures. Verified --bs-primary-rgb /
--brand-* / --bs-body-color / --bs-body-font-family in compiled CSS.
Workspace tests: 9292/9292 pass. `cargo xtask verify --skip-hub-build`
green.
Out of scope (filed as follow-ups): light/dark brand pairs (bd-v5z8w),
brand favicon hookup (bd-1elkd), navbar brand-image (bd-hp3tx), typst
brand (bd-dsco4), `quarto use brand` scaffolding (bd-1vlw8), wire into
future YAML validator (bd-q1fyw), scss-analysis annotations
(bd-u67gw), inline brand in single-file frontmatter (bd-rwxa0),
hub-client browser verify (bd-wjg4h).
Plan: claude-notes/plans/2026-05-20-brand-yml-support.md
Docs: docs/guide/themes/brand.qmd
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 75ef6db commit deab3fd
49 files changed
Lines changed: 4089 additions & 35 deletions
File tree
- .beads
- claude-notes/plans
- crates
- quarto-brand
- src
- tests
- fixtures
- brand-yaml
- kitchen-sink
- monospace-colors
- palette-colors
- use-brand
- basic-brand
- fonts
- multi-file-brand
- fonts
- nested-brand
- images
- quarto-core
- src/stage/stages
- tests
- quarto-sass
- src
- tests
- docs/guide
- themes
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
159 | 162 | | |
160 | 163 | | |
161 | 164 | | |
| |||
0 commit comments