Components are organised in numbered layers from atomic to full-page:
| Layer | Folder | Examples |
|---|---|---|
00-brand |
Brand tokens | colors, typography, icons, logo, themes |
01-base |
Base HTML elements | button, forms, grids, tables, typography |
02-unit |
Small UI units | avatar, card, tag, date, badge, hero, media |
03-group |
Composed groups | activity, profiles, ventures, events, articles |
04-region |
Page regions | site-header, site-footer, navigation, app-bar |
05-entity |
Full entity views | project, profile, organization, venture, user, post |
06-template |
Page templates | dashboard, search, onboarding, error-pages |
07-demo |
Demo/preview fixtures | — |
Gulp tasks handle:
gulp-svgminRun with gulp (dev) or gulp --prod (production build).
Custom Twig functions defined in fractal.js mirror the theming layer of the platforms this system serves:
get_component_class / get_entity_class — BEM class generation with modifier, theme, and layout supportget_entity_template / get_template — dynamic template resolution by view modesvg() — inline SVG inclusionclean_class, t() — WordPress/Twig filter adaptersTwig namespaces (@base, @unit, @group, etc.) allow components to include each other across layers.
The docs/publishing-and-play/ folder mirrors plugin READMEs from the parent repository. When plugin docs change there, the corresponding files here are updated to keep documentation in sync.
Add a progressively-enhanced Article feedback form [*]
New Yes/No feedback form for articles (“Was this play helpful?”), meant to be embedded via the CTA component’s formTemplate option. Without JavaScript, all three controls (Yes, No, and the “what went wrong” Submit button) are real submit buttons and the detail textarea is never hidden server-side, so the form is fully usable as a plain POST. With JavaScript, the detail field is moved after the Yes/No actions and hidden until “No” is clicked, the chosen answer submits asynchronously, and the clicked button is locked in (recolored, disabled) instead of removed, so the visitor can see what they picked but can’t change it.
Release date: 05.08.2026
New
components/02-unit/forms/article-feedback-form.twig, article-feedback-form.config.yml: new self-contained Yes/No feedback form, following the mailing-list-form.twig data-uuid/response-container patterncta/cta.config.yml: new “Article feedback” variant wiring the form in via formTemplate: 'article-feedback-form'_utilities/_progressive-enhancement.scss: new js-no-js-hide, js-with-js-hide, js-no-js-show, js-with-js-show utility classes for toggling visibility between the existing no-js/with-js states on <html>global.js: new process_article_feedback_forms() — moves and hides the detail field for JS visitors, reveals it (and its Submit button) on “No”, locks in the chosen button (c-button--success/c-button--danger, the other c-button--muted) instead of hiding either, and on a connection error only re-enables the controls relevant to the failed attempt (Yes/No for a direct submit, just the detail field and its Submit button when retrying feedback text)Render Venture matches as a list in the Profile and Venture full-page templates [*]
profile--full.twig already rendered its “Venture matches” section by including @group/entities directly inside an .l-section__entities wrapper; venture--full.twig only ever showed a single venture_match. Both now go through a new reusable venture-matches group component instead, and venture--full.twig gains the plural “Venture matches” list, falling back to the old singular output when only venture_match is present.
Release date: 24.07.2026
New
components/03-group/venture-matches/: new group component wrapping @group/entities with an optional heading, for rendering a collection of Venture Match entitiesprofile.config.yml, venture.config.yml: add venture_matches fixture data for the new sectionImprovements
profile--full.twig, venture--full.twig: “Venture matches” section now renders via the new venture-matches group component when a venture_matches collection is present; venture--full.twig falls back to the existing single venture_match output otherwise. profile--full.twig no longer passes an explicit display: { component: 'section__entities' } override into entities for this section, so the list wrapper and its items now render as c-profile/c-venture (from venture_matches.display.component) instead of c-section__entitiesventure-match.twig: bottom action bar (links/button) now also renders in list-item view mode, so entries in the venture-matches list can show their own actions_section.scss: .l-section--card border/spacing and workflow-info rules previously only matched the literal c-section__entities/.l-section__entities classes, which the venture-matches list no longer emits (see above); they now also match generic [class*='__items__item']/[class*='__items']/[class*='__item'] substrings, so the list gets the same card styling regardless of its actual component nameFixes
_theme.scss: muted/disabled link selectors had one fewer :not() clause than the themed border/background rule, so they always lost that specificity contest and never actually overrode the themed border color, no matter their source order. Adding the same .c-dropdown__item__link exclusion brings them to parity — they now reliably win the cascade, and dropdown result rows are excluded from muted/disabled styling consistently with the other link rulesAdd a bottom action bar to the Meeting and Venture Match full-page templates [*]
Both templates already received a Drupal-computed links/button context (a Meeting’s Update/Cancel/Delete links, a Venture Match’s “Add meeting” button), but neither one rendered it. meeting.twig also passed its whole ambient context into the boarding-pass include without scoping it, and venture-match--full.twig passed its banner context the same way — both let button/links leak into the nested banner/boarding-pass component whether or not that component was meant to show its own actions.
Release date: 21.07.2026
New
meeting.twig, venture-match--full.twig: new bottom @region/app-bar block rendering the entity’s links/button, shown only in full view modeFixes
meeting.twig: boarding-pass include now uses only and explicitly excludes button/links from its scope in full view mode, so the bottom action bar’s links no longer also render inside the boarding passventure-match--full.twig: banner include now uses only, so the ambient button no longer leaks into the banner and renders a second time thereAdd a Dropdown unit and style Drupal’s autocomplete widget to match [*]
New Dropdown unit component for autocomplete-style result lists (hover/active states, 5-row scrollable max-height, empty-results variant), reused by a new Drupal frontend adapter that styles core’s jQuery UI .ui-autocomplete widget on entity reference autocomplete fields.
Release date: 20.07.2026
New
components/02-unit/dropdown/: new Dropdown unit for autocomplete-style result lists_autocomplete.scss: new Drupal frontend adapter applying the Dropdown unit’s styles to core’s jQuery UI .ui-autocomplete widget (.ui-menu-item, .ui-menu-item-wrapper, .ui-state-active)Fixes
_theme.scss: exclude .c-dropdown__item__link from the themed link border and hover-expanding background, so autocomplete/dropdown result rows no longer render with a link underlineParticipants in Discovery Journey Phase, Supporters in Learning Group, and guard empty Profile meta
Release date: 10.07.2026
New
discovery-journey-phase--full.twig: new “Participants” section, mirroring the existing “Projects” section, shown when participantsCollection or participantsEmpty is presentlearning-group--full.twig: new “Supporters” block in the details column, shown when supporters is present, using @group/entities/entities.twigImprovements
discovery-journey-phase--full.twig: “Projects” section now only renders its heading when projectsCollection or projectsEmpty is present, instead of unconditionallylearning-group--full.twig, expert-pool--full.twig: remove stray l-section class from the details <section>Fixes
profile--full.twig: default meta no longer shows a stray ", " when both indexCard.role and indexCard.organisation are empty; falls back to an empty items listExpand and normalise country maps [*]
Ten new countries added to the country maps component, all map assets regenerated to a consistent dot-grid format, and the generation process documented for future additions.
Release date: 15.05.2026
New
country-maps.config.yml: added Albania, Azerbaijan, Germany, Italy, Kenya, Kosovo, Portugal, Switzerland, Tajikistan, TunisiaImprovements
assets/src/graphic/maps/: all map SVGs normalised to a consistent dot-grid format (viewBox="0 0 100 100", radius 1.25, 3.5-unit grid, single <path>, no metadata)components/00-brand/icons/README.md: documented map SVG spec and Claude Design generation promptSilence autoprefixer warnings about flex alignment [*]
Release date: 27.04.2026
Fixes
_full-height.scss, _section.scss: replace justify-content: end with justify-content: flex-end to resolve autoprefixer mixed-support warningsExclude banner, callout and CTA headings from block anchor links [*]
Release date: 27.04.2026
Fixes
global.js: headings inside .c-banner, .c-callout, and .c-cta are now excluded from receiving the js-has-block-anchor class and the permalink anchor linkAdapt Page styles to include Discovery Journey timeline and fit the content
Release date: 01.04.2026
Improvements
_page.scss: replace ‘application-timeline’ with ‘c-timeline–columns-2’Remove unused sitemap data and overview files from src
Release date: 31.03.2026
Improvements
sitemap-data.json and sitemap-overview.html removed from assets/srcFor the full history see the changelog.