Skip to content

feat(token-sets): four demo schools in Zuiddrecht (wilgenboom, vaartveld, esdoornveen, warmtepompacademie) - #1092

Merged
rubenvdlinde merged 9 commits into
developmentfrom
feat/school-token-sets
Oct 5, 2026
Merged

rubenvdlinde merged 9 commits into
developmentfrom
feat/school-token-sets

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Four token sets, one per finished school design, built the way zuiddrecht is: wilgenboom (Basisschool De Wilgenboom), vaartveld (Vaartveld College), esdoornveen (Esdoornveen, mbo college) and warmtepompacademie (Warmtepompacademie). Spec: openspec/changes/school-token-sets.

What each set ships

  • css/tokens/<set>.css on the nldesign vocabulary, with the design's main, main-deep, main-light, accent and accent-text colours, the fixed status pills and the workplace values from the Cunningham layer (ink #1B1C1D, muted #5E6168, line #E4E6EA, workspace #F5F6F8).
  • A generated dark variant, and css/token-overrides/<set>.css for the dark page and workspace, the 200 by 44 login wordmark, and the dark values the generator leaves under AA.
  • Four logos (colour, white as -dark, emblem, grey emblem for the login watermark) and a token-sets.json entry with a light workplace layout block.
  • Its typefaces, bundled and OFL-annotated: Lexend; Red Hat Display over Red Hat Text; IBM Plex Sans with IBM Plex Mono; Barlow Semi Condensed over Barlow.
  • A generated reference page, plus updated counts, contrast report and coverage table.

Three small shared additions

  • --nldesign-brand-stripe-image: the brand stripe draws a set's own image in place of the three bands. That is where Zuiddrecht's three bands live, so the school motifs are there too (twigs, canal, slanted cut, temperature line). The stripe is on by default only for esdoornveen, whose 6px cut fits inside the top bar the way Zuiddrecht's 5px stripe does.
  • --nldesign-website-border-radius and -large, read only by css/public-bridge.css, so the website gets its own corners (10/14, 6/10, 4/8, 3/6) while the workplace keeps 8 and 12.
  • The bridge's heading roles read --nldesign-component-heading-font-family before the text face.

Existing sets are unchanged. The example-* education sets are untouched.

Verified

  • bash scripts/token-set-gate.sh: exit 0 (PHPUnit 344 tests, vitest 370).
  • npm run lint, npm run format, npm run stylelint, npm run test:l10n, check:l10n-js, test:fonts, test:component-scopes, audit:token-sets:check, test:token-set-coverage, check:manifest: all exit 0.
  • openspec validate school-token-sets: valid. vendor/bin/hydra-gates --scope-to-diff --base origin/development: exit 0.
  • composer check:strict: lint, phpcs, phpmd, psalm and phpstan green; cs:check flagged one alignment in a test I added, fixed. test:all skips here (no server tree).
  • Full vitest: green except playgroundOwnStage.spec.js, whose five tests timed out at 5 s under load and pass when run alone.
  • Live on Nextcloud 34: each set selected, and computed values read from the Files app (light and dark), the settings navigation, the login page and the portal site. Fonts, primary, workspace, dark surface #121315, watermark, login wordmark, the esdoornveen stripe, the portal's website radius roles and the heading faces all matched.

Known gaps

  • The portal paints what the public bridge maps. Like zuiddrecht, these sets declare no --utrecht-* role layer, so the portal header and the DigiD button render unstyled. The header and footer motifs are portaliq's work; portaliq draws no motif today, not even Zuiddrecht's.
  • Den Haag's mijn-omgeving components keep --nldesign-border-radius, which comes from the generated mapping, so their corners follow the workplace scale.
  • REUSE lint was not run locally (the tool isn't installed). fontLicences.spec.js checks the notices and annotations.
  • Inherited: the test files I touched carry phpcs findings that were there before (named arguments, @return tags). phpcs.xml does not cover tests.

🤖 Generated with Claude Code

… gets website corners and heading faces

- css/brand-stripe.css draws --nldesign-brand-stripe-image when a set names
  one, in place of the three bands. Unset, the stripe is the gradient it was.
- css/public-bridge.css maps the website's control and card roles onto
  --nldesign-website-border-radius and -large, with no fallback, so a set
  that names neither leaves every portal as it was. Only the bridge reads
  them, so the workplace keeps Nextcloud's 8px and 12px.
- The bridge's heading roles read --nldesign-component-heading-font-family
  before the text face.
- Fonts for the four school sets (Fontsource 5.3.0, OFL 1.1, latin woff2):
  Lexend, Red Hat Display, Red Hat Text, Barlow, Barlow Semi Condensed, IBM
  Plex Sans 500 and IBM Plex Mono 400 and 500. IBM Plex Mono moves from the
  notice-only table into FAMILIES; its 400 file keeps its old name and is
  byte-identical to the package's.

Spec: openspec/changes/school-token-sets.
Token file, generated dark variant, overrides (dark page and workspace, login wordmark, and the dark values the generator leaves under AA), four logos and the reference page. Colours, faces and radii from the design; see openspec/changes/school-token-sets.
Token file, generated dark variant, overrides (dark page and workspace, login wordmark, and the dark values the generator leaves under AA), four logos and the reference page. Colours, faces and radii from the design; see openspec/changes/school-token-sets.
Token file, generated dark variant, overrides (dark page and workspace, login wordmark, and the dark values the generator leaves under AA), four logos and the reference page. Colours, faces and radii from the design; see openspec/changes/school-token-sets.
Token file, generated dark variant, overrides (dark page and workspace, login wordmark, and the dark values the generator leaves under AA), four logos and the reference page. Colours, faces and radii from the design; see openspec/changes/school-token-sets.
- token-sets.json lists wilgenboom, vaartveld, esdoornveen and
  warmtepompacademie on nldesign, each with a light workplace layout block;
  wilgenboom and esdoornveen also turn the brand stripe on, as their
  designed Nextcloud login shows the motif.
- tests/vitest/schoolTokenSets.spec.js computes every text pair in the light
  and both dark scopes, and checks the palette, overrides, faces, logos,
  motif and the public bridge's website corners. The token-set gate runs it.
- LayoutOptionsServiceTest and SetLogoReachTest name the new sets.
- Regenerated: contrast report, token reference index, coverage table and
  set counts. Logo inventory and counts (57), brand identity, changelog.
…heir real specificity

css/token-overrides/<set>.css puts :root in front of the dark scopes so it outranks the generated dark file that loads after it. The test's cascade matched neither the prefixed selector nor the extra specificity, so it measured the generated value the overrides replace (esdoornveen: 4.42:1 hovered, where the page shows 5.67:1). Control: removing esdoornveen's override makes the test fail again. Also aligns LayoutOptionsServiceTest with php-cs-fixer.
Measured on Nextcloud 34: the stripe sits inside the 50px top bar, and the 14px twigs covered the bottom of the wordmark and of the search field. The designed workplace bar carries no motif, so the set no longer turns the stripe on; the twigs stay declared and draw along the top bar and the login card when an administrator turns it on. esdoornveen's 6px cut fits the way zuiddrecht's 5px stripe does and stays on.
@rubenvdlinde
rubenvdlinde merged commit 9f4e837 into development Oct 5, 2026
34 checks passed
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/thematiq @ 75baa78

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
test-fonts ✅
test-token-set-coverage ✅
composer ✅ ✅ 107/107
npm ✅ ✅ 2/2
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅
Newman ✅
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ✅

Quality workflow — 2026-10-05 12:25 UTC

Download the full PDF report from the workflow artifacts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant