@conciso/design-system-mcp 0.0.0-bootstrap.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/bin/cds-mcp.mjs +9 -0
- package/package.json +48 -0
- package/snapshot/manifests/components.json +617 -0
- package/snapshot/manifests/docs.json +293 -0
- package/snapshot/services/addon-docs/mdx/beispielseiten-/303/274bersicht--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-barrierefreiheit--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-design-tokens--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-einrichtung--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-elevation--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-icons--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-responsive--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/grundlagen-spacing-grid--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-buchungsformular--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-buttons--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-call-to-action--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-cards-teaser--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-chips-badges-pills--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-code-block--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-dropdowns--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-feedback--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-footer--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-hero--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-inputs-forms--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-navigation--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-sektion--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-slider-carousel--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-tabelle--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-theme-umschalter--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/komponenten-zitate-testimonials--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/marke-bildsprache--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/marke-brand-areas--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/marke-logo--verwendung.json +18 -0
- package/snapshot/services/addon-docs/mdx/marke-markenrad--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/referenzen-quellen--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/seitenmuster-angebots-detailseite--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/seitenmuster-beitrags/303/274bersicht--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/seitenmuster-seminar-/302/267-training--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/seitenmuster-veranstaltung--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/seitenmuster-veranstaltungs/303/274bersicht--/303/274bersicht.json +18 -0
- package/snapshot/services/addon-docs/mdx/seitenmuster-wissensbeitrag--/303/274bersicht.json +18 -0
- package/snapshot/services/core/docgen/grundlagen-farben.json +3 -0
- package/snapshot/services/core/docgen/grundlagen-typografie.json +3 -0
- package/snapshot/services/core/docgen/komponenten-buttons-button.json +183 -0
- package/snapshot/services/core/docgen/komponenten-call-to-action-cta-band.json +131 -0
- package/snapshot/services/core/docgen/komponenten-call-to-action-downloadcta.json +182 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-card.json +146 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-feature-liste.json +128 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-featured-karte.json +158 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-icon-karte.json +111 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-klickbare-karte.json +161 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-statcard.json +115 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-statstrip.json +58 -0
- package/snapshot/services/core/docgen/komponenten-cards-teaser-tier-trenner.json +56 -0
- package/snapshot/services/core/docgen/komponenten-chips-badges-pills-bereichs-badge.json +63 -0
- package/snapshot/services/core/docgen/komponenten-chips-badges-pills-chip.json +95 -0
- package/snapshot/services/core/docgen/komponenten-chips-badges-pills-pill.json +78 -0
- package/snapshot/services/core/docgen/komponenten-chips-badges-pills-status-badge.json +63 -0
- package/snapshot/services/core/docgen/komponenten-code-block-code-block.json +91 -0
- package/snapshot/services/core/docgen/komponenten-dropdowns-combobox.json +224 -0
- package/snapshot/services/core/docgen/komponenten-dropdowns-custom-select.json +173 -0
- package/snapshot/services/core/docgen/komponenten-feedback-snackbar.json +97 -0
- package/snapshot/services/core/docgen/komponenten-footer-komplett.json +21 -0
- package/snapshot/services/core/docgen/komponenten-footer-oberer-teil.json +39 -0
- package/snapshot/services/core/docgen/komponenten-footer-unterer-teil.json +105 -0
- package/snapshot/services/core/docgen/komponenten-hero-hero-bild.json +162 -0
- package/snapshot/services/core/docgen/komponenten-hero-st/303/266rer.json +41 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-auswahlfeld.json +192 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-checkbox.json +182 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-radio.json +181 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-skala.json +179 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-slider.json +259 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-textbereich.json +190 -0
- package/snapshot/services/core/docgen/komponenten-inputs-forms-textfeld.json +207 -0
- package/snapshot/services/core/docgen/komponenten-navigation-topnav.json +186 -0
- package/snapshot/services/core/docgen/komponenten-sektion-sektion.json +113 -0
- package/snapshot/services/core/docgen/komponenten-slider-carousel-carousel.json +92 -0
- package/snapshot/services/core/docgen/komponenten-slider-carousel-logocarousel.json +92 -0
- package/snapshot/services/core/docgen/komponenten-tabelle-tabelle.json +74 -0
- package/snapshot/services/core/docgen/komponenten-tabelle-vergleichstabelle.json +142 -0
- package/snapshot/services/core/docgen/komponenten-theme-umschalter-cycle-button.json +41 -0
- package/snapshot/services/core/docgen/komponenten-theme-umschalter-dropdown.json +41 -0
- package/snapshot/services/core/docgen/komponenten-theme-umschalter-segment.json +41 -0
- package/snapshot/services/core/docgen/komponenten-zitate-testimonials-blockquote.json +96 -0
- package/snapshot/services/core/docgen/komponenten-zitate-testimonials-teamvoice.json +130 -0
- package/snapshot/services/core/docgen/komponenten-zitate-testimonials-testimonial.json +96 -0
- package/snapshot/services/core/docgen/marke-brand-areas-areatabs.json +75 -0
- package/snapshot/services/core/docgen/marke-logo-logo.json +71 -0
- package/snapshot/services/core/docgen/seitenmuster-seminar-/302/267-training-fakten-liste.json +79 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-article-header.json +196 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-author-card.json +91 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-avatar.json +100 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-callout.json +64 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-faq.json +41 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-figure.json +73 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-inhaltsverzeichnis.json +75 -0
- package/snapshot/services/core/docgen/seitenmuster-wissensbeitrag-pull-quote.json +63 -0
- package/snapshot/services/core/story-docs/grundlagen-farben.json +19 -0
- package/snapshot/services/core/story-docs/grundlagen-typografie.json +25 -0
- package/snapshot/services/core/story-docs/komponenten-buttons-button.json +48 -0
- package/snapshot/services/core/story-docs/komponenten-call-to-action-cta-band.json +27 -0
- package/snapshot/services/core/story-docs/komponenten-call-to-action-downloadcta.json +17 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-card.json +37 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-feature-liste.json +37 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-featured-karte.json +36 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-icon-karte.json +41 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-klickbare-karte.json +26 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-statcard.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-statstrip.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-cards-teaser-tier-trenner.json +22 -0
- package/snapshot/services/core/story-docs/komponenten-chips-badges-pills-bereichs-badge.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-chips-badges-pills-chip.json +27 -0
- package/snapshot/services/core/story-docs/komponenten-chips-badges-pills-pill.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-chips-badges-pills-status-badge.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-code-block-code-block.json +26 -0
- package/snapshot/services/core/story-docs/komponenten-dropdowns-combobox.json +37 -0
- package/snapshot/services/core/story-docs/komponenten-dropdowns-custom-select.json +37 -0
- package/snapshot/services/core/story-docs/komponenten-feedback-snackbar.json +27 -0
- package/snapshot/services/core/story-docs/komponenten-footer-komplett.json +22 -0
- package/snapshot/services/core/story-docs/komponenten-footer-oberer-teil.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-footer-unterer-teil.json +32 -0
- package/snapshot/services/core/story-docs/komponenten-hero-hero-bild.json +37 -0
- package/snapshot/services/core/story-docs/komponenten-hero-st/303/266rer.json +26 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-auswahlfeld.json +32 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-checkbox.json +32 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-radio.json +32 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-skala.json +42 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-slider.json +37 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-textbereich.json +27 -0
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-textfeld.json +32 -0
- package/snapshot/services/core/story-docs/komponenten-navigation-topnav.json +26 -0
- package/snapshot/services/core/story-docs/komponenten-sektion-sektion.json +41 -0
- package/snapshot/services/core/story-docs/komponenten-slider-carousel-carousel.json +31 -0
- package/snapshot/services/core/story-docs/komponenten-slider-carousel-logocarousel.json +27 -0
- package/snapshot/services/core/story-docs/komponenten-tabelle-tabelle.json +36 -0
- package/snapshot/services/core/story-docs/komponenten-tabelle-vergleichstabelle.json +32 -0
- package/snapshot/services/core/story-docs/komponenten-theme-umschalter-cycle-button.json +31 -0
- package/snapshot/services/core/story-docs/komponenten-theme-umschalter-dropdown.json +26 -0
- package/snapshot/services/core/story-docs/komponenten-theme-umschalter-segment.json +26 -0
- package/snapshot/services/core/story-docs/komponenten-zitate-testimonials-blockquote.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-zitate-testimonials-teamvoice.json +21 -0
- package/snapshot/services/core/story-docs/komponenten-zitate-testimonials-testimonial.json +21 -0
- package/snapshot/services/core/story-docs/marke-brand-areas-areatabs.json +26 -0
- package/snapshot/services/core/story-docs/marke-logo-logo.json +23 -0
- package/snapshot/services/core/story-docs/seitenmuster-seminar-/302/267-training-fakten-liste.json +21 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-article-header.json +37 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-author-card.json +31 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-avatar.json +32 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-callout.json +26 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-faq.json +27 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-figure.json +22 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-inhaltsverzeichnis.json +27 -0
- package/snapshot/services/core/story-docs/seitenmuster-wissensbeitrag-pull-quote.json +21 -0
- package/src/instructions.mjs +38 -0
- package/src/server.mjs +111 -0
- package/src/version-check.mjs +80 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-navigation--verwendung": {
|
|
4
|
+
"id": "komponenten-navigation--verwendung",
|
|
5
|
+
"name": "komponenten-navigation--verwendung",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-navigation--verwendung": {
|
|
8
|
+
"id": "komponenten-navigation--verwendung",
|
|
9
|
+
"name": "Verwendung",
|
|
10
|
+
"path": "./src/docs/komponenten/navigation-verwendung.mdx",
|
|
11
|
+
"title": "Komponenten/Navigation",
|
|
12
|
+
"content": "import { Meta, Unstyled } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Navigation\" name=\"Verwendung\" tags={['angular']} />\n\n# Verwendung\n\nNavigation führt drei Elemente: Topnav, Breadcrumb und Back-to-Top-Button. Nur die\nTopnav hat ein eigenes Bauteil (Story `Topnav`); Breadcrumb und Back-to-Top sind\nCSS-Rezepte ohne Angular-Komponente.\n\n## Wann welches Element\n\n| Element | Bauteil | Wann einsetzen |\n|---|---|---|\n| Topnav | Story `Topnav` | Auf jeder Customer-Page als persistente Kopfzeile: Logo, vier Top-Items, Kontakt-CTA |\n| Breadcrumb | bauteillos (CSS-Rezept `.article-breadcrumb`) | Auf Unterseiten ab der zweiten Ebene, zeigt den Pfad von der Startseite zur aktuellen Seite |\n| Back-to-Top-Button | bauteillos (CSS-Rezept `.back-to-top`) | Auf jeder Customer-Page, sticky unten rechts, erscheint ab `scrollY > 400px` |\n\n## Topnav: Aufbau\n\n| Element | Regel |\n|---|---|\n| Logo | Immer ganz links, immer sichtbar, Verlässlichkeit in der ersten Sekunde |\n| Top-Items | Vier Einträge: Angewandte KI · Leistungen · Wissen · Unternehmen. „Angewandte KI“, „Leistungen“ und „Unternehmen“ sind Links zur jeweiligen Übersicht mit aufklappbarem Submenü über einen separaten Caret-Button, „Wissen“ ist ein einfacher Link ohne Submenü. Aktiver Eintrag über `aria-current=\"page\"` |\n| CTA-Button | Genau ein Outlined-Button, Label „Kontakt“, Brand-Petrol (`--co-700`), ganz rechts über `margin-left:auto` |\n| Layout und Hintergrund | `.ep-topnav` mit `--bg-surface`, `border-bottom:var(--bd)`, Padding `var(--s4) var(--s8)` (rund 64 px hoch). Ein `gap`-basierter Flow (kein `justify-content`) hält die Nav am Logo, der CTA wird per `margin-left:auto` nach rechts gedrückt, das Layout bleibt stabil, egal wie viele Nav-Items dazukommen |\n\nDas Schema zeigt den Nav-Bar-Wireframe und darunter die zugehörige Callout-Zeile mit den\nnummerierten Hinweisen ①②③ zu Logo, Top-Items und Kontakt-Button.\n\n<Unstyled>\n <div style={{ border: 'var(--bd-strong)', borderRadius: 'var(--r-lg)', overflow: 'hidden', marginBottom: 'var(--s8)' }}>\n {/* Nav-Bar-Schema */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--s4)',\n padding: '0 var(--s6)',\n height: '64px',\n background: 'var(--bg-surface)',\n borderBottom: 'var(--bd)',\n }}\n >\n <div\n style={{\n background: 'var(--co-700)',\n borderRadius: 'var(--r-xs)',\n padding: '3px 10px',\n font: '700 12px/16px var(--font)',\n color: '#fff',\n flexShrink: 0,\n }}\n >\n Logo\n </div>\n <div style={{ display: 'flex', gap: 'var(--s5)', flex: 1, alignItems: 'center' }}>\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 'var(--s1)',\n font: '400 12px/16px var(--font)',\n color: 'var(--tx-secondary)',\n }}\n >\n Angewandte KI <span style={{ opacity: 0.5 }}>▾</span>\n </div>\n <div\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 'var(--s1)',\n font: '400 12px/16px var(--font)',\n color: 'var(--tx-secondary)',\n }}\n >\n Leistungen <span style={{ opacity: 0.5 }}>▾</span>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)' }}>Wissen</div>\n <div\n className=\"t-co\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 'var(--s1)',\n font: '600 12px/16px var(--font)',\n }}\n >\n Unternehmen <span style={{ opacity: 0.5 }}>▾</span>\n </div>\n </div>\n <div\n className=\"t-co\"\n style={{\n border: '1.5px solid var(--co-700)',\n borderRadius: 'var(--r-full)',\n padding: '2px 12px',\n font: '600 12px/16px var(--font)',\n flexShrink: 0,\n }}\n >\n Kontakt\n </div>\n </div>\n {/* Callout-Zeile zur Nav */}\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 'var(--s4)',\n padding: 'var(--s3) var(--s6)',\n background: 'var(--bg-overlay)',\n }}\n >\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-muted)', flexShrink: 0, width: '80px' }}>\n ① Logo<br />immer links\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-muted)', flex: 1 }}>\n ② Top-Items · 4 Einträge · „Angewandte KI“, „Leistungen“ und „Unternehmen“ mit aufklappbarem Submenü,\n „Wissen“ ohne · aktiver Eintrag in\n Brand-Petrol via <code className=\"token\" style={{ fontSize: '12px' }}>aria-current=\"page\"</code>\n </div>\n <div\n style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-muted)', flexShrink: 0, textAlign: 'right' }}\n >\n ③ Outlined „Kontakt“<br />ganz rechts\n </div>\n </div>\n </div>\n</Unstyled>\n\n**Aktiv-Markierung:** Aktiver Punkt über `aria-current=\"page\"` ausgezeichnet und\nzusätzlich durch einen nicht-farbigen Indikator bestätigt: Top-Level-Links tragen einen\ndezenten Akzent-Unterstrich, Submenü-Einträge eine Tönungsfläche (`--co-50`) plus\nFettung. Die Markierung hängt also nie allein an der Farbe (WCAG 1.4.1). Nur Hover und\ndas bloße Aufklappen markieren ausschließlich über Farbe und Caret-Drehung, den\nUnterstrich gibt es allein im Aktiv-Zustand.\n\n## Topnav-Dropdowns: Disclosure-Pattern\n\nJedes Top-Item mit Submenü besteht aus zwei getrennten Bedienelementen: dem Label-Link\n(`.ep-nav-btn`, ein echtes `<a>`), der direkt zur Übersichtsseite navigiert, und einem\nseparaten Caret-Button (`.ep-nav-item-toggle`), der ausschließlich das Submenü öffnet\nund schließt. Es ist ein Disclosure-Pattern aus Links, kein Menü-Widget, deshalb bewusst\nohne `aria-haspopup`.\n\n- `aria-expanded` (`true`/`false`) und `aria-controls` sitzen auf dem Caret-Button; die JS-Klasse `.is-open` markiert das geöffnete `.ep-nav-has-sub`.\n- Geöffnet wird per Klick/Tap, Tastatur (`Enter`/`Space` auf dem Caret) oder, nur auf Geräten mit echtem Hover (`pointer:fine`), per Hover (JS-gesteuert mit Intent-Verzögerung und unsichtbarer Brücke über den Gap, WCAG 1.4.13).\n- Pfeiltasten (`↓`/`↑`) sowie `Home`/`End` navigieren die Einträge innerhalb des geöffneten Submenüs.\n- `Escape` schließt das Submenü und gibt den Fokus auf den Caret zurück; ein Klick außerhalb, das Heraustabben oder eine Navigation schließen ebenfalls.\n- **Kein reines CSS-`:hover`-Öffnen:** Der Reveal hängt immer an `.is-open`, damit `aria-expanded` mitläuft.\n- **Nie zwei Menüs gleichzeitig offen:** Vor jedem Öffnen ruft das JS `closeAllNavItems`.\n- Der Label-Link navigiert unverändert direkt zur Übersicht, nur der Caret-Button klappt auf; ein Klick auf das Label öffnet oder schließt kein Menü.\n- Mobil (ab 760 px und darunter): ein Hamburger-Button wird injiziert, Submenüs öffnen dort inline statt als schwebendes Overlay.\n- Der Caret-Button hat eine eigene Hit-Area ≥ 24 px (WCAG 2.5.8); mobil liegen Label und Caret in einer Zeile mit ≥ 44 px Tap-Fläche.\n\n## Breadcrumb\n\nAuf Unterseiten (zweite Ebene und tiefer) sitzt über dem Inhalt eine Breadcrumb-Leiste\n(`.article-breadcrumb`). Sie zeigt den Pfad von der Startseite bis zur aktuellen Seite;\ndas letzte Element ist die aktuelle Seite, trägt `aria-current=\"page\"` und ist kein\nLink.\n\n| Aspekt | Regel |\n|---|---|\n| Hülle | Eigene `.ep-section` mit `padding-block:var(--s5)` und `--bg-surface`, direkt unter der Topnav; das `<nav>` mit `margin-bottom:0` |\n| Ausrichtung | Immer linksbündig, auch auf redaktionellen Seiten (Wissensbeitrag, Stellen-Detail). Titel und Lead dürfen darunter zentriert sein, der Breadcrumb bleibt links |\n| Pfad | Startseite → … → aktuelle Seite; Trenner `.article-breadcrumb-sep` (dekorativ, `aria-hidden`); letztes Element `aria-current=\"page\"`, ohne Link |\n| Nicht | Den Breadcrumb nicht in einen zentrierten `.article-header` einbetten, sonst wird er mittig ausgerichtet und bekommt einen abweichenden Abstand zur Nav |\n\n## Back-to-Top-Button\n\nGlobaler Page-Button, der nach `scrollY > 400px` sanft eingeblendet wird und beim Klick\nsmooth zum Seitenanfang scrollt. Sitzt sticky unten rechts (`position:fixed`), damit er\nauf langen Seiten ohne Scrollen erreichbar bleibt; typischer Anwendungsfall:\nWissensbeiträge, Bereichsseiten, Listen-Übersichten. Gehört auf jede Customer-Page, auch\nLanding-Pages, Detailseiten und Beispielartikel.\n\n- `aria-label=\"Nach oben scrollen\"`, der reine Caret-Icon-Button braucht eine textuelle Beschriftung.\n- `type=\"button\"`, verhindert Submit-Verhalten in einem Form-Kontext.\n- Tastatur: per `Tab` erreichbar, `Enter`/`Space` löst aus, keine zusätzliche ARIA-Rolle nötig (natives `<button>`).\n- Reduced Motion: bei `prefers-reduced-motion: reduce` springt die Seite ohne Smooth-Scroll-Animation an den Anfang (WCAG 2.3.3).\n- Touch-Target: 44×44 px erfüllt WCAG 2.5.5 (Target Size).\n- Fokus-Ring: `var(--focus-ring)` bei Tastaturfokus, sichtbar gegen den weißen Hintergrund und gegen farbige Inhalte.\n\n## Barrierefreiheit\n\n| Aspekt | Regel |\n|---|---|\n| Semantik | `<nav>` mit `aria-label=\"Hauptnavigation\"`, wenn mehrere Navigationsbereiche auf einer Seite stehen, listen Screenreader alle Landmarks auf |\n| Aktiver Eintrag | `aria-current=\"page\"` auf dem aktiven Nav-Link setzen, der visuelle Active-State allein ist für Screenreader nicht erkennbar |\n| Tastatur | Alle Nav-Items per `Tab`; `Enter`/`Space` öffnet das Submenü; `↓`/`↑` und `Home`/`End` navigieren die Einträge; `Esc` schließt (Fokus zurück zum Toggle), vollständig ohne Maus bedienbar |\n| Dropdown-Zustand | Das Label ist ein `<a>`-Link zur Übersicht; ein separater Caret-`<button>` trägt per JS `aria-expanded` und `aria-controls` auf das Submenü (Disclosure aus Links, kein Menü-Widget, daher kein `aria-haspopup`); geöffnet wird per Klick/Tastatur und, additiv nur auf `pointer:fine`, per Hover (JS-gesteuert über `.is-open`, nie rein per CSS-`:hover`) |\n| Skip-Link | „Zum Inhalt springen“-Link als erstes fokussierbares Element, ermöglicht Tastaturnutzern das Überspringen langer Navigationen |\n\n## Dos & Don'ts\n\n**Tun**\n\n- Aktiven Eintrag über `aria-current=\"page\"` und zusätzlich einen nicht-farbigen Indikator markieren (Unterstrich beziehungsweise Tönungsfläche plus Fettung), nie nur über Farbe (WCAG 1.4.1)\n- Genau einen Outlined-Kontakt-Button ganz rechts, per `margin-left:auto` vom Nav-Flow abgesetzt\n- Label-Link und Caret-Button als getrennte Bedienelemente führen: Label navigiert, Caret klappt auf\n- Breadcrumb immer linksbündig setzen, auch wenn Titel und Lead darunter zentriert sind\n- Back-to-Top auf jeder Customer-Page einbinden, inklusive Fallback auf einen Hard-Jump bei `prefers-reduced-motion`\n\n**Nicht tun**\n\n- Dropdown-Menüs rein über CSS `:hover` öffnen, nicht per Tastatur erreichbar; `aria-expanded` für den Toggle nutzen\n- Vom IA-Schema (Angewandte KI · Leistungen · Wissen · Unternehmen plus Kontakt) abweichen oder zusätzliche Top-Items ergänzen, das verwässert die Customer-Page-Navigation\n- Breadcrumb in einen zentrierten `.article-header` einbetten, sonst verschiebt sich seine Ausrichtung\n- Zwei Submenüs gleichzeitig offen lassen, vor jedem Öffnen muss das vorherige schließen\n- Back-to-Top ohne `aria-label` oder ohne Fallback bei `prefers-reduced-motion` ausliefern\n\n## Verwandte Seiten\n\n- Komponenten/Navigation/Topnav\n- Komponenten/Hero (Zusammenspiel von Topnav und Hero)\n",
|
|
13
|
+
"summary": "# Verwendung Navigation führt drei Elemente: Topnav, Breadcrumb und Back-to-Top-Button. Nu..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-sektion--übersicht": {
|
|
4
|
+
"id": "komponenten-sektion--übersicht",
|
|
5
|
+
"name": "komponenten-sektion--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-sektion--übersicht": {
|
|
8
|
+
"id": "komponenten-sektion--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/komponenten/sektion.mdx",
|
|
11
|
+
"title": "Komponenten/Sektion",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Sektion\" name=\"Übersicht\" />\n\n# Sektion\n\nDas strukturelle Gerüst, in dem auf den Beispielseiten praktisch jeder andere\nBaustein sitzt: `.ep-section` mit dem optionalen Kopf-Trio aus Kicker, Überschrift\nund Lead. 133 Vorkommen in den Beispielseiten, 85 davon mit Kopfzeile. Das\nAngular-Bauteil ist `Komponenten/Sektion/Sektion` (`[cdsSection]`).\n\nQuelle: `docs/index.html#sec-section`.\n\n## Aufbau\n\nDrei Klassen bilden den Kopf: `.ep-section-label` (Kicker, bereichsfärbbar über\n`.t-co` / `.t-ki` / `.t-es` / `.t-wo`), `.ep-section-h2` (Überschrift) und\n`.ep-section-sub` (Lead). Alle drei sind Beiwerk: Eine Sektion besteht auch ganz\nohne Kopf, nur aus ihrem Inhalt darunter.\n\n```html\n<div class=\"ep-section\" style=\"background:var(--n-50)\">\n <div class=\"ep-section-label t-co\">Was wir tun</div>\n <h2 class=\"ep-section-h2\">So ist eine Sektion aufgebaut.</h2>\n <p class=\"ep-section-sub\">Kicker, Überschrift und Lead sind Beiwerk, der Inhalt darunter ist frei.</p>\n <!-- beliebiger Inhalt -->\n</div>\n```\n\n## Angular-Wrapper\n\n`[cdsSection]` ist ein Attributselektor statt eines eigenen Elements\n(`docs/adr/0008-selektortyp-der-wrapper-komponenten.md`). Der\nKonsument wählt das Tag: `<section cdsSection>` oder `<div cdsSection>`. Die\nKomponente setzt `aria-labelledby`, wenn ein zugänglicher Name verfügbar ist:\nentweder die eigene Überschrift oder eine per `labelledBy` übergebene id einer\nÜberschrift außerhalb der Komponente. Fehlt beides, setzt sie kein\n`aria-labelledby`.\n\n## Verwendung\n\nDie Fläche gehört der Seite, nicht dem Bauteil. Sektionen wechseln im Rhythmus\nzwischen `--bg-surface` und `--n-50`, auf einzelnen Sektionsflächen kommt\nzusätzlich eine Bereichstönung als Akzent vor. Welche Fläche eine Sektion trägt,\nhängt von ihren Nachbarn ab, und nur die Seite kennt diese Nachbarn. Deshalb setzt\n`.ep-section` selbst keinen Hintergrund, und `[cdsSection]` hat keinen\n`background`-Input: Die Fläche kommt per Klasse oder Inline-Style direkt an das\nElement, das `cdsSection` trägt (`<section cdsSection style=\"background:…\">`).\n",
|
|
13
|
+
"summary": "# Sektion Das strukturelle Gerüst, in dem auf den Beispielseiten praktisch jeder andere Ba..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-slider-carousel--verwendung": {
|
|
4
|
+
"id": "komponenten-slider-carousel--verwendung",
|
|
5
|
+
"name": "komponenten-slider-carousel--verwendung",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-slider-carousel--verwendung": {
|
|
8
|
+
"id": "komponenten-slider-carousel--verwendung",
|
|
9
|
+
"name": "Verwendung",
|
|
10
|
+
"path": "./src/docs/komponenten/slider-verwendung.mdx",
|
|
11
|
+
"title": "Komponenten/Slider & Carousel",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Slider & Carousel\" name=\"Verwendung\" tags={['angular']} />\n\n# Verwendung\n\nSlider & Carousel führt zwei getrennte Formen: das Bild-Carousel zur Seiten-Integration\n(Story `Carousel`) und das Kundenlogo-Karussell (Story `LogoCarousel`) als CSS-Laufband.\nBeide sind WCAG 2.1 AA konform und respektieren `prefers-reduced-motion`. Die\nSlider-Hero-Variante für den Seitenkopf ist unter Komponenten/Hero dokumentiert.\n\n## Bild-Carousel · Verwendung\n\nEingebettet in Seiteninhalt, maximal 780 px breit, abgerundete Ecken (16:9). Caption\nerscheint unterhalb des Bildes auf weißem Grund, keine Modifier-Klasse nötig, nur die\nBasis-Klasse `.img-slider`. Übergang per Crossfade über 600 ms; unter\n`prefers-reduced-motion: reduce` entfällt die Transition automatisch.\n\n### Barrierefreiheit & ARIA\n\n| Attribut | Zweck |\n|---|---|\n| `role=\"region\"` | Semantischer Landmark für den gesamten Slider |\n| `aria-roledescription` | „Bildschirmpräsentation“, Screenreader liest den Typ vor |\n| `role=\"group\"` auf Slide | Fasst Bild und Caption je Folie zusammen |\n| `aria-hidden=\"true\"` | Inaktive Slides werden übersprungen (setzt JS) |\n| `aria-label` auf Button | „Vorherige / Nächste Folie“, kein Icon-only |\n| `role=\"tablist\"` Dots | Dot-Navigation als Tab-Gruppe, bekanntes Tastatur-Pattern |\n\n| Taste | Funktion |\n|---|---|\n| ← | Vorherige Folie |\n| → | Nächste Folie |\n| Tab | Fokus auf Prev/Next-Button oder Dot |\n| Enter / Space | Dot oder Button aktivieren |\n\n### Dos & Don'ts\n\n**Tun**\n\n- Immer aussagekräftiges `alt`-Attribut bei echten Bildern, kein `alt=\"\"` bei inhaltlichen Fotos\n- Caption für jede Folie, gibt dem Inhalt auch ohne Bild ausreichend Kontext\n- Bilder mit `object-fit: cover` und fester Höhe einsetzen, verhindert Layout-Sprünge beim Laden\n\n**Nicht tun**\n\n- Kein Auto-Play ohne Pause-Button, WCAG 2.1 Kriterium 2.2.2 verbietet unkontrollierte Bewegung\n- Mehr als 6 bis 7 Slides, Nutzende verlieren die Orientierung, lieber eine separate Galerie verwenden\n- Kartentypen oder Seitenverhältnisse innerhalb eines Carousels mischen, einheitliche Bildgröße halten\n\n## Kundenlogo-Karussell · Verwendung\n\nDiskrete Sets von je 5 Logos, die alle 6 Sekunden per Crossfade wechseln. Pausiert\nautomatisch bei Hover und Tastatur-Fokus, zusätzlich manueller Pause-Button (WCAG\n2.2.2). Pagination-Dots erlauben gezieltes Springen, Tastatur-Navigation über Pfeil-,\nHome- und End-Taste. Die Logos sitzen randlos auf einer hellen Platte (`--bg-plate`),\ndie in beiden Themes hell bleibt, weil Kundenlogos meist nur in einer farbigen\nbeziehungsweise dunklen Fassung ohne Dark-Variante vorliegen. Kein Hover-Effekt, da die\nLogos nicht verlinkt sind, ein Lift würde fälschlich Klickbarkeit suggerieren.\n\n### Barrierefreiheit\n\n| Attribut | Zweck |\n|---|---|\n| `role=\"region\"` + `aria-roledescription` | Semantischer Landmark mit Karussell-Hinweis für Screenreader |\n| `aria-hidden` | Inaktive Sets werden Screenreader-seitig ausgeblendet, nur das sichtbare Set wird vorgelesen |\n| `role=\"group\"` pro Set | Logos als Gruppe gebündelt mit eigenem `aria-label` („Set 1 von 2“) |\n| `role=\"tablist\"` + `role=\"tab\"` | Pagination-Dots als Tab-Pattern, `aria-selected` markiert das aktive Set, Roving-Tabindex |\n| `aria-pressed` auf Pause-Button | Toggle-State (pausiert / läuft) für Screenreader hörbar |\n| Tastatur-Navigation | Pfeil-Tasten wechseln Sets, Home / End springen zum ersten / letzten Set, Pause via Space oder Enter |\n| `prefers-reduced-motion` | Auto-Rotation und Crossfade deaktiviert, Set 1 bleibt statisch sichtbar, Dots bleiben nutzbar |\n\n### Dos & Don'ts\n\n**Tun**\n\n- Genau 5 Logos pro Set, gleiche Anzahl in allen Sets für gleichmäßiges Grid\n- Logos als SVG einbinden, skalieren verlustfrei auf jede Displaydichte\n- Einheitliche Tile-Höhe (72 px), unterschiedliche Logo-Proportionen über `object-fit: contain` angleichen\n- Pro Set eine eindeutige `id` für die `aria-controls`-Verknüpfung der Dots\n\n**Nicht tun**\n\n- Keine Kundennamen in bunten Markenfarben, Logos einheitlich grau oder schwarz halten\n- Mehr als 3 Sets vermeiden, ab 4 Sets wird die Pagination unübersichtlich und wirkt zu werblich\n- Intervall unter 5 Sekunden setzen, gibt Lesenden keine Zeit, ein Logo aufzunehmen\n\n## Bewegungs-Anforderung (prefers-reduced-motion)\n\nDie globale Barrierefreiheits-Sektion (Grundlagen/Barrierefreiheit) hält für\n`prefers-reduced-motion: reduce` die Basisregel fest: `animation-duration`,\n`transition-duration` und `scroll-behavior` fallen auf `0.01ms` beziehungsweise `auto`\nzurück (WCAG 2.3.3 AAA). Für die beiden Karussell-Typen gilt zusätzlich:\n\n- **Bild-Carousel:** die Crossfade-Transition (600 ms) entfällt automatisch, keine gesonderte Handhabung im Markup nötig.\n- **Kundenlogo-Karussell:** bei aktiver Reduktion bleibt das erste Set sichtbar, ohne Auto-Wechsel; die Pagination-Dots bleiben bedienbar.\n\nVon der Ausnahme unberührt bleibt der 2-Pixel-Hover-Lift auf klickbaren Karten und dem\nStörer: Er läuft auch unter `prefers-reduced-motion: reduce` weiter, weil er reine\nKlickbarkeit signalisiert. Auto-Bewegung ist davon getrennt zu betrachten, nur sie\nrespektieren die Carousels.\n\n## Verwandte Seiten\n\n- Komponenten/Slider & Carousel/Carousel\n- Komponenten/Slider & Carousel/LogoCarousel\n- Komponenten/Hero (Slider-Hero-Variante)\n- Grundlagen/Barrierefreiheit (Basisregel `prefers-reduced-motion`)\n",
|
|
13
|
+
"summary": "# Verwendung Slider & Carousel führt zwei getrennte Formen: das Bild-Carousel zur Seiten-I..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-tabelle--übersicht": {
|
|
4
|
+
"id": "komponenten-tabelle--übersicht",
|
|
5
|
+
"name": "komponenten-tabelle--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-tabelle--übersicht": {
|
|
8
|
+
"id": "komponenten-tabelle--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/komponenten/tabelle.mdx",
|
|
11
|
+
"title": "Komponenten/Tabelle",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Tabelle\" name=\"Übersicht\" />\n\n# Tabelle\n\nBarrierefreie Datentabellen mit `<caption>`, `scope`-Attributen und\nTastaturnavigation, in zwei Varianten: Standard und Gestreift, dazu eine\naufklappbare Vergleichstabelle. Standard und Gestreift deckt das Angular-Bauteil\n`Komponenten/Tabelle/Tabelle` (`cds-table`) ab: es liefert `.tbl-wrap` samt\nTastaturzugriff und Name sowie `.tbl`/`.tbl--striped`, der Konsument projiziert\n`<thead>`/`<tbody>`/`<tfoot>` unverändert hinein. Die aufklappbare Vergleichstabelle\ndeckt `Komponenten/Tabelle/Vergleichstabelle` (`cds-compare`) ab: anders als\n`cds-table` bekommt sie einen Daten-Input (`columns`/`rows`), weil ihre Zellen auf\nJa/Nein oder eine kurze Angabe begrenzt sind.\n\nQuelle: `docs/index.html#sec-table` (Zeilen 4979 bis 5208).\n\n## Standard\n\nZeilentrenner, Hover-Highlight, numerische Spalten rechtsbündig. Der\nScroll-Container ist per Tastatur fokussierbar (`tabindex=\"0\"`).\n\n```html\n<div class=\"tbl-wrap\" tabindex=\"0\" role=\"region\" aria-label=\"Leistungsübersicht Tabelle\">\n <table class=\"tbl\">\n <caption>Beratungsleistungen im Überblick</caption>\n <thead>\n <tr>\n <th scope=\"col\">Leistung</th>\n <th scope=\"col\">Format</th>\n <th scope=\"col\" data-num>Dauer (Tage)</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th scope=\"row\">KI-Readiness Assessment</th>\n <td>Workshop & Analyse</td>\n <td data-num>2</td>\n </tr>\n </tbody>\n </table>\n</div>\n```\n\nNumerische Spalten bekommen `data-num` an `<th>`/`<td>`, nicht eine eigene Klasse:\n`.tbl td[data-num]`/`.tbl th[data-num]` richten rechtsbündig aus und schalten auf\ntabellarische Ziffern (`font-variant-numeric: tabular-nums`) um.\n\n## Gestreift\n\nModifier `.tbl--striped` für Tabellen mit vielen Zeilen, verbessert die Lesbarkeit\nohne zusätzliche Rahmen.\n\n```html\n<div class=\"tbl-wrap\" tabindex=\"0\" role=\"region\" aria-label=\"Veranstaltungskalender Tabelle\">\n <table class=\"tbl tbl--striped\">\n <caption>Veranstaltungen & Workshops 2025</caption>\n <thead>\n <tr>\n <th scope=\"col\">Datum</th>\n <th scope=\"col\">Veranstaltung</th>\n <th scope=\"col\">Status</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>15. Jan 2025</td>\n <th scope=\"row\">KI im Unternehmensalltag, Einstiegsworkshop</th>\n <td>Abgeschlossen</td>\n </tr>\n </tbody>\n </table>\n</div>\n```\n\nSortierbare Spaltenüberschriften nutzen `.tbl-sort` (ein `<button>` in der `<th>`)\nzusammen mit `aria-sort=\"ascending\"` bzw. `\"descending\"` auf der `<th>`; `.tbl--striped`\nund `.tbl-sort` lassen sich kombinieren, gestreift und sortierbar für\ndatenintensive Ansichten.\n\n## Vergleichstabelle (aufklappbar)\n\nFür den zeilenweisen Vergleich zweier oder mehrerer Pakete beziehungsweise Tarife.\nPreiskarten tragen Preis und drei bis vier Highlights (Konversion), die vollständige\nMerkmalsliste steckt in der aufklappbaren Tabelle (Tiefenvergleich auf Abruf). So\nbleibt der Schnell-Scan kurz, und Karten und Tabelle überschneiden sich nicht.\nErprobt auf der Beispielseite Angewandte KI, AI.Box (Leistungspakete).\n\nAufklappbar via nativem `<details>`/`<summary>` (`.ep-compare`, standardmäßig zu,\ngleiche Mechanik wie das Inhaltsverzeichnis in `Seitenmuster/Wissensbeitrag`).\nTabelle `.ep-compare-table` mit `<caption class=\"sr-only\">` und `scope`-Attributen.\nDie empfohlene Spalte wird über `.ep-compare-pro` (bereichsgetönt) hervorgehoben.\nEnthalten/Nicht enthalten als `.ep-compare-yes` (✓) beziehungsweise `.ep-compare-no`\n(−), jeweils mit `.sr-only`-Text, da Farbe und Glyph allein keine Bedeutung tragen\n(WCAG 1.4.1).\n\n```html\n<details class=\"ep-compare\">\n <summary class=\"ep-compare-summary\">Alle Funktionen vergleichen</summary>\n <div class=\"ep-compare-table-wrap\">\n <table class=\"ep-compare-table\">\n <caption class=\"sr-only\">Funktionsvergleich Core und Pro</caption>\n <thead>\n <tr>\n <th scope=\"col\">Funktion</th>\n <th scope=\"col\">Core</th>\n <th scope=\"col\" class=\"ep-compare-pro\">Pro</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th scope=\"row\">Hosting in Deutschland</th>\n <td><span class=\"ep-compare-yes\" aria-hidden=\"true\">✓</span><span class=\"sr-only\">Enthalten</span></td>\n <td class=\"ep-compare-pro\">…</td>\n </tr>\n </tbody>\n </table>\n </div>\n</details>\n```\n\n## Verwendung\n\n<div className=\"doc-eyebrow\">Wann welche Variante?</div>\n\n| Variante | Wann einsetzen |\n|---|---|\n| Standard | Für Tabellen mit bis zu 6 Zeilen, klare Zeilentrenner reichen zur Orientierung |\n| Gestreift (`.tbl--striped`) | Ab ca. 7 Zeilen, der alternierende Hintergrund verbessert die Lesbarkeit ohne zusätzliche Rahmen |\n| Sortierbar (`.tbl-sort`) | Wenn Nutzer die Reihenfolge selbst bestimmen müssen, Klick auf die Spaltenüberschrift sortiert auf- oder absteigend |\n| Kombination | `.tbl--striped` und `.tbl-sort` lassen sich kombinieren, gestreift und sortierbar für datenintensive Ansichten |\n\n<div className=\"doc-eyebrow\">Barrierefreiheit</div>\n\n| Attribut / Element | Zweck |\n|---|---|\n| `<caption>` | Pflicht, Screenreader lesen den Titel vor, bevor die Zellen vorgelesen werden |\n| `scope=\"col\"` | Auf alle `<th>` im `<thead>`, ordnet Spaltenüberschriften den Zellen darunter zu |\n| `scope=\"row\"` | Wenn die erste Spalte eine Zeilenüberschrift ist, ordnet die Überschrift den Zellen rechts davon zu |\n| `tabindex=\"0\"` | Auf dem Scroll-Container, macht horizontales Scrollen per Tastatur erreichbar |\n| `role=\"region\"` + `aria-label` | Auf dem Scroll-Container, kennzeichnet ihn als benannten Landmark für Screenreader |\n\n<div className=\"doc-eyebrow\">Dos & Don'ts</div>\n\n**✓ Tun**\n\n- `<caption>` und `scope`-Attribute immer setzen, auch bei einfachen Tabellen\n- Numerische Spalten über `data-num` rechtsbündig ausrichten, erleichtert den Vergleich von Zahlen\n- Scroll-Container verwenden statt die Tabelle zu verkleinern, Lesbarkeit hat Vorrang\n- Spaltenüberschriften kurz und eindeutig benennen, maximal zwei bis drei Wörter\n\n**✕ Nicht tun**\n\n- Tabellen für Seiten-Layouts verwenden, dafür CSS Grid oder Flexbox nutzen\n- Mehr als sieben bis acht Spalten, lieber aufteilen oder Prioritäten setzen\n- Langen Fließtext in Zellen, Tabellen sind für strukturierte, scannbare Daten gedacht\n- Nur Farbe zur Bedeutungsvermittlung nutzen, Status-Badges zusätzlich mit Text kennzeichnen (siehe `Komponenten/Chips, Badges & Pills/Status-Badge`)\n\n## Verwandte Seiten\n\n- Doku-Sektion: `docs/index.html#sec-table`\n- `Komponenten/Tabelle/Tabelle` (Angular-Bauteil `cds-table` für Standard und Gestreift)\n- `Komponenten/Tabelle/Vergleichstabelle` (Angular-Bauteil `cds-compare` für die aufklappbare\n Vergleichstabelle)\n- `Komponenten/Chips, Badges & Pills/Status-Badge` (für Status-Zellen)\n",
|
|
13
|
+
"summary": "# Tabelle Barrierefreie Datentabellen mit ``, `scope`-Attributen und Tastaturnavigation, i..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-theme-umschalter--verwendung": {
|
|
4
|
+
"id": "komponenten-theme-umschalter--verwendung",
|
|
5
|
+
"name": "komponenten-theme-umschalter--verwendung",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-theme-umschalter--verwendung": {
|
|
8
|
+
"id": "komponenten-theme-umschalter--verwendung",
|
|
9
|
+
"name": "Verwendung",
|
|
10
|
+
"path": "./src/docs/komponenten/theme-umschalter.mdx",
|
|
11
|
+
"title": "Komponenten/Theme-Umschalter",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Theme-Umschalter\" name=\"Verwendung\" tags={['angular']} />\n\n# Theme-Umschalter · Verwendung\n\nDiese Seite ist die Ausnahme in diesem Spiegel: Die drei Bauteile Cycle-Button,\nSegment und Dropdown haben in `docs/index.html` keine Sektion (0 Treffer bei der\nSuche nach „Theme“ beziehungsweise „Umschalter“). Die Doku-Site kennt diesen\nUmschalter nicht, das Spiegel-Prinzip dieser Docs-Struktur (Docs-Sektion wird\nStorybook-Ordner) hat für ihn also keine Quelle. Diese Seite behauptet deshalb\nkeine Vollständigkeit gegenüber der Doku-Site, sondern beschreibt das Bauteil aus\ndem Repo selbst: der Angular-Lib\n(`angular-lib/projects/design-system-angular/src/lib/theme-switch/`) und der\nStorybook-Konfiguration (`.storybook/preview.ts`).\n\n## Dreistufiger Modus\n\n`CdsThemeMode` kennt drei Werte: `light`, `dark`, `system`. `system` folgt der\nBetriebssystem-Einstellung (`prefers-color-scheme`). Die Reihenfolge, in der alle\ndrei Umschalter zyklen beziehungsweise Optionen anbieten, ist fest:\n`CDS_THEME_ORDER = ['light', 'dark', 'system']`.\n\n| Modus | Label | Icon-Key |\n|---|---|---|\n| `light` | Hell | `heroSun` |\n| `dark` | Dunkel | `heroMoon` |\n| `system` | System | `heroComputerDesktop` |\n\nAlle drei Umschalter teilen denselben `showSystem`-Parameter: `true` zeigt alle drei\nModi (tri), `false` blendet „System“ aus und zyklt nur zwischen Hell und Dunkel\n(binär). Die Auswahl trifft `cdsThemeModes(showSystem)` in `theme-mode.ts`.\n\n## `themeStore` als einziger Schreiber von `data-theme`\n\nAlle drei Komponenten und die Storybook-Toolbar lesen und schreiben über\n`themeStore` (`theme-mode.ts`), eine modul-globale Quelle, kein Angular-Service:\nJede Story hat ihre eigene App-Instanz mit eigenem Root-Injector, Angular-DI allein\nwürde den Zustand also nicht über alle Stories hinweg teilen. `ThemeModeService` ist\nnur ein dünner Injectable-Wrapper darüber für `inject(ThemeModeService)` im\ngewohnten Muster.\n\n`themeStore` ist die **einzige** Stelle im System, die das Attribut `data-theme` am\n`<html>`-Element setzt oder entfernt:\n\n- `dark` gesetzt → `data-theme=\"dark\"`.\n- `light` → Attribut entfernt (Light ist der Default ohne Attribut).\n- `system` → koppelt live an `window.matchMedia('(prefers-color-scheme: dark)')`\n und reflektiert dessen `matches`-Wert als `dark` oder `light`; ein\n `change`-Listener hält das synchron, solange der Modus `system` bleibt.\n\nEin `document`/`window`-Guard schützt SSR und Prerendering: Ohne `document` wird\ndas Attribut übersprungen, der Modus bleibt im Signal erhalten und greift, sobald im\nBrowser das nächste `apply()` läuft. Die Lib fasst den globalen Cascade sonst nicht\nan (siehe `docs/adr/0001`).\n\n## Synchronisation mit der Storybook-Toolbar\n\n`.storybook/preview.ts` verdrahtet zwei Richtungen:\n\n1. **Store → Toolbar.** `themeStore.subscribe(...)` emittiert bei jeder Änderung\n `UPDATE_GLOBALS` an den Storybook-Channel, damit der globale\n Theme-Toolbar-Schalter mitwandert, wenn eine Story-Komponente den Modus ändert.\n2. **Toolbar → Store.** Ein Decorator ruft bei jedem Kontextwechsel\n `themeStore.setSilent(context.globals['theme'])` auf: `setSilent` wendet den\n Modus an, **ohne** erneut zu emittieren, sonst entstünde eine Rückkopplungs-\n schleife zwischen Toolbar und Store.\n\nDamit bleiben Toolbar, Docs-Vorschau und alle drei Switcher-Komponenten immer\ndenselben Modus zeigen. Das Docs-Chrome selbst (Überschriften, Tabellen) bleibt\ndavon unabhängig immer im Light-Theme (`concisoLight`), weil Storybook Toolbar- und\nDocs-Theme nicht koppelt.\n\n## Dark Mode: der Unterbau aus der CSS-Schicht\n\nDer CSS-Schicht-Vertrag (`docs/GETTING-STARTED.md` § 3) kennt nur ein Attribut:\n\n```js\ndocument.documentElement.setAttribute('data-theme', 'dark'); // dunkel\ndocument.documentElement.removeAttribute('data-theme'); // hell (Default)\n```\n\n**Genau zwei Modi in der ausgelieferten CSS.** Das System kennt Light und Dark,\nkeinen dritten Modus, der der Betriebssystem-Präferenz folgt: `prefers-color-scheme`\nwird im ausgelieferten CSS nicht ausgewertet, Default ist Light. Der dritte,\nUI-seitige Modus „System“ der drei Theme-Umschalter-Komponenten liegt deshalb eine\nEbene **über** der CSS-Schicht: `themeStore` löst `system` selbst über\n`matchMedia` auf und schreibt der CSS-Schicht am Ende immer nur einen der zwei\nZustände, die sie kennt (`data-theme=\"dark\"` gesetzt oder entfernt). Ein Consumer,\nder die Betriebssystem-Präferenz ohne diese Komponenten übernehmen will, wertet sie\nim eigenen Produkt genauso aus:\n\n```js\nif (matchMedia('(prefers-color-scheme: dark)').matches)\n document.documentElement.setAttribute('data-theme', 'dark');\n```\n\n**Anti-Flash-Snippet.** Als erstes Skript im `<head>`, vor dem CSS-Paint, damit beim\nReload nicht kurz Light aufblitzt. Liest die gespeicherte Präferenz aus\n`localStorage`:\n\n```html\n<script>\n (function(){\n try {\n var t = localStorage.getItem('ds-theme');\n if (t && t !== 'light') document.documentElement.setAttribute('data-theme', t);\n } catch(e) {}\n })();\n</script>\n```\n\nPersistenz beim Umschalten: `localStorage.setItem('ds-theme', 'dark' | 'light')`.\nDie drei Angular-Umschalter selbst persistieren nicht; das bleibt Aufgabe des\nConsumers, der `themeStore.subscribe(...)` an die eigene Persistenz anschließt.\n\n**Warum das für jede Komponente gilt (CONTRIBUTING § 5).** `data-theme` ist der\neinzige Schalter im System: Alle Token flippen darüber, keine Komponente wertet\n`prefers-color-scheme` selbst aus oder führt eine eigene dritte Flächen-Stufe ein.\nWeil `themeStore` der einzige Schreiber dieses Attributs ist, bleibt diese Garantie\nauch mit drei unterschiedlichen Umschalter-Bauteilen (Cycle-Button, Segment,\nDropdown) und der Storybook-Toolbar intakt: Es gibt genau eine Quelle der Wahrheit\nfür den Modus, unabhängig davon, über welchen Umschalter er gesetzt wurde.\n\n## Verwandte Seiten\n\n- `Komponenten/Theme-Umschalter/Cycle-Button` (Icon-Button, ein Klick zyklt durch die Modi, vorgesehen für den Header)\n- `Komponenten/Theme-Umschalter/Segment` (Segment-Leiste zum Hovern, immer responsiv und animiert)\n- `Komponenten/Theme-Umschalter/Dropdown` (Custom Select, vorgesehen nur in den Einstellungen, nicht als persistentes Element)\n",
|
|
13
|
+
"summary": "# Theme-Umschalter · Verwendung Diese Seite ist die Ausnahme in diesem Spiegel: Die drei B..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-zitate-testimonials--verwendung": {
|
|
4
|
+
"id": "komponenten-zitate-testimonials--verwendung",
|
|
5
|
+
"name": "komponenten-zitate-testimonials--verwendung",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-zitate-testimonials--verwendung": {
|
|
8
|
+
"id": "komponenten-zitate-testimonials--verwendung",
|
|
9
|
+
"name": "Verwendung",
|
|
10
|
+
"path": "./src/docs/komponenten/quotes-verwendung.mdx",
|
|
11
|
+
"title": "Komponenten/Zitate & Testimonials",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Zitate & Testimonials\" name=\"Verwendung\" tags={['angular']} />\n\n# Verwendung\n\nZitate & Testimonials führt vier Formen: Blockquote, Testimonial-Card, Team-Stimme und\ndas offene Zitat. Alle Formen teilen dasselbe semantische Grundgerüst\n(`<figure>` + `<blockquote>` + `<figcaption>`). Nur das offene Zitat hat kein eigenes\nBauteil, es ist ein CSS-Rezept ohne Karten-Chrome.\n\n## Wann welche Variante\n\n| Variante | Bauteil | Wann einsetzen |\n|---|---|---|\n| Blockquote | Story `Blockquote` | Kürzere Zitate (1 bis 3 Sätze, max. 200 Zeichen) im redaktionellen Kontext, eingebettet in Fließtext oder Abschnitte |\n| Testimonial-Card | Story `Testimonial` | Kundenreferenzen als eigenständige visuelle Einheit: Referenz-Sektionen, Hero-nahe Bereiche, Abschluss von Leistungsbeschreibungen, 2 bis 5 Sätze |\n| Team-Stimme | Story `TeamVoice` | Fotostarke, editoriale Variante der Testimonial-Card für Repräsentation (zum Beispiel Karriereseiten), volle Breite, großes Foto seitlich, abwechselnd links und rechts |\n| Offenes Zitat | bauteillos (CSS-Rezept, ohne Karten-Chrome) | Mehrere gleichrangige Stimmen in einer eigenen Sektion (zum Beispiel Workshop-Stimmen), Serif aufrecht statt kursiv, Trennung nur über Haarlinien |\n\n## Abgrenzung: Pull-Quote gegen Blockquote\n\nZwei Muster teilen sich dieselbe typografische Familie, aber nicht denselben Zweck. Ein\n**Pull-Quote** (`.article-pullquote`, dokumentiert unter Seitenmuster/Wissensbeitrag)\nhebt einen Satz aus dem eigenen Lauftext typografisch hervor: ohne Attribution, denn\ndie Autorin zitiert sich nicht selbst, sondern setzt einen Schlüsselsatz visuell ab. Der\n**Blockquote** (`.bq`, das Bauteil dieser Seite) ist dagegen ein wörtliches Zitat einer\ndritten Person (Kundin, Forschungsstimme, Branchen-Statement) mit Attribution (Name und\nRolle) und einer area-getönten Akzent-Box samt Quote-Icon. Beide teilen den\n4-Pixel-Linksakzent in der Bereichsfarbe; der Pull-Quote bleibt bewusst „offen“ (Serif\nkursiv, kein Hintergrund, kein Icon), der Blockquote ist umrahmt. Details zum Pull-Quote\nstehen unter Seitenmuster/Wissensbeitrag.\n\n## Barrierefreiheit\n\n| Aspekt | Regel |\n|---|---|\n| Semantik | `<blockquote>` korrekt für Zitate verwenden, Screenreader kündigen es als „Blockzitat“ an |\n| Dekoration | SVG-Anführungszeichen und Avatar-Initialen mit `aria-hidden=\"true\"` und `focusable=\"false\"` ausblenden |\n| Attribution | `<figcaption>` verknüpft die Quellenangabe semantisch mit dem Zitat, kein zusätzliches ARIA nötig |\n| Kontrast | Zitattext und Name in `--tx-primary`, Rolle in `--tx-secondary`, Avatar-Text geprüft ≥4,5:1 auf Bereichshintergrund in Light und Dark |\n| Anführungszeichen | Im Zitattext direkt eingebettet („…“), `quotes: none` verhindert doppelte Browser-Anführungszeichen |\n\n### Team-Stimme: zusätzliche Regeln\n\n| Aspekt | Regel |\n|---|---|\n| Semantik | `<figure>` + `<blockquote>` + `<figcaption>`, Quote-Icon dekorativ (`aria-hidden=\"true\"`, `focusable=\"false\"`) |\n| Bild-Alt | Beschreibendes `alt`, das keine konkrete Identität behauptet, solange Platzhalter- oder Stimmungsfotos genutzt werden |\n| Elevation | Statisch, daher flacher Rahmen (`--bd-strong`), kein Schatten, keine Klick-Affordanz |\n| Bereichs-Rahmen | Trägt das Bereichssignal und muss die 3:1-Schwelle für grafische Objekte erfüllen: Light `-600`/`-700`/`-500` (3,29 bis 5,66:1 auf Weiß), Dark `-300` (4,25 bis 9,48:1 auf der Karte). Vorher trug er mit `-200` im Light nur 1,27 bis 2,03:1 und mit `-800` im Dark 1,07 bis 1,63:1, war also in beiden Modi kein Signal |\n| Responsive | Unter 768 px stapelt das Grid zu Foto oben, Text unten |\n\n## Dos & Don'ts\n\n**Tun**\n\n- `<figure>` + `<blockquote>` + `<figcaption>` als semantisches Grundgerüst nutzen\n- Echte Kundenstimmen verwenden, keine KI-generierten Platzhalter in der Produktion\n- Bereichsfarbe über `data-area` steuern, keine hardcodierten Farbwerte\n- Zitate authentisch halten: gesprochene Sprache, konkrete Ergebnisse, keine Marketingfloskeln\n- Testimonial-Cards auf gleiche Höhe bringen: `align-items:stretch` im Grid plus `flex:1` auf dem Zitattext hält die Attribution am unteren Rand ausgerichtet\n\n**Nicht tun**\n\n- `<blockquote>` für eingerückte Aufzählungen oder rein visuell hervorgehobenen Text verwenden\n- Anführungszeichen doppelt setzen, entweder im Text oder via CSS `content`, nicht beides\n- Attribution weglassen, jedes Zitat braucht eine überprüfbare Quelle\n- Mehr als 3 Testimonials in einer Reihe, Lesbarkeit und visuelle Balance leiden\n- Dekorative Icons mit `role=\"img\"` oder `alt` versehen, sie sind `aria-hidden` und übermitteln keine Information\n\n## Verwandte Seiten\n\n- Komponenten/Zitate & Testimonials/Blockquote\n- Komponenten/Zitate & Testimonials/Testimonial\n- Komponenten/Zitate & Testimonials/TeamVoice\n- Seitenmuster/Wissensbeitrag (Abgrenzung Pull-Quote gegen Blockquote)\n",
|
|
13
|
+
"summary": "# Verwendung Zitate & Testimonials führt vier Formen: Blockquote, Testimonial-Card, Team-S..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"marke-bildsprache--übersicht": {
|
|
4
|
+
"id": "marke-bildsprache--übersicht",
|
|
5
|
+
"name": "marke-bildsprache--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"marke-bildsprache--übersicht": {
|
|
8
|
+
"id": "marke-bildsprache--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/marke/bildsprache.mdx",
|
|
11
|
+
"title": "Marke/Bildsprache",
|
|
12
|
+
"content": "import { Meta, Unstyled } from '@storybook/addon-docs/blocks';\nimport icons from '../../../../icons/icons.json';\n\n<Meta title=\"Marke/Bildsprache\" name=\"Übersicht\" />\n\n# Bildsprache\n\nFotografie · Illustration · vier Brand Areas, abgeleitet aus dem Markenrad.\n\nBilder kommunizieren schneller als Worte. Die Bildsprache von Conciso übersetzt den Kernwert **Gelassenheit** in visuelle Reize: ruhige Kompositionen, klare Motive und echte Energie statt inszenierter Hochglanz-Ästhetik.\n\n## Grundprinzipien aus dem Markenrad\n\nJeder der drei Markenpfeiler übersetzt sich direkt in visuelle Entscheidungen, von der Wahl des Motivs bis zur Bildbearbeitung.\n\n| Markenpfeiler | Eigenschaften | Bildsprache-Übersetzung |\n|---|---|---|\n| Ruhig | Verlässlich · Selbstsicher · Kompetent | Ausgewogene Komposition, großzügiger Weißraum, natürliches, diffuses Licht ohne harte Schatten, keine überfüllten Bildausschnitte |\n| Klar | Aufmerksam · Präzise · Pragmatisch | Scharfer Motivfokus, aufgeräumte Hintergründe, ein dominantes Motiv pro Bild, kein dekoratives Beiwerk ohne Zweck |\n| Energiegeladen | Kraftvoll · Agil · Leidenschaftlich | Echte Momente statt Pose, Menschen in echter Konzentration oder Zusammenarbeit, Bewegung und Dynamik, ohne Unruhe zu erzeugen |\n\n## Fotografie\n\nJede Brand Area hat einen eigenen Bildkontext, die gemeinsamen Stilprinzipien (siehe unten) gelten übergreifend. Reihenfolge co · ki · es · wo.\n\n**Corporate · Vertrauen & Kompetenz.** Menschen im Gespräch, beim Beratungsgespräch oder in ruhiger Konzentration, neutrale, helle Büroumgebungen, Handshakes und partnerschaftliche Gesten, Blickkontakt und Offenheit. Stichworte: Gespräch, Partnerschaft, Büroatmosphäre.\n\n**Angewandte KI · Mensch & Technologie.** Nahaufnahmen von Screens und Interfaces, Menschen, die mit KI-Tools interagieren, abstrakte Datenmuster als visuelle Akzente, immer mit menschlichem Fokus: Technologie ist Werkzeug, nicht Hauptdarsteller. Stichworte: Interfaces, Interaktion, Muster & Daten.\n\n**Effektive Software · Fokus & Präzision.** Nahaufnahmen von Code und Interfaces, Entwickler in tiefer Konzentration, saubere, aufgeräumte Screens, Terminal, IDE und Architekturdiagramme als visuelle Metaphern. Stichworte: Code, Interfaces, Konzentration.\n\n**Wirksame Organisationen · Kollaboration & Wirkung.** Diverse Teams in echter Zusammenarbeit, Workshops, Retrospektiven, Whiteboard-Momente, echte Emotionen wie Lachen und Konzentration, keine uniformen Gruppenfotos ohne Leben. Stichworte: Teams, Workshop, Echte Momente.\n\n**Ergänzung aus `conciso-claude-powerpoint-instructions.md` § 7.2** (dort geführt, in der Doku-Sektion nicht vollständig): Effektive Software zusätzlich mit dem Stichwort *geometrische Strukturen*, Wirksame Organisationen zusätzlich mit *organische Strukturen* und *Wandel*.\n\nStorybook bindet bewusst keine Personenfotos ein: Der folgende Block zeigt je Brand Area nur den Bildslot und seine Bereichsfarbe, nicht das Motiv.\n\nexport const imagerySlots = [\n { area: 'co', iconKey: 'co-building', name: 'Corporate', keywords: 'Gespräch, Partnerschaft, Büroatmosphäre' },\n { area: 'ki', iconKey: 'ki-bot', name: 'Angewandte KI', keywords: 'Interfaces, Interaktion, Muster & Daten' },\n { area: 'es', iconKey: 'es-window-check', name: 'Effektive Software', keywords: 'Code, Interfaces, Konzentration' },\n { area: 'wo', iconKey: 'wo-network', name: 'Wirksame Organisationen', keywords: 'Teams, Workshop, Echte Momente' },\n];\n\nexport const ImagerySlot = ({ area, iconKey, name, keywords }) => {\n const icon = icons[iconKey];\n const svgAttrs =\n icon.style === 'solid'\n ? { fill: 'currentColor' }\n : { fill: 'none', stroke: 'currentColor', strokeWidth: icon.strokeWidth || '1' };\n return (\n <div className=\"card\" data-area={area}>\n <div className=\"card-media\">\n <svg\n viewBox={icon.viewBox}\n width={64}\n height={64}\n aria-hidden=\"true\"\n {...svgAttrs}\n dangerouslySetInnerHTML={{ __html: icon.body }}\n />\n </div>\n <div className=\"card-body\">\n <span className=\"card-eyebrow\">{name}</span>\n <p className=\"card-text\">{keywords}</p>\n </div>\n </div>\n );\n};\n\n<Unstyled>\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))',\n gap: 'var(--s5)',\n }}\n >\n {imagerySlots.map((slot) => (\n <ImagerySlot key={slot.area} {...slot} />\n ))}\n </div>\n</Unstyled>\n\nDie Kacheln oben zeigen Slot, Seitenverhältnis (16:9) und Bereichsfarbe je Brand Area; konkrete Beispielfotos zeigt weiterhin die Doku-Site (`docs/index.html#gt-imagery-beispiele`).\n\n## Stilprinzipien Fotografie\n\n- **Licht & Ton.** Natürliches, weiches Licht, helle, leicht entsättigte Töne, kein Filmdrama, kein HDR, Helligkeit leicht anheben, Kontrast etwas reduzieren.\n- **Komposition.** Drittel-Regel und goldener Schnitt, Freiflächen für Text-Overlays einplanen, ein dominantes Motiv, ruhige Umgebung, kein Informations-Overload im Bild.\n- **Menschen.** Authentische Personen aus echten Arbeitskontexten, diverse Repräsentation, Blickkontakt oder echte Konzentration, keine Stockphoto-Posen.\n\n## Illustration\n\nIllustrationen werden ergänzend eingesetzt, für abstrakte Konzepte, die sich nicht fotografisch abbilden lassen: KI-Prozesse, Systemarchitektur, Organisationsmodelle.\n\n- **Linienstil.** Klare, gleichmäßige Linien, keine Füllflächen ohne Bedeutung, Strichstärke konsistent.\n- **Geometrisch.** Vereinfachte Formen statt realistischer Darstellung, keine Gradients innerhalb von Figuren.\n- **Systemfarben.** Ausschließlich Design-System-Tokens (`--co-500`, `--ki-500` und so weiter), keine Freihandfarben.\n- **Weißraum.** Leere Fläche ist gestalterisches Element, nicht jeder Pixel muss belegt sein, Illustration atmen lassen.\n\n## Verwendung\n\nKontext entscheidet über das richtige Bildformat: Hero-Bereiche brauchen Freiräume für Text, Teaser-Cards arbeiten mit Ausschnitten, Illustrationen kommen dort zum Einsatz, wo Fotos zu konkret wären.\n\n| Kontext | Empfehlung |\n|---|---|\n| Hero-Bereich | Querformat, heller, ruhiger Hintergrund im Bild, untere Bildhälfte frei für Text-Overlay, Foto darf nicht mit der Headline konkurrieren |\n| Card / Teaser | 16:9 oder 3:2, Motiv mittig, kein Text im Bild selbst, Brand-Area-Farbe als Eyebrow über dem Bild, nicht als Tint im Bild |\n| Wissensartikel | Illustration für abstrakte Prozesse, Foto für Praxisbeispiele, Bildunterschrift immer vorhanden, Bilder nie als einziger Informationsträger |\n| Testimonial | Porträt im quadratischen oder runden Ausschnitt, Blick zur Kamera oder leicht seitlich, neutraler, heller Hintergrund, kein Hintergrund-Clutter |\n\n### Barrierefreiheit\n\n| Aspekt | Regel |\n|---|---|\n| Alt-Text | Jedes inhaltstragende Bild benötigt einen beschreibenden `alt`-Text: er beschreibt, was zu sehen ist, nicht was das Bild bedeutet. Dekorative Bilder erhalten `alt=\"\"` |\n| Text-Overlay | Text auf Foto-Hintergründen mindestens 4,5:1 (WCAG 1.4.3), gerechnet gegen die hellste Stelle unter dem Text, nicht gegen den Bilddurchschnitt: Fotos haben ausgebrannte Bereiche, dort entscheidet sich die Lesbarkeit. Weiße Schrift braucht dafür einen Scrim von mindestens `rgba(0,0,0,.60)`, `.45` reicht nicht (trägt über einer weißen Bildstelle nur rund 3:1). Bei einem Verlauf gilt der Wert an der Stelle, an der der Text sitzt, nicht am dichten Ende. `text-shadow` hilft optisch, zählt für WCAG nicht |\n| Auslaufstrecke des Scrims | Genauso wichtig wie der Deckkraft-Wert ist die Strecke, über die er aufgebaut wird: ein Verlauf fällt dort auf, wo seine Steilheit springt, nicht wo er dicht ist. Faustwert: rund 0,007 Deckkraft pro Pixel. Für 0,6 Deckkraft am obersten Textelement sind das etwa 90 px Auslauf darüber. Reicht die Höhe nicht, wächst die Polsterung, nicht die Steilheit |\n| Nicht allein | Informationen nie ausschließlich im Bild transportieren, der gleiche Inhalt muss als Text verfügbar sein (WCAG 1.1.1) |\n| Bewegung | Animierte Illustrationen oder Hintergrund-Videos mit `prefers-reduced-motion` pausieren |\n\n### Dos & Don'ts\n\n✓ Tun\n\n- Authentische Menschen aus echten Arbeitskontexten wählen, kein gestelltes Stockphoto-Lächeln.\n- Helles, leicht entsättigtes Farbklima beibehalten, Gelassenheit überträgt sich auf die Bildstimmung.\n- Freiraum für Text-Overlays im Bild einplanen, besonders bei Hero-Fotos.\n- Illustrationen ausschließlich mit Design-System-Tokens, Farb-Konsistenz auch im SVG.\n- Brand-Area-Farbe als Kontext-Element um das Bild herum einsetzen, nicht als Farbfilter im Bild.\n\n✕ Nicht tun\n\n- Generische Stockfotos (lachende Gruppe am Tisch, Handshake vor weißem Hintergrund): wirken unecht und austauschbar.\n- Übersättigte oder hochkontrastige Bearbeitungen widersprechen dem Markenwert Gelassenheit.\n- Bereichsfarbe als Tint-Filter über das Foto legen, wirkt aufdringlich und überdeckt die natürliche Bildstimmung.\n- Realistische oder fotografische Illustrationsstile, das bricht den klaren, geometrischen Linienstil.\n- Bilder ohne `alt`-Text oder mit generischem „Foto“: Screenreader-Nutzende erhalten keinen Mehrwert.\n",
|
|
13
|
+
"summary": "# Bildsprache Fotografie · Illustration · vier Brand Areas, abgeleitet aus dem Markenrad. ..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"marke-brand-areas--übersicht": {
|
|
4
|
+
"id": "marke-brand-areas--übersicht",
|
|
5
|
+
"name": "marke-brand-areas--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"marke-brand-areas--übersicht": {
|
|
8
|
+
"id": "marke-brand-areas--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/marke/brand-areas.mdx",
|
|
11
|
+
"title": "Marke/Brand Areas",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Marke/Brand Areas\" name=\"Übersicht\" tags={['angular']} />\n\n# Brand Areas\n\nVier Unternehmensbereiche mit eigenem Farbsystem, alle konsistent und stimmig als System. Reihenfolge überall co · ki · es · wo.\n\n## Die vier Bereiche\n\nWerte aus der CSS-Schicht (`css/tokens.css`), nicht aus dieser Doku-Kopie.\n\n| Kürzel | Bereich | Thema | Token-Präfix | Primär (`--XX-500`) | Text (`--XX-ink`) |\n|---|---|---|---|---|---|\n| `co` | Corporate | Marke · Kommunikation · Strategie | `--co-*` | `--co-500` (`#00BEBE`) | `--co-ink` = `--co-700` (`#007575`) |\n| `ki` | Angewandte KI | Intelligenz · Automatisierung · Wirkung | `--ki-*` | `--ki-500` (`#B5E61C`) | `--ki-ink` = `--ki-800` (`#475705`) |\n| `es` | Effektive Software | Präzision · Verlässlichkeit · Qualität | `--es-*` | `--es-500` (`#2F5FD4`) | `--es-ink` = `--es-700` (`#1B3D9A`) |\n| `wo` | Wirksame Organisationen | Struktur · Wirkung · Wandel | `--wo-*` | `--wo-500` (`#44A030`) | `--wo-ink` = `--wo-700` (`#285E1A`) |\n\n`--ki-ink` zeigt auf `-800`, nicht auf `-700` wie die übrigen drei Bereiche: `ki-700` trägt im Light-Modus nur 4,05:1 und reißt damit die AA-Schwelle für Normaltext.\n\n## Bereichs-Komponenten Vergleich\n\nDieselben Bauteile (Buttons in Filled/Tonal/Outlined/Text, Bereichs-Badge, zwei Chips) einmal je Bereich, um die vier Paletten nebeneinander zu prüfen. Buttons und Badge/Chip-Flächen setzen ihre Bereichsfarbe klassenbasiert (`.btn-co`, `.btn-ki`, `.btn-es`, `.btn-wo`, `data-area`), nicht über `data-accent` (siehe unten).\n\nDie Bauteile selbst existieren bereits als eigene Stories (Buttons, Chip, Bereichs-Badge); dieser Vergleich wird deshalb nicht als Markup nachgebaut, sondern lebt in der Story **`Marke/Brand Areas/AreaTabs`**.\n\n## Bereichs-Kontext: `data-accent`\n\nDetail- und Stellenseiten gehören oft zu einem Bereich, nutzen aber Komponenten mit `co`-Default-Akzent (zum Beispiel die Stelle „Java / JEE Developer“ zu Effektive Software). Über `data-accent=\"ki|es|wo\"` werden die Default-Akzent-Utilities `.t-co` (Überschriften-Icons, Bullets, Eyebrows) und `.body-link` auf die Bereichsfarbe umgetönt: Light auf `-700` (`ki` auf `-800`, aus demselben Grund wie oben), Dark-Override auf `-200`.\n\n- **Wo das Attribut sitzt.** Am Container, der einen Bereichsblock aufspannt: für eine ganze Seite der `.ep-page`-Root, für einen einzelnen Block der Wrapper um den Block (zum Beispiel ein Buchungsformular in einer sonst corporate Seite). Der Selektor ist bewusst nicht an `.ep-page` gebunden, sonst bräuchte so ein Block Inline-Farben an den einzelnen Links, die im Dark Mode brechen würden.\n- **Was es nicht abdeckt.** Buttons und CTA-Band bleiben Bereichs-Klassen (`.btn-es`, `.btn-es.btn-on-band`), `data-accent` tönt nur Text-/Link-Utilities im Inhalt.\n- **Chrome bleibt corporate.** Footer-`.body-link` und Topnav (`.ep-topnav .t-co`, zum Beispiel die aktive Sektion) werden per Reset auf `co` zurückgesetzt. Ohne diesen Reset erschiene die aktive Nav-Sektion auf einer `wo`-Seite grün statt Petrol, inkonsistent zur Nav aller anderen Seiten.\n\n### Bereichs-Umschalter in der Storybook-Toolbar\n\nDie Toolbar (`areaContext` in `.storybook/preview.ts`) setzt genau diesen Selektor, nicht eine Simulation davon: bei aktiver Auswahl hüllt ein `componentWrapperDecorator` die Story in `<div [class.ep-page]=\"cdsAreaCtx\" [attr.data-accent]=\"cdsAreaCtx || null\" style=\"display:contents\">`. Der `display:contents`-Wrapper trägt kein eigenes Layout, also keine Nebenwirkungen wie zusätzliches `.ep-page`-Padding, nur die echte Tönung durch den CSS-Kern.\n\nDefault ist `none`: Komponenten rendern ohne Bereichs-Kontext, isoliert. Die Toolbar-Werte sind, in dieser Reihenfolge, `co` (Corporate), `ki` (Toolbar-Beschriftung „AI.Applied“), `es` (Effektive Software) und `wo` (Wirksame Organisationen). Das Toolbar-Label für `ki` weicht damit vom Bereichsnamen auf dieser Seite und in der Doku-Site ab, die durchgängig „Angewandte KI“ schreiben.\n\nDer Bereichs-Kontext der Seite ist ein eigener, bewusst wählbarer Zustand, getrennt vom `area`-Input einzelner Komponenten.\n\n## Eigenständige Bereichs-Text-Utilities\n\nDieselben Töne gibt es klassenbasiert als `.t-co` / `.t-ki` / `.t-es` / `.t-wo` (Light `-700`, `ki` `-800`, Dark-Override `-200`/`-100`) für inline gesetzten Akzenttext wie Eyebrows, Labels oder Kennzahlen.\n\nBereichsfarbigen Text immer über diese Utilities, `data-area` (Chips, Badges, Pills, CTA-Links via `.card-cta-link[data-area]`) oder `--ki-ink` führen, nie als rohes `style=\"color:var(--XX-700/800)\"`, das bliebe im Dark Mode dunkel-auf-dunkel.\n",
|
|
13
|
+
"summary": "# Brand Areas Vier Unternehmensbereiche mit eigenem Farbsystem, alle konsistent und stimmi..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"marke-logo--verwendung": {
|
|
4
|
+
"id": "marke-logo--verwendung",
|
|
5
|
+
"name": "marke-logo--verwendung",
|
|
6
|
+
"docs": {
|
|
7
|
+
"marke-logo--verwendung": {
|
|
8
|
+
"id": "marke-logo--verwendung",
|
|
9
|
+
"name": "Verwendung",
|
|
10
|
+
"path": "./src/docs/marke/logo-verwendung.mdx",
|
|
11
|
+
"title": "Marke/Logo",
|
|
12
|
+
"content": "import { Meta, Unstyled } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Marke/Logo\" name=\"Verwendung\" tags={['angular']} />\n\n# Verwendung\n\nVerwendungsregeln zum Logo: Größen, Schutzraum, Einsatz nach Hintergrund, Barrierefreiheit und Dos & Don'ts. Die drei Varianten (Default, Light, Dark) zeigt die Story **`Marke/Logo/Logo`**; diese Seite ergänzt die Regeln dazu, inklusive des Hintergrund-Kontexts, den die Story allein nicht zeigt.\n\nDas Logo ist die primäre Markenkennung. Es wird stets als Vektor (SVG) verwendet, nie verzerrt oder eingefärbt.\n\n## Größen\n\nDie Höhe ist die maßgebliche Größenangabe, die Breite ergibt sich proportional aus dem Vektor (Verhältnis ≈ 7,6 : 1). Mindesthöhe nicht unterschreiten, sonst leidet die Lesbarkeit der „o.“-Form.\n\n| Kontext | Höhe | Hinweis |\n|---|---|---|\n| Topnav (Standard) | 24 px | Default-Variante, schaltet im Dark Mode auf Light um |\n| Footer | 32 px | Light-Variante, da Footer-Hintergrund `--n-700` immer dunkel ist |\n| Hero / Marketing-Header | 40 bis 48 px | Wenn das Logo selbst die Aufmerksamkeit tragen soll |\n| Mobile / kompakte Layouts | 20 px | Mindestgröße digital, darunter wird der Punkt schwer erkennbar |\n| Print | mindestens 12 mm | Mindestgröße im Druck, Punkt muss sauber drucken |\n\n## Schutzraum\n\nUm das Logo herum bleibt mindestens die Höhe des „C“ als freier Raum: keine konkurrierenden Elemente, kein Beschnitt durch andere Layout-Komponenten. Als Vielfaches ausgedrückt: die Referenzimplementierung der Doku-Site setzt ein Padding in Höhe des gesamten Logos (1:1-Clearance) an, eine praktikable Annäherung an dieselbe Regel.\n\nDas folgende Diagramm zeigt genau diese 1:1-Clearance: eine gestrichelte Box im Abstand einer vollen Logo-Höhe, hier 36 px, um die Wortmarke.\n\n<Unstyled>\n <div style={{ background: 'var(--bg-surface)', border: 'var(--bd-strong)', borderRadius: 'var(--r-lg)', padding: 'var(--s10)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 'var(--s8)' }}>\n {/* Padding 36px = exakte Logo-Image-Höhe (1:1-Clearance, Schutzraum-Regel der Brand Guidelines) */}\n <div style={{ position: 'relative', display: 'inline-block', padding: '36px' }}>\n <div style={{ position: 'absolute', inset: 0, border: '1px dashed var(--co-300)', borderRadius: 'var(--r-sm)', pointerEvents: 'none' }} />\n {/* Theme-abhängiges Logo: --bg-surface ist im Dark Mode dunkel, daher Default (dunkle Wortmarke) im Light, Light-Variante im Dark. Der Wechsel läuft über .logo-themed-default/.logo-themed-light (display:none/block), nicht über Inline-Styles. */}\n <img src=\"./conciso/brand/logo-conciso.svg\" alt=\"\" aria-hidden=\"true\" className=\"logo-themed-default\" style={{ height: '36px', width: 'auto', verticalAlign: 'middle' }} />\n <img src=\"./conciso/brand/logo-conciso-light.svg\" alt=\"\" aria-hidden=\"true\" className=\"logo-themed-light\" style={{ height: '36px', width: 'auto', verticalAlign: 'middle' }} />\n </div>\n </div>\n</Unstyled>\n\n## Verwendung\n\nDie Wahl der Variante richtet sich nach Hintergrund und Kontext. Im Zweifel die Default-Variante auf hellem, neutralem Untergrund verwenden.\n\nSo wirkt jede Variante auf dem Hintergrund, für den sie gedacht ist. Diesen Hintergrund-Kontext liefert die Story `Marke/Logo/Logo` allein nicht:\n\n<Unstyled>\n <div className=\"layout-grid\" style={{ marginBottom: 'var(--s8)' }}>\n <div className=\"col-4\" style={{ background: 'var(--bg-surface)', border: 'var(--bd-strong)', borderRadius: 'var(--r-lg)', overflow: 'hidden' }}>\n {/* --bg-plate: im Light reinweiß (der Anwendungsfall der Variante), im Dark gedämpft, damit die helle Platte auf der tiefen Seite nicht blendet. */}\n <div style={{ background: 'var(--bg-plate)', padding: 'var(--s8) var(--s6)', display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '120px' }}>\n <img src=\"./conciso/brand/logo-conciso.svg\" alt=\"Conciso, Default-Variante\" style={{ height: '36px', width: 'auto', display: 'block' }} />\n </div>\n <div style={{ padding: 'var(--s5) var(--s6)', borderTop: 'var(--bd)' }}>\n <div className=\"doc-eyebrow\" style={{ marginBottom: 'var(--s2)' }}>Default</div>\n <div style={{ font: 'var(--ty-title-sm)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>Vollfarbe</div>\n <p style={{ font: 'var(--ty-body-md)', color: 'var(--tx-secondary)', margin: 0 }}>Wortmarke in <code className=\"token\">--tx-brand</code> mit teal-Punkt in <code className=\"token\">--co-500</code>. Standard für helle Hintergründe.</p>\n </div>\n </div>\n <div className=\"col-4\" style={{ background: 'var(--bg-surface)', border: 'var(--bd-strong)', borderRadius: 'var(--r-lg)', overflow: 'hidden' }}>\n <div style={{ background: 'var(--n-700)', padding: 'var(--s8) var(--s6)', display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '120px' }}>\n <img src=\"./conciso/brand/logo-conciso-light.svg\" alt=\"Conciso, helle Variante\" style={{ height: '36px', width: 'auto', display: 'block' }} />\n </div>\n <div style={{ padding: 'var(--s5) var(--s6)', borderTop: 'var(--bd)' }}>\n <div className=\"doc-eyebrow\" style={{ marginBottom: 'var(--s2)' }}>Light</div>\n <div style={{ font: 'var(--ty-title-sm)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>Weiß</div>\n <p style={{ font: 'var(--ty-body-md)', color: 'var(--tx-secondary)', margin: 0 }}>Vollständig weiß, für dunkle Hintergründe (Footer, Hero-Gradients, Dark Mode).</p>\n </div>\n </div>\n <div className=\"col-4\" style={{ background: 'var(--bg-surface)', border: 'var(--bd-strong)', borderRadius: 'var(--r-lg)', overflow: 'hidden' }}>\n {/* Panel-Hintergrund fest hell (#F5F7F7), nicht das theme-reaktive Token: das Monochrom-Logo ist fix in --tx-brand gezeichnet und bräuchte im Dark Mode sonst dunkel-auf-dunkel. */}\n <div style={{ background: '#F5F7F7', padding: 'var(--s8) var(--s6)', display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '120px' }}>\n <img src=\"./conciso/brand/logo-conciso-dark.svg\" alt=\"Conciso, monochrom-dunkle Variante\" style={{ height: '36px', width: 'auto', display: 'block' }} />\n </div>\n <div style={{ padding: 'var(--s5) var(--s6)', borderTop: 'var(--bd)' }}>\n <div className=\"doc-eyebrow\" style={{ marginBottom: 'var(--s2)' }}>Dark</div>\n <div style={{ font: 'var(--ty-title-sm)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>Monochrom</div>\n <p style={{ font: 'var(--ty-body-md)', color: 'var(--tx-secondary)', margin: 0 }}>Komplett in <code className=\"token\">--tx-brand</code>, ohne teal-Punkt. Für Druck, Stempel, einfarbige Anwendungen oder wenn der Akzent visuell stört.</p>\n </div>\n </div>\n </div>\n</Unstyled>\n\n| Hintergrund | Variante | Begründung |\n|---|---|---|\n| Weiß / hell-neutral | Default | Volle Brand-Identität mit teal-Akzent |\n| Dunkel (mindestens 60 % Schwarzanteil) | Light | Vollständig weiß für maximale Lesbarkeit |\n| Bereichsfarbe (`--co/ki/es/wo-500`) | Light oder Dark | Default vermeiden, der teal-Punkt konkurriert mit der Bereichsfarbe |\n| Foto / unruhiger Hintergrund | Light auf Scrim | Halbtransparente dunkle Fläche unter Logo legen, dann Light verwenden |\n| Druck monochrom, Stempel, Embossing | Dark | Kein Akzent verfügbar, komplett einfarbig |\n| Dark-Mode-Interfaces | Light (auto-swap) | Wechsel via `[data-theme=\"dark\"]`-Selektor |\n\n### Barrierefreiheit\n\n| Aspekt | Regel |\n|---|---|\n| Alt-Text | Inhaltlich tragend (zum Beispiel Footer-Brand): `alt=\"Conciso\"`. Dekorativ daneben (zum Beispiel Topnav-Wortmarke neben Text-Logo): `alt=\"\"` mit `aria-hidden=\"true\"` |\n| Kontrast | Mindestens 3:1 zwischen Logo und Hintergrund (WCAG 1.4.11, Non-Text Contrast). Default auf Weiß: 11,7:1. Light auf `--n-700`: 15,3:1 |\n| Theme-Wechsel | Logo-Swap via CSS und `[data-theme=\"dark\"]`-Selektor, funktioniert ohne JS und respektiert die Nutzer-Präferenz |\n| Skalierung | SVG ist auflösungsunabhängig, bleibt scharf bei beliebigem Browser-Zoom (WCAG 1.4.4) |\n\n### Dos & Don'ts\n\n✓ Tun\n\n- Default-Variante auf hellen, neutralen Hintergründen: der teal-Punkt verankert die Brand-Identität.\n- Light-Variante auf dunklen Hintergründen ab `--n-700` oder Hero-Gradients.\n- Dark-Variante (monochrom) für Druck, Stempel oder wo der teal-Punkt visuell stört.\n- Schutzraum von mindestens der „C“-Höhe um das Logo herum freihalten.\n- Logo proportional skalieren (Höhe als Leitmaß), der Vektor bleibt in jeder Größe scharf.\n- Theme-Swap nutzen: `.logo-themed-default` + `.logo-themed-light`, schaltet automatisch via `[data-theme]`.\n\n✕ Nicht tun\n\n- Logo stauchen, dehnen, rotieren oder schief stellen: immer proportional und gerade.\n- Den teal-Punkt durch andere Bereichsfarben ersetzen (KI-Lime, ES-Blau, WO-Grün), Default ist immer `--co-500`.\n- Default-Variante auf dunklem Hintergrund einsetzen: die dunkle Schrift verschwindet, der teal-Punkt wird zur isolierten Insel.\n- Logo unter 20 px Höhe digital oder 12 mm im Druck verwenden, der Punkt zerfällt.\n- Logo als PNG oder JPG einbinden, immer SVG verwenden, damit es scharf bleibt und der Theme-Swap funktioniert.\n- Logo als dekoratives Element in Texten, Mustern oder Hintergrundgrafiken einsetzen, es bleibt eigenständig.\n",
|
|
13
|
+
"summary": "# Verwendung Verwendungsregeln zum Logo: Größen, Schutzraum, Einsatz nach Hintergrund, Bar..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"marke-markenrad--übersicht": {
|
|
4
|
+
"id": "marke-markenrad--übersicht",
|
|
5
|
+
"name": "marke-markenrad--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"marke-markenrad--übersicht": {
|
|
8
|
+
"id": "marke-markenrad--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/marke/markenrad.mdx",
|
|
11
|
+
"title": "Marke/Markenrad",
|
|
12
|
+
"content": "import { Meta, Unstyled } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Marke/Markenrad\" name=\"Übersicht\" />\n\n# Markenrad\n\nDer Kernwert **Gelassenheit** entfaltet sich in drei Markenpfeilern (Ruhig, Klar, Energiegeladen) mit je drei charakterisierenden Eigenschaften. Das Unternehmen erzeugt Gelassenheit, auf ruhige, klare und energiegeladene Weise.\n\nDiese Seite ist die Begründungsschicht für die übrige Marke-Dokumentation (Brand Areas, Logo, Bildsprache): Wer eine dortige Regel hinterfragt, findet die Begründung hier.\n\n{/* Geometrie bewusst aus docs/index.html dupliziert: die Doku-Site ist eine statische\n Einzeldatei ohne Build, es gibt keinen gemeinsamen Import-Pfad für dieses SVG. Farben\n und Schriftgrößen kommen aus den .bw-*-Klassen in css/components.css und\n css/dark-mode.css, deshalb stimmt das Rad in Light und Dark automatisch mit der\n Doku-Site überein. */}\n\n<Unstyled>\n <div className=\"bw-wrap\">\n <svg viewBox=\"0 0 520 520\" className=\"bw-svg\" role=\"img\" aria-labelledby=\"bw-title bw-desc\">\n <title id=\"bw-title\">Markenrad: Ruhige Energie</title>\n <desc id=\"bw-desc\">Kreisdiagramm mit Kernwert Gelassenheit im Zentrum. Pfeiler Ruhig mit den Eigenschaften Verlässlich, Selbstsicher, Kompetent. Pfeiler Klar mit Aufmerksam, Präzise, Pragmatisch. Pfeiler Energiegeladen mit Kraftvoll, Agil, Leidenschaftlich.</desc>\n\n <path className=\"bw-outer\" d=\"M 73.8 367.5 A 215 215 0 0 1 260 45 L 260 100 A 160 160 0 0 0 121.4 340 Z\" />\n <path className=\"bw-outer\" d=\"M 260 45 A 215 215 0 0 1 446.2 367.5 L 398.6 340 A 160 160 0 0 0 260 100 Z\" />\n <path className=\"bw-outer\" d=\"M 446.2 367.5 A 215 215 0 0 1 73.8 367.5 L 121.4 340 A 160 160 0 0 0 398.6 340 Z\" />\n\n <path className=\"bw-middle\" d=\"M 121.4 340 A 160 160 0 0 1 260 100 L 260 175 A 85 85 0 0 0 186.4 302.5 Z\" />\n <path className=\"bw-middle\" d=\"M 260 100 A 160 160 0 0 1 398.6 340 L 333.6 302.5 A 85 85 0 0 0 260 175 Z\" />\n <path className=\"bw-middle\" d=\"M 398.6 340 A 160 160 0 0 1 121.4 340 L 186.4 302.5 A 85 85 0 0 0 333.6 302.5 Z\" />\n\n <circle className=\"bw-inner\" cx=\"260\" cy=\"260\" r=\"85\" />\n\n <line className=\"bw-divider\" x1=\"260\" y1=\"260\" x2=\"260\" y2=\"45\" />\n <line className=\"bw-divider\" x1=\"260\" y1=\"260\" x2=\"446.2\" y2=\"367.5\" />\n <line className=\"bw-divider\" x1=\"260\" y1=\"260\" x2=\"73.8\" y2=\"367.5\" />\n\n <circle className=\"bw-ring-outline\" cx=\"260\" cy=\"260\" r=\"215\" />\n\n <text className=\"bw-label-core\" x=\"260\" y=\"260\" textAnchor=\"middle\" dominantBaseline=\"middle\">GELASSENHEIT</text>\n\n <text className=\"bw-label-segment\" x=\"154\" y=\"199\" textAnchor=\"middle\" dominantBaseline=\"middle\">RUHIG</text>\n <text className=\"bw-label-segment\" x=\"366\" y=\"199\" textAnchor=\"middle\" dominantBaseline=\"middle\">KLAR</text>\n <text className=\"bw-label-segment\" x=\"260\" y=\"382\" textAnchor=\"middle\" dominantBaseline=\"middle\">ENERGIEGELADEN</text>\n\n <text className=\"bw-label-attr\" x=\"75.8\" y=\"292.5\" textAnchor=\"middle\" dominantBaseline=\"middle\">VERLÄSSLICH</text>\n <text className=\"bw-label-attr\" x=\"98\" y=\"166.5\" textAnchor=\"middle\" dominantBaseline=\"middle\">SELBSTSICHER</text>\n <text className=\"bw-label-attr\" x=\"196\" y=\"84\" textAnchor=\"middle\" dominantBaseline=\"middle\">KOMPETENT</text>\n\n <text className=\"bw-label-attr\" x=\"324\" y=\"84\" textAnchor=\"middle\" dominantBaseline=\"middle\">AUFMERKSAM</text>\n <text className=\"bw-label-attr\" x=\"422\" y=\"166.5\" textAnchor=\"middle\" dominantBaseline=\"middle\">PRÄZISE</text>\n <text className=\"bw-label-attr\" x=\"444\" y=\"292.5\" textAnchor=\"middle\" dominantBaseline=\"middle\">PRAGMATISCH</text>\n\n <text className=\"bw-label-attr\" x=\"380\" y=\"403\" textAnchor=\"middle\" dominantBaseline=\"middle\">KRAFTVOLL</text>\n <text className=\"bw-label-attr\" x=\"260\" y=\"447\" textAnchor=\"middle\" dominantBaseline=\"middle\">AGIL</text>\n <text className=\"bw-label-attr\" x=\"140\" y=\"403\" textAnchor=\"middle\" dominantBaseline=\"middle\">LEIDENSCHAFTLICH</text>\n </svg>\n </div>\n</Unstyled>\n\n## Drei Markenpfeiler\n\n| Pfeiler | Eigenschaften | Sprachliche Wirkung |\n|---|---|---|\n| Ruhig | Verlässlich · Selbstsicher · Kompetent | nicht aufgeregt, keine Verkaufs-Rhetorik, keine Übertreibungen |\n| Klar | Aufmerksam · Präzise · Pragmatisch | konkret statt blumig, kurze Sätze, eindeutige Verben |\n| Energiegeladen | Kraftvoll · Agil · Leidenschaftlich | aktive Verben, Tempo wo angemessen, Überzeugung statt Floskel |\n\nWirkt ein Text wie auf einer Beratungs-Mainstream-Seite („visionäre Lösungen für die digitale Transformation“), ist er nicht im Conciso-Ton.\n\nDie neun Eigenschaften (verlässlich, selbstsicher, kompetent, aufmerksam, präzise, pragmatisch, kraftvoll, agil, leidenschaftlich) sollen in Karten-Texten und längerer Copy spürbar werden, gern visuell hervorgehoben (`<strong>`).\n\n## Sprache & Schreibweise\n\nPrimärsprache ist **Deutsch**: alle Customer-Pages, Marketing-Texte, UI-Labels, Komponenten-Beispieltexte und Design-System-Dokumentation. Englische Fachbegriffe (zum Beispiel Token-Namen, Komponenten-Klassen, Code-Beispiele) bleiben unverändert, im Fließtext wird der englische Begriff übersetzt oder erläutert. Lokalisierung in andere Sprachen ist nicht vorgesehen.\n\n### Anführungszeichen\n\nDeutsche Typografie-Konvention „99 … 66“: öffnend unten, schließend oben.\n\n| Zeichen | Unicode | Position |\n|---|---|---|\n| „ | U+201E | Öffnend, unten (sieht aus wie 99) |\n| “ | U+201C | Schließend, oben (sieht aus wie 66) |\n\nNicht verwenden: ASCII-`\"` (U+0022, gerade), `”` (U+201D, „99 oben“) oder die englische Konvention `“…”`. `npm run check:quotes` prüft das Gate, auch für nicht committete Dateien.\n\n### Keine Gedankenstriche\n\nEm-Dashes (U+2014) und En-Dashes (U+2013) in eigenen Copy-Texten vermeiden. Sie wirken im deutschen Lesefluss englisch-zitathaft und schwächen den ruhigen Markenton.\n\n| Statt | Lieber |\n|---|---|\n| Wir machen Software — und zwar gute. | Wir machen Software, und zwar gute. |\n| Drei Bereiche – ein Anspruch. | Drei Bereiche, ein Anspruch. |\n| Schau Dir an, wie wir arbeiten — oder buch direkt ein Erstgespräch. | Schau Dir an, wie wir arbeiten, oder buch direkt ein Erstgespräch. |\n\nErsatz: Komma, Doppelpunkt, Punkt oder Klammern. Der mittige Punkt `·` (U+00B7) bleibt als Trenner in Meta-Listen erlaubt („Bereich · Lesezeit“).\n\n### Schreibregeln aus der Mikrocopy\n\nAus `mikrocopy-conventions.md`, schärfer als die allgemeine Tonalität:\n\n- **Aktiv statt Passiv.** „Wir entwickeln Systeme, die halten“ statt „Es werden Systeme entwickelt, die halten“.\n- **Konkrete Verben statt Adjektiv-Nebel.** „Wir hören erst zu, dann bauen wir“ statt „Aufmerksamer, partnerschaftlicher Ansatz“.\n- **Kein Marketing-Sprech.** Vermeiden: „state-of-the-art“, „cutting-edge“, „next level“, „digital transformation“, „synergetische Lösungen“, Buzzwords ohne Substanz.\n- **Zahlen sprechen.** „120+ Projekte, 10 Jahre, 70+ Menschen“ statt „Langjährige Erfahrung mit zahlreichen Kunden“.\n\n## Tonalität: Du statt Sie\n\nAuf der gesamten Webseite spricht Conciso Leserinnen und Leser mit **Du** an. Diese Entscheidung ist keine Stilfrage, sondern fällt direkt aus dem Markenrad: Wer Gelassenheit erzeugen will, kann nicht in der Distanz des „Sie“ sprechen. Das Du ist der konsequenteste Weg, die drei Pfeiler in einem Wort zusammenzubringen, und bleibt höflich, weil die Tonalität ruhig, klar und ehrlich ist, nicht kumpelhaft.\n\n| Pfeiler | wird zu |\n|---|---|\n| Ruhig | Vertrauen ohne Distanz. Das Du nimmt das Förmliche heraus, ohne die Verlässlichkeit zu verlieren. |\n| Klar | Direktheit ohne Floskeln. Wir sagen, was Sache ist, kürzer, präziser, ohne Konjunktiv-Wolken. |\n| Energiegeladen | Persönlichkeit ohne Lautstärke. Das Du holt die Leser:innen ins Gespräch, nicht ins Auditorium. |\n\n**Anrede** (aus `mikrocopy-conventions.md`, schärfer als der allgemeine Grundsatz):\n\n- Du-Form durchgängig, kleingeschrieben im Fließtext: „Du schilderst Deine Situation.“\n- Großschreibung in der höflichen Anrede, in CTAs und Formularfeldern: „Wie können wir Dir helfen?“, „Dein Anliegen“.\n- Kein Mischen von Du- und Sie-Anreden auf einer Seite.\n- Das Du wird konsequent großgeschrieben (Du, Dir, Dein, Deinem): eine Stilentscheidung, kein Tippfehler.\n\n### Ausnahme: Wann das Sie gilt\n\nDas Du ist die Regel für alle öffentlichen und redaktionellen Texte. In der direkten Kommunikation zwischen Dienstleister und Kunde kann die Hierarchie ein Sie verlangen. Dann geht Angemessenheit vor Marke: im Zweifel lieber das Sie wählen, als die Anrede zu erzwingen. Das Du folgt, sobald das Gegenüber es anbietet oder selbst nutzt.\n\n- **E-Mail an Kund:innen.** Herrscht Unsicherheit über die passende Anrede, tendiert Conciso zum Sie. Ein zu früh gesetztes Du kann distanzlos wirken, gerade im schriftlichen Erstkontakt.\n- **Veranstaltungen mit Leadership-Fokus.** Bei Veranstaltungen, zu denen vorrangig Leadership- und Entscheider:innen-Positionen erwartet werden, erfolgt die Ansprache im Sie, in der Einladung wie vor Ort.\n\n## Was nicht geht\n\nAus `mikrocopy-conventions.md`:\n\n- Mischung Du / Sie auf einer Seite.\n- „Erfolgreich!“ als Bestätigungstext (Floskel).\n- Generische Button-Texte („Senden“, „OK“, „Weiter“).\n- Übertreibungen ohne Substanz.\n- Anglizismen, wo deutsche Worte präziser sind („Termin buchen“ statt „Slot booken“).\n",
|
|
13
|
+
"summary": "# Markenrad Der Kernwert **Gelassenheit** entfaltet sich in drei Markenpfeilern (Ruhig, Kl..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"referenzen-quellen--übersicht": {
|
|
4
|
+
"id": "referenzen-quellen--übersicht",
|
|
5
|
+
"name": "referenzen-quellen--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"referenzen-quellen--übersicht": {
|
|
8
|
+
"id": "referenzen-quellen--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/referenzen.mdx",
|
|
11
|
+
"title": "Referenzen/Quellen",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Referenzen/Quellen\" name=\"Übersicht\" />\n\n# Quellen\n\nExterne Referenzen, die als Grundlage für Entscheidungen in diesem Design System dienten,\nsowie die Repo-internen Dokumente, die den Rest des Systems erschließen. Quelle der\nexternen Referenzen: `docs/index.html#sec-sources`.\n\n## Externe Referenzen\n\n| Thema | Quelle | Wofür |\n|---|---|---|\n| Komponentensystem | [Material Design](https://m3.material.io) | Grundlage für Komponentenarchitektur, Elevationssystem, Button-Typen, Card-Varianten und Spacing-Prinzipien |\n| Typografie | [Google Fonts](https://fonts.google.com) | Quelle für Libre Baskerville (Display/Headline) und Montserrat (Title/Body/Label), beide frei lizenziert (SIL Open Font License) |\n| Icons | [Heroicons](https://heroicons.com) | Icon-Bibliothek von Steve Schoger und den Machern von Tailwind CSS, Quelle für alle UI-Icons im Outline-Stil, frei unter MIT-Lizenz, optimiert auf 24×24 |\n| Barrierefreiheit | [WCAG 2.2 Quickref](https://www.w3.org/WAI/WCAG22/quickref/) | Offizielle Kriterien-Übersicht des W3C, Referenz für alle WCAG-Verweise in `Grundlagen/Barrierefreiheit` (Kontrast, Tastaturnavigation, ARIA, Touch Targets, Reduzierte Bewegung) |\n\n## Repo-Dokumente\n\nWer im Storybook landet und den Rest des Repos nicht kennt, findet hier den Einstieg:\n\n| Dokument | Wofür man es aufschlägt |\n|---|---|\n| `README.md` | Einstieg ins Repo: was das Design System ist, für wen es gedacht ist und wie die Doku-Site lokal geöffnet wird |\n| `CONTRIBUTING.md` | Die Konventionen, nach denen das System gebaut ist: Namensschema, Farbe und Kontrast, Elevation, Dark Mode, Typografie, Spacing, Doku-Struktur |\n| `CONTEXT.md` | Das Glossar des Repos: CSS-Schicht, Angular-Lib, Wrapper-Komponente, DS-Glyphen und weitere Begriffe genau so verwenden, wie sie dort definiert sind |\n| `docs/GETTING-STARTED.md` | Wie das Design System in ein Projekt eingebunden wird: Einbindereihenfolge der CSS-Dateien, Fonts, Dark Mode, optionales JavaScript, Tokens, Icons, Frameworks |\n| `docs/adr/` | Die Architekturentscheidungen des Repos als einzelne ADRs, etwa zur Angular-Lib als CSS-Wrapper (ADR-0001) oder zu Storybook, Docgen-Server und MCP (ADR-0006) |\n| `docs/agents/` | Die Agenten-Skills dieses Repos: Issue-Tracker, Triage-Labels, Storybook-Werkzeuge und die Domain-Doku-Struktur |\n",
|
|
13
|
+
"summary": "# Quellen Externe Referenzen, die als Grundlage für Entscheidungen in diesem Design System..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
package/snapshot/services/addon-docs/mdx/seitenmuster-angebots-detailseite--/303/274bersicht.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"seitenmuster-angebots-detailseite--übersicht": {
|
|
4
|
+
"id": "seitenmuster-angebots-detailseite--übersicht",
|
|
5
|
+
"name": "seitenmuster-angebots-detailseite--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"seitenmuster-angebots-detailseite--übersicht": {
|
|
8
|
+
"id": "seitenmuster-angebots-detailseite--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/seitenmuster/angebots-detailseite.mdx",
|
|
11
|
+
"title": "Seitenmuster/Angebots-Detailseite",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Seitenmuster/Angebots-Detailseite\" name=\"Übersicht\" />\n\n# Angebots-Detailseite\n\nPage-Pattern für die Landingpage eines einzelnen Angebots unterhalb eines Bereichs, an den\nBereich gebunden (`data-accent`). Quelle: `docs/index.html#sec-leistung-detail`. Beispiele\nin der Doku-Site: Erste Hilfe bei Meetingflut, Scrum Trainings, Lean Portfolio Management,\nIdentity mit Keycloak, Keycloak-Erweiterungen (siehe `Beispielseiten`, Gruppe Leistungen).\n\n## Aufbau\n\nReihenfolge nach Funnel-Logik: Aufmerksamkeit, Problem, Lösung, Vertrauen, Abschluss. Nicht\njede Sektion ist Pflicht, Angebots-Box und zusätzliche Rahmendaten hängen am Preismodell.\n\n| Sektion | Inhalt | Hintergrund |\n|---|---|---|\n| Topnav + Breadcrumb | Startseite / Bereich / Angebot, Leistungen plus Bereich hervorgehoben | weiß |\n| Hero | Hero-Image mit Caption, Eyebrow „Bereich · Kategorie“, H1 = Angebot, Lead | Bild |\n| Rahmendaten (nur falls die Angebots-Box sie nicht schon nennt) | Dauer, Umfang, Ergebnis, Preis als `.ep-facts` in der Angebots-Box, nicht als eigener Streifen | — |\n| Intro / Worum es geht | Zweispaltig, Serif-Lead plus Fließtext plus Bild plus CTAs | `--n-50` |\n| Problem / Herausforderung (optional) | Karten oder leichte Textblöcke (Akzentbalken) | weiß |\n| Ablauf / Lösung | Nummerierte Schritte (`<ol>`) oder Karten-Reihe | `--n-50` |\n| Angebots-Box + „Für wen“ (bei Festpreis) | Zweispaltig: Preis-Box plus Zielgruppe | `--n-50` |\n| Social Proof (optional) | Referenzen / Experte, direkt nach der Lösung | wechselnd |\n| Weiter im Thema | Zwei Cross-Link-Karten | wechselnd |\n| CTA-Band | Bereich-700, genau ein Handlungsaufruf | Bereich-700 |\n| Footer | Standard-Footer (siehe `Komponenten/Footer`) | grau |\n\n**Rhythmus:** Flächen weiß/`--n-50` strikt alternieren, keine zwei gleichen Hintergründe\nstapeln, im Dark läuft dieselbe Folge, Karten grenzen sich dort per Rand ab statt per\nTonstufe. Nur der Hero ist randlos, Zwischenbilder als `.ep-media-band` content-breit.\n\n## Angebots-Box\n\nFür Festpreis-Angebote: zweispaltig (`.layout-grid`, `align-items:start`), links die Box,\nrechts eine „Für wen das passt“-Häkchenliste. Die Box folgt der Konvention Elevation gleich\nInteraktivität (siehe `Komponenten/Cards & Teaser/Card`): statisch, also flach mit Rahmen\nund Top-Akzent, kein Schatten.\n\n| Element | Umsetzung |\n|---|---|\n| Container | `background:var(--bg-surface)`, `border:var(--bd-strong)`, `border-top:4px solid var(--XX-500)`, `border-radius:var(--r-lg)`, `padding:var(--s8)` |\n| Label | `--ty-label-xs`, uppercase, Bereichston über `.t-XX` (z. B. „Festpreis · in 3 Wochen“) |\n| Preis | `--ty-display-sm` · `--tx-primary`, MwSt.-Zusatz `--ty-body-sm` · `--tx-secondary` |\n| Leistungen | Häkchenliste, Haken über `.t-XX` („✓“), Text `--ty-body-md` |\n| CTA | `.btn-filled` in Bereichsfarbe → Kontaktseite (`data-k-bereich`/`data-k-anliegen`) |\n| „Für wen“ | `.col-5`-Häkchenliste, gleiche Haken, ohne Rahmen |\n\n**Fallstricke:** Padding aus der Skala, es gibt kein `--s7`, sonst fällt `padding` auf 0.\nFarbige Haken und Labels immer über `.t-XX` (dark-safe), nie als Inline-Bereichsfarbe. Nicht\nden dünnen 1-px-Rand nutzen: Mit dem 4-px-Top-Akzent entstehen sonst „Ohren“ an den oberen\nEcken, daher `--bd-strong`.\n\n## Preismodelle\n\nDrei Fälle, je nach Angebot:\n\n| Modell | Darstellung | Beispiel |\n|---|---|---|\n| Festpreis | Angebots-Box, sie nennt Laufzeit, Leistung und Ergebnis meist schon selbst, dann entfallen zusätzliche Rahmendaten | Meetingflut (3.600 €), Keycloak-Erweiterungen (9.900 €) |\n| Mehrere Pakete / Varianten | Preiskarten je Variante, nach Anbieter gruppiert | Scrum Trainings (Scrum.org / TÜV SÜD) |\n| Beratung ohne Festpreis | Kein Preis, CTA „individuelles Angebot“ | Lean Portfolio Management |\n\nDie MwSt.-Angabe (zzgl. oder inkl.) immer aus der Quelle übernehmen und je Seite einheitlich\nhalten. Preis nur einmal laut zeigen (Angebots-Box oder Preiskarte), nicht mehrfach\nwiederholen. Steht er dort, gehört er nicht zusätzlich in die Rahmendaten (siehe\n`Seitenmuster/Seminar · Training`, Abschnitt Rahmendaten).\n\n## Cross-Links „Weiter im Thema“\n\nAm Seitenende vor dem CTA-Band zwei `.ep-card-link`-Karten: zuerst Geschwister-Angebote im\nselben Bereich, dann ein Nachbar-Bereich als Cross-Sell. Titel als Frage, kurzer Text,\n`.ep-card-cta` „… ansehen →“. Verweise nur auf real existierende Seiten, „Landingpage\nfolgt“ bleibt ohne Link.\n\n## Verwendung\n\n**Dos**\n- Genau ein CTA-Ziel pro Seite (Kontaktformular), Erst- und Schluss-CTA konsistent\n benennen.\n- Social Proof (Referenzen/Experte) direkt nach der Lösung, solange das Interesse hoch ist.\n- Nur die Sektionen bauen, die das Angebot trägt, ohne Preis keine leere Preis-Box.\n\n**Don'ts**\n- Mehrere Card-Reihen stapeln, stattdessen leichte Textblöcke (Akzentbalken) zwischen den\n Card-Sektionen einstreuen.\n- Denselben Preis mehrfach laut wiederholen (Strip plus Karte plus Fließtext).\n- Sie-Anrede verwenden, das System ist durchgängig du/ihr.\n",
|
|
13
|
+
"summary": "# Angebots-Detailseite Page-Pattern für die Landingpage eines einzelnen Angebots unterhalb..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"seitenmuster-beitragsübersicht--übersicht": {
|
|
4
|
+
"id": "seitenmuster-beitragsübersicht--übersicht",
|
|
5
|
+
"name": "seitenmuster-beitragsübersicht--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"seitenmuster-beitragsübersicht--übersicht": {
|
|
8
|
+
"id": "seitenmuster-beitragsübersicht--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/seitenmuster/beitragsuebersicht.mdx",
|
|
11
|
+
"title": "Seitenmuster/Beitragsübersicht",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Seitenmuster/Beitragsübersicht\" name=\"Übersicht\" />\n\n# Beitragsübersicht\n\nPage-Pattern für Listing-Seiten mit Bereichs-Filter: zentrierter Header mit Lead,\nFilter-Chip-Leiste, ein Featured-Beitrag pro Bereich, der mit dem Filter rotiert, darunter\nein Card-Grid. Quelle: `docs/index.html#sec-listing`. Dasselbe Pattern trägt auch\n`Seitenmuster/Veranstaltungsübersicht`, dort mit „Format · Preis“ statt „Lesezeit“ in der\nPill und dem Anmeldungs-Flow statt des Beitrags-Lesers.\n\n## Aufbau\n\nDie Seite folgt einem Lesefluss von Orientierung über kuratierte Empfehlung zur freien\nErkundung:\n\n1. **Topnav** (siehe `Komponenten/Navigation/Topnav`): „Wissen“ mit `aria-current=\"page\"`.\n2. **Page-Header:** H1, Lead, optionales Such-Feld (`role=\"search\"` mit Magnifier-Icon und\n `<input type=\"search\">`), Filter-Chips. Zentriert, max. 720 px für die Lead-Breite. Der\n H1 trägt `--ty-display-sm` (36 px Serif), nicht kleiner, er ist der alleinige Page-Anker\n (Listings haben kein Hero-Image). So entsteht die Hierarchie 36 px H1, 28 px Section-H2,\n 24 px Featured-Card-Hero, 20 px Standard-Card-Titel.\n3. **Featured-Beitrag:** zweispaltige Hero-Card (Bild links im 16:9, Inhalt rechts),\n bereichsspezifisch, siehe Filter-aware Featured unten.\n4. **Beitrags-Grid:** `.card.card-elevated` in `.col-4` mit Bild oben, Pill „Bereich ·\n Lesezeit“, Titel, Lead und CTA „Beitrag lesen →“ am Karten-Unterrand.\n5. **„Mehr laden“-Block** (optional, ab vielen Beiträgen): zentrierter Outline-Button mit\n Counter darunter (`aria-live=\"polite\"`), lädt die nächste Beitragsseite nach. Alternative\n zu Pagination oder Infinite-Scroll, der Footer bleibt erreichbar und deterministisch\n zugänglich.\n6. **CTA-Band** für Newsletter oder vergleichbare Conversion.\n7. **Footer** (siehe `Komponenten/Footer`).\n\n**Header-Pattern, Editorial statt Marketing:** Der Page-Header ist bewusst zentriert, weil\ndie Seite zum Lesen und Stöbern einlädt, nicht zum Scannen einer Service-Übersicht. Das\nfolgt derselben Logik wie der Article-Header in `Seitenmuster/Wissensbeitrag`. Auf\nListing-Seiten gilt Editorial-Konvention, auf Service- und Marketing-Seiten\nMarketing-Konvention (linksbündig, `.ep-section-*`).\n\n## Such-Verhalten\n\nSuch-Konzept als Phase-1-Implementierung: vollständig client-seitig, ohne Backend.\nFunktioniert verlässlich bis rund 100 Beiträge, danach lohnt eine indexierte Lösung (Algolia,\nMeilisearch, eigener Service). Die folgenden Regeln beschreiben das Verhalten, nicht die\nImplementierung aus `docs/main.js`.\n\n| Aspekt | Verhalten |\n|---|---|\n| Instant-Search | Filtert beim Tippen mit 300 ms Debounce, kein Submit, keine separate Result-Page |\n| Such-Scope | Titel plus Lead plus Pill pro Card (case-insensitive Substring-Match), Body-Text bewusst ausgespart (zu teuer client-seitig, erzeugt False Positives) |\n| Kombination mit Filter | AND-Logik: aktiver Bereichs-Filter plus Suche ergibt die engere Schnittmenge |\n| Featured-Verhalten | Wird bei aktiver Suche komplett ausgeblendet, Featured ist redaktionell kuratiert, nicht algorithmisch |\n| Live-Count | `.wb-result-count` mit `role=\"status\" aria-live=\"polite\"`, nur während aktiver Suche sichtbar |\n| Empty State | Eigener Block ersetzt das Grid, kontextueller Detailtext, zwei Exit-Pfade (Reset, Newsletter) |\n| „Mehr laden“ | Wird bei aktiver Suche ausgeblendet, bei Filter-only bleibt der Block aktiv |\n\n**Tastatur und A11y:**\n\n| Eingabe | Aktion |\n|---|---|\n| `/` | Global-Shortcut, fokussiert das Such-Feld, wenn der Fokus nicht bereits in einem anderen Eingabefeld liegt |\n| `Esc` | Leert das Such-Feld, Fokus bleibt im Feld, Filter werden nicht zurückgesetzt |\n| `role=\"search\"` | Landmark um das gesamte Such-Feld, Screenreader können direkt dorthin springen |\n| `<input type=\"search\">` | Natives Such-Input mit Browser-X-Button zum Leeren, `aria-label` statt sichtbarem Label |\n\n## Filter-aware Featured\n\nDer Featured-Block enthält pro Bereich eine eigene Hero-Card. Alle drei Cards liegen im\nselben Container und tragen `data-area=\"ki|es|wo\"`. Per Default ist eine sichtbar, die\nanderen tragen `.is-hidden`. Beim Klick auf einen Filter-Chip blendet das JS die passende\nVariante ein. Für den Filter „Alle“ zeigt der Editorial-Pick (im Beispiel die KI-Variante).\n\n**Warum diese Variante:** Ein statisches Featured würde beim Filtern auf andere Bereiche\nthematisch nicht zur Auswahl passen. Eine versteckte Featured-Section lässt das Layout beim\nFilterwechsel um die Höhe der Card springen. Ein Featured pro Bereich erhält die topische\nKohärenz und vermeidet zugleich Layout-Sprünge.\n\n**Typografie:** Der Titel der Featured-Card nutzt `.card-title-hero` (24 px Serif,\nHeadline-sm) statt des Standard-`.card-title` (20 px Sans), das Featured ist ein\neditorialer Hero, kein Grid-Card.\n\n```html\n<section id=\"wb-featured-section\">\n <p class=\"ep-section-label\">Featured</p>\n <a class=\"card card-elevated\" data-area=\"ki\" href=\"…\">…</a>\n <a class=\"card card-elevated is-hidden\" data-area=\"es\" href=\"…\">…</a>\n <a class=\"card card-elevated is-hidden\" data-area=\"wo\" href=\"…\">…</a>\n</section>\n```\n\n## Verwendung\n\n| Aspekt | Regel |\n|---|---|\n| Filter-Chips | Toggle-Buttons mit `aria-pressed` und `data-filter=\"all\\|ki\\|es\\|wo\"`, aktiver Chip gefüllt in Petrol mit weißem Text |\n| Featured pro Bereich | Jede Variante als `.card.card-elevated` mit `data-area` im selben Container, nur eine sichtbar |\n| „Alle“-Default | Zeigt den Editorial-Pick, Konvention für Conciso: KI-Variante als Lead-Thema |\n| Grid-Karten | `.card.card-elevated.col-4` mit `data-area` auf Karte und Pill, CTA-Farbe einheitlich `--co-700` |\n| Pill-Form | „Bereich · Lesezeit“ mit `data-area` für den Bereichston, auf Listing-Seiten ohne Breadcrumb zulässig |\n| Layout-Stabilität | Featured-Section nie ganz verstecken, nur den Inhalt austauschen, sonst springt das Layout |\n\n**Dos**\n- Pro Bereich eine eigene Featured-Variante pflegen, kuratierter Top-Beitrag für die\n jeweilige Zielgruppe.\n- CTAs im Grid einheitlich in `--co-700`, die Bereichsfarbe trägt die Pill.\n- Featured-Card visuell anders strukturieren als Grid-Karten, damit die Hierarchie sofort\n lesbar ist.\n\n**Don'ts**\n- Featured beim Filterwechsel komplett ausblenden, das Layout springt um die Card-Höhe.\n- Statisches Featured eines Bereichs zeigen, während ein anderer Bereich aktiv gefiltert\n ist.\n- Featured und Grid-Karten gleich darstellen, ohne Hierarchie scrollen Nutzende am\n redaktionellen Anker vorbei.\n",
|
|
13
|
+
"summary": "# Beitragsübersicht Page-Pattern für Listing-Seiten mit Bereichs-Filter: zentrierter Heade..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"seitenmuster-seminar-·-training--übersicht": {
|
|
4
|
+
"id": "seitenmuster-seminar-·-training--übersicht",
|
|
5
|
+
"name": "seitenmuster-seminar-·-training--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"seitenmuster-seminar-·-training--übersicht": {
|
|
8
|
+
"id": "seitenmuster-seminar-·-training--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/seitenmuster/seminar.mdx",
|
|
11
|
+
"title": "Seitenmuster/Seminar · Training",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Seitenmuster/Seminar · Training\" name=\"Übersicht\" />\n\n# Seminar · Training\n\nPage-Pattern für die Landingpage eines einzelnen Seminars oder Trainings, an einen Bereich\ngebunden (Beispiel: Wirksame Organisationen, `data-accent=\"wo\"`). Quelle:\n`docs/index.html#sec-seminar`.\n\n## Aufbau\n\nReihenfolge nach Entscheidungslogik: erst Orientierung und Vertrauen, dann Buchung, dann\nTiefe. Das Vertrauen (Trainer) steht bewusst vor den Terminen.\n\n| Sektion | Inhalt | Hintergrund |\n|---|---|---|\n| Hero | Pill-Eyebrow plus große Headline plus Subline, kein CTA | Bereich-50 (getönt) |\n| Lernziele plus Angebots-Kasten | Zweispaltig: links (`.col-8`) die scanbare Bullet-Liste, rechts (`.col-4`) Preis und Rahmendaten. Ein eigener Fakten-Streifen unter dem Header entfällt bewusst | weiß |\n| Trainer | Bei einer Person das Profil groß, bei zwei bis vier `.author-card-group.is-grid` (siehe unten) | weiß |\n| Termine | Wiederholbare Termin-Zeilen plus Anmeldung | grau (`--n-50`) |\n| Inhalte & Voraussetzungen | Zweispaltig, Fließtext plus Sidebar | weiß |\n\n**Rhythmus:** ein getönter Hero als Akzent, danach Weiß/Grau-Wechsel, die letzte Sektion\nbleibt weiß, sodass der graue Footer sich klar absetzt (Haarlinie).\n\n## Rahmendaten · `.ep-facts`\n\nDauer, Format, Gruppengröße, Sprache, Preis: die Angaben, an denen sich entscheidet, ob ein\nAngebot passt. Sie stehen als semantische `<dl>` mit `.ep-facts`, einspaltig, Label über\nWert, Haarlinie zwischen den Paaren. Labels tragen den Bereichston über `.t-XX`, nie als\nInline-Farbe.\n\n**Zwei Darstellungen:** einspaltig als Grundform, zweispaltig über `.is-grid` für Kästen,\ndie neben Inhalt stehen (macht den Kasten kompakter, verzichtet dafür auf die Haarlinien und\neignet sich nur für kurze Werte, lange Werte brauchen die Grundform). Über `auto-fit` wird\nsie in schmalen Kästen von selbst wieder einspaltig.\n\nDie Liste bringt keinen eigenen Rahmen und keine Fläche mit, sie zieht in einen Container\nein, den die Seite schon hat (Angebots-Box oder Sticky-Sidebar). Nur wenn eine Seite keinen\nsolchen Container hat, bekommt sie einen schlichten eigenen. Vorher prüfen, was der\nContainer schon sagt: Eine Angebots-Box nennt Laufzeit, Leistung und Ergebnis oft bereits\nim Label und in der Häkchenliste, dann entfällt die Liste ganz. Doppelte Angaben sind\nschlimmer als fehlende, sie lesen sich wie zwei Quellen, die sich widersprechen könnten.\n\n**Kein eigener Streifen unter dem Hero.** Die Angaben standen früher als eigener\nKey-Facts-Streifen zwischen Hero und erster Inhaltssektion. Sie sitzen jetzt dort, wo auch\nüber das Angebot entschieden wird, das hält sie an einer Stelle statt an zweien.\n\n```html\n<!-- Ohne eigenen Rahmen: steht bereits in einer Angebots-Box oder Sidebar. -->\n<dl class=\"ep-facts\">\n <div>\n <dt class=\"t-wo\">Dauer</dt>\n <dd>2 Tage, 9 bis 17 Uhr</dd>\n </div>\n <!-- weitere Paare, nur Angaben, die der Container nicht schon nennt -->\n</dl>\n```\n\n## Trainer:innen\n\nDie Sektion steht bewusst vor den Terminen: Wer bucht, will vorher wissen, wer vorne steht.\nTrainer:innen kommen nur auf Seminar- und Training-Landings vor, nicht in Wissensbeiträgen.\nMarkup-seitig sind sie keine eigene Komponente, sondern die Author Card (siehe\n`Seitenmuster/Wissensbeitrag`, Abschnitt Author Card) in einer Gruppe:\n`.author-card-group` stapelt untereinander, `.author-card-group.is-grid` stellt sie\nzweispaltig. Eine gemeinsame `.author-card-group-eyebrow` ersetzt die Eyebrows der einzelnen\nKarten, trägt die Sektion bereits ein `.ep-section-label` plus H2, entfällt sie.\n\n**Wann welche Darstellung:** Die Entscheidung fällt an der Personenzahl, nicht am\nGeschmack.\n\n| Personen | Darstellung | Warum |\n|---|---|---|\n| 1 | Große Sektion: Bild im Format 4:3 in `.col-5`, Name, Rolle und Bio in `.col-7` | Bei genau einer Person trägt das große Bild, ein 64-px-Avatar wirkt beiläufig, obwohl die Person hier das Vertrauen stiftet |\n| 2 bis 4 | `.author-card-group.is-grid`, Avatar `.article-avatar-lg` (64 px), ein bis zwei Sätze Bio | Gestapelt würden vier volle Bios die Sektion über 1.500 px lang machen und die Termine aus dem Blick schieben |\n| Mehr als 4 | Nicht mit diesem Muster, auf die durchführenden Personen kürzen oder auf das Team-Tile-Grid ohne Bio wechseln | Ab der dritten Reihe liest niemand mehr Bios |\n\n**Warum Raster statt Tile-Grid:** Das Team-Tile-Grid (siehe `Seitenmuster/Wissensbeitrag`)\nstellt vier Personen kompakter dar, aber ohne Bio. Auf einer Landing, die etwas verkauft,\nist die Bio das Argument, sie beantwortet, warum diese Person das Training hält. Container\nist 960 statt 720 px, weil zwei Karten nebeneinander sonst je rund 340 px hätten und der\nAvatar den Text auf etwa 260 px drückt. Mobil kollabiert das Raster bei 768 px einspaltig.\n\n```html\n<!-- Gemeinsame Überschrift ist optional: Trägt die Sektion bereits ein\n .ep-section-label plus H2, entfällt sie. -->\n<p class=\"author-card-group-eyebrow\">Trainer:innen</p>\n<div class=\"author-card-group is-grid\">\n <!-- Unveränderte Author Card, nur ohne .author-card-eyebrow -->\n <div class=\"author-card\" data-area=\"wo\">\n <div class=\"article-avatar article-avatar-lg\" data-area=\"wo\" aria-hidden=\"true\">TM</div>\n <div>\n <p class=\"author-card-name\">Tobias Mehnert</p>\n <p class=\"author-card-role\">Senior-Berater Organisationsentwicklung</p>\n <p class=\"author-card-bio\">Begleitet seit über 15 Jahren Veränderungsvorhaben.</p>\n </div>\n </div>\n <!-- 1 bis 3 weitere Karten, insgesamt maximal 4 -->\n</div>\n```\n\n## Termine-Modul\n\nBeliebig wiederholbare Termin-Zeile (`<li>`) mit linker Bereichs-Akzentleiste. Der\nAnmeldebutton führt auf die adaptive Kontaktseite mit vorbelegtem Bereich und Anliegen.\n\n**Anfrage statt Direktbuchung:** Das ist bewusst so, weil Seminartermine bei Conciso oft im\nGespräch entstehen. Steht bei einem Angebot der Preis pro Platz fest und ist das Kontingent\nbekannt, gehört stattdessen das Buchungsformular (siehe `Komponenten/Buchungsformular`) auf\ndie Seite.\n\n| Element | Umsetzung |\n|---|---|\n| Datum / Ort | Datum `--ty-title-sm`, Ort oder „Online“ `--ty-body-sm` · `--tx-secondary` |\n| Termingarantie / Status | `.badge-ok` „Durchführung garantiert“ wenn gesichert, sonst neutraler Status-Text („Noch Plätze frei“) |\n| Anmeldung | `.btn-sm` in Bereichsfarbe „Platz anfragen“ → Kontaktseite (`data-k-bereich`/`data-k-anliegen`) |\n| Leerzustand | Ohne offene Termine entfällt die Liste, stattdessen Hinweis „nur auf Anfrage“ plus Outlined-CTA „Termin anfragen“ |\n\n## Inhalte & Sticky-Sidebar\n\nHauptteil zweispaltig (`.layout-grid`, `align-items:start`): links (`.col-8`) langer\nFließtext mit eingestreuten Bildern und den Voraussetzungen als Unterabschnitt, rechts\n(`.col-4`) das Kontaktformular. Preis und Rahmendaten sitzen nicht hier, sondern weiter oben\nneben den Lernzielen. Die Formular-Überschrift ist ein gefüllter Bereichsbalken und sitzt\noben auf ihrer eigenen Karte.\n\n**Sticky:** Die Sidebar trägt `position:sticky;top:var(--s4)` und läuft in Produktion beim\nScrollen mit. Auf Mobile rutscht die Sidebar unter den Fließtext.\n\n## Buchungs-Anker\n\nAm Ende der Inhalte ein dezenter Text-Link „Zu den Terminen“ als In-Page-Anker auf die\nTermine-Sektion (`id=\"seminar-termine\"`), smooth-scrollend. Schließt die Buchungs-Schleife\nohne zweites CTA-Band.\n\n## Verwendung\n\n**Dos**\n- Vertrauen (Trainer, Belege) vor die Termine setzen, die Buchung folgt der Überzeugung.\n- Rahmendaten und Preis dort zeigen, wo über das Angebot entschieden wird, das\n Termine-Modul auch im Leerzustand bedienen.\n\n**Don'ts**\n- Viele große Bilder pro Sektion, wenige platzierte Bilder halten den Lesefluss ruhig.\n- Buchungs-CTA nur ganz oben, ohne Anker am Seitenende.\n",
|
|
13
|
+
"summary": "# Seminar · Training Page-Pattern für die Landingpage eines einzelnen Seminars oder Traini..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"seitenmuster-veranstaltung--übersicht": {
|
|
4
|
+
"id": "seitenmuster-veranstaltung--übersicht",
|
|
5
|
+
"name": "seitenmuster-veranstaltung--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"seitenmuster-veranstaltung--übersicht": {
|
|
8
|
+
"id": "seitenmuster-veranstaltung--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/seitenmuster/veranstaltung.mdx",
|
|
11
|
+
"title": "Seitenmuster/Veranstaltung",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Seitenmuster/Veranstaltung\" name=\"Übersicht\" />\n\n# Veranstaltung\n\nPage-Pattern für die Detail-Seite einer einzelnen Veranstaltung: Hero-Image, Meta-Strip mit\nKey-Facts, Sub-Strip mit Anmeldungs-CTAs, Themen-Cards, Agenda, Speaker:innen und\nAnmeldungs-Form. Liegt in der Topnav unter „Unternehmen“. Quelle:\n`docs/index.html#sec-event`. Die zugehörige Listing-Seite ist\n`Seitenmuster/Veranstaltungsübersicht`.\n\n## Aufbau\n\nDie Detail-Seite führt vom „Worum geht's?“ über „Wann, wo, wieviel?“ zur Anmeldung:\n\n1. **Topnav** mit „Unternehmen“ als `aria-current=\"page\"`.\n2. **Hero-Image** (siehe `Komponenten/Hero`) mit Eyebrow im Schema „Fokusveranstaltung ·\n Format · Preis“, H1 (Veranstaltungs-Titel), Lead.\n3. **Meta-Strip:** vier Info-Badges in einem Strip (Datum, Ort, Format, Eintritt), siehe\n unten.\n4. **Sub-Strip** in Bereichsfarbe-50 mit Markenrad-Eyebrow, Lead und zwei CTAs („Platz\n sichern“ plus „Programm ansehen“ als In-Page-Anker).\n5. **Themen-Cards** (3× `.card.card-elevated.col-4`) mit „Input 1/2/3“-Eyebrow als\n Programm-Vorschau.\n6. **Agenda und Speaker** (siehe unten).\n7. **Anmeldungs-Form** (siehe unten).\n8. **Page-End-CTA-Band** und **Footer** (siehe `Komponenten/Footer`).\n\nIn-Page-Anker (`href=\"#ev-anmeldung\"`, `href=\"#ev-agenda\"`) animieren das Scrollen. Bei\n`prefers-reduced-motion: reduce` bleibt der Hard-Jump erhalten.\n\n## Meta-Strip\n\nDirekt unter dem Hero stehen vier Info-Badges in einem Strip: Datum, Ort, Format, Eintritt.\nSie beantworten die Hard-Filter-Fragen, bevor der Besuch in die Themen-Cards einsteigt.\n\n| Element | Spezifikation |\n|---|---|\n| Container | `.layout-grid` mit vier `.col-3`-Spalten, vertikaler Strip mit `padding-block:var(--s8)`, Border-Bottom in `--n-100` |\n| Badge | 40×40 Round (`--r-full`) in Bereichsfarbe-50 (`--{area}-50`) |\n| Icon | Small (24×24, Stroke 1,25) in Bereichsfarbe-700 (`--{area}-700`) |\n| Label | Eyebrow-Style: `--ty-label-xs`, `letter-spacing:.09em`, uppercase, `color:var(--{area}-700)` |\n| Value | 16 px medium (`font:500 16px/24px var(--font)`), `color:var(--tx-primary)` |\n| Helper | Optional in `--ty-body-md`, `--tx-secondary`, z. B. „18:00 bis 21:00 Uhr“ unter dem Datum |\n| Sekundär-Link | Optional, unterstrichen in Bereichsfarbe-700, z. B. „Karte öffnen →“ |\n\n## Programm & Speaker\n\nDie Agenda ist eine Zeit-Tabelle (Spalte 120 px für Uhrzeit, Spalte 1fr für Titel plus\nSpeaker) mit Border-Bottom je Zeile. Uhrzeiten in `font-variant-numeric:tabular-nums` für\nsaubere vertikale Ausrichtung der Ziffern.\n\nSpeaker:innen folgen dem Author-Card-Pattern (siehe `Seitenmuster/Wissensbeitrag`, Abschnitt\nAuthor Card) mit Initialen oder Foto, Name, Rolle und kurzer Bio. Bei mehreren\nSpeaker:innen pro Veranstaltung analog zu „Mehrere Autor:innen“ im selben Muster.\n\n```html\n<div style=\"display:grid;grid-template-columns:120px 1fr;gap:var(--s4) var(--s6);padding:var(--s4) 0;border-bottom:1px solid var(--n-200);align-items:baseline\">\n <div style=\"font:500 14px/20px var(--font);color:var(--es-700);font-variant-numeric:tabular-nums\">18:30 bis 18:50</div>\n <div>\n <div style=\"font:500 16px/24px var(--font);color:var(--tx-primary)\">Input 1 · Warum n8n gerade jetzt</div>\n <div style=\"font:var(--ty-body-md);color:var(--tx-secondary)\">mit Marc Hoffmann</div>\n </div>\n</div>\n```\n\n## Anmeldung\n\nDie Anmeldungs-Form folgt dem Kontaktformular-Pattern (siehe\n`Komponenten/Inputs & Forms/Textfeld` und verwandte Felder), aber im Bereich-Theme der\nVeranstaltung: Header in Bereichsfarbe-700 mit weißem Text, Form-Body in `var(--n-50)`.\nAnker-ID `#ev-anmeldung` für den „Platz sichern“-Sprung aus dem Sub-Strip.\n\n| Element | Regel |\n|---|---|\n| Form-Header | Vollbreite Banner in `--{area}-700` mit weißem Text, trägt H2 und kurzen Lead |\n| Form-Body | `background:var(--n-50)`, `padding:var(--s6)`, Felder zweispaltig (Vorname, Nachname), Single-Field für E-Mail, Select für Rolle/Erfahrung, Textarea für „Was Dich beschäftigt“ |\n| Submit-Button | `.btn.btn-filled.btn-{area}.btn-full`, Text formatabhängig: „Platz reservieren“ (Meet-Up), „Anmelden & bezahlen“ (kostenpflichtiges Training) |\n| Anker-ID | `id=\"ev-anmeldung\"` auf dem Form-Container |\n| Datenschutz-Konsent | Checkbox vor dem Submit-Button, `accent-color:var(--{area}-700)` trifft das Bereich-Theme auch im nativen Browser-Render |\n\n## Formate\n\nConciso nutzt ausschließlich fünf Veranstaltungsformate. Pill, Format-Filter und das\nFormat-Feld im Meta-Strip kennen nur diese Begriffe.\n\n| Format | Wofür | Typische Länge | Preis |\n|---|---|---|---|\n| Meet-Up | Kurze Abend-Veranstaltungen, Inputs plus offene Runde, oft kostenlos | 2 bis 3 Stunden, abends | Kostenlos |\n| Konferenz | Größere Multi-Speaker-Veranstaltungen mit Track-Programm | 1 bis 2 Tage | Eintritts-Tickets |\n| Training | Strukturierte Lerneinheit mit Hands-On-Anteil | Halbtägig bis mehrtägig | Pauschal pro Teilnehmer:in |\n| Webinar | Online-Format, meist kürzer und niedrigschwelliger | 1 bis 4 Stunden, online | Kostenlos oder Pauschal |\n| Jobmesse | Recruiting-Veranstaltung | Stunden bis halbtägig | Kostenlos |\n\n**Charakter-Wörter im Titel sind erlaubt.** Titel wie „Refactoring Bootcamp“ oder\n„Retro-Werkstatt“ dürfen Marketing-Wörter als Branding tragen. Die Pill kategorisiert\ndennoch nach den fünf Formaten. Klebt der Charakter-Begriff direkt an der Pill und die\nInkonsistenz fällt auf (Titel „AI Readiness Workshop“, Pill „Training“), wird der Titel\numbenannt.\n\n## Datum & Uhrzeit\n\nZwei Prinzipien: Wochentag als Hard-Filter zuerst, Monatsnamen ausgeschrieben.\n\n| Kontext | Format | Beispiel |\n|---|---|---|\n| Eintägig mit Uhrzeit | Wt, T. Monat JJJJ · HH:MM | Fr, 5. Februar 2027 · 18:00 |\n| Eintägig ganztägig | Wt, T. Monat JJJJ · ganztägig | Di, 9. März 2027 · ganztägig |\n| Halbtägig | Wt, T. Monat JJJJ · halbtägig | Do, 10. Juni 2027 · halbtägig |\n| Mehrtägig | Wt1 & Wt2, T1. / T2. Monat JJJJ | Mo & Di, 22. / 23. Februar 2027 |\n| Zeitspanne (Meta-Strip-Helper) | HH:MM bis HH:MM Uhr | 18:00 bis 21:00 Uhr |\n\nWochentag-Abkürzungen: Mo, Di, Mi, Do, Fr, Sa, So (zwei Buchstaben, ohne Punkt). Bei\nMehrtages-Spans optional ausgeschrieben, im Card-Kontext kurz halten.\n\n## Verwendung\n\n| Aspekt | Regel |\n|---|---|\n| Hero-Eyebrow | Schema „Fokusveranstaltung · Format · Preis“, für Konferenzen ersetzbar durch „Konferenz“ |\n| Bereich-Theme | Komplette Seite trägt eine Bereichsfarbe (ki, es, wo), nicht Corporate-Petrol |\n| Anker-Konvention | `#ev-anmeldung` für Form, `#ev-agenda` für Agenda, beide smooth-scrollend |\n| Speaker-Pflicht | Jede Veranstaltung mindestens einer Speaker:in zuordnen, anonyme Programme reduzieren die Anmeldebereitschaft |\n| Submit-Button-Label | Format-spezifisch: „Platz reservieren“ (Meet-Up), „Anmelden & bezahlen“ (kostenpflichtig), „Ticket buchen“ (Konferenz) |\n\n**Dos**\n- Komplette Detail-Seite in einem Bereich-Theme halten, Mischfarben irritieren beim\n Anmeldeschritt.\n- Meta-Strip mit allen vier Badges zeigen, auch wenn ein Wert „Kostenlos“ oder „Online“\n ist.\n- Speaker:innen mit Foto oder Initialen plus Bio nennen.\n- Smooth-Scroll bei In-Page-Ankern, außer bei `prefers-reduced-motion`.\n\n**Don'ts**\n- Generic-Form ohne Bereich-Header.\n- Eigene Format-Begriffe einführen.\n- Programm ohne Uhrzeiten oder ohne benannte Speaker.\n- Datum nur als Zahl („05.02.2027“) ohne Wochentag und ausgeschriebenen Monat.\n",
|
|
13
|
+
"summary": "# Veranstaltung Page-Pattern für die Detail-Seite einer einzelnen Veranstaltung: Hero-Imag..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"seitenmuster-veranstaltungsübersicht--übersicht": {
|
|
4
|
+
"id": "seitenmuster-veranstaltungsübersicht--übersicht",
|
|
5
|
+
"name": "seitenmuster-veranstaltungsübersicht--übersicht",
|
|
6
|
+
"docs": {
|
|
7
|
+
"seitenmuster-veranstaltungsübersicht--übersicht": {
|
|
8
|
+
"id": "seitenmuster-veranstaltungsübersicht--übersicht",
|
|
9
|
+
"name": "Übersicht",
|
|
10
|
+
"path": "./src/docs/seitenmuster/veranstaltungsuebersicht.mdx",
|
|
11
|
+
"title": "Seitenmuster/Veranstaltungsübersicht",
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Seitenmuster/Veranstaltungsübersicht\" name=\"Übersicht\" />\n\n# Veranstaltungsübersicht\n\nListing-Seite für Veranstaltungen, parallel zu `Seitenmuster/Beitragsübersicht`: zentrierter\nHeader mit Suche und Bereichs-Filter, Featured pro Bereich, Card-Grid darunter. Quelle:\n`docs/index.html#sec-events`. Die Detail-Seite ist separat als `Seitenmuster/Veranstaltung`\ndokumentiert.\n\n## Aufbau\n\nDie Übersichts-Seite folgt im Wesentlichen dem Aufbau der Beitragsübersicht: zentrierter\nHeader, Such-Feld, Filter-Chips pro Bereich, Featured pro Bereich, Card-Grid darunter,\n„Mehr laden“-Block, CTA-Band, Footer. Such-Logik und Filter-aware-Featured sind 1:1\nübernommen und über eine gemeinsame Funktion `setupListPage()` konfiguriert.\n\n**Anpassungen gegenüber der Beitragsübersicht:**\n\n- **Pill-Inhalt:** „Bereich · Format“ statt „Bereich · Lesezeit“, das Format-Vokabular ist\n auf fünf Begriffe begrenzt (siehe `Seitenmuster/Veranstaltung`, Abschnitt Formate).\n- **Card-Meta:** Datum (mit Wochentag) und Ort sitzen oberhalb des Titels, nicht am\n Card-Fuß. Datum ist der wichtigste Hard-Filter und kommt vor dem Titel-Investment.\n- **Default-Featured:** „Effektive Software“ statt „Angewandte KI“.\n- **Counter:** „6 anstehend · 18 im Archiv“ statt „6 von 24 Beiträgen“, weil Veranstaltungen\n zeitlich gebunden sind und Vergangenes nicht im Default-View erscheint.\n- **Empty-State-Sekundär-CTA:** „Veranstaltungs-Newsletter“ statt „Contentletter\n abonnieren“.\n\n## Veranstaltungs-Card\n\nDer Reading-Flow ist auf die Entscheidung für eine Veranstaltung optimiert. Für\nVeranstaltungen ist das Datum ein harter Filter („Kann ich überhaupt?“) und gehört vor das\nTitel-Investment.\n\n**Reihenfolge:** Bild (Atmosphäre, optional), Pill „Bereich · Format“ (Filter-Check), Datum\nmit Wochentag (Kalender-Check), Ort („Dortmund“ für vor Ort, „Online“ für Webinar), Titel\n(Interesse-Hook), Body (worum geht's), CTA „Zur Veranstaltung →“.\n\n| Element | Style | Begründung |\n|---|---|---|\n| Pill | `.pill` mit `data-area`, ohne `style` | Bereichsfarbe als Filter-Signal, die Eigenmarge nehmen `.card-body` und `.card-featured-body` selbst zurück |\n| Meta-Trio (Datum, Ort, Format) | `--ty-body-sm` (14 px), `--tx-muted`, vertikal gestapelt | Editorial-Listen-Look, Hard-Filter über die Reihenfolge, nicht über visuelle Hervorhebung |\n| Ort-Spezifik | Stadt-Name oder „Online“ | Bei Webinaren „Online“, sonst Stadt-Name, nicht der Venue |\n| Icons | Micro (16×16, Stroke 1) | Konvention für Inline-Meta-Icons |\n| CTA | `color:var(--co-700)`, `margin-top:auto` | Einheitliche Bereichs-übergreifende CTA-Farbe, Auto-Margin für gemeinsame Baseline |\n\n## Featured, horizontale Großkarte\n\nFür Landing-Sektionen und Bereichs-Hubs, wenn genau ein kommender Termin hervorgehoben\nwerden soll (kein Grid, kein Listing). Eine horizontale `.card.card-elevated.card-featured`\nals Anker, links das Bild im 16:9-Verhältnis, rechts der Content-Block: Pill, Meta-Strip\n(Datum, Ort, Format), Titel, Lead, CTA. Die Bildspalte trägt `.card-media` mit demselben\nVerhältnis wie die Listing-Cards, Redaktion pflegt ein Bild in einem Zuschnitt für Featured\nund Grid. Die Spaltenteilung (60 Prozent Bild, 40 Prozent Content) liegt in der Klasse, nicht\nim `style`-Attribut. Auf Tablet-Breite verschiebt sie sich auf 65/35, unter 900 px\nKartenbreite wird gestapelt.\n\n**Editorial-Variant:** Featured-Cards nutzen `.card-title-hero` (24 px Serif, Headline-sm)\nstatt der 20 px Sans des Standard-`.card-title`. Ein Termin bekommt die alleinige Bühne,\ndas rechtfertigt das Serif-Treatment zwischen Section-H2 (28 px Serif) und\nStandard-Card-Title (20 px Sans).\n\n**Warum nicht ein Grid mit drei Karten?** Auf einer Landing ist die Frage „Was passiert als\nNächstes?“ wichtiger als „Welche Veranstaltungen laufen aktuell?“. Ein einziges,\natmosphärisch bebildertes Highlight kommuniziert klarer als drei kleinere Cards. Die\nÜbersichts-Seite erfüllt die Breitenrolle, der Featured-Block auf der Landing die\nTiefenrolle.\n\n```html\n<a class=\"card card-elevated card-featured\" data-area=\"es\" href=\"/veranstaltungen/n8n\">\n <div class=\"card-media\"><img src=\"hero.jpg\" alt=\"\" aria-hidden=\"true\" style=\"object-position:center 35%\"></div>\n <div class=\"card-featured-body\">\n <span class=\"pill\" data-area=\"es\">Effektive Software</span>\n <div style=\"display:flex;flex-direction:column;gap:var(--s2);font:var(--ty-body-sm);color:var(--tx-muted)\">\n <span>Do, 3. Dezember 2026 · 18:00</span>\n <span>WORKGARDEN Dortmund</span>\n <span>Meet-Up</span>\n </div>\n <h3 class=\"card-title-hero\">Effizienz durch n8n.</h3>\n <p class=\"card-text\">Drei kurze Inputs …</p>\n <span class=\"card-cta-link\">Zur Veranstaltung <span aria-hidden=\"true\">→</span></span>\n </div>\n</a>\n```\n\n| Aspekt | Featured (Landing) | Standard-Card (Listing) |\n|---|---|---|\n| Anlass | Genau ein hervorgehobener Termin | Mehrere parallel sichtbare Termine |\n| Layout | Horizontal, 16:9 Bild plus Content, drei Stufen nach Kartenbreite | Vertikal, 16:9 Bild über Content |\n| Headline | `.card-title-hero` (24 px Serif) | `.card-title` (20 px Sans), `line-clamp:2` |\n| Lead | `.card-text`, `min-height:0`, `line-clamp` bleibt als Riegel gegen zu lange Leads | `.card-text` mit `line-clamp:3` |\n| Meta-Strip | Datum, Ort, Format vertikal gestapelt, `--ty-body-sm`, `--tx-muted` | Pill „Bereich“ über Datum plus Ort gestapelt |\n| Kürzen bei zu viel Text | Das Bild bestimmt die Höhe, der Lead gibt zuerst nach (`line-clamp`) | Titel `line-clamp:2`, Text `line-clamp:3`, Gleichhöhe über `min-height` |\n\n## Verwendung\n\n| Aspekt | Regel |\n|---|---|\n| Pill-Vokabular | Nur die fünf Formate, keine eigenen Wörter wie „Workshop“ oder „Bootcamp“ |\n| Pill-Margin | Kein `margin-bottom` im Markup, `.card-body` und `.card-featured-body` nehmen die Eigenmarge der Pill selbst zurück |\n| Pill-Breite | Kein `width:fit-content` und kein `align-self` im Markup, die Pill bringt das selbst mit |\n| Datums-Reihenfolge | Cards chronologisch, kommende Veranstaltungen zuerst, Vergangenes über „Frühere Veranstaltungen ansehen“ oder Archiv-Filter |\n| Datums-Format | Wochentag plus ausgeschriebener Monat |\n| Card-Ort | Stadt-Name, nicht der Venue, für Webinar „Online“ |\n| Filter-Logik | Drei Bereichs-Chips (ki, es, wo), kein Corporate-Chip |\n| Such-Scope | Titel plus Lead plus Pill über `setupListPage()`, Datum und Ort sind nicht Teil des Such-Index |\n| CTA-Text | Einheitlich „Zur Veranstaltung →“ |\n\n**Dos**\n- Datum vor Titel platzieren, „Kann ich da?“ ist der wichtigste Filter.\n- Wochentag mitgeben, macht bei Meet-Ups nach 18:00 den Unterschied.\n- Pill auf das Format-Vokabular beschränken, Charakter-Begriffe gehören in den Titel.\n- Monatsnamen ausschreiben, passt zur Marken-Tonalität.\n\n**Don'ts**\n- Datum am Card-Fuß platzieren (Wissensbeitrag-Muster).\n- Vergangene Veranstaltungen im Default-View mischen.\n- Eigene Format-Begriffe einführen.\n- Preis und Verfügbarkeit auf jeder Card zeigen, das gehört auf die Detail-Seite.\n",
|
|
13
|
+
"summary": "# Veranstaltungsübersicht Listing-Seite für Veranstaltungen, parallel zu `Seitenmuster/Bei..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|