orgaMAX × Growably

How the new orgamax.de is built, run and maintained

One reference for everyone on the project: developers and designers at Growably, and the orgaMAX team who edit the site. What is open, who owns it, how every page, component, script and CMS collection works, and how to change things safely. Filter by topic or search for any class, attribute, field or page.

CMS collections
28
Pages & templates
112
Components
160+
Guide entries
121
8 entries

Start here

Who this guide is for

This guide describes the new orgamax.de on Webflow for everyone who works on it. Pick your path:

  • orgaMAX team (content, marketing, IT): Open tasks → lanes 1 and 2 (your checklist), CMS (every collection: why it exists, what to fill), Components, How to (recipes), the rich text list styler in Custom code explained, and the video tutorials linked in Important links.
  • Developers (Growably or anyone taking over): Your first hour, Rules & standards, Pages & structure, Scripts & site code, Custom code explained, Webflow gotchas.
  • Project leads: Open tasks: the four-lane task board plus the detail entries below it.

Search finds any class, attribute, field name or page. Every entry has a # link to share and every code block a Copy button. The switch at the top changes light and dark mode.

Important links

WhatLink
Video tutorials (everything we recorded for orgaMAX)growably-onboarding.webflow.io/clients/orgamax
Webflow workspaceorgaMAX – deltra Business Software (orgaMAX's workspace). Growably login: team@growably.de, role Guest. Switch to it in the Dashboard workspace menu.
Webflow Designerorgamax.design.webflow.com
Staging site (becomes the live site at launch)orgamax.webflow.io
Figma designorgaMAX - Website Project
Feedback sheet (all open points)Open ToDos (tab gesammelte-fehler)
Nav, footer and CTA links videoTella walkthrough
Component library pageDesigner → Pages → [Draft] Example Components (see Components)
Slack: client channel#orgamax-x-growably
Redirect map (YOYABA)Redirect sheet
SEO keyword benchmark (YOYABA)Keyword sheet
Hub panel request (#90) in FigmaFunktionen frame

Your first hour (developers)

  1. Check access (10 min): log in to Webflow as team@growably.de and switch the Dashboard workspace from "Growably" to orgaMAX – deltra Business Software (the site is not in the Growably workspace). Then open everything in Important links (Designer, staging, sheet, Figma, Slack) plus Pastel. Watch the tutorials once: they show how orgaMAX edits the site. Connect Claude to Webflow and Pastel (Claude, MCP & tools).
  2. Read three entries (20 min): Open tasks (the task board: lane 3 is yours), Page skeleton every page must follow (body u-theme-light, main.page-main, Sections), Working rules on this project (what we do vs what orgaMAX does).
  3. Skim the sheet (15 min): filter In charge = growably, Status not done. Every row must have a short English comment from us.
  4. Know where code lives (15 min): site head and footer (Scripts & site code), Global Styles component (Custom CSS), one entry per script (Custom code explained), and the Attribute index when you find an unknown attribute.

Three things never to do: publish without checking that nobody on the orgaMAX team is mid-edit, change a CMS field type (it breaks bindings, see Rules), or edit a minified script line by hand.

When something breaks: search this page for the class or attribute on the broken element. Every script entry has a "What breaks it" and a "How to test" part with console snippets (each code block has a Copy button; each entry has a # link you can share).

Project in one paragraph

orgaMAX (deltra Business Software, part of Buhl) is relaunching orgamax.de from TYPO3 to Webflow. Growably builds the site: strategy, design (Melissa, Piko), development (Sachin; Nikola covers while Sachin is on vacation) and CMS architecture. The site is German only, no Webflow Localization. Design is in Figma, the build uses the Lumos framework (utility classes u-*, components with props, variables for every colour, size and space).

Current phase: the build is feature-complete. We are in the feedback phase: orgaMAX reports issues in a shared Google Sheet, our designers review in Pastel, and orgaMAX's content team fills the CMS. Launch prep (redirects, SEO benchmark keywords) runs with YOYABA in parallel.

How current this guide is

Every entry was checked against the live Designer, the CMS, the staging site, the feedback sheet, Slack and Pastel on 10 and 11 October 2026. Two Designer facts were read directly via the Webflow API that day (TOC template element type, Lexikon panel transition).

When you change something this guide describes, update the entry the same day: the guide is generated from build_handover.py (edit ENTRIES, run it, it writes this single HTML file). An entry that is wrong is worse than a missing one.

Access, IDs and links

WhatWhere / value
Webflow workspaceThe site lives in orgaMAX's own workspace "orgaMAX – deltra Business Software", not in the Growably agency workspace. Growably works in it as a Guest through the Webflow login team@growably.de. To find it: Webflow Dashboard → workspace switcher top left (shows "Growably") → pick orgaMAX – deltra Business Software → All projects → orgaMAX (orgamax.webflow.io, plan badge Team).
Webflow site6a7981e0c5fe5f5bfb985799 (workspace 6a05f2872e67b37aead389ab)
Designerorgamax.design.webflow.com
Stagingorgamax.webflow.io (staging subdomain of the same site; at launch the custom domain is added to this site, nothing is cloned. Florian asked this on 8 Oct, confirm it to him)
PlanWebflow Enterprise contract, Team tier. Per Webflow: no Optimize (A/B, geo), no DevLink, no Webflow Custom Hosting. Webflow Cloud is included. Branching is available.
FigmaorgaMAX - Website Project (always check the frame before setting backgrounds, ratios, spacing)
Client to-do sheetOpen ToDos, tab gesammelte-fehler (open rows) and Done (finished rows get moved there)
Design reviewPastel (internal Growably comments on the staging pages). Pastel MCP is connected in Claude.
Slack#orgamax-x-growably (shared channel: orgaMAX, Growably, YOYABA)
Nav and footer walkthroughTella video sent to the client (they maintain links themselves)
Redirect mapYOYABA redirect sheet (orgaMAX turned it into IMPORT_REDIRECTS.csv)
SEO keywordsYOYABA keyword benchmark

People

WhoRoleTalk to them about
Sachin (Growably)Lead Webflow developerEverything built in this guide. On vacation from 12 Oct for about a week
Nikola (Growably)DeveloperCovers development while Sachin is away
Yannik (Growably)Project leadScope, architecture decisions, anything new or unplanned. First contact while Sachin is on vacation
Florian Lückert (orgaMAX)Main client contactSheet items, content, technical questions, redirects, HubSpot, custom code pages
Shereen Bornemann (orgaMAX)Content editorCMS content, imports
Jannis Lange (orgaMAX)Marketing leadOn vacation until 26 Oct. Decides HubSpot consent, pricing content
Melissa, Piko (Growably)DesignFigma, Lottie re-exports, visual questions
Mindaugas / Oliver (YOYABA)SEO partnerRedirect map, keyword tracking
Pierre, Kristina (Growably)Also build in the CMSCMS entries

How the client feedback loop works

  1. orgaMAX writes issues into the sheet (tab gesammelte-fehler). Columns: Nr, Area, URL, Section, Device, Description, In charge (growably / orgamax), Status (open, in progress, feedback needed, fixed, done), Informations.
  2. We set In charge, Status and write a short English comment for every row. Always match rows by the Nr column, never by sheet row number: finished rows are moved to the Done tab and the rows shift.
  3. Rule: content, CMS entries and simple Designer edits (section props, visibility, reordering, links) are maintained by the orgaMAX team; Growably provides how-to guidance for them and handles development.
  4. Pastel is used for design review. Dev items get fixed and set to In review. Content items get added to the sheet with In charge = orgamax plus a Pastel reply.
  5. Status fixed means fixed by us and live after the next publish. done means nothing to change or already confirmed.
6 entries

Open tasks

Task boardDo first

Every open point is one card, in the column of who acts next. The coloured badge on each card names the person. Cards with an answer or note carry the ready text: Nikola posts answers in the right Slack thread, Yannik reads his notes and decides. Ticks are saved in your browser; the shared record stays the feedback sheet (tags like #88 are its rows). State: 12-10-2026.

orgaMAX · do now

22

Nothing blocks these: content, CMS, links, images, HubSpot.

orgaMAX · waiting on Growably

1

Questions orgaMAX asked that still need our answer. Each card says who answers.

  • Note for Yannik

    Yannik, a decision for you: Florian asked (9 Oct, sheet thread) whether the ~377 auto-imported newsletter images can be fixed without re-uploading each by hand. They are small and partly still load from the old domain.

    • Technically possible: a script via the Webflow API downloads the originals, converts them to AVIF in the right ratio, uploads them and relinks every item.
    • Not in the original scope. Please decide whether we offer it (and at what effort) or orgaMAX replaces them manually. Sachin can estimate after his vacation.

    Then reply to Florian in that thread.

Growably · do now

5

Our own next steps. The badge says who.

  • Note for Yannik

    Yannik, a decision for you: Florian asked (9 Oct, sheet thread) whether the ~377 auto-imported newsletter images can be fixed without re-uploading each by hand. They are small and partly still load from the old domain.

    • Technically possible: a script via the Webflow API downloads the originals, converts them to AVIF in the right ratio, uploads them and relinks every item.
    • Not in the original scope. Please decide whether we offer it (and at what effort) or orgaMAX replaces them manually. Sachin can estimate after his vacation.

    Then reply to Florian in that thread.

  • Note for Yannik

    Yannik, a decision for you: orgaMAX's own Pastel board has 6 Home comments from 28 Aug (Lisa, Jannis) that nobody has picked up. Two look like build fixes (hover overlap, a hover effect), the rest are images or design. Please decide whether we propose to take the build ones; Nikola can then ask Florian to confirm. Details: Client Pastel board entry below.

Growably · after orgaMAX replies

8

Starts when the answer, file or decision arrives. Developer = Nikola now, Sachin after his vacation.

Done this week

8

Fixed by Growably on 12-10-2026, live after the next publish.

  • Footer accessibility: logo link named "orgaMAX Startseite", names for the 3 social links, German alt texts for the 4 award badges.SachinA11yFooter
  • Footer mobile accordion: closed sections hidden from the keyboard under reduced motion; chevron breakpoint aligned to 992 px.SachinA11yFooter
  • Table of contents: items are real links (keyboard and screen readers) on the Lexikon and E-Rechnungs Hub templates, the TOC and Social Share component (newsletter, case studies) and all 12 competitor pages.SachinA11yTOC
  • Load More: generic announcement "weitere Einträge geladen"; the team page keeps "Personen" via attributes.SachinA11yLoad More
  • GSAP console warnings on /rechnungen: solved.SachinFixSlack 8 Oct
  • /funktionen rail script documented (Custom code explained).SachinDocs#90
  • Single-plan pricing hero built as Section / Pricing / Single Plan; the showcase instance was removed from /preise.SachinBuildLP hero
  • Answers sent to Florian by DM: IP range for Buhl IT, GSAP / webflow.schunk, which page the single-plan hero is for (for Shereen), and the launch question about the backend URL.SachinReplySlack

Detail · Homepage hero: waiting on designNext

The homepage hero is still work in progress on the design side: Jannis left 2 change comments in Figma (homepage hero frame, Sachin tagged) and Piko sent Florian two new hero graphic versions on 9 Oct. Only when design marks the hero as final: implement Jannis' comments and swap the hero graphic. If it is not final next week, it waits for Sachin.

Detail · Open Slack threads (checked 12 Oct)Do first

Messages from Growably that still wait for an answer or action from orgaMAX, and questions from orgaMAX that Growably has not answered yet. Check these threads first when you start; reply in the thread, never in a new message.

Waiting on orgaMAX (no reply yet):

  • 11 Oct, /funktionen hub panels: 6 questions (content, links, behaviour, design, CMS fix). Sheet #90. See the task above.
  • 10 Oct, tab visuals: list of 18 pages that still show homepage animations; how to set image / video / Lottie per tab. Sheet #88.
  • 10 Oct (thread of 9 Oct), ERP link and announcement bar: we asked for a screenshot or link of Florian's Figma comment (flexible ERP link, #4) and for the target page of "Deutschland-Tor am 25.06.26". No answer.
  • 8 Oct, navigation guide + video: asked orgaMAX to set the remaining nav, footer and CTA links themselves (sheet #1, #2, #77, #89).
  • 8 Oct, images: AVIF only, no PNG/JPG, export at display size, logos as SVG. Reference for anyone uploading images.
  • 8 Oct, headings: H1 for the hero, H2 for every section, set the tag after pasting. Info.
  • 7 Oct, pricing API: how prices and the comparison table are controlled on /preise. Info.

Questions from orgaMAX: IP range, console / webflow.schunk and Shereen's page question were answered by DM to Florian on 12-10-2026. Only the newsletter images remain (Yannik decides).

Background:

  • 9 Oct (in the sheet thread), imported images: Florian asked if the auto-imported newsletter images (about 377, small, old-domain fallbacks) can be fixed without uploading each by hand. Possible with a script via the Webflow API; approach and effort are agreed with Yannik (project lead) first.
  • 8 Oct (components thread), console and files: GSAP warnings solved (12 Oct). The answer to Florian, including the "webflow.schunk" explanation, is ready on the Task board (column orgaMAX · waiting on Growably) for Nikola to post.
  • 8 Oct, IP range for the Buhl mail server: Webflow does not publish a fixed IP range for form or backend traffic. Needs a Webflow support answer (via Webflow support), then reply to Florian.
  • 7 Oct (LP hero thread), Shereen: asked which page the single-plan pricing hero is for. See the next task.

Detail · Client Pastel board (Home page comments)Next

Where: Pastel canvas Client board (orgamax.webflow.io), project "Client". This is orgaMAX's own feedback board. Growably's internal design review is a separate canvas, orgaMAX - Review.

Status: the comments below were left on 28 Aug by Lisa (Lisa Krawczyk) and Jannis on the Home page and are still active. They have not been worked on yet: the next step is to agree with orgaMAX which points are build changes and which are content or design changes. A comment is resolved only after the agreed change is live.

#FromComment (short)Likely owner
1LisaWhen zooming in, the image crop cuts off too much of the headImage choice / focal point (orgaMAX), crop CSS if they want a fix
2LisaOn hover the images slightly overlap the button text; asks if employee photos will be addedHover overlap: Growably (CSS). Photos: orgaMAX
3LisaSecond image has English text in the top left corner, should be GermanDesign asset (Melissa / Piko)
4LisaA hover effect here would be niceDesign decision first, then Growably
5LisaImage should change: shows a call centre person, not a tax advisorImage from orgaMAX or design
10JannisTypo inside the Dokumentenmanagement image: "Orgamax Buchgaltung" → "orgaMAX Buchhaltung"Design asset (re-export the visual / Lottie)

Also waiting on orgaMAX (marked in review, awaiting a decision): #11 Markus: the homepage headline is not final for him. #13 Markus: the dashboard visual should show a better, more realistic UI. #16 Marleen: tiles stack on mobile, asks for horizontal scrolling. #17 Marleen: shorten a button text on mobile so it stays on one line.

What to do: open each comment and read the replies. Then ask Florian in the client Slack thread which of #1 to #5 and #10 Growably should handle, and send the design items to Melissa / Piko. Development starts on the confirmed points; new requests are planned with Yannik (project lead).

Detail · SEA landing page hero with a single pricing plan

Status 12-10-2026: built. The section is the component Section / Pricing / Single Plan (Components panel). It was shown on /preise as a showcase and has been removed there. orgaMAX adds it to the landing pages where it is needed and sets eyebrow, title, text, variant and plan in the properties. It uses the same pricing attributes and script as /preise, so prices and the Monatlich / Jährlich switch work automatically (see JS / Pricing Card).

Requirements confirmed by Florian on 7 Oct: white and blue version, working billing switch, every plan selectable. Shereen's question (which page) was answered by DM to Florian on 12-10-2026.

Detail · /funktionen hub panels (#90)Next

Status: new request (from Jannis via Florian), an extension of the current /funktionen design. Questions sent to Florian on 11 Oct, sheet row #90 is feedback needed. Sachin builds this after his vacation. Work starts once the answers and content are in. If orgaMAX needs it sooner, Nikola can start as soon as points 1 to 4 below are answered.

What they want: on /funktionen ("Alle Funktionen auf einen Blick", Figma frame), clicking a hub in the left rail (Rechnungen, Angebote & Aufträge, Stammdaten & Kontakte, Steuern, Warenwirtschaft) should also show a panel on the right, like clicking a function does today. Today: a hub only opens/closes its list of functions; a function shows image, title, text, 3 bullets, "Mehr dazu" + "Kostenlos testen" on the right; on load the first hub opens with its first function shown.

Questions we asked (answers go in the sheet comment of #90):

  1. Content per hub: panel image (same style as function panels), 150 to 250 character text, 3 bullets, button label. Who writes it, by when? Nothing goes live until all five are filled.
  2. Button target per hub (hubs have no CMS page of their own, so the link is entered manually).
  3. Our proposal: on desktop one hub always stays open (clicking the open hub does nothing); mobile keeps collapsing as today.
  4. Our proposal: on load show the first hub's own panel instead of its first function.
  5. Selected-hub style in the rail: design question for Melissa (who briefs her?).
  6. CMS fix first: Angebote & Aufträge lists (E-)Rechnungen and Mahnwesen under Funktionen im Bereich although they belong to other hubs; (E-)Rechnungen twice breaks the rail once hubs are clickable. Plus a stray character at the end of that hub's name.

Build plan once answered:

  • New fields in Funktionen Hubs, following the CMS field type rule: Panel Bild (Image), Panel Bild Alt (PlainText), Panel Text (RichText), Panel Vorteile (RichText, a bullet list: the list styler gives the check icons), Panel Button Text (PlainText), Panel Button Link (Link). Run the field type self-check before calling it done.
  • Add a hub panel to the right column (same layout as the function panel, bound to the new fields) and extend the rail script on /funktionen (page-level u-embed-js embed) so a hub click shows its panel; apply decisions 3 and 4.
  • Read that embed before changing anything: it is the one script not yet covered in Custom code explained.
  • Test: keyboard (Enter/Space on hub and function), focus stays visible, screen reader state (aria-expanded on hubs), 375 px accordion, no duplicate functions in the rail.
1 entries

For orgaMAX editors

Editing rules for everyone

  • Images: AVIF only (convert via picflow.com), export at 2x, in the exact Figma aspect ratio. Logos and icons as SVG.
  • Headings: hero = H1 (one per page), every section below = H2. Pasted text loses the tag, set it again in Rich Text.
  • [CMS] components: content comes from the CMS, only eyebrow, title, description are props. [Global Component]: edit inside the component, applies everywhere (Section / Resourcen is used 27 times).
  • Nav, footer, CTA links: they maintain them (video).
  • FAQ names do not contain page names (some FAQs are shared by 10 pages).
5 entries

Rules & standards

Working rules on this project

  • Webflow classes are the source of truth. If a property can be set in Webflow (incl. breakpoints, states, variants) set it there with variables. Embeds only hold what Webflow cannot do.
  • Variables only, never hex. Exact names: --swatch--primary--blue, -blue-300, -blue-100; --accent--gold (-300, -100); --neutral--grey-600 to -100, --neutral--white (-80, -30, -16, -12, -8). Never --swatch--neutral--*. Error red has no variable: #eb1c1c.
  • Spacing --_spacing---space--0/4/8/12/16/20/24/32/40/48/56/64/80/96/112. Fonts Sora (primary), Poppins (secondary).
  • CSS quality bar: hover inside @media (hover: hover), keyboard parity with :focus-visible / :focus-within, ring overlays via ::after (no layout shift), reduced motion and forced colors handled, @supports for new features.
  • CSS and JS in separate embeds. When changing an embed, replace the full block, not partial snippets. Embed limit 50k characters.
  • Test before handing over. Console snippets or a Playwright harness, desktop and 375 px.
  • Debugging: one step at a time, confirm the cause with a console check before changing anything.
  • Section backgrounds: Figma fill style Gradient/bg-1, bg-2, bg-3 = Gradient component variant BG 1, 2, 3.
  • Messages to the client: English, short, only what was agreed, no promising calls. CMS field names and help texts stay German.

Class naming (Lumos)

  • Utilities start with u- and do one thing: u-margin-bottom-24, u-gap-16, u-radius-20-16 (desktop / ≤991 pair), u-color-grey-500, u-theme-dark, u-hide-if-empty-cms.
  • Component classes are block_element: faq_question_text, card_case-studies_logo_wrap, nav_header. Collection lists: *_clw (wrapper), *_cl (list), *_ci (item).
  • States and variants are combo classes starting with is-: is-active, is-support, is-inline. Webflow component variants appear as w-variant-… in the HTML.
  • Scripts hook onto attributes (data-*, cg-*), never onto styling classes, so renaming a class does not break JS.

CMS field type rule

Every text field is Rich Text (headings, labels, badges, stats, body). Plain Text only for: the main hero H1 of a CMS template (Name), button labels, SEO / meta fields, image alt text, technical IDs (embed / form IDs). Reason: Webflow cannot bind Rich Text to attributes, embeds or buttons.

Apply it when creating fields, never after (changing a type means delete and recreate, the slug gets a -2 suffix and every binding breaks). After adding fields, list every text field and check it against this rule.

Swiper standard

Every slider init is scoped per instance (querySelectorAll), waits for the Swiper global, never uses loop (duplicate slides hurt SEO), keeps a11y with German labels, speed 0 on reduced motion, watchOverflow, observer / observeParents, lazy init via IntersectionObserver. Pagination bullets are generated by Swiper, never built in the Designer. Swiper is loaded by the components CDN / Swiper CSS and CDN / Swiper JS (only on pages that need it).

Heading tags and images

H1 once in the hero, H2 for every section below. Images as AVIF in the Figma ratio. When you set a background or a visual value, check the Figma frame first.

4 entries

Pages & structure

Page skeleton every page must follow

body.u-theme-light        ← required on every page
└─ page_wrap
   ├─ Global Styles        (component: all global CSS embeds)
   ├─ Navbar               (component: fixed nav + its CSS/JS)
   ├─ Global Guides        (component: grid preview, hidden)
   ├─ main.page-main       ← required
   │  ├─ Section           (component; its u-container gets the nav spacer)
   │  ├─ Section ...
   └─ Footer               (component)

The nav is fixed. The spacer that pushes content below it only applies when the first section inside .page-main has a .u-container. Custom code pages must put their embed inside a Section's container. Escape hatch: add data-nav-offset-target to the element that should get the spacer.

Body class: the body of every page and template always carries u-theme-light. It sets the page's base theme (text colours, button tokens, card accent). Dark areas are added per section with u-theme-dark, never on the body. Check it on every new or duplicated page: Designer → select Body → class u-theme-light.

Light page without a dark hero: set the Navbar prop data-nav-theme = light. Special pages without menu: Navbar visibility props and Footer Footer CTA Visibility (used on /passwort-vergeben).

Page map

AreaPagesNotes
Funktionen/funktionen, hubs /rechnungen /angebote-auftraege /stammdaten-kontakte /steuern /warenwirtschaft, template /funktion/[slug]Hubs are static pages built from the static template Funktionen-Hub-Template (Pages → Static page templates → +)
ERP/erp-hub, template /erp-funktionen/[slug]Separate collection ERP Funktionen
Branchen/branchen (filter overview), template /branchen/[slug]Slider of same-category industries (native filters)
Kunden/kunden, template /kundenstories/[slug]Case Studies collection
Wissen/guides-vorlagen, /webinare, /lexikon, /e-rechnung-themen, /newsletter, /newsletter-archiv, /weiterbildungen, /roadmapTemplates for guides, webinars, lexikon, e-rechnung, newsletter articles, weiterbildungen
Pricing/preise, /supportpaketeStatic, attribute-driven pricing JS
Competitorfolder /competitor: lexoffice, DATEV, easybill, fastbill, HERO, JTL, papierkram, plancraft, sevdesk, weclapp, XentralStatic pages from one base page
LPs (SEA)folder /lp: angebot, auftrag, belege, rechnung, eur, lieferscheine, mahnung, ustva, warenwirtschaft, orgamax-auftrag(-pro), orgamax-warenwirtschaft(-pro), paid-social; plus /google-shoppingFAQ section per page uses the Website Pages tag
Unternehmen/uber-uns, /team, /karriere + template /stellenangebote/[slug], /partner, /auszeichnungen, /datensicherheit
Service/support, /supportpakete, /dienstleistungen, /fernwartung, /download, /produktberatung, /weiterempfehlung, /wechselrabatt-bis-zu-50-mit-orgamax
Legal / special/impressum, /datenschutz, /agb, /avv-abschliessen, /e-rechnungs-quiz, /passwort-vergeben, /passwort-aendern, /ch/...AVV and quiz contain orgaMAX's own code; password pages are legacy ERP flows
New SEO pages/rechnungsprogramm, /enterprise-warenwirtschaft, /xrechnung-vs-zugferd-vergleich (draft)Built by orgaMAX / Yannik from templates

Which pages use which special code

FeatureWhere
Filter + search (omxf)/branchen (with category blocks), /guides-vorlagen, /webinare, /e-rechnung-themen, /kunden. Check any page with document.querySelectorAll('[data-filter="section"]')
Roadmap script/roadmap (own script: month grouping, reveal window, search + chips)
Lexikon A to Z/lexikon (letter chips jump to #lex-A..., disabled when a letter has no entries)
Table of contents + shareLexikon, E-Rechnungs Hub, Guides, Case Studies, Competitor templates
Pricing API/preise, /supportpakete
Lottie loaderHub pages (/rechnungen, ...), section Section / Two / Column / Visual Lottie Loader
Load more/team, galleries (data-load-more)
HubSpot form CSSNewsletter, download / guide forms, contact sections

Site settings, SEO and launch-critical config

  • Staging blocks robots (normal for webflow.io). Google tools cannot crawl staging: test schema by pasting the page source into validator.schema.org or the Rich Results Test (Code tab).
  • Backend URL: the site head sets window.ORGAMAX_BACKEND_BASE_URL = "https://orgamax.webflow.io" and loads /api/embeds/general.min.js (orgaMAX's Webflow Cloud app for signup / registration drawer). At launch confirm with Florian whether this must change to the live domain.
  • Cookie consent: Usercentrics (settings ID FDavgBK4), loaded in the site head. Changes to consent categories happen in Usercentrics, not Webflow.
  • Redirects: 301 only (Project settings → Publishing). Import IMPORT_REDIRECTS.csv at launch; remove the old /preise redirect loop.
  • Special pages: /search (Webflow site search, used by the WebSite schema), /404, /401 (password page), /weiterempfehlung (noindex).
  • Open Graph: default OG image opengraph.png (stays PNG on purpose). CMS templates bind their own OG image fields.
  • SEO fields: every CMS template binds Meta/SEO title + description fields (Plain Text). Static pages set them in Page settings.
5 entries

Animation engine

How the animation engine works

Scroll reveal animations run on GSAP 3.12.5 + ScrollTrigger (site footer, from cdnjs) and our own script cg animation template v2 (site footer). You never write JS for an animation: you add attributes.

  1. Put cg-animation-trigger on a wrapper (usually the section container or a grid). This is the scroll trigger.
  2. Put cg-animation-el on each child that should animate. Children animate one after another (stagger 0.2 s).
  3. Animations play once (once: true).

Safety net (site head): a tiny script adds html.cg-anim. CSS hides only elements with an animation value until the engine marks them data-cg-done. If GSAP fails, the 4 s failsafe removes cg-anim and everything shows. In the Designer (.w-editor) nothing is hidden. Print shows everything. Reduced motion: no animation, everything visible.

Adding animations with the Attriflow app (no typing)

Animations are added in the Designer with the Attriflow app (Apps panel → Attriflow). It holds the ready-made template "GSAP Animation Template" (by Creoglyph) with every attribute of our engine, so nobody has to type attribute names.

  1. Open Attriflow. If the template is not in My Templates yet: All Templates → "GSAP Animation Template" → + to add it.
  2. Select the wrapper in the Navigator and click cg-animation-trigger="vertical" (or "horizontal").
  3. Select each child that should animate and click cg-animation-el="vertical" (or "top-left" / "bottom-right" inside a horizontal trigger).
  4. Optional, on the trigger: cg-animation-stagger, cg_animation-offset, cg_animation-delay, cg_animation-min-width / max-width. Replace the example value with a real one (e.g. 0.1, "top 90%", 0.3, 992).
  5. On tabs, accordions or toggles that change the page height: cg_refresh-anim-template="click" (or "hover") plus cg_refresh-anim-timeout.

The main ones in one line each: cg-animation-trigger = the scroll start point (wrapper); cg-animation-el = what animates (children); vertical = fade + rise; top-left / bottom-right = slide in from left / right; stagger = delay between children. The template also lists cg_no-will-change; the current engine (v2) does not need it. Many Lumos components already expose these as props (Animation Trigger / Animation Direction), so check the props panel first.

Attribute reference

AttributeOnValues / effect
cg-animation-trigger="vertical"wrapperChildren with el=vertical rise 1rem and fade in. Starts at top 80 %
cg-animation-trigger="vertical-noscale"wrapperChildren with el=vertical rise 4rem. Starts at top 60 %
cg-animation-trigger="horizontal"wrapperChildren el=top-left slide in from the left (-2rem), el=bottom-right from the right (+2rem), at the same time
cg-animation-el="vertical"childAnimated by the nearest vertical / vertical-noscale trigger
cg-animation-el="top-left"childAnimated by the nearest horizontal trigger (from left)
cg-animation-el="bottom-right"childAnimated by the nearest horizontal trigger (from right)
cg-animation-stagger="0.1"triggerDelay between children in seconds (default 0.2)
cg_animation-offset="top 90%"triggerCustom ScrollTrigger start
cg_animation-delay="0.3"triggerDelay before the timeline starts (s)
cg_animation-min-width="992"triggerOnly animate at or above this viewport width (px)
cg_animation-max-width="991"triggerOnly animate at or below this width (px)
cg_refresh-anim-template="click"tabs, accordions, togglesAfter the event, recalculates all scroll positions (content height changed)
cg_refresh-anim-timeout="600"same elementWait in ms before refresh (default 1000)

Event: the trigger fires cg-animation-complete when its timeline is done. Global helpers: window.refreshAnimationTemplateScrollTrigger(), window.animateElements(...) (v1 API kept).

Using it in components

  • Lumos components have props for it: Animation Trigger (Content Wrapper, Grid), Animation Direction / cg-animation-el (Typography, Buttons, Images, Cards). Set the trigger on the wrapper, the direction on the children.
  • Helper components: Animation / Top Left, Animation / Bottom Right, u-animation-trigger.
  • Nesting: a child belongs to the nearest trigger that animates its value. A vertical child inside a horizontal trigger inside a vertical section is animated by the vertical section, not twice.
  • CMS lists / late content: a MutationObserver picks up items added later (load more, filters). Height changes (lazy images) refresh the scroll positions automatically.
  • Section near the page end that can never reach its start point plays immediately.
  • Keyboard: focusing a still-hidden element finishes its animation.

Debug an animation

// list all triggers and whether their children are done
document.querySelectorAll('[cg-animation-trigger]').forEach(t => console.log(
  t.getAttribute('cg-animation-trigger'), t,
  t.querySelectorAll('[cg-animation-el]:not([data-cg-done])').length + ' hidden'));
console.log('ready:', document.documentElement.classList.contains('cg-anim-ready'));
4 entries

Navigation

Navbar architecture

The Navbar component contains its own markup, a CSS embed and a JS embed ("orgaMAX navigation production master"). It is a disclosure navigation (buttons with aria-expanded, not ARIA menus).

  • .custom_nav_main_wrap is position: fixed, contains the announcement bar ([data-nav-announcement], close button), and header[data-nav].
  • Top of page: transparent, white text (for dark heroes). Scrolled: .is-scrolled turns it into a white pill with dark text.
  • Desktop (≥ 992): one shared .nav_viewport morphs height and slides panels left/right between triggers. First open uses a two-frame hidden render then clip reveal (prevents a blank shell). Hover opens after 90 ms, closes after 180 ms.
  • Mobile (≤ 991): burger opens a fixed sheet. Each panel is moved into its nav item and becomes an accordion. Page scroll is locked without touching body overflow (sticky-safe).
  • Keyboard: arrows, Home/End, Escape, focus containment on mobile, logical tab order into panels.
  • API: window.orgaMaxNav.refresh(), .close(), .closeMenu().
  • Webflow w--current is mirrored to aria-current="page".

Nav offset router (why content can sit under the nav)

JS measures the announcement bar + nav shell and sets --nav-stack-height on html. CSS adds a ::before spacer of that height inside the first section's .u-container:

:where(.page_main, .page-main) > :first-child > .u-container::before,      /* up to 4 wrapper levels */
:where(.page_main, .page-main) [data-nav-offset-target]::before { height: var(--nav-stack-height); }

So the section background runs behind the transparent nav, and content starts below it. If a page has no .page-main or the first child has no .u-container, there is no spacer and content hides under the nav (that was the bug on AVV, quiz and password pages).

Navbar props

PropEffect
Funktionen / Lösungen / Preise / Wissen / Unternehmen VisibilityHide single menu entries
Login Visibility, CTA Kostenlos Testen Visibility, Phone Number VisibilityHide the actions
data-nav-theme = dark (default) / lightlight: dark logo, links, phone, Login, burger at page top. For pages without a dark hero. Needs the light rule in the nav CSS
data-nav-contact-info-hide = trueHides the phone number between 992 and 1280 px (space)

When all entries are hidden, a CSS rule hides the burger on mobile (.nav_bar:not(:has(.nav_list > .nav_item)) .nav_burger). /passwort-vergeben uses all of this.

Funktionen dropdown is CMS-driven

  • Kernfunktionen: the 5 Funktionen Hubs (list .nav_function_hubs_cl) + Funktionen with Nav Gruppe = Kernfunktion (list .nav_function_kern_cl). A small script merges both lists into one by data-nav-order (= Reihenfolge) and removes the empty second list.
  • Weitere Funktionen: Funktionen with Nav Gruppe = Weitere Funktion.
  • Text, icon, description: Name, Icon, Nav Beschreibung. Hub links: Bereichsseite Link.
  • Lösungen, Wissen, Unternehmen and the footer are static on purpose: hand-picked SEO links and the 20 collection lists per page budget (nav already uses 3).
3 entries

Filter system

Why we wrote our own filter script

  • Webflow Collection Lists cannot filter or search interactively, and show max 100 items per list.
  • Finsweet attributes were used early on. They are a heavy dependency, and leftover fs-cmsfilter-* attributes caused the "Filter zurücksetzen" bug on /branchen. Some leftover attributes (fs-cmsfilter-*, fs-cmsload-*, reset-radio-parent, cg_filters-item) may still sit on markup. They are harmless while the Finsweet script is not loaded. Remove them when you touch a section.
  • We needed one small, standard attribute API for all filter pages, with German-aware search (ä→a, ß→ss, &→und), deep links, accessibility and pagination.

Result: omxf, in the component JS / Filter and Load More (plus CSS / Filter Active Styles, filter_empty_state_wrap, Filter / Category / Chip).

Filter attribute reference

AttributeElementPurpose
data-filter="section"section wrapperOne filter instance (class fallback .section_filter)
data-filter="group" + data-filter-name="Branche"chip groupA filter dimension. The name becomes the URL parameter
data-filter="chip"each chip (.filter_category_wrap with radio or checkbox)One value per group: radio or checkbox both work, a second chip in the same group replaces the first
data-filter="reset"reset linkClears chips and search
data-filter="search"search inputFree text search (German normalised)
data-filter="search-submit"search buttonOptional
data-filter="results"results wrapperArea that gets filtered
data-filter="item"each CMS itemWhat gets shown / hidden
data-filter="block"group of itemsWhole block hides when it has no visible items (Branchen categories)
data-filter="empty"empty stateShown when nothing matches
data-filter="pagination"Webflow paginationNext pages are loaded in the background and merged, so filtering covers all items
data-filter="load-more" / load-more-countbutton / counterLoad more instead of pages
data-filter="status"optionalScreen reader live region (auto-created if missing)

Behaviour: on ready the section gets data-filter-ready="true". Active chip wrapper gets is-filter-active, its label is-active, the reset link is-filter-reset while nothing is active, the section is-loading while extra pages load. Fetched pages are cached in sessionStorage, keyed by the site's "Last Published" date, so a new publish invalidates the cache. Filter state is written to the URL with history.replaceState (e.g. ?branche=handwerk) and restored on load.

Native filters we use instead of JS

  • Branchen slider (industry template): Collection List of Branchen with Branche ≠ Current Branche and Branchen Kategorie = Branchen Kategorie of Current Branche, sorted by Reihenfolge. No JS. Rebuilt 9 Oct (Branchen Gewerke deleted).
  • Per page content (FAQs, testimonials, logos, gallery, team): filtered by the Website Pages tag, e.g. Website Page contains Paid Social. Cloned pages keep the original filter: when you duplicate a page, create a new Website Pages item and change the filter on the clone.
  • Rechnungen hub slider: nested list from Funktionen Hubs → Mehr Funktionen Slider (max 5).
9 entries

Scripts & site code

About the JavaScript on this site

Every script on this site is custom code written specifically for orgaMAX. There are no plugin libraries for features: no Finsweet, no Webflow template scripts, no copied snippets. The only third-party libraries are the engines underneath: GSAP + ScrollTrigger (animation), Swiper (sliders), Lottie (animations from Figma), Usercentrics (cookies), HubSpot (forms).

AI output was never shipped as is: during the build AI tools invented Webflow and GSAP APIs that do not exist. So every script (navigation, animation engine v2, filter omxf, pricing API, TOC, load more, Lexikon, Roadmap, dates, hyphenation) was written against the real markup, tested in the browser at desktop and mobile, and is documented here. If you change a script, test it the same way before publishing.

Structured data (schema)

  • Home: Organization + WebSite JSON-LD in the page head (legal name deltra Business Software GmbH & Co. KG, phone, support email, Detmold, site search /search?query=).
  • Lexikon, E-Rechnung, Case Studies and Guides templates: Article + BreadcrumbList JSON-LD in the template head, filled from the CMS (Name, SEO Beschreibung, slug). After a publish, view source on an entry and search ld+json: you must see the real title, not {{wf.
  • FAQs: FAQPage microdata inside Section / FAQ [CMS] (itemscope / itemtype / itemprop on list, item, question, answer). Server-rendered, so it follows the CMS on every page and template. Keep one FAQ component per page (one FAQPage per page).
  • Test any page with Google's Rich Results Test.

Page speed: what was done and what to watch

  • Images: all content images are AVIF (209 assets). On 10 Oct the last 21 PNG/JPG/WebP images (from the new SEO pages, Lagerverwaltung, Rechnungsprogramm, EDI LinkedIn page) were compressed to AVIF in place: 4.45 MB down to 0.54 MB. The Open Graph image (opengraph.png, edi-collage.png) stays PNG on purpose, because social networks do not read AVIF.
  • Lotties: the tab animations (Auftragswesen, Buchhaltung, Dokumentenmanagement) were re-exported: about 3.4 MB instead of 23 MB, in the asset folder "Final Optimized Lotties". Still heavy: Passt sich Deinem Unternehmen an.json (2.3 MB) and funktionenhero.json (1.5 MB). Same fix if needed: export as .lottie with WebP images, convert to .json (WebP embedded as base64), upload.
  • New uploads: the client uploads AVIF only. If PNG/JPG shows up again, compress it via the Webflow asset API (compress to AVIF) or ask them to re-upload.

Site head code

Project settings → Custom code → Head:

  • Animation failsafe (html.cg-anim + hide rule + 4 s timeout). See Animation engine.
  • [cg_banner_new] hidden by default (banner toggled by script).
  • Usercentrics CMP (cookie consent, settings ID FDavgBK4).
  • general.min.js from orgamax.webflow.io/api/embeds/ + window.ORGAMAX_BACKEND_BASE_URL: orgaMAX's own backend (registration drawer / signup flow, built by Florian from deltra on Webflow Cloud). Do not touch, ask Florian.
  • Auto hyphenation: headings (and [data-hyphenate]) get data-hyphenated + lang="de" only when the longest word does not fit (long German compounds). Opt out with data-hyphenate="off". Re-checks on resize and after fonts load.
  • TOC skeleton shimmer until the TOC script sets html.toc-ready; hides "Inhalt" when an article has no headings. Optional cleanup later: it could live in the TOC component instead of the head, it does no harm where it is.
  • [data-date-de] hidden until translated.

Site footer code

  • GSAP 3.12.5 + ScrollTrigger (cdnjs with SRI).
  • Old animation template v1 (commented out, kept for reference).
  • cg animation template v2 (active).
  • German dates: any element with data-date-de that shows an English date ("October 9, 2026", "Oct 2026") is rewritten to German ("9. Oktober 2026"). Works for CMS items loaded later. Fixes the English month in Lexikon (sheet).

Component scripts (JS embeds)

Component / placeWhat it does
Navbar JSNavigation runtime (see Navigation) + Funktionen list merge
JS / Filter and Load Moreomxf filter, search, pagination merge, URL state
JS / Load MoreSimple load more for lists (data-load-more="wrap", button, count). Team page, galleries
JS / Table of Contents (+ TOC and Social Share)Builds the TOC from [cg_generate-toc="h2"] headings inside the article, scroll offset respects the fixed nav, sets html.toc-ready. Share buttons use data-social-share-* (url, title, text, image, utm) and get tooltips
JS / Pricing Card, JS / Pricing Card / BadgesPricing API, see next entry
Single Testimonial / JSBranche testimonial slider (side arrows desktop, bullets + bottom arrows mobile) + card video player. With one slide all controls hide (intended, sheet #26). See Custom code explained
CDN / Swiper JS + per section initSliders (follow the Swiper standard)
Lexikon pageA to Z chips (data-lex-jump) link to #lex-X anchors, disabled when a letter is empty; accordion, 5 terms per letter + Mehr anzeigen (see Custom code explained)
Roadmap pageGroups releases by month, 2-month reveal window, counter, "Ältere Releases anzeigen", search and chips. Grey dots for upcoming via data-zeitraum
Section / Custom / TabsResponsive tabs (data-rtabs, -list, -panels, -heading, -panel). Each tab has Image / Video / Lottie Visibility props: switch to the image while a Lottie is missing (done for tab 3 on /rechnungen)
Section / Video / SliderCard video modal, video URL via prop data-video-src
Section / Two / Column / Visual Lottie LoaderNo custom code: the Lottie is played by a native Webflow interaction (Interactions panel). Heavy file: see open task #66
breadcrumb_componentFallback: an empty or # link becomes /funktionen with label Funktionen
Starter JS / Starter CSSLumos templates: unlink before use

Pricing API (/preise)

Everything on the pricing page is attribute-driven, nothing hardcoded.

  • Card values on .pricing_card_values_main_wrap: data-plan, data-price-monthly, data-price-yearly. Plans: auftrag 49/39, auftrag-pro 69/49, warenwirtschaft 99/69, warenwirtschaft-pro 139/99.
  • Inside a card: data-price-role="current|regular|promo".
  • Billing switch [data-billing-switch] with [data-billing-option="monthly|yearly"]; URL ?billing=monthly; event orgamax:billingchange; html[data-billing-cycle].
  • Table: tr[data-price-key] td[data-price-plan] [data-price-value]. Keys are generated from the feature name on load.
  • API: orgamaxPricing.setPlanPrice('auftrag',{monthly:49,yearly:39}), setCycle / getCycle, setTableValue(key, plan|'*', text), list().
  • Comparison table CSS is in a page embed scoped to [data-pricing-section]. Column widths: Preise 46 % / 18 % (3 plans), Supportpakete via combo classes .is-support 44 % / 14 %.

HubSpot forms

Two CSS files, both locked:

  • Legacy forms (raw HTML, .hs-form): component CSS / Hubspot, tokens --hsf-* on :root (not --omx-hsf-*, the SKILL note is out of date). Neutralises HubSpot's injected layout CSS first (95 % widths, 500 px fieldsets, floats, phone field).
  • New editor forms (.hsfc-*): component CSS / Hubspot / No Raw HTML, tokens --omx-hsfc-*, sets HubSpot's --hsf-*__* variables on .hsfc-Renderer[data-hsfc-id="Renderer"].
  • Form directly on a dark background: add data-hsf-surface="dark" to the wrapper. Never key on .u-theme-dark.
  • Each file is about 33k characters, so they live in two separate embeds (50k limit).
  • Consent / privacy text / fields / labels are configured in HubSpot by orgaMAX.

Page-level custom code (full inventory, 10 Oct)

PageHeadFooter
HomeOrganization + WebSite JSON-LD–
Lexikon templateArticle + Breadcrumb JSON-LD (CMS bound)Date localiser (data-localize-date)+ social share script
E-Rechnungs Hub templateArticle + Breadcrumb JSON-LD–
Case Studies templateArticle + Breadcrumb JSON-LD–
Guides & Vorlagen templateArticle + Breadcrumb JSON-LD–
Newsletter article template–Date localiser + social share script
/passwort-vergeben, /passwort-aendern, /ch/…–<script src="/api/embeds/account.min.js" defer> (orgaMAX backend, password flow; do not touch)
/weiterempfehlung<meta name="robots" content="noindex, nofollow"> (intentional, referral page)–
All other pagesemptyempty

Everything else lives in component embeds (Navbar, Global Styles, JS / … and CSS / … components) or in the site-wide head/footer. Tip: the Webflow MCP can read page and site code (get_page_freeform_code), but not the content of HTML embed elements; those you open in the Designer.

20 entries

Custom code explained

How to read this topic

One entry per custom script, written from the code that is live on staging. Every entry answers the same six questions: what it does, how it works, what it needs in the Designer, how to change it safely, what breaks it, how to test it.

Three rules apply to all of them:

  • Attributes and class names are the contract. The scripts find elements by data-* attributes (and a few class names as fallback). Renaming a class or deleting an attribute in the Designer silently switches a feature off. No console error, it just stops working.
  • Change behaviour through attributes first, code second. When code must change, replace the whole embed block and keep a copy of the old one in a text file, so you can roll back.
  • Test on staging after publishing, desktop and 375 px, keyboard and reduced motion. The Designer canvas does not run most of these scripts.

Coverage: every custom script and custom CSS file on the site is in this topic, including the page-level script on /funktionen that drives the hub/function rail. Two items need no own entry: Section / Two / Column / Visual Lottie Loader uses a native Webflow interaction (no custom code), and /newsletter-archiv uses the same omxf filter and load more as every other filter page.

Attribute index (which script reads what)

Attribute or classRead bySee entry
cg-animation-trigger, cg-animation-el, cg_animation-*, cg_refresh-anim-templateanimation engine v2 (site footer)Animation engine
data-nav*, data-nav-theme, data-nav-offset-targetnavbar JS + CSSNavigation
data-filter="...", data-filter-nameomxfJS / Filter and Load More
.filter_category_wrap.is-filter-activeCSS / Filter Active StylesCSS / Filter Active Styles
cg_toc-*, cg_generate-toc, cg_rich-text-containerTOC scriptJS / Table of Contents
data-social-share-*, data-tooltipshare script + share CSSTOC and Social Share
data-lex-*, .alphabets_ci, .lexikon_letterLexikon script/lexikon A to Z script
data-load-more="wrap"JS / Load MoreJS / Load More
data-rtabs*, .rtabs__lottie[data-src], video[data-rtabs-video]rtabsSection / Custom / Tabs
data-plan, data-price-*, data-billing-*, data-pricing-card-lightpricing JS + CSSJS / Pricing Card
data-video-src, data-slider="previous|next"video sliderSection / Video / Slider
data-hsf-surface="dark"both HubSpot CSS filesHubSpot CSS
data-card="hover"card hover CSS (Global Styles)Custom CSS
data-date-deGerman dates (site footer)Site footer code
data-dynamic-year, .footer_group_*, .floating_card.is-cta-*footer embeds (year, mobile accordion, floating cards)Footer component
data-hyphenateauto hyphenation (site head)Site head code
data-zeitraum, .roadmap_*roadmap script/roadmap script
[[...]] in rich text, data-rt-badgebadges scriptJS / Pricing Card / Badges
data-icon-check, data-icon-yellow, data-list-style-dot, data-horizontal, data-list-margin-bottom, data-size="16"rich text list CSS (Global Styles)Rich text list styler
data-link-style="medium-600", data-vertical-tabet-belowrich text helpers (Global Styles)Rich text list styler
data-cmp-alias, data-cmp-level, .comparison_*comparison table script/preise comparison table
.branche-testimonials_component, .card_mega_video_*testimonial slider + card videoSingle Testimonial
data-number, data-wf--*Lumos framework + Webflow variants, not our scriptsRules & standards

Rule of thumb: an attribute you do not find here is either a Lumos/Webflow internal (data-wf-*) or a Finsweet leftover (fs-*) that can be removed when you touch that section.

JS / Filter and Load More (omxf)

Where: Component JS / Filter and Load More, placed inside each filter section. Used on /branchen, /lexikon (search only), /newsletter-archiv, /roadmap (chips, with the roadmap script on top), /guides-vorlagen, /webinare and every other page with chips or search.

What it does

Turns a normal Webflow Collection List into a searchable, filterable list. Visitors type in a search box or click category chips, and the list updates instantly without a page reload. It also loads the list's other pages in the background, so the filter searches all items, not only the first page, and it replaces Webflow's page numbers with a "load more" button.

How it works, step by step

  1. On page load it looks for every [data-filter="section"] (fallback class .section_filter). Each section is set up once and then marked data-filter-ready="true".
  2. Inside the section it finds the results area, the chip groups and the search box. If a section has neither chips nor search, or no items, it does nothing.
  3. It reads every item (card) once: its title, its text (for search) and its values, which are the texts of the small tags on the card ([data-filter="value"] or .chip_item). Values are normalised: lowercase, ä→a, ß→ss, &→und, punctuation removed.
  4. Each chip's label is normalised the same way. A chip matches a card when the two normalised texts are equal. That is the whole matching logic: chip label text = tag text on the card.
  5. Each group holds one active value. Clicking a second chip in the same group replaces the first. Groups combine with AND (Branche = X and Kategorie = Y). Search is AND on top.
  6. Search waits 180 ms after typing, then shows only cards whose title or text contains the term, and highlights the match with <mark>.
  7. Visible cards fade in (420 ms, small stagger). The empty state shows when nothing matches. A hidden live region announces "X Ergebnisse gefunden" for screen readers.
  8. The state is written to the URL: each group's name becomes a parameter, search becomes ?q=. The URL can be shared and the back button works.
  9. When the browser is idle, it fetches the list's other Webflow pages (max 40, 8 s timeout each), adds their cards hidden, and from then on filters across all of them. Fetched pages are cached in sessionStorage, keyed by the site's "Last Published" date, so every publish starts fresh.
  10. The "load more" button shows the next batch (batch size = items per page set on the Collection List) and moves keyboard focus to the first new card.
  11. Block mode (cards grouped under headings, e.g. Branchen categories, Lexikon letters): when [data-filter="block"] exists, a block hides when none of its cards are visible, background page loading is off, and an ItemList JSON-LD schema is added to the page head.

What it needs

Attribute (class fallback)OnRequired?
data-filter="section" (.section_filter)outer wrapperyes
data-filter="results" (.filter_form_bottom_right_wrap)wrapper around the listyes
data-filter="item" (.w-dyn-item)each cardrecommended
data-filter="group" + data-filter-nameeach chip group; name becomes the URL parameterfor chips
data-filter="chip" (.filter_category_wrap)each chip, must contain a radio or checkboxfor chips
data-filter="chip-label" (.filter_category_label)chip textoptional
data-filter="value" (.chip_item)tag on the card that chips match againstfor chips
data-filter="title" / "text"what search reads (fallback: headings, .u-rich-text)optional
data-filter="search" (.search_bar_input)search inputfor search
data-filter="reset" (.filter_reset_link)"Alle" chip / reset linkoptional
data-filter="empty" (.filter_empty_state_wrap)no results messagerecommended
data-filter="pagination" (.w-pagination-wrapper)Webflow pagination of the listfor load more
data-filter="load-more" / "load-more-count"button / remaining countoptional (else Webflow's Next link is used)
data-filter="block" / "block-name"group of cards / its headingblock mode only

Change it safely

  • Add a new filter page by copying an existing one (e.g. /webinare) and changing the Collection List source. All attributes come with it.
  • Add a chip: duplicate a chip and change its label so it matches the card tag text exactly (case and umlauts do not matter).
  • Rename a URL parameter: change data-filter-name on the group. Old shared links with the old name stop pre-filtering.
  • Change the batch size: change "items per page" on the Collection List, not the script.
  • The embed is minified. Do not edit the line by hand in the Designer. If the logic must change: copy it into a formatter (e.g. prettier), use the function map below, change, test on a branch page, paste the whole block back.

What breaks it

  • A chip label that differs from the card tag text ("Handwerk & Bau" chip vs "Handwerk und Bau" tag works, "Handwerker" vs "Handwerk" does not).
  • Removing the radio/checkbox inside a chip: the chip is ignored.
  • Leftover Finsweet attributes (fs-cmsfilter-*) or a second filter script on the same section.
  • Two data-filter="section" wrappers nested inside each other.
  • Draft items: they are not on the published pages, so the filter cannot find them.

How to test

// 1. Is it running, and how many cards does it see?
document.querySelectorAll('[data-filter="section"],.section_filter').forEach(s =>
  console.log(s.dataset.filterReady, s.querySelectorAll('[data-filter="item"],.w-dyn-item').length));

// 2. What did the last action find?
document.querySelector('[data-filter="status"]')?.textContent

// 3. Force fresh background pages (clears the cache)
Object.keys(sessionStorage).filter(k => k.startsWith('omxf:')).forEach(k => sessionStorage.removeItem(k));

Then click every chip once, type a search term with an umlaut, use the back button, open the page with the URL parameters copied, and check "load more" moves focus.

omxf: map of the minified code

For when the script itself has to change. Paste the embed into a formatter first; the short names below then read like a normal program.

Name in the codeWhat it is
e, t, r, n, aclass names: is-filter-active, is-active, is-filter-reset, is-hidden (load more button), is-loading (section)
i = "omxf:"sessionStorage key prefix, followed by the Last Published date and the page url
d(name)builds the selector [data-filter="name"]
_(section)set up one filter section (everything else runs inside it)
w(text) / A(text) / S(text)lowercase + umlauts / full normalise (ß→ss, &→und) / slug for URL parameters
ge, Ae, Sefind cards / read one card (title, values, search text, dedupe key) / collect all cards (block mode aware)
kegroup name: data-filter-name, else first text in the group
Oe / Iecard matches active chips / card matches search
Perender: show and hide cards and blocks, highlight, animate, empty state, load more, status text
Desync chip classes and the reset link
qe / Leread state from the URL / write state to the URL
Cefetch a page with timeout (8 s) and the sessionStorage cache
Re / Mesearch submit (180 ms debounce) / load more click
xe / _ewrap search matches in <mark>

Texts that appear on the site live in Pe: "Keine Ergebnisse gefunden.", "X Ergebnisse gefunden.", "Y davon werden angezeigt." and the fallback aria-label "Mehr erfahren" in Ae.

CSS / Filter Active Styles

Where: Component CSS / Filter Active Styles, next to the filter script on each filter page.

What it does

Paints the selected chip: blue background, white text. One rule.

.filter_category_wrap.is-filter-active {
  background: var(--swatch--primary--blue);
  color: var(--neutral--white);
}

How it works, step by step

  1. omxf adds is-filter-active to the active chip wrapper and removes it from the others.
  2. This CSS colours whatever has that class.

What it needs

The chip wrapper class must stay filter_category_wrap. The class is-filter-active is added by JS, so it does not exist in the Designer and will not show in the style panel.

Change it safely

  • Change the active colours here, using variables only.
  • Hover and focus styles of chips live on the Webflow class, not here.

What breaks it

  • Renaming the chip class in the Designer.
  • Removing the component from a page: chips still filter, but the active one is no longer visible.

How to test

Click a chip: it turns blue. Click "Alle": no chip is blue.

JS / Table of Contents

Where: Component JS / Table of Contents (7ef29323-fee9-1ea9-6998-b5aec654dacd), on article templates (Lexikon, E-Rechnung, Guides, Newsletter articles, Case Studies).

What it does

Builds the "Inhalt" list in the sidebar from the headings of the article, scrolls smoothly to a heading on click, and highlights the heading you are currently reading.

How it works, step by step

  1. Waits for the whole page to load (images included), so positions are correct.
  2. Inside each [cg_toc-container] it reads the headings of the rich text marked [cg_rich-text-container]. Which headings: the value of cg_generate-toc (here h2).
  3. For every heading it clones the template link [cg_toc-link], sets its text to the heading text and its link to #id-.... Headings without an id get one from their text (lowercase, a to z and digits only, so "Übersicht" becomes id-bersicht).
  4. The template link is removed afterwards.
  5. Click: scrolls with its own easing, stops cg_toc-offset px above the heading (room for the fixed nav), then writes the hash into the URL.
  6. While scrolling it finds the last heading above the offset and gives its link the active class (is-toc-active by default).
  7. If the page is opened with a hash, it jumps to that heading. A second small script sets html.toc-ready, which ends the skeleton shimmer from the site head.

What it needs

AttributeOnValue
cg_toc-containerwrapper around TOC and articleempty
cg_generate-tocTOC listh2 (any selector list)
cg_toc-linkone template itemempty
cg_rich-text-containerarticle rich textempty
cg_toc-offsetcontainerpx, e.g. 120
cg_toc_scroll-duration / cg_toc-easingcontainerms (300) / easeOut, easeIn, easeInOut, linear
cg_link-active-classcontainerdefault is-toc-active
cg_toc-numbering / cg_toc-numbering-seperatorcontainertrue / e.g. "."

Change it safely

  • Include H3s: set cg_generate-toc to h2 h3.
  • Nav height changed: adjust cg_toc-offset (currently 150 on the Lexikon template).
  • Keep the hidden .hide div with is-toc-active inside the component: it keeps the class alive so Webflow does not clean it up as unused.

What breaks it

  • Fixed 11 Oct: the template .toc_item[cg_toc-link] is now a Link Block everywhere (Lexikon and E-Rechnungs Hub templates, the TOC and Social Share component, all 12 competitor pages). If you build a new TOC, the template item must be a Link Block, never a div: a div is not reachable by keyboard.
  • Two headings with the same text get the same id: both TOC links go to the first one.
  • Content that changes height after load (accordions, late images) shifts positions until the next resize. Highlighting can be off by one section in that case.
  • Missing cg_rich-text-container: empty TOC, skeleton stays until the 4 s failsafe.

How to test

document.documentElement.classList.contains('toc-ready');           // true
[...document.querySelectorAll('[cg_generate-toc] a,[cg_generate-toc] > *')].map(a => a.textContent + ' -> ' + a.getAttribute('href'));

Then Tab into the TOC (every item must get focus), press Enter, scroll and watch the highlight.

TOC and Social Share (component)

Where: The sticky sidebar block .u-position-sticky.is-toc on article templates: the TOC above, the share buttons below.

What it does

Holds the markup the two scripts need, plus the CSS for the share tooltips ("Link kopieren", "Auf LinkedIn teilen", "Link kopiert"). The share script itself is in Scripts & site code.

How it works, step by step

  1. TOC part: heading "Inhalt", list .toc[cg_generate-toc="h2"] with one template item .toc_item[cg_toc-link] containing .toc_text.
  2. A hidden .hide div holds .toc_column, .is-toc-active and .toc_item.is-toc-active, so these script-only classes are not deleted by Webflow's "clean up unused styles".
  3. Share part: three links with data-social-share-link: empty = copy link, linkedin, email.
  4. The CSS draws a tooltip from the data-tooltip attribute that the share script sets. It shows on hover (mouse only), on keyboard focus, and as confirmation while .is-copied is set.

What it needs

The attributes above, and the tooltip colours via --share-tooltip-bg / --share-tooltip-color (default dark grey / white).

Change it safely

  • Add a network: duplicate a share link and set its data-social-share-link value (the share script must support that value).
  • Change tooltip text in the share script, not in the CSS.

What breaks it

  • Deleting the .hide div and running "clean up styles": the active TOC state loses its style.
  • Setting the share links' own text: the tooltip comes from data-tooltip.

How to test

Hover each share icon (tooltip), Tab to it (tooltip), click copy ("kopiert" state, link in clipboard).

/lexikon A to Z script

Where: Page /lexikon, embed after the filter section (plus a CSS embed for .lexikon_collector and one for the alphabet bar).

What it does

Makes the glossary usable: each term opens like an accordion, each letter shows 5 terms with "Mehr anzeigen" for the rest, the A to Z bar jumps to a letter and greys out empty letters, and the page gets DefinedTermSet schema for Google.

How it works, step by step

  1. Accordion: every [data-lex-accordion] gets ids and ARIA (button + region). Panels start at height 0. Links inside a closed panel are taken out of the Tab order.
  2. Click on [data-lex-toggle]: the panel animates from 0 to its real height (or back), then the height is set to auto. While animating, extra clicks are ignored.
  3. Truncate: per letter block it counts the visible terms in .lexikon_cl. After 5, the rest is hidden and [data-lex-more] shows "Mehr anzeigen" with the hidden count; clicking toggles to "Weniger anzeigen".
  4. A to Z: each block's letter (.lexikon_letter) gives the block the id lex-a. Each chip .alphabets_ci gets data-lex-jump; letters without visible terms get is-disabled and cannot be focused. Click scrolls to the block (CSS scroll-margin-top: 120px leaves room for the nav).
  5. Works with omxf search: a MutationObserver watches the section. When omxf hides or shows terms, truncation and the A to Z state are recalculated.
  6. Schema: when the browser is idle it adds one DefinedTermSet JSON-LD with every term's name, short text and link. (omxf adds an ItemList on the same page, both are valid.)

What it needs

SelectorWhat it is
[data-filter="block"]one letter block (also used by omxf)
.lexikon_letterthe letter heading of a block
.lexikon_cl > .w-dyn-itemthe terms of a letter
[data-lex-accordion], [data-lex-toggle], [data-lex-panel]one term, its button, its answer
[data-lex-more] + [data-lex-more-label]Mehr anzeigen button and its text
.alphabets_ci > .alphabets_letter_wrapA to Z chip and its letter
.lexikon_collector_panelmust have a height transition on its Webflow class

Change it safely

  • Terms per letter: change LIMIT = 5 at the top of the script.
  • Button texts: MORE / LESS at the top.
  • Accordion colours: the --lex-* tokens in the .lexikon_collector CSS embed (.is-open = open state).
  • After loading terms by other code, call window.lexRefresh().

What breaks it

  • Removing the height transition from .lexikon_collector_panel (today: height, 320 ms, verified 10 Oct): the end-of-animation event never fires, the term stays "busy" and cannot be toggled again (reduced motion is not affected).
  • Letter collection items without terms still render a block; omxf hides them because no card is visible. Keep omxf on the page.
  • Renaming .lexikon_letter, .lexikon_cl or .alphabets_ci.

How to test

document.querySelectorAll('[data-lex-ready="true"]').length;   // number of terms set up
document.querySelectorAll('.alphabets_ci.is-disabled').length;  // empty letters
JSON.parse(document.getElementById('lex-schema').textContent).hasDefinedTerm.length;

Open and close a term twice quickly, use "Mehr anzeigen", search "rechnung" (letters update), jump to Z, Tab through a letter.

JS / Load More

Where: Component JS / Load More (two spaces in the name). For simple lists without filters, e.g. the team grid.

What it does

Replaces Webflow's "Next page" link with a load more button: the next page's items are appended to the list without a reload.

How it works, step by step

  1. Finds every [data-load-more="wrap"] that contains a Collection List and its pagination.
  2. Hides "Previous" and the page count, removes Webflow's prerender link, turns "Next" into a button.
  3. Pre-fetches the next page on hover, on focus, or when the browser is idle, so the click feels instant.
  4. On click: reads the next page, takes the items of the same wrap (by position on the page: first wrap, second wrap...), appends them, makes images lazy.
  5. New cards with animation attributes are revealed with the same motion as the rest of the site, and scroll positions are recalculated.
  6. Focus moves to the first new card, a hidden live region announces the count. The button disappears on the last page.
  7. If anything fails (offline, timeout 10 s) it falls back to opening the real next page.

What it needs

data-load-more="wrap" on a wrapper around the Collection List, pagination switched on in the Collection List settings, items per page set there.

Change it safely

  • Batch size = items per page on the Collection List.
  • Screen reader wording: default "X weitere Einträge geladen". Per list, set data-load-more-one and data-load-more-many on the wrapper (the team page uses "weitere Person" / "weitere Personen").

What breaks it

  • Showing or hiding one of several load-more lists conditionally, so their order differs between pages.
  • Putting this on a list that omxf already controls: use one or the other, never both.

How to test

Click "Mehr anzeigen" until the end: no duplicates, button gone, focus on the first new card, animations play. Then set the network to offline in DevTools and click: it must open the next page instead.

Section / Custom / Tabs (rtabs + Lottie)

Where: Component Section / Custom / Tabs: Home, Funktionen hubs, /erp-hub, competitor pages. Script version window.RTabs.version = 2.3.

What it does

One component that is tabs on desktop (992 px and up) and an accordion below. It auto-advances every 7 seconds with a gold progress line, plays the matching Lottie or video in each tab, and pauses while the visitor is looking at or using it.

How it works, step by step

  1. Reads the mode from the CSS variable --rtabs-mode (tabs from 992 px, accordion below) and switches on resize. Tabs get tab/tablist ARIA, the accordion gets aria-expanded.
  2. Each trigger is paired with the panel at the same position. Missing [data-rtabs-content] wrappers are created automatically.
  3. Autoplay runs only while the component is on screen, the browser tab is visible and reduced motion is off. It pauses (and remembers the remaining time) while the mouse is over the active panel, while focus is inside it, or after the visitor touches a video.
  4. Media per panel: on desktop the Lottie in .rtabs__media_wrap, on mobile the one in .rtabs__media_wrap.is-mobile. The script takes the Lotties over from Webflow, preloads every JSON, and plays the active one from frame 0 each time, without looping.
  5. Videos video[data-rtabs-video] are moved between the desktop and mobile wrapper, reset to the start, and played with sound when the tab opens (browsers may block that; then the visitor presses play).
  6. Switching tabs, scrolling away or hiding the browser tab stops all media.
  7. Keyboard: arrow keys move between tabs (left/right in tabs, up/down in accordion), Home/End jump.

What it needs

AttributeOn
data-rtabscomponent root. Options: data-rtabs-activation="manual" (arrow keys move focus only), data-rtabs-multiple (accordion keeps several open)
data-rtabs-list > data-rtabs-heading > data-rtabs-triggertab buttons (data-rtabs-open = tab open at start)
data-rtabs-panels > data-rtabs-panelpanels, same count and order as triggers
.rtabs__lottie with data-srcWebflow Lottie element, JSON url
video[data-rtabs-video]optional video

The Image / Video / Lottie Visibility props switch a tab to a static image while a Lottie is missing (#81).

Change it safely

  • Speed: --rtabs-auto-duration (7s). Colours: --rtabs-rule / --rtabs-rule-active (gold).
  • The CSS exists twice: an old copy (v1.9) in the CSS embed and the current one inside the JS embed (it has the paused state). The later one wins. Edit the copy in the JS embed, and remove the old CSS block when you next touch the component.
  • New Lottie: upload the optimised JSON (see Page speed), paste its url into the Lottie element. Keep it under about 1.5 MB.

What breaks it

  • Different number of triggers and panels: the component is skipped (console warning "[RTabs] skipped").
  • An empty data-src: the panel shows nothing. Switch the tab to the image prop.
  • Webflow's own Lottie settings (autoplay, loop on scroll) are overwritten on purpose. Set them in the script, not in the Designer.

How to test

RTabs.version;                                             // "2.3-media-final"
document.querySelectorAll('[data-rtabs]').forEach(r => console.log(r.dataset.rtabsMode, r.dataset.rtabsAutoplay));

Watch one full cycle, hover the panel (progress pauses), Tab into the panel (pauses), resize to 375 px (accordion), turn on reduced motion (no autoplay).

JS / Pricing Card (billing switch + pricing CSS)

Where: Component JS / Pricing Card on /preise and every page with pricing cards (light variant on hubs). Plus the pricing cards CSS embed. Badges have their own script (not documented yet).

What it does

Switches all prices between monthly and yearly payment. Yearly shows the promo price, the struck-through regular price and the "Aktion" badge; monthly shows the regular price only. Prices count up or down when switching. It also keeps the comparison table header prices in sync and gives every table row a stable key so prices can be changed from code.

How it works, step by step

  1. Runs once per page even if the embed is there twice.
  2. Collects every price block [data-plan][data-price-monthly]. The yearly price falls back to the monthly one if missing.
  3. Finds the parts inside a block by data-price-role: current (big number), regular (strike price), promo (badge). The first .u-text child is the "bei ... Zahlung" line.
  4. Comparison table: reads the plan names in .comparison_plan_name, turns them into slugs ("Auftrag Pro" → auftrag-pro) and links each header price to the card with that data-plan. Every row gets data-price-key from its feature name.
  5. Switch: [data-billing-switch] becomes a radio group, its options [data-billing-option="monthly|yearly"] work with click, Enter, Space and arrow keys.
  6. Start value: ?billing=monthly (or monatlich / yearly / jaehrlich) in the URL, else the option with is-active, else yearly.
  7. On change: numbers animate (420 ms, none with reduced motion), strike price and badge fade (they keep their space, so card rows stay aligned), the cycle text is rewritten, html[data-billing-cycle] is set and the event orgamax:billingchange fires.

What it needs

AttributeOn
data-plan + data-price-monthly / data-price-yearly.pricing_card_values_main_wrap (e.g. auftrag, 49, 39)
data-price-role="current|regular|promo"number, strike price, Aktion badge
data-price-formatoptional strike text pattern, e.g. statt {price} €
data-billing-switch / data-billing-optionswitch wrapper / its two options
.comparison_pricing_table .comparison_plan_celltable header cells with plan name and price

Pricing cards CSS: 1 column below 992 px, 4 columns above. Rows of all cards line up through CSS subgrid: the highlight wrapper spans 8 rows (badge + 7 card rows). The light variant [data-pricing-card-light] spans 9 / 8 (two buttons and a subtitle). [data-pricing-card-light="accent-gold"] turns the active switch gold.

Change it safely

  • Change a price: in the Designer on the data-price-* attributes. From code: orgamaxPricing.setPlanPrice('auftrag',{monthly:49,yearly:39}).
  • Change "bei monatlicher / jährlicher Zahlung": edit CYCLE_TEXT in the script. Editing that text in the Designer has no effect, the script overwrites it.
  • Adding or removing an element inside a pricing card changes the row count: update grid-row: span 8 / span 7 (or 9 / 8 for light) in the CSS, or the rows stop lining up.

What breaks it

  • Renaming a plan in the comparison table so its slug no longer equals data-plan: that header price stops switching.
  • A comma in a price attribute is fine ("39,90"), text like "ab 39" is not.
  • Removing data-price-role from the number: the first .pricing_card_value is used instead.

How to test

orgamaxPricing.list();          // plans + table row keys
orgamaxPricing.getCycle();      // "yearly"
orgamaxPricing.setCycle('monthly');

Switch with mouse and with arrow keys, open /preise?billing=monthly, check that the header prices in the table follow, and check card rows line up at 992 and 1440 px.

Section / Video / Slider

Where: Component Section / Video / Slider ("So arbeitet es sich mit orgaMAX"). Needs Swiper, loaded by CDN / Swiper JS.

What it does

A card slider (1 / 2 / 3 cards by screen size) where each card opens its customer video in a full-screen player.

How it works, step by step

  1. Waits for Swiper to exist (up to 10 s) and starts each slider only when it is about to scroll into view.
  2. Takes over the section's arrows [data-slider="previous"] / [data-slider="next"]. It clones them first, because another site-wide Swiper script was also binding these arrows and the two fought. Arrows get German labels, grey out at the ends and hide when all cards fit.
  3. Every card button gets the label "Video abspielen: {card heading}".
  4. Click on a card: reads data-video-src (must be an http(s) url), builds the player once (native dialog), plays the video with a loading spinner, shows an error text if it fails.
  5. Close with the X, Escape or a click on the dark overlay. The video stops, the download is cancelled, focus returns to the card.
  6. A click that ends a swipe does not open the video.

What it needs

Structure .video_slider_component > .swiper > .swiper-wrapper > .swiper-slide[data-video-src], the arrows anywhere in the same section. The video url comes from the slide's prop.

Change it safely

  • Cards per view: the breakpoints block (480 → 2, 992 → 3).
  • Player look: the --omx-vm-* tokens at the top of the CSS.
  • Videos: MP4, 1280×720, compressed, uploaded as assets.

What breaks it

  • Removing the Swiper CDN component from the page.
  • Two video slider sections in one section wrapper: they would share the arrows.
  • A video url without https.

How to test

document.querySelector('.video_slider_component .swiper').swiper.slides.length;

Swipe, use the arrows to the end (arrow greys out), open a video, press Escape (focus back on the card), test at 375 px.

HubSpot CSS (legacy and new editor forms)

Where: CSS / Hubspot (legacy raw HTML forms, .hs-form) and CSS / Hubspot / No Raw HTML (new editor forms, .hsfc-*). Two embeds because each file is about 33k characters.

What it does

Makes every HubSpot form look like orgaMAX: 48 px fields, blue focus, red errors, custom checkboxes and radios, a pill submit button, icons for e-mail and dropdowns. Text colours work on light cards and, on request, on dark backgrounds.

How it works, step by step

  1. Legacy forms: HubSpot injects its own layout CSS at runtime (95 % widths, 500 px fieldsets, floats, 20 px indent). Section 1 of the file switches that off, with !important where HubSpot's selectors are stronger.
  2. Then it styles labels, inputs, checkboxes, file upload, submit and the dropdown menu (Chrome 135+ gets a styled menu, other browsers the native one).
  3. New editor forms: HubSpot reads its own documented variables (--hsf-field-input__border-color and so on) before the form editor's settings. Section A sets those on .hsfc-Renderer[data-hsfc-id="Renderer"]. Section B styles what has no variable (height, hover, focus, error, checkbox, dropdown).
  4. Text colours are forced with !important so site theme styles never turn form text white on a white card.

What it needs

  • Legacy forms set to raw HTML in HubSpot (renderRawHtml: true). New editor forms embedded with "Developer code (Advanced)".
  • Form directly on a dark background (no white card): data-hsf-surface="dark" on the embed wrapper. Never use .u-theme-dark for this.

Change it safely

  • Every value is a token at the top of the file: legacy --hsf-*, new editor --omx-hsfc-*. Change tokens, not rules.
  • Never give a legacy token a name with a double underscore: HubSpot's own variables use --hsf-...__... and would collide.
  • Labels, consent text and fields are configured in HubSpot by orgaMAX.

What breaks it

  • Turning raw HTML off on a legacy form (HubSpot's theme CSS returns).
  • Embedding a new editor form with the simple embed code instead of developer code.
  • Going over 50k characters by merging the two files into one embed.

How to test

Submit an empty form (red borders and messages), Tab through every field (visible focus), open the dropdown, tick the consent box, check at 375 px, and once on a dark section with the dark attribute.

/roadmap script (release timeline)

Where: Page /roadmap, page-level embed. Works together with omxf (chips and search on the same page).

What it does

Turns the Releases Collection List into a timeline: newest month first, "Demnächst" (upcoming) on top, the month label shown once per month, only the last 2 months visible until "Ältere Releases anzeigen" is clicked, plus a live counter ("12 Releases · zeigt die letzten 2 Monate").

How it works, step by step

  1. Reads every .roadmap_ci item: its month from data-zeitraum (e.g. Oktober 2026 or Demnächst), its date from .card_roadmap_date (DD.MM.YYYY), and title + text for search.
  2. Sorts the items in the page: Demnächst first, then months newest to oldest, inside a month newest date first.
  3. Shows the month label .roadmap_zeitrum_date only on the first item of each month (via data-rm-first).
  4. Collapsed state: Demnächst + the 2 newest months. Older items get data-rm-hide (hidden by a small injected CSS rule).
  5. Adds a counter p.roadmap_counter above the list (live region) and a button button.roadmap_more below it.
  6. Search: reads the same .search_bar_input itself (180 ms, umlaut-tolerant). While searching, or while a chip is active (URL has release-typ or release-status), all months are shown.
  7. omxf hides items by inline style when a chip is clicked; a MutationObserver sees that and recalculates labels, counter and button.
  8. .filter_reset clears search, collapses, and clicks every .filter_reset_link so omxf resets its chips too.

What it needs

Selector / attributeWhat it is
.roadmap_cl > .roadmap_cilist and release items
data-zeitraumon each item, bound to the CMS: German month + year, or exactly Demnächst
.roadmap_zeitrum_datemonth label inside the item (class name has a typo on purpose: zeitrum)
.card_roadmap_date, .card_roadmap_title, .u-rich-textdate, title, text
.search_bar_input, .filter_resetsearch box, "reset all" link
.roadmap_counter, .roadmap_morecreated by the script: style these classes in Webflow (on a hidden style-guide element so they are not cleaned up)

Change it safely

  • Months visible: MONTHS_SHOWN = 2. Upcoming label: UPCOMING.
  • Counter and button texts are in paintCounter / paintMore.
  • If the omxf group names change, update the regex release-typ|release-status in chipsActive().

What breaks it

  • A wrong month value: data-zeitraum must be the German month name as written in MONTH_NR ("März" with ä, not "Maerz" or "March"). Anything unknown is ranked like Demnächst and jumps to the top.
  • A date not in DD.MM.YYYY: the item still shows, but sorts last inside its month.
  • Renaming the chip groups: the "show everything while a chip is active" rule stops working.
  • The list has no id, so the button's aria-controls is empty. Harmless, but give .roadmap_cl an id when you touch it.

How to test

[...document.querySelectorAll('.roadmap_ci')].map(e => e.dataset.zeitraum).filter((v,i,a) => a.indexOf(v) === i);  // months in order
document.querySelector('.roadmap_counter').textContent;

Expand and collapse, search "rechnung", click a chip (all months appear), reset, check the month labels appear once per month.

Single Testimonial (Branche testimonials slider + card video)

Where: Component Single Testimonial on Branchen pages and hubs: two scripts in one embed. Needs Swiper (CDN / Swiper JS).

What it does

A one-card-at-a-time testimonial slider with two control sets (side arrows on desktop, bullets + bottom arrows on mobile, CSS decides which is visible), and a video player for testimonial cards that have a video: an overlay play button, one video at a time, pause when scrolled away.

How it works, step by step

  1. Slider: starts each .branche-testimonials_component when it comes within 200 px of the screen. Waits for Swiper.
  2. With 0 slides it does nothing; with 1 slide (or when Swiper reports nothing to scroll) it hides both control sets.
  3. Side arrows ([data-slider] as direct children of the component) are Swiper's navigation. Bottom arrows inside .u-botton-slider-navigation are wired by hand and mirror the disabled state (is-disabled).
  4. Bullets are generated into .slider_bullet_list with classes slider_bullet_item / is-active. The height adapts to each card (autoHeight), and is recalculated when late images load.
  5. Card video: each .card_mega_video_wrap with a video and .card_mega_video_overlay. The overlay becomes a "Video abspielen" button. Click: overlay hides, controls appear, video plays, swiping is disabled on it.
  6. Starting one video pauses all others. Scrolling the video out of view pauses it. At the end it rewinds and the overlay returns with focus.

What it needs

SelectorWhat it is
.branche-testimonials_component > .swiper.is-branche-testimonialsroot and slider
[data-slider="previous|next"]side arrows, must be direct children of the root
.u-botton-slider-navigationbottom bar (class has a typo: botton) with .slider_bullet_list and its own two arrows
.card_mega_video_wrap, .card_mega_video_overlayvideo card and its play overlay

Change it safely

  • German labels for screen readers are in the a11y block. Speed: SPEED (0 with reduced motion).
  • Content loaded later (e.g. by another script): call window.omxCardVideo.init() for the videos.
  • Which control set shows at which breakpoint: Webflow classes, not the script.

What breaks it

  • Moving the side arrows into a wrapper: they are no longer direct children, so Swiper gets no navigation.
  • If Swiper never loads, the boot loop keeps checking every 50 ms without a limit (cheap, but the slider stays static).
  • A video without the overlay element: the card video player is skipped for that card.
  • Bottom arrows get tabindex -1 at the ends: keyboard focus on a disabled arrow is lost (minor).

How to test

document.querySelectorAll('.swiper.is-branche-testimonials').forEach(s => console.log(s.dataset.swiperInit, s.swiper?.slides.length));

Desktop: side arrows. 375 px: bullets + bottom arrows. A page with one testimonial: no controls. Play a card video, swipe (should not swipe), start a second video (first pauses).

JS / Pricing Card / Badges ([[...]] badges)

Where: Component JS / Pricing Card / Badges. Styling (.rt_badge, .rt_line) is in the pricing cards CSS.

What it does

Lets the client add a small gradient badge to any line of a rich text, without HTML: write the badge text in double square brackets at the end of a list item.

KI-Agent MAX für Texte [[✨ KI-Agent]]

How it works, step by step

  1. Runs once when the page loads, on every [data-rt-badge] rich text and on the rich text inside light pricing cards ([data-pricing-card-light] .pricing_card .u-rich-text).
  2. Finds every [[...]] in the text and replaces it with <span class="rt_badge">...</span>, trimming spaces.
  3. Inside a list item it wraps text and badges in .rt_line (text left, badge right) so the check icon grid of the rich text list stays intact.

What it needs

The rich text needs data-rt-badge (any value), unless it sits in a light pricing card. The client writes the brackets in the CMS or in the component text.

Change it safely

  • Badge look: .rt_badge in the pricing CSS (cobalt gradient, pill, never wraps).
  • To use badges outside pricing: add data-rt-badge to that rich text element.

What breaks it

  • Content that arrives after page load (omxf background pages, load more) is not converted: the brackets stay visible there.
  • A closing bracket inside the badge text ([[a]b]]) ends the badge early.
  • On the dark /preise cards the brackets show as text unless the rich text has data-rt-badge.

How to test

document.querySelectorAll('.rt_badge').length;   // badges rendered
[...document.querySelectorAll('.u-rich-text')].filter(e => e.textContent.includes('[[')).length;   // should be 0

/preise comparison table (JS + CSS)

Where: Embed on /preise and /supportpakete inside the comparison section (.comparison).

What it does

Makes the big feature table usable: collapsible categories and sub-categories, plan names and category headers that stay stuck while scrolling, a search for features, tooltips that are never cut off, synced horizontal scrolling on small screens, and proper table semantics for screen readers.

How it works, step by step

  1. Repair: the feature-name cells contain a div (tag + tooltip) inside a <tr>, which is invalid HTML; browsers move it out of the table. The script moves each one back into its row's cell. If counts do not match it warns "[comparison] Could not map hoisted feature tags" and leaves them.
  2. Sticky fix: any ancestor with overflow: hidden breaks sticky headers, so the script switches those ancestors to overflow: clip (same look, sticky works).
  3. Grouping: each blue toggle (level 1) starts a .comparison_group; grey toggles (level 2, from the variant name or data-cmp-level) collapse their own section. Buttons get aria-expanded / aria-controls.
  4. Sticky offsets: measures nav, plan header and category bar and writes --cmp-top, --cmp-plans-h, --cmp-l1-h, which the CSS uses for the stacked sticky positions. Updates on resize and when the nav changes state.
  5. Accordion: height animation 320 ms; collapsed content uses hidden="until-found" so Ctrl+F still finds hidden rows and opens them. Collapsing a stuck header keeps the page from jumping.
  6. Search: the input[data-filter="search"] in the same section filters rows by feature name plus optional aliases (data-cmp-alias on the row or cell). All words must match, umlauts and hyphens are tolerated ("erechnung" finds "E-Rechnung"). Matching sections open, empty ones hide, Escape clears. Empty result shows the Designer block .comparison_section.is-no-results.
  7. Tooltips: positioned in screen coordinates (never clipped), flip below when the sticky headers would cover them, tap to toggle on touch, Escape closes. Empty tooltips are hidden.
  8. Accessibility: fills table captions (category – sub-category) and hidden header cells with plan names; scroll areas become keyboard stops only when they actually scroll.

What it needs

Selector / attributeWhat it is
.comparison > .comparison_frameroot, sections container
.comparison_pricing_stickysticky plan header (with .comparison_plan_name)
.comparison_section, .comparison_section_toggle, .comparison_panelsection, its toggle(s), its collapsible panel
.comparison_data_table with caption + .comparison_a11y_headthe table per section
.comparison_hscrollhorizontal scroll areas (synced)
.tooltip_wrap / _trigger / _contenttooltips
data-cmp-aliasoptional extra search words on a row, e.g. "XRechnung ZUGFeRD"
data-pricing-section, .is-supportcolumn widths 46 % / 18 % on /preise; Supportpakete uses its .is-support classes

Change it safely

  • Add a feature row: duplicate a row in the Designer. The repair, search and keys pick it up automatically.
  • Help a search term: add data-cmp-alias with extra words to that row.
  • Texts: EMPTY_TITLE / EMPTY_TEXT (fallback only, the Designer empty block wins).
  • Mobile sticky "Funktion" cell uses --swatch--primary--cobalt (#121e3f, exists, verified 10 Oct) and background sizes 53 / 48 / 45.5 rem that must match the row width.

What breaks it

  • Wrapping the comparison section in data-filter="section": omxf would grab the same search input.
  • Removing .is-no-results: the generated fallback text appears instead (fine, but unstyled).
  • Changing the table width in Webflow without updating the mobile background-size values.
  • The repair warning in the console means a row lost its tag/tooltip: usually a row added without the wrapper div.

How to test

document.querySelector('.comparison').classList.contains('is-ready');   // true
getComputedStyle(document.querySelector('.comparison')).getPropertyValue('--cmp-top');

Scroll: nav, plans and category stack without gaps. Collapse and expand a category while it is stuck. Search "erechnung", then Escape. Ctrl+F a term inside a collapsed category. Hover, focus and tap a tooltip near the sticky header. 375 px: swipe the table, header follows.

Rich text list styler (check, yellow check, dots, horizontal)

Where: Global Styles component, embed block CREOGLYPH · RICH TEXT LISTS (plus the INLINE CONTENT FIX block right after it). Applies to every rich text that carries u-text u-rich-text (the Typography Paragraph component) or u-rich-text w-richtext. Pure CSS, no JS.

What it does

Every bullet list typed into a Paragraph automatically gets orgaMAX's blue check icons instead of browser bullets. One attribute on the paragraph switches the look: tighter checks, yellow checks, small dots, or a horizontal row. Nobody writes HTML: the client types a normal bulleted list in the rich text editor.

How to build a styled list, step by step

  1. Add a Typography Paragraph (or use one in a section). Pick its Variant (text size) as usual.
  2. In the text, use the rich text toolbar's bulleted list button (or numbered list, it looks the same: numbers are hidden). Type one item per line.
  3. Done: blue checks, 24 px icon, 12 px between icon and text, 12 px between items, 24 px space above and below the list.
  4. For another look, add one attribute from the table below to the same element that has u-text u-rich-text (the paragraph itself, not a wrapper). The selectors are written as .u-text.u-rich-text[data-icon-yellow], so an attribute on a parent div does nothing.

Where to type the attribute: select the element, Settings panel (D), Custom attributes, +. If the Settings panel on a Paragraph instance only shows props and no Custom attributes, use a plain Rich Text element with the classes u-text + u-rich-text instead (it gets exactly the same styling), or add the attribute inside the component where the paragraph lives.

Recipes

LookAttribute(s) on the paragraphResult
Blue checks (default)none24 px blue check icon, 12 px gaps, 24 px above and below
Compact blue checksdata-icon-checksame icon, 8 px between icon and text and between items
Yellow checks (dark sections)data-icon-yellowgold check icon. Combine with data-icon-check for the compact version
Blue dotsdata-list-style-dot="6"6 px blue dot, 16 px gap, aligned to the first text line
Small grey dotsdata-list-style-dot="4"4 px grey-500 dot, 8 px gaps (dense lists, footnotes)
Horizontal rowdata-horizontalitems side by side, centred, 32 px apart, wrap on smaller screens, one line from 1280 px. Text is forced white: only on dark backgrounds
No space under the listdata-list-margin-bottom="0"removes the 24 px under the list (when a paragraph or button follows)
List text at 16 pxdata-size="16"list items 16 px even if the paragraph variant is smaller or larger
White textclass u-color-white (Classes prop)paragraph, list items, links and bold text white

How the CSS works

  1. The list (ul / ol) becomes a vertical flex column, browser bullets off.
  2. Each li becomes a 2-column grid: icon column (width --cg-list-icon-size) and text column. The icon is a ::before with a background image (the check SVG).
  3. Each variant attribute only changes a few CSS variables: --cg-list-icon (which image), --cg-list-icon-size, --cg-list-icon-gap, --cg-list-item-gap, --cg-list-icon-offset (vertical nudge). The dot variants replace the image with a round coloured box.
  4. Inline fix: a grid would split a list item like "Bold start and normal text" into two columns. Items that contain bold, italic, links, spans, code or line breaks switch to a padding layout with an absolutely placed icon, so the sentence flows normally. Plain items stay on the grid.

Related rich text helpers (same Global Styles)

  • Semibold without bold: text formatted as subscript (<sub>) in a .u-text.u-rich-text renders as normal-size, baseline-aligned semibold (600) text instead of small lowered text, so it works as an emphasis style (e.g. a lead-in inside a list item). Has its own Designer-only rules so it previews correctly on the canvas.
  • data-link-style="medium-600" on the paragraph: links become their own line, 16 px above, grey-600, medium weight ("Mehr erfahren" style links in text).
  • Links inside paragraphs: blue, underline grows from 0 to 100 % on hover and focus; in .u-theme-dark the hover turns white.
  • data-vertical-tabet-below (typo kept on purpose, it is in use) on a section or wrapper: below 992 px its content wrappers and rich text centre.
  • Long-form CMS bodies (articles, Lexikon, guides) use .u-rich-text-content for tables and figures. Never style .u-rich-text globally: every Typography component carries it.

Change it safely

  • New icon: upload an SVG, then either change --cg-list-icon in :root (all lists) or add a new attribute block like the yellow one (one rule setting --cg-list-icon).
  • New variant: copy the dot or yellow block, change only the variables. Keep the :is(.u-text.u-rich-text, .u-rich-text.w-richtext)[data-...] selector shape.

What breaks it

  • Attribute on a wrapper instead of the paragraph: no effect.
  • data-horizontal on a light background: white text on white.
  • Dot and yellow together: the dot wins (the dot rule removes the image).
  • Horizontal lists with long items from 1280 px: they never wrap there and can run past the container. Keep items short (2 to 4 words).
  • Pricing cards have their own list layout (title line + description, icon spanning both) in the pricing CSS; do not add these attributes inside pricing cards.

How to test

// every styled list on the page and its look
[...document.querySelectorAll('.u-rich-text ul, .u-rich-text ol')].map(l => {
  const p = l.closest('.u-rich-text');
  return [...p.attributes].map(a => a.name).filter(n => /^data-(icon|list|horizontal|size)/.test(n)).join(' ') || 'default';
});

Check one list with a bold lead-in (text must flow on one line next to the icon), check 375 px (icon stays aligned with the first line), check the yellow version on a dark section.

Footer component (structure, mobile accordion, floating CTA cards, year)

Where: Global component Footer on every page (inside .page_wrap after main.page-main). Three embeds live inside it: a small CSS embed for the chevron, the floating-card CSS in the CTA, and one JS + CSS embed at the bottom (year script, mobile accordion).

What it does

The footer has five parts, top to bottom:

  1. CTA card (.footer_cta_wrap › .cta_wrap.u-glass-effect.is-footer): eyebrow, H2, text and two buttons ("Kostenlos testen" → #orgamax-testen, "Beratungstermin buchen" → /produktberatung), framed by two floating avatars and two glass cards ("bez. Rechnungen 82.470 €", "Betrag 55.830,92 €"). Texts and links are Footer props; the prop Footer CTA Visibility hides the whole card (used on /passwort-vergeben).
  2. Link columns (.footer_navigation_link_wrap): four section.footer_group_wrap groups, Funktionen, Lösungen, Wissen, Unternehmen, plus a fifth group with an empty title that holds "Weitere Funktionen" and visually continues the Funktionen column on desktop. Gold uppercase lines (Kernfunktionen, Nach Branche, Vergleiche, Service ...) are normal items with u-text-transform-uppercase u-color-gold-100.
  3. Body (.footer_body_wrap): logo (links to /), tagline, social icons, address, phone (tel: link) and opening hours.
  4. Badges (.badges_component): four award SVGs.
  5. Bottom bar (.footer_bottom_wrap): © line with the year and the legal links Impressum, AGB, Datenschutz, Cookie Einstellungen.

The footer is dark (u-theme-dark) on a full-bleed background image (u-cover-absolute), and has a screen-reader-only H2 "Footer" so it shows up in the heading outline. Its links are static on purpose: hand-picked SEO targets, and no extra Collection Lists on every page.

How it works, step by step

  1. Year: on DOMContentLoaded every [data-dynamic-year] gets the current year, so the © line never goes stale.
  2. Mobile accordion (≤ 991 px), building groups: the script walks all .footer_group_wrap. A group whose title is empty (only a non-breaking space) is attached to the previous titled group and gets footer_group_continuation. So Funktionen + Weitere Funktionen become one accordion on mobile.
  3. Accessibility setup: each title becomes role="button", tabindex="0", aria-expanded and aria-controls (all panel ids of that accordion, e.g. footer-accordion-1-panel-1 footer-accordion-1-panel-2). A chevron SVG is injected if the title has none.
  4. Opening: click, Enter or Space. Only one accordion is open at a time; opening one closes the others. Panels animate height from 0 to their content height (350 ms), then switch to height auto so they adapt to content.
  5. Closing: height animates back to 0, then the panel gets hidden so its links leave the tab order.
  6. Breakpoint change: crossing 991 px resets everything: on mobile all accordions start closed, on desktop roles and tabindex are removed and every list is visible again (no reload needed).
  7. Floating cards: pure CSS. One translucent fill (white 8 %), one glossy gradient edge drawn by a masked ::before, radius, border width and shadow taken from Figma. A shared @keyframes orgamax-float moves avatars and cards; each element has its own drift, rotation, duration (8.5 to 13 s) and negative delay, so they never move in sync. The two cards keep a permanent tilt (-3° left, +3° right). Between 992 and 1180 px the cards are repositioned so they do not cover the text.

What it needs

Selector / attributeRole
.footer_group_wrap › .footer_group_title + .footer_group_listone link column: title and list (the script needs exactly this pair)
empty .footer_group_title (non-breaking space)marks a continuation column that joins the previous accordion on mobile
.footer_group_chevronchevron; hidden on desktop by the small CSS embed
[data-dynamic-year]span that receives the current year
.floating_card.is-cta-left/right, .floating_avatar_wrap.is-cta-left/rightfloating elements; the CSS applies to these classes on any CTA on the page, not only the footer
--orgamax--floating--* on :rootvalue size, easing, tilt angles, glass fill and edge gradient

Change it safely

  • Add a link: duplicate an item inside the right column and change text and URL (the Tella video shows it). No code involved.
  • Add a column: duplicate a whole footer_group_wrap with a title. It becomes its own accordion on mobile automatically.
  • Extend a column on desktop without a new mobile accordion: duplicate the continuation group and keep its title empty.
  • Motion: change durations or --float-x / --float-y / --float-r per element in the floating-card CSS; tilt via --orgamax--floating--left-rotation / right-rotation.
  • Breakpoint: 991 px appears in the JS (matchMedia) and the accordion CSS; change both together.

What breaks it

  • Typing text into the empty continuation title: it becomes a separate accordion called by that text on mobile.
  • Renaming footer_group_wrap, footer_group_title or footer_group_list: the accordion stops working (desktop is unaffected).
  • Fixed 11 Oct, reduced motion: with transitions off, transitionend never fires; the script now skips the animation under reduced motion so closed panels get hidden and leave the tab order. Keep this when editing.
  • Fixed 11 Oct: the chevron CSS now uses min-width: 992px, matching the accordion's max-width: 991px. Change both together.
  • Fixed 11 Oct: logo link name (Clickable prop Screen Reader Text = orgaMAX Startseite), aria-labels on the 3 social links, alt texts on the 4 badges (inside the Badges component). Keep them when swapping icons or badges.

How to test

// mobile: accordions found, states and panel ids
[...document.querySelectorAll('.footer_group_title[role="button"]')].map(t => [t.textContent.trim(), t.getAttribute('aria-expanded'), t.getAttribute('aria-controls')]);
// links that are still placeholders
[...document.querySelectorAll('.footer_wrap a')].filter(a => ['#', '/'].includes(a.getAttribute('href'))).map(a => a.textContent.trim() || a.className);

At 375 px: tap Funktionen (Kernfunktionen and Weitere Funktionen open together), tap Wissen (Funktionen closes), Tab through with the keyboard (only open links get focus), rotate to landscape and back. Desktop: no chevrons, all columns open. Reduced motion: cards stand still with their tilt.

/funktionen rail script (hubs, functions, panels)

Where: Page /funktionen, one page-level embed (u-embed-js) below the section. The rail and the panel column are two separate Collection Lists (Funktionen Hubs with nested Funktionen, and Funktionen).

What it does

Turns the left rail into an accordion of the five hubs with their functions, and shows the selected function's panel (image, title, text, bullets, buttons) on the right. On mobile the panel opens inline under the tapped function. The selected function is written to the URL (?funktion=slug) so a state can be shared, and an ItemList schema of all functions is added for search engines.

How it works, step by step

  1. Finds .funktionen_layout › .funktionen_rail and .funktionen_panel_col. Every rail row and every panel carries data-fn = the function slug; panels are matched by slug, not by order, because the two lists sort differently.
  2. Hubs: each .funktionen_hub_ci has a .funktionen_hub_row (button) and a .funktionen_child_wrap (the functions). One hub is open at a time; height animates 320 ms, measured on the inner list so it never jumps.
  3. Selecting a function: row gets is-active and aria-selected, all other panels are hidden, the matching panel fades in, its image switches from lazy to eager loading.
  4. Mobile (≤ 991 px): one shared holder moves the active panel directly under its row; tapping the active function again closes it.
  5. Accessibility: rail = tablist, function rows = tab with aria-controls, panels = tabpanel, hub rows = buttons with aria-expanded. Enter/Space select, ↑/↓ move between visible functions.
  6. Start state: the function from ?funktion= if present, otherwise the first hub opens and its first function is shown (desktop only).
  7. Schema: builds an ItemList JSON-LD from what is rendered (names from the panel titles, links from the panel buttons).

What it needs

Selector / attributeRole
.funktionen_row[data-fn]a function row in the rail (slug in data-fn)
.funktionen_panel[data-fn]the matching panel on the right (same slug)
.funktionen_hub_ci › .funktionen_hub_row / .funktionen_child_wraphub row and its function list
.funktionen_hub_chevronchevron, rotated by the script
.funktionen_panel_titlepanel title (used for the schema)

Change it safely

  • Order of hubs and functions: Reihenfolge fields in the CMS, no code.
  • A function belongs to exactly one hub (Funktionen im Bereich). The script finds a row's hub by where it sits in the rail.
  • Timing and easing: DURATION / EASING at the top. URL parameter name: PARAM.
  • #90 (hub panels): add panels with their own data-fn (e.g. the hub slug), make hub rows selectable in select(), decide the toggle and start behaviour as agreed with orgaMAX.

What breaks it

  • A function listed under two hubs (today (E-)Rechnungen and Mahnwesen also sit under Angebote & Aufträge): the same data-fn appears twice, rowOf() always finds the first, so the second row never highlights and the wrong hub can open. Fix in the CMS first (#90).
  • A function in the rail without a published panel item (draft in one list, published in the other): clicking it does nothing.
  • Renaming any of the classes above, or removing data-fn from the rail rows or panels.

How to test

document.querySelectorAll('.funktionen_row[data-fn]').length;          // rows in the rail
[...document.querySelectorAll('.funktionen_row[data-fn]')].map(r => r.dataset.fn).filter((v,i,a) => a.indexOf(v) !== i);  // duplicates: should be []

Desktop: click through all five hubs and a few functions, check the URL updates, reload with that URL. 375 px: tap a function (panel opens below), tap again (closes). Keyboard: Tab to a hub, Enter, ↓ through functions.

4 entries

Custom CSS

Where global CSS lives

All global CSS sits in the Global Styles component (on every page), split into embeds by topic. Component-specific CSS sits in the component (CSS / ... components or an embed as first child).

Global Styles embeds

BlockWhat it does
Lumos baseBox sizing, button reset, margin trim (first/last child margins removed in content wrappers), line clamp (u-line-clamp-2..4), rich text link z-index, icon colouring, focus states, u-hide-if-empty-cms, state manager (data-state / data-trigger), responsive column attributes (data-large|medium|small|xsmall-columns), slot styler, slider offset
Helpersu-align-start-portrait, hyphenation [data-long-word="true"], align-self utilities, rich text list size [data-size="16"], desktop order, [data-vertical-tabet-below]
Buttonsbutton_main variants: primary, secondary (gradient 1px border via background-clip: border-area with mask fallback), tertiary (looping arrow), link. Light and dark theme tokens. Nothing moves on hover. Slider arrow gradient hover, disabled state
Rich text linksAnimated underline 0 to 100 %, white in dark theme
Equal width buttons[data-button-equal-width]: two buttons share 50/50, stack below 480
Radiusu-radius-0..40 and pairs like u-radius-24-20 (smaller at ≤ 991)
Shadowsu-shadow-s/m/l/xl, u-shadow-blur, u-glass-effect
Dark theme typographyInside .u-theme-dark: headings white, text white 80, any u-color-* wins. Light inside dark via @scope
Gradientsu-bg-gradient-* cobalt-blue, blue-gold, blue, gold, beige, bg-1, bg-2, bg-3
Rich text listsCheck icon bullets; variants data-icon-check, data-list-style-dot="6|4", data-icon-yellow, data-horizontal, data-list-margin-bottom="0"
Iconsu-icon-12..96 and responsive pairs u-icon-48-40-32
Card hoverdata-card="hover": blue ring via ::after, heading colour, image scale, CTA arrow loop. Bento cards lift
Split layout.u-split + .u-split-left[data-number="63"]: left width in %, stacks ≤ 991
Rich text content.u-rich-text-content only (never on Typography components): tables scroll horizontally, striped, rounded; figures full width with caption border
Glass.u-glass-card, [data-glass="icon"]
Number attributedata-number="0..100" sets --number used by max-widths and split widths

Component CSS

ComponentPurpose
CSS / HubspotLegacy HubSpot forms
CSS / Hubspot / No Raw HTMLNew editor HubSpot forms
CSS / Filter Active StylesActive chip and filter states
CSS / RichText Overflow SolutionLong words and tables in rich text do not overflow
CSS / Legal SidebarSticky sidebar on legal pages
CSS / TooltipTooltips (data-tooltip)
CSS / Search IconSearch input icon
CSS / Pricing CardPricing cards, badges, switch
Single Testimonial / CSSTestimonial slider + locked state
Navbar CSSNav tokens, offset router, states, mobile sheet, light theme, burger hide
Pricing page embedComparison table + tooltip, scoped to [data-pricing-section]

Gradient backgrounds

Section backgrounds use the Gradient component in the Section's background slot. Variants: BG 1 (white → light blue, base), BG 2 (light blue → white), BG 3 (warm sand). Visibility prop to switch it off. Map from the Figma fill style 1:1.

30 entries

CMS

CMS principles

  • No duplicated content across collections: reference the single source item (lesson from Branchen Gewerke, now deleted).
  • Website Pages is an empty tag collection: one item per static page. Other collections tag themselves to pages through a multi-reference, and sections filter by it. This is how FAQs, testimonials, logos, gallery images and team members are assigned to static pages.
  • Max 20 Collection Lists per page. The nav uses 3 on every page. Strategic, rarely changing content stays static.
  • Help texts on every field are in German and tell editors what goes there and how long.
  • Logos: only Customer Logos. Never create another logo collection.
  • Check existing content before creating items. Publishing is a separate step after create / update. Draft items are not live.

Working in the CMS: rules for every editor

  • Empty hides: most optional sections, cards, tabs and buttons hide when their title or text field is empty. Leave a field empty to switch that part off, fill it to show it.
  • Headings in RichText fields: pasted text loses its heading tag. Hero headings must be H1 (one per page), section headings H2. Select the text and set the tag.
  • Lists: use the normal bullet list button. Check icons come from the design automatically.
  • Images: AVIF, exported at 2x, in the exact Figma ratio; logos and icons SVG. Always fill the Alt-Text field next to an image.
  • Order fields (Reihenfolge, Order No): smallest number first.
  • Slugs: do not change the slug of a published item; links and redirects break.
  • Draft vs published: drafts never show on the live site, also not in the nav or sliders. Publish the item, then publish the site.
  • References: deleting an item silently removes it from every page that referenced it. Unpublish (draft) instead of deleting when unsure.
  • Help texts under each field in the CMS (German) say what goes there and how long it should be.

Website Pages

Tag per static page, used to assign content to pages

ID 6a84351c26a28574a2b79c93 · slug website-pages · 0 custom fields

Why it exists: Webflow cannot filter a Collection List by "the static page I am on". So every static page that shows CMS content gets one item here (an empty tag). Content items point to it, and the section on that page filters by it.

Where it shows up: FAQs, Testimonials, Customer Logos, Galerie Bilder, Team, Themen, Formate, Branchen Kategorien and Funktionen (Kachel-/Icon-Grid) all reference it.

What to fill and how:

  • New static page that should show FAQs, testimonials or logos: create an item with the page name, tag the content items with it, then set the section's Filters prop to Website Page contains [item].
  • A duplicated page still filters by the original page's item. Give it its own item and change the filter (this is why cloned SEA pages showed the Paid Social FAQs).

Watch out:

  • Deleting or renaming an item makes every section filtering by it silently empty ("No items found").
All fields with type

No custom fields: Name and Slug only.

FAQs

All FAQs, assigned to pages, Branchen, Funktionen, hubs, guides, webinars, ERP, Weiterbildungen

ID 6a8436365008f4ff2442383f · slug faq · 10 custom fields

Why it exists: One source for every question and answer, reused across pages so the same answer is never maintained twice.

Where it shows up: Section / FAQ [CMS] on static pages (filter by Website Page) and on the templates of Branchen, Funktionen, hubs, Guides, Webinare, ERP Funktionen and Weiterbildungen (filtered by the current item).

What to fill and how:

  • Name = the question, FAQ Answer = the answer, Order No = position (smallest first).
  • Tag every place it should appear in the matching multi-reference field. One FAQ can appear on many pages.

Watch out:

  • Never write a page name into the question: many FAQs are shared by up to 10 pages.
  • Answers are RichText: use real lists and links, no pasted formatting.
All fields with type
FieldType
Order NoNumber
FAQ AnswerRichText
Website PageMultiReference→Website Pages
BranchenMultiReference→Branchen
FunktionenMultiReference→Funktionen
FunktionsbereicheMultiReference→Funktionen Hubs
Guides & VorlagenMultiReference→Guides & Vorlagen
WebinareMultiReference→Webinare
ERP FunktionenMultiReference→ERP Funktionen
WeiterbildungenMultiReference→Weiterbildungen

Authors

People: case study authors, Lexikon experts, job contacts

ID 6a85676f1f792226d9e0ba12 · slug authors · 4 custom fields

Why it exists: One record per person so names, photos and roles stay consistent everywhere.

Where it shows up: Case study authors and quote authors, the Lexikon and E-Rechnung expert box (CTA Experte), job contacts (Stellenangebote) and the author of a testimonial.

What to fill and how:

  • Designation = role line, Avatar = square photo (AVIF), Bio, LinkedIn.

Watch out:

  • Deleting a person empties every box that references them.
All fields with type
FieldType
DesignationPlainText
AvatarImage
BioRichText
LinkedInLink

Testimonials

Quotes, video testimonials, ratings; assigned to pages and Branchen

ID 6a85676f527656bb527bc757 · slug testimonials · 15 custom fields

Why it exists: All customer quotes (text, rating, video) in one place, assigned to wherever they should appear.

Where it shows up: Section / Testimonials [CMS] and Section / Single / Testimonials [CMS] on static pages (Website Page), Branchen pages (Branchen, Branchen Kategorien, Highlight Testimonials), Funktionen (Kundenstimmen Auswahl), case studies (Zitat), Karriere (employee quotes).

What to fill and how:

  • Quote + Kurzzitat (short version for small cards), Author, Customer Logo, Bild + Alt-Text, optional Bewertung (stars), Video URL + Video Poster for a video testimonial, Case Study Link.
  • Assign via Website Page (static pages) or Branchen / Branchen Kategorien (industry pages). Order No sorts.

Watch out:

  • The slider shows arrows and a left-aligned header automatically when a page has many testimonials; with few, they fit without a slider and the header centres. That is intended (sheet #26).
  • A section showing "No items found" means no testimonial is tagged to that page yet.
All fields with type
FieldType
KurzzitatRichText
QuoteRichText
AuthorReference→Authors
Customer LogoReference→Customer Logos
Website PageMultiReference→Website Pages
Order NoNumber
BranchenMultiReference→Branchen
Branchen KategorienMultiReference→Branchen Kategorien
LabelPlainText
BildImage
Case Study LinkLink
BewertungNumber
Video URLLink
Bild Alt-TextPlainText
Video PosterImage

Customer Logo Categories

Logo grouping for the category logo section

ID 6a881bc087e34e16878688c4 · slug customer-logo-category · 0 custom fields

Why it exists: Groups for the logo section that shows customers by company type.

Where it shows up: Section / Customer / Logo / Category [CMS] (e.g. on hubs like Warenwirtschaft).

What to fill and how:

  • One item per group label; logos join groups through their Customer Logo Category field.

Watch out:

  • A group with no logos does not appear; missing groups on a page usually mean no logo is tagged to it.
All fields with type

No custom fields: Name and Slug only.

Customer Logos

The only logo collection (colour and white versions, order, mobile hide)

ID 6a881bf4d06a58a3e93f49cd · slug customer-logo · 6 custom fields

Why it exists: The only logo collection on the site (decided: never create a second one).

Where it shows up: Logo bars and logo sections, case studies (Logo), testimonials (Customer Logo).

What to fill and how:

  • Logo (colour) and Logo White (for dark sections), SVG only. Logo Order sorts. Hide On Mobile hides it on small screens. Website Page and Category assign it.

Watch out:

  • Upload both versions: a dark section shows the white file.
All fields with type
FieldType
LogoImage
Logo WhiteImage
Customer Logo CategoryMultiReference→Customer Logo Categories
Logo OrderNumber
Hide On MobilePlainText
Website PageMultiReference→Website Pages

Branchen Kategorien

6 industry categories; testimonial, claim, slider heading

ID 6a9666eca3cb744de52874aa · slug branchen-kategorien · 7 custom fields

Why it exists: The 6 industry groups (e.g. Handwerk & Bau). They group the /branchen overview and its filter tabs and drive the industry slider heading.

Where it shows up: /branchen overview (groups + filter chips), the slider on each industry page, case studies (Kategorie), testimonials.

What to fill and how:

  • Reihenfolge = order of groups. Slider Eyebrow / Überschrift / Text = heading above the industry slider on industry pages of this category. Testimonial + Claim for the category.

Watch out:

  • Open on 10 Oct: only Handwerk & Bau has slider texts; Handel has no industries yet, so its filter shows "not found".
All fields with type
FieldType
TestimonialReference→Testimonials
ReihenfolgeNumber
ClaimRichText
SeitenMultiReference→Website Pages
Slider EyebrowRichText
Slider ÜberschriftRichText
Slider TextRichText

Branchen

Industry pages (template /branchen/[slug]) incl. overview card and slider card fields

ID 6a9666eead0d5b6a9a33d9ca · slug branchen · 46 custom fields

Why it exists: One item per industry page. The whole page is built from these fields (template /branchen/[slug]); field groups in the editor follow the page from top to bottom.

Where it shows up: /branchen/[slug], cards on /branchen, the industry slider on other pages of the same category, case studies (Branchenseite).

What to fill and how:

  • Overview card: Kategorie, Reihenfolge, Karten Bild, Karten Text.
  • Page: Hero, Logo-Leiste, Büro-Alltag (4 cards), Lösung (text + check list), Tabs (4 tabs with image), Highlight Testimonials, CTA, Kundenstimmen, FAQ, SEO.
  • Slider card on sibling pages: Slider Titel + Slider Text + Karten Bild.

Watch out:

  • An empty field hides its part: empty Büro-Alltag Überschrift hides the section, empty Alltag/Tab titles hide that card/tab, empty Logo-Leiste Überschrift hides the logo bar, no Highlight Testimonials hides the quote block.
  • Open on 10 Oct: 8 Handwerk industries are drafts, 3 industries have no category, Tabs Button Label/Link missing on many items, slider images and texts partly placeholders (sheet #87).
All fields with type
FieldType
Branchen KategorieReference→Branchen Kategorien
ReihenfolgeNumber
Karten BildImage
Karten TextRichText
Primary Button TextPlainText
Primary Button LinkLink
Secondary Button TextPlainText
Secondary Button LinkLink
Hero EyebrowRichText
Hero ÜberschriftRichText
Hero SublineRichText
Hero Button 1 TextPlainText
Hero Button 1 LinkLink
Hero Button 2 TextPlainText
Hero Button 2 LinkLink
Hero BildImage
Logo-Leiste ÜberschriftRichText
Büro-Alltag EyebrowRichText
Büro-Alltag ÜberschriftRichText
Alltag 1–4 IconImage
Alltag 1–4 TitelRichText
Alltag 1–4 TextRichText
Alltag 1–4 LinkLink
Lösung EyebrowRichText
Lösung ÜberschriftRichText
Lösung TextRichText
Tab 1–4 TitelRichText
Tab 1–4 TextRichText
Tab 1–4 BildImage
Tabs Button LabelPlainText
Tabs Button LinkLink
Highlight TestimonialsMultiReference→Testimonials
CTA EyebrowRichText
CTA ÜberschriftRichText
CTA SublineRichText
Kundenstimmen EyebrowRichText
Kundenstimmen ÜberschriftRichText
Kundenstimmen SublineRichText
FAQ EyebrowRichText
FAQ ÜberschriftRichText
FAQ SublineRichText
Slider TitelRichText
Slider TextRichText
Meta TitlePlainText
Meta DescriptionPlainText
OG BildImage

Branchen Vorteile

Repeatable body blocks of an industry page

ID 6a9666f2498515d44b18e700 · slug branchen-vorteile · 28 custom fields

Why it exists: Optional repeatable body block for an industry page (eyebrow, heading, up to 4 blocks with text, checklist, image, link).

Where it shows up: Industry pages, linked through the Branche reference.

What to fill and how:

  • Create one item per industry that needs the block and set Branche.

Watch out:

  • Check the template before relying on it: most industry content now lives in Branchen itself.
All fields with type
FieldType
BrancheReference→Branchen
Block 1 ChecklisteRichText
Block 1 BildImage
Block 1 LinkLink
Block 2 ChecklisteRichText
Block 2 BildImage
Block 2 LinkLink
Block 3 ChecklisteRichText
Block 3 BildImage
Block 3 LinkLink
Block 4 ChecklisteRichText
Block 4 BildImage
Block 4 LinkLink
SublineRichText
Block 1 TextRichText
Block 2 TextRichText
Block 3 TextRichText
Block 4 TextRichText
EyebrowRichText
ÜberschriftRichText
Block 1 EyebrowRichText
Block 1 ÜberschriftRichText
Block 2 EyebrowRichText
Block 2 ÜberschriftRichText
Block 3 EyebrowRichText
Block 3 ÜberschriftRichText
Block 4 EyebrowRichText
Block 4 ÜberschriftRichText

Funktionen Hubs

5 function areas: nav, hub links, functions in area, slider

ID 6a9910772efaf3ef317dccfa · slug bereiche · 9 custom fields

Why it exists: The 5 function areas (Rechnungen, Angebote & Aufträge, Stammdaten & Kontakte, Steuern, Warenwirtschaft). They tie functions together for the nav, the /funktionen rail and the hub pages.

Where it shows up: Nav Funktionen dropdown (Kernfunktionen), /funktionen rail, hub pages (/rechnungen and the other four), the back link on function pages.

What to fill and how:

  • Kurzname, Nav Beschreibung, Icon, Reihenfolge: how the area shows in the nav and rail.
  • Funktionen im Bereich: the functions listed under the area (rail and hub grid).
  • Bereichsseite Link: path of the hub page (nav link and the back arrow on function pages).
  • Erfolgsgeschichten: case studies on the hub. Mehr Funktionen Slider: functions in the "Mehr aus orgaMAX herausholen" slider (max 5).

Watch out:

  • A function listed under two hubs breaks the /funktionen rail (sheet #90: Angebote & Aufträge still lists (E-)Rechnungen and Mahnwesen).
  • Hub pages are static pages made from the Funktionen-Hub-Template, not CMS template pages. Panel fields for #90 are still to be added.
All fields with type
FieldType
KurznamePlainText
Nav BeschreibungPlainText
ReihenfolgeNumber
IconImage
Icon Alt-TextPlainText
Funktionen im BereichMultiReference→Funktionen
Bereichsseite LinkLink
ErfolgsgeschichtenMultiReference→Case Studies
Mehr Funktionen SliderMultiReference→Funktionen

Funktionen

Function pages (template /funktion/[slug]) + nav groups

ID 6a99110c79ee0d9064278cc5 · slug funktion · 90 custom fields

Why it exists: One item per function page (template /funktion/[slug]) plus the data the nav and hub grids need.

Where it shows up: /funktion/[slug], nav (Nav Gruppe), hub grids and cards (Grid fields), /funktionen rail and panel, Kachel-/Icon-Grid sections on static pages.

What to fill and how:

  • Nav: Nav Gruppe (Kernfunktion / Weitere Funktion / Nicht in Navigation), Reihenfolge, Nav Beschreibung, Icon.
  • Bereich: the hub it belongs to (drives the back link).
  • Cards: Grid Bild, Grid Text, Grid Vorteile, Grid Button; Seiten – Kachel-Grid / Icon-Grid choose static pages where the card appears.
  • Page: Hero, Vorteile (4), Funktionsweise (4 steps with image, list and button), Kundenstimmen Auswahl, Verwandte Funktionen, CTA, SEO, Noindex.

Watch out:

  • 90 fields, close to Webflow's limit: do not add fields casually.
  • Drafts (e.g. Einkauf, Auswertungen) do not show in the nav until published.
All fields with type
FieldType
BereichReference→Funktionen Hubs
Nav GruppeOption
Nav BeschreibungPlainText
ReihenfolgeNumber
IconImage
Icon Alt-TextPlainText
Grid BildImage
Grid Bild Alt-TextPlainText
Grid TextRichText
Hero EyebrowRichText
Hero SublineRichText
Hero BildImage
Hero Bild Alt-TextPlainText
Hero Button 2 LinkLink
Vorteile EyebrowRichText
Vorteile ÜberschriftRichText
Vorteil 1 TitelRichText
Vorteil 1 TextRichText
Vorteil 1 IconImage
Vorteil 2 TitelRichText
Vorteil 2 TextRichText
Vorteil 2 IconImage
Vorteil 3 TitelRichText
Vorteil 3 TextRichText
Vorteil 3 IconImage
Vorteil 4 TitelRichText
Vorteil 4 TextRichText
Vorteil 4 IconImage
Funktionsweise EyebrowRichText
Funktionsweise ÜberschriftRichText
Funktionsweise SublineRichText
Schritt 1 EyebrowRichText
Schritt 1 TitelRichText
Schritt 1 TextRichText
Schritt 1 BildImage
Schritt 2 EyebrowRichText
Schritt 2 TitelRichText
Schritt 2 TextRichText
Schritt 2 BildImage
Schritt 3 EyebrowRichText
Schritt 3 TitelRichText
Schritt 3 TextRichText
Schritt 3 BildImage
Schritt 4 EyebrowRichText
Schritt 4 TitelRichText
Schritt 4 TextRichText
Schritt 4 BildImage
Kundenstimmen EyebrowRichText
Kundenstimmen ÜberschriftRichText
Kundenstimmen SublineRichText
Kundenstimmen AuswahlMultiReference→Testimonials
Verwandte EyebrowRichText
Verwandte ÜberschriftRichText
Verwandte SublineRichText
Verwandte FunktionenMultiReference→Funktionen
Meta TitlePlainText
Meta DescriptionPlainText
OG BildImage
NoindexSwitch
Grid Button LinkLink
Grid VorteileRichText
Schritt 1 VorteileRichText
Schritt 2 VorteileRichText
Schritt 3 VorteileRichText
Schritt 4 VorteileRichText
Grid Button TextPlainText
Hero Button 2 TextPlainText
Hero ÜberschriftRichText
Hero Buton 1 TextPlainText
Hero Button 1 LinkLink
Schritt 1 Button TextPlainText
Schritt 1 Button LinkLink
Schritt 2 Button TextPlainText
Schritt 2 Button LinkLink
Schritt 3 Button TextPlainText
Schritt 3 Button LinkLink
Schritt 4 Button TextPlainText
Schritt 4 Button LinkLink
Seiten – Kachel-GridMultiReference→Website Pages
Grid IconImage
Grid Icon Alt-TextPlainText
Seiten – Icon-GridMultiReference→Website Pages
Grid ReihenfolgeNumber
CTA EyebrowRichText
CTA ÜberschriftRichText
CTA SublineRichText
CTA Button 1 TextPlainText
CTA Button 1 LinkLink
CTA Button 2 TextPlainText
CTA Button 2 LinkLink

Case Studies

Customer stories (template /kundenstories/[slug])

ID 6a99110d017afb3097b75873 · slug kundenstories · 45 custom fields

Why it exists: Customer stories with their own page (template /kundenstories/[slug]) and cards across the site.

Where it shows up: /kundenstories/[slug], /kunden, Section / Case Studies [CMS], hubs (Erfolgsgeschichten), industry pages.

What to fill and how:

  • Card: Eyebrow, Überschrift, Text, Bild, Logo, Kategorie, Reihenfolge.
  • Page: Über das Unternehmen, Das Wichtigste in Kürze, Herausforderung, Lösung, Ergebnisse (3 values), Artikel, Zitat, CTA, Autor, SEO.

Watch out:

  • Card images use the Figma ratio: a different ratio gets cropped (sheet #27, #57).
All fields with type
FieldType
EyebrowRichText
ÜberschriftRichText
TextRichText
BildImage
Bild Alt-TextPlainText
MitarbeitendeRichText
RechtsformRichText
BranchenseiteReference→Branchen
LinkLink
ReihenfolgeNumber
Meta TitlePlainText
Meta DescriptionPlainText
DatumDateTime
Über das UnternehmenRichText
Das Wichtigste in KürzeRichText
Erreichte ErgebnisseRichText
HerausforderungRichText
LösungRichText
ArtikelRichText
CTA TextRichText
CTA Button TextPlainText
CTA Button LinkLink
CTA BildImage
ZitatReference→Testimonials
LogoReference→Customer Logos
KategorieMultiReference→Branchen Kategorien
AutorMultiReference→Authors
Tag 1RichText
Tag 2RichText
LesezeitRichText
SitzRichText
Ergebnisse ÜberschriftRichText
Ergebnisse SublineRichText
Ergebnis 1 WertRichText
Ergebnis 1 LabelRichText
Ergebnis 2 WertRichText
Ergebnis 2 LabelRichText
Ergebnis 3 WertRichText
Ergebnis 3 LabelRichText
CTA TitelRichText
CTA Bild LabelRichText
BrancheRichText
WebsiteRichText
FirmennamePlainText
Zitat AutorReference→Authors

Themen

Topic tags for guides and webinars

ID 6aa0d3305503fda884c1165c · slug themen · 2 custom fields

Why it exists: Topic tags for filter chips.

Where it shows up: /guides-vorlagen, /webinare, E-Rechnungs Hub (Thema); Seiten decides on which listing page a topic chip appears.

What to fill and how:

  • Add a topic, set Reihenfolge, tag the pages where it should be a chip.

Watch out:

  • The filter matches chip text to card tag text: keep the name identical everywhere.
All fields with type
FieldType
SeitenMultiReference→Website Pages
ReihenfolgeNumber

Formate

Format tags

ID 6aa0d331dbb344b54f697ec5 · slug formate · 2 custom fields

Why it exists: Format tags (e.g. Checkliste, Vorlage) for filter chips.

Where it shows up: /guides-vorlagen (Format); Seiten decides where the chip appears.

What to fill and how:

  • Same as Themen.

Watch out:

  • Same as Themen.
All fields with type
FieldType
SeitenMultiReference→Website Pages
ReihenfolgeNumber

Webinare

Webinars (WebinarGeek links)

ID 6aa0d338fc83ce4bda2fd348 · slug webinare · 10 custom fields

Why it exists: Live and on-demand webinars hosted on WebinarGeek.

Where it shows up: /webinare (filterable list), webinar template, FAQs (Webinare).

What to fill and how:

  • Thema, Verfügbarkeit, Termin, Dauer, Beschreibung, Bild + Alt, WebinarGeek Link, Button Text, Reihenfolge.

Watch out:

  • The registration happens on WebinarGeek: the link must be the exact event URL.
All fields with type
FieldType
ThemaMultiReference→Themen
VerfügbarkeitOption
DauerPlainText
BeschreibungRichText
BildImage
Bild Alt-TextPlainText
WebinarGeek LinkLink
Button TextPlainText
TerminDateTime
ReihenfolgeNumber

Guides & Vorlagen

Guides, templates, downloads (template)

ID 6aa0d33abb37e6334507fa27 · slug guides-vorlagen · 55 custom fields

Why it exists: Downloads (guides, checklists, templates) with a landing page each, optionally gated by a HubSpot form.

Where it shows up: /guides-vorlagen (filterable list), template /guides-vorlagen/[slug], Empfehlungen on other guides.

What to fill and how:

  • Card: Beschreibung, Bild, Thema, Format, Reihenfolge, Empfehlung (featured).
  • Download: Datei or Download Link. HubSpot Formular ID = the form that gates the download; switch Ohne Formular on for a direct download.
  • Page: Hero (badge, checklist, image), Kennzahlen (3 values), Inhalt, Download, CTA, FAQ, SEO.

Watch out:

  • A wrong HubSpot form ID shows an empty form area. Test the download on staging.
All fields with type
FieldType
BeschreibungRichText
BildImage
Bild Alt-TextPlainText
Download LinkLink
Button TextPlainText
DateiFile
ReihenfolgeNumber
ThemaMultiReference→Themen
EmpfehlungSwitch
Hero TextRichText
Hero ChecklisteRichText
Hero Button TextPlainText
Hero BildImage
Hero Bild Alt-TextPlainText
Kennzahlen Button TextPlainText
Inhalt TextRichText
Inhalt ListeRichText
Inhalt Button TextPlainText
Inhalt BildImage
Inhalt Bild Alt-TextPlainText
Download TextRichText
Download ChecklisteRichText
Download Formular Button TextPlainText
CTA TextRichText
CTA ListeRichText
CTA Button TextPlainText
CTA Button LinkLink
CTA BildImage
CTA Bild Alt-TextPlainText
EmpfehlungenMultiReference→Guides & Vorlagen
Meta TitelPlainText
Meta BeschreibungPlainText
Open Graph BildImage
FormatMultiReference→Formate
Hero BadgeRichText
Kennzahlen EyebrowRichText
Kennzahlen TextRichText
Kennzahl 1 WertRichText
Kennzahl 1 LabelRichText
Kennzahl 2 WertRichText
Kennzahl 2 LabelRichText
Kennzahl 3 WertRichText
Kennzahl 3 LabelRichText
Inhalt EyebrowRichText
Download EyebrowRichText
CTA EyebrowRichText
HubSpot Formular IDPlainText
Ohne FormularSwitch
Kennzahlen ÜberschriftRichText
Inhalt ÜberschriftRichText
Download ÜberschriftRichText
CTA ÜberschriftRichText
FAQ ÜberschriftRichText
FAQ SublineRichText
Hero ÜberschriftRichText

Newsletter Archivs

Newsletter articles (template /newsletter-artikel/[slug])

ID 6aaa43a724f1ec8a89b94bcd · slug newsletter-artikel · 3 custom fields

Why it exists: Past newsletter articles (about 377, imported from the old site) with their own page.

Where it shows up: Template /newsletter-artikel/[slug], /newsletter-archiv via Newsletter Ausgaben.

What to fill and how:

  • Thumbnail, Inhalt, Tag.

Watch out:

  • Imported images are small and in the wrong ratio (sheet #52). Florian asked on 9 Oct whether this can be fixed without re-uploading by hand: Yannik decides, see the Task board.
All fields with type
FieldType
ThumbnailImage
InhaltRichText
TagRichText

Newsletter Ausgaben

Newsletter issues grouping articles

ID 6aaa87ed886745b0aa27401c · slug newsletter-ausgaben · 3 custom fields

Why it exists: Newsletter issues: groups articles by send date for the archive.

Where it shows up: /newsletter-archiv (year filter, monthly overview).

What to fill and how:

  • Datum, Thumbnail, and the articles of that issue in Newsletter Archivs.

Watch out:

  • The archive uses the shared filter script (omxf).
All fields with type
FieldType
DatumDateTime
ThumbnailImage
Newsletter ArchivsMultiReference→Newsletter Archivs

Lexikon

Glossary entries (template /lexikon/[slug])

ID 6aabce6a3c0a5103ad678d87 · slug lexikon · 23 custom fields

Why it exists: Glossary entries, an SEO cornerstone (template /lexikon/[slug]).

Where it shows up: /lexikon (A to Z + search), /lexikon/[slug], Verwandte Wörter on other entries.

What to fill and how:

  • Buchstabe, Kurz zusammengefasst, Definition, Artikel Inhalt (use real H2s: they build the table of contents), Datum, Lesezeit, Thumbnail.
  • CTA block (Titel, Beschreibung, Button, Bild, Experte) and Sidebar CTA.
  • Verwandte Wörter: related entries. SEO Titel / Beschreibung.

Watch out:

  • The end-of-article CTA block shows only when CTA Titel is filled (sheet #14).
  • Imported entries have one sentence per paragraph; they need merging by someone who knows the content (sheet #11).
All fields with type
FieldType
ThumbnailImage
Thumbnail Alt-TextPlainText
BuchstabeReference→Lexikon Buchstaben
Kurz zusammengefasstRichText
Artikel InhaltRichText
CTA TitelRichText
CTA BeschreibungRichText
CTA Button TextPlainText
CTA Button LinkLink
CTA BildImage
CTA Bild Alt-TextPlainText
CTA ExperteReference→Authors
Verwandte WörterMultiReference→Lexikon
SEO TitelPlainText
SEO BeschreibungPlainText
DefinitionRichText
LesezeitRichText
CTA Bild LabelRichText
Sidebar CTA TitelRichText
Sidebar CTA BeschreibungRichText
Sidebar CTA Button TextPlainText
Sidebar CTA Button LinkLink
DatumDateTime

Lexikon Buchstaben

A to Z letters with their entries

ID 6aabce6b1a896a6ef812d38d · slug lexikon-buchstaben · 4 custom fields

Why it exists: The A to Z letters with their entries, so /lexikon can render letter groups.

Where it shows up: /lexikon A to Z accordion and letter bar.

What to fill and how:

  • Begriffe: entries under this letter. Reihenfolge, SEO fields.

Watch out:

  • An entry missing here does not appear under its letter even if it is published.
All fields with type
FieldType
ReihenfolgeNumber
BegriffeMultiReference→Lexikon
SEO TitelPlainText
SEO BeschreibungPlainText

ERP Funktionen

ERP function pages (template /erp-funktionen/[slug])

ID 6ab23c5110225db7d1c7e50f · slug erp-funktionen · 90 custom fields

Why it exists: Function pages for the ERP product line, same structure as Funktionen (template /erp-funktionen/[slug]).

Where it shows up: /erp-funktionen/[slug], /erp-hub.

What to fill and how:

  • Same field logic as Funktionen.

Watch out:

  • 90 fields, near the limit.
All fields with type
FieldType
BereichReference→Funktionen Hubs
Nav GruppeOption
ReihenfolgeNumber
IconImage
Icon Alt-TextPlainText
Grid BildImage
Grid Bild Alt-TextPlainText
Grid TextRichText
Grid VorteileRichText
Grid Button TextPlainText
Grid Button LinkLink
Hero EyebrowRichText
Hero SublineRichText
Hero BildImage
Hero Bild Alt-TextPlainText
Hero Button 1 TextPlainText
Hero Button 1 LinkLink
Hero Button 2 TextPlainText
Hero Button 2 LinkLink
Vorteile EyebrowRichText
Vorteile ÜberschriftRichText
Vorteil 1 TitelRichText
Vorteil 1 TextRichText
Vorteil 1 IconImage
Vorteil 2 TitelRichText
Vorteil 2 TextRichText
Vorteil 2 IconImage
Vorteil 3 TitelRichText
Vorteil 3 TextRichText
Vorteil 3 IconImage
Vorteil 4 TitelRichText
Vorteil 4 TextRichText
Vorteil 4 IconImage
Funktionsweise EyebrowRichText
Funktionsweise ÜberschriftRichText
Funktionsweise SublineRichText
Schritt 1 EyebrowRichText
Schritt 1 TitelRichText
Schritt 1 TextRichText
Schritt 1 VorteileRichText
Schritt 1 Button TextPlainText
Schritt 1 Button LinkLink
Schritt 1 BildImage
Schritt 2 EyebrowRichText
Schritt 2 TitelRichText
Schritt 2 TextRichText
Schritt 2 VorteileRichText
Schritt 2 Button TextPlainText
Schritt 2 Button LinkLink
Schritt 2 BildImage
Schritt 3 EyebrowRichText
Schritt 3 TitelRichText
Schritt 3 TextRichText
Schritt 3 VorteileRichText
Schritt 3 Button TextPlainText
Schritt 3 Button LinkLink
Schritt 3 BildImage
Schritt 4 EyebrowRichText
Schritt 4 TitelRichText
Schritt 4 TextRichText
Schritt 4 VorteileRichText
Schritt 4 Button TextPlainText
Schritt 4 Button LinkLink
Schritt 4 BildImage
Kundenstimmen EyebrowRichText
Kundenstimmen ÜberschriftRichText
Kundenstimmen SublineRichText
Kundenstimmen AuswahlMultiReference→Testimonials
Verwandte EyebrowRichText
Verwandte ÜberschriftRichText
Verwandte SublineRichText
Verwandte FunktionenMultiReference→ERP Funktionen
Meta TitlePlainText
Meta DescriptionPlainText
OG BildImage
NoindexSwitch
Seiten – Kachel-GridMultiReference→Website Pages
Grid IconImage
Grid Icon Alt-TextPlainText
Seiten – Icon-GridMultiReference→Website Pages
Grid ReihenfolgeNumber
Nav BeschreibungPlainText
Hero ÜberschriftRichText
CTA EyebrowRichText
CTA ÜberschriftRichText
CTA SublineRichText
CTA Button 1 TextPlainText
CTA Button 1 LinkLink
CTA Button 2 TextPlainText
CTA Button 2 LinkLink

Weiterbildungen

Training courses (template)

ID 6ab23ca7f1dffd4af58850a3 · slug weiterbildungen · 22 custom fields

Why it exists: Training courses with their own page (template /weiterbildungen/[slug]).

Where it shows up: /weiterbildungen and the course template.

What to fill and how:

  • Card: Karte Beschreibung, Thumbnail, Reihenfolge. Page: Hero (eyebrow, heading, text, price, button), 3 Vorteile, SEO.

Watch out:

  • Price is text: write it exactly as it should appear.
All fields with type
FieldType
Karte BeschreibungRichText
ReihenfolgeNumber
ThumbnailImage
Thumbnail Alt-TextPlainText
Hero EyebrowRichText
Hero BeschreibungRichText
PreisRichText
Preis HinweisRichText
Hero Button TextPlainText
Hero Button LinkLink
Vorteil 1 IconImage
Vorteil 1 TitelRichText
Vorteil 1 TextRichText
Vorteil 2 IconImage
Vorteil 2 TitelRichText
Vorteil 2 TextRichText
Vorteil 3 IconImage
Vorteil 3 TitelRichText
Vorteil 3 TextRichText
Meta TitlePlainText
Meta DescriptionPlainText
Hero ÜberschriftRichText

Roadmap Zeitraum

Roadmap periods (Demnächst flag)

ID 6ab78330ceb091fbb08f8af8 · slug roadmap-zeitraum · 2 custom fields

Why it exists: The months (and "Demnächst") that group releases on /roadmap.

Where it shows up: /roadmap: the roadmap script reads the month name to sort and label.

What to fill and how:

  • Name = German month + year, e.g. "Oktober 2026"; or Demnächst with Ist Demnächst on. Reihenfolge.

Watch out:

  • The name must match the German month spelling ("März"), otherwise the release jumps to the top (see /roadmap script).
All fields with type
FieldType
ReihenfolgeNumber
Ist DemnächstSwitch

Roadmap Releases

Releases on the roadmap timeline

ID 6ab78330ceb091fbb08f8b47 · slug roadmap-releases · 8 custom fields

Why it exists: Single releases on the timeline.

Where it shows up: /roadmap (cards, chips Release Typ and Release Status, search).

What to fill and how:

  • Zeitraum, Datum (DD.MM.YYYY on the card), Termin Label, Beschreibung, Bild + Alt, Release Typ, Release Status.

Watch out:

  • Renaming the option fields changes the chip URL parameters the roadmap script expects.
All fields with type
FieldType
BeschreibungRichText
DatumDateTime
Termin LabelRichText
BildImage
Bild Alt-TextPlainText
Release TypOption
Release StatusOption
ZeitraumReference→Roadmap Zeitraum

Galerie Bilder

Culture gallery images (slider + bento)

ID 6abe04ef9593004b1921c177 · slug galerie-bilder · 6 custom fields

Why it exists: Culture images for the gallery slider and bento.

Where it shows up: Karriere / Über uns sections, assigned through Website Pages.

What to fill and how:

  • Bild + Alt-Text, Seitenverhältnis Slider, Bildfokus (which part stays visible when cropped), Reihenfolge.

Watch out:

  • Use Bildfokus instead of re-cropping the file.
All fields with type
FieldType
BildImage
Alt-TextPlainText
Seitenverhältnis SliderOption
BildfokusOption
ReihenfolgeNumber
Website PagesMultiReference→Website Pages

Team

Team members (Team page)

ID 6ac103526b141dd3f4c1bf9d · slug team · 6 custom fields

Why it exists: Team members for /team.

Where it shows up: /team (Load More script), assigned through Website Pages.

What to fill and how:

  • Position, Kurzbeschreibung, Profilbild, LinkedIn, Reihenfolge.

Watch out:

  • The page loads more people per click; the screen reader text says "Person(en)".
All fields with type
FieldType
PositionRichText
KurzbeschreibungRichText
ProfilbildImage
LinkedInLink
Website PagesMultiReference→Website Pages
ReihenfolgeNumber

E-Rechnungs Hub

E-Rechnung articles (template /e-rechnung-themen/[slug])

ID 6ac63dffa7e7347368e5d791 · slug e-rechnung-themen · 31 custom fields

Why it exists: The 14 E-Rechnung topic pages (template /e-rechnung-themen/[slug]); added on 7 Oct.

Where it shows up: /e-rechnung-themen overview and the article template.

What to fill and how:

  • Kachel: Beschreibung, Kachel Bild, Reihenfolge, Empfehlung, Button Text.
  • Article: Hero Überschrift, Kurz zusammengefasst, Definition, Artikel Inhalt (main content, real H2s), Lesezeit, Datum, CTA + Sidebar CTA, CTA Experte, Thema, Verwandte Artikel, SEO, Open Graph Bild.

Watch out:

  • Same CTA logic as Lexikon: blocks hide when their title is empty.
All fields with type
FieldType
BeschreibungRichText
Kachel BildImage
Kachel Bild Alt-TextPlainText
ReihenfolgeNumber
EmpfehlungSwitch
Button TextPlainText
ThumbnailImage
Thumbnail Alt-TextPlainText
DatumDateTime
LesezeitRichText
Kurz zusammengefasstRichText
DefinitionRichText
Artikel InhaltRichText
CTA TitelRichText
CTA BeschreibungRichText
CTA Button TextPlainText
CTA Button LinkLink
CTA BildImage
CTA Bild Alt-TextPlainText
CTA Bild LabelRichText
Sidebar CTA TitelRichText
Sidebar CTA BeschreibungRichText
Sidebar CTA Button TextPlainText
Sidebar CTA Button LinkLink
SEO TitelPlainText
SEO BeschreibungPlainText
Open Graph BildImage
ThemaMultiReference→Themen
CTA ExperteReference→Authors
Verwandte ArtikelMultiReference→E-Rechnungs Hub
Hero ÜberschriftRichText

Stellenangebote

Job posts (template /stellenangebote/[slug])

ID 6ac77dbc1ad6c967043ee912 · slug stellenangebote · 13 custom fields

Why it exists: Job posts with their own page (template /stellenangebote/[slug]); added on 8 Oct.

Where it shows up: /karriere job tiles and the job template.

What to fill and how:

  • Team, Ort switches (Detmold, Hybrid, Remote), Start / Startdatum, Anstellungsart, Aufgabenbereich, Das bringst du mit, Bewerbungs-Link, Ansprechpartner, SEO.

Watch out:

  • Unpublish filled positions instead of deleting them, so links do not break while they are still shared.
All fields with type
FieldType
TeamPlainText
Ort: DetmoldSwitch
Ort: HybridSwitch
Ort: RemoteSwitch
StartOption
StartdatumDateTime
AnstellungsartOption
Bewerbungs-LinkLink
AufgabenbereichRichText
Das bringst du mitRichText
AnsprechpartnerReference→Authors
SEO-TitelPlainText
SEO-BeschreibungPlainText
9 entries

Components

How components are organised

  • [CMS] in the name: content comes from the CMS, only eyebrow / title / description are props. Section / FAQ [CMS], Funktionen [CMS], Testimonials [CMS], Single / Testimonials [CMS], Case Studies [CMS], Customer / Logo / V2 [CMS], Customer / Logo / Category / Version [CMS], More Features [CMS].
  • [Global Component]: no props, edit inside, applies everywhere. Section / Creadibility / Bento, Section / Expand, Section / Pricing, Section / Resourcen (used 27 times). Navbar and Footer work the same way.
  • Filters are not components (Webflow cannot put filterable CMS lists in components the way we need), they are built on the page.
  • Lumos building blocks: Section (theme, padding, background slot, container), Content Wrapper, Grid, Layout, Block, Typography Eyebrow / Heading / Paragraph / Tag / Plain, Button Main (variants primary, secondary, tertiary, link + small), Button Wrapper, Visual Image / Video, Clickable (makes a parent clickable, a11y text), Card / Image / Eyebrow / Title / Description / CTA (the general card with many visibility props).
  • Utility: Starter JS / Starter CSS (unlink before use), Global Guides, Global Styles, Theme / Space / Input Switcher.

Library: Sections

  • Section / Bento
  • Section / Banner / CTA
  • Section / Banner / CTA / V2
  • Section / CTA
  • Section / CTA / Gradient
  • Section / Custom / Tabs
  • Section / Product Tour
  • Section / Process
  • Section / Trust
  • Section / Vertical
  • Section / Vertical / Header
  • Section / Header / Vertical
  • Section / Two / Column / Visual / Content
  • Section / Two / Column / Visual Lottie Loader
  • Section / Video / Slider
  • Section / Highlight / Testimonials
  • Section / Funktionen
  • Section / Legal / Header
  • Section / Pricing / Single Plan

Library: Cards

  • Card / Bento
  • Card / Testimonials
  • Card / Avatar / Ratings / Quote
  • Card / Mega Testimonials
  • Card / Metrics
  • Card / Career
  • Card / Sticky
  • Card / Video / Slide
  • Card / Ads Ons
  • Card / Upsell Features
  • Card / Alt / Pricing
  • Card / Alt / Pricing / Features
  • Card Primary

Library: Navigation & layout

  • Navbar
  • Nav / Funktionen
  • Nav / Lösungen
  • Nav / Wissen
  • Nav / Unternehmen
  • nav_dropdown_item
  • Nav Banner
  • Footer
  • Footer Group
  • Footer Link
  • breadcrumb_component
  • Sidebar / CTA / Information
  • Sidebar / Legal
  • Legal / Content
  • TOC and Social Share
  • Template / Date / Read / Time
  • CTA / Template

Library: Interactive

  • Slider
  • Slider / Navigation
  • Slider / Navigation Arrow
  • Accordion List
  • Accordion Item
  • Tab
  • Tab Link
  • Modal
  • Dropdown
  • Expand / Item
  • cg_expandable_panel
  • cg_expandable_menu_item
  • Search
  • Filter / Category / Chip
  • filter_empty_state_wrap
  • Chip
  • Chip / Icon/ Text
  • Badges
  • Ratings

Library: Pricing table

  • comparison_feature_label
  • comparison_value_cell
  • comparison_plan_cell
  • comparison_price_label
  • comparison_section_toggle
  • TR

Library: Code carriers

  • CDN / Swiper JS
  • CDN / Swiper CSS
  • JS / Filter and Load More
  • JS / Load More
  • JS / Table of Contents
  • JS / Pricing Card
  • JS / Pricing Card / Badges
  • CSS / Pricing Card
  • CSS / Hubspot
  • CSS / Hubspot / No Raw HTML
  • CSS / Filter Active Styles
  • CSS / RichText Overflow Solution
  • CSS / Legal Sidebar
  • CSS / Tooltip
  • CSS / Search Icon
  • Single Testimonial / CSS
  • Single Testimonial / JS

Example Components page (the component library)

Where: Pages → [Draft] Example Components (/example-components, page id 6a7981efc5fe5f5bfb985a53). Draft on purpose: never publish it, never delete it.

What it is: one page that holds an instance of every section component from the Figma design, with working default props and placeholder content. It is the place to see a component, copy it and paste it into a real page, and to test component changes without touching live pages.

What is on it (top to bottom): Global Styles, Navbar, Global Guides, then

  • Headers (section_header_components): Section / Vertical / Header, Vertical / Header / Simple (2 variants), Legal / Header, plus 6 more hero variants still named just "Section".
  • Global components (section_global_components): Resourcen, Pricing, Expand, Creadibility / Bento (all [Global Component]: edit once, changes everywhere).
  • Section / FAQ [CMS], Custom / Tabs, Waechst mit dir, Ergebnis-Metriken, Video / Slider, Process.
  • CTAs (section_cta): 3x Section / CTA, 2x Banner / CTA / V2, plus a container with further CTA pieces.
  • Made In Germany, Two / Column / Visual / Content, Two / Column / Image / Video / Lottie, the zig-zag sections (section_zig_zag).
  • Single / Testimonials [CMS], Testimonials [CMS], Feature / Details, Product Tour, Case Studies [CMS], Footer.

How to use it:

  1. Find the look you need here (or in Figma, then find its twin here).
  2. Select the component instance in the Navigator, copy (Cmd/Ctrl+C), go to the target page, select the section above the insert point, paste.
  3. Change the props on the right (texts, Variant, Visibility switches, links, CMS Filters for [CMS] sections). Do not unlink (detach) components.
  4. Replace every placeholder: lorem ipsum, # links, sample videos (samplelib.com), placeholder images. Rule: no # link may go live.

Still pending (Sachin, after his vacation): the curation is not finished. A few designs from Figma are not on the page yet, the 6 generic "Section" header instances still need proper names, and some instances still show placeholder content. If you add a component to the site, add one instance here too, named like the others.

Card component: the visibility props

Card / Image / Eyebrow / Title / Description / CTA is used almost everywhere (awards, sliders, grids). It switches parts on and off with props: Rich Text Title vs Simple Title Visibility, Button Visibility (e.g. hide "Mehr dazu" when there is no link), Subtext Visibility, Play Button, image Visibility, plus data-card (hover state) and cg-animation-el. When something "is missing" on a card, check these props first.

8 entries

How to (recipes)

Add a new static page

  1. Duplicate a similar existing page (keeps page_wrap / Global Styles / Navbar / Global Guides / main.page-main / Footer).
  2. Check the Body has the class u-theme-light (required on every page).
  3. Build with Section components; content inside the Section's u-container.
  4. Set SEO title, description, OG image in Page settings. Hero heading = H1, all section headings = H2.
  5. If the page shows FAQs / testimonials / logos: create a Website Pages CMS item for it and point the section's Filters prop (e.g. on Section / FAQ [CMS]) to that item. A duplicated page still points to the original page's item until you change it.
  6. Light page without dark hero: Navbar prop data-nav-theme = light.

Add a new function hub page

Pages → Static page templates → Funktionen-Hub-Template → +, fill the page details, Create (or duplicate /rechnungen). Then: create/adjust the Funktionen Hubs item (Kurzname, Icon, Nav Beschreibung, Reihenfolge, Bereichsseite Link = the new URL, Funktionen im Bereich, Mehr Funktionen Slider) and publish it. The nav dropdown and the "<" back link on its function pages pick it up automatically. Set the tab section visuals per tab (Image / Video / Lottie Visibility).

Add a new function, industry, lexikon entry, guide, job

  • Function: new item in Funktionen; set Bereich, Nav Gruppe (Kernfunktion / Weitere Funktion / Nicht in Navigation), Reihenfolge, Icon, Nav Beschreibung. It appears in the nav and on its hub automatically.
  • Industry: new item in Branchen; set Branchen Kategorie (required for the slider), Reihenfolge, Karten Bild, Slider Titel, Slider Text; add its Branchen Vorteile item(s) with the Branche reference. It shows up in every sibling page's slider automatically.
  • Lexikon: new item in Lexikon + reference its Lexikon Buchstabe and add it to that letter's Begriffe. The CTA block appears only when CTA Titel is filled.
  • Guide / Webinar / E-Rechnung article / Job: new item in the matching collection; set Thema/Format tags so filters find it.
  • Always: images AVIF in the Figma ratio, headings H2 inside rich text, then publish the item (drafts are not live).

Add a new competitor page or SEA landing page

  • Competitor: duplicate /competitor/competitor into the competitor folder, rename slug and texts, set the tab steps (image/video/Lottie per tab), the Sidebar CTA props and SEO.
  • SEA LP: duplicate an LP in the lp folder. Create a Website Pages item and switch the FAQ / testimonial sections' Filters prop to it, otherwise it shows the source page's FAQs.

Embed a HubSpot form

  1. New-editor form: HubSpot → Share → Embed code → Developer code (Advanced). Legacy form: set to raw HTML.
  2. Paste into an Embed inside the Section's container. The form CSS components (CSS / Hubspot, CSS / Hubspot / No Raw HTML) style it automatically.
  3. Form directly on a dark background: add data-hsf-surface="dark" to the wrapper.
  4. Consent text, fields and button label are set in HubSpot by orgaMAX.

Add a filter page (search + chips)

  1. Copy the filter section from /guides-vorlagen (keeps the structure and attributes) or build: section data-filter="section" → chip groups data-filter="group" + data-filter-name → chips data-filter="chip" → results data-filter="results" → items data-filter="item".
  2. Each item needs the value(s) it is filtered by in the DOM (e.g. a nested list of tags with data-filter="value").
  3. Add the JS / Filter and Load More and CSS / Filter Active Styles components once on the page.
  4. Test: chip, search with umlauts, reset, URL parameter, load more, empty state.

Add a link to the navigation or footer

Navbar and Footer are global components and mostly static on purpose. Open the component, select the link, set the URL / page. Funktionen dropdown entries come from the CMS (see Navigation). orgaMAX maintains links themselves (Tella walkthrough). Remember the 20 collection lists per page budget before making anything else in nav/footer CMS-driven.

QA checklist before calling anything done

  • Desktop, 991, 767, 375 px; no horizontal scroll.
  • Keyboard: tab through, visible focus, Escape closes menus/modals.
  • Reduced motion: animations off, content visible.
  • Headings: one H1, H2 for sections. Images: AVIF, correct ratio, alt text.
  • CMS: no "No items found" on the page (check filters / Website Pages tag / drafts).
  • Console: no errors. Animations: run the debug snippet. Filters: data-filter-ready="true".
  • Publish, then check on staging (not only in the Designer).
2 entries

Webflow gotchas

Webflow learnings worth knowing

  • Changing a field type = delete + recreate. The old slug is reserved forever, the new one gets -2. All bindings break. Back up content first.
  • Field groups: updating rewrites all groups; leaving one out deletes it.
  • A field bound in the Designer cannot be deleted until the binding is removed (fails silently).
  • Assets via API: URL only re-uploads as a new asset. Pass fileId and url to reuse.
  • Navigator eye icon only hides on canvas. Settings → Visibility Hidden removes it from the published HTML.
  • Lumos .u-rich-text is on every Typography element. Never style it globally, use .u-rich-text-content.
  • The API cannot create Collection Lists or bind links / references to some targets. Those are Designer jobs.
  • Draft items are never live. Publishing a draft-heavy collection pushes half-finished content live too.
  • Duplicated pages keep their Collection List filters (e.g. Website Page = Paid Social). Change the filter on the copy.
  • Single page publishing needs Enterprise features; normally publish the whole site.
  • Playwright headless Chromium cannot decode H.264 MP4: convert test videos to WebM.

Known technical debt and risks

  • Heavy Lotties left: Passt sich Deinem Unternehmen an.json (2.3 MB), funktionenhero.json (1.5 MB); old tab Lotties (8.6 MB etc.) stay until orgaMAX replaces the tab visuals on hubs / competitor pages (#88).
  • Collection list budget: nav uses 3 of 20 per page; data-heavy pages (hubs, Branchen template) are close to the limit. Count before adding lists.
  • Finsweet leftovers: some markup still carries fs-cmsfilter-* attributes; harmless without the Finsweet script, remove when touched.
  • Funktionen and ERP Funktionen have 90 fields each (near Webflow's limit); add fields carefully.
  • Template schema uses CMS placeholders: if a Name ever contains a double quote, the JSON-LD breaks for that item. Avoid quotes in names.
  • Fixed 11 Oct: TOC items are real links on every template, component and competitor page.
  • Tabs CSS exists twice (old CSS embed + newer copy inside the JS embed of Section / Custom / Tabs). Edit the JS-embed copy; remove the old one when touched.
  • Comparison table markup is invalid HTML (div inside tr); the script repairs it at runtime. Fixing the row component would make the repair a no-op.
  • Intentional class-name typos are in use: roadmap_zeitrum_date, u-botton-slider-navigation, data-vertical-tabet-below, comparision_feature_*. Scripts depend on them: do not "correct" them.
  • Drafts: 30 Branchen were published on 10 Oct to make the slider work; orgaMAX was told to set unfinished ones back to Draft.
3 entries

Claude, MCP & tools

Connect Claude to the project

Most of this project was built with Claude (claude.ai Project Orgamax) using MCP connectors. To get the same setup:

  1. Join the Claude Project "Orgamax" (ask Yannik). It holds the project memory and standards.
  2. In Settings → Connectors enable: Webflow (Data API + Designer bridge), Figma, Google Sheets / Drive, Slack, Pastel, ClickUp.
  3. For Designer actions (select element, switch page), open the Webflow Designer MCP Bridge App inside the Designer and keep that tab in front.
  4. Add the orgaMAX skill (file delivered with this guide) so Claude follows the project rules automatically.

What Claude can and cannot do here

Can (API)Cannot (do it in the Designer)
CMS: create fields, items, update, publishCreate Collection Lists, change a list's source
Component props, static values, many bindingsBind links to references, conditional visibility
Styles and classes, element attributesCreate new component props
Page settings, SEO, scripts in head/footerRead embed code (copy it manually)
Google Sheet comments, Slack readingAnything behind a login (live checks need your browser console)

Useful console checks

// Which filters / scripts are on this page?
console.log({
  filters: document.querySelectorAll('[data-filter="section"]').length,
  filterReady: [...document.querySelectorAll('[data-filter="section"]')].map(s => s.dataset.filterReady),
  animTriggers: document.querySelectorAll('[cg-animation-trigger]').length,
  swiper: typeof window.Swiper, gsap: typeof window.gsap,
  pricing: typeof window.orgamaxPricing, nav: typeof window.orgaMaxNav,
  navStack: getComputedStyle(document.documentElement).getPropertyValue('--nav-stack-height')
});

Nothing matches this search and topic combination.