Skip to content

Release: merge development into beta - #1080

Open
github-actions[bot] wants to merge 28 commits into
betafrom
development
Open

github-actions[bot] wants to merge 28 commits into
betafrom
development

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Automated PR to sync development changes to beta for beta release.

Merging this PR will trigger the beta release workflow.

Reminder: Add a major, minor, or patch label to this PR to control the version bump. Default is patch.

github-actions Bot and others added 16 commits October 5, 2026 05:48
The 1.2.22-beta.20261005054829 release bumped the version on beta. Without this,
development stays behind beta and the next development -> beta promotion
conflicts on the version file.

Version files resolve to development's side, which is the higher line,
so this never moves a version backwards.
The one bump from dependabot's security PR #1074 that development lacked and
that clears the repo's 2-day min-release-age. http-cache-semantics 4.3.0 is a
day old (published 4 Oct 02:56) and stays out until it clears the cooldown.
…0261005071908

chore(sync): carry beta back into development
The report published textRatio and uiRatio and left the column names to
carry the whole explanation. "textRatio" reads as body ink on the page.
It is not: it is the colour written ON the primary colour, against the
primary colour. A reviewer read vng's 11.98 that way, recomputed
--nldesign-color-text on white as 12.63, and concluded the report
disagreed with itself. It did not, and finding that out cost more than
publishing the pair would have.

The document now carries a `pairs` block naming the foreground and
background of each ratio, read off the two constants the audit passes to
pairRatio(), so the published name and the measured pair cannot drift.
The Node audit reads `parsed.sets`, so the new key costs it nothing.

Purely additive to the generated file: 10 insertions, no verdict or
ratio changed.
…1079)

CnBrandStripe in nextcloud-vue reads --cn-brand-stripe-* and knows no theme.
While the stripe is on, css/brand-stripe.css now sets those seven properties
on :root from the --nldesign-brand-stripe-* tokens, with the fallbacks the
top bar stripe uses, so a portal header draws the same three bands.
…dored source (#1089)

* feat(token-sets): denhaag declares its component tokens from its own source

The coverage audit read denhaag at 0 of the 87 --utrecht-* names the bridge
reads. It is the one bridge-zero set whose upstream is already vendored here:
scripts/sources/denhaag/ holds the pinned @Gemeente-DenHaag token CSS under
EUPL-1.2, so the values can be sourced instead of chosen.

scripts/brands/denhaag.json plus the captured
scripts/brands/denhaag.components.json regenerate css/tokens/denhaag.css
through scripts/generate-brand-set.mjs. The set now declares 81 of the 87
bridge names: 52 are Den Haag's own, 29 come from the shared role layer with
the ramp re-pointed at Den Haag colours.

Nothing is interpolated. The pink ramp, extra-limegreen and extra-purple have
no Den Haag family and are left out, which the generator reports as 6
unsubstituted literals. Six bridge names stay undeclared because neither the
source nor the role layer states them.

The palette is converted from hsl() to 8-bit sRGB hex, with the whole table in
the brand file. ContrastService::parseColor returns null for hsl(), so leaving
it would turn every measured Den Haag pair into an unmeasurable one.

primary moves from the invented #1a7a3e to Den Haag's own green-3 #238541, and
the header moves from green to white, which is what
--denhaag-page-header-background-color states.

token-sets.json records the font licence position: Den Haag names TheSans, a
LucasFonts retail face, so the set declares it and renders the self-hosted
Fira Sans until an administrator uploads the licensed one.

REUSE.toml names both copyright holders on the generated set and the brand
files, because their values are half Den Haag's and half ours.

* feat(token-sets): regenerate every artifact denhaag derives

The dark variant, the contrast report, the token reference page, the coverage
table and the two coverage claims all follow from css/tokens/denhaag.css, and
their staleness checks compare byte for byte.

`generate-dark-variants.php --force` rewrote all 58 variants and only
css/tokens/dark/denhaag.css differs from development. Verified after both
generator runs.

Contrast moves and the verdict holds: textRatio and uiRatio both 5.39 -> 4.66,
thresholds 4.5 and 3.0, verdict pass. The 15 measured Den Haag pairs stay 15
pass, 0 fail, 0 unevaluated, which is what converting the palette to hex buys.

--nldesign-color-primary-light-hover is green-1 rather than green-2. Den Haag
states no hover wash and uses green-2 only as a border colour. Deriving the
dark variant with it pushed --nldesign-color-primary to near-black #111111,
because the repair loop could not reach 4.5:1 for primary on the lightened
green-2 wash. With green-1 the dark primary is #55d27b.

tests/vitest/denhaagBridge.spec.js used denhaag as its example of a
semantic-only set, which it no longer is. The subject moves to tilburg, which
the test now asserts declares no --denhaag-* property, and a second test covers
the mixed case: denhaag keeps its own case card title and subtitle and still
takes the card border through the bridge.

The bridge header and the portals doc claimed no set declares a case card
property. cunningham already declared one before this change, so the count is
two.

* style(token-sets): drop the nested parentheses from the denhaag provenance

The generator repeats the provenance string inside section A's own comment, so
a parenthesised licence note read as a bracket inside a bracket. Same facts,
commas instead. Only the two generated files and the brand file move; the
contrast report and the coverage table do not.
…eld, esdoornveen, warmtepompacademie) (#1092)

* feat(brand-stripe): a set may draw a motif of its own, and the portal 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.

* feat(token-sets): Basisschool De Wilgenboom (wilgenboom)

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.

* feat(token-sets): Vaartveld College (vaartveld)

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.

* feat(token-sets): Esdoornveen, mbo college (esdoornveen)

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.

* feat(token-sets): Warmtepompacademie (warmtepompacademie)

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.

* feat(token-sets): list the four school sets, with their tests and docs

- 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.

* test(nav): the selected-entry label test reads a set's overrides at their 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.

* fix(token-sets): wilgenboom leaves the stripe to the administrator

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.

* docs(openspec): the school sets were checked live on Nextcloud 34
…0261005125944

chore(sync): carry beta back into development
…tif and the accent from any set (#1097)

* feat(public-bridge): a portal gets the whole role layer, the brand stripe and the accent from any set

A portal on zuiddrecht or a school set resolved 116 of the 489 roles the
site reads (no logo, header and DigiD button in browser defaults). The
bridge now names the measured 375, hands the stripe and its new inverse
motif to the site as --cn-brand-stripe-*, and reads a new accent
vocabulary (--nldesign-color-accent, -light, -text) into --thematiq-accent-*.

openspec/changes/brand-motif-on-portals

* feat(public-bridge): the footer's bottom band, one step darker than the footer ground

* feat(token-sets): a light website hero for the four school sets, read through the bridge

* chore(token-sets): regenerate dark variants and reference pages for the hero tokens

* docs(openspec): brand-motif-on-portals checked live on :8091
…ce under the current menu item (#1099)

Six tokens for the Zuiddrecht set on a portal: a light hero ground with dark
type (14.88:1) and the grey emblem as its watermark, and the current menu item
drawn as a blue piece of the red line under the menu. The dark variant is
regenerated from the set.
OpenRegisterAutoloader::ensure() called \OC_App::registerAutoloading(),
which Nextcloud 35 removed. The Error was swallowed by the catch-all, so
ensure() returned false and the federated-config listener was never
registered on 35. Register a PSR-4 loader for OCA\OpenRegister\ over the
openregister app's lib/ with spl_autoload_register(), using only public
IAppManager::isEnabledForAnyone() and getAppPath(). ensure()'s signature
and call site are unchanged; it still never throws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M7DxSg7d7wqqZsUppLWf7J
…sion

OCP\Util::getVersion() is deprecated since 31; this app's floor is 32,
so OCP\ServerVersion is always available. Resolved lazily from the
server container, keeping the existing Throwable fallbacks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M7DxSg7d7wqqZsUppLWf7J
The hydra phpcs gate rejects \OCP\Server::get() in lib/ (global container
lookup), and the extra class reference pushed ComplianceReportService over
the phpmd CouplingBetweenObjects limit. ServerVersion is now an optional
constructor dependency of ComplianceReportService and PlaygroundStateService
(autowired by the container on every supported server, 32+); without it the
existing fallbacks ("unknown" / 0) apply, as before in isolated unit tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M7DxSg7d7wqqZsUppLWf7J
fix(nc35): register OpenRegister PSR-4 prefix without OC_App
rubenvdlinde and others added 12 commits October 6, 2026 16:12
….2.22-beta.20261005054829

chore(release): sync beta back into development
…ry; Zuiddrecht draws its boards (#1106)

The Mijn Zuiddrecht boards draw 44px page titles, 2px outlined buttons,
pill status tags, 36px process steps filled blue when done and ringed red
when current, a light blue notice with a 1px border and a red mark under
the tab on screen. No --nldesign-color-* token can say any of that, and a
set that declared the --utrecht-* or --denhaag-* roles itself would change
its workplace pages too.

So the public bridge gains a website vocabulary, read by the bridge only:
--nldesign-website-heading-{1,2,3}-font-size, -control-border-width,
-badge-border-radius, -step-marker-size, -step-done-color,
-step-done-mark-color, -step-current-color, -step-current-background-color,
-notice-{background-color,border-color,border-width} and
-tab-{line,current}-color. Every role keeps today's value as its fallback;
the Den Haag step marker roles are wrapped by the generator from a new
`website` section of the mapping, never by hand. The notice ground and
border, the data badge radius and the two new --thematiq-tab-* roles carry
no fallback, as the website radii do, so a consumer's own fallback applies
where a set names none.

The zuiddrecht set names them all, plus the website corners it never
declared (4px controls, 6px cards). Dark variant and token reference
regenerated. publicBridgeRoleLayer.spec.js resolves every role for
zuiddrecht and holds the four school sets and vng to the values they had.
…e vocabulary; Zuiddrecht names them (#1128)

* feat(bridge): the site's page title, lead, notice text and surface are vocabulary; Zuiddrecht names them

A set may name --nldesign-website-page-title-size and -line-height,
--nldesign-website-lead-font-size, --nldesign-website-notice-color and
--nldesign-color-surface for its portal. The public bridge reads each (the
lead size keeps 20px as its fallback, the other four carry none), so a set
that names none keeps every value it had. The zuiddrecht set names them as
the Kop, Home and Contentpagina boards draw them: 2.75rem on 1.15, 18px,
#1A1A1A and #F4F6F9; every pair computed in the light and in the dark.
Dark variant and reference page regenerated.

* feat(bridge): the attention strip has names of its own; Zuiddrecht names its yellow "Let op" strip

--nldesign-website-attention-background-color, -border-color and -color
name an attention strip apart from the plain notice, which stays the light
blue of #1106. The public bridge reads them into --thematiq-attention-*
without a fallback, so a set that names none draws nothing new. Zuiddrecht:
#FFF4DE, #E8C77D, #1A1A1A (15.95:1; generated dark 10.41:1).
… guest pages and the top bar as the boards do (#1127)

* feat(workplace-layout): the light workplace draws the login page, the guest pages and the top bar as the boards do

While the workplace layout is light, css/workplace-layout.css now shows Nextcloud's own guest logo
above the login card (56px, the set's logo) and retires the in-card stamp; the card is 420px wide
with a hairline, the container radius, the cards' shadow colour, 32px of padding and a 24px title;
the controls are 44px with a 1px edge; the two text actions under the form are 14px, regular and
underlined; the footer line is muted with no plate. On a guest page the "Back to …" button's label,
which the NL Design link rule painted link-blue on blue, takes the login button label colour. The
top bar is 68px through --header-height, the app grid button a 40px square and the search field a
44px pill on the workspace colour; the dashboard's panel row stays transparent. No colour literal.

Spec: openspec/changes/workplace-layout-core-pages. Tests: tests/vitest/workplaceLayout.spec.js.

* fix(workplace-layout): only the login title starts at the left; a guest page keeps its centred title

* fix(workplace-layout): the login page's two text actions take the link colour

"Wachtwoord vergeten?" and the device login are blue on the NcLogin board and were ink live: the
NL Design text rule forces every span to the body text. The tertiary buttons now set the rule's own
opt-out, --nldesign-color-on-surface, to --nldesign-color-link (#3669A5 on Zuiddrecht, 5.64:1 on the
white card).
…s cards on the surface (#1130)

* feat(workplace-layout): the light workplace draws the login page, the guest pages and the top bar as the boards do

While the workplace layout is light, css/workplace-layout.css now shows Nextcloud's own guest logo
above the login card (56px, the set's logo) and retires the in-card stamp; the card is 420px wide
with a hairline, the container radius, the cards' shadow colour, 32px of padding and a 24px title;
the controls are 44px with a 1px edge; the two text actions under the form are 14px, regular and
underlined; the footer line is muted with no plate. On a guest page the "Back to …" button's label,
which the NL Design link rule painted link-blue on blue, takes the login button label colour. The
top bar is 68px through --header-height, the app grid button a 40px square and the search field a
44px pill on the workspace colour; the dashboard's panel row stays transparent. No colour literal.

Spec: openspec/changes/workplace-layout-core-pages. Tests: tests/vitest/workplaceLayout.spec.js.

* fix(workplace-layout): only the login title starts at the left; a guest page keeps its centred title

* feat(workplace-layout): the light workplace draws the standard apps as cards on the surface

While the workplace layout is light, css/workplace-layout.css draws the dashboard's panels, the Files
list, the settings sections and the thematiq panel as cards on the grey workspace (the container
radius, a hairline, the cards' shadow colour), with the card title size on the dashboard, the Files
header and footer rows and the README block back on the card's background, a quiet 14px muted header
row, and a 44px token set select in the theme picker. No colour literal.

Spec: openspec/changes/workplace-layout-standard-apps. Tests: tests/vitest/workplaceLayout.spec.js.

* fix(workplace-layout): the login page's two text actions take the link colour

"Wachtwoord vergeten?" and the device login are blue on the NcLogin board and were ink live: the
NL Design text rule forces every span to the body text. The tertiary buttons now set the rule's own
opt-out, --nldesign-color-on-surface, to --nldesign-color-link (#3669A5 on Zuiddrecht, 5.64:1 on the
white card).
…fresh its reference page (#1105)

#1099 gave Zuiddrecht --nldesign-website-nav-current-in-line and
--nldesign-website-nav-current-color, but no stylesheet in thematiq (or
the portal) reads either name, so TokenSetVocabularyTest failed on every
PHPUnit leg, and the committed reference page still listed 82 tokens
instead of the set's current ones. Removing the two unread names changes
nothing on screen. The dark variant is regenerated from the set, and
docs/reference/token-sets/zuiddrecht.md from composer docs:token-reference,
so it now also lists the hero tokens from #1099 that public-bridge.css
does read.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Ruben van der Linde <ruben@conduction.nl>
…ss names, for this set only (#1116)

* feat(zuiddrecht): the workplace boards' measures on the library's class names, for this set only

* feat(zuiddrecht): the overrides outrank the library's scoped rules, headings through the NL Design token, the panel 264px wide

* fix(zuiddrecht): the attention card's primary action keeps a white label under the link sheet

* fix(zuiddrecht): the 34px counter is the stat widget's, not the countdown tile's

* fix(zuiddrecht): the chosen view keeps a readable label under the element sheet's span rule

* feat(capabilities): a set that ships an emblem exposes it as logos.emblem

* style(capabilities): the docblock as php-cs-fixer wants it

* test(zuiddrecht): the emblem test builds Capabilities the way development does; the override file holds no colour literal of its own

After merging development, Capabilities no longer takes a TokenSetService
(#1114), so the emblem test passes the four services the other tests pass.
The override file's light rules now carry the workplace boards' measures,
so the dark workspace test asserts what it meant: outside the dark scopes
no colour literal, a token's last-resort fallback aside.
…very layout choice in the bundle (#1129)

* feat(layout): four more layout options with per-theme defaults, and every layout choice in the bundle

Where the brand stripe is drawn (brand_stripe_placement), the navigation
width (navigation_width), the selected navigation entry's style
(navigation_active_style) and the login watermark (login_watermark) join
the workplace layout and the brand stripe as admin options. Each follows
the active token set's layout block until an administrator chooses, and a
set that names none keeps exactly what it had: Nextcloud's width, the
default entry, the stripe in both places, the watermark drawn. Zuiddrecht
names a 264px navigation and the soft entry, as its workplace boards draw
them. Each option is one conditional stylesheet; the width travels as one
inline :root variable. The configuration bundle now carries all six layout
choices as stored (config.layoutOptions, bundle version 4).

* fix(layout-options): the navigation width field no longer shares its id with the inline style

The admin page carries <style id="thematiq-navigation-width"> in its head,
and the width input had the same id. getElementById returned the style, the
form read its value as "undefined", and on the live instance no layout
option saved: width, selected entry, stripe placement and watermark all
stayed unset. The input is now thematiq-navigation-width-input, and a test
holds every admin-template id apart from every inline style id.
…ts inside it (#1135)

[class*='widget'] also matched BEM elements such as .cn-stages-widget__bar.
With the rule's ID-level specificity it painted dossiq's stage bars the page
background, so the bars were drawn but invisible on the case page. The rule
now skips classes holding 'widget__'; every container keeps its solid ground.

A jsdom test asks which elements the sheet's background selectors match: a
widget container and a panel still match, a stages bar does not. It fails on
the old sheet.
…ptions carry the navigation (#1137)

The navigation card link (cn-app-nav__card-link) is drawn in the link colour,
underlined, 14px 600, as DqZijbalk does, in the zuiddrecht set only. The
hard-coded 264px navigation and selected-entry wash are removed: since #1129
the set's layout block resolves both with nothing stored, and the literals
only overruled an administrator who picks another width or the plain entry.
The set also restores the text, grey and accent colours of dossiq's opt-in
My tasks list, which the NL Design element sheet repaints.

This branch has not been deployed

No deployments
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.

4 participants