@conciso/design-system-mcp 0.0.0-bootstrap.0 → 2.4.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/README.md +118 -23
- package/package.json +16 -2
- package/snapshot/manifests/components.json +10 -0
- package/snapshot/manifests/docs.json +1 -9
- package/snapshot/services/addon-docs/mdx/grundlagen-einrichtung--/303/274bersicht.json +2 -2
- package/snapshot/services/addon-docs/mdx/komponenten-buttons-button.json +18 -0
- package/snapshot/services/addon-docs/mdx/marke-bildsprache--/303/274bersicht.json +1 -1
- package/snapshot/services/addon-docs/mdx/marke-markenrad--/303/274bersicht.json +1 -1
- package/snapshot/services/core/docgen/komponenten-buttons-button.json +23 -2
- package/snapshot/services/core/story-docs/komponenten-buttons-button.json +8 -3
- package/snapshot/services/core/story-docs/komponenten-inputs-forms-radio.json +5 -0
- package/snapshot/services/addon-docs/mdx/komponenten-buttons--verwendung.json +0 -18
package/README.md
CHANGED
|
@@ -1,34 +1,82 @@
|
|
|
1
1
|
# @conciso/design-system-mcp
|
|
2
2
|
|
|
3
|
-
MCP-Server für
|
|
4
|
-
|
|
5
|
-
[Angular-Lib](https://www.npmjs.com/package/@conciso/design-system-angular)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
MCP-Server für das Conciso Design System. Er gibt deinem KI-Assistenten (Claude Code,
|
|
4
|
+
GitHub Copilot in VS Code, Cursor und andere) die echte, dokumentierte API der
|
|
5
|
+
[Angular-Lib](https://www.npmjs.com/package/@conciso/design-system-angular) an die Hand,
|
|
6
|
+
passend zu der Version, die in deinem Projekt installiert ist.
|
|
7
|
+
|
|
8
|
+
## Wozu?
|
|
9
|
+
|
|
10
|
+
KI-Assistenten kennen das Conciso Design System nicht. Fragst du nach einem Button mit Icon,
|
|
11
|
+
erfinden sie gern Inputs wie `icon` oder `iconPosition`, Elemente wie `<cds-icon>` oder
|
|
12
|
+
vergessen, dass die CSS-Schicht global eingebunden sein muss. Der Code sieht plausibel aus
|
|
13
|
+
und funktioniert nicht.
|
|
14
|
+
|
|
15
|
+
Mit diesem Server schlägt der Assistent nach, bevor er Code schreibt: welche Komponenten es
|
|
16
|
+
gibt, welche Inputs und Outputs sie haben, wie die Beispiele im Storybook aussehen. Gibt es
|
|
17
|
+
etwas nicht, sagt er das, statt es zu erfinden.
|
|
18
|
+
|
|
19
|
+
In unserem eigenen Test mit sechs typischen Fragen hat die KI ohne Server bei drei Fragen
|
|
20
|
+
Inputs oder Elemente erfunden, mit Server bei keiner.
|
|
21
|
+
|
|
22
|
+
## Was er kann
|
|
23
|
+
|
|
24
|
+
| Werkzeug | Liefert |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `docs-list` | alle Komponenten der Angular-Lib und alle Doku-Seiten des Storybooks mit ihren IDs |
|
|
27
|
+
| `docs-show` | zu einer Komponente die Inputs und Outputs mit Typen, Standardwerten und Beschreibung, dazu Code-Beispiele aus den Stories; zu einer Doku-Seite ihren vollständigen Text |
|
|
28
|
+
| `docs-show-story` | den Code einer einzelnen Story-Variante |
|
|
29
|
+
|
|
30
|
+
Beim Verbinden gibt der Server dem Assistenten außerdem feste Regeln mit:
|
|
31
|
+
|
|
32
|
+
1. CSS-Schicht und Fonts global einbinden, sonst bleiben die Komponenten ungestylt.
|
|
33
|
+
2. Kein eigenes CSS für Design-System-Komponenten, keine erfundenen CSS-Klassen.
|
|
34
|
+
3. Nur Inputs und Outputs verwenden, die `docs-show` liefert. Vorher nachsehen, nie raten.
|
|
35
|
+
4. Bei Fragen zur Einrichtung die Storybook-Seite „Einrichtung“ lesen.
|
|
36
|
+
|
|
37
|
+
Weitere Eigenschaften:
|
|
38
|
+
|
|
39
|
+
- **Offline.** Die Daten liegen als Snapshot des Storybook-Builds im Paket. Der Server
|
|
40
|
+
öffnet keinen Port und greift auf kein Netzwerk zu.
|
|
41
|
+
- **Versionsgenau.** Der Snapshot gehört zu genau einer Version des Design Systems. Beim
|
|
42
|
+
Start vergleicht der Server seine Version mit der installierten Angular-Lib und weist den
|
|
43
|
+
Assistenten bei Abweichung darauf hin. Er bricht dabei nie ab.
|
|
44
|
+
|
|
45
|
+
## Beispiel
|
|
46
|
+
|
|
47
|
+
> Schreib mir einen Conciso-Button in der Variante „outlined“, Bereich „ki“, groß,
|
|
48
|
+
> deaktiviert, mit Icon links.
|
|
49
|
+
|
|
50
|
+
Der Assistent ruft `docs-list` und `docs-show` für den Button auf, findet dort die Inputs
|
|
51
|
+
`area`, `disabled`, `full`, `label`, `size`, `type` und `variant` und antwortet:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<cds-button label="Vorschau" variant="outlined" area="ki" size="lg" [disabled]="true" />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Dazu der Hinweis, dass der Button keinen Input für ein Icon hat, statt eines erfundenen.
|
|
58
|
+
|
|
59
|
+
## Voraussetzungen
|
|
60
|
+
|
|
61
|
+
- Node.js 20 oder neuer
|
|
62
|
+
- ein KI-Assistent, der MCP-Server über stdio einbinden kann
|
|
9
63
|
|
|
10
64
|
## Installation
|
|
11
65
|
|
|
12
|
-
|
|
13
|
-
Projekt die CSS-Schicht nur kopiert statt installiert hat, dann mit fester Version statt
|
|
14
|
-
`latest`, passend zum kopierten Stand):
|
|
66
|
+
Empfohlen als Entwicklungsabhängigkeit, in derselben Version wie die Angular-Lib:
|
|
15
67
|
|
|
16
68
|
```bash
|
|
17
69
|
npm i -D @conciso/design-system-mcp
|
|
18
70
|
```
|
|
19
71
|
|
|
20
|
-
|
|
21
|
-
npx
|
|
22
|
-
```
|
|
72
|
+
Hält dein Projekt das Design System nicht als Paket, sondern als kopierte Dateien, startest
|
|
73
|
+
du den Server ohne Installation über `npx` mit fester Version (siehe unten, „Versionen“).
|
|
23
74
|
|
|
24
|
-
|
|
25
|
-
MCP-Server gibt es erst ab einer späteren Version als die CSS-Schicht; welche Versionen
|
|
26
|
-
existieren, zeigt `npm view @conciso/design-system-mcp versions`. Ist dein Stand älter, nimm
|
|
27
|
-
die älteste verfügbare Version und aktualisiere die Kopie bei Gelegenheit.
|
|
75
|
+
## Einbinden
|
|
28
76
|
|
|
29
|
-
|
|
77
|
+
Die Konfiguration als Datei im Projekt committen, dann hat das ganze Team den Server.
|
|
30
78
|
|
|
31
|
-
|
|
79
|
+
**Claude Code**, `.mcp.json` im Projektordner:
|
|
32
80
|
|
|
33
81
|
```json
|
|
34
82
|
{
|
|
@@ -41,19 +89,66 @@ Mit installiertem Paket, als `.mcp.json` im Projekt committen:
|
|
|
41
89
|
}
|
|
42
90
|
```
|
|
43
91
|
|
|
44
|
-
|
|
92
|
+
Oder per Befehl: `claude mcp add --scope project conciso-ds -- npx cds-mcp`
|
|
93
|
+
|
|
94
|
+
**VS Code / GitHub Copilot**, `.vscode/mcp.json`:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"servers": {
|
|
99
|
+
"conciso-ds": {
|
|
100
|
+
"type": "stdio",
|
|
101
|
+
"command": "npx",
|
|
102
|
+
"args": ["cds-mcp"]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Cursor**, `.cursor/mcp.json`:
|
|
45
109
|
|
|
46
110
|
```json
|
|
47
111
|
{
|
|
48
112
|
"mcpServers": {
|
|
49
113
|
"conciso-ds": {
|
|
50
114
|
"command": "npx",
|
|
51
|
-
"args": ["-
|
|
115
|
+
"args": ["cds-mcp"]
|
|
52
116
|
}
|
|
53
117
|
}
|
|
54
118
|
}
|
|
55
119
|
```
|
|
56
120
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
121
|
+
**Ohne installiertes Paket** ersetzt du in allen drei Varianten `"args": ["cds-mcp"]` durch
|
|
122
|
+
`"args": ["-y", "@conciso/design-system-mcp@<Version>"]`.
|
|
123
|
+
|
|
124
|
+
## Versionen
|
|
125
|
+
|
|
126
|
+
Angular-Lib, CSS-Schicht und MCP-Server tragen immer dieselbe Versionsnummer. Aktualisierst
|
|
127
|
+
du die Lib, aktualisiere den Server mit, dann passt die Doku zum Code.
|
|
128
|
+
|
|
129
|
+
Nutzt du den Server ohne installiertes Paket, ist `<Version>` die Version der CSS-Schicht,
|
|
130
|
+
die dein Projekt verwendet. Den MCP-Server gibt es erst ab einer späteren Version als die
|
|
131
|
+
CSS-Schicht; welche Versionen existieren, zeigt `npm view @conciso/design-system-mcp versions`.
|
|
132
|
+
Ist dein Stand älter, nimm die älteste verfügbare Version und aktualisiere die Kopie bei
|
|
133
|
+
Gelegenheit. Die automatische Versionsprüfung greift in diesem Fall nicht, der Server nennt
|
|
134
|
+
dann nur, für welche Version sein Snapshot gilt.
|
|
135
|
+
|
|
136
|
+
## Grenzen
|
|
137
|
+
|
|
138
|
+
- Die Werkzeuge beschreiben die **Angular-Lib**. Projekte ohne Angular (etwa Astro oder
|
|
139
|
+
statisches HTML) finden auf der Seite „Einrichtung“ und in den Komponenten-Beschreibungen
|
|
140
|
+
die CSS-Klassen, eigene HTML-Beispiele liefert der Server noch nicht.
|
|
141
|
+
- Design-Tokens und Icons lassen sich noch nicht direkt abfragen.
|
|
142
|
+
- Der Server sieht nur, was im Storybook dokumentiert ist. Was dort fehlt, gilt für ihn als
|
|
143
|
+
nicht vorhanden.
|
|
144
|
+
|
|
145
|
+
## Mehr
|
|
146
|
+
|
|
147
|
+
- Storybook des Design Systems mit allen Komponenten:
|
|
148
|
+
<https://conciso.github.io/conciso-design-system/>
|
|
149
|
+
- Einrichtung Schritt für Schritt, mit und ohne Angular:
|
|
150
|
+
[Storybook-Seite „Einrichtung“](https://conciso.github.io/conciso-design-system/?path=/docs/grundlagen-einrichtung--%C3%BCbersicht)
|
|
151
|
+
|
|
152
|
+
## Lizenz
|
|
153
|
+
|
|
154
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conciso/design-system-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "MCP-Server für Consumer des Conciso Design System, beantwortet docs-list, docs-show und docs-show-story über stdio aus einem mitgelieferten Storybook-Snapshot, ohne Netzzugriff.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,5 +44,19 @@
|
|
|
44
44
|
"@eslint/js": "^10.0.1",
|
|
45
45
|
"eslint": "^10.6.0",
|
|
46
46
|
"globals": "^17.12.0"
|
|
47
|
-
}
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://conciso.github.io/conciso-design-system/",
|
|
49
|
+
"keywords": [
|
|
50
|
+
"mcp",
|
|
51
|
+
"mcp-server",
|
|
52
|
+
"model-context-protocol",
|
|
53
|
+
"design-system",
|
|
54
|
+
"conciso",
|
|
55
|
+
"angular",
|
|
56
|
+
"storybook",
|
|
57
|
+
"claude",
|
|
58
|
+
"copilot",
|
|
59
|
+
"cursor",
|
|
60
|
+
"ai"
|
|
61
|
+
]
|
|
48
62
|
}
|
|
@@ -46,6 +46,16 @@
|
|
|
46
46
|
},
|
|
47
47
|
"stories": {
|
|
48
48
|
"$ref": "../services/core/story-docs/komponenten-buttons-button.json#/components/komponenten-buttons-button"
|
|
49
|
+
},
|
|
50
|
+
"docs": {
|
|
51
|
+
"komponenten-buttons-button--verwendung": {
|
|
52
|
+
"id": "komponenten-buttons-button--verwendung",
|
|
53
|
+
"name": "Verwendung",
|
|
54
|
+
"mdx": {
|
|
55
|
+
"$ref": "../services/addon-docs/mdx/komponenten-buttons-button.json#/components/komponenten-buttons-button/docs/komponenten-buttons-button--verwendung"
|
|
56
|
+
},
|
|
57
|
+
"summary": "# Verwendung Buttons sind die primäre Aktions-Komponente des Systems: fünf Stilvarianten (..."
|
|
58
|
+
}
|
|
49
59
|
}
|
|
50
60
|
},
|
|
51
61
|
"komponenten-chips-badges-pills-chip": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"mdx": {
|
|
40
40
|
"$ref": "../services/addon-docs/mdx/grundlagen-einrichtung--übersicht.json#/components/grundlagen-einrichtung--übersicht/docs/grundlagen-einrichtung--übersicht"
|
|
41
41
|
},
|
|
42
|
-
"summary": "# Einrichtung So bindest du das Conciso Design System in ein
|
|
42
|
+
"summary": "# Einrichtung So bindest du das Conciso Design System in ein Projekt ein, von der Installa..."
|
|
43
43
|
},
|
|
44
44
|
"grundlagen-spacing-grid--übersicht": {
|
|
45
45
|
"id": "grundlagen-spacing-grid--übersicht",
|
|
@@ -89,14 +89,6 @@
|
|
|
89
89
|
},
|
|
90
90
|
"summary": "# Barrierefreiheit Kontrastverhältnisse aller Brand-Farben, Tastaturnavigation, ARIA Patte..."
|
|
91
91
|
},
|
|
92
|
-
"komponenten-buttons--verwendung": {
|
|
93
|
-
"id": "komponenten-buttons--verwendung",
|
|
94
|
-
"name": "Verwendung",
|
|
95
|
-
"mdx": {
|
|
96
|
-
"$ref": "../services/addon-docs/mdx/komponenten-buttons--verwendung.json#/components/komponenten-buttons--verwendung/docs/komponenten-buttons--verwendung"
|
|
97
|
-
},
|
|
98
|
-
"summary": "# Verwendung Buttons sind die primäre Aktions-Komponente des Systems: fünf Stilvarianten (..."
|
|
99
|
-
},
|
|
100
92
|
"komponenten-chips-badges-pills--verwendung": {
|
|
101
93
|
"id": "komponenten-chips-badges-pills--verwendung",
|
|
102
94
|
"name": "Verwendung",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"name": "Übersicht",
|
|
10
10
|
"path": "./src/docs/grundlagen/einrichtung.mdx",
|
|
11
11
|
"title": "Grundlagen/Einrichtung",
|
|
12
|
-
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Grundlagen/Einrichtung\" name=\"Übersicht\" />\n\n# Einrichtung\n\nSo bindest du das Conciso Design System in ein Angular-Projekt ein, von der Installation\nbis zur ersten Komponente, und schließt optional eine KI daran an.\n\n## Beide Pakete installieren\n\nAngular-Lib und CSS-Schicht tragen immer dieselbe Versionsnummer und liegen öffentlich auf\nnpmjs.org, du brauchst keinen Account und kein Token:\n\n```bash\nnpm i @conciso/design-system @conciso/design-system-angular\n```\n\n**Alternative: GitHub Packages.** Für Consumer innerhalb der GitHub-Organisation\n`conciso` liegen beide Pakete zusätzlich privat, org-scoped in GitHub Packages. Dafür\neine `.npmrc` im Projekt anlegen, die den `@conciso`-Scope umleitet, plus ein Token mit\nScope `read:packages` auch fürs Lesen (in GitHub Actions genügt `secrets.GITHUB_TOKEN`):\n\n```ini\n@conciso:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n```\n\nAusführliche Anleitung (Token-Beschaffung, CI vs. lokaler Rechner): README von\n`@conciso/design-system-angular` auf\n[npmjs.com](https://www.npmjs.com/package/@conciso/design-system-angular).\n\n## CSS und Fonts global einbinden\n\nDie Angular-Lib liefert **kein eigenes CSS**: Die Wrapper-Komponenten setzen nur die\nvorhandenen Klassen der CSS-Schicht zusammen, das Styling kommt aus einem globalen\nCascade, der sich nicht pro Komponente kapseln lässt. Fehlt dieser Schritt, erscheinen die\nKomponenten ungestylt.\n\n**`angular.json`** → `architect.build.options`, Eintrag `assets` ergänzen (`css` und\n`fonts` werden unverändert kopiert, kein CSS-Bundling durch den Angular-Build, deshalb\n`assets` statt `styles`):\n\n```jsonc\n{\n \"assets\": [\n // … bestehende Einträge (z. B. \"public\") …\n {\n \"glob\": \"**/*\",\n \"input\": \"node_modules/@conciso/design-system/css\",\n \"output\": \"conciso/css\"\n },\n {\n \"glob\": \"**/*\",\n \"input\": \"node_modules/@conciso/design-system/fonts\",\n \"output\": \"conciso/fonts\"\n }\n ]\n}\n```\n\n**`src/index.html`**, CSS in genau dieser Reihenfolge laden (fonts → tokens → dark-mode →\nbase → components; `fonts.css` referenziert die Font-Dateien relativ als `../fonts/*`,\n`conciso/css` und `conciso/fonts` müssen also Geschwisterordner bleiben):\n\n```html\n<link rel=\"stylesheet\" href=\"conciso/css/fonts.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/tokens.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/dark-mode.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/base.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/components.css\" />\n```\n\n**Kritisches CSS deaktivieren.** Der Angular-Production-Build versucht standardmäßig,\nreferenziertes CSS als kritisches CSS zu inlinen. Das über `assets` eingebundene CSS liegt\nzu diesem Zeitpunkt aber noch nicht im Ausgabeverzeichnis, das führt zu harmlosen, aber\nvermeidbaren Build-Warnungen. In `architect.build.configurations.production` ergänzen:\n\n```jsonc\n{\n \"optimization\": {\n \"scripts\": true,\n \"fonts\": true,\n \"styles\": { \"minify\": true, \"inlineCritical\": false }\n }\n}\n```\n\nWeitere Details: README von `@conciso/design-system-angular` auf\n[npmjs.com](https://www.npmjs.com/package/@conciso/design-system-angular).\n\n## Erste Komponente verwenden\n\n```ts\nimport { ButtonComponent } from '@conciso/design-system-angular';\n```\n\n```html\n<cds-button area=\"co\" variant=\"filled\" label=\"Kontakt\" />\n```\n\n`area` (Default `co`), `variant` (Default `filled`) und `label` (Default `Button`) sind die\ndokumentierten Inputs von `ButtonComponent`. Vollständige Liste mit allen Varianten:\n`Komponenten/Buttons/Button` in diesem Storybook, oder per KI-Assistent das Werkzeug\n`docs-show` (siehe unten).\n\n## KI-Assistenten anbinden\n\nDas Design System bringt einen eigenen MCP-Server mit: `@conciso/design-system-mcp`\n(`bin`: `cds-mcp`), Transport stdio, kein Port, nichts im Netz erreichbar. Er liefert\ndieselben Werkzeuge, mit denen auch diese Seite entstanden ist (`docs-list`, `docs-show`,\n`docs-show-story`), als mitgelieferten Snapshot passend zur installierten Version, ohne\nLive-Abruf von einer Website.\n\n```bash\nnpm i -D @conciso/design-system-mcp\n```\n\n**Versionen synchron halten.** Der Server vergleicht beim Start seine eigene Version mit\nder installierten Version der Angular-Lib und **warnt** bei Abweichung (in seinen\n`instructions` und auf stderr), bricht aber nicht ab. Am einfachsten: alle drei Pakete\ngemeinsam auf derselben Version installieren oder aktualisieren, zum Beispiel\n`npm i @conciso/design-system@X @conciso/design-system-angular@X\n@conciso/design-system-mcp@X`.\n\n### Claude Code\n\nEmpfohlen als committete Projektdatei `.mcp.json` im Repo-Root:\n\n```json\n{\n \"mcpServers\": {\n \"conciso-ds\": {\n \"command\": \"npx\",\n \"args\": [\"cds-mcp\"]\n }\n }\n}\n```\n\n### VS Code / GitHub Copilot\n\n`.vscode/mcp.json`, Schlüssel `servers`, mit explizitem `\"type\": \"stdio\"` (laut aktueller\nVS-Code-Doku ein Pflichtfeld für stdio-Server):\n\n```json\n{\n \"servers\": {\n \"conciso-ds\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"cds-mcp\"]\n }\n }\n}\n```\n\n### Cursor\n\n`.cursor/mcp.json`, Schlüssel `mcpServers`:\n\n```json\n{\n \"mcpServers\": {\n \"conciso-ds\": {\n \"command\": \"npx\",\n \"args\": [\"cds-mcp\"]\n }\n }\n}\n```\n\nAlle drei Varianten starten denselben Prozess über stdio, ohne laufenden Dienst und ohne\nPort.\n\n## Siehe auch\n\n- `Komponenten/Buttons/Button` in diesem Storybook\n- README von `@conciso/design-system` auf\n [npmjs.com](https://www.npmjs.com/package/@conciso/design-system)\n- README von `@conciso/design-system-angular` auf\n [npmjs.com](https://www.npmjs.com/package/@conciso/design-system-angular)\n- README von `@conciso/design-system-mcp` auf\n [npmjs.com](https://www.npmjs.com/package/@conciso/design-system-mcp)\n",
|
|
13
|
-
"summary": "# Einrichtung So bindest du das Conciso Design System in ein
|
|
12
|
+
"content": "import { Meta } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Grundlagen/Einrichtung\" name=\"Übersicht\" />\n\n# Einrichtung\n\nSo bindest du das Conciso Design System in ein Projekt ein, von der Installation bis zum\nersten Element, und schließt optional eine KI daran an. Zwei Wege stehen offen: mit\nAngular-Wrapper-Komponenten, oder rein über die CSS-Schicht, etwa in Astro oder einem\nstatischen HTML-Projekt.\n\n## Mit Angular einrichten\n\n### Beide Pakete installieren\n\nAngular-Lib und CSS-Schicht tragen immer dieselbe Versionsnummer und liegen öffentlich auf\nnpmjs.org, du brauchst keinen Account und kein Token:\n\n```bash\nnpm i @conciso/design-system @conciso/design-system-angular\n```\n\n**Alternative: GitHub Packages.** Für Consumer innerhalb der GitHub-Organisation\n`conciso` liegen beide Pakete zusätzlich privat, org-scoped in GitHub Packages. Dafür\neine `.npmrc` im Projekt anlegen, die den `@conciso`-Scope umleitet, plus ein Token mit\nScope `read:packages` auch fürs Lesen (in GitHub Actions genügt `secrets.GITHUB_TOKEN`):\n\n```ini\n@conciso:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}\n```\n\nAusführliche Anleitung (Token-Beschaffung, CI vs. lokaler Rechner): README von\n`@conciso/design-system-angular` auf\n[npmjs.com](https://www.npmjs.com/package/@conciso/design-system-angular).\n\n### CSS und Fonts global einbinden\n\nDie Angular-Lib liefert **kein eigenes CSS**: Die Wrapper-Komponenten setzen nur die\nvorhandenen Klassen der CSS-Schicht zusammen, das Styling kommt aus einem globalen\nCascade, der sich nicht pro Komponente kapseln lässt. Fehlt dieser Schritt, erscheinen die\nKomponenten ungestylt.\n\n**`angular.json`** → `architect.build.options`, Eintrag `assets` ergänzen (`css` und\n`fonts` werden unverändert kopiert, kein CSS-Bundling durch den Angular-Build, deshalb\n`assets` statt `styles`):\n\n```jsonc\n{\n \"assets\": [\n // … bestehende Einträge (z. B. \"public\") …\n {\n \"glob\": \"**/*\",\n \"input\": \"node_modules/@conciso/design-system/css\",\n \"output\": \"conciso/css\"\n },\n {\n \"glob\": \"**/*\",\n \"input\": \"node_modules/@conciso/design-system/fonts\",\n \"output\": \"conciso/fonts\"\n }\n ]\n}\n```\n\n**`src/index.html`**, CSS in genau dieser Reihenfolge laden (fonts → tokens → dark-mode →\nbase → components; `fonts.css` referenziert die Font-Dateien relativ als `../fonts/*`,\n`conciso/css` und `conciso/fonts` müssen also Geschwisterordner bleiben):\n\n```html\n<link rel=\"stylesheet\" href=\"conciso/css/fonts.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/tokens.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/dark-mode.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/base.css\" />\n<link rel=\"stylesheet\" href=\"conciso/css/components.css\" />\n```\n\n**Kritisches CSS deaktivieren.** Der Angular-Production-Build versucht standardmäßig,\nreferenziertes CSS als kritisches CSS zu inlinen. Das über `assets` eingebundene CSS liegt\nzu diesem Zeitpunkt aber noch nicht im Ausgabeverzeichnis, das führt zu harmlosen, aber\nvermeidbaren Build-Warnungen. In `architect.build.configurations.production` ergänzen:\n\n```jsonc\n{\n \"optimization\": {\n \"scripts\": true,\n \"fonts\": true,\n \"styles\": { \"minify\": true, \"inlineCritical\": false }\n }\n}\n```\n\nWeitere Details: README von `@conciso/design-system-angular` auf\n[npmjs.com](https://www.npmjs.com/package/@conciso/design-system-angular).\n\n### Erste Komponente verwenden\n\n```ts\nimport { ButtonComponent } from '@conciso/design-system-angular';\n```\n\n```html\n<cds-button area=\"co\" variant=\"filled\" label=\"Kontakt\" />\n```\n\n`area` (Default `co`), `variant` (Default `filled`) und `label` (Default `Button`) sind die\ndokumentierten Inputs von `ButtonComponent`. Vollständige Liste mit allen Varianten:\n`Komponenten/Buttons/Button` in diesem Storybook, oder per KI-Assistent das Werkzeug\n`docs-show` (siehe unten).\n\n## Ohne Angular einrichten\n\nKein Angular-Projekt, etwa Astro oder statisches HTML? Dann fällt der Angular-Lib-Teil\nweg, übrig bleibt die CSS-Schicht `@conciso/design-system` allein, dieselbe Quelle, die\nauch die Angular-Wrapper oben nutzen.\n\n### Paket installieren (empfohlen)\n\n```bash\nnpm i @conciso/design-system\n```\n\nAm einfachsten das gebündelte Einzel-CSS importieren (Ladereihenfolge und Fonts bereits\nenthalten):\n\n```js\nimport '@conciso/design-system';\n// entspricht: import '@conciso/design-system/dist/conciso-ds.css';\n```\n\nBrauchst du stattdessen nur einzelne Dateien, etwa nur `tokens.css` ohne die fertigen\nKomponentenklassen, importierst du sie einzeln, in genau dieser Reihenfolge (fonts →\ntokens → dark-mode → base → components):\n\n```js\nimport '@conciso/design-system/css/fonts.css';\nimport '@conciso/design-system/css/tokens.css';\nimport '@conciso/design-system/css/dark-mode.css';\nimport '@conciso/design-system/css/base.css';\nimport '@conciso/design-system/css/components.css';\n```\n\n### Dateien direkt kopieren\n\nHält dein Projekt die CSS-Schicht stattdessen als kopierte Dateien vor, ganz ohne\n`npm install` und ohne Build, gilt dieselbe Reihenfolge wie oben, nur als `<link>`-Tags\n(Tokens definieren Variablen, Dark-Mode überschreibt sie, Base setzt Grundlagen, Components\nnutzt alles):\n\n```html\n<link rel=\"stylesheet\" href=\"css/fonts.css\" />\n<link rel=\"stylesheet\" href=\"css/tokens.css\" />\n<link rel=\"stylesheet\" href=\"css/dark-mode.css\" />\n<link rel=\"stylesheet\" href=\"css/base.css\" />\n<link rel=\"stylesheet\" href=\"css/components.css\" />\n```\n\n`fonts.css` referenziert die Font-Dateien relativ als `../fonts/*`, der `fonts`-Ordner\nmuss also als Geschwisterordner neben `css` liegen, sonst brechen die `@font-face`-Regeln.\n\n**Alternative: ein einziges Bundle.** Statt der fünf Dateien reicht auch ein einzelner\nLink auf das gebündelte CSS (Reihenfolge und `@font-face`-Regeln bereits enthalten):\n\n```html\n<link rel=\"stylesheet\" href=\"dist/conciso-ds.css\" />\n```\n\nAuch hier muss `fonts` als Geschwisterordner neben `dist` liegen: Die `url(...)`-Pfade im\nBundle lösen relativ zur CSS-Datei auf.\n\n### Astro\n\nCSS aus einem npm-Paket bindest du in Astro am saubersten global in einem Layout ein: ein\nESM-`import` im Frontmatter der Layout-Komponente, oben bei den übrigen Imports. Am\neinfachsten mit dem gebündelten CSS:\n\n```astro\n---\nimport '@conciso/design-system';\n---\n```\n\nBrauchst du stattdessen nur einzelne Dateien, importierst du sie einzeln, in derselben\nReihenfolge wie oben (fonts → tokens → dark-mode → base → components):\n\n```astro\n---\nimport '@conciso/design-system/css/fonts.css';\nimport '@conciso/design-system/css/tokens.css';\nimport '@conciso/design-system/css/dark-mode.css';\nimport '@conciso/design-system/css/base.css';\nimport '@conciso/design-system/css/components.css';\n---\n```\n\nKopierte Dateien statt des npm-Pakets bindest du in Astro genauso über `<link>`-Tags im\nLayout ein, wie oben unter „Dateien direkt kopieren“ beschrieben.\n\n### Erstes Element verwenden\n\nKein Framework nötig, die Komponenten sind CSS-Klassen auf normalem HTML:\n\n```html\n<button type=\"button\" class=\"btn btn-filled btn-co\">Kontakt</button>\n```\n\nWelche Klassen zu welcher Variante gehören, zeigt die Storybook-Seite der jeweiligen\nKomponente (z. B. `Komponenten/Buttons/Button` in diesem Storybook), oder per KI-Assistent\ndas Werkzeug `docs-show` (siehe unten).\n\n## KI-Assistenten anbinden\n\nDas Design System bringt einen eigenen MCP-Server mit: `@conciso/design-system-mcp`\n(`bin`: `cds-mcp`), Transport stdio, kein Port, nichts im Netz erreichbar. Er liefert\ndieselben Werkzeuge, mit denen sich auch diese Seite abfragen lässt (`docs-list`,\n`docs-show`, `docs-show-story`), als mitgelieferten Snapshot passend zur installierten\nVersion, ohne Live-Abruf von einer Website. Zwei Wege, ihn einzubinden: mit installiertem\nPaket, oder per `npx` ganz ohne Installation, etwa wenn dein Projekt die CSS-Schicht nur\nkopiert statt installiert hat (siehe oben, „Dateien direkt kopieren“).\n\n### Mit installiertem Paket\n\n```bash\nnpm i -D @conciso/design-system-mcp\n```\n\n**Versionen synchron halten.** Der Server vergleicht beim Start seine eigene Version mit\nder installierten Version der Angular-Lib und **warnt** bei Abweichung (in seinen\n`instructions` und auf stderr), bricht aber nicht ab. Am einfachsten: alle drei Pakete\ngemeinsam auf derselben Version installieren oder aktualisieren, zum Beispiel\n`npm i @conciso/design-system@X @conciso/design-system-angular@X\n@conciso/design-system-mcp@X`. Ohne Angular-Projekt bleibt dieser automatische Abgleich\naus, auch mit installiertem `@conciso/design-system-mcp`: Die Prüfung vergleicht bislang\nnur gegen die Angular-Lib, nicht gegen die CSS-Schicht selbst.\n\n**Claude Code.** Empfohlen als committete Projektdatei `.mcp.json` im Repo-Root:\n\n```json\n{\n \"mcpServers\": {\n \"conciso-ds\": {\n \"command\": \"npx\",\n \"args\": [\"cds-mcp\"]\n }\n }\n}\n```\n\n**VS Code / GitHub Copilot.** `.vscode/mcp.json`, Schlüssel `servers`, mit explizitem\n`\"type\": \"stdio\"` (laut aktueller VS-Code-Doku ein Pflichtfeld für stdio-Server):\n\n```json\n{\n \"servers\": {\n \"conciso-ds\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"cds-mcp\"]\n }\n }\n}\n```\n\n**Cursor.** `.cursor/mcp.json`, Schlüssel `mcpServers`:\n\n```json\n{\n \"mcpServers\": {\n \"conciso-ds\": {\n \"command\": \"npx\",\n \"args\": [\"cds-mcp\"]\n }\n }\n}\n```\n\nAlle drei Varianten starten denselben Prozess über stdio, ohne laufenden Dienst und ohne\nPort.\n\n### Ohne installiertes Paket\n\nIst `@conciso/design-system-mcp` im Projekt nicht installiert, startest du denselben\nServer trotzdem über `npx`, mit fester Versionsnummer statt `cds-mcp` und mit `-y`, damit\n`npx` das Paket ohne Rückfrage lädt:\n\n```json\n{\n \"mcpServers\": {\n \"conciso-ds\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@conciso/design-system-mcp@<Version>\"]\n }\n }\n}\n```\n\n`.vscode/mcp.json` (VS Code / GitHub Copilot), wieder mit `\"type\": \"stdio\"`:\n\n```json\n{\n \"servers\": {\n \"conciso-ds\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@conciso/design-system-mcp@<Version>\"]\n }\n }\n}\n```\n\n`.cursor/mcp.json` (Cursor):\n\n```json\n{\n \"mcpServers\": {\n \"conciso-ds\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@conciso/design-system-mcp@<Version>\"]\n }\n }\n}\n```\n\n**Version an den kopierten Stand binden.** `<Version>` ist die Version der CSS-Schicht,\ndie dein Projekt kopiert hat: Aktualisierst du die Kopie, ziehst du diese Versionsnummer\nmit, sonst dokumentiert der Server Komponenten, die dein kopierter Stand gar nicht kennt.\nDen MCP-Server gibt es erst ab einer späteren Version als die CSS-Schicht; welche Versionen\nexistieren, zeigt `npm view @conciso/design-system-mcp versions`. Ist dein Stand älter,\nnimmst du die älteste verfügbare Version. Die eingebaute Versionsprüfung greift hier\nohnehin nicht automatisch: Sie vergleicht sich beim Start mit der **installierten**\nVersion von\n`@conciso/design-system-angular` in `node_modules`. Ist nichts installiert, findet sie\nnichts zum Vergleichen und nennt stattdessen in ihren `instructions` nur, für welche\nVersion ihr eigener Snapshot gebaut wurde, den Rest prüfst du selbst gegen deinen\nkopierten Stand.\n\n## Siehe auch\n\n- `Komponenten/Buttons/Button` in diesem Storybook\n- README von `@conciso/design-system` auf\n [npmjs.com](https://www.npmjs.com/package/@conciso/design-system)\n- README von `@conciso/design-system-angular` auf\n [npmjs.com](https://www.npmjs.com/package/@conciso/design-system-angular)\n- README von `@conciso/design-system-mcp` auf\n [npmjs.com](https://www.npmjs.com/package/@conciso/design-system-mcp)\n",
|
|
13
|
+
"summary": "# Einrichtung So bindest du das Conciso Design System in ein Projekt ein, von der Installa..."
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"komponenten-buttons-button": {
|
|
4
|
+
"id": "komponenten-buttons-button",
|
|
5
|
+
"name": "komponenten-buttons-button",
|
|
6
|
+
"docs": {
|
|
7
|
+
"komponenten-buttons-button--verwendung": {
|
|
8
|
+
"id": "komponenten-buttons-button--verwendung",
|
|
9
|
+
"name": "Verwendung",
|
|
10
|
+
"path": "./src/docs/komponenten/buttons-verwendung.mdx",
|
|
11
|
+
"title": "Komponenten/Buttons/Button",
|
|
12
|
+
"content": "import { Meta, Unstyled } from '@storybook/addon-docs/blocks';\nimport * as ButtonStories from '../../lib/button/button.stories';\n\n<Meta of={ButtonStories} name=\"Verwendung\" />\n\n# Verwendung\n\nButtons sind die primäre Aktions-Komponente des Systems: fünf Stilvarianten (Filled · Tonal · Elevated · Outlined · Text), drei Größen (Standard · Small · Large), der Ton-Modifier `.btn-err` für destruktive Aktionen und der Inversions-Modifier `.btn-on-band` für Buttons auf farbigen Bereichs-Bändern. Jede Variante steht in allen vier Brand Areas zur Verfügung (Bereichsreihenfolge co · ki · es · wo), das Mindestmaß für ein Touch-Target ist 44 Pixel.\n\n## Wann welche Variante\n\nDie Hierarchie ist verbindlich: Filled vor Tonal oder Outlined vor Text. Pro Kontext höchstens ein Filled-Button, sonst ist die Hauptaktion nicht mehr eindeutig erkennbar. Elevated steht außerhalb dieser Kette und markiert eine freistehende, vom Hintergrund abgehobene Aktion.\n\nSo löst sich die Hierarchie in typischen Kontexten auf: ein Dialog mit Text- neben Filled-Button, ein Formular mit Outlined- neben Filled-Button und eine Feature-Karte mit Text- neben Tonal-Button.\n\n<Unstyled>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--s4)' }}>\n <div\n style={{\n border: 'var(--bd-strong)',\n borderRadius: 'var(--r-lg)',\n padding: 'var(--s5)',\n background: 'var(--bg-surface)',\n }}\n >\n <div style={{ font: '500 16px/24px var(--font)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>\n Aktion bestätigen\n </div>\n <div style={{ font: '400 14px/20px var(--font)', color: 'var(--tx-secondary)', marginBottom: 'var(--s5)' }}>\n Möchtest du die Änderungen wirklich speichern?\n </div>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 'var(--s2)', marginBottom: 'var(--s3)' }}>\n <button className=\"btn btn-text btn-sm btn-co\">Abbrechen</button>\n <button className=\"btn btn-filled btn-sm btn-co\">Speichern</button>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)', textAlign: 'right' }}>\n Text → Abbrechen · Filled → Hauptaktion\n </div>\n </div>\n <div\n style={{\n border: 'var(--bd-strong)',\n borderRadius: 'var(--r-lg)',\n padding: 'var(--s5)',\n background: 'var(--bg-surface)',\n }}\n >\n <div style={{ font: '500 16px/24px var(--font)', color: 'var(--tx-primary)', marginBottom: 'var(--s4)' }}>\n Formular einreichen\n </div>\n <div\n style={{\n height: '32px',\n background: 'var(--bg-overlay)',\n borderRadius: 'var(--r-sm)',\n border: 'var(--bd-strong)',\n marginBottom: 'var(--s5)',\n }}\n ></div>\n <div style={{ display: 'flex', gap: 'var(--s2)', marginBottom: 'var(--s3)' }}>\n <button className=\"btn btn-outlined btn-sm btn-co\">Vorschau</button>\n <button className=\"btn btn-filled btn-sm btn-co\">Absenden</button>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)' }}>\n Outlined → Alternativaktion · Filled → Primäraktion\n </div>\n </div>\n <div\n style={{\n border: 'var(--bd-strong)',\n borderRadius: 'var(--r-lg)',\n padding: 'var(--s5)',\n background: 'var(--bg-surface)',\n }}\n >\n <div style={{ font: '500 16px/24px var(--font)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>\n Feature entdecken\n </div>\n <div style={{ font: '400 14px/20px var(--font)', color: 'var(--tx-secondary)', marginBottom: 'var(--s5)' }}>\n Drei Bereiche, ein Ziel, Gelassenheit durch klare Struktur.\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--s2)', marginBottom: 'var(--s3)' }}>\n <button className=\"btn btn-text btn-sm btn-co\">Mehr erfahren</button>\n <button className=\"btn btn-tonal btn-sm btn-co\">Jetzt starten</button>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)' }}>\n Text → Nebenaktion · Tonal → unterstützende Aktion\n </div>\n </div>\n </div>\n</Unstyled>\n\n| Variante | Rolle in der Hierarchie | Einsatz | Beispiele |\n|---|---|---|---|\n| Filled | 1. Primäre Hauptaktion | Max. 1 bis 2 pro Kontext | Speichern, Absenden, Starten |\n| Tonal | 2. Sekundäre Bestätigung | Neben Filled oder eigenständig | Weiter, Übernehmen |\n| Outlined | 2. Gleichwertige Alternative | Ohne Primärfokus | Vorschau, Exportieren |\n| Text | 3. Nebenaktion | Niedrigste Priorität, link-ähnliche Funktion | Abbrechen, Mehr erfahren |\n| Elevated | Außerhalb der Hierarchie | Freistehende Aktion, visuell vom Hintergrund getrennt | Schwebende Elemente, FAB |\n\n## Destruktive Aktionen\n\n`.btn-err` (Angular: `tone=\"err\"`) markiert eine Aktion, die sich nicht rückgängig machen lässt: Löschen, Verwerfen, Entfernen. Der Modifier **ersetzt** die Bereichsfarbe, er wird statt `.btn-co` gesetzt, nicht zusätzlich. Gedacht für Filled, Outlined und Text.\n\n<Unstyled>\n <div style={{ display: 'flex', gap: 'var(--s4)', flexWrap: 'wrap', alignItems: 'center', marginBottom: 'var(--s5)' }}>\n <button className=\"btn btn-filled btn-err\">Löschen</button>\n <button className=\"btn btn-outlined btn-err\">Verwerfen</button>\n <button className=\"btn btn-text btn-err\">Entfernen</button>\n </div>\n</Unstyled>\n\nWelcher Button gefüllt ist, entscheidet der Kontext:\n\n| Kontext | Beispiel | Hauptaktion (Filled) | Nebenaktion |\n|---|---|---|---|\n| Selbst ausgelöst | Klick auf „Löschen“, danach eine Rückfrage | „Löschen“ mit `.btn-err` | „Abbrechen“ als Text |\n| Unterbrechung | Ungespeicherte Änderungen beim Verlassen | „Weiter bearbeiten“ in der Bereichsfarbe | „Verwerfen“ als Outlined mit `.btn-err` |\n\nBei einer Unterbrechung wollte die Person etwas anderes, das Verwerfen ist Nebenwirkung. Deshalb bekommt dort der sichere Weg das Gewicht. Die Farbe ist nie der einzige Hinweis, das Label nennt immer die Folge.\n\n## Barrierefreiheit\n\n| Aspekt | Regel |\n|---|---|\n| Icon-only | Buttons ohne sichtbaren Text benötigen `aria-label`, der SVG-Inhalt allein reicht für Screenreader nicht aus |\n| Disabled | `aria-disabled=\"true\"` statt HTML `disabled`, wenn der Button im Fokus-Flow bleiben soll, `disabled` entfernt das Element aus der Tastaturreihenfolge |\n| Touch-Target | Mindestgröße 44 mal 44 Pixel für alle Button-Varianten (WCAG 2.5.5), `btn-sm` bei Bedarf mit zusätzlichem Padding kompensieren |\n| Focus-Ring | Nie `outline: none` ohne sichtbaren Ersatz, der Design-System-Focus-Ring (`--focus-aa`) muss für alle Buttons erhalten bleiben |\n| Filled auf Bereichs-Section | Filled-Buttons auf hellen Bereichs-Hintergründen (`--co-50`, `--ki-50`, `--wo-50`, `--es-50`) brauchen eine ausreichend dunkle Variante mit weißer Schrift, sonst fehlt der UI-Komponenten-Kontrast (WCAG 1.4.11, mindestens 3 zu 1) zwischen Button-Fläche und Section |\n\nDrei der vier Bereiche sind über die Modifier-Klasse bereits korrekt abgedeckt: `.btn-co` auf `--co-700`, `.btn-ki` auf `--ki-800`, `.btn-es` auf `--es-700`. Die Default-Farbe von `.btn-wo` (`--wo-700`) ist im Allgemeinen passend, verfehlt aber auf `--wo-50`-Sub-Streifen den Kontrast. Dort die Bereichs-Klasse mit einem minimalen Inline-Override kombinieren:\n\n```html\n<button class=\"btn btn-filled btn-wo\" style=\"--c500:var(--wo-600)\">\n```\n\n`--c50` erbt korrekt von `.btn-wo`, ein `color`-Override entfällt, weil der Default aus `.btn-filled` (Weiß) bereits greift.\n\n## Dos & Don'ts\n\n**Tun**\n\n- Pro Kontext maximal ein Filled Button, klare Priorisierung der Hauptaktion für die Nutzerin.\n- Verb-Labels: konkret und handlungsorientiert, „Starten“, „Speichern“, „Anfragen“, „Absenden“.\n- Hierarchie konsequent einhalten: Filled vor Tonal oder Outlined vor Text.\n- Bereichsklasse passend zum Seitenkontext: `.btn-co`, `.btn-ki`, `.btn-es`, `.btn-wo`.\n- Touch-Target mindestens 44 Pixel einhalten, auch im Small-Modus ausreichend groß für sichere Bedienung.\n- `.btn-err` nur für Aktionen, die sich nicht rückgängig machen lassen, höchstens einer pro Ansicht, mit einem Label, das die Folge nennt: „Löschen“, „Verwerfen“.\n\n**Nicht tun**\n\n- Mehrere Filled Buttons nebeneinander, das lässt keine klare Primäraktion erkennen.\n- Substantive oder lange Phrasen als Labels, „Antragsformular einreichen“ statt lieber „Absenden“.\n- Disabled-State ohne sichtbare Begründung, Helper-Text oder Tooltip nutzen, um zu erklären warum.\n- Bereichsfarbe willkürlich tauschen, Corporate-Kontext immer `.btn-co`, nie `.btn-ki`.\n- Filled-Button mit `--area-500` auf hellem Bereichs-Hintergrund (`--area-50`), stattdessen die dunklere Bereichs-Variante nutzen (siehe Barrierefreiheits-Tabelle oben).\n- `.btn-err` als Blickfang oder für umkehrbare Aktionen („Abmelden“, „Filter zurücksetzen“), und nie neben einer Bereichsklasse am selben Button.\n\n## Verwandte Seiten\n\n- Buttons (`Komponenten/Buttons/Button`), alle Stilvarianten, Größen und Zustände als Stories.\n",
|
|
13
|
+
"summary": "# Verwendung Buttons sind die primäre Aktions-Komponente des Systems: fünf Stilvarianten (..."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"name": "Übersicht",
|
|
10
10
|
"path": "./src/docs/marke/bildsprache.mdx",
|
|
11
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",
|
|
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 `docs/marke/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
13
|
"summary": "# Bildsprache Fotografie · Illustration · vier Brand Areas, abgeleitet aus dem Markenrad. ..."
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"name": "Übersicht",
|
|
10
10
|
"path": "./src/docs/marke/markenrad.mdx",
|
|
11
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",
|
|
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 `docs/marke/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 `docs/marke/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 `docs/marke/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
13
|
"summary": "# Markenrad Der Kernwert **Gelassenheit** entfaltet sich in drei Markenpfeilern (Ruhig, Kl..."
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"argTypes": {
|
|
10
10
|
"area": {
|
|
11
11
|
"name": "area",
|
|
12
|
-
"description": "Markenbereich → .btn-co / .btn-ki / .btn-es / .btn-wo",
|
|
12
|
+
"description": "Markenbereich → .btn-co / .btn-ki / .btn-es / .btn-wo. Wirkungslos bei `tone=\"err\"`.",
|
|
13
13
|
"type": {
|
|
14
14
|
"name": "enum",
|
|
15
15
|
"value": [
|
|
@@ -97,6 +97,26 @@
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
|
+
"tone": {
|
|
101
|
+
"name": "tone",
|
|
102
|
+
"description": "Ton → `err` setzt .btn-err (destruktive Aktion) statt der Bereichsklasse.",
|
|
103
|
+
"type": {
|
|
104
|
+
"name": "enum",
|
|
105
|
+
"value": [
|
|
106
|
+
"def",
|
|
107
|
+
"err"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"table": {
|
|
111
|
+
"category": "inputs",
|
|
112
|
+
"type": {
|
|
113
|
+
"summary": "CdsButtonTone"
|
|
114
|
+
},
|
|
115
|
+
"defaultValue": {
|
|
116
|
+
"summary": "def"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
100
120
|
"type": {
|
|
101
121
|
"name": "type",
|
|
102
122
|
"type": {
|
|
@@ -158,7 +178,7 @@
|
|
|
158
178
|
}
|
|
159
179
|
}
|
|
160
180
|
},
|
|
161
|
-
"apiDescription": "## Inputs\n\n```\nexport type ButtonComponentInputs = {\n /**\n * Markenbereich → .btn-co / .btn-ki / .btn-es / .btn-wo\n *\n * @default co\n */\n area?: CdsArea;\n /** @default false */\n disabled?: boolean;\n /**\n * Volle Breite → .btn-full (Host wird block, damit 100% greifen).\n *\n * @default false\n */\n full?: boolean;\n /**\n * Sichtbarer Text des Buttons.\n *\n * @default Button\n */\n label?: string;\n /**\n * Größe → .btn-sm / (md = Default) / .btn-lg\n *\n * @default md\n */\n size?: CdsButtonSize;\n /** @default button */\n type?: \"button\" | \"submit\" | \"reset\";\n /**\n * Visuelle Variante → .btn-filled / .btn-tonal / .btn-elevated / .btn-outlined /\n * .btn-text; `filled-on-band` → .btn-filled + .btn-on-band (invertiert).\n *\n * @default filled\n */\n variant?: CdsButtonVariant;\n}\n```\n\n## Outputs\n\n```\nexport type ButtonComponentOutputs = {\n /** Klick auf den Button (feuert nicht, wenn `disabled`). */\n clicked: MouseEvent;\n}\n```",
|
|
181
|
+
"apiDescription": "## Inputs\n\n```\nexport type ButtonComponentInputs = {\n /**\n * Markenbereich → .btn-co / .btn-ki / .btn-es / .btn-wo. Wirkungslos bei `tone=\"err\"`.\n *\n * @default co\n */\n area?: CdsArea;\n /** @default false */\n disabled?: boolean;\n /**\n * Volle Breite → .btn-full (Host wird block, damit 100% greifen).\n *\n * @default false\n */\n full?: boolean;\n /**\n * Sichtbarer Text des Buttons.\n *\n * @default Button\n */\n label?: string;\n /**\n * Größe → .btn-sm / (md = Default) / .btn-lg\n *\n * @default md\n */\n size?: CdsButtonSize;\n /**\n * Ton → `err` setzt .btn-err (destruktive Aktion) statt der Bereichsklasse.\n *\n * @default def\n */\n tone?: CdsButtonTone;\n /** @default button */\n type?: \"button\" | \"submit\" | \"reset\";\n /**\n * Visuelle Variante → .btn-filled / .btn-tonal / .btn-elevated / .btn-outlined /\n * .btn-text; `filled-on-band` → .btn-filled + .btn-on-band (invertiert).\n *\n * @default filled\n */\n variant?: CdsButtonVariant;\n}\n```\n\n## Outputs\n\n```\nexport type ButtonComponentOutputs = {\n /** Klick auf den Button (feuert nicht, wenn `disabled`). */\n clicked: MouseEvent;\n}\n```",
|
|
162
182
|
"renderer": "angular",
|
|
163
183
|
"angularComponentMeta": {
|
|
164
184
|
"name": "ButtonComponent",
|
|
@@ -170,6 +190,7 @@
|
|
|
170
190
|
"full",
|
|
171
191
|
"label",
|
|
172
192
|
"size",
|
|
193
|
+
"tone",
|
|
173
194
|
"type",
|
|
174
195
|
"variant"
|
|
175
196
|
],
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"komponenten-buttons-button--interaktiv": {
|
|
9
9
|
"id": "komponenten-buttons-button--interaktiv",
|
|
10
10
|
"name": "Interaktiv",
|
|
11
|
-
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n @if (variant === 'filled-on-band') {\n <div\n [style.background]=\"'var(--' + area + (area === 'ki' ? '-800' : '-700') + ')'\"\n style=\"padding:24px;border-radius:var(--r-md)\">\n <cds-button\n [label]=\"label\"\n [variant]=\"variant\"\n [area]=\"area\"\n [size]=\"size\"\n [full]=\"full\"\n [disabled]=\"disabled\" />\n </div>\n } @else {\n <cds-button\n [label]=\"label\"\n [variant]=\"variant\"\n [area]=\"area\"\n [size]=\"size\"\n [full]=\"full\"\n [disabled]=\"disabled\" />\n }`,\n})\nexport class DemoComponent {\n label = 'Kontakt aufnehmen';\n variant = 'filled';\n area = 'co';\n size = 'md';\n full = false;\n disabled = false;\n}"
|
|
11
|
+
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n @if (variant === 'filled-on-band') {\n <div\n [style.background]=\"'var(--' + area + (area === 'ki' ? '-800' : '-700') + ')'\"\n style=\"padding:24px;border-radius:var(--r-md)\">\n <cds-button\n [label]=\"label\"\n [variant]=\"variant\"\n [area]=\"area\"\n [tone]=\"tone\"\n [size]=\"size\"\n [full]=\"full\"\n [disabled]=\"disabled\" />\n </div>\n } @else {\n <cds-button\n [label]=\"label\"\n [variant]=\"variant\"\n [area]=\"area\"\n [tone]=\"tone\"\n [size]=\"size\"\n [full]=\"full\"\n [disabled]=\"disabled\" />\n }`,\n})\nexport class DemoComponent {\n label = 'Kontakt aufnehmen';\n variant = 'filled';\n area = 'co';\n tone = 'def';\n size = 'md';\n full = false;\n disabled = false;\n}"
|
|
12
12
|
},
|
|
13
13
|
"komponenten-buttons-button--varianten": {
|
|
14
14
|
"id": "komponenten-buttons-button--varianten",
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
"name": "Bereichsfarben",
|
|
21
21
|
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n <div style=\"display:flex;gap:16px;flex-wrap:wrap;align-items:center\">\n <cds-button area=\"co\" label=\"Corporate\"></cds-button>\n <cds-button area=\"ki\" label=\"AI.Applied\"></cds-button>\n <cds-button area=\"es\" label=\"Eff. Software\"></cds-button>\n <cds-button area=\"wo\" label=\"Wirks. Orga\"></cds-button>\n </div>`,\n})\nexport class DemoComponent {}"
|
|
22
22
|
},
|
|
23
|
+
"komponenten-buttons-button--destruktiv": {
|
|
24
|
+
"id": "komponenten-buttons-button--destruktiv",
|
|
25
|
+
"name": "Destruktiv",
|
|
26
|
+
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n <div style=\"display:flex;gap:16px;flex-wrap:wrap;align-items:center\">\n <cds-button tone=\"err\" label=\"Löschen\"></cds-button>\n <cds-button tone=\"err\" variant=\"outlined\" label=\"Verwerfen\"></cds-button>\n <cds-button tone=\"err\" variant=\"text\" label=\"Entfernen\"></cds-button>\n </div>`,\n})\nexport class DemoComponent {}"
|
|
27
|
+
},
|
|
23
28
|
"komponenten-buttons-button--groessen": {
|
|
24
29
|
"id": "komponenten-buttons-button--groessen",
|
|
25
30
|
"name": "Größen",
|
|
@@ -33,13 +38,13 @@
|
|
|
33
38
|
"komponenten-buttons-button--deaktiviert": {
|
|
34
39
|
"id": "komponenten-buttons-button--deaktiviert",
|
|
35
40
|
"name": "Deaktiviert",
|
|
36
|
-
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n <cds-button\n [label]=\"'Nicht verfügbar'\"\n [variant]=\"'filled'\"\n [area]=\"'co'\"\n [size]=\"'md'\"\n [full]=\"false\"\n [disabled]=\"true\"\n (clicked)=\"clicked($event)\"\n />`,\n})\nexport class DemoComponent {\n clicked(event: unknown) {}\n}",
|
|
41
|
+
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n <cds-button\n [label]=\"'Nicht verfügbar'\"\n [variant]=\"'filled'\"\n [area]=\"'co'\"\n [tone]=\"'def'\"\n [size]=\"'md'\"\n [full]=\"false\"\n [disabled]=\"true\"\n (clicked)=\"clicked($event)\"\n />`,\n})\nexport class DemoComponent {\n clicked(event: unknown) {}\n}",
|
|
37
42
|
"warning": "Incomplete snippet: `fn()` could not be resolved statically."
|
|
38
43
|
},
|
|
39
44
|
"komponenten-buttons-button--klick-verhalten": {
|
|
40
45
|
"id": "komponenten-buttons-button--klick-verhalten",
|
|
41
46
|
"name": "Klick-Verhalten",
|
|
42
|
-
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n <cds-button\n [label]=\"'Kontakt aufnehmen'\"\n [variant]=\"'filled'\"\n [area]=\"'co'\"\n [size]=\"'md'\"\n [full]=\"false\"\n [disabled]=\"false\"\n (clicked)=\"clicked($event)\"\n />`,\n})\nexport class DemoComponent {\n clicked(event: unknown) {}\n}",
|
|
47
|
+
"snippet": "import { Component } from '@angular/core';\nimport { ButtonComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [ButtonComponent],\n template: `\n <cds-button\n [label]=\"'Kontakt aufnehmen'\"\n [variant]=\"'filled'\"\n [area]=\"'co'\"\n [tone]=\"'def'\"\n [size]=\"'md'\"\n [full]=\"false\"\n [disabled]=\"false\"\n (clicked)=\"clicked($event)\"\n />`,\n})\nexport class DemoComponent {\n clicked(event: unknown) {}\n}",
|
|
43
48
|
"warning": "Incomplete snippet: `fn()` could not be resolved statically."
|
|
44
49
|
}
|
|
45
50
|
}
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"name": "Deaktiviert",
|
|
16
16
|
"snippet": "import { Component } from '@angular/core';\nimport { RadioGroupComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [RadioGroupComponent],\n template: `\n <cds-radio-group\n [legend]=\"'Bevorzugter Kontaktweg'\"\n [options]=\"['E-Mail', 'Telefon', 'Beides']\"\n [value]=\"'E-Mail'\"\n [required]=\"false\"\n [disabled]=\"true\"\n [area]=\"'co'\"\n (disabledChange)=\"disabledChange($event)\"\n (valueChange)=\"valueChange($event)\"\n />`,\n})\nexport class DemoComponent {\n disabledChange(event: unknown) {}\n valueChange(event: unknown) {}\n}"
|
|
17
17
|
},
|
|
18
|
+
"komponenten-inputs-forms-radio--pflichtfeld": {
|
|
19
|
+
"id": "komponenten-inputs-forms-radio--pflichtfeld",
|
|
20
|
+
"name": "Pflichtfeld",
|
|
21
|
+
"snippet": "import { Component } from '@angular/core';\nimport { RadioGroupComponent } from '@conciso/design-system-angular';\n\n@Component({\n selector: 'app-demo',\n imports: [RadioGroupComponent],\n template: `\n <cds-radio-group\n [legend]=\"'Bevorzugter Kontaktweg'\"\n [options]=\"['E-Mail', 'Telefon', 'Beides']\"\n [value]=\"'E-Mail'\"\n [required]=\"true\"\n [disabled]=\"false\"\n [area]=\"'co'\"\n (disabledChange)=\"disabledChange($event)\"\n (valueChange)=\"valueChange($event)\"\n />`,\n})\nexport class DemoComponent {\n disabledChange(event: unknown) {}\n valueChange(event: unknown) {}\n}"
|
|
22
|
+
},
|
|
18
23
|
"komponenten-inputs-forms-radio--tastatur": {
|
|
19
24
|
"id": "komponenten-inputs-forms-radio--tastatur",
|
|
20
25
|
"name": "Tastatur",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"components": {
|
|
3
|
-
"komponenten-buttons--verwendung": {
|
|
4
|
-
"id": "komponenten-buttons--verwendung",
|
|
5
|
-
"name": "komponenten-buttons--verwendung",
|
|
6
|
-
"docs": {
|
|
7
|
-
"komponenten-buttons--verwendung": {
|
|
8
|
-
"id": "komponenten-buttons--verwendung",
|
|
9
|
-
"name": "Verwendung",
|
|
10
|
-
"path": "./src/docs/komponenten/buttons-verwendung.mdx",
|
|
11
|
-
"title": "Komponenten/Buttons",
|
|
12
|
-
"content": "import { Meta, Unstyled } from '@storybook/addon-docs/blocks';\n\n<Meta title=\"Komponenten/Buttons\" name=\"Verwendung\" tags={['angular']} />\n\n# Verwendung\n\nButtons sind die primäre Aktions-Komponente des Systems: fünf Stilvarianten (Filled · Tonal · Elevated · Outlined · Text), drei Größen (Standard · Small · Large) und der Inversions-Modifier `.btn-on-band` für Buttons auf farbigen Bereichs-Bändern. Jede Variante steht in allen vier Brand Areas zur Verfügung (Bereichsreihenfolge co · ki · es · wo), das Mindestmaß für ein Touch-Target ist 44 Pixel.\n\n## Wann welche Variante\n\nDie Hierarchie ist verbindlich: Filled vor Tonal oder Outlined vor Text. Pro Kontext höchstens ein Filled-Button, sonst ist die Hauptaktion nicht mehr eindeutig erkennbar. Elevated steht außerhalb dieser Kette und markiert eine freistehende, vom Hintergrund abgehobene Aktion.\n\nSo löst sich die Hierarchie in typischen Kontexten auf: ein Dialog mit Text- neben Filled-Button, ein Formular mit Outlined- neben Filled-Button und eine Feature-Karte mit Text- neben Tonal-Button.\n\n<Unstyled>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--s4)' }}>\n <div\n style={{\n border: 'var(--bd-strong)',\n borderRadius: 'var(--r-lg)',\n padding: 'var(--s5)',\n background: 'var(--bg-surface)',\n }}\n >\n <div style={{ font: '500 16px/24px var(--font)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>\n Aktion bestätigen\n </div>\n <div style={{ font: '400 14px/20px var(--font)', color: 'var(--tx-secondary)', marginBottom: 'var(--s5)' }}>\n Möchtest du die Änderungen wirklich speichern?\n </div>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 'var(--s2)', marginBottom: 'var(--s3)' }}>\n <button className=\"btn btn-text btn-sm btn-co\">Abbrechen</button>\n <button className=\"btn btn-filled btn-sm btn-co\">Speichern</button>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)', textAlign: 'right' }}>\n Text → Abbrechen · Filled → Hauptaktion\n </div>\n </div>\n <div\n style={{\n border: 'var(--bd-strong)',\n borderRadius: 'var(--r-lg)',\n padding: 'var(--s5)',\n background: 'var(--bg-surface)',\n }}\n >\n <div style={{ font: '500 16px/24px var(--font)', color: 'var(--tx-primary)', marginBottom: 'var(--s4)' }}>\n Formular einreichen\n </div>\n <div\n style={{\n height: '32px',\n background: 'var(--bg-overlay)',\n borderRadius: 'var(--r-sm)',\n border: 'var(--bd-strong)',\n marginBottom: 'var(--s5)',\n }}\n ></div>\n <div style={{ display: 'flex', gap: 'var(--s2)', marginBottom: 'var(--s3)' }}>\n <button className=\"btn btn-outlined btn-sm btn-co\">Vorschau</button>\n <button className=\"btn btn-filled btn-sm btn-co\">Absenden</button>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)' }}>\n Outlined → Alternativaktion · Filled → Primäraktion\n </div>\n </div>\n <div\n style={{\n border: 'var(--bd-strong)',\n borderRadius: 'var(--r-lg)',\n padding: 'var(--s5)',\n background: 'var(--bg-surface)',\n }}\n >\n <div style={{ font: '500 16px/24px var(--font)', color: 'var(--tx-primary)', marginBottom: 'var(--s2)' }}>\n Feature entdecken\n </div>\n <div style={{ font: '400 14px/20px var(--font)', color: 'var(--tx-secondary)', marginBottom: 'var(--s5)' }}>\n Drei Bereiche, ein Ziel, Gelassenheit durch klare Struktur.\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--s2)', marginBottom: 'var(--s3)' }}>\n <button className=\"btn btn-text btn-sm btn-co\">Mehr erfahren</button>\n <button className=\"btn btn-tonal btn-sm btn-co\">Jetzt starten</button>\n </div>\n <div style={{ font: '400 12px/16px var(--font)', color: 'var(--tx-secondary)' }}>\n Text → Nebenaktion · Tonal → unterstützende Aktion\n </div>\n </div>\n </div>\n</Unstyled>\n\n| Variante | Rolle in der Hierarchie | Einsatz | Beispiele |\n|---|---|---|---|\n| Filled | 1. Primäre Hauptaktion | Max. 1 bis 2 pro Kontext | Speichern, Absenden, Starten |\n| Tonal | 2. Sekundäre Bestätigung | Neben Filled oder eigenständig | Weiter, Übernehmen |\n| Outlined | 2. Gleichwertige Alternative | Ohne Primärfokus | Vorschau, Exportieren |\n| Text | 3. Nebenaktion | Niedrigste Priorität, link-ähnliche Funktion | Abbrechen, Mehr erfahren |\n| Elevated | Außerhalb der Hierarchie | Freistehende Aktion, visuell vom Hintergrund getrennt | Schwebende Elemente, FAB |\n\n## Barrierefreiheit\n\n| Aspekt | Regel |\n|---|---|\n| Icon-only | Buttons ohne sichtbaren Text benötigen `aria-label`, der SVG-Inhalt allein reicht für Screenreader nicht aus |\n| Disabled | `aria-disabled=\"true\"` statt HTML `disabled`, wenn der Button im Fokus-Flow bleiben soll, `disabled` entfernt das Element aus der Tastaturreihenfolge |\n| Touch-Target | Mindestgröße 44 mal 44 Pixel für alle Button-Varianten (WCAG 2.5.5), `btn-sm` bei Bedarf mit zusätzlichem Padding kompensieren |\n| Focus-Ring | Nie `outline: none` ohne sichtbaren Ersatz, der Design-System-Focus-Ring (`--focus-aa`) muss für alle Buttons erhalten bleiben |\n| Filled auf Bereichs-Section | Filled-Buttons auf hellen Bereichs-Hintergründen (`--co-50`, `--ki-50`, `--wo-50`, `--es-50`) brauchen eine ausreichend dunkle Variante mit weißer Schrift, sonst fehlt der UI-Komponenten-Kontrast (WCAG 1.4.11, mindestens 3 zu 1) zwischen Button-Fläche und Section |\n\nDrei der vier Bereiche sind über die Modifier-Klasse bereits korrekt abgedeckt: `.btn-co` auf `--co-700`, `.btn-ki` auf `--ki-800`, `.btn-es` auf `--es-700`. Die Default-Farbe von `.btn-wo` (`--wo-700`) ist im Allgemeinen passend, verfehlt aber auf `--wo-50`-Sub-Streifen den Kontrast. Dort die Bereichs-Klasse mit einem minimalen Inline-Override kombinieren:\n\n```html\n<button class=\"btn btn-filled btn-wo\" style=\"--c500:var(--wo-600)\">\n```\n\n`--c50` erbt korrekt von `.btn-wo`, ein `color`-Override entfällt, weil der Default aus `.btn-filled` (Weiß) bereits greift.\n\n## Dos & Don'ts\n\n**Tun**\n\n- Pro Kontext maximal ein Filled Button, klare Priorisierung der Hauptaktion für die Nutzerin.\n- Verb-Labels: konkret und handlungsorientiert, „Starten“, „Speichern“, „Anfragen“, „Absenden“.\n- Hierarchie konsequent einhalten: Filled vor Tonal oder Outlined vor Text.\n- Bereichsklasse passend zum Seitenkontext: `.btn-co`, `.btn-ki`, `.btn-es`, `.btn-wo`.\n- Touch-Target mindestens 44 Pixel einhalten, auch im Small-Modus ausreichend groß für sichere Bedienung.\n\n**Nicht tun**\n\n- Mehrere Filled Buttons nebeneinander, das lässt keine klare Primäraktion erkennen.\n- Substantive oder lange Phrasen als Labels, „Antragsformular einreichen“ statt lieber „Absenden“.\n- Disabled-State ohne sichtbare Begründung, Helper-Text oder Tooltip nutzen, um zu erklären warum.\n- Bereichsfarbe willkürlich tauschen, Corporate-Kontext immer `.btn-co`, nie `.btn-ki`.\n- Filled-Button mit `--area-500` auf hellem Bereichs-Hintergrund (`--area-50`), stattdessen die dunklere Bereichs-Variante nutzen (siehe Barrierefreiheits-Tabelle oben).\n\n## Verwandte Seiten\n\n- Buttons (`Komponenten/Buttons/Button`), alle Stilvarianten, Größen und Zustände als Stories.\n",
|
|
13
|
-
"summary": "# Verwendung Buttons sind die primäre Aktions-Komponente des Systems: fünf Stilvarianten (..."
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|