Skip to content

fix(templates): make the CV template's second hardcoded color themeable - #3699

Merged
santifer merged 1 commit into
mainfrom
fix/theme-secondary-color
Sep 5, 2026
Merged

santifer merged 1 commit into
mainfrom
fix/theme-secondary-color

Conversation

@Schlaflied

Copy link
Copy Markdown
Contributor

What does this PR do?

theme-style.mjs's "Themeable tokens" feature (#1837) exposes exactly 4 style: keys in STYLE_VAR_MAP: accent_color, font_family, font_size, margin. But templates/cv-template.html actually uses two distinct colors, not one — --accent-color (themeable) and a second color hardcoded as the literal hsl(270, 70%, 45%), used directly (not through any CSS variable) in .job-company, .project-title, .edu-org, .cert-org, .award-org, and the .header-gradient background's second stop (plus its html[lang="ar"] RTL mirror).

Because that second color was never routed through a CSS custom property, it was invisible to the theming system — a user asking for a monochrome CV via style: { accent_color: "#000000" } still got purple company names and a purple header gradient. This PR adds secondary_color → --secondary-color to STYLE_VAR_MAP, gives it a :root default matching the previous hardcoded value, and replaces every hardcoded occurrence in cv-template.html with var(--secondary-color).

templates/cv-template.zh-minimal.html and templates/resume-template.html had the identical hardcoded-purple pattern (verified by grep — no other shipped template does), so the same fix is applied there for consistency. Neither of those two templates currently exposes --accent-color theming at all (that's a separate, pre-existing gap, out of scope here), so each gets its own minimal :root { --secondary-color: ... } declaration rather than reusing cv-template.html's block.

templates/cover-letter-template.html and the other CV variants (compact/executive/jake/leadership/modern) don't use this color at all and are untouched.

Related issue

Closes #3695

Type of change

  • Bug fix
  • New feature
  • Documentation / translation
  • Refactor (no behavior change)

Details

theme-style.mjs

  • Added secondary_color: '--secondary-color' to STYLE_VAR_MAP.
  • Updated the module doc comment's example style: block.

templates/cv-template.html

  • Added --secondary-color: hsl(270, 70%, 45%) to the existing :root theme-defaults block.
  • Replaced all 7 remaining hardcoded hsl(270, 70%, 45%) occurrences with var(--secondary-color): the header gradient's second stop, its html[lang="ar"] RTL mirror, and the .job-company/.project-title/.edu-org/.cert-org/.award-org colors.

templates/cv-template.zh-minimal.html, templates/resume-template.html

  • Same fix: a new :root { --secondary-color: hsl(270, 70%, 45%); } block plus var() substitution everywhere the literal previously appeared, including the html[lang="ar"] header-gradient mirror.

config/profile.example.yml

  • Documented secondary_color alongside the existing 4 tokens.

tests/theme-style.test.mjs

  • styleTokensFrom key-count assertion 4 → 5, now also asserting secondary_color maps correctly.
  • New readStyleTokens case reading secondary_color from a profile file.
  • New buildThemeStyleBlock/injectThemeStyle round-trip assertions for --secondary-color, mirroring the existing --accent-color coverage.
  • New template guard: for cv-template.html, cv-template.zh-minimal.html, and resume-template.html, asserts each declares a --secondary-color :root default, reads it via var() everywhere, has no leftover hardcoded hsl(270, 70%, 45%), and no circular var() default.

No rendered-output change without a style.secondary_color override in config/profile.yml — the new :root defaults reproduce the exact previous hardcoded values.

Checklist

  • I have read CONTRIBUTING.md
  • Bug fix — exempt from issue-first (issue exists: theme-style.mjs's Themeable tokens don't cover the CV template's second hardcoded color (hsl(270,70%,45%)) #3695)
  • My PR does not include personal data
  • I ran node test-all.mjs — 7790 passed, 5 failed. All 5 failures are pre-existing and unrelated to this change (js-yaml is not installed at .../node_modules/js-yaml — a stale node_modules in this worktree checkout, affecting cv-section-order.test.mjs's linkRepoPackage helper and the generate-pdf-batch/generate-pdf-page-budget suites; plus one unrelated followup-cadence.mjs e2e crash). theme-style.mjs's own suite — which also imports js-yaml and is unaffected by the missing-module issue — passed all 24 assertions, including every new secondary_color case.
  • My changes respect the Data Contract (system-layer files only)
  • Aligns with the roadmap

theme-style.mjs's STYLE_VAR_MAP exposes only accent_color, font_family,
font_size, and margin, but cv-template.html actually uses two distinct
colors: --accent-color (themeable) and a second color hardcoded as the
literal hsl(270, 70%, 45%) for company/institution names and the header
gradient's second stop. That second color was invisible to the theming
system, so a style: override (e.g. accent_color: "#000000" for a
monochrome CV) could never fully recolor the CV.

Adds a secondary_color token mapping to --secondary-color, gives it a
:root default matching the previous hardcoded value, and replaces every
hardcoded hsl(270, 70%, 45%) in cv-template.html, cv-template.zh-minimal.html
and resume-template.html (the two other shipped templates with the same
pattern) with var(--secondary-color). No rendered-output change without a
profile override.

Closes #3695

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@santifer

santifer commented Sep 2, 2026

Copy link
Copy Markdown
Member

I see this, @Schlaflied, and the diagnosis holds: .job-company, .edu-org and friends read a literal hsl(270, 70%, 45%) that no style: key can reach, so a themed CV kept a purple second color no matter what. Exposing it as secondary_color through the same STYLE_VAR_MAP path is the right shape. It goes into the next merge batch (today's runs are closed); nothing needed from you.

@Scott-Emberson Scott-Emberson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at head 246c4b7. The owned test tests/theme-style.test.mjs pins this with a literal-count guard rather than a generic var() check, which is the robust way to do it. Across the three templates it requires the hsl(270, 70%, 45%) literal to survive only as the :root default (exactly one occurrence), so the moment any rule reverts to the hardcoded purple the count goes above one and it reddens; it also requires var(--secondary-color) to be present and guards the dead-fallback circular case. The diff confirms every previously-hardcoded occurrence (.job-org, .edu-org, .cert-org, .award-org, and the header gradient in both directions) is swapped to the variable, so the count-equals-one invariant genuinely binds those rules. The style-token round trip gained a secondary_color assertion mirroring accent_color, and the earlier zh-TW / ja / ko / zh CJK regression blocks are outside the diff and unchanged.

The substance here is templates/cv-template.html, outside our owned paths, so this is a test-axis review: the owned test is sound and the revert-detection is real, but the merge of the template change is the maintainer's call. Nothing blocking from the tests/ side.

@santifer
santifer merged commit 351f7f5 into main Sep 5, 2026
12 checks passed
@santifer
santifer deleted the fix/theme-secondary-color branch September 5, 2026 08:06
@santifer

santifer commented Sep 5, 2026

Copy link
Copy Markdown
Member

Another solid one, @Schlaflied. Promoting the second hardcoded colour to --secondary-color across the three templates, with a template guard that fails on any leftover hsl(270, 70%, 45%) beyond the :root default, closes the gap #1837 left. Merged, closes #3695.

@santifer santifer mentioned this pull request Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

theme-style.mjs's Themeable tokens don't cover the CV template's second hardcoded color (hsl(270,70%,45%))

3 participants