@conciso/design-system 0.0.0-bootstrap.0 → 2.1.1

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 CHANGED
@@ -50,8 +50,11 @@ npm install @conciso/design-system
50
50
  import '@conciso/design-system/dist/conciso-ds.css';
51
51
  // Tokens (optional, für JS/Framework):
52
52
  import { tokens } from '@conciso/design-system/tokens';
53
- // Icons (optional, maschinenlesbar — komplette <svg>-Bodies, currentColor):
54
- import { icons } from '@conciso/design-system/icons';
53
+ // Icons (optional, maschinenlesbar — komplette <svg>-Bodies, currentColor): benannter Import
54
+ // pro Icon, tree-shakable — nur importierte Glyphen landen im Bundle:
55
+ import { uiShieldCheck } from '@conciso/design-system/icons';
56
+ // Das aggregierte `icons`-Objekt (oder icons.json) zieht immer alle Icons ins Bundle — nur
57
+ // für Kataloge/Doku, nicht für Apps. Details: icons/README.md.
55
58
  // Brand-Logo (Wortmarke, drei Varianten):
56
59
  import logo from '@conciso/design-system/assets/brand/logo-conciso.svg';
57
60
  ```
@@ -151,6 +151,17 @@
151
151
  Interaktion liegt dann in den Buttons; so eine Karte ruht flach mit dem --bd-Rahmen aus .card.
152
152
  Deshalb hängt die ganze Variante an a.*: eine <article>/<div>-Karte bekommt den Schatten auch
153
153
  dann nicht, wenn die Klasse gesetzt ist. Das ist der Riegel, nicht nur eine Empfehlung. */
154
+ /* Ohne data-area erbt eine <article>/<div>-Karte die Seiten-Textfarbe automatisch, weil Eyebrow
155
+ und Media-Icon keine eigene Farbe setzen. Ein <a> bringt aber die UA-Linkfarbe UND -Unterstreichung
156
+ mit: ohne dieses Reset läuft die Unterstreichung durch alle Block-Kinder (Eyebrow, Titel, Text,
157
+ Meta), weil text-decoration nicht vererbt, sondern über in-flow-Nachfahren PROPAGIERT wird — ein
158
+ text-decoration:none auf dem Kind allein stoppt das nicht, nur der Reset am <a> selbst.
159
+ color:inherit + text-decoration:none gleichen beides an: Link-Card ohne Bereich = Card ohne
160
+ Bereich, Bereichs-Regeln (oben) bleiben unberührt, weil sie spezifischer sind (Befund 01).
161
+ .card-cta-link bleibt unberührt: als <span> im Card-Footer hatte es nie UA-Unterstreichung, als
162
+ eigenständiges a.card-cta-link (css/components.css ~1377) sitzt es nie verschachtelt in a.card
163
+ (ungültiges HTML, siehe LinkCardComponent-Klassendoku) und behält seinen eigenen Hover-Unterstrich. */
164
+ a.card{color:inherit;text-decoration:none}
154
165
  a.card-elevated{box-shadow:var(--e1);border:none;background:var(--bg-surface)}
155
166
  a.card-elevated:hover{box-shadow:var(--e2);transform:translateY(-2px)}
156
167
 
@@ -594,8 +605,11 @@ a.card-elevated:hover{box-shadow:var(--e2);transform:translateY(-2px)}
594
605
  /* ── Snackbar ── */
595
606
  .snack{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) var(--s5);border-radius:var(--r-md);font:var(--ty-body-md);max-width:480px;box-shadow:var(--e3);margin-bottom:var(--s3);min-height:48px}
596
607
  .snack-def{background:var(--n-700);color:var(--n-0)}
597
- .snack-ok{background:#0d5e39;color:#d6f5e8}
598
- .snack-err{background:#7a1515;color:#fde8e8}
608
+ /* Tokens statt Hardcodes (Befund 04): Werte und Kontraste stehen bei --c-success-strong/
609
+ --c-error-strong in tokens.css. Die Fläche flippt im Dark über den Token, kein eigenes
610
+ Dark-Overwrite hier nötig. */
611
+ .snack-ok{background:var(--c-success-strong);color:var(--c-success-on-strong)}
612
+ .snack-err{background:var(--c-error-strong);color:var(--c-error-on-strong)}
599
613
  .snack-act{margin-left:auto;background:none;border:none;color:inherit;opacity:.8;font:var(--ty-label-sm);cursor:pointer;text-transform:uppercase;letter-spacing:.04em;padding:0}
600
614
 
601
615
  /* ── Footer ──
@@ -1603,7 +1617,10 @@ thead th[aria-sort="descending"] .tbl-sort svg{opacity:1;color:var(--co-600)}
1603
1617
  .article-callout[data-area="ki"]{background:var(--ki-50);border-left-color:var(--ki-500)}
1604
1618
  .article-callout[data-area="es"]{background:var(--es-50);border-left-color:var(--es-500)}
1605
1619
  .article-callout[data-area="wo"]{background:var(--wo-50);border-left-color:var(--wo-500)}
1606
- .article-callout-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--co-700);margin:0 0 var(--s1)}
1620
+ /* Direktkind-Selektor statt reiner Klasse: die Eyebrow ist selbst ein <p>, also schlägt
1621
+ .article-callout > p (0,1,1) unten sonst diese Regel (0,1,0). Mit
1622
+ .article-callout > .article-callout-eyebrow (0,2,0) gewinnt die Eyebrow (Befund 02). */
1623
+ .article-callout > .article-callout-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--co-700);margin:0 0 var(--s1)}
1607
1624
  .article-callout[data-area="ki"] .article-callout-eyebrow{color:var(--ki-800)}
1608
1625
  .article-callout[data-area="es"] .article-callout-eyebrow{color:var(--es-700)}
1609
1626
  .article-callout[data-area="wo"] .article-callout-eyebrow{color:var(--wo-700)}
package/css/dark-mode.css CHANGED
@@ -78,6 +78,12 @@
78
78
  --c-error:#FFA5A5; /* auf bg-page: 9.32:1 ✓ AAA · auf bg-surface: 6.93:1 ✓ AAA. Angehoben von
79
79
  #FF8E8E, das nur gegen bg-page geprüft war und auf bg-surface 4.0:1
80
80
  erreichte. Inline-Fehlertext sitzt aber fast immer auf bg-surface. */
81
+ /* Dark-only: Snackbar-Fläche (Befund 04) flippt auf die bereits vorhandenen --c-*-bg-Tints, der
82
+ helle Text auf --c-success-on-strong wird angehoben (--c-error-on-strong und beide -icon-Tokens
83
+ bleiben in Light UND Dark gleich, deshalb hier bewusst kein Override). Kontraste siehe
84
+ tokens.css. (Light: #0d5e39 / #d6f5e8.) */
85
+ --c-success-strong:var(--c-success-bg); --c-success-on-strong:#b0f0d0;
86
+ --c-error-strong:var(--c-error-bg);
81
87
  /* Brand tints (Dark), getrennt nach den zwei Jobs, die --XX-50 im Light in einem Wert erledigt.
82
88
  Der Grund: Ein Band muss DUNKLER bleiben als die Karten darauf, eine Badge- oder Kachel-Füllung
83
89
  muss HELLER sein als ihr Grund, sonst liest sie nicht als Fläche. Bei einer Basis von 17,51:1
@@ -249,18 +255,17 @@
249
255
  [data-theme="dark"] .logo-carousel-pause:hover { color: var(--n-200) }
250
256
  [data-theme="dark"] .ai-warning { color:var(--ki-300) }
251
257
  [data-theme="dark"] .pal-note { background:var(--c-warning-bg);color:#f0d080;border-color:#806000 }
252
- /* Dark-only: Die Flächen standen hier als hartkodierte Kopien von --c-success-bg und --c-error-bg
253
- (#052415 / #220808). Als die Status-Tints angehoben wurden, blieben die Kopien zurück und trugen
254
- nur noch ❌ 1,06:1 bzw. 1,08:1 gegen die Seite, die Snackbar war als Fläche praktisch weg.
255
- Jetzt über die Token ✓ 1,78:1 und 1,79:1; Text darauf 7,60:1 und 8,34:1. */
256
- [data-theme="dark"] .snack-ok { background:var(--c-success-bg); color:#b0f0d0 }
257
- [data-theme="dark"] .snack-err { background:var(--c-error-bg); color:#fde8e8 }
258
- /* Dieselbe Familie wie die Snackbar darüber: die Kreisflächen standen als hartkodierte Kopien von
259
- --c-success-bg und --c-error-bg (#052415 / #220808) und blieben beim Anheben der Status-Tints
260
- zurück. Gegen die neue Seite trugen sie nur ❌ 1,06:1 bzw. 1,08:1, der Kreis war keine Fläche
261
- mehr, nur noch ein farbiger Glyph. Jetzt über die Token ✓ 1,78:1 und 1,79:1 zur Seite, 1,32 und
262
- 1,33:1 zur Card. Der Fehler-Glyph geht mit: #F08080 trägt auf der aufgehellten Füllung nur
263
- ❌ 3,78:1, --c-error (#FFA5A5) ✓ 5,21:1. Analog --c-success (#5CE8A0) auf Grün 6,33:1.
258
+ /* Snackbar-Fläche/-Text (.snack-ok/.snack-err) brauchten hier früher ein eigenes Dark-Overwrite,
259
+ weil die Farben in components.css als Hex standen und im Dark nicht mitliefen. Seit Befund 04
260
+ stehen sie über --c-success-strong/--c-error-strong (tokens.css, Dark-Werte oben im Token-Block),
261
+ die Fläche flippt jetzt über den Token selbst — kein Overwrite mehr nötig, siehe .snack-ok/
262
+ .snack-err in components.css. */
263
+ /* Die Kreisflächen hier standen als hartkodierte Kopien von --c-success-bg und --c-error-bg
264
+ (#052415 / #220808) und blieben beim Anheben der Status-Tints zurück. Gegen die neue Seite
265
+ trugen sie nur ❌ 1,06:1 bzw. 1,08:1, der Kreis war keine Fläche mehr, nur noch ein farbiger
266
+ Glyph. Jetzt über die Token ✓ 1,78:1 und 1,79:1 zur Seite, 1,32 und 1,33:1 zur Card. Der
267
+ Fehler-Glyph geht mit: #F08080 trägt auf der aufgehellten Füllung nur ❌ 3,78:1, --c-error
268
+ (#FFA5A5) ✓ 5,21:1. Analog --c-success (#5CE8A0) auf Grün 6,33:1.
264
269
  (Light: helle Tints #E6F9F1 / #FDEAEA mit dunklem Glyph, kein Fix nötig.) */
265
270
  [data-theme="dark"] .a11y-ok .a11y-rule-icon { background:var(--c-success-bg); color:var(--c-success) }
266
271
  [data-theme="dark"] .a11y-fail .a11y-rule-icon { background:var(--c-error-bg); color:var(--c-error) }
@@ -482,7 +487,13 @@
482
487
  /* In-Article-Callout-Eyebrow: 700er-/800er-Ton → dunkel-auf-dunkel auf der getönten -50-Fläche
483
488
  (1,6–2,5:1). Auf die hellen Bereichs-Tints heben (8–10:1), wie bei .t-Utilities und Badges. Body-Text ist
484
489
  tx-primary und flippt ohnehin. */
485
- [data-theme="dark"] .article-callout-eyebrow { color: var(--co-200) }
490
+ /* .article-callout > vorangestellt (Befund 02, Spezifitäts-Fix in components.css): ohne den
491
+ Eltern-Qualifier lag diese Regel bei 0,2,0, exakt gleichauf mit der neuen Light-Basisregel
492
+ .article-callout > .article-callout-eyebrow — bei Gleichstand gewinnt components.css, weil es
493
+ nach dark-mode.css gebündelt wird (bundle-css.mjs), der Ton fiel im Dark auf co-700 zurück
494
+ (1,77:1 statt 4,5:1, von check:contrast gefangen). 0,3,0 hält den Vorsprung, wie bei den
495
+ Bereichs-Varianten darunter. */
496
+ [data-theme="dark"] .article-callout > .article-callout-eyebrow { color: var(--co-200) }
486
497
  [data-theme="dark"] .article-callout[data-area="ki"] .article-callout-eyebrow { color: var(--ki-200) }
487
498
  [data-theme="dark"] .article-callout[data-area="es"] .article-callout-eyebrow { color: var(--es-100) }
488
499
  [data-theme="dark"] .article-callout[data-area="wo"] .article-callout-eyebrow { color: var(--wo-200) }
package/css/tokens.css CHANGED
@@ -78,6 +78,17 @@
78
78
  --c-warning:#785008; --c-warning-bg:#F5D08C; /* Text auf #fff 7,12:1, auf dem eigenen Tint 4,84:1 (vorher #8A5E0A: 5,70 bzw. nur 3,87:1) */
79
79
  --c-error:#9B2020; --c-error-bg:#F5BFBF; /* Text auf #fff 8,01:1, auf dem eigenen Tint 4,99:1 (vorher #B22020: 6,73 bzw. nur 4,19:1) */
80
80
 
81
+ /* --c-*-strong sind die satte Snackbar-Fläche (.snack-ok/.snack-err) plus Text-/Icon-Farbe darauf
82
+ (Befund 04): eigene Tokens statt --c-success/-error, weil das dort der Tint-Text ist, hier aber
83
+ eine volle Fläche. Werte = bisheriger hartkodierter Render, keine optische Änderung. Dark-Werte
84
+ in dark-mode.css (Fläche flippt auf --c-success-bg/--c-error-bg, Icon/Text meist unverändert).
85
+ Kontrast Text/Fläche und Icon/Fläche gemessen (Formel wie scripts/check-contrast.mjs):
86
+ Light: ok Text 6,76:1, ok Icon 5,72:1 · err Text 9,19:1, err Icon 5,75:1
87
+ Dark: ok Text 6,53:1, ok Icon 6,16:1 · err Text 7,57:1, err Icon 4,74:1
88
+ (Soll ≥ 4,5:1 Text, ≥ 3:1 Icon — alle acht Paare ✓) */
89
+ --c-success-strong:#0d5e39; --c-success-on-strong:#d6f5e8; --c-success-strong-icon:#88f0c4;
90
+ --c-error-strong:#7a1515; --c-error-on-strong:#fde8e8; --c-error-strong-icon:#f9a8a8;
91
+
81
92
  /* ── Component color tokens (theme-overridable) ── */
82
93
  --badge-ok-text:var(--c-success); --badge-warn-text:var(--c-warning); --badge-err-text:var(--c-error); /* dieselben Töne wie die semantischen Textfarben: sie stehen auf denselben Tints, zwei Werte dafür wären zwei Quellen der Wahrheit */
83
94
  --badge-neu-bg:var(--n-200); --badge-neu-text:var(--n-600); /* n-200 statt n-100: als Füllung trug n-100 nur 1,18:1 gegen Weiß und 1,10:1 gegen n-50, n-200 gibt 1,53 / 1,42:1. Text darauf 6,69:1 */
@@ -102,6 +102,17 @@
102
102
  --c-warning:#785008; --c-warning-bg:#F5D08C; /* Text auf #fff 7,12:1, auf dem eigenen Tint 4,84:1 (vorher #8A5E0A: 5,70 bzw. nur 3,87:1) */
103
103
  --c-error:#9B2020; --c-error-bg:#F5BFBF; /* Text auf #fff 8,01:1, auf dem eigenen Tint 4,99:1 (vorher #B22020: 6,73 bzw. nur 4,19:1) */
104
104
 
105
+ /* --c-*-strong sind die satte Snackbar-Fläche (.snack-ok/.snack-err) plus Text-/Icon-Farbe darauf
106
+ (Befund 04): eigene Tokens statt --c-success/-error, weil das dort der Tint-Text ist, hier aber
107
+ eine volle Fläche. Werte = bisheriger hartkodierter Render, keine optische Änderung. Dark-Werte
108
+ in dark-mode.css (Fläche flippt auf --c-success-bg/--c-error-bg, Icon/Text meist unverändert).
109
+ Kontrast Text/Fläche und Icon/Fläche gemessen (Formel wie scripts/check-contrast.mjs):
110
+ Light: ok Text 6,76:1, ok Icon 5,72:1 · err Text 9,19:1, err Icon 5,75:1
111
+ Dark: ok Text 6,53:1, ok Icon 6,16:1 · err Text 7,57:1, err Icon 4,74:1
112
+ (Soll ≥ 4,5:1 Text, ≥ 3:1 Icon — alle acht Paare ✓) */
113
+ --c-success-strong:#0d5e39; --c-success-on-strong:#d6f5e8; --c-success-strong-icon:#88f0c4;
114
+ --c-error-strong:#7a1515; --c-error-on-strong:#fde8e8; --c-error-strong-icon:#f9a8a8;
115
+
105
116
  /* ── Component color tokens (theme-overridable) ── */
106
117
  --badge-ok-text:var(--c-success); --badge-warn-text:var(--c-warning); --badge-err-text:var(--c-error); /* dieselben Töne wie die semantischen Textfarben: sie stehen auf denselben Tints, zwei Werte dafür wären zwei Quellen der Wahrheit */
107
118
  --badge-neu-bg:var(--n-200); --badge-neu-text:var(--n-600); /* n-200 statt n-100: als Füllung trug n-100 nur 1,18:1 gegen Weiß und 1,10:1 gegen n-50, n-200 gibt 1,53 / 1,42:1. Text darauf 6,69:1 */
@@ -313,6 +324,12 @@
313
324
  --c-error:#FFA5A5; /* auf bg-page: 9.32:1 ✓ AAA · auf bg-surface: 6.93:1 ✓ AAA. Angehoben von
314
325
  #FF8E8E, das nur gegen bg-page geprüft war und auf bg-surface 4.0:1
315
326
  erreichte. Inline-Fehlertext sitzt aber fast immer auf bg-surface. */
327
+ /* Dark-only: Snackbar-Fläche (Befund 04) flippt auf die bereits vorhandenen --c-*-bg-Tints, der
328
+ helle Text auf --c-success-on-strong wird angehoben (--c-error-on-strong und beide -icon-Tokens
329
+ bleiben in Light UND Dark gleich, deshalb hier bewusst kein Override). Kontraste siehe
330
+ tokens.css. (Light: #0d5e39 / #d6f5e8.) */
331
+ --c-success-strong:var(--c-success-bg); --c-success-on-strong:#b0f0d0;
332
+ --c-error-strong:var(--c-error-bg);
316
333
  /* Brand tints (Dark), getrennt nach den zwei Jobs, die --XX-50 im Light in einem Wert erledigt.
317
334
  Der Grund: Ein Band muss DUNKLER bleiben als die Karten darauf, eine Badge- oder Kachel-Füllung
318
335
  muss HELLER sein als ihr Grund, sonst liest sie nicht als Fläche. Bei einer Basis von 17,51:1
@@ -484,18 +501,17 @@
484
501
  [data-theme="dark"] .logo-carousel-pause:hover { color: var(--n-200) }
485
502
  [data-theme="dark"] .ai-warning { color:var(--ki-300) }
486
503
  [data-theme="dark"] .pal-note { background:var(--c-warning-bg);color:#f0d080;border-color:#806000 }
487
- /* Dark-only: Die Flächen standen hier als hartkodierte Kopien von --c-success-bg und --c-error-bg
488
- (#052415 / #220808). Als die Status-Tints angehoben wurden, blieben die Kopien zurück und trugen
489
- nur noch ❌ 1,06:1 bzw. 1,08:1 gegen die Seite, die Snackbar war als Fläche praktisch weg.
490
- Jetzt über die Token ✓ 1,78:1 und 1,79:1; Text darauf 7,60:1 und 8,34:1. */
491
- [data-theme="dark"] .snack-ok { background:var(--c-success-bg); color:#b0f0d0 }
492
- [data-theme="dark"] .snack-err { background:var(--c-error-bg); color:#fde8e8 }
493
- /* Dieselbe Familie wie die Snackbar darüber: die Kreisflächen standen als hartkodierte Kopien von
494
- --c-success-bg und --c-error-bg (#052415 / #220808) und blieben beim Anheben der Status-Tints
495
- zurück. Gegen die neue Seite trugen sie nur ❌ 1,06:1 bzw. 1,08:1, der Kreis war keine Fläche
496
- mehr, nur noch ein farbiger Glyph. Jetzt über die Token ✓ 1,78:1 und 1,79:1 zur Seite, 1,32 und
497
- 1,33:1 zur Card. Der Fehler-Glyph geht mit: #F08080 trägt auf der aufgehellten Füllung nur
498
- ❌ 3,78:1, --c-error (#FFA5A5) ✓ 5,21:1. Analog --c-success (#5CE8A0) auf Grün 6,33:1.
504
+ /* Snackbar-Fläche/-Text (.snack-ok/.snack-err) brauchten hier früher ein eigenes Dark-Overwrite,
505
+ weil die Farben in components.css als Hex standen und im Dark nicht mitliefen. Seit Befund 04
506
+ stehen sie über --c-success-strong/--c-error-strong (tokens.css, Dark-Werte oben im Token-Block),
507
+ die Fläche flippt jetzt über den Token selbst — kein Overwrite mehr nötig, siehe .snack-ok/
508
+ .snack-err in components.css. */
509
+ /* Die Kreisflächen hier standen als hartkodierte Kopien von --c-success-bg und --c-error-bg
510
+ (#052415 / #220808) und blieben beim Anheben der Status-Tints zurück. Gegen die neue Seite
511
+ trugen sie nur ❌ 1,06:1 bzw. 1,08:1, der Kreis war keine Fläche mehr, nur noch ein farbiger
512
+ Glyph. Jetzt über die Token ✓ 1,78:1 und 1,79:1 zur Seite, 1,32 und 1,33:1 zur Card. Der
513
+ Fehler-Glyph geht mit: #F08080 trägt auf der aufgehellten Füllung nur ❌ 3,78:1, --c-error
514
+ (#FFA5A5) ✓ 5,21:1. Analog --c-success (#5CE8A0) auf Grün 6,33:1.
499
515
  (Light: helle Tints #E6F9F1 / #FDEAEA mit dunklem Glyph, kein Fix nötig.) */
500
516
  [data-theme="dark"] .a11y-ok .a11y-rule-icon { background:var(--c-success-bg); color:var(--c-success) }
501
517
  [data-theme="dark"] .a11y-fail .a11y-rule-icon { background:var(--c-error-bg); color:var(--c-error) }
@@ -717,7 +733,13 @@
717
733
  /* In-Article-Callout-Eyebrow: 700er-/800er-Ton → dunkel-auf-dunkel auf der getönten -50-Fläche
718
734
  (1,6–2,5:1). Auf die hellen Bereichs-Tints heben (8–10:1), wie bei .t-Utilities und Badges. Body-Text ist
719
735
  tx-primary und flippt ohnehin. */
720
- [data-theme="dark"] .article-callout-eyebrow { color: var(--co-200) }
736
+ /* .article-callout > vorangestellt (Befund 02, Spezifitäts-Fix in components.css): ohne den
737
+ Eltern-Qualifier lag diese Regel bei 0,2,0, exakt gleichauf mit der neuen Light-Basisregel
738
+ .article-callout > .article-callout-eyebrow — bei Gleichstand gewinnt components.css, weil es
739
+ nach dark-mode.css gebündelt wird (bundle-css.mjs), der Ton fiel im Dark auf co-700 zurück
740
+ (1,77:1 statt 4,5:1, von check:contrast gefangen). 0,3,0 hält den Vorsprung, wie bei den
741
+ Bereichs-Varianten darunter. */
742
+ [data-theme="dark"] .article-callout > .article-callout-eyebrow { color: var(--co-200) }
721
743
  [data-theme="dark"] .article-callout[data-area="ki"] .article-callout-eyebrow { color: var(--ki-200) }
722
744
  [data-theme="dark"] .article-callout[data-area="es"] .article-callout-eyebrow { color: var(--es-100) }
723
745
  [data-theme="dark"] .article-callout[data-area="wo"] .article-callout-eyebrow { color: var(--wo-200) }
@@ -1409,6 +1431,17 @@ body{font-family:var(--font);font-size:1rem;line-height:1.7;color:var(--tx-prima
1409
1431
  Interaktion liegt dann in den Buttons; so eine Karte ruht flach mit dem --bd-Rahmen aus .card.
1410
1432
  Deshalb hängt die ganze Variante an a.*: eine <article>/<div>-Karte bekommt den Schatten auch
1411
1433
  dann nicht, wenn die Klasse gesetzt ist. Das ist der Riegel, nicht nur eine Empfehlung. */
1434
+ /* Ohne data-area erbt eine <article>/<div>-Karte die Seiten-Textfarbe automatisch, weil Eyebrow
1435
+ und Media-Icon keine eigene Farbe setzen. Ein <a> bringt aber die UA-Linkfarbe UND -Unterstreichung
1436
+ mit: ohne dieses Reset läuft die Unterstreichung durch alle Block-Kinder (Eyebrow, Titel, Text,
1437
+ Meta), weil text-decoration nicht vererbt, sondern über in-flow-Nachfahren PROPAGIERT wird — ein
1438
+ text-decoration:none auf dem Kind allein stoppt das nicht, nur der Reset am <a> selbst.
1439
+ color:inherit + text-decoration:none gleichen beides an: Link-Card ohne Bereich = Card ohne
1440
+ Bereich, Bereichs-Regeln (oben) bleiben unberührt, weil sie spezifischer sind (Befund 01).
1441
+ .card-cta-link bleibt unberührt: als <span> im Card-Footer hatte es nie UA-Unterstreichung, als
1442
+ eigenständiges a.card-cta-link (css/components.css ~1377) sitzt es nie verschachtelt in a.card
1443
+ (ungültiges HTML, siehe LinkCardComponent-Klassendoku) und behält seinen eigenen Hover-Unterstrich. */
1444
+ a.card{color:inherit;text-decoration:none}
1412
1445
  a.card-elevated{box-shadow:var(--e1);border:none;background:var(--bg-surface)}
1413
1446
  a.card-elevated:hover{box-shadow:var(--e2);transform:translateY(-2px)}
1414
1447
 
@@ -1852,8 +1885,11 @@ a.card-elevated:hover{box-shadow:var(--e2);transform:translateY(-2px)}
1852
1885
  /* ── Snackbar ── */
1853
1886
  .snack{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) var(--s5);border-radius:var(--r-md);font:var(--ty-body-md);max-width:480px;box-shadow:var(--e3);margin-bottom:var(--s3);min-height:48px}
1854
1887
  .snack-def{background:var(--n-700);color:var(--n-0)}
1855
- .snack-ok{background:#0d5e39;color:#d6f5e8}
1856
- .snack-err{background:#7a1515;color:#fde8e8}
1888
+ /* Tokens statt Hardcodes (Befund 04): Werte und Kontraste stehen bei --c-success-strong/
1889
+ --c-error-strong in tokens.css. Die Fläche flippt im Dark über den Token, kein eigenes
1890
+ Dark-Overwrite hier nötig. */
1891
+ .snack-ok{background:var(--c-success-strong);color:var(--c-success-on-strong)}
1892
+ .snack-err{background:var(--c-error-strong);color:var(--c-error-on-strong)}
1857
1893
  .snack-act{margin-left:auto;background:none;border:none;color:inherit;opacity:.8;font:var(--ty-label-sm);cursor:pointer;text-transform:uppercase;letter-spacing:.04em;padding:0}
1858
1894
 
1859
1895
  /* ── Footer ──
@@ -2861,7 +2897,10 @@ thead th[aria-sort="descending"] .tbl-sort svg{opacity:1;color:var(--co-600)}
2861
2897
  .article-callout[data-area="ki"]{background:var(--ki-50);border-left-color:var(--ki-500)}
2862
2898
  .article-callout[data-area="es"]{background:var(--es-50);border-left-color:var(--es-500)}
2863
2899
  .article-callout[data-area="wo"]{background:var(--wo-50);border-left-color:var(--wo-500)}
2864
- .article-callout-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--co-700);margin:0 0 var(--s1)}
2900
+ /* Direktkind-Selektor statt reiner Klasse: die Eyebrow ist selbst ein <p>, also schlägt
2901
+ .article-callout > p (0,1,1) unten sonst diese Regel (0,1,0). Mit
2902
+ .article-callout > .article-callout-eyebrow (0,2,0) gewinnt die Eyebrow (Befund 02). */
2903
+ .article-callout > .article-callout-eyebrow{font:var(--ty-label-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--co-700);margin:0 0 var(--s1)}
2865
2904
  .article-callout[data-area="ki"] .article-callout-eyebrow{color:var(--ki-800)}
2866
2905
  .article-callout[data-area="es"] .article-callout-eyebrow{color:var(--es-700)}
2867
2906
  .article-callout[data-area="wo"] .article-callout-eyebrow{color:var(--wo-700)}
package/icons/README.md CHANGED
@@ -7,7 +7,9 @@ neue/geänderte Icons in `icons/source/` ablegen und `npm run build:icons` ausf
7
7
  ## Inhalt
8
8
 
9
9
  - `icons/icons.json` — Map `key → { name, area, style, viewBox, strokeWidth?, body, svg, usage? }`
10
- - `icons/icons.js` — derselbe Datensatz als ESM (`import { icons } from '@conciso/design-system/icons'`)
10
+ - `icons/icons.js` — derselbe Datensatz als ESM: **ein benannter Export pro Icon** (camelCase,
11
+ z. B. `uiShieldCheck`) **plus** das aggregierte `icons`-Objekt (Key → Eintrag)
12
+ - `icons/icons.d.ts` — Typdeklaration zu `icons/icons.js` (benannte Exporte + `icons`, je `CdsIconEntry`)
11
13
  - `icons/source/*.svg` — die einzelnen normalisierten Quell-SVGs (Dateiname = Key)
12
14
 
13
15
  ## Konventionen
@@ -20,15 +22,37 @@ neue/geänderte Icons in `icons/source/` ablegen und `npm run build:icons` ausf
20
22
  `color` (z. B. `color: var(--ki-800)` bzw. im Dark `--ki-200`). Keine hartkodierten Hex-Werte.
21
23
  - **Self-contained:** Outline-Icons tragen ihre `stroke-width` inline → `set:html` funktioniert ohne
22
24
  Wrapper-Annahmen über den Stil. Größe via `width`/`height` oder CSS (viewBox bleibt erhalten).
23
- - **Keys:** `{area}-{name}` für die Bereichs-Glyphen (`co|ki|es|wo`), `ui-{name}` für bereichsneutrale Icons.
25
+ - **Keys:** `{area}-{name}` für die Bereichs-Glyphen (`co|ki|es|wo`), `ui-{name}` für bereichsneutrale
26
+ Icons. Jeder Key hat einen benannten Export in camelCase (Bindestrich-Segment groß:
27
+ `ui-caret-down` → `uiCaretDown`, `co-building` → `coBuilding`); der Generator bricht bei einer
28
+ Kollision oder einem ungültigen JS-Bezeichner ab.
24
29
 
25
30
  ## Verwendung
26
31
 
32
+ **Empfohlen: benannter Import.** Nur benannte Imports sind tree-shakable — jeder Export ist ein
33
+ eigenes `const` auf Modulebene ohne Property-Zugriff oder Funktionsaufruf, Bundler (Webpack,
34
+ Rollup, esbuild, Angular/Vite) lassen dadurch jedes nicht importierte Icon aus dem Bundle.
35
+
36
+ ```js
37
+ import { uiShieldCheck } from '@conciso/design-system/icons';
38
+
39
+ uiShieldCheck.svg // komplettes <svg>…</svg> (currentColor, self-contained)
40
+ uiShieldCheck.body // nur das innere Markup (für set:html in ein bestehendes <svg>)
41
+ uiShieldCheck.style // "outline"
42
+ ```
43
+
44
+ **Aggregat `icons` / `icons.json`: nur für Kataloge und Doku.** `import { icons } from
45
+ '@conciso/design-system/icons'` oder der Import von `icons.json` liefert alle 99 Icons in einem
46
+ Objekt — praktisch für eine Icon-Galerie oder einen dynamischen Lookup per String-Key, zieht dabei
47
+ aber immer die komplette Bibliothek ins Bundle, auch wenn nur ein Icon benutzt wird. In Apps daher
48
+ immer den benannten Import verwenden; `icons`/`icons.json` bleiben Kataloge/Doku (z. B. die
49
+ Storybook-Icon-Galerie) vorbehalten.
50
+
27
51
  ```js
28
52
  import { icons } from '@conciso/design-system/icons';
29
53
  // oder: import iconsJson from '@conciso/design-system/icons.json' assert { type: 'json' };
30
54
 
31
- const shield = icons['ui-shield-check'];
55
+ const shield = icons['ui-shield-check']; // äquivalent zu uiShieldCheck oben, aber nicht tree-shakable
32
56
  shield.svg // komplettes <svg>…</svg> (currentColor, self-contained)
33
57
  shield.body // nur das innere Markup (für set:html in ein bestehendes <svg>)
34
58
  shield.style // "outline"
@@ -38,8 +62,8 @@ shield.style // "outline"
38
62
 
39
63
  ```astro
40
64
  ---
41
- import { icons } from '@conciso/design-system/icons';
42
- const { svg } = icons['ki-bot'];
65
+ import { kiBot } from '@conciso/design-system/icons';
66
+ const { svg } = kiBot;
43
67
  ---
44
68
  <span class="icon" set:html={svg} />
45
69
  <style>.icon { color: var(--ki-800); display: inline-flex; }
@@ -63,124 +87,124 @@ Karten. Das Marken-Glyph ist dem Verweis auf den Bereich selbst vorbehalten.
63
87
 
64
88
  ### Corporate
65
89
 
66
- | Key | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
67
- |---|---|---|---|
68
- | `co-building` | Corporate / Unternehmen – Bereichs-Glyphe (Gebäude) | solid | icon-size-swatch @co |
69
- | `co-mark` | Corporate – Logo-Zeichen „C.“ (nur mit Logo verwenden) | solid | icon-size-swatch @co |
90
+ | Key | Export | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
91
+ |---|---|---|---|---|
92
+ | `co-building` | `coBuilding` | Corporate / Unternehmen – Bereichs-Glyphe (Gebäude) | solid | icon-size-swatch @co |
93
+ | `co-mark` | `coMark` | Corporate – Logo-Zeichen „C.“ (nur mit Logo verwenden) | solid | icon-size-swatch @co |
70
94
 
71
95
  ### Angewandte KI
72
96
 
73
- | Key | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
74
- |---|---|---|---|
75
- | `ki-bot` | Angewandte KI – Bereichs-Glyphe (Tablet/Bot) | solid | icon-size-swatch @ki, ep-card-icon t-ki @ki |
97
+ | Key | Export | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
98
+ |---|---|---|---|---|
99
+ | `ki-bot` | `kiBot` | Angewandte KI – Bereichs-Glyphe (Tablet/Bot) | solid | icon-size-swatch @ki, ep-card-icon t-ki @ki |
76
100
 
77
101
  ### Effektive Software
78
102
 
79
- | Key | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
80
- |---|---|---|---|
81
- | `es-window-check` | Effektive Software – Bereichs-Glyphe (Fenster + Check) | solid | icon-size-swatch @es, ep-card-icon t-es @es |
103
+ | Key | Export | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
104
+ |---|---|---|---|---|
105
+ | `es-window-check` | `esWindowCheck` | Effektive Software – Bereichs-Glyphe (Fenster + Check) | solid | icon-size-swatch @es, ep-card-icon t-es @es |
82
106
 
83
107
  ### Wirksame Organisationen
84
108
 
85
- | Key | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
86
- |---|---|---|---|
87
- | `wo-network` | Wirksame Organisationen – Bereichs-Glyphe (Netzwerk) | solid | icon-size-swatch @wo, ep-card-icon t-wo @wo |
109
+ | Key | Export | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
110
+ |---|---|---|---|---|
111
+ | `wo-network` | `woNetwork` | Wirksame Organisationen – Bereichs-Glyphe (Netzwerk) | solid | icon-size-swatch @wo, ep-card-icon t-wo @wo |
88
112
 
89
113
  ### Bereichsneutral (UI)
90
114
 
91
- | Key | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
92
- |---|---|---|---|
93
- | `ui-academic-cap` | Doktorhut / Lernen | outline | ep-feature-icon @co |
94
- | `ui-adjustments-horizontal` | Regler / Einstellungen | outline (1.25) | ep-card-icon @ki |
95
- | `ui-arrow-down-tray-2` | Download (Outline-Variante) | outline (1.5) | docs-nav (cta) |
96
- | `ui-arrow-down-tray` | Download | solid | cta-dl-icon @ki |
97
- | `ui-arrow-path` | Aktualisieren / Kreislauf | outline (1.25) | ep-card-icon @wo |
98
- | `ui-arrow-trending-up` | Trend aufwärts | outline (1.25) | ep-card-icon @ki |
99
- | `ui-banknotes` | Geldscheine | outline | ep-feature-icon @co |
100
- | `ui-bars-3-center-left` | Balken, mittlere Zeile kurz und linksbündig (Footer) | outline (1.5) | docs-nav (footer) |
101
- | `ui-bars-3` | Balken (Hamburger-Navigation) | outline (1.5) | docs-nav (navigation) |
102
- | `ui-bolt-2` | Blitz (Variante) | outline (1.25) | card-media @es |
103
- | `ui-bolt` | Blitz | outline (1.25) | ep-card-icon @co, ep-card-icon @ki |
104
- | `ui-book-open` | Aufgeschlagenes Buch / Quellen | outline (1.5) | docs-nav (sources) |
105
- | `ui-briefcase-2` | Aktenkoffer (Variante) | outline | ep-section |
106
- | `ui-briefcase` | Aktenkoffer | outline (1.25) | ep-card-icon @co |
107
- | `ui-building-office` | Bürogebäude | outline (1.5) | ep-tl-icon |
108
- | `ui-calendar-days` | Kalender (Tage) | outline (1.25) | ep-card-icon @co, col-3, stoerer-icon (Veranstaltung) |
109
- | `ui-calendar` | Kalender | outline (1) | card-meta |
110
- | `ui-caret-down` | Caret nach unten (Nav-Toggle) | outline | ep-tab-toggle, ep-nav-btn ep-nav-item-toggle, ep-nav-btn ep-nav-item-toggle t-co |
111
- | `ui-chart-bar` | Balkendiagramm | outline | ep-feature-icon @co |
112
- | `ui-chat-bubble-left-right` | Chat-Blasen (Dialog) | outline (1.5) | ep-feature-icon, ep-feature-icon @ki |
113
- | `ui-chat-bubble-oval-left-ellipsis` | Chat-Blase oval mit Auslassungspunkten | outline (1.5) | docs-nav (feedback) |
114
- | `ui-chat-bubble-oval` | Chat-Blase (oval) | outline (1.25) | ep-card-icon @ki |
115
- | `ui-check-badge` | Verifiziert-Abzeichen | solid | — |
116
- | `ui-check-circle-2` | Häkchen im Kreis (Variante) | outline (1.5) | — |
117
- | `ui-check-circle` | Häkchen im Kreis | outline | — |
118
- | `ui-check` | Häkchen (klein) | outline | — |
119
- | `ui-chevron-down` | Chevron nach unten (FAQ/Akkordeon) | outline (1.25) | ep-faq, ep-faq-a, ep-compare-summary, article-toc-summary |
120
- | `ui-chevron-up-down` | Chevron auf/ab (Dropdown-Toggle) | outline (1.5) | docs-nav (dropdowns) |
121
- | `ui-circle-stack` | Datenbank / Stapel | outline (1.25) | card-media @es |
122
- | `ui-clock` | Uhr | outline | ep-feature-icon @co |
123
- | `ui-code-bracket-2` | Code-Klammern (Variante) | outline (1.25) | ep-card-icon @es |
124
- | `ui-code-bracket-square` | Code-Klammern im Quadrat | outline (1.5) | docs-nav (code) |
125
- | `ui-code-bracket` | Code-Klammern | outline | — |
126
- | `ui-cog-6tooth` | Zahnrad (6 Zähne) | outline (1.5) | ep-feature-icon @ki |
127
- | `ui-cog` | Zahnrad | outline (1.25) | ep-card-icon @ki |
128
- | `ui-computer-desktop` | Desktop-Rechner / Hero | outline (1.5) | docs-nav (hero) |
129
- | `ui-cpu-chip-2` | CPU / Chip (Variante) | outline (1.5) | ep-feature-icon |
130
- | `ui-cpu-chip` | CPU / Chip | outline (1.25) | ep-card-icon @ki |
131
- | `ui-cube-2` | Würfel (Variante) | outline (1.5) | ep-feature-icon @ki |
132
- | `ui-cube-transparent` | Würfel transparent / Design Tokens | outline (1.5) | docs-nav (tokens) |
133
- | `ui-cube` | Würfel / Box | outline (1.25) | ep-card-icon @ki |
134
- | `ui-currency-euro` | Euro | outline (1.25) | col-3 |
135
- | `ui-cursor-arrow-rays` | Cursor mit Strahlen / Interaktion | outline (1.5) | docs-nav (buttons) |
136
- | `ui-device-phone-mobile` | Mobilgerät / Responsive | outline (1.5) | docs-nav (responsive) |
137
- | `ui-document-text` | Dokument mit Text / Wissensbeitrag | outline (1.5) | docs-nav (article) |
138
- | `ui-face-smile` | Smiley / Icons | outline (1.5) | docs-nav (icons) |
139
- | `ui-flag` | Fahne / Markenrad | outline (1.5) | docs-nav (brand) |
140
- | `ui-folder` | Ordner | outline (1.25) | ep-card-icon @co |
141
- | `ui-hand-raised` | Erhobene Hand | outline (1.25) | ep-card-icon @co |
142
- | `ui-heart` | Herz | outline | ep-feature-icon @co |
143
- | `ui-information-circle` | Info im Kreis | outline (1.25) | stoerer-icon (Info) |
144
- | `ui-language` | Sprache / Typografie | outline (1.5) | docs-nav (typography) |
145
- | `ui-link` | Kettenglied / Link | outline (1.5) | ep-feature-icon @ki |
146
- | `ui-list-bullet` | Aufzählungsliste | outline | — |
147
- | `ui-lock-closed-2` | Schloss (Variante) | outline (1.25) | ep-card-icon @ki |
148
- | `ui-lock-closed` | Schloss geschlossen | outline (1.5) | ep-feature-icon |
149
- | `ui-magnifying-glass` | Lupe | outline (1.25) | ep-card-icon @ki |
150
- | `ui-map-pin-2` | Standort-Pin (Variante) | outline (1.25) | col-3 |
151
- | `ui-map-pin` | Standort-Pin | outline (1) | — |
152
- | `ui-megaphone` | Megafon / Verlautbarung | outline (1.25) | stoerer-icon (Pressemitteilung) |
153
- | `ui-newspaper-2` | Zeitung / Artikel (Variante) | outline (1.5) | docs-nav (listing), docs-nav (events) |
154
- | `ui-newspaper` | Zeitung / Artikel | outline (1.25) | ep-card-icon @co, ep-card-icon @ki, stoerer-icon (Wissensbeitrag) |
155
- | `ui-pause` | Pause | solid | logo-carousel-pause |
156
- | `ui-pencil-square` | Stift im Quadrat / Bearbeiten | outline (1.5) | docs-nav (inputs) |
157
- | `ui-photo` | Foto / Bildsprache | outline (1.5) | docs-nav (imagery) |
158
- | `ui-play` | Play | solid | icon-pause |
159
- | `ui-puzzle-piece` | Puzzleteil | outline (1.5) | ep-tl-icon |
160
- | `ui-quote` | Zitatzeichen (Team-Stimme) | solid | team-voice-body @co |
161
- | `ui-rectangle-stack` | Rechteck-Stapel / Cards | outline (1.5) | docs-nav (cards) |
162
- | `ui-rocket-launch` | Rakete | outline (1.5) | ep-tl-icon |
163
- | `ui-shield-check-2` | Schild mit Häkchen (Variante) | outline | ep-feature-icon @co |
164
- | `ui-shield-check` | Schild mit Häkchen | outline (1.25) | ep-card-icon @co, ep-card-icon @ki, ep-card-icon @es |
165
- | `ui-sparkles-2` | Funkeln (Variante) | outline (1.5) | ep-feature-icon @ki |
166
- | `ui-sparkles-3` | Funkeln (Variante) | outline (1.25) | card-media @es |
167
- | `ui-sparkles-4` | Funkeln (Variante, drei Strahlen) | outline (1.5) | docs-nav (brand) |
168
- | `ui-sparkles` | Funkeln / Sparkles | outline (1.25) | ep-card-icon @ki |
169
- | `ui-square-2-stack` | Quadrate gestapelt / Slider | outline (1.5) | docs-nav (slider) |
170
- | `ui-squares-2x2` | Raster 2×2 | outline (1.25) | ep-card-icon @ki, ep-card-icon @es |
171
- | `ui-squares-plus` | Module / Raster+ | outline (1.25) | ep-card-icon @wo |
172
- | `ui-star-2` | Stern (Variante) | outline | — |
173
- | `ui-star` | Stern | outline (1.5) | ep-tl-icon |
174
- | `ui-sun` | Sonne / Theme-Umschalter | outline (1.5) | docs-nav (theme) |
175
- | `ui-swatch` | Farbfeld / Swatch | outline (1.5) | ep-tl-icon |
176
- | `ui-table-cells` | Tabellenzellen | outline (1.5) | docs-nav (table) |
177
- | `ui-tag` | Preisschild / Tag | outline (1.5) | docs-nav (chips), docs-nav (leistung-detail) |
178
- | `ui-trophy-2` | Pokal (Variante) | outline | — |
179
- | `ui-trophy` | Pokal | outline (1.5) | ep-tl-icon |
180
- | `ui-user-group-2` | Personengruppe (Variante) | outline | ep-feature-icon @co |
181
- | `ui-user-group` | Personengruppe (3) | outline (1.25) | ep-card-icon @co, ep-card-icon @wo, col-3 |
182
- | `ui-users-2` | Personen (Variante) | outline | — |
183
- | `ui-users` | Personen (2) | outline (1) | — |
184
- | `ui-viewfinder-circle` | Sucher / Fokus | outline (1.25) | ep-card-icon @co |
185
- | `ui-window` | Browserfenster / Beispielseiten | outline (1.5) | docs-nav (examples) |
186
- | `ui-wrench-screwdriver` | Werkzeug (Schlüssel + Schraubendreher) | outline (1.25) | ep-card-icon @co |
115
+ | Key | Export | Name | Stil (Stroke-Width) | Verwendung (DS-Kontext) |
116
+ |---|---|---|---|---|
117
+ | `ui-academic-cap` | `uiAcademicCap` | Doktorhut / Lernen | outline | ep-feature-icon @co |
118
+ | `ui-adjustments-horizontal` | `uiAdjustmentsHorizontal` | Regler / Einstellungen | outline (1.25) | ep-card-icon @ki |
119
+ | `ui-arrow-down-tray-2` | `uiArrowDownTray2` | Download (Outline-Variante) | outline (1.5) | docs-nav (cta) |
120
+ | `ui-arrow-down-tray` | `uiArrowDownTray` | Download | solid | cta-dl-icon @ki |
121
+ | `ui-arrow-path` | `uiArrowPath` | Aktualisieren / Kreislauf | outline (1.25) | ep-card-icon @wo |
122
+ | `ui-arrow-trending-up` | `uiArrowTrendingUp` | Trend aufwärts | outline (1.25) | ep-card-icon @ki |
123
+ | `ui-banknotes` | `uiBanknotes` | Geldscheine | outline | ep-feature-icon @co |
124
+ | `ui-bars-3-center-left` | `uiBars3CenterLeft` | Balken, mittlere Zeile kurz und linksbündig (Footer) | outline (1.5) | docs-nav (footer) |
125
+ | `ui-bars-3` | `uiBars3` | Balken (Hamburger-Navigation) | outline (1.5) | docs-nav (navigation) |
126
+ | `ui-bolt-2` | `uiBolt2` | Blitz (Variante) | outline (1.25) | card-media @es |
127
+ | `ui-bolt` | `uiBolt` | Blitz | outline (1.25) | ep-card-icon @co, ep-card-icon @ki |
128
+ | `ui-book-open` | `uiBookOpen` | Aufgeschlagenes Buch / Quellen | outline (1.5) | docs-nav (sources) |
129
+ | `ui-briefcase-2` | `uiBriefcase2` | Aktenkoffer (Variante) | outline | ep-section |
130
+ | `ui-briefcase` | `uiBriefcase` | Aktenkoffer | outline (1.25) | ep-card-icon @co |
131
+ | `ui-building-office` | `uiBuildingOffice` | Bürogebäude | outline (1.5) | ep-tl-icon |
132
+ | `ui-calendar-days` | `uiCalendarDays` | Kalender (Tage) | outline (1.25) | ep-card-icon @co, col-3, stoerer-icon (Veranstaltung) |
133
+ | `ui-calendar` | `uiCalendar` | Kalender | outline (1) | card-meta |
134
+ | `ui-caret-down` | `uiCaretDown` | Caret nach unten (Nav-Toggle) | outline | ep-tab-toggle, ep-nav-btn ep-nav-item-toggle, ep-nav-btn ep-nav-item-toggle t-co |
135
+ | `ui-chart-bar` | `uiChartBar` | Balkendiagramm | outline | ep-feature-icon @co |
136
+ | `ui-chat-bubble-left-right` | `uiChatBubbleLeftRight` | Chat-Blasen (Dialog) | outline (1.5) | ep-feature-icon, ep-feature-icon @ki |
137
+ | `ui-chat-bubble-oval-left-ellipsis` | `uiChatBubbleOvalLeftEllipsis` | Chat-Blase oval mit Auslassungspunkten | outline (1.5) | docs-nav (feedback) |
138
+ | `ui-chat-bubble-oval` | `uiChatBubbleOval` | Chat-Blase (oval) | outline (1.25) | ep-card-icon @ki |
139
+ | `ui-check-badge` | `uiCheckBadge` | Verifiziert-Abzeichen | solid | — |
140
+ | `ui-check-circle-2` | `uiCheckCircle2` | Häkchen im Kreis (Variante) | outline (1.5) | — |
141
+ | `ui-check-circle` | `uiCheckCircle` | Häkchen im Kreis | outline | — |
142
+ | `ui-check` | `uiCheck` | Häkchen (klein) | outline | — |
143
+ | `ui-chevron-down` | `uiChevronDown` | Chevron nach unten (FAQ/Akkordeon) | outline (1.25) | ep-faq, ep-faq-a, ep-compare-summary, article-toc-summary |
144
+ | `ui-chevron-up-down` | `uiChevronUpDown` | Chevron auf/ab (Dropdown-Toggle) | outline (1.5) | docs-nav (dropdowns) |
145
+ | `ui-circle-stack` | `uiCircleStack` | Datenbank / Stapel | outline (1.25) | card-media @es |
146
+ | `ui-clock` | `uiClock` | Uhr | outline | ep-feature-icon @co |
147
+ | `ui-code-bracket-2` | `uiCodeBracket2` | Code-Klammern (Variante) | outline (1.25) | ep-card-icon @es |
148
+ | `ui-code-bracket-square` | `uiCodeBracketSquare` | Code-Klammern im Quadrat | outline (1.5) | docs-nav (code) |
149
+ | `ui-code-bracket` | `uiCodeBracket` | Code-Klammern | outline | — |
150
+ | `ui-cog-6tooth` | `uiCog6tooth` | Zahnrad (6 Zähne) | outline (1.5) | ep-feature-icon @ki |
151
+ | `ui-cog` | `uiCog` | Zahnrad | outline (1.25) | ep-card-icon @ki |
152
+ | `ui-computer-desktop` | `uiComputerDesktop` | Desktop-Rechner / Hero | outline (1.5) | docs-nav (hero) |
153
+ | `ui-cpu-chip-2` | `uiCpuChip2` | CPU / Chip (Variante) | outline (1.5) | ep-feature-icon |
154
+ | `ui-cpu-chip` | `uiCpuChip` | CPU / Chip | outline (1.25) | ep-card-icon @ki |
155
+ | `ui-cube-2` | `uiCube2` | Würfel (Variante) | outline (1.5) | ep-feature-icon @ki |
156
+ | `ui-cube-transparent` | `uiCubeTransparent` | Würfel transparent / Design Tokens | outline (1.5) | docs-nav (tokens) |
157
+ | `ui-cube` | `uiCube` | Würfel / Box | outline (1.25) | ep-card-icon @ki |
158
+ | `ui-currency-euro` | `uiCurrencyEuro` | Euro | outline (1.25) | col-3 |
159
+ | `ui-cursor-arrow-rays` | `uiCursorArrowRays` | Cursor mit Strahlen / Interaktion | outline (1.5) | docs-nav (buttons) |
160
+ | `ui-device-phone-mobile` | `uiDevicePhoneMobile` | Mobilgerät / Responsive | outline (1.5) | docs-nav (responsive) |
161
+ | `ui-document-text` | `uiDocumentText` | Dokument mit Text / Wissensbeitrag | outline (1.5) | docs-nav (article) |
162
+ | `ui-face-smile` | `uiFaceSmile` | Smiley / Icons | outline (1.5) | docs-nav (icons) |
163
+ | `ui-flag` | `uiFlag` | Fahne / Markenrad | outline (1.5) | docs-nav (brand) |
164
+ | `ui-folder` | `uiFolder` | Ordner | outline (1.25) | ep-card-icon @co |
165
+ | `ui-hand-raised` | `uiHandRaised` | Erhobene Hand | outline (1.25) | ep-card-icon @co |
166
+ | `ui-heart` | `uiHeart` | Herz | outline | ep-feature-icon @co |
167
+ | `ui-information-circle` | `uiInformationCircle` | Info im Kreis | outline (1.25) | stoerer-icon (Info) |
168
+ | `ui-language` | `uiLanguage` | Sprache / Typografie | outline (1.5) | docs-nav (typography) |
169
+ | `ui-link` | `uiLink` | Kettenglied / Link | outline (1.5) | ep-feature-icon @ki |
170
+ | `ui-list-bullet` | `uiListBullet` | Aufzählungsliste | outline | — |
171
+ | `ui-lock-closed-2` | `uiLockClosed2` | Schloss (Variante) | outline (1.25) | ep-card-icon @ki |
172
+ | `ui-lock-closed` | `uiLockClosed` | Schloss geschlossen | outline (1.5) | ep-feature-icon |
173
+ | `ui-magnifying-glass` | `uiMagnifyingGlass` | Lupe | outline (1.25) | ep-card-icon @ki |
174
+ | `ui-map-pin-2` | `uiMapPin2` | Standort-Pin (Variante) | outline (1.25) | col-3 |
175
+ | `ui-map-pin` | `uiMapPin` | Standort-Pin | outline (1) | — |
176
+ | `ui-megaphone` | `uiMegaphone` | Megafon / Verlautbarung | outline (1.25) | stoerer-icon (Pressemitteilung) |
177
+ | `ui-newspaper-2` | `uiNewspaper2` | Zeitung / Artikel (Variante) | outline (1.5) | docs-nav (listing), docs-nav (events) |
178
+ | `ui-newspaper` | `uiNewspaper` | Zeitung / Artikel | outline (1.25) | ep-card-icon @co, ep-card-icon @ki, stoerer-icon (Wissensbeitrag) |
179
+ | `ui-pause` | `uiPause` | Pause | solid | logo-carousel-pause |
180
+ | `ui-pencil-square` | `uiPencilSquare` | Stift im Quadrat / Bearbeiten | outline (1.5) | docs-nav (inputs) |
181
+ | `ui-photo` | `uiPhoto` | Foto / Bildsprache | outline (1.5) | docs-nav (imagery) |
182
+ | `ui-play` | `uiPlay` | Play | solid | icon-pause |
183
+ | `ui-puzzle-piece` | `uiPuzzlePiece` | Puzzleteil | outline (1.5) | ep-tl-icon |
184
+ | `ui-quote` | `uiQuote` | Zitatzeichen (Team-Stimme) | solid | team-voice-body @co |
185
+ | `ui-rectangle-stack` | `uiRectangleStack` | Rechteck-Stapel / Cards | outline (1.5) | docs-nav (cards) |
186
+ | `ui-rocket-launch` | `uiRocketLaunch` | Rakete | outline (1.5) | ep-tl-icon |
187
+ | `ui-shield-check-2` | `uiShieldCheck2` | Schild mit Häkchen (Variante) | outline | ep-feature-icon @co |
188
+ | `ui-shield-check` | `uiShieldCheck` | Schild mit Häkchen | outline (1.25) | ep-card-icon @co, ep-card-icon @ki, ep-card-icon @es |
189
+ | `ui-sparkles-2` | `uiSparkles2` | Funkeln (Variante) | outline (1.5) | ep-feature-icon @ki |
190
+ | `ui-sparkles-3` | `uiSparkles3` | Funkeln (Variante) | outline (1.25) | card-media @es |
191
+ | `ui-sparkles-4` | `uiSparkles4` | Funkeln (Variante, drei Strahlen) | outline (1.5) | docs-nav (brand) |
192
+ | `ui-sparkles` | `uiSparkles` | Funkeln / Sparkles | outline (1.25) | ep-card-icon @ki |
193
+ | `ui-square-2-stack` | `uiSquare2Stack` | Quadrate gestapelt / Slider | outline (1.5) | docs-nav (slider) |
194
+ | `ui-squares-2x2` | `uiSquares2x2` | Raster 2×2 | outline (1.25) | ep-card-icon @ki, ep-card-icon @es |
195
+ | `ui-squares-plus` | `uiSquaresPlus` | Module / Raster+ | outline (1.25) | ep-card-icon @wo |
196
+ | `ui-star-2` | `uiStar2` | Stern (Variante) | outline | — |
197
+ | `ui-star` | `uiStar` | Stern | outline (1.5) | ep-tl-icon |
198
+ | `ui-sun` | `uiSun` | Sonne / Theme-Umschalter | outline (1.5) | docs-nav (theme) |
199
+ | `ui-swatch` | `uiSwatch` | Farbfeld / Swatch | outline (1.5) | ep-tl-icon |
200
+ | `ui-table-cells` | `uiTableCells` | Tabellenzellen | outline (1.5) | docs-nav (table) |
201
+ | `ui-tag` | `uiTag` | Preisschild / Tag | outline (1.5) | docs-nav (chips), docs-nav (leistung-detail) |
202
+ | `ui-trophy-2` | `uiTrophy2` | Pokal (Variante) | outline | — |
203
+ | `ui-trophy` | `uiTrophy` | Pokal | outline (1.5) | ep-tl-icon |
204
+ | `ui-user-group-2` | `uiUserGroup2` | Personengruppe (Variante) | outline | ep-feature-icon @co |
205
+ | `ui-user-group` | `uiUserGroup` | Personengruppe (3) | outline (1.25) | ep-card-icon @co, ep-card-icon @wo, col-3 |
206
+ | `ui-users-2` | `uiUsers2` | Personen (Variante) | outline | — |
207
+ | `ui-users` | `uiUsers` | Personen (2) | outline (1) | — |
208
+ | `ui-viewfinder-circle` | `uiViewfinderCircle` | Sucher / Fokus | outline (1.25) | ep-card-icon @co |
209
+ | `ui-window` | `uiWindow` | Browserfenster / Beispielseiten | outline (1.5) | docs-nav (examples) |
210
+ | `ui-wrench-screwdriver` | `uiWrenchScrewdriver` | Werkzeug (Schlüssel + Schraubendreher) | outline (1.25) | ep-card-icon @co |