diff --git a/css/brand-stripe.css b/css/brand-stripe.css
index 4c1f583f4..d6e49d7cb 100644
--- a/css/brand-stripe.css
+++ b/css/brand-stripe.css
@@ -136,4 +136,15 @@
--cn-brand-stripe-ratio-2: var(--nldesign-brand-stripe-ratio-2, 1);
--cn-brand-stripe-ratio-3: var(--nldesign-brand-stripe-ratio-3, 1);
--cn-brand-stripe-height: var(--nldesign-brand-stripe-height, 4px);
+ /*
+ * The motif, when the set names one, and its variant for a dark band
+ * (openspec/changes/brand-motif-on-portals). No fallback: with the set
+ * silent both are the guaranteed-invalid value and the component draws its
+ * three bands, exactly as before.
+ */
+ --cn-brand-stripe-image: var(--nldesign-brand-stripe-image);
+ --cn-brand-stripe-image-inverse: var(
+ --nldesign-brand-stripe-image-inverse,
+ var(--nldesign-brand-stripe-image)
+ );
}
diff --git a/css/public-bridge.css b/css/public-bridge.css
index d1d54bbea..673382479 100644
--- a/css/public-bridge.css
+++ b/css/public-bridge.css
@@ -360,6 +360,766 @@
--nldesign-hero-title-color: var(--nldesign-color-primary-text, #fff);
--nldesign-hero-body-color: var(--nldesign-color-primary-light, #eee);
+ /*
+ * THE ROLE LAYER THE PORTAL SITE READS (openspec/changes/brand-motif-on-portals).
+ *
+ * A set that declares only `--nldesign-*` (zuiddrecht, the four school
+ * sets, and every set the coverage line above counts as nldesignOnly) used
+ * to reach the site with 116 of the 489 component roles it reads, against
+ * 489 for an `example-*` set that carries its own role layer. Measured on a
+ * portal with `wilgenboom` in place of `example-basisschool`: no logo, the
+ * header and the DigiD button in browser defaults, the footer without its
+ * padding. A portal that moved to a school set looked worse than before.
+ *
+ * So the roles the site reads are named here, once, for every set:
+ *
+ * colours from the set's `--nldesign-*` layer, each with a fallback;
+ * logos from `--nldesign-logo-url`, which the portal resolves to an
+ * absolute address, and the set's light logo for the footer;
+ * geometry (spacing, sizes, the type scale) as neutral values, the scale
+ * of the reference implementation the vendored CSS came from.
+ *
+ * A set with a role layer of its own loads after this file and keeps every
+ * value it declares; tests/vitest/publicBridgeRoleLayer.spec.js holds the
+ * list to what the site reads and the `example-*` sets to their own values.
+ */
+
+ /* Logos. The footer band is dark, so it takes the light variant the
+ * portal names in --nldesign-logo-inverse-url when the set ships one. */
+ --conduction-logo-header-background-image: var(--nldesign-logo-url, none);
+ --conduction-logo-navbar-background-image: var(--nldesign-logo-url, none);
+ --conduction-logo-footer-background-image: var(
+ --nldesign-logo-inverse-url,
+ var(--nldesign-logo-url, none)
+ );
+ --conduction-logo-header-block-size: var(--nldesign-website-logo-height, 50px);
+ --conduction-logo-header-inline-size: var(--nldesign-website-logo-width, 96px);
+ --conduction-logo-navbar-block-size: var(--nldesign-website-logo-height, 50px);
+ --conduction-logo-navbar-inline-size: var(--nldesign-website-logo-width, 96px);
+ --conduction-logo-footer-block-size: var(--nldesign-website-logo-height, 50px);
+ --conduction-logo-footer-inline-size: var(--nldesign-website-logo-width, 96px);
+ /*
+ * A logo that carries the organisation's name (a wordmark) makes the site
+ * title beside it a second copy. Such a set says so with
+ * `--nldesign-website-logo-text-size: 0`; the portal then keeps the title
+ * for screen readers only. No fallback: unset keeps the portal's size.
+ */
+ --thematiq-logo-text-font-size: var(--nldesign-website-logo-text-size);
+
+ /* The dropdown under a menu item */
+ --conduction-primary-top-nav-dropdown-background-color: var(
+ --nldesign-color-background,
+ #fff
+ );
+ --conduction-primary-top-nav-dropdown-color: var(--nldesign-color-text, #1b1b23);
+ --conduction-primary-top-nav-dropdown-current-background-color: var(
+ --nldesign-color-primary-light,
+ #eee
+ );
+ --conduction-primary-top-nav-dropdown-current-color: var(
+ --nldesign-color-text,
+ #1b1b23
+ );
+ --conduction-primary-top-nav-dropdown-hover-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --conduction-primary-top-nav-dropdown-hover-color: var(
+ --nldesign-color-text,
+ #1b1b23
+ );
+ --conduction-tooltip-background-color: var(--nldesign-color-text, #1b1b23);
+ --conduction-tooltip-color: var(--nldesign-color-background, #fff);
+
+ /* The tilburg roles the site's own components read */
+ --tilburg-color-dark-alpha-50: rgba(0, 0, 0, 0.05);
+ --tilburg-color-extra-purple: var(--nldesign-color-primary, #1b1b23);
+ --tilburg-color-green-100: var(
+ --nldesign-component-status-badge-success-background-color,
+ rgba(var(--nldesign-color-success-rgb, 57, 135, 12), 0.12)
+ );
+ --tilburg-color-green-300: var(--nldesign-color-success, #39870c);
+ --tilburg-color-orange-100: var(
+ --nldesign-component-status-badge-warning-background-color,
+ rgba(var(--nldesign-color-warning-rgb, 225, 112, 0), 0.12)
+ );
+ --tilburg-color-orange-300: var(--nldesign-color-warning, #e17000);
+ --tilburg-color-pink-100: var(--nldesign-color-primary-light, #eee);
+ --tilburg-color-pink-200: var(
+ --nldesign-color-primary-light-hover,
+ var(--nldesign-color-primary-light, #ddd)
+ );
+ --tilburg-color-pink-300: var(--nldesign-color-primary, #1b1b23);
+ --tilburg-color-pink-400: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-color-red-100: var(
+ --nldesign-component-status-badge-error-background-color,
+ rgba(var(--nldesign-color-error-rgb, 213, 43, 30), 0.12)
+ );
+ --tilburg-color-red-300: var(--nldesign-color-error, #d52b1e);
+ --tilburg-color-red-400: var(
+ --nldesign-color-error-hover,
+ var(--nldesign-color-error, #d52b1e)
+ );
+ --tilburg-document-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-document-inverse-color: var(--nldesign-color-primary-text, #fff);
+ --tilburg-document-subtle-color: var(--nldesign-color-text-muted, #75758a);
+ --tilburg-feedback-informative-color: var(
+ --nldesign-color-info,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-feedback-negative-color: var(--nldesign-color-error, #d52b1e);
+ --tilburg-feedback-positive-color: var(--nldesign-color-success, #39870c);
+ --tilburg-feedback-warning-border-color: var(--nldesign-color-warning, #e17000);
+ --tilburg-feedback-warning-color: var(--nldesign-color-warning, #e17000);
+ --tilburg-focus-background-color: var(--nldesign-color-primary-light, #eee);
+ --tilburg-focus-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-form-control-background-color: var(--nldesign-color-background, #fff);
+ --tilburg-form-control-border-color: var(
+ --nldesign-color-border-dark,
+ var(--nldesign-color-background-darker, #8a929e)
+ );
+ --tilburg-form-control-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-form-control-disabled-color: var(--nldesign-color-text-muted, #75758a);
+ --tilburg-form-control-focus-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-form-control-hover-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-form-control-placeholder-color: var(
+ --nldesign-color-text-muted,
+ #75758a
+ );
+ --tilburg-form-control-read-only-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-heading-color: var(--nldesign-color-text, #1b1b23);
+ --tilburg-interaction-active-color: var(
+ --nldesign-color-link-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-interaction-color: var(
+ --nldesign-color-link,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-interaction-hover-color: var(
+ --nldesign-color-link-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-line-border-color: var(--nldesign-color-border, #e2e2ea);
+ /* The header's account links: a filled button in the primary colour, as
+ * the vendored header draws them. */
+ --tilburg-navigation-background-color: var(--nldesign-color-primary, #1b1b23);
+ --tilburg-navigation-color: var(--nldesign-color-primary-text, #fff);
+ --tilburg-navigation-hover-background-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-navigation-hover-color: var(--nldesign-color-primary-text, #fff);
+ --tilburg-navigation-mobile-background-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --tilburg-navigation-mobile-item-border-bottom-color: var(
+ --nldesign-color-border,
+ #e2e2ea
+ );
+
+ /* Buttons: every state the site draws, from the primary and its tints */
+ --utrecht-button-background-color: transparent;
+ --utrecht-button-border-color: var(--nldesign-color-primary, #1b1b23);
+ --utrecht-button-color: var(--nldesign-color-primary, #1b1b23);
+ --utrecht-button-hover-background-color: var(
+ --nldesign-color-primary-light,
+ #eee
+ );
+ --utrecht-button-hover-border-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-hover-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-active-background-color: var(
+ --nldesign-color-primary-light-hover,
+ var(--nldesign-color-primary-light, #ddd)
+ );
+ --utrecht-button-active-border-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-active-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-focus-background-color: var(
+ --nldesign-color-primary-light,
+ #eee
+ );
+ --utrecht-button-focus-border-color: transparent;
+ --utrecht-button-focus-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-button-disabled-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-button-disabled-border-color: transparent;
+ --utrecht-button-disabled-color: var(--nldesign-color-text-muted, #75758a);
+ --utrecht-button-primary-action-border-color: var(
+ --nldesign-color-button-primary-border,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-primary-action-hover-border-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-primary-action-hover-color: var(
+ --nldesign-color-primary-text,
+ #fff
+ );
+ --utrecht-button-primary-action-active-background-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-primary-action-active-border-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-primary-action-active-color: var(
+ --nldesign-color-primary-text,
+ #fff
+ );
+ --utrecht-button-primary-action-focus-background-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-primary-action-focus-border-color: transparent;
+ --utrecht-button-primary-action-focus-color: var(
+ --nldesign-color-primary-text,
+ #fff
+ );
+ --utrecht-button-primary-action-disabled-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-button-primary-action-disabled-border-color: transparent;
+ --utrecht-button-primary-action-disabled-color: var(
+ --nldesign-color-text-muted,
+ #75758a
+ );
+ --utrecht-button-secondary-action-border-color: var(
+ --nldesign-color-primary,
+ #1b1b23
+ );
+ --utrecht-button-secondary-action-hover-background-color: var(
+ --nldesign-color-primary-light,
+ #eee
+ );
+ --utrecht-button-secondary-action-hover-border-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-secondary-action-hover-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-secondary-action-active-background-color: var(
+ --nldesign-color-primary-light-hover,
+ var(--nldesign-color-primary-light, #ddd)
+ );
+ --utrecht-button-secondary-action-active-border-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-secondary-action-active-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-secondary-action-focus-background-color: var(
+ --nldesign-color-primary-light,
+ #eee
+ );
+ --utrecht-button-secondary-action-focus-border-color: var(
+ --nldesign-color-primary,
+ #1b1b23
+ );
+ --utrecht-button-secondary-action-focus-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-secondary-action-disabled-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-button-secondary-action-disabled-border-color: transparent;
+ --utrecht-button-secondary-action-disabled-color: var(
+ --nldesign-color-text-muted,
+ #75758a
+ );
+ --utrecht-button-subtle-background-color: transparent;
+ --utrecht-button-subtle-border-color: transparent;
+ --utrecht-button-subtle-color: var(
+ --nldesign-color-link,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-subtle-hover-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-button-subtle-hover-border-color: transparent;
+ --utrecht-button-subtle-hover-color: var(
+ --nldesign-color-link-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-subtle-active-background-color: var(
+ --nldesign-color-background-dark,
+ #e2e2ea
+ );
+ --utrecht-button-subtle-active-border-color: transparent;
+ --utrecht-button-subtle-active-color: var(
+ --nldesign-color-link-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-button-subtle-focus-background-color: var(
+ --nldesign-color-primary-light,
+ #eee
+ );
+ --utrecht-button-subtle-focus-border-color: transparent;
+ --utrecht-button-subtle-focus-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-button-subtle-disabled-background-color: transparent;
+ --utrecht-button-subtle-disabled-border-color: transparent;
+ --utrecht-button-subtle-disabled-color: var(
+ --nldesign-color-text-muted,
+ #75758a
+ );
+
+ /* Links, lists, separators, alerts and the accordion */
+ --utrecht-link-active-color: var(
+ --nldesign-color-link-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-link-focus-background-color: transparent;
+ --utrecht-link-focus-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-link-text-decoration-color: currentcolor;
+ --utrecht-breadcrumb-nav-link-disabled-color: var(
+ --nldesign-color-text-muted,
+ #75758a
+ );
+ --utrecht-document-inverse-color: var(--nldesign-color-primary-text, #fff);
+ --utrecht-paragraph-lead-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-paragraph-small-color: var(--nldesign-color-text-muted, #75758a);
+ --utrecht-unordered-list-marker-color: var(--nldesign-color-primary, #1b1b23);
+ --utrecht-separator-color: var(--nldesign-color-border, #e2e2ea);
+ --utrecht-alert-info-border-color: var(
+ --nldesign-color-info,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --utrecht-alert-info-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-alert-ok-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-alert-warning-color: var(--thematiq-status-warning-text);
+ --utrecht-alert-error-color: var(--thematiq-status-error-text);
+ --utrecht-alert-icon-positive-color: var(--nldesign-color-success, #39870c);
+ --utrecht-alert-icon-warning-color: var(--nldesign-color-warning, #e17000);
+ --utrecht-accordion-button-active-background-color: var(
+ --nldesign-color-background-dark,
+ #e2e2ea
+ );
+ --utrecht-accordion-button-border-color: transparent;
+ --utrecht-accordion-panel-border-color: transparent;
+
+ /* Form controls: every state */
+ --utrecht-form-label-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-form-field-error-message-color: var(--thematiq-status-error-text);
+ --utrecht-textbox-background-color: var(--nldesign-color-background, #fff);
+ --utrecht-textbox-placeholder-color: var(--nldesign-color-text-muted, #75758a);
+ --utrecht-textbox-focus-background-color: var(--nldesign-color-background, #fff);
+ --utrecht-textbox-focus-border-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-textbox-focus-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-textbox-invalid-background-color: var(
+ --nldesign-color-background,
+ #fff
+ );
+ --utrecht-textbox-invalid-border-color: var(--nldesign-color-error, #d52b1e);
+ --utrecht-textbox-invalid-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-textbox-disabled-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-textbox-disabled-border-color: var(
+ --nldesign-color-border-dark,
+ #8a929e
+ );
+ --utrecht-textbox-disabled-color: var(--nldesign-color-text-muted, #75758a);
+ --utrecht-textbox-read-only-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-textbox-read-only-border-color: var(
+ --nldesign-color-border-dark,
+ #8a929e
+ );
+ --utrecht-textbox-read-only-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-select-background-color: var(--nldesign-color-background, #fff);
+ --utrecht-select-border-color: var(
+ --nldesign-color-border-dark,
+ var(--nldesign-color-background-darker, #8a929e)
+ );
+ --utrecht-select-color: var(--nldesign-color-text, #1b1b23);
+ --utrecht-select-disabled-background-color: var(
+ --nldesign-color-background-hover,
+ #f0f0f3
+ );
+ --utrecht-select-disabled-border-color: var(
+ --nldesign-color-border-dark,
+ #8a929e
+ );
+ --utrecht-select-disabled-color: var(--nldesign-color-text-muted, #75758a);
+ --utrecht-select-font-family: var(--nldesign-font-family, system-ui, sans-serif);
+ --utrecht-radio-button-label-font-family: var(
+ --nldesign-font-family,
+ system-ui,
+ sans-serif
+ );
+ --utrecht-heading-4-font-family: var(
+ --nldesign-component-heading-font-family,
+ var(--nldesign-font-family, system-ui, sans-serif)
+ );
+ --utrecht-heading-5-font-family: var(
+ --nldesign-component-heading-font-family,
+ var(--nldesign-font-family, system-ui, sans-serif)
+ );
+ --utrecht-heading-6-font-family: var(
+ --nldesign-component-heading-font-family,
+ var(--nldesign-font-family, system-ui, sans-serif)
+ );
+
+ /* Geometry: the spacing, sizes and type scale, brand neutral */
+ --conduction-primary-top-nav-dropdown-hover-text-decoration: underline;
+ --conduction-primary-top-nav-dropdown-text-decoration: none;
+ --conduction-tooltip-border-radius: 0px;
+ --conduction-tooltip-padding-block-end: 8px;
+ --conduction-tooltip-padding-block-start: 8px;
+ --conduction-tooltip-padding-inline-end: 14px;
+ --conduction-tooltip-padding-inline-start: 14px;
+ --tilburg-border-radius-lg: 16px;
+ --tilburg-border-radius-md: 8px;
+ --tilburg-border-radius-round: 999px;
+ --tilburg-border-radius-sm: 4px;
+ --tilburg-border-width-lg: 4px;
+ --tilburg-border-width-md: 2px;
+ --tilburg-border-width-sm: 1px;
+ --tilburg-document-font-size: 16px;
+ --tilburg-document-font-weight: 400;
+ --tilburg-document-line-height: 150%;
+ --tilburg-document-strong-font-weight: 700;
+ --tilburg-erm-font-size: 16px;
+ --tilburg-footer-link-hover-text-decoration: underline;
+ --tilburg-footer-link-text-decoration: none;
+ --tilburg-form-control-border-width: 1px;
+ --tilburg-heading-font-weight: 700;
+ --tilburg-icon-functional-size: 24px;
+ --tilburg-navigation-font-weight: 700;
+ --tilburg-pointer-target-min-size: 48px;
+ --tilburg-size-2xs: 16px;
+ --tilburg-size-4xs: 4px;
+ --tilburg-size-icon-4xl: 48px;
+ --tilburg-size-icon-md: 24px;
+ --tilburg-size-icon-sm: 16px;
+ --tilburg-size-md: 48px;
+ --tilburg-size-xs: 24px;
+ --tilburg-space-block-ant: 4px;
+ --tilburg-space-block-beetle: 8px;
+ --tilburg-space-block-cat: 32px;
+ --tilburg-space-block-dog: 48px;
+ --tilburg-space-block-flea: 2px;
+ --tilburg-space-block-mouse: 16px;
+ --tilburg-space-block-pig: 64px;
+ --tilburg-space-block-rabbit: 24px;
+ --tilburg-space-block-rat: 20px;
+ --tilburg-space-block-snail: 12px;
+ --tilburg-space-column-ant: 2px;
+ --tilburg-space-column-beetle: 4px;
+ --tilburg-space-column-cat: 24px;
+ --tilburg-space-column-dog: 28px;
+ --tilburg-space-column-elephant: 96px;
+ --tilburg-space-column-horse: 64px;
+ --tilburg-space-column-mouse: 12px;
+ --tilburg-space-column-pig: 32px;
+ --tilburg-space-column-rabbit: 20px;
+ --tilburg-space-column-rat: 16px;
+ --tilburg-space-column-snail: 8px;
+ --tilburg-space-column-tiger: 48px;
+ --tilburg-space-inline-ant: 4px;
+ --tilburg-space-inline-beetle: 8px;
+ --tilburg-space-inline-mouse: 16px;
+ --tilburg-space-inline-rabbit: 24px;
+ --tilburg-space-inline-snail: 12px;
+ --tilburg-space-row-cat: 24px;
+ --tilburg-space-row-dog: 28px;
+ --tilburg-space-row-elephant: 96px;
+ --tilburg-space-row-mouse: 12px;
+ --tilburg-space-row-rabbit: 20px;
+ --tilburg-space-row-rat: 16px;
+ --tilburg-space-row-snail: 8px;
+ --tilburg-space-row-tiger: 48px;
+ --tilburg-space-text-beetle: 4px;
+ --tilburg-space-text-mouse: 8px;
+ --tilburg-space-text-snail: 6px;
+ --tilburg-typography-font-size-2xl: 32px;
+ --tilburg-typography-font-size-3xl: 36px;
+ --tilburg-typography-font-size-lg: 20px;
+ --tilburg-typography-font-size-md: 16px;
+ --tilburg-typography-font-size-sm: 14px;
+ --tilburg-typography-font-size-xl: 24px;
+ --tilburg-typography-font-weight-bold: 700;
+ --tilburg-typography-font-weight-normal: 400;
+ --tilburg-typography-line-height-md: 150%;
+ --tilburg-typography-line-height-sm: 125%;
+ --utrecht-accordion-button-border-width: 1px;
+ --utrecht-accordion-button-line-height: 150%;
+ --utrecht-accordion-button-padding-block-end: 12px;
+ --utrecht-accordion-button-padding-block-start: 12px;
+ --utrecht-accordion-button-padding-inline-end: 16px;
+ --utrecht-accordion-button-padding-inline-start: 16px;
+ --utrecht-accordion-panel-border-width: 4px;
+ --utrecht-alert-border-width: 2px;
+ --utrecht-button-border-width: 1px;
+ --utrecht-button-font-size: 16px;
+ --utrecht-button-font-weight: 700;
+ --utrecht-button-icon-size: 24px;
+ --utrecht-button-line-height: 150%;
+ --utrecht-button-min-block-size: 48px;
+ --utrecht-button-min-inline-size: 48px;
+ --utrecht-button-padding-block-end: 12px;
+ --utrecht-button-padding-block-start: 12px;
+ --utrecht-button-padding-inline-end: 16px;
+ --utrecht-button-padding-inline-start: 16px;
+ --utrecht-button-primary-action-font-weight: 700;
+ --utrecht-button-secondary-action-font-weight: 700;
+ --utrecht-button-subtle-font-weight: 700;
+ --utrecht-data-list-item-key-font-weight: 700;
+ --utrecht-document-font-size: 16px;
+ --utrecht-document-line-height: 150%;
+ --utrecht-form-label-checkbox-font-weight: 400;
+ --utrecht-form-label-font-size: 16px;
+ --utrecht-form-label-font-weight: 700;
+ --utrecht-heading-1-font-size: 36px;
+ --utrecht-heading-1-font-weight: 700;
+ --utrecht-heading-1-line-height: 125%;
+ --utrecht-heading-2-font-size: 32px;
+ --utrecht-heading-2-font-weight: 700;
+ --utrecht-heading-2-line-height: 125%;
+ --utrecht-heading-3-font-size: 24px;
+ --utrecht-heading-3-font-weight: 700;
+ --utrecht-heading-3-line-height: 125%;
+ --utrecht-heading-4-font-size: 20px;
+ --utrecht-heading-4-font-weight: 700;
+ --utrecht-heading-4-line-height: 150%;
+ --utrecht-heading-5-font-size: 16px;
+ --utrecht-heading-5-font-weight: 700;
+ --utrecht-heading-5-line-height: 150%;
+ --utrecht-heading-6-font-size: 14px;
+ --utrecht-heading-6-font-weight: 700;
+ --utrecht-heading-6-line-height: 150%;
+ --utrecht-link-focus-text-decoration: none;
+ --utrecht-link-focus-text-decoration-thickness: auto;
+ --utrecht-link-hover-text-decoration: none;
+ --utrecht-link-hover-text-decoration-thickness: auto;
+ --utrecht-link-icon-margin-inline: 4px;
+ --utrecht-link-icon-size: 24px;
+ --utrecht-link-text-decoration: underline;
+ --utrecht-link-text-decoration-thickness: auto;
+ --utrecht-link-text-underline-offset: auto;
+ --utrecht-ordered-list-font-size: 16px;
+ --utrecht-ordered-list-item-margin-block-end: 4px;
+ --utrecht-ordered-list-item-margin-block-start: 4px;
+ --utrecht-ordered-list-padding-inline-start: 24px;
+ --utrecht-paragraph-font-size: 16px;
+ --utrecht-paragraph-font-weight: 400;
+ --utrecht-paragraph-lead-font-size: 20px;
+ --utrecht-paragraph-lead-font-weight: 400;
+ --utrecht-paragraph-lead-line-height: 150%;
+ --utrecht-paragraph-line-height: 150%;
+ --utrecht-paragraph-small-font-size: 14px;
+ --utrecht-paragraph-small-font-weight: 400;
+ --utrecht-paragraph-small-line-height: 150%;
+ --utrecht-radio-button-label-font-size: 16px;
+ --utrecht-radio-button-label-font-weight: 400;
+ --utrecht-radio-button-label-line-height: 150%;
+ --utrecht-radio-button-min-block-size: 16px;
+ --utrecht-radio-button-min-inline-size: 16px;
+ --utrecht-select-border-width: 1px;
+ --utrecht-select-font-size: 16px;
+ --utrecht-select-hover-border-width: 2px;
+ --utrecht-select-max-inline-size: 400px;
+ --utrecht-separator-margin-block-end: 32px;
+ --utrecht-separator-margin-block-start: 32px;
+ --utrecht-skip-link-text-decoration: underline;
+ --utrecht-table-cell-padding-inline-start: 12px;
+ --utrecht-textbox-border-width: 1px;
+ --utrecht-textbox-font-size: 16px;
+ --utrecht-textbox-font-weight: 400;
+ --utrecht-textbox-max-inline-size: 400px;
+ --utrecht-textbox-padding-block-start: 12px;
+ --utrecht-textbox-padding-inline-end: 12px;
+ --utrecht-textbox-padding-inline-start: 12px;
+ --utrecht-unordered-list-font-size: 16px;
+ --utrecht-unordered-list-item-margin-block-end: 4px;
+ --utrecht-unordered-list-item-margin-block-start: 4px;
+ --utrecht-unordered-list-padding-inline-start: 24px;
+
+ --tilburg-box-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
+ --tilburg-box-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.1);
+ --conduction-tooltip-z-index: 9999;
+
+ /* Tabs */
+ --conduction-tabs-scroll-button-background-color: var(
+ --nldesign-color-primary,
+ #1b1b23
+ );
+ --conduction-tabs-scroll-button-color: var(--nldesign-color-primary-text, #fff);
+ --conduction-tabs-scroll-button-hover-background-color: var(
+ --nldesign-color-primary-hover,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --conduction-tabs-scroll-button-hover-color: var(
+ --nldesign-color-primary-text,
+ #fff
+ );
+ --conduction-tabs-tab-background-color: transparent;
+ --conduction-tabs-tab-color: var(--nldesign-color-text, #1b1b23);
+ --conduction-tabs-tab-font-family: var(
+ --nldesign-font-family,
+ system-ui,
+ sans-serif
+ );
+ --conduction-tabs-tab-hover-background-color: transparent;
+ --conduction-tabs-tab-hover-color: var(--nldesign-color-text, #1b1b23);
+ --conduction-tabs-tab-list-border-bottom-color: var(
+ --nldesign-color-border,
+ #e2e2ea
+ );
+ --conduction-tabs-tab-selected-background-color: transparent;
+ --conduction-tabs-tab-selected-border-bottom-color: var(--thematiq-accent-color);
+ --conduction-tabs-tab-selected-color: var(--nldesign-color-text, #1b1b23);
+ --conduction-tabs-tab-selected-hover-color: var(--nldesign-color-text, #1b1b23);
+ --conduction-tabs-tab-bottom: -3px;
+ --conduction-tabs-tab-button-bottom: 0px;
+ --conduction-tabs-tab-font-size: 16px;
+ --conduction-tabs-tab-font-weight: 400;
+ --conduction-tabs-tab-hover-font-weight: 700;
+ --conduction-tabs-tab-letter-spacing: normal;
+ --conduction-tabs-tab-list-border-bottom-style: solid;
+ --conduction-tabs-tab-list-border-bottom-width: 0.3rem;
+ --conduction-tabs-tab-list-margin-block-end: 0px;
+ --conduction-tabs-tab-list-padding-inline-end: 2px;
+ --conduction-tabs-tab-list-padding-inline-start: 2px;
+ --conduction-tabs-tab-min-height: 48px;
+ --conduction-tabs-tab-padding-block-end: 6px;
+ --conduction-tabs-tab-padding-block-start: 6px;
+ --conduction-tabs-tab-padding-inline-end: 12px;
+ --conduction-tabs-tab-padding-inline-start: 12px;
+ --conduction-tabs-tab-panel-padding-block-end: 24px;
+ --conduction-tabs-tab-panel-padding-block-start: 24px;
+ --conduction-tabs-tab-panel-padding-inline-end: 24px;
+ --conduction-tabs-tab-panel-padding-inline-start: 24px;
+ --conduction-tabs-tab-selected-border-bottom-style: solid;
+ --conduction-tabs-tab-selected-border-bottom-width: 0.3rem;
+ --conduction-tabs-tab-selected-font-weight: 700;
+ --conduction-tabs-tab-selected-hover-font-weight: 700;
+
+ /*
+ * THE ACCENT (openspec/changes/brand-motif-on-portals).
+ *
+ * A school set has a second colour besides its interactive primary: sun
+ * yellow, aqua, maple rose, ember. It marks the menu item on screen, the
+ * count badges and the "today first" card; it is never the colour of a
+ * button or a link. A set names it in three vocabulary tokens:
+ *
+ * --nldesign-color-accent the accent itself (bars, underlines)
+ * --nldesign-color-accent-light its light wash (a card's ground)
+ * --nldesign-color-accent-text text in the accent's hue on that wash
+ *
+ * The site reads the three roles below. A set that names no accent gets
+ * its primary, so the marks still show, in the brand's main colour.
+ */
+ --thematiq-accent-color: var(
+ --nldesign-color-accent,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ --thematiq-accent-light-color: var(
+ --nldesign-color-accent-light,
+ var(--nldesign-color-primary-light, #eee)
+ );
+ --thematiq-accent-text-color: var(
+ --nldesign-color-accent-text,
+ var(--nldesign-color-primary, #1b1b23)
+ );
+ /* A count badge: the set's own navigation badge, else the accent with the
+ * primary's text colour on it. */
+ --thematiq-badge-background-color: var(
+ --nldesign-component-navigation-badge-background-color,
+ var(--thematiq-accent-color)
+ );
+ --thematiq-badge-color: var(
+ --nldesign-component-navigation-badge-color,
+ var(--nldesign-color-primary-text, #fff)
+ );
+
+ /*
+ * The footer's bottom band: the footer's own ground one step darker, as
+ * the school designs draw it. No fallback: a set that names no footer
+ * colour keeps the band it had.
+ */
+ --thematiq-footer-legal-background-color: color-mix(
+ in srgb,
+ var(--nldesign-color-footer-background) 80%,
+ #000
+ );
+
+ /*
+ * A light hero (openspec/changes/brand-motif-on-portals). The vendored hero
+ * band paints itself in the primary with white type; a set whose website
+ * hero is a light ground names it, its first button and a watermark
+ * (--nldesign-hero-decoration-image, usually the emblem the portal names
+ * in --nldesign-emblem-url). No fallbacks: a set that names none keeps the
+ * hero it had. The type colours are --nldesign-hero-title-color and
+ * --nldesign-hero-body-color above, which such a set declares itself.
+ */
+ --thematiq-hero-background-color: var(--nldesign-hero-background-color);
+ --thematiq-hero-action-background-color: var(
+ --nldesign-hero-action-background-color
+ );
+ --thematiq-hero-action-color: var(--nldesign-hero-action-color);
+ --thematiq-hero-decoration-image: var(--nldesign-hero-decoration-image);
+
+ /*
+ * THE BRAND STRIPE ON THE PORTAL (openspec/changes/brand-motif-on-portals).
+ *
+ * css/brand-stripe.css draws the stripe on Nextcloud's own pages; a portal
+ * never loads that file, so the same tokens reach the site here, under the
+ * names the component library's CnBrandStripe reads.
+ *
+ * NO FALLBACKS, unlike brand-stripe.css. That file is loaded only while
+ * the stripe is on; this one is loaded for every set, and a set that
+ * declares no stripe must not suddenly grow one on its portal. With the
+ * set silent every name below is the guaranteed-invalid value, the site's
+ * own `var(--cn-brand-stripe-height, 0)` applies and nothing is drawn.
+ *
+ * The image is the motif (the twigs, the canal, the cut, the temperature
+ * line). The inverse image is the same motif for a dark band such as the
+ * footer; a set that names none draws its one image there too.
+ */
+ --cn-brand-stripe-color-1: var(--nldesign-brand-stripe-color-1);
+ --cn-brand-stripe-color-2: var(--nldesign-brand-stripe-color-2);
+ --cn-brand-stripe-color-3: var(--nldesign-brand-stripe-color-3);
+ --cn-brand-stripe-ratio-1: var(--nldesign-brand-stripe-ratio-1);
+ --cn-brand-stripe-ratio-2: var(--nldesign-brand-stripe-ratio-2);
+ --cn-brand-stripe-ratio-3: var(--nldesign-brand-stripe-ratio-3);
+ --cn-brand-stripe-height: var(--nldesign-brand-stripe-height);
+ --cn-brand-stripe-image: var(--nldesign-brand-stripe-image);
+ --cn-brand-stripe-image-inverse: var(
+ --nldesign-brand-stripe-image-inverse,
+ var(--nldesign-brand-stripe-image)
+ );
+
/*
* `--navigation-bar-height` IS DELIBERATELY NOT BRIDGED HERE, and the reason
* is worth keeping: it cannot be.
diff --git a/css/tokens/dark/esdoornveen.css b/css/tokens/dark/esdoornveen.css
index 5f97df43e..9c706a36f 100644
--- a/css/tokens/dark/esdoornveen.css
+++ b/css/tokens/dark/esdoornveen.css
@@ -1,4 +1,4 @@
-/* GENERATED by nldesign DarkPaletteService v9 from tokens/esdoornveen.css (sha256:8ac6ac2d78efe283e417e7c6531c3136a3de845af542852764920f4598fa574a) — do not edit */
+/* GENERATED by nldesign DarkPaletteService v9 from tokens/esdoornveen.css (sha256:4dd3dc67d814c743232804048c851806a639c89f934e514f62cd9dd557e306ae) — do not edit */
@media (prefers-color-scheme: dark) {
body:not([data-theme-light]):not([data-theme-dark]):not([data-theme-light-highcontrast]):not([data-theme-dark-highcontrast]) {
--esdoornveen-color-accent: #d14274;
@@ -14,6 +14,9 @@
--nldesign-brand-stripe-color-1: #966bc9;
--nldesign-brand-stripe-color-2: #d14274;
--nldesign-brand-stripe-color-3: #966bc9;
+ --nldesign-color-accent: #d14274;
+ --nldesign-color-accent-light: #330c1b;
+ --nldesign-color-accent-text: #e36390;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -118,6 +121,11 @@
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #966bc9;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #141414;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/esdoornveen-dark.svg');
}
}
@@ -136,6 +144,9 @@ body[data-themes*=dark] {
--nldesign-brand-stripe-color-1: #966bc9;
--nldesign-brand-stripe-color-2: #d14274;
--nldesign-brand-stripe-color-3: #966bc9;
+ --nldesign-color-accent: #d14274;
+ --nldesign-color-accent-light: #330c1b;
+ --nldesign-color-accent-text: #e36390;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -240,5 +251,10 @@ body[data-themes*=dark] {
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #966bc9;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #141414;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/esdoornveen-dark.svg');
}
diff --git a/css/tokens/dark/vaartveld.css b/css/tokens/dark/vaartveld.css
index ab58ad4ac..73bf8f8bc 100644
--- a/css/tokens/dark/vaartveld.css
+++ b/css/tokens/dark/vaartveld.css
@@ -1,9 +1,12 @@
-/* GENERATED by nldesign DarkPaletteService v9 from tokens/vaartveld.css (sha256:68520f56278546eecb05e89457f957288f0a301f063c8da11170b9f315d13534) — do not edit */
+/* GENERATED by nldesign DarkPaletteService v9 from tokens/vaartveld.css (sha256:2f7092d1d4a3d830d4580f784ed672dd50a3a6faf70f14d9ca8e2090965d7d9b) — do not edit */
@media (prefers-color-scheme: dark) {
body:not([data-theme-light]):not([data-theme-dark]):not([data-theme-light-highcontrast]):not([data-theme-dark-highcontrast]) {
--nldesign-brand-stripe-color-1: #2f5bd7;
--nldesign-brand-stripe-color-2: #4cd7cb;
--nldesign-brand-stripe-color-3: #2f5bd7;
+ --nldesign-color-accent: #4cd7cb;
+ --nldesign-color-accent-light: #143a35;
+ --nldesign-color-accent-text: #9df4eb;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -108,6 +111,11 @@
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #2f5bd7;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #0a1735;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/vaartveld-dark.svg');
--vaartveld-color-accent: #4cd7cb;
--vaartveld-color-accent-light: #143a35;
@@ -126,6 +134,9 @@ body[data-themes*=dark] {
--nldesign-brand-stripe-color-1: #2f5bd7;
--nldesign-brand-stripe-color-2: #4cd7cb;
--nldesign-brand-stripe-color-3: #2f5bd7;
+ --nldesign-color-accent: #4cd7cb;
+ --nldesign-color-accent-light: #143a35;
+ --nldesign-color-accent-text: #9df4eb;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -230,6 +241,11 @@ body[data-themes*=dark] {
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #2f5bd7;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #0a1735;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/vaartveld-dark.svg');
--vaartveld-color-accent: #4cd7cb;
--vaartveld-color-accent-light: #143a35;
diff --git a/css/tokens/dark/warmtepompacademie.css b/css/tokens/dark/warmtepompacademie.css
index 71cea3410..1d61753cf 100644
--- a/css/tokens/dark/warmtepompacademie.css
+++ b/css/tokens/dark/warmtepompacademie.css
@@ -1,9 +1,12 @@
-/* GENERATED by nldesign DarkPaletteService v9 from tokens/warmtepompacademie.css (sha256:b9f1022121447cad03bf560e643d517d99e0d71d4c37fa383adb126207aa0277) — do not edit */
+/* GENERATED by nldesign DarkPaletteService v9 from tokens/warmtepompacademie.css (sha256:d6b7d265c31a592a841b35dd69b338cac9ac6bba39ccdee989a2d8a9dfc05dc9) — do not edit */
@media (prefers-color-scheme: dark) {
body:not([data-theme-light]):not([data-theme-dark]):not([data-theme-light-highcontrast]):not([data-theme-dark-highcontrast]) {
--nldesign-brand-stripe-color-1: #79e0ec;
--nldesign-brand-stripe-color-2: #24272d;
--nldesign-brand-stripe-color-3: #e6612d;
+ --nldesign-color-accent: #e9713f;
+ --nldesign-color-accent-light: #3f2109;
+ --nldesign-color-accent-text: #ed8765;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -20,6 +23,8 @@
--nldesign-color-favorite: #f48c25;
--nldesign-color-focus: #79e0ec80;
--nldesign-color-focus-rgb: 121, 224, 236;
+ --nldesign-color-footer-background: #95e6f0;
+ --nldesign-color-footer-text: #5e5e5e;
--nldesign-color-header-background: #141414;
--nldesign-color-header-text: #e2e3e4;
--nldesign-color-info: #79e0ec;
@@ -108,6 +113,11 @@
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #79e0ec;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #182f33;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/warmtepompacademie-dark.svg');
--warmtepompacademie-color-accent: #e9713f;
--warmtepompacademie-color-accent-light: #3f2109;
@@ -127,6 +137,9 @@ body[data-themes*=dark] {
--nldesign-brand-stripe-color-1: #79e0ec;
--nldesign-brand-stripe-color-2: #24272d;
--nldesign-brand-stripe-color-3: #e6612d;
+ --nldesign-color-accent: #e9713f;
+ --nldesign-color-accent-light: #3f2109;
+ --nldesign-color-accent-text: #ed8765;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -143,6 +156,8 @@ body[data-themes*=dark] {
--nldesign-color-favorite: #f48c25;
--nldesign-color-focus: #79e0ec80;
--nldesign-color-focus-rgb: 121, 224, 236;
+ --nldesign-color-footer-background: #95e6f0;
+ --nldesign-color-footer-text: #5e5e5e;
--nldesign-color-header-background: #141414;
--nldesign-color-header-text: #e2e3e4;
--nldesign-color-info: #79e0ec;
@@ -231,6 +246,11 @@ body[data-themes*=dark] {
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #79e0ec;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #182f33;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/warmtepompacademie-dark.svg');
--warmtepompacademie-color-accent: #e9713f;
--warmtepompacademie-color-accent-light: #3f2109;
diff --git a/css/tokens/dark/wilgenboom.css b/css/tokens/dark/wilgenboom.css
index a39b52620..8e8944f96 100644
--- a/css/tokens/dark/wilgenboom.css
+++ b/css/tokens/dark/wilgenboom.css
@@ -1,9 +1,12 @@
-/* GENERATED by nldesign DarkPaletteService v9 from tokens/wilgenboom.css (sha256:aa4115341e3337618236e3a119a4dec711ae543d9e7c221e34e15245c9d46b33) — do not edit */
+/* GENERATED by nldesign DarkPaletteService v9 from tokens/wilgenboom.css (sha256:b66140b0d636d1714c92ddf169d32b0b1683700bfb38729027f4a36de801fcf1) — do not edit */
@media (prefers-color-scheme: dark) {
body:not([data-theme-light]):not([data-theme-dark]):not([data-theme-light-highcontrast]):not([data-theme-dark-highcontrast]) {
--nldesign-brand-stripe-color-1: #8cc8a7;
--nldesign-brand-stripe-color-2: #cc9414;
--nldesign-brand-stripe-color-3: #8cc8a7;
+ --nldesign-color-accent: #cc9414;
+ --nldesign-color-accent-light: #453507;
+ --nldesign-color-accent-text: #ffde94;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -20,6 +23,8 @@
--nldesign-color-favorite: #f48c25;
--nldesign-color-focus: #8cc8a780;
--nldesign-color-focus-rgb: 140, 200, 167;
+ --nldesign-color-footer-background: #a7d6bd;
+ --nldesign-color-footer-text: #3e3e3e;
--nldesign-color-header-background: #141414;
--nldesign-color-header-text: #e2e3e4;
--nldesign-color-info: #8cc8a7;
@@ -108,6 +113,11 @@
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #8cc8a7;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #1c2c21;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/wilgenboom-dark.svg');
--wilgenboom-color-accent: #cc9414;
--wilgenboom-color-accent-light: #453507;
@@ -126,6 +136,9 @@ body[data-themes*=dark] {
--nldesign-brand-stripe-color-1: #8cc8a7;
--nldesign-brand-stripe-color-2: #cc9414;
--nldesign-brand-stripe-color-3: #8cc8a7;
+ --nldesign-color-accent: #cc9414;
+ --nldesign-color-accent-light: #453507;
+ --nldesign-color-accent-text: #ffde94;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -142,6 +155,8 @@ body[data-themes*=dark] {
--nldesign-color-favorite: #f48c25;
--nldesign-color-focus: #8cc8a780;
--nldesign-color-focus-rgb: 140, 200, 167;
+ --nldesign-color-footer-background: #a7d6bd;
+ --nldesign-color-footer-text: #3e3e3e;
--nldesign-color-header-background: #141414;
--nldesign-color-header-text: #e2e3e4;
--nldesign-color-info: #8cc8a7;
@@ -230,6 +245,11 @@ body[data-themes*=dark] {
--nldesign-component-textbox-hover-border-color: #656c78;
--nldesign-component-textbox-invalid-border-color: #f54949;
--nldesign-component-unordered-list-color: #e2e3e4;
+ --nldesign-hero-action-background-color: #8cc8a7;
+ --nldesign-hero-action-color: #9e9e9e;
+ --nldesign-hero-background-color: #1c2c21;
+ --nldesign-hero-body-color: #111111;
+ --nldesign-hero-title-color: #111111;
--nldesign-logo-url: url('../../../img/logos/wilgenboom-dark.svg');
--wilgenboom-color-accent: #cc9414;
--wilgenboom-color-accent-light: #453507;
diff --git a/css/tokens/dark/zuiddrecht.css b/css/tokens/dark/zuiddrecht.css
index eb645997f..38c439631 100644
--- a/css/tokens/dark/zuiddrecht.css
+++ b/css/tokens/dark/zuiddrecht.css
@@ -1,9 +1,12 @@
-/* GENERATED by nldesign DarkPaletteService v9 from tokens/zuiddrecht.css (sha256:1156eaede9aa12500e92190fc80a24c7b039687a1443fa2040d5c657d46fbe37) — do not edit */
+/* GENERATED by nldesign DarkPaletteService v9 from tokens/zuiddrecht.css (sha256:b89321e4bf069e173f56a0cd9bb9e4a1e380a5b4b3b731818d545f15d47097f0) — do not edit */
@media (prefers-color-scheme: dark) {
body:not([data-theme-light]):not([data-theme-dark]):not([data-theme-light-highcontrast]):not([data-theme-dark-highcontrast]) {
--nldesign-brand-stripe-color-1: #f43535;
--nldesign-brand-stripe-color-2: #5b8ac2;
--nldesign-brand-stripe-color-3: #f43535;
+ --nldesign-color-accent: #f43535;
+ --nldesign-color-accent-light: #310d0a;
+ --nldesign-color-accent-text: #ff5c5c;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -20,6 +23,8 @@
--nldesign-color-favorite: #f48c25;
--nldesign-color-focus: #5b8ac280;
--nldesign-color-focus-rgb: 91, 138, 194;
+ --nldesign-color-footer-background: #7fa6d4;
+ --nldesign-color-footer-text: #2e2e2e;
--nldesign-color-header-background: #141414;
--nldesign-color-header-text: #e2e3e4;
--nldesign-color-info: #5b8ac2;
@@ -126,6 +131,9 @@ body[data-themes*=dark] {
--nldesign-brand-stripe-color-1: #f43535;
--nldesign-brand-stripe-color-2: #5b8ac2;
--nldesign-brand-stripe-color-3: #f43535;
+ --nldesign-color-accent: #f43535;
+ --nldesign-color-accent-light: #310d0a;
+ --nldesign-color-accent-text: #ff5c5c;
--nldesign-color-background: #171a20;
--nldesign-color-background-dark: #1d2026;
--nldesign-color-background-darker: #2d333c;
@@ -142,6 +150,8 @@ body[data-themes*=dark] {
--nldesign-color-favorite: #f48c25;
--nldesign-color-focus: #5b8ac280;
--nldesign-color-focus-rgb: 91, 138, 194;
+ --nldesign-color-footer-background: #7fa6d4;
+ --nldesign-color-footer-text: #2e2e2e;
--nldesign-color-header-background: #141414;
--nldesign-color-header-text: #e2e3e4;
--nldesign-color-info: #5b8ac2;
diff --git a/css/tokens/esdoornveen.css b/css/tokens/esdoornveen.css
index 9604e639f..58490e924 100644
--- a/css/tokens/esdoornveen.css
+++ b/css/tokens/esdoornveen.css
@@ -173,4 +173,30 @@
--nldesign-brand-stripe-ratio-3: 10;
--nldesign-brand-stripe-height: 6px;
--nldesign-brand-stripe-image: linear-gradient(122deg, #5B2E91 0 28.73px, #C2255C 28.73px 110.13px, #5B2E91 110.13px);
+ /* Over the footer the cut sits at the other end, mirrored. */
+ --nldesign-brand-stripe-image-inverse: linear-gradient(238deg, #5B2E91 0 28.73px, #C2255C 28.73px 110.13px, #5B2E91 110.13px);
+
+ /* THE WEBSITE (openspec/changes/brand-motif-on-portals). Read only by
+ * css/public-bridge.css, which a portal links and an instance page never
+ * does.
+ * The accent (maple rose): the menu item on screen, count badges and the
+ * "today first" card. Never a button or a link colour. */
+ --nldesign-color-accent: #C2255C;
+ --nldesign-color-accent-light: #FBE9F0;
+ --nldesign-color-accent-text: #9C1C49;
+ /* The footer band: the primary's deep step, white text on it. */
+ --nldesign-color-footer-background: #43206E;
+ --nldesign-color-footer-text: #ffffff;
+ /* The logo in the site header and footer, 50px high. It carries the
+ * name, so the portal keeps its title for screen readers only. */
+ --nldesign-website-logo-height: 50px;
+ --nldesign-website-logo-width: 198px;
+ --nldesign-website-logo-text-size: 0;
+ /* The hero on the website: a light ground with dark type, the first
+ * button in the primary colour. */
+ --nldesign-hero-background-color: #ffffff;
+ --nldesign-hero-title-color: #1B1C1D;
+ --nldesign-hero-body-color: #1B1C1D;
+ --nldesign-hero-action-background-color: #5B2E91;
+ --nldesign-hero-action-color: #ffffff;
}
diff --git a/css/tokens/vaartveld.css b/css/tokens/vaartveld.css
index 26d053685..d818437e3 100644
--- a/css/tokens/vaartveld.css
+++ b/css/tokens/vaartveld.css
@@ -173,4 +173,32 @@
--nldesign-brand-stripe-ratio-3: 4;
--nldesign-brand-stripe-height: 9px;
--nldesign-brand-stripe-image: linear-gradient(to bottom, #1F4FD8 0 4px, transparent 4px 7px, #1FB5A8 7px 9px);
+ /* On the dark footer band the bank between the two lines is drawn white. */
+ --nldesign-brand-stripe-image-inverse: linear-gradient(to bottom, #1F4FD8 0 4px, #ffffff 4px 7px, #1FB5A8 7px 9px);
+
+ /* THE WEBSITE (openspec/changes/brand-motif-on-portals). Read only by
+ * css/public-bridge.css, which a portal links and an instance page never
+ * does.
+ * The accent (aqua): the menu item on screen, count badges and the
+ * "today first" card. Never a button or a link colour. */
+ --nldesign-color-accent: #1FB5A8;
+ --nldesign-color-accent-light: #DDF5F2;
+ --nldesign-color-accent-text: #0B6259;
+ /* The footer band: the primary's deep step, white text on it. */
+ --nldesign-color-footer-background: #14338F;
+ --nldesign-color-footer-text: #ffffff;
+ /* The logo in the site header and footer, 50px high. It carries the
+ * name, so the portal keeps its title for screen readers only. */
+ --nldesign-website-logo-height: 50px;
+ --nldesign-website-logo-width: 173px;
+ --nldesign-website-logo-text-size: 0;
+ /* The hero on the website: a light ground with dark type, the first
+ * button in the primary colour, and the emblem as a faint watermark. */
+ --nldesign-hero-background-color: #E8EEFC;
+ --nldesign-hero-title-color: #1B1C1D;
+ --nldesign-hero-body-color: #1B1C1D;
+ --nldesign-hero-action-background-color: #1F4FD8;
+ --nldesign-hero-action-color: #ffffff;
+ /* The portal names the set's emblem in --nldesign-emblem-url. */
+ --nldesign-hero-decoration-image: var(--nldesign-emblem-url);
}
diff --git a/css/tokens/warmtepompacademie.css b/css/tokens/warmtepompacademie.css
index 3176c239b..c21403ef0 100644
--- a/css/tokens/warmtepompacademie.css
+++ b/css/tokens/warmtepompacademie.css
@@ -173,4 +173,28 @@
--nldesign-brand-stripe-ratio-3: 11;
--nldesign-brand-stripe-height: 5px;
--nldesign-brand-stripe-image: linear-gradient(to right, #0B6E7A 0 33.333%, #5FA3A8 33.333% 45.833%, #E4E6EA 45.833% 54.167%, #EFA06F 54.167% 66.667%, #D9480F 66.667%);
+
+ /* THE WEBSITE (openspec/changes/brand-motif-on-portals). Read only by
+ * css/public-bridge.css, which a portal links and an instance page never
+ * does.
+ * The accent (ember): the menu item on screen, count badges and the
+ * "today first" card. Never a button or a link colour. */
+ --nldesign-color-accent: #C2410C;
+ --nldesign-color-accent-light: #FCEBDD;
+ --nldesign-color-accent-text: #9A3412;
+ /* The footer band: the primary's deep step, white text on it. */
+ --nldesign-color-footer-background: #084F58;
+ --nldesign-color-footer-text: #ffffff;
+ /* The logo in the site header and footer, 50px high. It carries the
+ * name, so the portal keeps its title for screen readers only. */
+ --nldesign-website-logo-height: 50px;
+ --nldesign-website-logo-width: 189px;
+ --nldesign-website-logo-text-size: 0;
+ /* The hero on the website: a light ground with dark type, the first
+ * button in the primary colour. */
+ --nldesign-hero-background-color: #E3F1F3;
+ --nldesign-hero-title-color: #1B1C1D;
+ --nldesign-hero-body-color: #1B1C1D;
+ --nldesign-hero-action-background-color: #0B6E7A;
+ --nldesign-hero-action-color: #ffffff;
}
diff --git a/css/tokens/wilgenboom.css b/css/tokens/wilgenboom.css
index b2b03aa04..6736b428d 100644
--- a/css/tokens/wilgenboom.css
+++ b/css/tokens/wilgenboom.css
@@ -166,6 +166,35 @@
--nldesign-brand-stripe-ratio-1: 3;
--nldesign-brand-stripe-ratio-2: 1;
--nldesign-brand-stripe-ratio-3: 3;
- --nldesign-brand-stripe-height: 14px;
- --nldesign-brand-stripe-image: url("data:image/svg+xml,");
+ --nldesign-brand-stripe-height: 17px;
+ --nldesign-brand-stripe-image: url("data:image/svg+xml,");
+ /* On the dark footer band the twigs hang from its top edge, in a light
+ * green (#5F9A78) and the same yellow, without the green line. */
+ --nldesign-brand-stripe-image-inverse: url("data:image/svg+xml,");
+
+ /* THE WEBSITE (openspec/changes/brand-motif-on-portals). Read only by
+ * css/public-bridge.css, which a portal links and an instance page never
+ * does.
+ * The accent (sun yellow; #6B4A00 on #FDF3D7 7.36:1): the menu item on screen, count badges and the
+ * "today first" card. Never a button or a link colour. */
+ --nldesign-color-accent: #F5B82E;
+ --nldesign-color-accent-light: #FDF3D7;
+ --nldesign-color-accent-text: #6B4A00;
+ /* The footer band: the primary's deep step, white text on it. */
+ --nldesign-color-footer-background: #1F4A33;
+ --nldesign-color-footer-text: #ffffff;
+ /* The logo in the site header and footer, 50px high. It carries the
+ * name, so the portal keeps its title for screen readers only. */
+ --nldesign-website-logo-height: 50px;
+ --nldesign-website-logo-width: 238px;
+ --nldesign-website-logo-text-size: 0;
+ /* The hero on the website: a light ground with dark type, the first
+ * button in the primary colour, and the emblem as a faint watermark. */
+ --nldesign-hero-background-color: #E8F1EB;
+ --nldesign-hero-title-color: #1F4A33;
+ --nldesign-hero-body-color: #1B1C1D;
+ --nldesign-hero-action-background-color: #2F6B4A;
+ --nldesign-hero-action-color: #ffffff;
+ /* The portal names the set's emblem in --nldesign-emblem-url. */
+ --nldesign-hero-decoration-image: var(--nldesign-emblem-url);
}
diff --git a/css/tokens/zuiddrecht.css b/css/tokens/zuiddrecht.css
index 69ab55910..8af7ea471 100644
--- a/css/tokens/zuiddrecht.css
+++ b/css/tokens/zuiddrecht.css
@@ -168,4 +168,21 @@
--nldesign-brand-stripe-ratio-2: 3;
--nldesign-brand-stripe-ratio-3: 1;
--nldesign-brand-stripe-height: 5px;
+
+ /* THE WEBSITE (openspec/changes/brand-motif-on-portals). Read only by
+ * css/public-bridge.css, which a portal links and an instance page never
+ * does.
+ * The accent (the red of the arms): the menu item on screen, count badges and the
+ * "today first" card. Never a button or a link colour. */
+ --nldesign-color-accent: #CC0000;
+ --nldesign-color-accent-light: #FCEDEC;
+ --nldesign-color-accent-text: #A30000;
+ /* The footer band: the primary's deep step, white text on it. */
+ --nldesign-color-footer-background: #234A78;
+ --nldesign-color-footer-text: #ffffff;
+ /* The logo in the site header and footer, 50px high. It carries the
+ * name, so the portal keeps its title for screen readers only. */
+ --nldesign-website-logo-height: 50px;
+ --nldesign-website-logo-width: 234px;
+ --nldesign-website-logo-text-size: 0;
}
diff --git a/docs/reference/token-sets/esdoornveen.md b/docs/reference/token-sets/esdoornveen.md
index e5b926b46..6f20c0f98 100644
--- a/docs/reference/token-sets/esdoornveen.md
+++ b/docs/reference/token-sets/esdoornveen.md
@@ -2,7 +2,7 @@
# Esdoornveen, mbo college
-Token set `esdoornveen`: 79 declared by this set, 129 from the defaults layer.
+Token set `esdoornveen`: 93 declared by this set, 129 from the defaults layer.
Contrast: primary text on primary 9.36:1, primary on background 8.65:1 (pass).
@@ -278,9 +278,15 @@ Contrast: primary text on primary 9.36:1, primary on background 8.65:1 (pass).
| `--nldesign-brand-stripe-color-3` |  `#5B2E91` |  `#966bc9` | this set | |
| `--nldesign-brand-stripe-height` | `6px` | | this set | |
| `--nldesign-brand-stripe-image` | `linear-gradient(122deg, #5B2E91 0 28.73px, #C2255C 28.73px 110.13px, #5B2E91 110.13px)` | | this set | |
+| `--nldesign-brand-stripe-image-inverse` | `linear-gradient(238deg, #5B2E91 0 28.73px, #C2255C 28.73px 110.13px, #5B2E91 110.13px)` | | this set | |
| `--nldesign-brand-stripe-ratio-1` | `1` | | this set | |
| `--nldesign-brand-stripe-ratio-2` | `3` | | this set | |
| `--nldesign-brand-stripe-ratio-3` | `10` | | this set | |
+| `--nldesign-color-accent` |  `#C2255C` |  `#d14274` | this set | |
+| `--nldesign-color-accent-light` |  `#FBE9F0` |  `#330c1b` | this set | |
+| `--nldesign-color-accent-text` |  `#9C1C49` |  `#e36390` | this set | |
+| `--nldesign-color-footer-background` |  `#43206E` | | this set | |
+| `--nldesign-color-footer-text` |  `#ffffff` | | this set | |
| `--nldesign-component-content-card-shadow-color` |  `rgba(27, 28, 29, 0.04)` |  `#d2d3d40a` | this set | |
| `--nldesign-component-content-surface-background-color` |  `#F5F6F8` |  `#171a20` | this set | |
| `--nldesign-component-navigation-active-background-color` |  `#C2255C` |  `#d14274` | this set | |
@@ -295,8 +301,16 @@ Contrast: primary text on primary 9.36:1, primary on background 8.65:1 (pass).
| `--nldesign-component-status-badge-success-color` |  `#1E6B2A` |  `#94e1a0` | this set | |
| `--nldesign-component-status-badge-warning-background-color` |  `#FFF4DE` |  `#412d03` | this set | |
| `--nldesign-component-status-badge-warning-color` |  `#7A4F00` |  `#ffd485` | this set | |
+| `--nldesign-hero-action-background-color` |  `#5B2E91` |  `#966bc9` | this set | |
+| `--nldesign-hero-action-color` |  `#ffffff` |  `#9e9e9e` | this set | |
+| `--nldesign-hero-background-color` |  `#ffffff` |  `#141414` | this set | |
+| `--nldesign-hero-body-color` |  `#1B1C1D` |  `#111111` | this set | |
+| `--nldesign-hero-title-color` |  `#1B1C1D` |  `#111111` | this set | |
| `--nldesign-login-watermark-image` | `url('../../img/logos/esdoornveen-emblem-grey.svg')` | | this set | |
| `--nldesign-login-watermark-opacity` | `0.06` | | this set | |
| `--nldesign-logo-url` | `url('../../img/logos/esdoornveen.svg')` | `url('../../../img/logos/esdoornveen-dark.svg')` | this set | |
| `--nldesign-website-border-radius` | `4px` | | this set | |
| `--nldesign-website-border-radius-large` | `8px` | | this set | |
+| `--nldesign-website-logo-height` | `50px` | | this set | |
+| `--nldesign-website-logo-text-size` | `0` | | this set | |
+| `--nldesign-website-logo-width` | `198px` | | this set | |
diff --git a/docs/reference/token-sets/vaartveld.md b/docs/reference/token-sets/vaartveld.md
index 5c64328ef..e53b90935 100644
--- a/docs/reference/token-sets/vaartveld.md
+++ b/docs/reference/token-sets/vaartveld.md
@@ -2,7 +2,7 @@
# Vaartveld College
-Token set `vaartveld`: 79 declared by this set, 128 from the defaults layer.
+Token set `vaartveld`: 94 declared by this set, 128 from the defaults layer.
Contrast: primary text on primary 6.63:1, primary on background 6.13:1 (pass).
@@ -267,9 +267,15 @@ Contrast: primary text on primary 6.63:1, primary on background 6.13:1 (pass).
| `--nldesign-brand-stripe-color-3` |  `#1F4FD8` |  `#2f5bd7` | this set | |
| `--nldesign-brand-stripe-height` | `9px` | | this set | |
| `--nldesign-brand-stripe-image` | `linear-gradient(to bottom, #1F4FD8 0 4px, transparent 4px 7px, #1FB5A8 7px 9px)` | | this set | |
+| `--nldesign-brand-stripe-image-inverse` | `linear-gradient(to bottom, #1F4FD8 0 4px, #ffffff 4px 7px, #1FB5A8 7px 9px)` | | this set | |
| `--nldesign-brand-stripe-ratio-1` | `4` | | this set | |
| `--nldesign-brand-stripe-ratio-2` | `2` | | this set | |
| `--nldesign-brand-stripe-ratio-3` | `4` | | this set | |
+| `--nldesign-color-accent` |  `#1FB5A8` |  `#4cd7cb` | this set | |
+| `--nldesign-color-accent-light` |  `#DDF5F2` |  `#143a35` | this set | |
+| `--nldesign-color-accent-text` |  `#0B6259` |  `#9df4eb` | this set | |
+| `--nldesign-color-footer-background` |  `#14338F` | | this set | |
+| `--nldesign-color-footer-text` |  `#ffffff` | | this set | |
| `--nldesign-component-content-card-shadow-color` |  `rgba(27, 28, 29, 0.04)` |  `#d2d3d40a` | this set | |
| `--nldesign-component-content-surface-background-color` |  `#F5F6F8` |  `#171a20` | this set | |
| `--nldesign-component-navigation-active-background-color` |  `#1FB5A8` |  `#4cd7cb` | this set | |
@@ -284,11 +290,20 @@ Contrast: primary text on primary 6.63:1, primary on background 6.13:1 (pass).
| `--nldesign-component-status-badge-success-color` |  `#1E6B2A` |  `#94e1a0` | this set | |
| `--nldesign-component-status-badge-warning-background-color` |  `#FFF4DE` |  `#412d03` | this set | |
| `--nldesign-component-status-badge-warning-color` |  `#7A4F00` |  `#ffd485` | this set | |
+| `--nldesign-hero-action-background-color` |  `#1F4FD8` |  `#2f5bd7` | this set | |
+| `--nldesign-hero-action-color` |  `#ffffff` |  `#9e9e9e` | this set | |
+| `--nldesign-hero-background-color` |  `#E8EEFC` |  `#0a1735` | this set | |
+| `--nldesign-hero-body-color` |  `#1B1C1D` |  `#111111` | this set | |
+| `--nldesign-hero-decoration-image` | `var(--nldesign-emblem-url)` | | this set | |
+| `--nldesign-hero-title-color` |  `#1B1C1D` |  `#111111` | this set | |
| `--nldesign-login-watermark-image` | `url('../../img/logos/vaartveld-emblem-grey.svg')` | | this set | |
| `--nldesign-login-watermark-opacity` | `0.08` | | this set | |
| `--nldesign-logo-url` | `url('../../img/logos/vaartveld.svg')` | `url('../../../img/logos/vaartveld-dark.svg')` | this set | |
| `--nldesign-website-border-radius` | `6px` | | this set | |
| `--nldesign-website-border-radius-large` | `10px` | | this set | |
+| `--nldesign-website-logo-height` | `50px` | | this set | |
+| `--nldesign-website-logo-text-size` | `0` | | this set | |
+| `--nldesign-website-logo-width` | `173px` | | this set | |
| `--vaartveld-color-accent` |  `#1FB5A8` |  `#4cd7cb` | this set | |
| `--vaartveld-color-accent-light` |  `#DDF5F2` |  `#143a35` | this set | |
| `--vaartveld-color-accent-text` |  `#0B6259` |  `#9df4eb` | this set | |
diff --git a/docs/reference/token-sets/warmtepompacademie.md b/docs/reference/token-sets/warmtepompacademie.md
index c7a5e7ce9..c158e62e8 100644
--- a/docs/reference/token-sets/warmtepompacademie.md
+++ b/docs/reference/token-sets/warmtepompacademie.md
@@ -2,7 +2,7 @@
# Warmtepompacademie
-Token set `warmtepompacademie`: 79 declared by this set, 128 from the defaults layer.
+Token set `warmtepompacademie`: 92 declared by this set, 128 from the defaults layer.
Contrast: primary text on primary 5.96:1, primary on background 5.51:1 (pass).
@@ -270,6 +270,11 @@ Contrast: primary text on primary 5.96:1, primary on background 5.51:1 (pass).
| `--nldesign-brand-stripe-ratio-1` | `11` | | this set | |
| `--nldesign-brand-stripe-ratio-2` | `2` | | this set | |
| `--nldesign-brand-stripe-ratio-3` | `11` | | this set | |
+| `--nldesign-color-accent` |  `#C2410C` |  `#e9713f` | this set | |
+| `--nldesign-color-accent-light` |  `#FCEBDD` |  `#3f2109` | this set | |
+| `--nldesign-color-accent-text` |  `#9A3412` |  `#ed8765` | this set | |
+| `--nldesign-color-footer-background` |  `#084F58` |  `#95e6f0` | this set | |
+| `--nldesign-color-footer-text` |  `#ffffff` |  `#5e5e5e` | this set | |
| `--nldesign-component-content-card-shadow-color` |  `rgba(27, 28, 29, 0.04)` |  `#d2d3d40a` | this set | |
| `--nldesign-component-content-surface-background-color` |  `#F5F6F8` |  `#171a20` | this set | |
| `--nldesign-component-navigation-active-background-color` |  `#C2410C` |  `#e9713f` | this set | |
@@ -284,10 +289,18 @@ Contrast: primary text on primary 5.96:1, primary on background 5.51:1 (pass).
| `--nldesign-component-status-badge-success-color` |  `#1E6B2A` |  `#94e1a0` | this set | |
| `--nldesign-component-status-badge-warning-background-color` |  `#FFF4DE` |  `#412d03` | this set | |
| `--nldesign-component-status-badge-warning-color` |  `#7A4F00` |  `#ffd485` | this set | |
+| `--nldesign-hero-action-background-color` |  `#0B6E7A` |  `#79e0ec` | this set | |
+| `--nldesign-hero-action-color` |  `#ffffff` |  `#9e9e9e` | this set | |
+| `--nldesign-hero-background-color` |  `#E3F1F3` |  `#182f33` | this set | |
+| `--nldesign-hero-body-color` |  `#1B1C1D` |  `#111111` | this set | |
+| `--nldesign-hero-title-color` |  `#1B1C1D` |  `#111111` | this set | |
| `--nldesign-login-watermark-image` | `url('../../img/logos/warmtepompacademie-emblem-grey.svg')` | | this set | |
| `--nldesign-logo-url` | `url('../../img/logos/warmtepompacademie.svg')` | `url('../../../img/logos/warmtepompacademie-dark.svg')` | this set | |
| `--nldesign-website-border-radius` | `3px` | | this set | |
| `--nldesign-website-border-radius-large` | `6px` | | this set | |
+| `--nldesign-website-logo-height` | `50px` | | this set | |
+| `--nldesign-website-logo-text-size` | `0` | | this set | |
+| `--nldesign-website-logo-width` | `189px` | | this set | |
| `--warmtepompacademie-color-accent` |  `#C2410C` |  `#e9713f` | this set | |
| `--warmtepompacademie-color-accent-light` |  `#FCEBDD` |  `#3f2109` | this set | |
| `--warmtepompacademie-color-accent-mark` |  `#D9480F` |  `#e6612d` | this set | |
diff --git a/docs/reference/token-sets/wilgenboom.md b/docs/reference/token-sets/wilgenboom.md
index f3d508938..40059523a 100644
--- a/docs/reference/token-sets/wilgenboom.md
+++ b/docs/reference/token-sets/wilgenboom.md
@@ -2,7 +2,7 @@
# Basisschool De Wilgenboom
-Token set `wilgenboom`: 77 declared by this set, 129 from the defaults layer.
+Token set `wilgenboom`: 92 declared by this set, 129 from the defaults layer.
Contrast: primary text on primary 6.32:1, primary on background 5.84:1 (pass).
@@ -265,11 +265,17 @@ Contrast: primary text on primary 6.32:1, primary on background 5.84:1 (pass).
| `--nldesign-brand-stripe-color-1` |  `#2F6B4A` |  `#8cc8a7` | this set | |
| `--nldesign-brand-stripe-color-2` |  `#F5B82E` |  `#cc9414` | this set | |
| `--nldesign-brand-stripe-color-3` |  `#2F6B4A` |  `#8cc8a7` | this set | |
-| `--nldesign-brand-stripe-height` | `14px` | | this set | |
-| `--nldesign-brand-stripe-image` | `url("data:image/svg+xml,")` | | this set | |
+| `--nldesign-brand-stripe-height` | `17px` | | this set | |
+| `--nldesign-brand-stripe-image` | `url("data:image/svg+xml,")` | | this set | |
+| `--nldesign-brand-stripe-image-inverse` | `url("data:image/svg+xml,")` | | this set | |
| `--nldesign-brand-stripe-ratio-1` | `3` | | this set | |
| `--nldesign-brand-stripe-ratio-2` | `1` | | this set | |
| `--nldesign-brand-stripe-ratio-3` | `3` | | this set | |
+| `--nldesign-color-accent` |  `#F5B82E` |  `#cc9414` | this set | |
+| `--nldesign-color-accent-light` |  `#FDF3D7` |  `#453507` | this set | |
+| `--nldesign-color-accent-text` |  `#6B4A00` |  `#ffde94` | this set | |
+| `--nldesign-color-footer-background` |  `#1F4A33` |  `#a7d6bd` | this set | |
+| `--nldesign-color-footer-text` |  `#ffffff` |  `#3e3e3e` | this set | |
| `--nldesign-component-content-card-shadow-color` |  `rgba(27, 28, 29, 0.04)` |  `#d2d3d40a` | this set | |
| `--nldesign-component-content-surface-background-color` |  `#F5F6F8` |  `#171a20` | this set | |
| `--nldesign-component-navigation-active-background-color` |  `#F5B82E` |  `#cc9414` | this set | |
@@ -284,10 +290,19 @@ Contrast: primary text on primary 6.32:1, primary on background 5.84:1 (pass).
| `--nldesign-component-status-badge-success-color` |  `#1E6B2A` |  `#94e1a0` | this set | |
| `--nldesign-component-status-badge-warning-background-color` |  `#FFF4DE` |  `#412d03` | this set | |
| `--nldesign-component-status-badge-warning-color` |  `#7A4F00` |  `#ffd485` | this set | |
+| `--nldesign-hero-action-background-color` |  `#2F6B4A` |  `#8cc8a7` | this set | |
+| `--nldesign-hero-action-color` |  `#ffffff` |  `#9e9e9e` | this set | |
+| `--nldesign-hero-background-color` |  `#E8F1EB` |  `#1c2c21` | this set | |
+| `--nldesign-hero-body-color` |  `#1B1C1D` |  `#111111` | this set | |
+| `--nldesign-hero-decoration-image` | `var(--nldesign-emblem-url)` | | this set | |
+| `--nldesign-hero-title-color` |  `#1F4A33` |  `#111111` | this set | |
| `--nldesign-login-watermark-image` | `url('../../img/logos/wilgenboom-emblem-grey.svg')` | | this set | |
| `--nldesign-logo-url` | `url('../../img/logos/wilgenboom.svg')` | `url('../../../img/logos/wilgenboom-dark.svg')` | this set | |
| `--nldesign-website-border-radius` | `10px` | | this set | |
| `--nldesign-website-border-radius-large` | `14px` | | this set | |
+| `--nldesign-website-logo-height` | `50px` | | this set | |
+| `--nldesign-website-logo-text-size` | `0` | | this set | |
+| `--nldesign-website-logo-width` | `238px` | | this set | |
| `--wilgenboom-color-accent` |  `#F5B82E` |  `#cc9414` | this set | |
| `--wilgenboom-color-accent-light` |  `#FDF3D7` |  `#453507` | this set | |
| `--wilgenboom-color-accent-text` |  `#6B4A00` |  `#ffde94` | this set | |
diff --git a/docs/reference/token-sets/zuiddrecht.md b/docs/reference/token-sets/zuiddrecht.md
index 85429e169..a71c80aab 100644
--- a/docs/reference/token-sets/zuiddrecht.md
+++ b/docs/reference/token-sets/zuiddrecht.md
@@ -2,7 +2,7 @@
# Gemeente Zuiddrecht
-Token set `zuiddrecht`: 74 declared by this set, 129 from the defaults layer.
+Token set `zuiddrecht`: 82 declared by this set, 129 from the defaults layer.
Contrast: primary text on primary 5.64:1, primary on background 5.22:1 (pass).
@@ -269,6 +269,11 @@ Contrast: primary text on primary 5.64:1, primary on background 5.22:1 (pass).
| `--nldesign-brand-stripe-ratio-1` | `6` | | this set | |
| `--nldesign-brand-stripe-ratio-2` | `3` | | this set | |
| `--nldesign-brand-stripe-ratio-3` | `1` | | this set | |
+| `--nldesign-color-accent` |  `#CC0000` |  `#f43535` | this set | |
+| `--nldesign-color-accent-light` |  `#FCEDEC` |  `#310d0a` | this set | |
+| `--nldesign-color-accent-text` |  `#A30000` |  `#ff5c5c` | this set | |
+| `--nldesign-color-footer-background` |  `#234A78` |  `#7fa6d4` | this set | |
+| `--nldesign-color-footer-text` |  `#ffffff` |  `#2e2e2e` | this set | |
| `--nldesign-component-content-card-shadow-color` |  `rgba(27, 28, 29, 0.04)` |  `#d2d3d40a` | this set | |
| `--nldesign-component-content-surface-background-color` |  `#F5F6F8` |  `#171a20` | this set | |
| `--nldesign-component-navigation-active-background-color` |  `#CC0000` |  `#f43535` | this set | |
@@ -285,6 +290,9 @@ Contrast: primary text on primary 5.64:1, primary on background 5.22:1 (pass).
| `--nldesign-component-status-badge-warning-color` |  `#7A4F00` |  `#ffd485` | this set | |
| `--nldesign-login-watermark-image` | `url('../../img/logos/zuiddrecht-emblem-grey.svg')` | | this set | |
| `--nldesign-logo-url` | `url('../../img/logos/zuiddrecht.svg')` | `url('../../../img/logos/zuiddrecht-dark.svg')` | this set | |
+| `--nldesign-website-logo-height` | `50px` | | this set | |
+| `--nldesign-website-logo-text-size` | `0` | | this set | |
+| `--nldesign-website-logo-width` | `234px` | | this set | |
| `--zuiddrecht-color-blue` |  `#3669A5` |  `#5b8ac2` | this set | |
| `--zuiddrecht-color-blue-dark` |  `#234A78` |  `#7fa6d4` | this set | |
| `--zuiddrecht-color-blue-light` |  `#EAF0F7` |  `#13202e` | this set | |
diff --git a/openspec/changes/brand-motif-on-portals/proposal.md b/openspec/changes/brand-motif-on-portals/proposal.md
new file mode 100644
index 000000000..44da4f974
--- /dev/null
+++ b/openspec/changes/brand-motif-on-portals/proposal.md
@@ -0,0 +1,68 @@
+---
+kind: code
+---
+
+## Why
+
+A portal that switched from an `example-*` set to `zuiddrecht` or one of the four school sets
+looked worse than before. Measured on a live portal (portaliq, :8091, 5 October): with
+`wilgenboom` in place of `example-basisschool` the site resolved 116 of the 489 component roles
+it reads, against 489. There was no logo, the header and the DigiD button drew in browser
+defaults and the footer lost its padding. The `example-*` sets carry a role layer of their own;
+the newer sets declare only the `--nldesign-*` vocabulary, and the public bridge mapped only 85
+roles from it.
+
+The school designs also draw their motif under the website header and over its footer, use an
+accent colour for the menu item on screen and for count badges, and show a light logo on the dark
+footer. The motif token (`--nldesign-brand-stripe-*`, with `-image` for a motif that is not three
+bands) reached only Nextcloud's own pages: `css/public-bridge.css`, the one file a portal links,
+had no stripe line. The accent existed only as palette entries (`---color-accent`), which a
+generic site cannot read.
+
+## What Changes
+
+- **The bridge carries the whole role layer the site reads.** Every role that resolved on
+ `example-basisschool` and not on `wilgenboom` (375, listed in
+ `tests/vitest/fixtures/portal-site-roles.json`) is declared in `css/public-bridge.css`:
+ colours from the `--nldesign-*` layer with a fallback each, logos from `--nldesign-logo-url`,
+ geometry (spacing, sizes, the type scale) as neutral values. A set with a role layer of its own
+ loads after the bridge and keeps every value.
+- **The brand stripe reaches the portal.** The bridge hands the stripe tokens to the site under
+ the names the component library's `CnBrandStripe` reads (`--cn-brand-stripe-*`), plus
+ `--cn-brand-stripe-image` and `--cn-brand-stripe-image-inverse`. No fallbacks: a set that
+ declares no stripe draws none on its portal. `css/brand-stripe.css` hands the two image names to
+ the library on Nextcloud's pages too.
+- **A motif for a dark band.** A set may name `--nldesign-brand-stripe-image-inverse`, the same
+ motif drawn for a dark band such as the footer. wilgenboom (light green twigs, no green line),
+ vaartveld (the bank drawn white) and esdoornveen (the cut at the other end) name one. It is a
+ variant of the one motif token, not a second mechanism.
+- **The accent is vocabulary.** `--nldesign-color-accent`, `-accent-light` and `-accent-text`,
+ declared by the four school sets and zuiddrecht. The bridge reads them into
+ `--thematiq-accent-color`, `--thematiq-accent-light-color` and `--thematiq-accent-text-color`
+ (falling back to the primary), and the navigation badge tokens into
+ `--thematiq-badge-background-color` and `--thematiq-badge-color`.
+- **The website logo and footer.** `--nldesign-website-logo-width`, `-height` and
+ `-text-size` (0 when the logo carries the name, so the portal keeps its title for screen readers
+ only), and `--nldesign-color-footer-background` and `-footer-text` in the five sets. The bridge
+ shows the light logo on the footer when the portal names it in `--nldesign-logo-inverse-url`.
+- wilgenboom's header motif gains the 3px green line the twigs hang from (17px high).
+
+**Out of scope:** drawing the stripe, the header search and the footer button on the portal
+(portaliq `site-chrome-follows-the-design`); the motif in `CnBrandStripe` (nextcloud-vue
+`brand-motif-token`).
+
+## Capabilities
+
+### New Capabilities
+- `brand-motif-on-portals`: the role layer a portal needs from any set, the stripe and its
+ inverse on a portal, the accent vocabulary, the website logo and footer tokens.
+
+## Impact
+
+- Changed: `css/public-bridge.css`, `css/brand-stripe.css`, the token files of `wilgenboom`,
+ `vaartveld`, `esdoornveen`, `warmtepompacademie` and `zuiddrecht` (with their generated dark
+ variants and reference pages).
+- Portals on a set with only `--nldesign-*` now draw buttons, form controls, the header account
+ button and the footer from their own colours instead of browser defaults. Portals on a set with
+ a role layer of its own (the `example-*` sets, vng, rotterdam) do not change.
+- No migration. Additive, so a minor version.
diff --git a/openspec/changes/brand-motif-on-portals/specs/brand-motif-on-portals/spec.md b/openspec/changes/brand-motif-on-portals/specs/brand-motif-on-portals/spec.md
new file mode 100644
index 000000000..c2000a988
--- /dev/null
+++ b/openspec/changes/brand-motif-on-portals/specs/brand-motif-on-portals/spec.md
@@ -0,0 +1,86 @@
+# Spec: Brand motif and role layer on portals
+
+What a public portal gets from any token set through `css/public-bridge.css`.
+
+## ADDED Requirements
+
+### Requirement: The bridge names every role the portal site reads
+`css/public-bridge.css` MUST declare every `--utrecht-*`, `--tilburg-*` and `--conduction-*` role
+that the portal site reads and that an `example-*` set declares for itself: colours from the
+`--nldesign-*` layer with a fallback, logos from `--nldesign-logo-url`, geometry as neutral
+values. A set that declares a role itself MUST keep its own value, because it loads after the
+bridge.
+
+#### Scenario: A school set paints the whole site
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js resolves the bridge and each set the way a page does
+- GIVEN a portal on `wilgenboom`, `vaartveld`, `esdoornveen`, `warmtepompacademie` or `zuiddrecht`
+- WHEN the bridge and the set are resolved
+- THEN every role in `tests/vitest/fixtures/portal-site-roles.json` MUST be declared
+- AND the primary button and the header account button MUST resolve to the set's primary colour
+- AND the header logo MUST be the set's own logo, 50px high
+
+#### Scenario: A set with a role layer keeps it
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js
+- GIVEN a portal on `example-basisschool`
+- WHEN the bridge and the set are resolved
+- THEN the primary button MUST keep the set's own value
+
+### Requirement: The brand stripe reaches the portal
+The bridge MUST hand `--nldesign-brand-stripe-color-1..3`, `-ratio-1..3`, `-height` and `-image`
+to the portal as `--cn-brand-stripe-*`, and `--cn-brand-stripe-image-inverse` from
+`--nldesign-brand-stripe-image-inverse`, else from `-image`. None of them MAY carry a fallback,
+so a set that declares no stripe draws none. `css/brand-stripe.css` MUST hand the two image names
+to the component library on Nextcloud's pages, also without a fallback.
+
+#### Scenario: Zuiddrecht keeps its three bands
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js and workplaceLayout.spec.js
+- GIVEN a portal on `zuiddrecht`
+- WHEN the stripe tokens are resolved
+- THEN the colours MUST be #CC0000, #3669A5 and #CC0000 in the ratio 6 : 3 : 1, 5px high
+- AND no stripe image MUST resolve
+
+#### Scenario: A school motif and its inverse
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js
+- GIVEN a portal on `wilgenboom`
+- WHEN the stripe tokens are resolved
+- THEN `--cn-brand-stripe-image` MUST be the twigs as an SVG data URI
+- AND `--cn-brand-stripe-image-inverse` MUST be the light green twigs
+
+#### Scenario: A set without a stripe draws none
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js
+- GIVEN a portal on `vng`
+- WHEN the stripe tokens are resolved
+- THEN `--cn-brand-stripe-height` and `--cn-brand-stripe-image` MUST be the guaranteed-invalid value
+
+### Requirement: The accent is vocabulary
+A set MAY name its accent in `--nldesign-color-accent`, `--nldesign-color-accent-light` and
+`--nldesign-color-accent-text`. The bridge MUST read them into `--thematiq-accent-color`,
+`--thematiq-accent-light-color` and `--thematiq-accent-text-color`, each falling back to the
+primary's matching step, and the set's navigation badge tokens into
+`--thematiq-badge-background-color` and `--thematiq-badge-color`. The accent MUST NOT be the
+colour of a button or a link.
+
+#### Scenario: The school accents
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js
+- GIVEN a school set
+- WHEN its accent tokens are read
+- THEN they MUST equal the set's palette entries `---color-accent`, `-accent-light` and `-accent-text`
+- AND `--thematiq-accent-color` MUST resolve to the accent, not the primary
+
+#### Scenario: A set without an accent
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js
+- GIVEN a portal on `vng`
+- WHEN `--thematiq-accent-color` is resolved
+- THEN it MUST be the set's primary colour
+
+### Requirement: The website logo and footer
+A set MAY name `--nldesign-website-logo-width` and `-height` (the logo box in the site header and
+footer) and `--nldesign-website-logo-text-size` (0 when the logo carries the name). The bridge
+MUST map them onto the logo roles and `--thematiq-logo-text-font-size`, and MUST show
+`--nldesign-logo-inverse-url` on the footer when the portal names it, else the set's logo.
+
+#### Scenario: The school logo carries the name
+@e2e exclude Static file check: tests/vitest/publicBridgeRoleLayer.spec.js
+- GIVEN a school set
+- WHEN the logo roles are resolved
+- THEN the header logo MUST be 50px high and `--thematiq-logo-text-font-size` MUST be 0
diff --git a/openspec/changes/brand-motif-on-portals/tasks.md b/openspec/changes/brand-motif-on-portals/tasks.md
new file mode 100644
index 000000000..ff7d30050
--- /dev/null
+++ b/openspec/changes/brand-motif-on-portals/tasks.md
@@ -0,0 +1,24 @@
+# Tasks: Brand motif and role layer on portals
+
+## 1. Spec
+- [x] 1.1 Proposal and the spec delta.
+
+## 2. Bridge
+- [x] 2.1 `css/public-bridge.css`: the role layer the site reads (375 roles, measured).
+- [x] 2.2 The brand stripe and its inverse under the library names, without fallbacks.
+- [x] 2.3 The accent roles and the badge roles.
+- [x] 2.4 The website logo roles and the footer logo.
+- [x] 2.5 `css/brand-stripe.css`: hand the two image names to the library.
+
+## 3. Token sets
+- [x] 3.1 Accent, footer and website logo tokens in `wilgenboom`, `vaartveld`, `esdoornveen`, `warmtepompacademie` and `zuiddrecht`.
+- [x] 3.2 Inverse motifs for `wilgenboom`, `vaartveld` and `esdoornveen`; wilgenboom's green line.
+- [x] 3.3 Regenerated dark variants and reference pages.
+
+## 4. Tests
+- [x] 4.1 vitest `tests/vitest/publicBridgeRoleLayer.spec.js` (roles, stripe, accent, logo, the control).
+- [x] 4.2 `workplaceLayout.spec.js` (the two image names), `schoolTokenSets.spec.js` (wilgenboom 17px).
+- [x] 4.3 `bash scripts/token-set-gate.sh` runs the new spec.
+
+## 5. Verify
+- [x] 5.1 Live check on a portal (:8091) with each school set and zuiddrecht: logo, styled buttons, stripe under the header and over the footer (needs portaliq `site-chrome-follows-the-design`).
diff --git a/scripts/token-set-gate.sh b/scripts/token-set-gate.sh
index 15c9a69bb..b9f76d735 100755
--- a/scripts/token-set-gate.sh
+++ b/scripts/token-set-gate.sh
@@ -40,5 +40,6 @@ npx vitest run \
tests/vitest/syncUpstreamTokens.spec.js \
tests/vitest/zuiddrechtTokenSet.spec.js \
tests/vitest/schoolTokenSets.spec.js \
+ tests/vitest/publicBridgeRoleLayer.spec.js \
tests/vitest/componentScopesGenerator.spec.js \
tests/vitest/workplaceLayout.spec.js
diff --git a/tests/vitest/fixtures/portal-site-roles.json b/tests/vitest/fixtures/portal-site-roles.json
new file mode 100644
index 000000000..2efbaa6fc
--- /dev/null
+++ b/tests/vitest/fixtures/portal-site-roles.json
@@ -0,0 +1,380 @@
+{
+ "source": "Measured on a live portal (portaliq 776e746, :8091, 2026-10-05): every --utrecht-*, --tilburg-* and --conduction-* role the site reads that resolved on example-basisschool and resolved to nothing on wilgenboom, before brand-motif-on-portals",
+ "roles": [
+ "--conduction-logo-footer-background-image",
+ "--conduction-logo-footer-block-size",
+ "--conduction-logo-footer-inline-size",
+ "--conduction-logo-header-background-image",
+ "--conduction-logo-header-block-size",
+ "--conduction-logo-header-inline-size",
+ "--conduction-logo-navbar-background-image",
+ "--conduction-logo-navbar-block-size",
+ "--conduction-logo-navbar-inline-size",
+ "--conduction-primary-top-nav-dropdown-background-color",
+ "--conduction-primary-top-nav-dropdown-color",
+ "--conduction-primary-top-nav-dropdown-current-background-color",
+ "--conduction-primary-top-nav-dropdown-current-color",
+ "--conduction-primary-top-nav-dropdown-hover-background-color",
+ "--conduction-primary-top-nav-dropdown-hover-color",
+ "--conduction-primary-top-nav-dropdown-hover-text-decoration",
+ "--conduction-primary-top-nav-dropdown-text-decoration",
+ "--conduction-tabs-scroll-button-background-color",
+ "--conduction-tabs-scroll-button-color",
+ "--conduction-tabs-scroll-button-hover-background-color",
+ "--conduction-tabs-scroll-button-hover-color",
+ "--conduction-tabs-tab-background-color",
+ "--conduction-tabs-tab-bottom",
+ "--conduction-tabs-tab-button-bottom",
+ "--conduction-tabs-tab-color",
+ "--conduction-tabs-tab-font-family",
+ "--conduction-tabs-tab-font-size",
+ "--conduction-tabs-tab-font-weight",
+ "--conduction-tabs-tab-hover-background-color",
+ "--conduction-tabs-tab-hover-color",
+ "--conduction-tabs-tab-hover-font-weight",
+ "--conduction-tabs-tab-letter-spacing",
+ "--conduction-tabs-tab-list-border-bottom-color",
+ "--conduction-tabs-tab-list-border-bottom-style",
+ "--conduction-tabs-tab-list-border-bottom-width",
+ "--conduction-tabs-tab-list-margin-block-end",
+ "--conduction-tabs-tab-list-padding-inline-end",
+ "--conduction-tabs-tab-list-padding-inline-start",
+ "--conduction-tabs-tab-min-height",
+ "--conduction-tabs-tab-padding-block-end",
+ "--conduction-tabs-tab-padding-block-start",
+ "--conduction-tabs-tab-padding-inline-end",
+ "--conduction-tabs-tab-padding-inline-start",
+ "--conduction-tabs-tab-panel-padding-block-end",
+ "--conduction-tabs-tab-panel-padding-block-start",
+ "--conduction-tabs-tab-panel-padding-inline-end",
+ "--conduction-tabs-tab-panel-padding-inline-start",
+ "--conduction-tabs-tab-selected-background-color",
+ "--conduction-tabs-tab-selected-border-bottom-color",
+ "--conduction-tabs-tab-selected-border-bottom-style",
+ "--conduction-tabs-tab-selected-border-bottom-width",
+ "--conduction-tabs-tab-selected-color",
+ "--conduction-tabs-tab-selected-font-weight",
+ "--conduction-tabs-tab-selected-hover-color",
+ "--conduction-tabs-tab-selected-hover-font-weight",
+ "--conduction-tooltip-background-color",
+ "--conduction-tooltip-border-radius",
+ "--conduction-tooltip-color",
+ "--conduction-tooltip-padding-block-end",
+ "--conduction-tooltip-padding-block-start",
+ "--conduction-tooltip-padding-inline-end",
+ "--conduction-tooltip-padding-inline-start",
+ "--conduction-tooltip-z-index",
+ "--tilburg-border-radius-lg",
+ "--tilburg-border-radius-md",
+ "--tilburg-border-radius-round",
+ "--tilburg-border-radius-sm",
+ "--tilburg-border-width-lg",
+ "--tilburg-border-width-md",
+ "--tilburg-border-width-sm",
+ "--tilburg-box-shadow-lg",
+ "--tilburg-box-shadow-md",
+ "--tilburg-color-dark-alpha-50",
+ "--tilburg-color-extra-purple",
+ "--tilburg-color-green-100",
+ "--tilburg-color-green-300",
+ "--tilburg-color-orange-100",
+ "--tilburg-color-orange-300",
+ "--tilburg-color-pink-100",
+ "--tilburg-color-pink-200",
+ "--tilburg-color-pink-300",
+ "--tilburg-color-pink-400",
+ "--tilburg-color-red-100",
+ "--tilburg-color-red-300",
+ "--tilburg-color-red-400",
+ "--tilburg-document-color",
+ "--tilburg-document-font-size",
+ "--tilburg-document-font-weight",
+ "--tilburg-document-inverse-color",
+ "--tilburg-document-line-height",
+ "--tilburg-document-strong-font-weight",
+ "--tilburg-document-subtle-color",
+ "--tilburg-erm-font-size",
+ "--tilburg-feedback-informative-color",
+ "--tilburg-feedback-negative-color",
+ "--tilburg-feedback-positive-color",
+ "--tilburg-feedback-warning-border-color",
+ "--tilburg-feedback-warning-color",
+ "--tilburg-focus-background-color",
+ "--tilburg-focus-color",
+ "--tilburg-footer-link-hover-text-decoration",
+ "--tilburg-footer-link-text-decoration",
+ "--tilburg-form-control-background-color",
+ "--tilburg-form-control-border-color",
+ "--tilburg-form-control-border-width",
+ "--tilburg-form-control-color",
+ "--tilburg-form-control-disabled-color",
+ "--tilburg-form-control-focus-color",
+ "--tilburg-form-control-hover-color",
+ "--tilburg-form-control-placeholder-color",
+ "--tilburg-form-control-read-only-color",
+ "--tilburg-heading-color",
+ "--tilburg-heading-font-weight",
+ "--tilburg-icon-functional-size",
+ "--tilburg-interaction-active-color",
+ "--tilburg-interaction-color",
+ "--tilburg-interaction-hover-color",
+ "--tilburg-line-border-color",
+ "--tilburg-navigation-background-color",
+ "--tilburg-navigation-color",
+ "--tilburg-navigation-font-weight",
+ "--tilburg-navigation-hover-background-color",
+ "--tilburg-navigation-hover-color",
+ "--tilburg-navigation-mobile-background-color",
+ "--tilburg-navigation-mobile-item-border-bottom-color",
+ "--tilburg-pointer-target-min-size",
+ "--tilburg-size-2xs",
+ "--tilburg-size-4xs",
+ "--tilburg-size-icon-4xl",
+ "--tilburg-size-icon-md",
+ "--tilburg-size-icon-sm",
+ "--tilburg-size-md",
+ "--tilburg-size-xs",
+ "--tilburg-space-block-ant",
+ "--tilburg-space-block-beetle",
+ "--tilburg-space-block-cat",
+ "--tilburg-space-block-dog",
+ "--tilburg-space-block-flea",
+ "--tilburg-space-block-mouse",
+ "--tilburg-space-block-pig",
+ "--tilburg-space-block-rabbit",
+ "--tilburg-space-block-rat",
+ "--tilburg-space-block-snail",
+ "--tilburg-space-column-ant",
+ "--tilburg-space-column-beetle",
+ "--tilburg-space-column-cat",
+ "--tilburg-space-column-dog",
+ "--tilburg-space-column-elephant",
+ "--tilburg-space-column-horse",
+ "--tilburg-space-column-mouse",
+ "--tilburg-space-column-pig",
+ "--tilburg-space-column-rabbit",
+ "--tilburg-space-column-rat",
+ "--tilburg-space-column-snail",
+ "--tilburg-space-column-tiger",
+ "--tilburg-space-inline-ant",
+ "--tilburg-space-inline-beetle",
+ "--tilburg-space-inline-mouse",
+ "--tilburg-space-inline-rabbit",
+ "--tilburg-space-inline-snail",
+ "--tilburg-space-row-cat",
+ "--tilburg-space-row-dog",
+ "--tilburg-space-row-elephant",
+ "--tilburg-space-row-mouse",
+ "--tilburg-space-row-rabbit",
+ "--tilburg-space-row-rat",
+ "--tilburg-space-row-snail",
+ "--tilburg-space-row-tiger",
+ "--tilburg-space-text-beetle",
+ "--tilburg-space-text-mouse",
+ "--tilburg-space-text-snail",
+ "--tilburg-typography-font-size-2xl",
+ "--tilburg-typography-font-size-3xl",
+ "--tilburg-typography-font-size-lg",
+ "--tilburg-typography-font-size-md",
+ "--tilburg-typography-font-size-sm",
+ "--tilburg-typography-font-size-xl",
+ "--tilburg-typography-font-weight-bold",
+ "--tilburg-typography-font-weight-normal",
+ "--tilburg-typography-line-height-md",
+ "--tilburg-typography-line-height-sm",
+ "--utrecht-accordion-button-active-background-color",
+ "--utrecht-accordion-button-border-color",
+ "--utrecht-accordion-button-border-width",
+ "--utrecht-accordion-button-line-height",
+ "--utrecht-accordion-button-padding-block-end",
+ "--utrecht-accordion-button-padding-block-start",
+ "--utrecht-accordion-button-padding-inline-end",
+ "--utrecht-accordion-button-padding-inline-start",
+ "--utrecht-accordion-panel-border-color",
+ "--utrecht-accordion-panel-border-width",
+ "--utrecht-alert-border-width",
+ "--utrecht-alert-error-color",
+ "--utrecht-alert-icon-positive-color",
+ "--utrecht-alert-icon-warning-color",
+ "--utrecht-alert-info-border-color",
+ "--utrecht-alert-info-color",
+ "--utrecht-alert-ok-color",
+ "--utrecht-alert-warning-color",
+ "--utrecht-breadcrumb-nav-link-disabled-color",
+ "--utrecht-button-active-background-color",
+ "--utrecht-button-active-border-color",
+ "--utrecht-button-active-color",
+ "--utrecht-button-background-color",
+ "--utrecht-button-border-color",
+ "--utrecht-button-border-width",
+ "--utrecht-button-color",
+ "--utrecht-button-disabled-background-color",
+ "--utrecht-button-disabled-border-color",
+ "--utrecht-button-disabled-color",
+ "--utrecht-button-focus-background-color",
+ "--utrecht-button-focus-border-color",
+ "--utrecht-button-focus-color",
+ "--utrecht-button-font-size",
+ "--utrecht-button-font-weight",
+ "--utrecht-button-hover-background-color",
+ "--utrecht-button-hover-border-color",
+ "--utrecht-button-hover-color",
+ "--utrecht-button-icon-size",
+ "--utrecht-button-line-height",
+ "--utrecht-button-min-block-size",
+ "--utrecht-button-min-inline-size",
+ "--utrecht-button-padding-block-end",
+ "--utrecht-button-padding-block-start",
+ "--utrecht-button-padding-inline-end",
+ "--utrecht-button-padding-inline-start",
+ "--utrecht-button-primary-action-active-background-color",
+ "--utrecht-button-primary-action-active-border-color",
+ "--utrecht-button-primary-action-active-color",
+ "--utrecht-button-primary-action-border-color",
+ "--utrecht-button-primary-action-disabled-background-color",
+ "--utrecht-button-primary-action-disabled-border-color",
+ "--utrecht-button-primary-action-disabled-color",
+ "--utrecht-button-primary-action-focus-background-color",
+ "--utrecht-button-primary-action-focus-border-color",
+ "--utrecht-button-primary-action-focus-color",
+ "--utrecht-button-primary-action-font-weight",
+ "--utrecht-button-primary-action-hover-border-color",
+ "--utrecht-button-primary-action-hover-color",
+ "--utrecht-button-secondary-action-active-background-color",
+ "--utrecht-button-secondary-action-active-border-color",
+ "--utrecht-button-secondary-action-active-color",
+ "--utrecht-button-secondary-action-border-color",
+ "--utrecht-button-secondary-action-disabled-background-color",
+ "--utrecht-button-secondary-action-disabled-border-color",
+ "--utrecht-button-secondary-action-disabled-color",
+ "--utrecht-button-secondary-action-focus-background-color",
+ "--utrecht-button-secondary-action-focus-border-color",
+ "--utrecht-button-secondary-action-focus-color",
+ "--utrecht-button-secondary-action-font-weight",
+ "--utrecht-button-secondary-action-hover-background-color",
+ "--utrecht-button-secondary-action-hover-border-color",
+ "--utrecht-button-secondary-action-hover-color",
+ "--utrecht-button-subtle-active-background-color",
+ "--utrecht-button-subtle-active-border-color",
+ "--utrecht-button-subtle-active-color",
+ "--utrecht-button-subtle-background-color",
+ "--utrecht-button-subtle-border-color",
+ "--utrecht-button-subtle-color",
+ "--utrecht-button-subtle-disabled-background-color",
+ "--utrecht-button-subtle-disabled-border-color",
+ "--utrecht-button-subtle-disabled-color",
+ "--utrecht-button-subtle-focus-background-color",
+ "--utrecht-button-subtle-focus-border-color",
+ "--utrecht-button-subtle-focus-color",
+ "--utrecht-button-subtle-font-weight",
+ "--utrecht-button-subtle-hover-background-color",
+ "--utrecht-button-subtle-hover-border-color",
+ "--utrecht-button-subtle-hover-color",
+ "--utrecht-data-list-item-key-font-weight",
+ "--utrecht-document-font-size",
+ "--utrecht-document-inverse-color",
+ "--utrecht-document-line-height",
+ "--utrecht-form-field-error-message-color",
+ "--utrecht-form-label-checkbox-font-weight",
+ "--utrecht-form-label-color",
+ "--utrecht-form-label-font-size",
+ "--utrecht-form-label-font-weight",
+ "--utrecht-heading-1-font-size",
+ "--utrecht-heading-1-font-weight",
+ "--utrecht-heading-1-line-height",
+ "--utrecht-heading-2-font-size",
+ "--utrecht-heading-2-font-weight",
+ "--utrecht-heading-2-line-height",
+ "--utrecht-heading-3-font-size",
+ "--utrecht-heading-3-font-weight",
+ "--utrecht-heading-3-line-height",
+ "--utrecht-heading-4-font-family",
+ "--utrecht-heading-4-font-size",
+ "--utrecht-heading-4-font-weight",
+ "--utrecht-heading-4-line-height",
+ "--utrecht-heading-5-font-family",
+ "--utrecht-heading-5-font-size",
+ "--utrecht-heading-5-font-weight",
+ "--utrecht-heading-5-line-height",
+ "--utrecht-heading-6-font-family",
+ "--utrecht-heading-6-font-size",
+ "--utrecht-heading-6-font-weight",
+ "--utrecht-heading-6-line-height",
+ "--utrecht-link-active-color",
+ "--utrecht-link-focus-background-color",
+ "--utrecht-link-focus-color",
+ "--utrecht-link-focus-text-decoration",
+ "--utrecht-link-focus-text-decoration-thickness",
+ "--utrecht-link-hover-text-decoration",
+ "--utrecht-link-hover-text-decoration-thickness",
+ "--utrecht-link-icon-margin-inline",
+ "--utrecht-link-icon-size",
+ "--utrecht-link-text-decoration",
+ "--utrecht-link-text-decoration-color",
+ "--utrecht-link-text-decoration-thickness",
+ "--utrecht-link-text-underline-offset",
+ "--utrecht-ordered-list-font-size",
+ "--utrecht-ordered-list-item-margin-block-end",
+ "--utrecht-ordered-list-item-margin-block-start",
+ "--utrecht-ordered-list-padding-inline-start",
+ "--utrecht-paragraph-font-size",
+ "--utrecht-paragraph-font-weight",
+ "--utrecht-paragraph-lead-color",
+ "--utrecht-paragraph-lead-font-size",
+ "--utrecht-paragraph-lead-font-weight",
+ "--utrecht-paragraph-lead-line-height",
+ "--utrecht-paragraph-line-height",
+ "--utrecht-paragraph-small-color",
+ "--utrecht-paragraph-small-font-size",
+ "--utrecht-paragraph-small-font-weight",
+ "--utrecht-paragraph-small-line-height",
+ "--utrecht-radio-button-label-font-family",
+ "--utrecht-radio-button-label-font-size",
+ "--utrecht-radio-button-label-font-weight",
+ "--utrecht-radio-button-label-line-height",
+ "--utrecht-radio-button-min-block-size",
+ "--utrecht-radio-button-min-inline-size",
+ "--utrecht-select-background-color",
+ "--utrecht-select-border-color",
+ "--utrecht-select-border-width",
+ "--utrecht-select-color",
+ "--utrecht-select-disabled-background-color",
+ "--utrecht-select-disabled-border-color",
+ "--utrecht-select-disabled-color",
+ "--utrecht-select-font-family",
+ "--utrecht-select-font-size",
+ "--utrecht-select-hover-border-width",
+ "--utrecht-select-max-inline-size",
+ "--utrecht-separator-color",
+ "--utrecht-separator-margin-block-end",
+ "--utrecht-separator-margin-block-start",
+ "--utrecht-skip-link-text-decoration",
+ "--utrecht-table-cell-padding-inline-start",
+ "--utrecht-textbox-background-color",
+ "--utrecht-textbox-border-width",
+ "--utrecht-textbox-disabled-background-color",
+ "--utrecht-textbox-disabled-border-color",
+ "--utrecht-textbox-disabled-color",
+ "--utrecht-textbox-focus-background-color",
+ "--utrecht-textbox-focus-border-color",
+ "--utrecht-textbox-focus-color",
+ "--utrecht-textbox-font-size",
+ "--utrecht-textbox-font-weight",
+ "--utrecht-textbox-invalid-background-color",
+ "--utrecht-textbox-invalid-border-color",
+ "--utrecht-textbox-invalid-color",
+ "--utrecht-textbox-max-inline-size",
+ "--utrecht-textbox-padding-block-start",
+ "--utrecht-textbox-padding-inline-end",
+ "--utrecht-textbox-padding-inline-start",
+ "--utrecht-textbox-placeholder-color",
+ "--utrecht-textbox-read-only-background-color",
+ "--utrecht-textbox-read-only-border-color",
+ "--utrecht-textbox-read-only-color",
+ "--utrecht-unordered-list-font-size",
+ "--utrecht-unordered-list-item-margin-block-end",
+ "--utrecht-unordered-list-item-margin-block-start",
+ "--utrecht-unordered-list-marker-color",
+ "--utrecht-unordered-list-padding-inline-start"
+ ]
+}
\ No newline at end of file
diff --git a/tests/vitest/publicBridgeRoleLayer.spec.js b/tests/vitest/publicBridgeRoleLayer.spec.js
new file mode 100644
index 000000000..4b0442fa9
--- /dev/null
+++ b/tests/vitest/publicBridgeRoleLayer.spec.js
@@ -0,0 +1,247 @@
+/**
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * The public bridge carries the whole role layer the portal site reads, the
+ * accent and the brand stripe (openspec/changes/brand-motif-on-portals).
+ *
+ * Measured before this change: a portal on `wilgenboom` resolved 116 of the
+ * 489 component roles the site reads, against 489 on `example-basisschool`,
+ * so the header, the logo and the DigiD button drew in browser defaults. The
+ * tests below resolve a set the way a portal page does: the bridge first,
+ * then the set, `var()` followed to its end.
+ *
+ * @spec openspec/changes/brand-motif-on-portals/specs/brand-motif-on-portals/spec.md
+ */
+
+import fs from 'node:fs'
+import path from 'node:path'
+import postcss from 'postcss'
+import { describe, expect, it } from 'vitest'
+
+const ROOT = path.resolve(__dirname, '../..')
+const read = (rel) => fs.readFileSync(path.join(ROOT, rel), 'utf8')
+const SITE_ROLES = JSON.parse(
+ read('tests/vitest/fixtures/portal-site-roles.json'),
+).roles
+const SCHOOLS = ['wilgenboom', 'vaartveld', 'esdoornveen', 'warmtepompacademie']
+
+/**
+ * Custom properties declared on a stylesheet's top-level `:root` rules.
+ *
+ * @param {string} css The stylesheet.
+ * @return {Record} Property to raw value.
+ */
+function rootTokens(css) {
+ const tokens = {}
+ postcss.parse(css).walkRules((rule) => {
+ if (rule.parent.type === 'root' && rule.selector.trim() === ':root') {
+ rule.walkDecls(/^--/, (d) => {
+ tokens[d.prop] = d.value.replace(/\s+/g, ' ').trim()
+ })
+ }
+ })
+ return tokens
+}
+
+const BRIDGE = rootTokens(read('css/public-bridge.css'))
+
+/**
+ * The tokens a portal page ends up with: the bridge, then the set on top.
+ *
+ * @param {string} set The set id.
+ * @return {Record} The merged declarations.
+ */
+function pageTokens(set) {
+ return { ...BRIDGE, ...rootTokens(read(`css/tokens/${set}.css`)) }
+}
+
+/**
+ * Follow `var()` to its end, the way a browser computes a custom property.
+ * An undeclared name without a fallback is the guaranteed-invalid value,
+ * returned as null.
+ *
+ * @param {Record} tokens The declarations.
+ * @param {string} value A raw value.
+ * @param {number} depth Recursion guard.
+ * @return {string|null} The resolved value, or null.
+ */
+function resolve(tokens, value, depth = 0) {
+ if (depth > 20) {
+ return null
+ }
+ const start = value.indexOf('var(')
+ if (start === -1) {
+ return value
+ }
+ let level = 0
+ let end = start + 4
+ for (; end < value.length; end++) {
+ if (value[end] === '(') level++
+ if (value[end] === ')') {
+ if (level === 0) break
+ level--
+ }
+ }
+ const inner = value.slice(start + 4, end)
+ const comma = inner.indexOf(',')
+ const name = (comma === -1 ? inner : inner.slice(0, comma)).trim()
+ const fallback = comma === -1 ? null : inner.slice(comma + 1).trim()
+ let replacement = null
+ if (tokens[name] !== undefined) {
+ replacement = resolve(tokens, tokens[name], depth + 1)
+ }
+ if (replacement === null && fallback !== null) {
+ replacement = resolve(tokens, fallback, depth + 1)
+ }
+ if (replacement === null) {
+ return null
+ }
+ return resolve(
+ tokens,
+ value.slice(0, start) + replacement + value.slice(end + 1),
+ depth + 1,
+ )
+}
+
+const token = (set, name) => {
+ const tokens = pageTokens(set)
+ return tokens[name] === undefined ? null : resolve(tokens, tokens[name])
+}
+
+describe('the bridge names every role the portal site reads', () => {
+ it('declares each of them, so a set with only --nldesign-* paints the whole site', () => {
+ const missing = SITE_ROLES.filter((role) => BRIDGE[role] === undefined)
+ expect(missing).toEqual([])
+ })
+
+ it('holds at least the roles that were missing on 5 October (the control)', () => {
+ expect(SITE_ROLES.length).toBeGreaterThan(350)
+ for (const role of [
+ '--conduction-logo-header-background-image',
+ '--tilburg-navigation-background-color',
+ '--utrecht-button-primary-action-border-color',
+ '--tilburg-space-row-elephant',
+ ]) {
+ expect(SITE_ROLES, role).toContain(role)
+ }
+ })
+})
+
+describe.each([...SCHOOLS, 'zuiddrecht'])('%s on a portal', (set) => {
+ const primary = token(set, '--nldesign-color-primary')
+
+ it('draws the primary button and the header account button in its primary', () => {
+ expect(token(set, '--utrecht-button-primary-action-background-color')).toBe(
+ primary,
+ )
+ expect(token(set, '--tilburg-navigation-background-color')).toBe(primary)
+ })
+
+ it('shows its own logo in the header and a light one on the footer band', () => {
+ expect(token(set, '--conduction-logo-header-background-image')).toContain(
+ `img/logos/${set}.svg`,
+ )
+ expect(token(set, '--conduction-logo-header-block-size')).toBe('50px')
+ // The portal names the light logo in --nldesign-logo-inverse-url; with it
+ // absent the footer falls back to the set's own logo.
+ expect(token(set, '--conduction-logo-footer-background-image')).toContain(
+ `img/logos/${set}.svg`,
+ )
+ expect(token(set, '--thematiq-logo-text-font-size')).toBe('0')
+ })
+
+ it('reads its accent through the three vocabulary tokens', () => {
+ expect(token(set, '--thematiq-accent-color')).toBe(
+ token(set, '--nldesign-color-accent'),
+ )
+ expect(token(set, '--thematiq-accent-light-color')).toBe(
+ token(set, '--nldesign-color-accent-light'),
+ )
+ expect(token(set, '--thematiq-accent-text-color')).toBe(
+ token(set, '--nldesign-color-accent-text'),
+ )
+ expect(token(set, '--nldesign-color-accent')).not.toBe(primary)
+ })
+
+ it('hands its brand stripe to the site under the library names', () => {
+ expect(token(set, '--cn-brand-stripe-height')).toBe(
+ token(set, '--nldesign-brand-stripe-height'),
+ )
+ expect(token(set, '--cn-brand-stripe-color-1')).toBe(
+ token(set, '--nldesign-brand-stripe-color-1'),
+ )
+ })
+})
+
+describe.each(SCHOOLS)('%s accent agrees with its own palette', (set) => {
+ it('declares the palette entries as the vocabulary values', () => {
+ for (const step of ['', '-light', '-text']) {
+ expect(token(set, `--nldesign-color-accent${step}`)).toBe(
+ token(set, `--${set}-color-accent${step}`),
+ )
+ }
+ })
+})
+
+describe('the stripe and the motif', () => {
+ it('draws the motif image on the portal, and its inverse on a dark band', () => {
+ expect(token('wilgenboom', '--cn-brand-stripe-image')).toMatch(
+ /^url\("data:image\/svg\+xml,/,
+ )
+ expect(token('wilgenboom', '--cn-brand-stripe-image-inverse')).toContain(
+ '%235F9A78',
+ )
+ expect(token('esdoornveen', '--cn-brand-stripe-image-inverse')).toContain(
+ '238deg',
+ )
+ // No inverse of its own: the one image again.
+ expect(token('warmtepompacademie', '--cn-brand-stripe-image-inverse')).toBe(
+ token('warmtepompacademie', '--cn-brand-stripe-image'),
+ )
+ })
+
+ it('keeps zuiddrecht at three bands: red, blue, red, 6 : 3 : 1, 5px, no image', () => {
+ expect(token('zuiddrecht', '--cn-brand-stripe-image')).toBeNull()
+ expect(
+ [1, 2, 3].map((n) =>
+ token('zuiddrecht', `--cn-brand-stripe-color-${n}`),
+ ),
+ ).toEqual(['#CC0000', '#3669A5', '#CC0000'])
+ expect(
+ [1, 2, 3].map((n) =>
+ token('zuiddrecht', `--cn-brand-stripe-ratio-${n}`),
+ ),
+ ).toEqual(['6', '3', '1'])
+ expect(token('zuiddrecht', '--cn-brand-stripe-height')).toBe('5px')
+ })
+
+ it('draws nothing for a set that declares no stripe', () => {
+ expect(token('vng', '--cn-brand-stripe-height')).toBeNull()
+ expect(token('vng', '--cn-brand-stripe-image')).toBeNull()
+ })
+})
+
+describe('the footer bottom band', () => {
+ it('is the footer ground a step darker for a set that names one, nothing otherwise', () => {
+ expect(token('wilgenboom', '--thematiq-footer-legal-background-color')).toBe(
+ 'color-mix( in srgb, #1F4A33 80%, #000 )',
+ )
+ expect(token('vng', '--thematiq-footer-legal-background-color')).toBeNull()
+ })
+})
+
+describe('a set with a role layer of its own keeps it', () => {
+ it('example-basisschool still paints its primary button with its own value', () => {
+ const own = rootTokens(read('css/tokens/example-basisschool.css'))
+ const role = '--utrecht-button-primary-action-background-color'
+ expect(own[role]).toBeDefined()
+ expect(pageTokens('example-basisschool')[role]).toBe(own[role])
+ })
+
+ it('a set without an accent still marks the current item, in its primary', () => {
+ expect(token('vng', '--thematiq-accent-color')).toBe(
+ token('vng', '--nldesign-color-primary'),
+ )
+ })
+})
diff --git a/tests/vitest/schoolTokenSets.spec.js b/tests/vitest/schoolTokenSets.spec.js
index ed0aef1cf..4a78b4caf 100644
--- a/tests/vitest/schoolTokenSets.spec.js
+++ b/tests/vitest/schoolTokenSets.spec.js
@@ -46,7 +46,7 @@ const SETS = {
heading: null,
website: ['10px', '14px'],
stripe: false,
- stripeHeight: '14px',
+ stripeHeight: '17px',
legacyLabel: '#1A1A1A',
},
vaartveld: {
diff --git a/tests/vitest/workplaceLayout.spec.js b/tests/vitest/workplaceLayout.spec.js
index c8da66148..72a99ec5f 100644
--- a/tests/vitest/workplaceLayout.spec.js
+++ b/tests/vitest/workplaceLayout.spec.js
@@ -257,7 +257,16 @@ describe('brand stripe', () => {
)
}
expect(handed['--cn-brand-stripe-height']).toBe(stripe.height)
- expect(Object.keys(handed).length).toBe(7)
+ // The motif and its dark-band variant, with no fallback, so a set that
+ // names no image keeps the component's three bands
+ // (openspec/changes/brand-motif-on-portals).
+ expect(handed['--cn-brand-stripe-image']).toBe(
+ 'var(--nldesign-brand-stripe-image)',
+ )
+ expect(handed['--cn-brand-stripe-image-inverse'].replace(/\s+/g, ' ')).toBe(
+ 'var( --nldesign-brand-stripe-image-inverse, var(--nldesign-brand-stripe-image) )',
+ )
+ expect(Object.keys(handed).length).toBe(9)
})
it('is really drawn: content and display are declared, and important', () => {