@conciso/design-system 0.0.0-bootstrap.0 → 2.1.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 +22 -26
- package/css/components.css +20 -3
- package/css/dark-mode.css +24 -13
- package/css/tokens.css +11 -0
- package/dist/conciso-ds.css +55 -16
- package/package.json +1 -1
- package/tokens/tokens.js +9 -0
- package/tokens/tokens.json +9 -0
- package/tokens/tokens.scss +9 -0
package/README.md
CHANGED
|
@@ -41,8 +41,15 @@ Ausführlich in [docs/GETTING-STARTED.md](docs/GETTING-STARTED.md). Kurzfassung:
|
|
|
41
41
|
|
|
42
42
|
Die Schriften (Montserrat + Libre Baskerville) liegen self-hosted unter `fonts/` und werden über `css/fonts.css` eingebunden — keine externe CDN-Anfrage. Das gebündelte `dist/conciso-ds.css` enthält die `@font-face`-Regeln bereits.
|
|
43
43
|
|
|
44
|
-
**Variante B — als npm-Paket
|
|
44
|
+
**Variante B — als npm-Paket aus GitHub Packages** (der empfohlene Weg):
|
|
45
45
|
|
|
46
|
+
Das Paket liegt privat und org-scoped in GitHub Packages. Das Konsumenten-Projekt
|
|
47
|
+
braucht dafür eine `.npmrc`, die den `@conciso`-Scope umleitet:
|
|
48
|
+
|
|
49
|
+
```ini
|
|
50
|
+
@conciso:registry=https://npm.pkg.github.com
|
|
51
|
+
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
|
|
52
|
+
```
|
|
46
53
|
```bash
|
|
47
54
|
npm install @conciso/design-system
|
|
48
55
|
```
|
|
@@ -56,37 +63,26 @@ import { icons } from '@conciso/design-system/icons';
|
|
|
56
63
|
import logo from '@conciso/design-system/assets/brand/logo-conciso.svg';
|
|
57
64
|
```
|
|
58
65
|
|
|
59
|
-
Keine `.npmrc` nötig — das Paket liegt auf der öffentlichen npm-Registry, `npm install`
|
|
60
|
-
funktioniert ohne weitere Einrichtung. Siehe [ADR-0011](docs/adr/0011-veroeffentlichung-auf-npmjs.md).
|
|
61
|
-
Gilt ab dem ersten echten Release nach dem Merge dieser Änderung; bis dahin liegt auf
|
|
62
|
-
npmjs nur eine Bootstrap-Platzhalterversion (siehe ADR-0011).
|
|
63
|
-
|
|
64
66
|
Die Wortmarke liegt als SVG unter [`assets/brand/`](assets/brand/README.md) (Default, Light, Dark). Größen, Schutzraum und Verwendung stehen in der Doku unter **Marke → Logo**.
|
|
65
67
|
|
|
66
68
|
> Das Paket steht unter der [MIT-Lizenz](LICENSE) (Ausnahmen — Brand-Assets, Schriften,
|
|
67
|
-
> Icons — siehe [NOTICE](NOTICE))
|
|
68
|
-
>
|
|
69
|
-
>
|
|
70
|
-
>
|
|
71
|
-
>
|
|
72
|
-
>
|
|
73
|
-
> ```ini
|
|
74
|
-
> @conciso:registry=https://npm.pkg.github.com
|
|
75
|
-
> //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
|
|
76
|
-
> ```
|
|
77
|
-
> GitHub Packages verlangt diese Auth wegen der **Registry**, nicht wegen der Lizenz.
|
|
78
|
-
> Details in [Getting Started](docs/GETTING-STARTED.md#1-einbinden), Begründung in
|
|
79
|
-
> [ADR-0004](docs/adr/0004-verteilung-und-versionierung.md). Ohne npm bleibt Variante A
|
|
80
|
-
> (Vendoren von `dist/conciso-ds.css` + `fonts/`) der schlankeste Weg.
|
|
69
|
+
> Icons — siehe [NOTICE](NOTICE)), liegt aber weiterhin in GitHub Packages statt der
|
|
70
|
+
> öffentlichen npm-Registry — GitHub Packages verlangt daher Auth auch fürs Lesen (lokal
|
|
71
|
+
> ein Token mit Scope `read:packages` als `GITHUB_TOKEN`, in GitHub Actions genügt
|
|
72
|
+
> `secrets.GITHUB_TOKEN`). Details in [Getting Started](docs/GETTING-STARTED.md#1-einbinden),
|
|
73
|
+
> Begründung in [ADR-0004](docs/adr/0004-verteilung-und-versionierung.md). Ohne npm bleibt
|
|
74
|
+
> Variante A (Vendoren von `dist/conciso-ds.css` + `fonts/`) der schlankeste Weg.
|
|
81
75
|
>
|
|
82
|
-
>
|
|
83
|
-
>
|
|
84
|
-
>
|
|
76
|
+
> Der Lese-Auth-Zwang gilt damit nur wegen der **Registry**, nicht wegen der Lizenz, und
|
|
77
|
+
> betrifft nur das **Paket** selbst. Die **Doku** (Storybook, die Komponenten-Referenz der
|
|
78
|
+
> Angular-Lib) ist dagegen öffentlich einsehbar unter
|
|
79
|
+
> <https://conciso.github.io/conciso-design-system/> — ohne Auth, aber `noindex` (nicht für
|
|
80
|
+
> Suchmaschinen bestimmt). Details und Abwägung in
|
|
85
81
|
> [ADR-0009](docs/adr/0009-storybook-oeffentlich-auf-github-pages.md).
|
|
86
82
|
|
|
87
83
|
**Angular:** Für Angular gibt es Komponenten statt nur CSS-Klassen —
|
|
88
|
-
`@conciso/design-system-angular` aus
|
|
89
|
-
|
|
84
|
+
`@conciso/design-system-angular` aus derselben Registry, im Lockstep auf derselben Version.
|
|
85
|
+
Siehe [README der Lib](angular-lib/projects/design-system-angular/README.md).
|
|
90
86
|
|
|
91
87
|
**Dark Mode:** `data-theme="dark"` am `<html>` setzen. Siehe [Getting Started](docs/GETTING-STARTED.md#3-dark-mode) für das Anti-Flash-Snippet.
|
|
92
88
|
|
|
@@ -127,7 +123,7 @@ npm run check:contrast # Kontrast der gerenderten Doku in Light UND Dark
|
|
|
127
123
|
|
|
128
124
|
## Versionierung
|
|
129
125
|
|
|
130
|
-
[SemVer](https://semver.org/lang/de/). Die Version steht **nicht** im Repo, sondern im jeweiligen Git-Tag `vX.Y.Z`; Änderungen dazu stehen im zugehörigen GitHub-Release. Releases entstehen automatisch aus Conventional Commits auf `main` ([ADR-0010](docs/adr/0010-release-ausloesung-und-versionsquelle.md)) und werden nach
|
|
126
|
+
[SemVer](https://semver.org/lang/de/). Die Version steht **nicht** im Repo, sondern im jeweiligen Git-Tag `vX.Y.Z`; Änderungen dazu stehen im zugehörigen GitHub-Release. Releases entstehen automatisch aus Conventional Commits auf `main` ([ADR-0010](docs/adr/0010-release-ausloesung-und-versionsquelle.md)) und werden nach GitHub Packages veröffentlicht. Der handgeschriebene [CHANGELOG](CHANGELOG.md) ist mit Version 2.0.0 eingefroren. `@conciso/design-system` und `@conciso/design-system-angular` tragen dabei im **Lockstep** immer dieselbe Version, damit die peerDependency der Angular-Lib auf die CSS-Schicht eng gepinnt auflöst ([ADR-0004](docs/adr/0004-verteilung-und-versionierung.md)).
|
|
131
127
|
|
|
132
128
|
## Lizenz & Kontakt
|
|
133
129
|
|
package/css/components.css
CHANGED
|
@@ -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
|
-
|
|
598
|
-
.
|
|
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
|
-
|
|
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
|
-
/*
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
|
|
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 */
|
package/dist/conciso-ds.css
CHANGED
|
@@ -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
|
-
/*
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1856
|
-
.
|
|
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
|
-
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conciso/design-system",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Conciso Design System — Design Tokens, CSS-Komponenten und Light/Dark-Mode, framework-agnostisch und WCAG-AA-konform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
package/tokens/tokens.js
CHANGED
|
@@ -79,6 +79,12 @@ export const tokens = {
|
|
|
79
79
|
"c-warning-bg": "#F5D08C",
|
|
80
80
|
"c-error": "#9B2020",
|
|
81
81
|
"c-error-bg": "#F5BFBF",
|
|
82
|
+
"c-success-strong": "#0d5e39",
|
|
83
|
+
"c-success-on-strong": "#d6f5e8",
|
|
84
|
+
"c-success-strong-icon": "#88f0c4",
|
|
85
|
+
"c-error-strong": "#7a1515",
|
|
86
|
+
"c-error-on-strong": "#fde8e8",
|
|
87
|
+
"c-error-strong-icon": "#f9a8a8",
|
|
82
88
|
"badge-ok-text": "#0E6644",
|
|
83
89
|
"badge-warn-text": "#785008",
|
|
84
90
|
"badge-err-text": "#9B2020",
|
|
@@ -196,6 +202,9 @@ export const darkTokens = {
|
|
|
196
202
|
"c-success": "#5CE8A0",
|
|
197
203
|
"c-warning": "#F0C060",
|
|
198
204
|
"c-error": "#FFA5A5",
|
|
205
|
+
"c-success-strong": "#1F573B",
|
|
206
|
+
"c-success-on-strong": "#b0f0d0",
|
|
207
|
+
"c-error-strong": "#882725",
|
|
199
208
|
"co-50": "#134C47",
|
|
200
209
|
"ki-50": "#384912",
|
|
201
210
|
"wo-50": "#144E1F",
|
package/tokens/tokens.json
CHANGED
|
@@ -79,6 +79,12 @@
|
|
|
79
79
|
"c-warning-bg": "#F5D08C",
|
|
80
80
|
"c-error": "#9B2020",
|
|
81
81
|
"c-error-bg": "#F5BFBF",
|
|
82
|
+
"c-success-strong": "#0d5e39",
|
|
83
|
+
"c-success-on-strong": "#d6f5e8",
|
|
84
|
+
"c-success-strong-icon": "#88f0c4",
|
|
85
|
+
"c-error-strong": "#7a1515",
|
|
86
|
+
"c-error-on-strong": "#fde8e8",
|
|
87
|
+
"c-error-strong-icon": "#f9a8a8",
|
|
82
88
|
"badge-ok-text": "#0E6644",
|
|
83
89
|
"badge-warn-text": "#785008",
|
|
84
90
|
"badge-err-text": "#9B2020",
|
|
@@ -195,6 +201,9 @@
|
|
|
195
201
|
"c-success": "#5CE8A0",
|
|
196
202
|
"c-warning": "#F0C060",
|
|
197
203
|
"c-error": "#FFA5A5",
|
|
204
|
+
"c-success-strong": "#1F573B",
|
|
205
|
+
"c-success-on-strong": "#b0f0d0",
|
|
206
|
+
"c-error-strong": "#882725",
|
|
198
207
|
"co-50": "#134C47",
|
|
199
208
|
"ki-50": "#384912",
|
|
200
209
|
"wo-50": "#144E1F",
|
package/tokens/tokens.scss
CHANGED
|
@@ -80,6 +80,12 @@ $c-warning: #785008;
|
|
|
80
80
|
$c-warning-bg: #F5D08C;
|
|
81
81
|
$c-error: #9B2020;
|
|
82
82
|
$c-error-bg: #F5BFBF;
|
|
83
|
+
$c-success-strong: #0d5e39;
|
|
84
|
+
$c-success-on-strong: #d6f5e8;
|
|
85
|
+
$c-success-strong-icon: #88f0c4;
|
|
86
|
+
$c-error-strong: #7a1515;
|
|
87
|
+
$c-error-on-strong: #fde8e8;
|
|
88
|
+
$c-error-strong-icon: #f9a8a8;
|
|
83
89
|
$badge-ok-text: #0E6644;
|
|
84
90
|
$badge-warn-text: #785008;
|
|
85
91
|
$badge-err-text: #9B2020;
|
|
@@ -197,6 +203,9 @@ $conciso-dark: (
|
|
|
197
203
|
"c-success": #5CE8A0,
|
|
198
204
|
"c-warning": #F0C060,
|
|
199
205
|
"c-error": #FFA5A5,
|
|
206
|
+
"c-success-strong": #1F573B,
|
|
207
|
+
"c-success-on-strong": #b0f0d0,
|
|
208
|
+
"c-error-strong": #882725,
|
|
200
209
|
"co-50": #134C47,
|
|
201
210
|
"ki-50": #384912,
|
|
202
211
|
"wo-50": #144E1F,
|